Re: [PATCH v3 15/36] KVM: arm64: gic-v5: Implement GICv5 load/put and save/restore
From: Jonathan Cameron <jonathan.cameron@huawei.com>
Date: 2026-01-12 15:49:42
Also in:
kvm, kvmarm
On Fri, 9 Jan 2026 17:04:44 +0000 Sascha Bischoff [off-list ref] wrote:
This change introduces GICv5 load/put. Additionally, it plumbs in save/restore for: * PPIs (ICH_PPI_x_EL2 regs) * ICH_VMCR_EL2 * ICH_APR_EL2 * ICC_ICSR_EL1 A GICv5-specific enable bit is added to struct vgic_vmcr as this differs from previous GICs. On GICv5-native systems, the VMCR only contains the enable bit (driven by the guest via ICC_CR0_EL1.EN) and the priority mask (PCR). A struct gicv5_vpe is also introduced. This currently only contains a single field - bool resident - which is used to track if a VPE is currently running or not, and is used to avoid a case of double load or double put on the WFI path for a vCPU. This struct will be extended as additional GICv5 support is merged, specifically for VPE doorbells. Co-authored-by: Timothy Hayes [off-list ref] Signed-off-by: Timothy Hayes <redacted> Signed-off-by: Sascha Bischoff <redacted>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> One comment below.
quoted hunk ↗ jump to hunk
--- arch/arm64/kvm/hyp/nvhe/switch.c | 12 +++++ arch/arm64/kvm/vgic/vgic-mmio.c | 28 +++++++---- arch/arm64/kvm/vgic/vgic-v5.c | 74 ++++++++++++++++++++++++++++++ arch/arm64/kvm/vgic/vgic.c | 32 ++++++++----- arch/arm64/kvm/vgic/vgic.h | 7 +++ include/kvm/arm_vgic.h | 2 + include/linux/irqchip/arm-gic-v5.h | 5 ++ 7 files changed, 141 insertions(+), 19 deletions(-)diff --git a/arch/arm64/kvm/hyp/nvhe/switch.c b/arch/arm64/kvm/hyp/nvhe/switch.c index c23e22ffac080..bc446a5d94d68 100644 --- a/arch/arm64/kvm/hyp/nvhe/switch.c +++ b/arch/arm64/kvm/hyp/nvhe/switch.c@@ -113,6 +113,12 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu) /* Save VGICv3 state on non-VHE systems */ static void __hyp_vgic_save_state(struct kvm_vcpu *vcpu) { + if (kern_hyp_va(vcpu->kvm)->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V5) {
Why can't you use the helper? e.g
if (vgic_is_v5(kern_hyp_va(vcpu->kvm))) {
Whilst kvm/arm_vgic.h isn't directly included here other stuff from that header
is in use like kvm_vgic_global_state.
quoted hunk ↗ jump to hunk
+ __vgic_v5_save_state(&vcpu->arch.vgic_cpu.vgic_v5); + __vgic_v5_save_ppi_state(&vcpu->arch.vgic_cpu.vgic_v5); + return; + } + if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif)) { __vgic_v3_save_state(&vcpu->arch.vgic_cpu.vgic_v3); __vgic_v3_deactivate_traps(&vcpu->arch.vgic_cpu.vgic_v3);@@ -122,6 +128,12 @@ static void __hyp_vgic_save_state(struct kvm_vcpu *vcpu) /* Restore VGICv3 state on non-VHE systems */ static void __hyp_vgic_restore_state(struct kvm_vcpu *vcpu) { + if (kern_hyp_va(vcpu->kvm)->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V5) { + __vgic_v5_restore_state(&vcpu->arch.vgic_cpu.vgic_v5); + __vgic_v5_restore_ppi_state(&vcpu->arch.vgic_cpu.vgic_v5); + return; + } +