1*bb4ee6a4SAndroid Build Coastguard Worker# Interrupts (x86_64) 2*bb4ee6a4SAndroid Build Coastguard Worker 3*bb4ee6a4SAndroid Build Coastguard WorkerInterrupts are how devices request service from the guest drivers. This page explores the details of 4*bb4ee6a4SAndroid Build Coastguard Workerinterrupt routing from the perspective of CrosVM. 5*bb4ee6a4SAndroid Build Coastguard Worker 6*bb4ee6a4SAndroid Build Coastguard Worker## Critical acronyms 7*bb4ee6a4SAndroid Build Coastguard Worker 8*bb4ee6a4SAndroid Build Coastguard WorkerThis subject area uses *a lot* of acronyms: 9*bb4ee6a4SAndroid Build Coastguard Worker 10*bb4ee6a4SAndroid Build Coastguard Worker- IRQ: Interrupt ReQuest 11*bb4ee6a4SAndroid Build Coastguard Worker- ISR: Interrupt Service Routine 12*bb4ee6a4SAndroid Build Coastguard Worker- EOI: End Of Interrupt 13*bb4ee6a4SAndroid Build Coastguard Worker- MSI: message signaled interrupts. In this document, synonymous with MSI-X. 14*bb4ee6a4SAndroid Build Coastguard Worker- MSI-X: message signaled interrupts - extended 15*bb4ee6a4SAndroid Build Coastguard Worker- LAPIC: local APIC 16*bb4ee6a4SAndroid Build Coastguard Worker- APIC: Advanced Programmable Interrupt Controller (successor to the legacy PIC) 17*bb4ee6a4SAndroid Build Coastguard Worker- IOAPIC: IO APIC (has physical interrupt lines, which it responds to by triggering an MSI directed 18*bb4ee6a4SAndroid Build Coastguard Worker to the LAPIC). 19*bb4ee6a4SAndroid Build Coastguard Worker- PIC: Programmable Interrupt Controller (the "legacy PIC" / Intel 8259 chip). 20*bb4ee6a4SAndroid Build Coastguard Worker 21*bb4ee6a4SAndroid Build Coastguard Worker## Interrupts come in two flavors 22*bb4ee6a4SAndroid Build Coastguard Worker 23*bb4ee6a4SAndroid Build Coastguard WorkerInterrupts on `x86_64` in CrosVM come in two primary flavors: legacy and MSI-X. In this document, 24*bb4ee6a4SAndroid Build Coastguard WorkerMSI is used to refer to the concept of message signaled interrupts, but it always refers to 25*bb4ee6a4SAndroid Build Coastguard Workerinterrupts sent via MSI-X because that is what CrosVM uses. 26*bb4ee6a4SAndroid Build Coastguard Worker 27*bb4ee6a4SAndroid Build Coastguard Worker### Legacy interrupts (INTx) 28*bb4ee6a4SAndroid Build Coastguard Worker 29*bb4ee6a4SAndroid Build Coastguard WorkerThese interrupts are traditionally delivered via dedicated signal lines to PICs and/or the IOAPIC. 30*bb4ee6a4SAndroid Build Coastguard WorkerOlder devices, especially those that are used during early boot, often rely on these types of 31*bb4ee6a4SAndroid Build Coastguard Workerinterrupts. These typically are the first 24 GSIs, and are serviced either by the PIC (during very 32*bb4ee6a4SAndroid Build Coastguard Workerearly boot), or by the IOAPIC (after it is activated & the PIC is switched off). 33*bb4ee6a4SAndroid Build Coastguard Worker 34*bb4ee6a4SAndroid Build Coastguard Worker#### Background on EOI 35*bb4ee6a4SAndroid Build Coastguard Worker 36*bb4ee6a4SAndroid Build Coastguard WorkerThe purpose of EOI is rooted in how legacy interrupt lines are shared. If two devices `D1` and `D2` 37*bb4ee6a4SAndroid Build Coastguard Workershare a line `L`, `D2` has no guarantee that it will be serviced when `L` is asserted. After 38*bb4ee6a4SAndroid Build Coastguard Workerreceiving EOI, `D2` has to check whether it was serviced, and if it was not, to re-assert `L`. An 39*bb4ee6a4SAndroid Build Coastguard Workerexample of how this occurs is if `D2` requests service while `D1` is already being serviced. In that 40*bb4ee6a4SAndroid Build Coastguard Workercase, the line has to be reasserted otherwise `D2` won't be serviced. 41*bb4ee6a4SAndroid Build Coastguard Worker 42*bb4ee6a4SAndroid Build Coastguard WorkerBecause interrupt lines to the IOAPIC can be shared by multiple devices, EOI is critical for devices 43*bb4ee6a4SAndroid Build Coastguard Workerto figure out whether they were serviced in response to sending the IRQ, or whether the IRQ needs to 44*bb4ee6a4SAndroid Build Coastguard Workerbe resent. The operating principles mean that sending extra EOIs to a legacy device is perfectly 45*bb4ee6a4SAndroid Build Coastguard Workersafe, because they could be due to another device on the same line receiving service, and so devices 46*bb4ee6a4SAndroid Build Coastguard Workermust be tolerant of such "extra" (from their perspective) EOIs. 47*bb4ee6a4SAndroid Build Coastguard Worker 48*bb4ee6a4SAndroid Build Coastguard WorkerThese "extra" EOIs come from the fact that EOI is often a broadcast message that goes to all legacy 49*bb4ee6a4SAndroid Build Coastguard Workerdevices. Broadcast is required because interrupt lines can be routed through the two 8259 PICs via 50*bb4ee6a4SAndroid Build Coastguard Workercascade before they reach the CPU, broadcast to both PICs (and attached devices) is the only way to 51*bb4ee6a4SAndroid Build Coastguard Workerensure EOI reaches the device that was serviced. 52*bb4ee6a4SAndroid Build Coastguard Worker 53*bb4ee6a4SAndroid Build Coastguard Worker#### EOI in CrosVM 54*bb4ee6a4SAndroid Build Coastguard Worker 55*bb4ee6a4SAndroid Build Coastguard WorkerWhen the guest's ISR completes and signals EOI, the CrosVM irqchip implementation is responsible for 56*bb4ee6a4SAndroid Build Coastguard Workerpropagating EOI to the device backends. EOI is delivered to the devices via their 57*bb4ee6a4SAndroid Build Coastguard Worker[resample event](https://crosvm.dev/doc/devices/struct.IrqLevelEvent.html). Devices are then 58*bb4ee6a4SAndroid Build Coastguard Workerresponsible for listening to that resample event, and checking their internal state to see if they 59*bb4ee6a4SAndroid Build Coastguard Workerreceived service. If the device wasn't serviced, it must then reassert the IRQ. 60*bb4ee6a4SAndroid Build Coastguard Worker 61*bb4ee6a4SAndroid Build Coastguard Worker### MSIs 62*bb4ee6a4SAndroid Build Coastguard Worker 63*bb4ee6a4SAndroid Build Coastguard WorkerMSIs do not use dedicated signal lines; instead, they are "messages" which are sent on the system 64*bb4ee6a4SAndroid Build Coastguard Workerbus. The LAPIC(s) receive these messages, and inject the interrupt into the VCPU (where injection 65*bb4ee6a4SAndroid Build Coastguard Workermeans: jump to ISR). 66*bb4ee6a4SAndroid Build Coastguard Worker 67*bb4ee6a4SAndroid Build Coastguard Worker#### About EOI 68*bb4ee6a4SAndroid Build Coastguard Worker 69*bb4ee6a4SAndroid Build Coastguard WorkerEOI is not meaningful for MSIs because lines are *never* shared. No devices using MSI will listen 70*bb4ee6a4SAndroid Build Coastguard Workerfor the EOI event, and the irqchip will not signal it. 71*bb4ee6a4SAndroid Build Coastguard Worker 72*bb4ee6a4SAndroid Build Coastguard Worker## The fundamental deception on x86_64: there are no legacy interrupts (usually) 73*bb4ee6a4SAndroid Build Coastguard Worker 74*bb4ee6a4SAndroid Build Coastguard WorkerAfter very early boot, the PIC is switched off and legacy interrupts somewhat cease to be legacy. 75*bb4ee6a4SAndroid Build Coastguard WorkerInstead of being handled by the PIC, legacy interrupts are handled by the IOAPIC, and all the IOAPIC 76*bb4ee6a4SAndroid Build Coastguard Workerdoes is convert them into MSIs; in other words, from the perspective of CrosVM & the guest VCPUs, 77*bb4ee6a4SAndroid Build Coastguard Workerafter early boot, every interrupt is a MSI. 78*bb4ee6a4SAndroid Build Coastguard Worker 79*bb4ee6a4SAndroid Build Coastguard Worker## Interrupt handling irqchip specifics 80*bb4ee6a4SAndroid Build Coastguard Worker 81*bb4ee6a4SAndroid Build Coastguard WorkerEach `IrqChip` can handle interrupts differently. Often these differences are because the underlying 82*bb4ee6a4SAndroid Build Coastguard Workerhypervisors will have different interrupt features such as KVM's irqfds. Generally a hypervisor has 83*bb4ee6a4SAndroid Build Coastguard Workerthree choices for implementing an irqchip: 84*bb4ee6a4SAndroid Build Coastguard Worker 85*bb4ee6a4SAndroid Build Coastguard Worker- Fully in kernel: all of the irqchip (LAPIC & IOAPIC) are implemented in the kernel portion of the 86*bb4ee6a4SAndroid Build Coastguard Worker hypervisor. 87*bb4ee6a4SAndroid Build Coastguard Worker- Split: the performance critical part of the irqchip (LAPIC) is implemented in the kernel, but the 88*bb4ee6a4SAndroid Build Coastguard Worker IOAPIC is implemented by the VMM. 89*bb4ee6a4SAndroid Build Coastguard Worker- Userspace: here, the entire irqchip is implemented in the VMM. This is generally slower and not 90*bb4ee6a4SAndroid Build Coastguard Worker commonly used. 91*bb4ee6a4SAndroid Build Coastguard Worker 92*bb4ee6a4SAndroid Build Coastguard WorkerBelow, we describe the rough flow for interrupts in virtio devices for each of the chip types. We 93*bb4ee6a4SAndroid Build Coastguard Workerlimit ourselves to virtio devices becauseas these are the performance critical devices in CrosVM. 94*bb4ee6a4SAndroid Build Coastguard Worker 95*bb4ee6a4SAndroid Build Coastguard Worker### Kernel mode IRQ chip (w/ irqfd support) 96*bb4ee6a4SAndroid Build Coastguard Worker 97*bb4ee6a4SAndroid Build Coastguard Worker#### MSIs 98*bb4ee6a4SAndroid Build Coastguard Worker 99*bb4ee6a4SAndroid Build Coastguard Worker1. Device wants service, so it signals an `Event` object. 100*bb4ee6a4SAndroid Build Coastguard Worker1. The `Event` object is registered with the hypervisor, so the hypervisor immediately routes the 101*bb4ee6a4SAndroid Build Coastguard Worker IRQ to a LAPIC so a VCPU can be interrupted. 102*bb4ee6a4SAndroid Build Coastguard Worker1. The LAPIC interrupts the VCPU, which jumps to the kernel's ISR (interrupt service routine). 103*bb4ee6a4SAndroid Build Coastguard Worker1. The ISR runs. 104*bb4ee6a4SAndroid Build Coastguard Worker 105*bb4ee6a4SAndroid Build Coastguard Worker#### Legacy interrupts 106*bb4ee6a4SAndroid Build Coastguard Worker 107*bb4ee6a4SAndroid Build Coastguard WorkerThese are handled similarly to MSIs, except the kernel mode IOAPIC is what initially picks up the 108*bb4ee6a4SAndroid Build Coastguard Workerevent, rather than the LAPIC. 109*bb4ee6a4SAndroid Build Coastguard Worker 110*bb4ee6a4SAndroid Build Coastguard Worker### Split IRQ chip (w/ irqfd support) 111*bb4ee6a4SAndroid Build Coastguard Worker 112*bb4ee6a4SAndroid Build Coastguard WorkerThis is the same as the kernel mode case. 113*bb4ee6a4SAndroid Build Coastguard Worker 114*bb4ee6a4SAndroid Build Coastguard Worker### Split IRQ chip (no irqfd kernel support) 115*bb4ee6a4SAndroid Build Coastguard Worker 116*bb4ee6a4SAndroid Build Coastguard Worker#### MSIs 117*bb4ee6a4SAndroid Build Coastguard Worker 118*bb4ee6a4SAndroid Build Coastguard Worker1. Device wants service, so it signals an `Event` object. 119*bb4ee6a4SAndroid Build Coastguard Worker1. The `Event`object is attached to the IrqChip in CrosVM. An interrupt handling thread wakes up 120*bb4ee6a4SAndroid Build Coastguard Worker from the `Event` signal. 121*bb4ee6a4SAndroid Build Coastguard Worker1. The IrqChip resets the `Event`. 122*bb4ee6a4SAndroid Build Coastguard Worker1. The IrqChip asserts the interrupt to the LAPIC in the kernel via an ioctl (or equivalent). 123*bb4ee6a4SAndroid Build Coastguard Worker1. The LAPIC interrupts the VCPU, which jumps to the kernel’s ISR (interrupt service routine). 124*bb4ee6a4SAndroid Build Coastguard Worker1. The ISR runs, and on completion sends EOI (end of interrupt). In CrosVM, this is called the 125*bb4ee6a4SAndroid Build Coastguard Worker [resample event](https://crosvm.dev/doc/devices/struct.IrqLevelEvent.html). 126*bb4ee6a4SAndroid Build Coastguard Worker1. EOI is sent. 127*bb4ee6a4SAndroid Build Coastguard Worker 128*bb4ee6a4SAndroid Build Coastguard Worker#### Legacy interrupts 129*bb4ee6a4SAndroid Build Coastguard Worker 130*bb4ee6a4SAndroid Build Coastguard WorkerThis introduces an additional `Event` object in the interrupt path, since the IRQ pin itself is an 131*bb4ee6a4SAndroid Build Coastguard Worker`Event`, and the MSI is also an `Event`. These interrupts are processed twice by the IRQ handler: 132*bb4ee6a4SAndroid Build Coastguard Workeronce as a legacy IOAPIC event, and a second time as an MSI. 133*bb4ee6a4SAndroid Build Coastguard Worker 134*bb4ee6a4SAndroid Build Coastguard Worker### Userspace IRQ chip 135*bb4ee6a4SAndroid Build Coastguard Worker 136*bb4ee6a4SAndroid Build Coastguard WorkerThis chip is not widely used in production. Contributions to fill in this section are welcome. 137