Attribute for processor interrupt handlers #1497
flysand7
started this conversation in
Ideas/Requests
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Abstract
Whenever an interrupt is issued, for example an IO interrupt when you press a mouse, or a user application page faults, the x86 processor would index into Interrupt Descriptor Table, get the address of the Interrupt Service Routine (ISR) and call it.
The ISRs are very different from normal functions in the structure, since upon calling that routine, more information is put on the stack. If a normal procedure call only pushes the return address, the ISR call (via INT or hardware interrupt) pushes far pointer to the original stack, (E/R)FLAGS register, and the far pointer to the code that was executing before the interrupt was issued. Therefore to return from an ISR a different instruction is required --
IRET
(IRETD/IRETQ).Most interrupt service routines also save the general-purpose registers on the stack so that after the ISR returns, the program can continue to run normally. Some ISRs also clear the direction flag DF.
Implementing ISR using inline assembly is considered to be a bad practice. An example from OSdev wiki:
This cannot work. The compiler doesn't understand what is going on. It doesn't understand that the registers and stack are required to be preserved between the asm statements; the optimizer will likely corrupt the function. Additionally, the compiler adds stack handling code before and after your function, which together with the iret results in assembly code resembling this:
An obvious observation is that this function corrupts the stack, since
iret
is executed first, returning from the interrupt handler with the wrong stack andleave
is never executed.Therefore the compiler needs to provide a way to write ISRs. Of course, programmers can resort to assembly when needed, but this requires 2 function calls (one ISR, another is the call of high-level handler) for each interrupt.
There are two alternatives to how ISR programming support can be added to a programming language:
Since I don't know any other use for the naked function and interrupt attribute would be in any way simpler for a kernel programmer to use, I advocate using that.
Overview of how interrupts work
Whenever an interrupt is initiated, either by hardware or by a program calling INT instruction, the processor switches to the kernel privilege level and calls an interrupt service routine.
The stack at that point looks like this:
I will not explain the meaning of those fields, but the processor needs them in order to return back to the original program after interrupt has finished servicing.
Some interrupts also push the error code onto the stack, in which case the stack has different offsets:
So there are two kinds of ISRs -- those that take the error code and those that do not. IRET instruction automatically clears this stack, so no additional care is needed. Note, however that for some interrupts the ISR wants to know the values of certain fields from this stack. e.g. if a program has crashed, sometimes it's useful that the OS knows the failing address.
Proposed syntax and mechanism
So the ISR will be declared as a normal function with
interrupt
attribute.In the first version, the
stack_frame
would be the value of RSP at the time the function is called. The user will declare their own version of the stack frame struct.In the second version, the
stack_frame
would bersp+8
, anderror_code
would be a value of a qword located at the addressrsp
. Since error_code is typically only used for reading it doesn't matter where the actual variable is located.In addition to that @(interrupt) functions need to ensure the following:
Note that only the general-purpose registers are saved. If any other features of the processor are used within the ISR (SSE, AVX, MMX, ...) the registers corresponding to those features need to be saved as well. This is lots of overhead usually for no benefit. So the next item is:
Beta Was this translation helpful? Give feedback.
All reactions