]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: vgic: Rework vgic_is_v3() and add vgic_host_has_gicvX()
authorSascha Bischoff <Sascha.Bischoff@arm.com>
Thu, 19 Mar 2026 15:50:13 +0000 (15:50 +0000)
committerMarc Zyngier <maz@kernel.org>
Thu, 19 Mar 2026 16:25:55 +0000 (16:25 +0000)
The GIC version checks used to determine host capabilities and guest
configuration have become somewhat conflated (in part due to the
addition of GICv5 support). vgic_is_v3() is a prime example, which
prior to this change has been a combination of guest configuration and
host cabability.

Split out the host capability check from vgic_is_v3(), which now only
checks if the vgic model itself is GICv3. Add two new functions:
vgic_host_has_gicv3() and vgic_host_has_gicv5(). These explicitly
check the host capabilities, i.e., can the host system run a GICvX
guest or not.

The vgic_is_v3() check in vcpu_set_ich_hcr() has been replaced with
vgic_host_has_gicv3() as this only applies on GICv3-capable hardware,
and isn't strictly only applicable for a GICv3 guest (it is actually
vital for vGICv2 on GICv3 hosts).

Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
Link: https://patch.msgid.link/20260319154937.3619520-3-sascha.bischoff@arm.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/kvm/sys_regs.c
arch/arm64/kvm/vgic/vgic-v3.c
arch/arm64/kvm/vgic/vgic.h

index 4b9f4e5d946b1e31471df200f220b32ebe25b93a..0acd10e50aaba3e3e900dc6df42b747ddf9a0574 100644 (file)
@@ -1985,7 +1985,7 @@ static u64 sanitise_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
                val |= SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, CSV3, IMP);
        }
 
-       if (vgic_is_v3(vcpu->kvm)) {
+       if (vgic_host_has_gicv3()) {
                val &= ~ID_AA64PFR0_EL1_GIC_MASK;
                val |= SYS_FIELD_PREP_ENUM(ID_AA64PFR0_EL1, GIC, IMP);
        }
index 6a355eca19348376010b88b709faf8bd76d04ec5..9e841e7afd4a76f54e8efe1bf5722cf3fa04108f 100644 (file)
@@ -499,7 +499,7 @@ void vcpu_set_ich_hcr(struct kvm_vcpu *vcpu)
 {
        struct vgic_v3_cpu_if *vgic_v3 = &vcpu->arch.vgic_cpu.vgic_v3;
 
-       if (!vgic_is_v3(vcpu->kvm))
+       if (!vgic_host_has_gicv3())
                return;
 
        /* Hide GICv3 sysreg if necessary */
index c9b3bb07e483c115ba987ab63e91ee4b12599fb6..0bb8fa10bb4eff758edb16ec503bfd5817373853 100644 (file)
@@ -454,15 +454,24 @@ void vgic_v3_put_nested(struct kvm_vcpu *vcpu);
 void vgic_v3_handle_nested_maint_irq(struct kvm_vcpu *vcpu);
 void vgic_v3_nested_update_mi(struct kvm_vcpu *vcpu);
 
-static inline bool vgic_is_v3_compat(struct kvm *kvm)
+static inline bool vgic_is_v3(struct kvm *kvm)
+{
+       return kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3;
+}
+
+static inline bool vgic_host_has_gicv3(void)
 {
-       return cpus_have_final_cap(ARM64_HAS_GICV5_CPUIF) &&
+       /*
+        * Either the host is a native GICv3, or it is GICv5 with
+        * FEAT_GCIE_LEGACY.
+        */
+       return kvm_vgic_global_state.type == VGIC_V3 ||
                kvm_vgic_global_state.has_gcie_v3_compat;
 }
 
-static inline bool vgic_is_v3(struct kvm *kvm)
+static inline bool vgic_host_has_gicv5(void)
 {
-       return kvm_vgic_global_state.type == VGIC_V3 || vgic_is_v3_compat(kvm);
+       return kvm_vgic_global_state.type == VGIC_V5;
 }
 
 int vgic_its_debug_init(struct kvm_device *dev);