Interrupts
In a QNX hypervisor system, guests configure their virtual Progammable Interrupt Controllers (PICs), and the hypervisor manages interrupts in accordance with these configurations.
The hypervisor host must intervene to manage any interrupts asserted by the hardware, regardless of whose action triggered the interrupt or who owns the device asserting the interrupt, or of the interrupt's ultimate destination. This means that a guest exit is required so that the hypervisor can look after identifying the interrupt's destination, do any required processing, and pass the interrupt along to its destination.
For information about how to reduce the overhead required to handle interrupts in a
hypervisor system, see the Performance Tuning
chapter.
Interrupts for the hypervisor host
Interrupts destined only for the hypervisor host include interrupts from devices
owned by the hypervisor, and IPIs between physical CPUs. These interrupts are
handled by the QNX OS microkernel interrupt-handling
mechanisms, just like interrupts in a non-virtualized QNX OS (see Interrupts
in Getting Started
with the QNX OS). There is nothing you need to do with these interrupts
that is specific to a hypervisor system.
Interrupts for guests
Handling of interrupts destined for guests is shared between the microkernel (procnto) and the VMs (qvm process instances) hosting the guests.
The microkernel does the following steps:
- Save the context of the interrupted guest
- Identify the interrupt (using PIC-specific callouts)
- Mask the interrupt (using PIC-specific callouts)
- Inform the relevant qvm process instance that the interrupt is available for passing on to the guest
The relevant qvm process instance does the following steps:
- Deliver a virtual interrupt to the guest (may use PIC-specific hardware assist routines if these are available)
- Detect that the guest has handled the interrupt
- Unmask the interrupt (see InterruptUnmask() in the QNX OS C Library Reference).
The qvm process doesn't unmask interrupts until the guest has looked after them. This design ensures that if a guest makes an error when handling an interrupt, the error can't affect the hypervisor itself or other guests. In short, the hypervisor is protected from an interrupt storm caused by a guest error.
However, the hypervisor can't protect a guest from itself. If a guest doesn't clear an interrupt condition properly, or if the interrupt rate is too high, the guest will spend its time in its own interrupt-handling code and will not be able to run user threads on the vCPU. This behavior is exactly what would occur if the guest were running in a non-virtualized environment.
Interrupt priorities and destinations
Guest OSs configure their own interrupt priorities and destinations, just as they
would if they were running in a non-virtualized environment. The hypervisor presents
a virtual GIC (ARM) or APIC (x86) in the VM hosting the guest (see vdev gic and vdev ioapic
in the Virtual Device Reference
chapter).
To the guest these virtual interrupt controllers are indistinguishable from hardware GICs or APICs. The hypervisor delivers interrupts to the vCPUs according to the priorities and to the destinations configured by the guest. For example, a QNX guest expects interrupts to go to physical CPU 0, so the hypervisor delivers the interrupt to vCPU 0 in the VM hosting the guest.
Interrupts during startup and shutdown
The qvm process instance hosting a guest masks interrupts destined for that guest until the guest has successfully started, and started the appropriate device drivers. Similarly, when a guest begins its shutdown procedure, the hosting qvm process instance masks interrupts intended for that guest.