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 --- arch/arm64/kvm/sys_regs.c | 2 +- arch/arm64/kvm/vgic/vgic-v3.c | 2 +- arch/arm64/kvm/vgic/vgic.h | 17 +++++++++++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index b4e78958ede12..270f1c927c35b 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1982,7 +1982,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); } diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index 386ddf69a9c51..7fc2e0deccff2 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -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 */ diff --git a/arch/arm64/kvm/vgic/vgic.h b/arch/arm64/kvm/vgic/vgic.h index c9b3bb07e483c..0bb8fa10bb4ef 100644 --- a/arch/arm64/kvm/vgic/vgic.h +++ b/arch/arm64/kvm/vgic/vgic.h @@ -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); -- 2.34.1