x86_64::instructions::interrupts

Function enable_and_hlt

Source
pub fn enable_and_hlt()
Expand description

Atomically enable interrupts and put the CPU to sleep

Executes the sti; hlt instruction sequence. Since the sti instruction keeps interrupts disabled until after the immediately following instruction (called “interrupt shadow”), no interrupt can occur between the two instructions. (One exception to this are non-maskable interrupts; this is explained below.)

This function is useful to put the CPU to sleep without missing interrupts that occur immediately before the hlt instruction:

// there is a race between the check and the `hlt` instruction here:

if nothing_to_do() {
    // <- race when the interrupt occurs here
    x86_64::instructions::hlt(); // wait for the next interrupt
}

// avoid this race by using `enable_and_hlt`:

x86_64::instructions::interrupts::disable();
if nothing_to_do() {
    // <- no interrupts can occur here (interrupts are disabled)
    x86_64::instructions::interrupts::enable_and_hlt();
}

§Non-maskable Interrupts

On some processors, the interrupt shadow of sti does not apply to non-maskable interrupts (NMIs). This means that an NMI can occur between the sti and hlt instruction, with the result that the CPU is put to sleep even though a new interrupt occurred.

To work around this, it is recommended to check in the NMI handler if the interrupt occurred between sti and hlt instructions. If this is the case, the handler should increase the instruction pointer stored in the interrupt stack frame so that the hlt instruction is skipped.

See http://lkml.iu.edu/hypermail/linux/kernel/1009.2/01406.html for more information.