Interrupts
An interrupt is a small write.
A device raises an interrupt with an MSI or MSI-X: an ordinary memory write to a reserved address range. The IOMMU catches it, looks the device up and rewrites it using a table the OS owns. For a virtual machine, AVIC (Advanced Virtual Interrupt Controller) can pass it on to a running guest (what the CPU then does is in the AMD64 APM Vol. 2). Scroll to follow one.
Pinch or double-tap the drawing to zoom, two fingers to move. Schematic: routes and positions are drawn for clarity; entry values are examples.
Schematic: routes and positions are drawn for clarity. Entry values are examples.
Spec citations
AMD I/O Virtualization Technology (IOMMU) Specification, 48882 rev 3.11 (page numbers are the printed ones). Anything marked "APM Vol. 2" is not in this spec.
- 2.2.5.1, Figure 15, Table 20, p91-92: the IRTE 32-bit, used when guest virtual APIC is not enabled.
- 2.2.5.2, p92-94, and Table 21, p93: which MMIO bits (GASup, GAMSup, GAEn, GAMEn) pick the IRTE 32-bit or IRTE 128-bit and its Table. The processing steps are on p94. The IRTE fields not cached by the IOMMU are on p93. The command INVALIDATE_INTERRUPT_TABLE is 2.4.5, p131.
- Figure 17 and Table 22, p95-96: IRTE 128-bit with GuestMode=0. Step 7, p94: RemapEn=0 is reported as IO_PAGE_FAULT.
- Figure 18 and Table 23, p96-97: IRTE 128-bit with GuestMode=1 (IsRun, GALogIntr, GATag, Destination). The vIRR bit arithmetic and the doorbell are in the steps on p94.
- 2.2.5.3, p97, and Figures 19-20, p98: x2APIC (XTSup, XTEn, GAEn) and the 32-bit Destination. MMIO 0018h[XTEn] is on p218, [GAIntEn] and [GALogEn] on p219, [GAEn] on p220.
- 2.2.5.4, p99: GAPPI, the optional alternative to the GA Log for non-running guests.
- 2.7, p186-190: GA Log, when it is written, the tail pointer, GAInt and GAIntEn (MSI number MsiNumGA), and the full-log rule. 2.7.3, Figure 79, Table 76, p190-191: the GA_GUEST_NR entry. 2.7.4, p191: restart after overflow. MMIO 2020h [GAInt], [GALOverflow], [GALogRun], p255. The MMIO text of [GALOverflow] says no interrupt is generated when it is set; 2.7.1 says the same interrupt signals when the log is written or overflows.
- 2.5.9, Table 64, p161-162: INVALID_DEVICE_REQUEST, Type 101b is a posted write to the Interrupt/EOI range from a device with IntCtl=00b. 2.5.3, Table 44, p145: IO_PAGE_FAULT for an IRTE beyond the end of the table, a non-zero reserved IRTE bit, RemapEn=0 or a reserved IntType. 2.2.5.2, p93: INVALIDATE_INTERRUPT_TABLE is not needed for IRTE[IsRun], [Destination], [GALogIntr], [GAPPIDis] and [GATag] with GuestMode=1.
- What the CPU does with a doorbell (AVIC delivery into the running guest) is in the AMD64 APM Vol. 2, not in this spec.
- Table 3, p51: the interrupt address range FD_F800_0000h to FD_F8FF_FFFFh is controlled by IntCtl and the interrupt remapping tables. Table 19, p90, and the text after it: the MSI data bits 10:0 are the offset into the table, and 512 interrupts per function is the default (2K with NumIntRemapSup and NumIntRemapMode).
- Device Table Entry fields, p65-67 (IV, IntCtl, interrupt table root pointer, IntTabLen), and Table 9, p74-75: IV=1 with IntCtl=10b remaps fixed and arbitrated interrupts, IntCtl=00b target-aborts them.