[PATCH v3 15/36] KVM: arm64: gic-v5: Implement GICv5 load/put and save/restore

Jonathan Cameron jonathan.cameron at huawei.com
Mon Jan 12 07:49:16 PST 2026


On Fri, 9 Jan 2026 17:04:44 +0000
Sascha Bischoff <Sascha.Bischoff at arm.com> 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 <timothy.hayes at arm.com>
> Signed-off-by: Timothy Hayes <timothy.hayes at arm.com>
> Signed-off-by: Sascha Bischoff <sascha.bischoff at arm.com>

Reviewed-by: Jonathan Cameron <jonathan.cameron at huawei.com>

One comment below.

> ---
>  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.


> +		__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;
> +	}
> +






More information about the linux-arm-kernel mailing list