How to make user space code react to a kernel interrupt? - linux

If I write kernel code to handle interrupts, how can I inform user space code?
And how could user space code handle it? By a blocking read()?
Then the user space code can do nothing if the interrupt hasn't happened?
Or maybe a multi-threads user space code can be made: one thread is for the blocking read(), another thread can do things such as GUI update, etc, right?

Related

The communication between kernel helper thread and Kernel level code

I'm studying Linux kernel and I'm wondering if I can do like below assuming a helper kernel thread already created.
A code was inserted in a sys_call(ex. in sys_execv()).
I would make the code in the sys_call send a signal to the kernel thread, and the code "shall wait or stop" until receive a completion event from the helper thread.
How the code can do this?
Thank you for your help in advance.
//DAUM
Signals are meant for user space processes. Although it is possible to allow certain signals (like SIGKILL) to a kernel thread but we cannot have signal handlers in kernel threads. So the signal based approach will not work.
It is better to explore other approaches based on work queues to achieve the same thing.

Linux System Call Flow Sequence

I had a question regarding the deep working of Linux.
Lets say a multi-threaded process is being executed in the CPU. We will have a thread which is being executed on the CPU in such a case. At a more broader picture we will have the corresponding page belonging to the Process being loaded in the RAM for execution.
Lets say the thread makes a system call. I am a bit unclear on the workings after this. The Interrupt will generate a call. One of my questions is who will answer this call?
Lets say that the system has m:n user level thread to kernel level thread mapping, I am assuming that the corresponding Kernel Level Thread will answer this call.
So the Kernel will lookup the Interrupt Vector Table and get the routine which needs to be executed. My next question is which stack will be used in the execution of the Interrupt? Will it be the Kernel Thread's Stack or the User level Thread's Stack? (I am assuming that it will be the Kernel Thread's Stack.)
Coming back to the flow of the program lets say the operation is opening a file using fopen. The subsequent question I have is how will the jump from the ISR to System Call take place? Or is our ISR mapped to a System Call?
Also at a more broader picture when the Kernel Thread is being executed I am assuming that the "OS region" on the RAM will be used to house the pages which are executing the System Call.
Again looking at it from a different angle (Hope your still with me) finally I am assuming that the corresponding Kernel Thread is being handled by the CPU Scheduler where in a context switch would have happened from the User Level Thread to the corresponding Kernel Level Thread when the fopen System Call was being answered.
I have made a lot of assumptions and it would be absolutely fantastic if anyone could clear the doubts or at least guide me in the right direction.
Note: I work predominately with ARM machines so some of these things might be ARM specific. Also, I'm going to try and simplify it as much as I can. Feel free to correct anything that might be wrong or oversimplified.
Lets say the thread makes a system call. I am a bit unclear on the workings after this. The Interrupt will generate a call. One of my questions is who will answer this call?
Usually, the processor will start executing at some predetermined location in kernel mode. The kernel will save the current process state and look at the userspace registers to determine which system call was requested and dispatch that to the correct system call handler.
So the Kernel will lookup the Interrupt Vector Table and get the routine which needs to be executed. My next question is which stack will be used in the execution of the Interrupt? Will it be the Kernel Thread's Stack or the User level Thread's Stack? (I am assuming that it will be the Kernel Thread's Stack.)
I'm pretty sure it will switch to a kernel stack. There would be some pretty severe security problems with information leaks if they used the userspace stack.
Coming back to the flow of the program lets say the operation is opening a file using fopen. The subsequent question I have is how will the jump from the ISR to System Call take place? Or is our ISR mapped to a System Call?
fopen() is actually a libc function and not a system call itself. It may (and in most cases will) call the open() syscall in its implementation though.
So, the process (roughly) is:
Userspace calls fopen()
fopen performs a system call to open()
This triggers some sort of exception or interrupt. In response, the processor switches into a more privileged mode and starts executing at some preset location in the kernel.
Kernel determines what kind of interrupt and exception it is and handles it appropriately. In our case, it will be a system call.
Kernel determines which system call is being requested by reading the userspace registers and extracts any arguments and passes it to the appropriate handler.
Handler runs.
Kernel puts any return code into userspace registers.
Kernel transfers execution back to where the exception occured.
Also at a more broader picture when the Kernel Thread is being executed I am assuming that the "OS region" on the RAM will be used to house the pages which are executing the System Call.
Pages don't execute anything :) Usually, in Linux, any address mapped above 0xC0000000 belongs to the kernel.
Again looking at it from a different angle (Hope your still with me) finally I am assuming that the corresponding Kernel Thread is being handled by the CPU Scheduler where in a context switch would have happened from the User Level Thread to the corresponding Kernel Level Thread when the fopen System Call was being answered.
With a preemptive kernel, threads effectively aren't discriminated against. With my understanding, a new thread isn't created for the purpose of servicing a system call - it just runs in the same thread from which the system call was requested in, except in kernel mode.
That means a thread that is in kernel mode servicing a system call can be scheduled out just the same as any other thread. Hence, this is where you hear about 'userspace context' when developing for the kernel. It means it's executing in kernel mode on a usermode thread.
It's a little difficult to explain this so I hope I got it right.

How kernel notify a user space program an interrupt occurrs

I'm writing a user space program and a kernel space device driver.
Goal: Once an interrupt occurs, user space program needs to do something quickly.
My naive method: User space program uses ioctl to call wait_event_interruptible(), kernel ISR calls wake_up_interruptible() to wake up user space program. It turns out that it takes too much time from interrupt to user space.
Is there any better way?
Thanks!
There is a similar question asked here:
Notify gpio interrupt to user space from a kernel module
Please check above question. However, i can provide my approach which i suggested there as well.
You can send a signal to user space thread from kernel API, which can help u run non-blocking:
send_sig(int sig, struct task_struct *p, int priv);
You need to be aware of pid of user thread in Kernel. You can over come this by writing pid of user process via /proc and then kernel reading the pid. With this arrangement, when there is an interrupt, kernel can send signal to user thread. In case your process restarts or gets killed, you will have to update the pid via proc. Just for status notification you can use this method; however if you like to transfer data along with status than Netlink or char driver mechanism is good way.

Jumping to-and fro between Kernel and user code in Linux

I am doing some kernel hacking on Linux running x86-64 for a research project. From a kernel routine I need to jump to a user mode code page and immediately return back to kernel code. In other words, I need to do a trampoline on user code while executing in the kernel.
I am wondering whether this can be at all possible or not. If possible, can somebody give some idea how this can be achieved?
It is unlikely to be possible "easily".
Without knowing your application, and without suggesting that you rethink your kernel<->app interface, a possible hack for you could work like this: have the application register a piece of trampoline code with your kernel component by just passing the address of that code. The trampoline code would execute your "real" user mode function, then issue another syscall or exception to return to the kernel.
While this is not exactly a user-mode subroutine, it gets reasonably close: when your application calls whatever kernel function needs to do the callback, the kernel function can just save the real return address, change it to the registered trampoline address and return to user mode. The trampoline will call the function, the syscall/exception following it will kick you back into the kernel and you can continue whatever you were doing there.
You probably don't need to worry about security anyway, but if you do you'd probably have to make sure the "return from trampoline" syscall is only accepted from processes where you still have an open trampoline hack going on.
You can also take a look at how signals work; they are about having the kernel interrupt an application and having the application invoke a signal handler; a signal-like implementation would even work without your application having an active syscall going on (but it will also have all the limitations of a signal handler).
In fact, maybe you can just use a signal? Again, take a look at how signals work in the kernel, and just signal your user-code. Install the appropiate signal handler in your application, and have the signal handler invoke the "return from userspace trampoline" syscall.
Either way, it sounds a bit... hackish. Without ever having done any kernel stuff, I would assume that interfacing with your application through a device node, socket or similar mechanism would probably be a much better way... or just have your syscalls return a "to do" result item to the application telling it to invoke siome user space code and report back with another syscall.

Internals of a Linux system call

What happens (in detail) when a thread makes a system call by raising interrupt 80? What work does Linux do to the thread's stack and other state? What changes are done to the processor to put it into kernel mode? After running the interrupt handler, how is control restored back to the calling process?
What if the system call can't be completed quickly: e.g. a read from disk. How does the interrupt handler relinquish control so that the processor can do other stuff while data is being loaded and how does it then obtain control again?
A crash course in kernel mode in one stack overflow answer
Good questions! (Interview questions?)
What happens (in detail) when a
thread makes a system call by raising
interrupt 80?
The int $80 operation is vaguely like a function call. The CPU "takes a trap" and restarts at a known address in kernel mode, typically with a different MMU mode as well. The kernel will save many of the registers, though it doesn't have to save the registers that a program would not expect an ordinary function call to save.
What work does Linux do to the
thread's stack and other state?
Typically an OS will save registers that the ABI promises not to change during procedure calls. The stack will stay the same; the kernel will run on a per-thread kernel stack rather than the per-thread user stack. Naturally some state will change, otherwise there would be no reason to do the system call.
What changes are done to the
processor to put it into kernel mode?
This is usually entirely automatic. The CPU has, generically, a software-interrupt instruction that is a bit like a functional-call operation. It will cause the switch to kernel mode under controlled conditions. Typically, the CPU will change some sort of PSW protection bit, save the old PSW and PC, start at a well-known trap vector address, and may also switch to a different memory management protection and mapping arrangement.
After running the interrupt handler,
how is control restored back to the
calling process?
There will be some sort of "return from interrupt" or "return from trap" instruction, typically, that will act a bit like a complicated function-return instruction. Some RISC processors did very little automatically and required specific code to do the return and some CISC processors like x86 have (never-really-used) instructions that would execute dozens of operations documented in pages of architecture-manual pseudo-code for capability adjustments.
What if the system call can't be
completed quickly: e.g. a read from
disk. How does the interrupt handler
relinquish control so that the
processor can do other stuff while
data is being loaded and how does it
then obtain control again?
The kernel itself is threaded much like a threaded user program is. It just switches stacks (threads) and works on someone else's process for a while.
To answer the last part of the question - what does the kernel do if the system call needs to sleep -
After a system call, the kernel is still logically running in the context of the same task that made the system call - it's just in kernel mode rather than user mode - it is NOT a separate thread and most system calls do not invoke logic from another task/thread. What happens is that the system call calls wait_event, or wait_event_timeout or some other wait function, which adds the task to a list of tasks waiting for something, then puts the task to sleep, which changes its state, and calls schedule() to relinquish the current CPU.
After this the task cannot be run again until it gets woken up, typically by another task (kernel task, etc) or interrupt handler calling a wake* function which will wake up the task(s) sleeping waiting for that particular event, which means the scheduler will soon schedule them again.
It's worth noting that userspace tasks (i.e. threads) are only one type of task and there are a few others internal to the kernel which can do work as well - these are kernel threads and bottom half handlers / tasklets / task queues etc. Work which doesn't belong to any particular userspace process (for example network handling e.g. responding to pings) gets done in these. These tasks are allowed to go to sleep, unlike interrupts (which should not invoke the scheduler)
http://tldp.org/LDP/khg/HyperNews/get/syscall/syscall86.html
This should help people who seek for answers to what happens when the syscall instruction is executed which transfers the control to the kernel (user mode to kernel mode). This is based upon x86_64 architecture.
https://0xax.gitbooks.io/linux-insides/content/SysCall/syscall-2.html

Resources