[PATCH v3 4/5] KVM: arm64: vgic: Do not access the GICv5 CPU interface from EL1
Fuad Tabba
fuad.tabba at linux.dev
Mon Oct 12 09:15:23 PDT 2026
can_access_vgic_from_kernel() requires VHE only for the GICv3 system
register interface, so on a native GICv5 system without
FEAT_GCIE_LEGACY it returns true under nVHE. The kernel then saves and
restores the CPU interface from EL1, where ICH_VMCR_EL2 and the
ICH_PPI_* registers are UNDEFINED, and running a vCPU oopses the host.
The nVHE world switch already does that work at EL2.
Anything that requires EL2 system registers or instructions is out of
reach of a kernel running at EL1, which leaves GICv2, the one
memory-mapped CPU interface. Allow GICv2 from EL1 and require VHE for
everything else.
Fixes: 9b8e3d4ca0e73 ("KVM: arm64: gic-v5: Implement GICv5 load/put and save/restore")
Suggested-by: Marc Zyngier <maz at kernel.org>
Reviewed-by: Sascha Bischoff <sascha.bischoff at arm.com>
Signed-off-by: Fuad Tabba <fuad.tabba at linux.dev>
---
arch/arm64/kvm/vgic/vgic.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index b25303d9919fd..fe5b14a8b1214 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -1045,11 +1045,10 @@ static void vgic_flush_lr_state(struct kvm_vcpu *vcpu)
static inline bool can_access_vgic_from_kernel(void)
{
/*
- * GICv2 can always be accessed from the kernel because it is
- * memory-mapped, and VHE systems can access GICv3 EL2 system
- * registers.
+ * GICv2 is memory-mapped. Every other CPU interface uses EL2 system
+ * registers, which only VHE can access from the kernel.
*/
- return !static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif) || has_vhe();
+ return has_vhe() || kvm_vgic_global_state.type == VGIC_V2;
}
static inline void vgic_save_state(struct kvm_vcpu *vcpu)
--
2.39.5
More information about the linux-arm-kernel
mailing list