Article ID: 131323111
Published date: 25 Jul 2017
Last updated: -
Applies to: Generic Interrupt Controller, GIC-400 Generic Interrupt Controller, GIC-500 Generic Interrupt Controller
What are the purpose of the GIC Maintenance Interrupts?
Provide the scenario/s in which the problem might occur.
The GIC Architecture has a mechanism that allows a Hypervisor to programmatically generate Virtual Interrupts (vIRQs) that are sent to the Guest OS running at EL1. This achieved by writing to the List Registers (GICH_LR<n> or ICH_LR<n>_EL2) that are part of the GIC Virtual Interface Control.
Each list register contains information about a single virtual interrupt; including the INTID, Group and priority. If the virtual interrupt maps directly to a hardware interrupt, this mapping is also encoded in the list register. Finally the list register contains a two bit state field that encodes the current state of that interrupt. This can be used to maintain a similar state machine to that used by the physical interrupts and stored in the Active and Pending registers in the GIC Distributor.
The GIC Architecture allows for maintaining individual states for over a 1000 physical interrupts if LPIs are not used, if LPIs are present this number increases dramatically. The GIC architecture allows for up to 16 list registers and typically implementations choose to have less, with four being a common number. Typically fewer interrupts are live at any one time than can be represented as virtual interrupts in the list registers but a scenario cannot be ruled out where there are more live physical interrupts. This can be managed by the Hypervisor maintaining the state of any extra virtual interrupts in memory and swapping their state in and out of the list registers when the Guest OS needs to interact with them through the Virtual CPU interface. The GIC allows the configuration of a number of Maintenance Interrupts that can be signalled to the Hypervisor when certain conditions are met in the List Registers to allow the Hypervisor to manage the list.
Maintenance Interrupt are enabled using the Interrupt Controller Hyp Control Register (ICH_HCR_EL2 or ICH_HCR).
No Pending Interrupt
Only virtual interrupts in the Pending state will cause an exception to be taken, so if there is an abundance of virtual interrupts in is desirable to have those in the Pending state in the List Registers as they can then be signalled to the Guest OS. The GIC can be configured to send an interrupt to the Hypervisor when there are no virtual interrupts in the List Registers in the Pending state. This allows the Hypervisor the opportunity to swap the next highest priority interrupt from memory into the List Registers. Note that even if the list is full of interrupts in the active state this condition will still be met.
Pending virtual interrupts are stored in memory need to be moved into the list registers to generate an exception into the Guest OS and allow them to make progress. In the usual operation of the system another physical interrupt will cause the Hypervisor to re-evaluate the state of its managed virtual interrupts. If another interrupt does not occur in a timely fashion it can stall a virtual interrupt in the Hypervisor's data structure rather than signalling it to the Guest OS. If enabled, the underflow interrupt will signal the Hypervisor when there are less than two non-inactive interrupts in the List Registers.
List Register Entry Not Present
If the virtual interrupt is still resident in the list registers when the Guest OS writes its ID to the End of Interrupt (EOI) register it's state can be automatically updated by the GIC. If it is possible that active virtual IDs are not in the List Registers the Hypervisor can enable this maintenance interrupt which fires when an EOI request is received by the Virtual CPU interface for an ID that is not currently in the list.
The Hyp Control Register also has the ability to send interrupt when the Guest OS enables or disables interrupts.