I need to send a string from kernel to a user space function without asking for it in particular from the user space, sort of triggering a function or application in the use
An example I used in the past was to send signal to user space from hardware interrupt in kernel space.
KERNEL SPACE
You have to prepare siginfo and task_struct before sending a signal:
struct siginfo info;
struct task_struct *t;
info.si_signo = SIG_TEST;
info.si_code = SI_QUEUE;
info.si_int = 1234; // Any value you want to send
rcu_read_lock();
And also find the task with user space application PID. You have to send it from user-space to kernel-space through write or ioctl operations.
t = pid_task(find_pid_ns(pid, &init_pid_ns), PIDTYPE_PID);
Then you can send the signal.
rcu_read_unlock();
send_sig_info(SIG_TEST, &info, t);
I omitted here, but you must check the result of every operation.
The previous code prepare the signal structure and send it. Bear in mind that you need the application's PID. In my case the application from user space send its PID through ioctl driver procedure.
USER SPACE
You have to define and implement the callback function:
void signalFunction(int n, siginfo_t *info, void *unused) {
.....
.....
}
In main procedure:
struct sigaction sig;
sig.sa_sigaction = signalFunction; // Callback function
sig.sa_flags = SA_SIGINFO;
sigaction(SIG_TEST, &sig, NULL);
I hope it helps.
Here's how my process works, I would be interested in any suggestions for improvements as well:
Start user space application, which sends a custom command to the kernel module to register the user space PID for kernel module signals. In my case this was via a write to /dev/mymodule. The kernel module registers the PID:
...
printk("registering a new process id to receive signals: %d\n", current->pid);
signal_pid = current->pid;
...
The user space application also registers a handler with the kernel for certain types of signals.
void local_sig_handler(int signum) {
printf("received a signal from my module\n");
fflush(stdout); }
...
signal(SIGIO, local_sig_handler);
Kernel module generates a signal
...
struct siginfo info;
struct task_struct *t;
info.si_signo=SIGIO;
info.si_int=1;
info.si_code = SI_QUEUE;
printk("<1>IRQ received: %d\n", irq);
printk("<1>searching for task id: %d\n", signal_pid);
t= pid_task(find_vpid(signal_pid),PIDTYPE_PID);//user_pid has been fetched successfully
if(t == NULL){
printk("<1>no such pid, cannot send signal\n");
} else {
printk("<1>found the task, sending signal\n");
send_sig_info(SIGIO, &info, t);
}
Kernel relays the signal to the application's handler
You've got a few options: