2

As part of sending interrupts to user space I am seeing the following code snippet around but I don't understand how si_int affects the signal propagation.

static int SendToUsrSpace(void) {
  struct siginfo info;
  struct task_struct *t;
  int ret;

  memset(&info, 0, sizeof(struct siginfo));
  info.si_signo = 44;
  info.si_code = SI_QUEUE;
  info.si_int = 1234; // WHY NOT 36 or any random number?
  [...]
  ret = send_sig_info(44, &info, t);
  [...]
}
bardao
  • 914
  • 12
  • 23

1 Answers1

1

I think the explanation is in sigqueue(3). From the text:

       sigqueue() sends the signal specified in sig to the process whose PID
       is given in pid.  The permissions required to send a signal are the
       same as for kill(2).  As with kill(2), the null signal (0) can be
       used to check if a process with a given PID exists.

       The value argument is used to specify an accompanying item of data
       (either an integer or a pointer value) to be sent with the signal,
       and has the following type:

           union sigval {
               int   sival_int;
               void *sival_ptr;
           };

       If the receiving process has installed a handler for this signal
       using the SA_SIGINFO flag to sigaction(2), then it can obtain this
       data via the si_value field of the siginfo_t structure passed as the
       second argument to the handler.  Furthermore, the si_code field of
       that structure will be set to SI_QUEUE.

So, 1234 looks like an arbitrary value that a process can pull (if it has a handler for this signal). It looks like a way to send data with the signal.

Additional reading: I arrived at sigqueue from sigaction(2), which lays out the data type for siginfo_t.

jhelphenstine
  • 435
  • 2
  • 10
  • is it wrong to send the register value that was modified through the interrupt inside `si_int` or is that info embedded in other variables? – bardao Jun 20 '19 at 20:08
  • I think you're fine there -- sigqueue(3) references the sender of the signal determines that value, so I read that as 'it's up to you'. – jhelphenstine Jun 20 '19 at 21:14
  • what about the address location of that register along with the value, value goes in `si_int`, is there a way to extract the address itself? I can see that si_addr is (void*) so nothing there. – bardao Jun 20 '19 at 21:22
  • I'm not sure I follow. Assuming we're talking eax/ecx/eip etc, those don't have addresses; they hold addresses. Can you give me a sample of what the data you're looking for would be? – jhelphenstine Jun 20 '19 at 21:42
  • Assuming the driver detects an interrupt, when I forward the signal to the user space,` siginfo_t->si_value.sival_int` will contain the value of the address where the interrupt happened (assuming the interrupt is writing to that address). How can I also tell it which address was involved? – bardao Jun 20 '19 at 22:41