virt inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IAQV1W CVE: NA -------------------------------- Currently, on GICv4+ system if a vCPU is only runnable process on a pCPU and we are using direct injection of interrupts, the guest WFI trapping will be turn off. So in host view, the vcpu process's CPU util is almost 100%, which may confuse someone. Let's add a kvm parameter to control guest wfi trapping.
Signed-off-by: Zhiqiang Ni nizhiqiang1@huawei.com --- arch/arm64/include/asm/kvm_emulate.h | 3 ++ arch/arm64/include/asm/kvm_host.h | 2 ++ arch/arm64/kvm/arm.c | 49 ++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h index 2293caab9..6992d010b 100644 --- a/arch/arm64/include/asm/kvm_emulate.h +++ b/arch/arm64/include/asm/kvm_emulate.h @@ -119,6 +119,9 @@ static inline void vcpu_clear_wfx_traps(struct kvm_vcpu *vcpu) vcpu->arch.hcr_el2 &= ~HCR_TWI; else vcpu->arch.hcr_el2 |= HCR_TWI; + + if (force_wfi_trap) + vcpu->arch.hcr_el2 |= HCR_TWI; }
static inline void vcpu_set_wfx_traps(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index ac8115098..5ba983f71 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -54,6 +54,7 @@ #define KVM_REQ_SUSPEND KVM_ARCH_REQ(6) #define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7) #define KVM_REQ_RELOAD_TLBI_DVMBM KVM_ARCH_REQ(8) +#define KVM_REQ_RELOAD_WFI_TRAPS KVM_ARCH_REQ(9)
#define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ KVM_DIRTY_LOG_INITIALLY_SET) @@ -1244,6 +1245,7 @@ extern unsigned int twedel; void kvm_arm_vcpu_power_off(struct kvm_vcpu *vcpu); bool kvm_arm_vcpu_stopped(struct kvm_vcpu *vcpu);
+extern bool force_wfi_trap; extern bool kvm_ncsnp_support; extern bool kvm_dvmbm_support;
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index fe3add87e..22560263f 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -82,6 +82,48 @@ unsigned int twedel; module_param(twedel, uint, 0644); #endif
+static int vcpu_req_reload_wfi_traps(const char *val, const struct kernel_param *kp); + +static const struct kernel_param_ops force_wfi_trap_ops = { + .set = vcpu_req_reload_wfi_traps, + .get = param_get_bool, +}; + +bool force_wfi_trap = false; +module_param_cb(force_wfi_trap, &force_wfi_trap_ops, &force_wfi_trap, S_IRUGO | S_IWUSR); + +static int vcpu_req_reload_wfi_traps(const char *val, const struct kernel_param *kp) +{ + struct kvm *kvm; + bool oldvalue; + int err; + + oldvalue = force_wfi_trap; + err = param_set_bool(val, kp); + if (err) + return err; + + if (oldvalue == force_wfi_trap) + return err; + + /* + * If set the force_wfi_trap from 1 to 0, no need to kick vcpus here. + * The HCR_TWI flag will be cleared in kvm_arch_vcpu_load(). + */ + if (force_wfi_trap == 0) + return 0; + + /* + * We need to kick vcpus out of guest mode here to reload + * wfx trapping config when re-enter guest mode. + */ + mutex_lock(&kvm_lock); + list_for_each_entry(kvm, &vm_list, vm_list) + kvm_make_all_cpus_request(kvm, KVM_REQ_RELOAD_WFI_TRAPS); + mutex_unlock(&kvm_lock); + return err; +} + int kvm_arch_vcpu_should_kick(struct kvm_vcpu *vcpu) { return kvm_vcpu_exiting_guest_mode(vcpu) == IN_GUEST_MODE; @@ -958,6 +1000,13 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu)
if (kvm_check_request(KVM_REQ_RELOAD_TLBI_DVMBM, vcpu)) kvm_hisi_reload_lsudvmbm(vcpu->kvm); + + if (kvm_check_request(KVM_REQ_RELOAD_WFI_TRAPS, vcpu)) { + if (single_task_running()) + vcpu_clear_wfx_traps(vcpu); + else + vcpu_set_wfx_traps(vcpu); + } }
return 1;