[PATCH OLK-6.6 0/2] Fix TLBI broadcast optimization loss and incorrect dvmbm handling
Fix 1 In the TLBI broadcast-optimization feature, the SYS_LSUDVM_CTRL_EL2 register controls whether the feature is enabled. When LPI low-power mode is enabled, this register is cleared as the pCPU powers down into LPI mode, causing the TLBI broadcast optimization to stop working. The fix saves and restores this control register in the callbacks for entering and exiting LPI mode. Fix 2 The current TLBI broadcast-optimization logic only supports normal VMs. If the feature is enabled globally, VMs that are not yet adapted for it, such as CCA will use an incorrect TLBI broadcast bitmap, which can cause a panic in CCA VMs. The fix moves the actual enable/disable of the dvmbm functionality into the vcpu load and vcpu put functions. Tian Zheng (2): KVM: arm64: Fix TLBI optimization broken in LPI mode KVM: arm64: Fix CCA guest panic when dvmbm is enabled arch/arm64/kvm/arm.c | 6 ++++++ arch/arm64/kvm/hisilicon/hisi_virt.c | 8 +++----- arch/arm64/kvm/hisilicon/hisi_virt.h | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) -- 2.33.0
virt inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/8610 -------------------------------------------------------------------- When LPI is enabled, the dvmbm ctrl register is reset to 0, causing functional breakdown. To resolve this issue, the dvmbm ctrl register (SYS_LSUDVM_CTRL_EL2) must be saved and restored during CPU suspend and resume. Fixes: e85b97c7e2b4 ("KVM: arm64: Probe and configure DVMBM capability on HiSi CPUs") Signed-off-by: Tian Zheng <zhengtian10@huawei.com> Reviewed-by: Yanan Wang <wangyanan55@huawei.com> --- arch/arm64/kvm/arm.c | 6 ++++++ arch/arm64/kvm/hisilicon/hisi_virt.h | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index e59152ad5c4a..2ec4c75fdcc2 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -2424,6 +2424,9 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self, */ switch (cmd) { case CPU_PM_ENTER: + if (kvm_dvmbm_support) + kvm_save_dvmbm_ctrl_el2(); + if (__this_cpu_read(kvm_hyp_initialized)) /* * don't update kvm_hyp_initialized here @@ -2439,6 +2442,9 @@ static int hyp_init_cpu_pm_notifier(struct notifier_block *self, /* The hyp was enabled before suspend. */ cpu_hyp_reinit(); + if (kvm_dvmbm_support) + kvm_restore_dvmbm_ctrl_el2(); + return NOTIFY_OK; default: diff --git a/arch/arm64/kvm/hisilicon/hisi_virt.h b/arch/arm64/kvm/hisilicon/hisi_virt.h index 180618e42cbc..ba517eada3bb 100644 --- a/arch/arm64/kvm/hisilicon/hisi_virt.h +++ b/arch/arm64/kvm/hisilicon/hisi_virt.h @@ -17,6 +17,7 @@ enum hisi_cpu_type { HI_IP12, UNKNOWN_HI_TYPE }; +static DEFINE_PER_CPU(u64, kvm_dvmbm_ctrl_el2_val); /* HIP12 */ #ifdef CONFIG_ARM64_HISI_IPIV @@ -94,6 +95,16 @@ enum hisi_cpu_type { void probe_hisi_cpu_type(void); bool hisi_ncsnp_supported(void); bool hisi_dvmbm_supported(void); +static inline void kvm_save_dvmbm_ctrl_el2(void) +{ + __this_cpu_write(kvm_dvmbm_ctrl_el2_val, + read_sysreg_s(SYS_LSUDVM_CTRL_EL2)); +} +static inline void kvm_restore_dvmbm_ctrl_el2(void) +{ + write_sysreg_s(__this_cpu_read(kvm_dvmbm_ctrl_el2_val), + SYS_LSUDVM_CTRL_EL2); +} #ifdef CONFIG_ARM64_HISI_IPIV bool hisi_ipiv_supported(void); bool hisi_ipiv_supported_per_vm(struct kvm *kvm); @@ -119,6 +130,14 @@ static inline bool hisi_dvmbm_supported(void) { return false; } +static inline void kvm_save_dvmbm_ctrl_el2(void) +{ + return; +} +static inline void kvm_restore_dvmbm_ctrl_el2(void) +{ + return; +} #ifdef CONFIG_ARM64_HISI_IPIV static inline bool hisi_ipiv_supported(void) { -- 2.33.0
virt inclusion category: bugfix bugzilla: https://atomgit.com/openeuler/kernel/issues/8610 -------------------------------------------------------------------- Enabling TLBI optimization via kvm-arm.dvmbm_enabled=1 permanently sets the LSUDVM_CTRL_EL2 control bit. Since CCA doesn't yet support this feature, CCA VMs will read an erroneous bitmap from SYS_LSUDVMBM_EL2 when performing TLB flushes, causing a panic. To avoid this issue, this patch dynamically sets/clears the bit in vcpu_load/vcpu_put, limiting the optimization to normal VMs only. Fixes: e85b97c7e2b4 ("KVM: arm64: Probe and configure DVMBM capability on HiSi CPUs") Signed-off-by: Tian Zheng <zhengtian10@huawei.com> Reviewed-by: Yanan Wang <wangyanan55@huawei.com> --- arch/arm64/kvm/hisilicon/hisi_virt.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kvm/hisilicon/hisi_virt.c b/arch/arm64/kvm/hisilicon/hisi_virt.c index 5731d337b228..73454a894b8b 100644 --- a/arch/arm64/kvm/hisilicon/hisi_virt.c +++ b/arch/arm64/kvm/hisilicon/hisi_virt.c @@ -251,11 +251,6 @@ bool hisi_dvmbm_supported(void) return false; } - /* - * Enable TLBI Broadcast optimization by setting - * LSUDVM_CTRL_EL2's bit[0]. - */ - on_each_cpu(hardware_enable_dvmbm, NULL, 1); return true; } @@ -555,6 +550,7 @@ void kvm_tlbi_dvmbm_vcpu_load(struct kvm_vcpu *vcpu) if (!kvm_dvmbm_support) return; + hardware_enable_dvmbm(NULL); cpumask_copy(vcpu->arch.sched_cpus, current->cpus_ptr); if (likely(cpumask_equal(vcpu->arch.sched_cpus, @@ -605,6 +601,8 @@ void kvm_tlbi_dvmbm_vcpu_put(struct kvm_vcpu *vcpu) return; cpumask_copy(vcpu->arch.pre_sched_cpus, vcpu->arch.sched_cpus); + hardware_disable_dvmbm(NULL); + write_sysreg_s((DVMBM_RANGE_ALL_DIES << DVMBM_RANGE_SHIFT), SYS_LSUDVMBM_EL2); } void kvm_get_pg_cfg(void) -- 2.33.0
participants (1)
-
Tian Zheng