| From 5163373af195f10e0d99a8de3465c4ed36bdc337 Mon Sep 17 00:00:00 2001 |
| From: Marc Zyngier <maz@kernel.org> |
| Date: Tue, 3 May 2022 22:14:24 +0100 |
| Subject: KVM: arm64: vgic-v3: Consistently populate ID_AA64PFR0_EL1.GIC |
| |
| From: Marc Zyngier <maz@kernel.org> |
| |
| commit 5163373af195f10e0d99a8de3465c4ed36bdc337 upstream. |
| |
| When adding support for the slightly wonky Apple M1, we had to |
| populate ID_AA64PFR0_EL1.GIC==1 to present something to the guest, |
| as the HW itself doesn't advertise the feature. |
| |
| However, we gated this on the in-kernel irqchip being created. |
| This causes some trouble for QEMU, which snapshots the state of |
| the registers before creating a virtual GIC, and then tries to |
| restore these registers once the GIC has been created. Obviously, |
| between the two stages, ID_AA64PFR0_EL1.GIC has changed value, |
| and the write fails. |
| |
| The fix is to actually emulate the HW, and always populate the |
| field if the HW is capable of it. |
| |
| Fixes: 562e530fd770 ("KVM: arm64: Force ID_AA64PFR0_EL1.GIC=1 when exposing a virtual GICv3") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Marc Zyngier <maz@kernel.org> |
| Reported-by: Peter Maydell <peter.maydell@linaro.org> |
| Reviewed-by: Oliver Upton <oupton@google.com> |
| Link: https://lore.kernel.org/r/20220503211424.3375263-1-maz@kernel.org |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/arm64/kvm/sys_regs.c | 3 +-- |
| 1 file changed, 1 insertion(+), 2 deletions(-) |
| |
| --- a/arch/arm64/kvm/sys_regs.c |
| +++ b/arch/arm64/kvm/sys_regs.c |
| @@ -1080,8 +1080,7 @@ static u64 read_id_reg(const struct kvm_ |
| val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV2), (u64)vcpu->kvm->arch.pfr0_csv2); |
| val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3); |
| val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_CSV3), (u64)vcpu->kvm->arch.pfr0_csv3); |
| - if (irqchip_in_kernel(vcpu->kvm) && |
| - vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { |
| + if (kvm_vgic_global_state.type == VGIC_V3) { |
| val &= ~ARM64_FEATURE_MASK(ID_AA64PFR0_GIC); |
| val |= FIELD_PREP(ARM64_FEATURE_MASK(ID_AA64PFR0_GIC), 1); |
| } |