Commit 1c342c1a authored by lishusen's avatar lishusen
Browse files

KVM: arm64: Add kvm_vcpu_arch::sched_cpus and pre_sched_cpus

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 sched_cpus and pre_sched_cpus in struct
kvm_vcpu_arch. @sched_cpus always comes from current->cpus_ptr and
@pre_sched_cpus always comes from @sched_cpus.

Signed-off-by: default avatarQuan Zhou <zhouquan65@huawei.com>
Signed-off-by: default avatarlishusen <lishusen2@huawei.com>
parent e85b97c7
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -591,6 +591,12 @@ struct kvm_vcpu_arch {

	/* Per-vcpu CCSIDR override or NULL */
	u32 *ccsidr;

#ifdef CONFIG_KVM_HISI_VIRT
	/* pCPUs this vCPU can be scheduled on. Pure copy of current->cpus_ptr */
	cpumask_var_t sched_cpus;
	cpumask_var_t pre_sched_cpus;
#endif
};

/*
+10 −4
Original line number Diff line number Diff line
@@ -47,9 +47,7 @@

static enum kvm_mode kvm_mode = KVM_MODE_DEFAULT;

#ifdef CONFIG_KVM_HISI_VIRT
#include "hisilicon/hisi_virt.h"
#endif

DECLARE_KVM_HYP_PER_CPU(unsigned long, kvm_hyp_vector);

@@ -402,6 +400,10 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
	if (err)
		return err;

	err = kvm_sched_affinity_vcpu_init(vcpu);
	if (err)
		return err;

	return kvm_share_hyp(vcpu, vcpu + 1);
}

@@ -419,6 +421,8 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
	kvm_pmu_vcpu_destroy(vcpu);

	kvm_arm_vcpu_destroy(vcpu);

	kvm_sched_affinity_vcpu_destroy(vcpu);
}

void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu)
@@ -475,6 +479,8 @@ 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);

	kvm_tlbi_dvmbm_vcpu_load(vcpu);
}

void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@@ -490,6 +496,8 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)

	vcpu_clear_on_unsupported_cpu(vcpu);
	vcpu->cpu = -1;

	kvm_tlbi_dvmbm_vcpu_put(vcpu);
}

static void __kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu)
@@ -2425,11 +2433,9 @@ static __init int kvm_arm_init(void)
		return err;
	}

#ifdef CONFIG_KVM_HISI_VIRT
	probe_hisi_cpu_type();
	kvm_ncsnp_support = hisi_ncsnp_supported();
	kvm_dvmbm_support = hisi_dvmbm_supported();
#endif
	kvm_info("KVM ncsnp %s\n", kvm_ncsnp_support ? "enabled" : "disabled");
	kvm_info("KVM dvmbm %s\n", kvm_dvmbm_support ? "enabled" : "disabled");

+37 −0
Original line number Diff line number Diff line
@@ -173,3 +173,40 @@ bool hisi_dvmbm_supported(void)
	on_each_cpu(hardware_enable_dvmbm, NULL, 1);
	return true;
}

int kvm_sched_affinity_vcpu_init(struct kvm_vcpu *vcpu)
{
	if (!kvm_dvmbm_support)
		return 0;

	if (!zalloc_cpumask_var(&vcpu->arch.sched_cpus, GFP_ATOMIC) ||
	    !zalloc_cpumask_var(&vcpu->arch.pre_sched_cpus, GFP_ATOMIC))
		return -ENOMEM;

	return 0;
}

void kvm_sched_affinity_vcpu_destroy(struct kvm_vcpu *vcpu)
{
	if (!kvm_dvmbm_support)
		return;

	free_cpumask_var(vcpu->arch.sched_cpus);
	free_cpumask_var(vcpu->arch.pre_sched_cpus);
}

void kvm_tlbi_dvmbm_vcpu_load(struct kvm_vcpu *vcpu)
{
	if (!kvm_dvmbm_support)
		return;

	cpumask_copy(vcpu->arch.sched_cpus, current->cpus_ptr);
}

void kvm_tlbi_dvmbm_vcpu_put(struct kvm_vcpu *vcpu)
{
	if (!kvm_dvmbm_support)
		return;

	cpumask_copy(vcpu->arch.pre_sched_cpus, vcpu->arch.sched_cpus);
}
+25 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#ifndef __HISI_VIRT_H__
#define __HISI_VIRT_H__

#ifdef CONFIG_KVM_HISI_VIRT
enum hisi_cpu_type {
	HI_1612,
	HI_1616,
@@ -23,4 +24,28 @@ void probe_hisi_cpu_type(void);
bool hisi_ncsnp_supported(void);
bool hisi_dvmbm_supported(void);

int kvm_sched_affinity_vcpu_init(struct kvm_vcpu *vcpu);
void kvm_sched_affinity_vcpu_destroy(struct kvm_vcpu *vcpu);
void kvm_tlbi_dvmbm_vcpu_load(struct kvm_vcpu *vcpu);
void kvm_tlbi_dvmbm_vcpu_put(struct kvm_vcpu *vcpu);
#else
static inline void probe_hisi_cpu_type(void) {}
static inline bool hisi_ncsnp_supported(void)
{
	return false;
}
static inline bool hisi_dvmbm_supported(void)
{
	return false;
}

static inline int kvm_sched_affinity_vcpu_init(struct kvm_vcpu *vcpu)
{
	return 0;
}
static inline void kvm_sched_affinity_vcpu_destroy(struct kvm_vcpu *vcpu) {}
static inline void kvm_tlbi_dvmbm_vcpu_load(struct kvm_vcpu *vcpu) {}
static inline void kvm_tlbi_dvmbm_vcpu_put(struct kvm_vcpu *vcpu) {}
#endif /* CONFIG_KVM_HISI_VIRT */

#endif /* __HISI_VIRT_H__ */