From: Quan Zhou zhouquan65@huawei.com
virt inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I8TN8N CVE: NA
----------------------------------------------------
We already have cpus_ptr in current thread struct now, through which we can know the pcpu range the thread is allowed to run on. So in kvm_arch_vcpu_{load,put}, we can also know the pcpu range the vcpu thread is allowed to be scheduled on, and that is the range we want to configure for TLBI broadcast.
Introduce two variables cpus_ptr and pre_cpus_ptr in struct kvm_vcpu_arch. @cpus_ptr always comes from current->cpus_ptr and @pre_cpus_ptr always comes from @cpus_ptr.
Signed-off-by: Quan Zhou zhouquan65@huawei.com Reviewed-by: Zenghui Yu yuzenghui@huawei.com Reviewed-by: Nianyao Tang tangnianyao@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com
Signed-off-by: lishusen lishusen2@huawei.com --- arch/arm64/include/asm/kvm_host.h | 6 +++++ arch/arm64/kvm/arm.c | 18 +++++++++++++ arch/arm64/kvm/hisilicon/hisi_virt.c | 38 ++++++++++++++++++++++++++++ arch/arm64/kvm/hisilicon/hisi_virt.h | 5 ++++ 4 files changed, 67 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index be1e1a6e3754..9e7b2081e11e 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -591,6 +591,12 @@ struct kvm_vcpu_arch {
/* Per-vcpu CCSIDR override or NULL */ u32 *ccsidr; + +#ifdef CONFIG_KVM_HISI_VIRT + /* Copy of current->cpus_ptr */ + cpumask_t *cpus_ptr; + cpumask_t *pre_cpus_ptr; +#endif };
/* diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 7c08597501bf..6d22d5e3626c 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -402,6 +402,12 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) if (err) return err;
+#ifdef CONFIG_KVM_HISI_VIRT + err = kvm_hisi_dvmbm_vcpu_init(vcpu); + if (err) + return err; +#endif + return kvm_share_hyp(vcpu, vcpu + 1); }
@@ -419,6 +425,10 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) kvm_pmu_vcpu_destroy(vcpu);
kvm_arm_vcpu_destroy(vcpu); + +#ifdef CONFIG_KVM_HISI_VIRT + kvm_hisi_dvmbm_vcpu_destroy(vcpu); +#endif }
void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) @@ -475,6 +485,10 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
if (!cpumask_test_cpu(cpu, vcpu->kvm->arch.supported_cpus)) vcpu_set_on_unsupported_cpu(vcpu); + +#ifdef CONFIG_KVM_HISI_VIRT + kvm_hisi_dvmbm_load(vcpu); +#endif }
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) @@ -490,6 +504,10 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
vcpu_clear_on_unsupported_cpu(vcpu); vcpu->cpu = -1; + +#ifdef CONFIG_KVM_HISI_VIRT + kvm_hisi_dvmbm_put(vcpu); +#endif }
static void __kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/hisilicon/hisi_virt.c b/arch/arm64/kvm/hisilicon/hisi_virt.c index b81488cd663b..2c79e7f28ca5 100644 --- a/arch/arm64/kvm/hisilicon/hisi_virt.c +++ b/arch/arm64/kvm/hisilicon/hisi_virt.c @@ -173,3 +173,41 @@ bool hisi_dvmbm_supported(void) on_each_cpu(hardware_enable_dvmbm, NULL, 1); return true; } + +int kvm_hisi_dvmbm_vcpu_init(struct kvm_vcpu *vcpu) +{ + if (!kvm_dvmbm_support) + return 0; + + vcpu->arch.cpus_ptr = kzalloc(sizeof(cpumask_t), GFP_ATOMIC); + vcpu->arch.pre_cpus_ptr = kzalloc(sizeof(cpumask_t), GFP_ATOMIC); + if (!vcpu->arch.cpus_ptr || !vcpu->arch.pre_cpus_ptr) + return -ENOMEM; + + return 0; +} + +void kvm_hisi_dvmbm_vcpu_destroy(struct kvm_vcpu *vcpu) +{ + if (!kvm_dvmbm_support) + return; + + kfree(vcpu->arch.cpus_ptr); + kfree(vcpu->arch.pre_cpus_ptr); +} + +void kvm_hisi_dvmbm_load(struct kvm_vcpu *vcpu) +{ + if (!kvm_dvmbm_support) + return; + + cpumask_copy(vcpu->arch.cpus_ptr, current->cpus_ptr); +} + +void kvm_hisi_dvmbm_put(struct kvm_vcpu *vcpu) +{ + if (!kvm_dvmbm_support) + return; + + cpumask_copy(vcpu->arch.pre_cpus_ptr, vcpu->arch.cpus_ptr); +} diff --git a/arch/arm64/kvm/hisilicon/hisi_virt.h b/arch/arm64/kvm/hisilicon/hisi_virt.h index f505d44e386f..f28f4af35a9f 100644 --- a/arch/arm64/kvm/hisilicon/hisi_virt.h +++ b/arch/arm64/kvm/hisilicon/hisi_virt.h @@ -23,4 +23,9 @@ void probe_hisi_cpu_type(void); bool hisi_ncsnp_supported(void); bool hisi_dvmbm_supported(void);
+int kvm_hisi_dvmbm_vcpu_init(struct kvm_vcpu *vcpu); +void kvm_hisi_dvmbm_vcpu_destroy(struct kvm_vcpu *vcpu); +void kvm_hisi_dvmbm_load(struct kvm_vcpu *vcpu); +void kvm_hisi_dvmbm_put(struct kvm_vcpu *vcpu); + #endif /* __HISI_VIRT_H__ */