From: lishusen <lishusen2@h-partners.com> Unify the two DVMBM control switches so that tlbi_dvmbm_enable is the single runtime switch, initialized from the cmdline parameter kvm-arm.dvmbm_enabled at KVM init time. With this change, kvm-arm.dvmbm_enabled=1 automatically sets tlbi_dvmbm_enable=1, and the DVMBM feature state is consistent with tlbi_dvmbm_enable (/sys/module/kvm/parameters/tlbi_dvmbm_enable). --- arch/arm64/kvm/arm.c | 12 +++++++++- arch/arm64/kvm/hisilicon/hisi_virt.c | 36 ++++++++++++++++++++++++---- arch/arm64/kvm/hisilicon/hisi_virt.h | 16 +++++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 9319d1b72239..921a0a9150a1 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -105,6 +105,16 @@ static const struct kernel_param_ops force_wfi_trap_ops = { bool force_wfi_trap; module_param_cb(force_wfi_trap, &force_wfi_trap_ops, &force_wfi_trap, 0644); +static const struct kernel_param_ops tlbi_dvmbm_enable_ops = { + .set = dvmbm_enable_update, + .get = param_get_bool, +}; + +bool tlbi_dvmbm_enable = false; +MODULE_PARM_DESC(tlbi_dvmbm_enable, "bool"); +module_param_cb(tlbi_dvmbm_enable, &tlbi_dvmbm_enable_ops, &tlbi_dvmbm_enable, + 0644); + static int vcpu_req_reload_wfi_traps(const char *val, const struct kernel_param *kp) { struct kvm *kvm; @@ -3569,7 +3579,7 @@ static __init int kvm_arm_init(void) kvm_ncsnp_support = hisi_ncsnp_supported(); kvm_dvmbm_support = hisi_dvmbm_supported(); kvm_info("KVM ncsnp %s\n", kvm_ncsnp_support ? "enabled" : "disabled"); - kvm_info("KVM dvmbm %s\n", kvm_dvmbm_support ? "enabled" : "disabled"); + kvm_info("KVM dvmbm %s\n", kvm_dvmbm_enabled() ? "enabled" : "disabled"); if (kvm_dvmbm_support) kvm_get_pg_cfg(); diff --git a/arch/arm64/kvm/hisilicon/hisi_virt.c b/arch/arm64/kvm/hisilicon/hisi_virt.c index 0be4ebbc540d..e92661f201a4 100644 --- a/arch/arm64/kvm/hisilicon/hisi_virt.c +++ b/arch/arm64/kvm/hisilicon/hisi_virt.c @@ -146,7 +146,7 @@ static int __init early_dvmbm_enable(char *buf) } early_param("kvm-arm.dvmbm_enabled", early_dvmbm_enable); -static void hardware_enable_dvmbm(void) +static void hardware_enable_dvmbm(void *data) { u64 val; @@ -259,7 +259,9 @@ bool hisi_dvmbm_supported(void) /* reset */ on_each_cpu(hardware_disable_dvmbm, NULL, 1); - return dvmbm_enabled; + tlbi_dvmbm_enable = dvmbm_enabled; + + return true; } int kvm_sched_affinity_vcpu_init(struct kvm_vcpu *vcpu) @@ -558,7 +560,8 @@ void kvm_tlbi_dvmbm_vcpu_load(struct kvm_vcpu *vcpu) if (!kvm_dvmbm_support) return; - hardware_enable_dvmbm(); + if (kvm_dvmbm_enabled()) + hardware_enable_dvmbm(NULL); cpumask_copy(vcpu->arch.sched_cpus, current->cpus_ptr); if (likely(cpumask_equal(vcpu->arch.sched_cpus, @@ -609,7 +612,32 @@ 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); + if (kvm_dvmbm_enabled()) + hardware_disable_dvmbm(NULL); +} + +int dvmbm_enable_update(const char *val, const struct kernel_param *kp) +{ + int err = param_set_bool(val, kp); + + if (err) + return err; + + if (!kvm_dvmbm_support) { + kvm_info("TLBI dvmbm not supported by this hardware. " + "Config ignored!\n"); + return err; + } + + if (kvm_dvmbm_enabled()) { + on_each_cpu(hardware_enable_dvmbm, NULL, 1); + kvm_info("KVM dvmbm enabled\n"); + } else { + on_each_cpu(hardware_disable_dvmbm, NULL, 1); + kvm_info("KVM dvmbm disabled\n"); + } + + return err; } void kvm_get_pg_cfg(void) diff --git a/arch/arm64/kvm/hisilicon/hisi_virt.h b/arch/arm64/kvm/hisilicon/hisi_virt.h index 8e7a88a267c8..0dfcbd81e1fc 100644 --- a/arch/arm64/kvm/hisilicon/hisi_virt.h +++ b/arch/arm64/kvm/hisilicon/hisi_virt.h @@ -95,6 +95,13 @@ enum hisi_cpu_type { void probe_hisi_cpu_type(void); bool hisi_ncsnp_supported(void); bool hisi_dvmbm_supported(void); + +extern bool tlbi_dvmbm_enable; +static inline bool kvm_dvmbm_enabled(void) +{ + return kvm_dvmbm_support && tlbi_dvmbm_enable; +} +int dvmbm_enable_update(const char *val, const struct kernel_param *kp); #ifdef CONFIG_ARM64_HISI_IPIV bool hisi_ipiv_supported(void); bool hisi_ipiv_supported_per_vm(struct kvm *kvm); @@ -120,6 +127,15 @@ static inline bool hisi_dvmbm_supported(void) { return false; } +static inline bool kvm_dvmbm_enabled(void) +{ + return false; +} +static inline int dvmbm_enable_update(const char *val, + const struct kernel_param *kp) +{ + return 0; +} #ifdef CONFIG_ARM64_HISI_IPIV static inline bool hisi_ipiv_supported(void) { -- 2.33.0