Search code examples
x86arminterruptcpu-architecture

How does a CPU handle asynchronous interrupts?


CPUs split one instruction into several micro-ops, this works for x86 and ARM cores and maybe several other architectures. Micro-ops could be executed out-of-order and are stored in a ROB. They are retired in-order from this ROB.

How does a CPU handle asynchronous interrupts?

I think of 2 possible implementations:

  1. CPU will continue executing all micro-ops which are already in ROB, temporally ignoring the coming interrupt.
  2. CPU will flush its pipeline. But if the pipeline is flushed, could we face a situation when some micro-ops of an instruction are retired, while other micro-ops of the same instruction are flushed from ROB? And what resources will remain in a pipeline after the interrupt is raise

Solution

  • Interrupts are definitely always taken on instruction boundaries, even if that means discarding partial progress and restarting execution after interrupt return, at least on x86 and ARM microarchs. (Some instructions are interruptible, like rep movsb has a way to update registers. AVX2 gathers are also interruptible, or at least could be; the mask-updating rules might only ever get applied for synchronous exceptions encountered on one element).


    There's some evidence that Intel CPUs let one more instruction retire before taking an interrupt, at least for profiling interrupts (from the PMU); those are semi-synchronous but for some events don't have a fixed spot in the program where they must be taken, unlike page faults which have to fault on the faulting instruction.

    A multi-uop instruction that's already partially retired would have to be allowed to finish executing and retire the whole instruction, to reach the next consistent architectural state where an interrupt could possibly be taken.

    (Another possible reason for letting an instruction finish executing before taking an interrupt is to avoid starvation.)

    Otherwise yes, the ROB and RS are discarded and execution is rolled back to the retirement state. Keeping interrupt latency low is generally desirable, and a large ROB could hold a lot of cache-miss and TLB-miss loads making the worst-case interrupt latency really bad, so a malicious process could hurt the capabilities of a real-time OS.