I have a process PID that access a memory region that it's not allowed to, the CPU creates a trap into the kernel which calls do_page_fault() which will send SIGSEGV to the user process. The user process has a custom signal handler that has some logic and the faulting instruction is resumed. What I want to do is to move this signal handler logic to kernel space and prevent SIGSEGV from being sent.
For that could I write a kernel module that hijacks the fault handler for this PID or something? or do I have to add my logic to do_page_fault()? Some guidance would be helpful.
userfaultfd() could be useful to you. It allows you to handle
page faults in usermode.
Related
I know that when a user thread acquires for a lock(like event, semaphore and so on), the kernel will change the thread's state to waiting so the thread will not be scheduled to run until the kernel finds that the lock is available.
My question is how does the kernel captures the state of these locks? By polling or notifying?
By notifying. Before the thread goes to sleep, it adds itself to the wakeup list for whatever kernel object corresponds to the thing it's waiting for.
This works precisely the same way all other waits work. Say, for example, the process does a blocking read on a file and the process has to sleep until the read completes. Or say the process accesses some code that hasn't been read in from disk yet. In all of these cases, the process is added to the appropriate wakeup notification scheme when it puts itself to sleep.
What you are asking is highly system specific and lock specific. For example, quality operating systems have lock management facilities that will detect deadlocks.
Some locks might be implemented as spin locks where there is no process hibernation and no operating system notification at all.
In the case where waiting suspends a process, all the operating system needs to keep track of is the lock itself. If a process releases the lock, the operating system can send a notification to all the waiting process—no poling necessary.
Does interrupt handler is running like user programs in the meaning of virtual memory (TLB miss - load page descriptor) or there are on any CPU difference solution?
The interrupt service routine (ISR) is going to execute in kernel mode. The jump table that the processor uses to figure out what routine to run on the interrupt itself cannot be swapped out, because the page fault handler would also be found there. I don't know for sure what would happen if the handler address pointed to an unmapped region of memory. Virtual memory can be supported in kernel mode, at least on x86. Maybe some architectures could handle an access fault for an ISR address, but an OS would never implement that, because the latency for entering the ISR would be totally unacceptable.
My problem is:
Interrupt handler get triggered when free_irq is called. I noticed in kernel messages that handler is invoked but since our device hasn't requested interrupt it prompted that no interrupt has received.
Is it expected behavior ? Can anybody please help ?
When you are registering a handler for a (possibly) shared interrupt (with IRQF_SHARED), the interrupt can be triggered by other devices over which your driver has no control, so your driver must be prepared to receive an interrupt at any time.
To help with debugging drivers, the kernel will (when CONFIG_DEBUG_SHIRQ is set) fake some interrupts to check that your driver works correctly.
[source code]
If I understood your post right - you must turn off issuing interrupts in your hardware before you call free_irq() then you won't receive interrupts while free_irq().
I am trying to understand Asynchronous Interrupt handling in kernel, ofcourse through the legendary Understanding the Linux Kernel.
In this process how and who will trigger Kernel Interrupt Handler?
I would like some one to help me correcting this and to clarify my question on
1)How and Who trigger Kernel Interrupt Handler?
2)How to define new or change existing hardware interrupt handlers?
Thank you in Advance!
This picture from Robert Love's "Linux Kernel Development" pretty well describes path of interrupt. Processor interrupts the kernel in the predefined enty point do_IRQ(). If there is corresponding interrupt handler, it will get executed.
To handle interrupt, you should register your interrupt handler with request_irq().
Every device driver book talks about not using functions that sleep in interrupt routines.
What issues occur by calling these functions from ISRs ?
A total lockdown of the kernel is the issue here. The kernel is in interrupt context when executing interrupt handlers, that is, the interrupt handler is not associated with any process (the current macro cannot be used).
If you are able to sleep, you would never be able to get back to the interrupted code, since the scheduler would not know how to get back to it.
Holding a lock in the interrupt handler, and then sleeping, allowing another process to run and then entering the interrupt handler again and trying to re-acquire the lock would deadlock the kernel.
If you try to read more about how the scheduling in the kernel works, you will soon realize why sleeping is a no go in certain contexts.