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