提交 823f53c2 编写于 作者: Z Zenghui Yu 提交者: Yang Yingliang

KVM: arm64: Allow vcpus running without HCR_EL2.FB

virt inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I4BLL0
CVE: NA

--------------------------------

As per ARM DDI 0487G.a, seting the HCR_EL2.FB (Force broadcast) bit causes
a given set of TLBI and IC instructions to be broadcast within the Inner
Shareable domain when executed from EL1 (if HCR_EL2.TGE is 0).

And people complain that this leads to bad performance when running guests
on Kunpeng920 which has 128 physical CPUs in the IS domain, especially in
the case where vcpus are pinned to physical CPUs, where we indeed don't
need broadcast invalidations.

Introduce a new cmdline parameter "kvm-arm.hcr_nofb" for users and setting
it at boot time allows all vcpus running without HCR_EL2.FB. Note that we
now have to nuke the whole vcpu context in the general case (when vcpu is
loaded on to the new physical CPU).
Co-developed-by: NNianyao Tang <tangnianyao@huawei.com>
Signed-off-by: NNianyao Tang <tangnianyao@huawei.com>
Signed-off-by: NZenghui Yu <yuzenghui@huawei.com>
Reviewed-by: NCheng Jian <cj.chengjian@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 0190e611
...@@ -52,6 +52,8 @@ static inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu) ...@@ -52,6 +52,8 @@ static inline bool vcpu_el1_is_32bit(struct kvm_vcpu *vcpu)
return !(vcpu->arch.hcr_el2 & HCR_RW); return !(vcpu->arch.hcr_el2 & HCR_RW);
} }
extern bool kvm_hcr_nofb;
static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
{ {
vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS; vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS;
...@@ -76,6 +78,9 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) ...@@ -76,6 +78,9 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
*/ */
if (!vcpu_el1_is_32bit(vcpu)) if (!vcpu_el1_is_32bit(vcpu))
vcpu->arch.hcr_el2 |= HCR_TID3; vcpu->arch.hcr_el2 |= HCR_TID3;
if (unlikely(kvm_hcr_nofb))
vcpu->arch.hcr_el2 &= ~HCR_FB;
} }
static inline unsigned long *vcpu_hcr(struct kvm_vcpu *vcpu) static inline unsigned long *vcpu_hcr(struct kvm_vcpu *vcpu)
......
...@@ -74,6 +74,14 @@ static bool vgic_present; ...@@ -74,6 +74,14 @@ static bool vgic_present;
enum hisi_cpu_type hi_cpu_type = UNKNOWN_HI_TYPE; enum hisi_cpu_type hi_cpu_type = UNKNOWN_HI_TYPE;
bool kvm_ncsnp_support; bool kvm_ncsnp_support;
bool kvm_hcr_nofb;
static int __init early_hcr_nofb_cfg(char *buf)
{
return strtobool(buf, &kvm_hcr_nofb);
}
early_param("kvm-arm.hcr_nofb", early_hcr_nofb_cfg);
static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled); static DEFINE_PER_CPU(unsigned char, kvm_arm_hardware_enabled);
static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu) static void kvm_arm_set_running_vcpu(struct kvm_vcpu *vcpu)
...@@ -419,6 +427,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) ...@@ -419,6 +427,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{ {
int *last_ran; int *last_ran;
kvm_host_data_t *cpu_data; kvm_host_data_t *cpu_data;
bool flushed = false;
last_ran = this_cpu_ptr(vcpu->kvm->arch.last_vcpu_ran); last_ran = this_cpu_ptr(vcpu->kvm->arch.last_vcpu_ran);
cpu_data = this_cpu_ptr(&kvm_host_data); cpu_data = this_cpu_ptr(&kvm_host_data);
...@@ -435,8 +444,17 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) ...@@ -435,8 +444,17 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
if (*last_ran != vcpu->vcpu_id) { if (*last_ran != vcpu->vcpu_id) {
kvm_call_hyp(__kvm_flush_cpu_context, vcpu); kvm_call_hyp(__kvm_flush_cpu_context, vcpu);
*last_ran = vcpu->vcpu_id; *last_ran = vcpu->vcpu_id;
flushed = true;
} }
/*
* If FB (Force broadcast) is cleared, we have to nuke the
* vcpu context as well in case it is loaded on to the new
* physical CPU.
*/
if (unlikely(kvm_hcr_nofb) && vcpu->pre_pcpu != cpu && !flushed)
kvm_call_hyp(__kvm_flush_cpu_context, vcpu);
vcpu->cpu = cpu; vcpu->cpu = cpu;
vcpu->arch.host_cpu_context = &cpu_data->host_ctxt; vcpu->arch.host_cpu_context = &cpu_data->host_ctxt;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册