Does the CPU disable all interrupts on local CPU before calling the interrupt handler? Or does it only disable that particular interrupt line, which is being served?
-
1Which CPU? What architecture? – eepp Jul 10 '12 at 01:57
5 Answers
x86 disables all local interrupts (except NMI of course) before jumping to the interrupt vector. Linux normally masks the specific interrupt and re-enables the rest of the interrupts (which aren't masked), unless a specific flags is passed to the interrupt handler registration.
Note that while this means your interrupt handler will not race with itself on the same CPU, it can and will race with itself running on other CPUs in an SMP / SMT system.

- 14,900
- 40
- 57
-
Could you please provide the source to the claim "x86 disables all local interrupts .. before jumping to the interrupt vector"? I have in my posession Intel 3-volume architecture documentation, and 8259A documentation, also from Intel. I cannot find anything telling me that interrupts are automatically disabled prior to jumping to interrupt vector, i.e. at the point of entering an ISR (interrupt service routine / interrupt handler procedure) – Armen Michaeli Mar 17 '15 at 22:55
-
2Not strict HW behavior - the question was asked in the context of the linux kernel. The LAPIC behavior is programmable, but this is how Linux programs it - all interrupts of same priority, so one blocks the other, but Linux in software re-enables interrupts very quickly even before the interrupt handler runs. – gby Mar 19 '15 at 08:43
-
2I subsequently found reference to the "default" x86 HW behavior in question, in "Intel 64 and IA-32 Arch. Software Developer's Manual", p. 6-10 Vol. 1: "If an interrupt or exception handler is called through an interrupt gate, the processor clears the interrupt enable (IF) flag in the EFLAGS register to prevent subsequent interrupts from interfering with the execution of the handler." Thank you for clearing things up w/ regard to Linux. – Armen Michaeli Mar 21 '15 at 14:20
Normally (at least in x86), an interrupt disables interrupts.
When an interrupt is received, the hardware does these things:
1. Save all registers in a predetermined place.
2. Set the instruction pointer (AKA program counter) to the interrupt handler's address.
3. Set the register that controls interrupts to a value that disables all (or most) interrupts. This prevents another interrupt from interrupting this one.
An exception is NMI (non maskable interrupt) which can't be disabled.

- 16,023
- 3
- 35
- 65
-
6From Linux Kernel Development **Interrupt handlers in Linux need not be reentrant. When a given interrupt handler is executing, the corresponding interrupt line is masked out on all processors, preventing another interrupt on the same line from being received. Normally all other interrupts are enabled, so other interrupts are serviced, but the current line is always disabled. Consequently, the same interrupt handler is never invoked concurrently to service a nested interrupt. This greatly simplifies writing your interrupt handler.** So, only the current interrupt line is masked. – Harman Jul 10 '12 at 18:26
-
@Harman, This means that only the current interrupt line is guaranteed to be masked. I'm pretty sure the actual implementation on x86 is to mask them all. – ugoren Jul 11 '12 at 10:42
Yes, that's fine. I'd like to also add what I think might be relevant.
In many real-world drivers/kernel code, "bottom-half" (bh) handlers are used pretty often- tasklets, softirqs. These bh's run in interrupt context and can run in parallel with their top-half (th) handlers on SMP (esp softirq's).
Of course, recently there's a move (mainly code migrated from the PREEMPT_RT project) towards mainline, that essentially gets rid of the 'bh' mechanism- all interrupt handlers will run with all interrupts disabled. Not only that, handlers are (can be) converted to kernel threads- these are the so-called "threaded" interrupt handlers.
As of today, the choice is still left to the developer- you can use the 'traditional' th/bh style or the threaded style.
Ref and Details:

- 2,114
- 1
- 18
- 23
Quoting Intels own, surprisingly well-written "Intel® 64 and IA-32 Architectures Software Developer’s Manual", Volume 1, pages 6-10:
If an interrupt or exception handler is called through an interrupt gate, the processor clears the interrupt enable (IF) flag in the EFLAGS register to prevent subsequent interrupts from interfering with the execution of the handler. When a handler is called through a trap gate, the state of the IF flag is not changed.
So just to be clear - yes, effectively the CPU "disables" all interrupts before calling the interrupt handler. Properly described, the processor simply triggers a flag which makes it ignore all interrupt requests. Except probably non-maskable interrupts and/or its own software exceptions (please someone correct me on this, not verified).

- 8,625
- 8
- 58
- 95
We want ISR to be atomic and no one should be able to preempt the ISR.
Therefore, An ISR disables the local interrupts ( i.e. the interrupt on the current processor) and once the ISR calls ret_from_intr() function ( i.e. we have finished the ISR) , interrupts are again enabled on the current processor.
If an interrupt occurs, it will now be served by the other processor ( in SMP system) and ISR related to that interrupt will start running.
In SMP system , We also need to include the proper synchronization mechanism ( spin lock) in an ISR.

- 19
- 3
-
1Could you please elaborate more your answer adding a little more description about the solution you provide? – abarisone Sep 22 '15 at 12:01