CPU Interface (Vgicc)
Relevant source files
This document covers the Vgicc struct, which implements the per-CPU interface portion of the virtual Generic Interrupt Controller (GIC). The Vgicc manages CPU-specific interrupt state, list registers for interrupt virtualization, and processor state saving/restoration.
For information about the main VGIC controller that coordinates multiple CPU interfaces, see Virtual GIC Controller (Vgic). For system-wide constants and register layouts, see Constants and Register Layout.
Structure Overview
The Vgicc struct represents a single CPU's interface to the virtual interrupt controller. Each CPU core in the virtualized system has its own Vgicc instance that maintains independent interrupt state and configuration.
Vgicc Struct Layout
flowchart TD
subgraph subGraph3["Vgicc Struct"]
ID["id: u32CPU Identifier"]
subgraph subGraph1["Processor State Registers"]
SAVED_ELSR["saved_elsr0: u32Empty List Status Register"]
SAVED_APR["saved_apr: u32Active Priority Register"]
SAVED_HCR["saved_hcr: u32Hypervisor Control Register"]
end
subgraph subGraph0["List Register Management"]
PENDING_LR["pending_lr: [u32; 512]SPI Pending List Registers"]
SAVED_LR["saved_lr: [u32; 4]Hardware List Register State"]
end
subgraph subGraph2["Interrupt Configuration"]
ISENABLER["isenabler: u32SGI/PPI Enable Bits 0-31"]
PRIORITYR["priorityr: [u8; 32]PPI Priority Configuration"]
end
end
ID --> PENDING_LR
ISENABLER --> PRIORITYR
SAVED_ELSR --> SAVED_LR
SAVED_LR --> PENDING_LR
Sources: src/vgicc.rs(L3 - L14)
Field Categories and Responsibilities
| Category | Fields | Purpose |
|---|---|---|
| CPU Identity | id | Uniquely identifies the CPU core this interface serves |
| List Register State | pending_lr,saved_lr | Manages virtual interrupt injection through hardware list registers |
| Processor Context | saved_elsr0,saved_apr,saved_hcr | Preserves CPU-specific GIC state during VM context switches |
| Interrupt Control | isenabler,priorityr | Configures interrupt enables and priorities for SGIs and PPIs |
Sources: src/vgicc.rs(L4 - L13) src/consts.rs(L1 - L4)
List Register Management
The Vgicc manages two types of list register arrays that are central to ARM GIC virtualization:
Hardware List Registers vs Pending Arrays
flowchart TD
subgraph subGraph2["Interrupt Sources"]
SPI["SPI Interrupts(32-543)"]
PPI_SGI["PPI/SGI Interrupts(0-31)"]
end
subgraph subGraph1["Vgicc State"]
SAVED_LR["saved_lr[4]Hardware LR Backup"]
PENDING_LR["pending_lr[512]SPI Virtual Queue"]
SAVED_ELSR["saved_elsr0Empty LR Status"]
end
subgraph subGraph0["Physical Hardware"]
HW_LR["Physical List Registers(4 registers)"]
end
HW_LR --> SAVED_LR
PENDING_LR --> SAVED_LR
PPI_SGI --> HW_LR
SAVED_LR --> HW_LR
SAVED_LR --> SAVED_ELSR
SPI --> PENDING_LR
Sources: src/vgicc.rs(L5 - L6) src/consts.rs(L3 - L4)
The saved_lr array holds the contents of the 4 physical hardware list registers, while pending_lr provides a much larger virtual queue for SPI interrupts that cannot fit in the limited hardware registers.
Processor State Management
The Vgicc maintains three critical processor state registers that must be preserved across VM context switches:
State Register Functions
flowchart TD
subgraph subGraph2["Hardware Registers"]
HW_HCR["Physical GICH_HCR"]
HW_APR["Physical GICH_APR"]
HW_ELSR["Physical GICH_ELSR"]
end
subgraph subGraph1["Vgicc State Preservation"]
HCR["saved_hcrHypervisor Control• Virtual IRQ/FIQ enables• List register usage"]
APR["saved_aprActive Priority• Currently active interrupt priority• Priority grouping config"]
ELSR["saved_elsr0Empty List Status• Which LRs are available• Hardware resource tracking"]
end
subgraph subGraph0["VM Context Switch"]
VM_EXIT["VM Exit"]
VM_ENTRY["VM Entry"]
end
APR --> HW_APR
APR --> VM_ENTRY
ELSR --> HW_ELSR
ELSR --> VM_ENTRY
HCR --> HW_HCR
HCR --> VM_ENTRY
VM_EXIT --> APR
VM_EXIT --> ELSR
VM_EXIT --> HCR
Sources: src/vgicc.rs(L8 - L10)
Interrupt Configuration State
The Vgicc maintains per-CPU interrupt configuration for Software Generated Interrupts (SGIs) and Private Peripheral Interrupts (PPIs):
SGI and PPI Management
flowchart TD
subgraph subGraph2["Per-bit Mapping"]
BIT0["Bit 0: SGI 0"]
BIT15["Bit 15: SGI 15"]
BIT16["Bit 16: PPI 16"]
BIT31["Bit 31: PPI 31"]
end
subgraph subGraph1["Vgicc Configuration"]
ISENABLER["isenabler: u3232-bit enable maskOne bit per interrupt 0-31"]
PRIORITYR["priorityr: [u8; 32]8-bit priority per PPIIndices 0-31 for PPI IDs 0-31"]
end
subgraph subGraph0["Interrupt ID Space"]
SGI["SGI IDs 0-15Software Generated"]
PPI["PPI IDs 16-31Private Peripheral"]
end
ISENABLER --> BIT0
ISENABLER --> BIT15
ISENABLER --> BIT16
ISENABLER --> BIT31
PPI --> ISENABLER
PPI --> PRIORITYR
SGI --> ISENABLER
Sources: src/vgicc.rs(L12 - L13) src/consts.rs(L1 - L2)
The isenabler field uses individual bits to track enable/disable state for each of the 32 SGI and PPI interrupts, while priorityr stores 8-bit priority values specifically for the 32 PPI interrupts.
Integration with VGIC System
The Vgicc operates as part of the larger VGIC virtualization system:
System Integration Flow
flowchart TD
subgraph subGraph2["Physical Hardware"]
PHYSICAL_GIC["arm_gicv2Physical GIC Driver"]
HW_CPU_IF["Hardware CPUInterface Registers"]
end
subgraph subGraph1["VGIC System"]
VGIC_MAIN["Vgic Controller(Main coordinator)"]
VGICC_INSTANCES["Multiple Vgicc(Per-CPU instances)"]
end
subgraph subGraph0["Guest VM"]
GUEST["Guest OSInterrupt Operations"]
end
GUEST --> VGIC_MAIN
PHYSICAL_GIC --> HW_CPU_IF
VGICC_INSTANCES --> HW_CPU_IF
VGICC_INSTANCES --> PHYSICAL_GIC
VGIC_MAIN --> VGICC_INSTANCES
Sources: src/vgicc.rs(L1 - L14)
Each Vgicc instance manages the virtualization state for one CPU core, coordinating with the main Vgic controller to provide a complete virtual interrupt controller implementation to guest operating systems.