Backport 2 patches that are required on ARM64 platforms having firmware wrongly advertising GICv2 compatibility.
Patch 1 has nvhe related conflict resolution while patch 2 is cleanly applied.
Tested on HiSilicon D06 platform.
Marc Zyngier (2): KVM: arm64: Rename __vgic_v3_get_ich_vtr_el2() to __vgic_v3_get_gic_config() KVM: arm64: Workaround firmware wrongly advertising GICv2-on-v3 compatibility
arch/arm64/include/asm/kvm_asm.h | 4 +-- arch/arm64/kvm/hyp/nvhe/hyp-main.c | 4 +-- arch/arm64/kvm/hyp/vgic-v3-sr.c | 40 ++++++++++++++++++++++++++++-- arch/arm64/kvm/vgic/vgic-v3.c | 12 ++++++--- 4 files changed, 51 insertions(+), 9 deletions(-)
From: Marc Zyngier maz@kernel.org
commit b9d699e2694d032aa8ecc15141f698ccb050dc95 upstream.
As we are about to report a bit more information to the rest of the kernel, rename __vgic_v3_get_ich_vtr_el2() to the more explicit __vgic_v3_get_gic_config().
No functional change.
Cc: stable@vger.kernel.org #5.10 Tested-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com Signed-off-by: Marc Zyngier maz@kernel.org Message-Id: 20210305185254.3730990-7-maz@kernel.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com [Shameer: Back ported to 5.10] Signed-off-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com --- arch/arm64/include/asm/kvm_asm.h | 4 ++-- arch/arm64/kvm/hyp/nvhe/hyp-main.c | 4 ++-- arch/arm64/kvm/hyp/vgic-v3-sr.c | 7 ++++++- arch/arm64/kvm/vgic/vgic-v3.c | 4 +++- 4 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h index 54387ccd1ab2..21de2d632f97 100644 --- a/arch/arm64/include/asm/kvm_asm.h +++ b/arch/arm64/include/asm/kvm_asm.h @@ -52,7 +52,7 @@ #define __KVM_HOST_SMCCC_FUNC___kvm_tlb_flush_local_vmid 5 #define __KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff 6 #define __KVM_HOST_SMCCC_FUNC___kvm_enable_ssbs 7 -#define __KVM_HOST_SMCCC_FUNC___vgic_v3_get_ich_vtr_el2 8 +#define __KVM_HOST_SMCCC_FUNC___vgic_v3_get_gic_config 8 #define __KVM_HOST_SMCCC_FUNC___vgic_v3_read_vmcr 9 #define __KVM_HOST_SMCCC_FUNC___vgic_v3_write_vmcr 10 #define __KVM_HOST_SMCCC_FUNC___vgic_v3_init_lrs 11 @@ -191,7 +191,7 @@ extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
extern void __kvm_enable_ssbs(void);
-extern u64 __vgic_v3_get_ich_vtr_el2(void); +extern u64 __vgic_v3_get_gic_config(void); extern u64 __vgic_v3_read_vmcr(void); extern void __vgic_v3_write_vmcr(u32 vmcr); extern void __vgic_v3_init_lrs(void); diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c index e2eafe2c93af..1e09d0052bf3 100644 --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c @@ -62,8 +62,8 @@ static void handle_host_hcall(unsigned long func_id, case KVM_HOST_SMCCC_FUNC(__kvm_enable_ssbs): __kvm_enable_ssbs(); break; - case KVM_HOST_SMCCC_FUNC(__vgic_v3_get_ich_vtr_el2): - ret = __vgic_v3_get_ich_vtr_el2(); + case KVM_HOST_SMCCC_FUNC(__vgic_v3_get_gic_config): + ret = __vgic_v3_get_gic_config(); break; case KVM_HOST_SMCCC_FUNC(__vgic_v3_read_vmcr): ret = __vgic_v3_read_vmcr(); diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c index 452f4cacd674..54ce4048d7d1 100644 --- a/arch/arm64/kvm/hyp/vgic-v3-sr.c +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c @@ -403,7 +403,12 @@ void __vgic_v3_init_lrs(void) __gic_v3_set_lr(0, i); }
-u64 __vgic_v3_get_ich_vtr_el2(void) +/* + * Return the GIC CPU configuration: + * - [31:0] ICH_VTR_EL2 + * - [63:32] RES0 + */ +u64 __vgic_v3_get_gic_config(void) { return read_gicreg(ICH_VTR_EL2); } diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index 9cdf39a94a63..8e7bf3151057 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -583,9 +583,11 @@ early_param("kvm-arm.vgic_v4_enable", early_gicv4_enable); */ int vgic_v3_probe(const struct gic_kvm_info *info) { - u32 ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_ich_vtr_el2); + u64 ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_gic_config); int ret;
+ ich_vtr_el2 = (u32)ich_vtr_el2; + /* * The ListRegs field is 5 bits, but there is an architectural * maximum of 16 list registers. Just ignore bit 4...
From: Marc Zyngier maz@kernel.org
commit 9739f6ef053f104a997165701c6e15582c4307ee upstream.
It looks like we have broken firmware out there that wrongly advertises a GICv2 compatibility interface, despite the CPUs not being able to deal with it.
To work around this, check that the CPU initialising KVM is actually able to switch to MMIO instead of system registers, and use that as a precondition to enable GICv2 compatibility in KVM.
Note that the detection happens on a single CPU. If the firmware is lying *and* that the CPUs are asymetric, all hope is lost anyway.
Cc: stable@vger.kernel.org #5.10 Reported-by: Shameerali Kolothum Thodi shameerali.kolothum.thodi@huawei.com Tested-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com Signed-off-by: Marc Zyngier maz@kernel.org Message-Id: 20210305185254.3730990-8-maz@kernel.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com --- arch/arm64/kvm/hyp/vgic-v3-sr.c | 35 +++++++++++++++++++++++++++++++-- arch/arm64/kvm/vgic/vgic-v3.c | 8 ++++++-- 2 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c index 54ce4048d7d1..098b96c121e3 100644 --- a/arch/arm64/kvm/hyp/vgic-v3-sr.c +++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c @@ -406,11 +406,42 @@ void __vgic_v3_init_lrs(void) /* * Return the GIC CPU configuration: * - [31:0] ICH_VTR_EL2 - * - [63:32] RES0 + * - [62:32] RES0 + * - [63] MMIO (GICv2) capable */ u64 __vgic_v3_get_gic_config(void) { - return read_gicreg(ICH_VTR_EL2); + u64 val, sre = read_gicreg(ICC_SRE_EL1); + unsigned long flags = 0; + + /* + * To check whether we have a MMIO-based (GICv2 compatible) + * CPU interface, we need to disable the system register + * view. To do that safely, we have to prevent any interrupt + * from firing (which would be deadly). + * + * Note that this only makes sense on VHE, as interrupts are + * already masked for nVHE as part of the exception entry to + * EL2. + */ + if (has_vhe()) + flags = local_daif_save(); + + write_gicreg(0, ICC_SRE_EL1); + isb(); + + val = read_gicreg(ICC_SRE_EL1); + + write_gicreg(sre, ICC_SRE_EL1); + isb(); + + if (has_vhe()) + local_daif_restore(flags); + + val = (val & ICC_SRE_EL1_SRE) ? 0 : (1ULL << 63); + val |= read_gicreg(ICH_VTR_EL2); + + return val; }
u64 __vgic_v3_read_vmcr(void) diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c index 8e7bf3151057..6a4bced0851d 100644 --- a/arch/arm64/kvm/vgic/vgic-v3.c +++ b/arch/arm64/kvm/vgic/vgic-v3.c @@ -584,8 +584,10 @@ early_param("kvm-arm.vgic_v4_enable", early_gicv4_enable); int vgic_v3_probe(const struct gic_kvm_info *info) { u64 ich_vtr_el2 = kvm_call_hyp_ret(__vgic_v3_get_gic_config); + bool has_v2; int ret;
+ has_v2 = ich_vtr_el2 >> 63; ich_vtr_el2 = (u32)ich_vtr_el2;
/* @@ -605,13 +607,15 @@ int vgic_v3_probe(const struct gic_kvm_info *info) gicv4_enable ? "en" : "dis"); }
+ kvm_vgic_global_state.vcpu_base = 0; + if (!info->vcpu.start) { kvm_info("GICv3: no GICV resource entry\n"); - kvm_vgic_global_state.vcpu_base = 0; + } else if (!has_v2) { + pr_warn(FW_BUG "CPU interface incapable of MMIO access\n"); } else if (!PAGE_ALIGNED(info->vcpu.start)) { pr_warn("GICV physical address 0x%llx not page aligned\n", (unsigned long long)info->vcpu.start); - kvm_vgic_global_state.vcpu_base = 0; } else { kvm_vgic_global_state.vcpu_base = info->vcpu.start; kvm_vgic_global_state.can_emulate_gicv2 = true;
On 2021-03-25 09:14, Shameer Kolothum wrote:
From: Marc Zyngier maz@kernel.org
commit 9739f6ef053f104a997165701c6e15582c4307ee upstream.
It looks like we have broken firmware out there that wrongly advertises a GICv2 compatibility interface, despite the CPUs not being able to deal with it.
To work around this, check that the CPU initialising KVM is actually able to switch to MMIO instead of system registers, and use that as a precondition to enable GICv2 compatibility in KVM.
Note that the detection happens on a single CPU. If the firmware is lying *and* that the CPUs are asymetric, all hope is lost anyway.
Cc: stable@vger.kernel.org #5.10 Reported-by: Shameerali Kolothum Thodi shameerali.kolothum.thodi@huawei.com Tested-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com Signed-off-by: Marc Zyngier maz@kernel.org Message-Id: 20210305185254.3730990-8-maz@kernel.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com
Please hold on on that.
This patch causes a regression, and needs a fix that is currently queued for 5.12 [1]. Once this hits upstream, please add the fix to the series and post it as a whole.
Thanks,
M.
[1] https://lore.kernel.org/r/20210323162301.2049595-1-maz@kernel.org
-----Original Message----- From: Marc Zyngier [mailto:maz@kernel.org] Sent: 25 March 2021 09:33 To: Shameerali Kolothum Thodi shameerali.kolothum.thodi@huawei.com Cc: kvmarm@lists.cs.columbia.edu; kvm@vger.kernel.org; linux-arm-kernel@lists.infradead.org; stable@vger.kernel.org; pbonzini@redhat.com; Linuxarm linuxarm@huawei.com Subject: Re: [PATCH for-stable-5.10 2/2] KVM: arm64: Workaround firmware wrongly advertising GICv2-on-v3 compatibility
On 2021-03-25 09:14, Shameer Kolothum wrote:
From: Marc Zyngier maz@kernel.org
commit 9739f6ef053f104a997165701c6e15582c4307ee upstream.
It looks like we have broken firmware out there that wrongly advertises a GICv2 compatibility interface, despite the CPUs not being able to deal with it.
To work around this, check that the CPU initialising KVM is actually able to switch to MMIO instead of system registers, and use that as a precondition to enable GICv2 compatibility in KVM.
Note that the detection happens on a single CPU. If the firmware is lying *and* that the CPUs are asymetric, all hope is lost anyway.
Cc: stable@vger.kernel.org #5.10 Reported-by: Shameerali Kolothum Thodi shameerali.kolothum.thodi@huawei.com Tested-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com Signed-off-by: Marc Zyngier maz@kernel.org Message-Id: 20210305185254.3730990-8-maz@kernel.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com
Please hold on on that.
This patch causes a regression, and needs a fix that is currently queued for 5.12 [1]. Once this hits upstream, please add the fix to the series and post it as a whole.
Ok. Yes, I noted that. But was thinking if this goes through first and then we can have a stable tag for that one, we can manage it. Anyway, will wait now.
Thanks, Shameer
Thanks,
M.
[1] https://lore.kernel.org/r/20210323162301.2049595-1-maz@kernel.org
Jazz is not dead. It just smells funny...
On Thu, 25 Mar 2021 09:37:15 +0000, Shameerali Kolothum Thodi shameerali.kolothum.thodi@huawei.com wrote:
-----Original Message----- From: Marc Zyngier [mailto:maz@kernel.org] Sent: 25 March 2021 09:33 To: Shameerali Kolothum Thodi shameerali.kolothum.thodi@huawei.com Cc: kvmarm@lists.cs.columbia.edu; kvm@vger.kernel.org; linux-arm-kernel@lists.infradead.org; stable@vger.kernel.org; pbonzini@redhat.com; Linuxarm linuxarm@huawei.com Subject: Re: [PATCH for-stable-5.10 2/2] KVM: arm64: Workaround firmware wrongly advertising GICv2-on-v3 compatibility
On 2021-03-25 09:14, Shameer Kolothum wrote:
From: Marc Zyngier maz@kernel.org
commit 9739f6ef053f104a997165701c6e15582c4307ee upstream.
It looks like we have broken firmware out there that wrongly advertises a GICv2 compatibility interface, despite the CPUs not being able to deal with it.
To work around this, check that the CPU initialising KVM is actually able to switch to MMIO instead of system registers, and use that as a precondition to enable GICv2 compatibility in KVM.
Note that the detection happens on a single CPU. If the firmware is lying *and* that the CPUs are asymetric, all hope is lost anyway.
Cc: stable@vger.kernel.org #5.10 Reported-by: Shameerali Kolothum Thodi shameerali.kolothum.thodi@huawei.com Tested-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com Signed-off-by: Marc Zyngier maz@kernel.org Message-Id: 20210305185254.3730990-8-maz@kernel.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com
Please hold on on that.
This patch causes a regression, and needs a fix that is currently queued for 5.12 [1]. Once this hits upstream, please add the fix to the series and post it as a whole.
Ok. Yes, I noted that. But was thinking if this goes through first and then we can have a stable tag for that one, we can manage it.
The problem is we'd end-up with 5.10 being subtly broken for a while, and I want to avoid this.
Specially given that not having this series only affects broken platforms, while having an incomplete series breaks working systems (which is be counter productive).
Anyway, will wait now.
Thanks for that,
M.
On Thu, Mar 25, 2021 at 09:33:17AM +0000, Marc Zyngier wrote:
On 2021-03-25 09:14, Shameer Kolothum wrote:
From: Marc Zyngier maz@kernel.org
commit 9739f6ef053f104a997165701c6e15582c4307ee upstream.
It looks like we have broken firmware out there that wrongly advertises a GICv2 compatibility interface, despite the CPUs not being able to deal with it.
To work around this, check that the CPU initialising KVM is actually able to switch to MMIO instead of system registers, and use that as a precondition to enable GICv2 compatibility in KVM.
Note that the detection happens on a single CPU. If the firmware is lying *and* that the CPUs are asymetric, all hope is lost anyway.
Cc: stable@vger.kernel.org #5.10 Reported-by: Shameerali Kolothum Thodi shameerali.kolothum.thodi@huawei.com Tested-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com Signed-off-by: Marc Zyngier maz@kernel.org Message-Id: 20210305185254.3730990-8-maz@kernel.org Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Shameer Kolothum shameerali.kolothum.thodi@huawei.com
Please hold on on that.
This patch causes a regression, and needs a fix that is currently queued for 5.12 [1]. Once this hits upstream, please add the fix to the series and post it as a whole.
Both patches now dropped from my queue, thanks.
greg k-h
linux-stable-mirror@lists.linaro.org