From: Sascha Bischoff Date: Thu, 19 Mar 2026 15:57:14 +0000 (+0000) Subject: KVM: arm64: gic-v5: Initialise ID and priority bits when resetting vcpu X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a3ca7cf9b31715a63c4dd32f3b6209c3bd744988;p=thirdparty%2Fkernel%2Flinux.git KVM: arm64: gic-v5: Initialise ID and priority bits when resetting vcpu Determine the number of priority bits and ID bits exposed to the guest as part of resetting the vcpu state. These values are presented to the guest by trapping and emulating reads from ICC_IDR0_EL1. GICv5 supports either 16- or 24-bits of ID space (for SPIs and LPIs). It is expected that 2^16 IDs is more than enough, and therefore this value is chosen irrespective of the hardware supporting more or not. The GICv5 architecture only supports 5 bits of priority in the CPU interface (but potentially fewer in the IRS). Therefore, this is the default value chosen for the number of priority bits in the CPU IF. Note: We replicate the way that GICv3 uses the num_id_bits and num_pri_bits variables. That is, num_id_bits stores the value of the hardware field verbatim (0 means 16-bits, 1 would mean 24-bits for GICv5), and num_pri_bits stores the actual number of priority bits; the field value + 1. Signed-off-by: Sascha Bischoff Link: https://patch.msgid.link/20260319154937.3619520-30-sascha.bischoff@arm.com Signed-off-by: Marc Zyngier --- diff --git a/arch/arm64/kvm/vgic/vgic-init.c b/arch/arm64/kvm/vgic/vgic-init.c index 75185651ff64c..fe854cac5272c 100644 --- a/arch/arm64/kvm/vgic/vgic-init.c +++ b/arch/arm64/kvm/vgic/vgic-init.c @@ -398,7 +398,11 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) static void kvm_vgic_vcpu_reset(struct kvm_vcpu *vcpu) { - if (kvm_vgic_global_state.type == VGIC_V2) + const struct vgic_dist *dist = &vcpu->kvm->arch.vgic; + + if (dist->vgic_model == KVM_DEV_TYPE_ARM_VGIC_V5) + vgic_v5_reset(vcpu); + else if (kvm_vgic_global_state.type == VGIC_V2) vgic_v2_reset(vcpu); else vgic_v3_reset(vcpu); diff --git a/arch/arm64/kvm/vgic/vgic-v5.c b/arch/arm64/kvm/vgic/vgic-v5.c index 14e1fad913f06..c263e097786f9 100644 --- a/arch/arm64/kvm/vgic/vgic-v5.c +++ b/arch/arm64/kvm/vgic/vgic-v5.c @@ -87,6 +87,21 @@ int vgic_v5_probe(const struct gic_kvm_info *info) return 0; } +void vgic_v5_reset(struct kvm_vcpu *vcpu) +{ + /* + * We always present 16-bits of ID space to the guest, irrespective of + * the host allowing more. + */ + vcpu->arch.vgic_cpu.num_id_bits = ICC_IDR0_EL1_ID_BITS_16BITS; + + /* + * The GICv5 architeture only supports 5-bits of priority in the + * CPUIF (but potentially fewer in the IRS). + */ + vcpu->arch.vgic_cpu.num_pri_bits = 5; +} + int vgic_v5_init(struct kvm *kvm) { struct kvm_vcpu *vcpu; diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index 0f1986fcd7d0a..9d941241c8a2b 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -364,6 +364,7 @@ void vgic_debug_init(struct kvm *kvm); void vgic_debug_destroy(struct kvm *kvm); int vgic_v5_probe(const struct gic_kvm_info *info); +void vgic_v5_reset(struct kvm_vcpu *vcpu); int vgic_v5_init(struct kvm *kvm); int vgic_v5_map_resources(struct kvm *kvm); void vgic_v5_set_ppi_ops(struct kvm_vcpu *vcpu, u32 vintid);