From 8360c3dfe6f4f4a75b5129690d87472a89ef3628 Mon Sep 17 00:00:00 2001 From: Tao Yuhong Date: Fri, 5 Mar 2021 06:18:18 -0500 Subject: [PATCH] HV: enable #GP for UC lock For an atomic operation using bus locking, it would generate LOCK# bus signal, if it has Non-WB memory operand. This is an UC lock. It will ruin the RT behavior of the system. If MSR_IA32_CORE_CAPABILITIES[bit4] is 1, then CPU can trigger #GP for instructions which cause UC lock. This feature is controlled by MSR_TEST_CTL[bit28]. This patch enables #GP for guest UC lock. Tracked-On: #6299 Signed-off-by: Tao Yuhong Acked-by: Eddie Dong --- hypervisor/arch/x86/cpu.c | 18 ++++++++++++++++-- hypervisor/arch/x86/guest/vmsr.c | 4 ++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c index 8cdef8a3e..9419f31ad 100644 --- a/hypervisor/arch/x86/cpu.c +++ b/hypervisor/arch/x86/cpu.c @@ -113,14 +113,27 @@ static void enable_ac_for_splitlock(void) #ifndef CONFIG_ENFORCE_TURNOFF_AC uint64_t test_ctl; - if (has_core_cap(1U << 5U)) { + if (has_core_cap(CORE_CAP_SPLIT_LOCK)) { test_ctl = msr_read(MSR_TEST_CTL); - test_ctl |= (1U << 29U); + test_ctl |= MSR_TEST_CTL_AC_SPLITLOCK; msr_write(MSR_TEST_CTL, test_ctl); } #endif /*CONFIG_ENFORCE_TURNOFF_AC*/ } +static void enable_gp_for_uclock(void) +{ +#ifndef CONFIG_ENFORCE_TURNOFF_GP + uint64_t test_ctl; + + if (has_core_cap(CORE_CAP_UC_LOCK)) { + test_ctl = msr_read(MSR_TEST_CTL); + test_ctl |= MSR_TEST_CTL_GP_UCLOCK; + msr_write(MSR_TEST_CTL, test_ctl); + } +#endif /*CONFIG_ENFORCE_TURNOFF_GP*/ +} + void init_pcpu_pre(bool is_bsp) { uint16_t pcpu_id; @@ -210,6 +223,7 @@ void init_pcpu_post(uint16_t pcpu_id) load_gdtr_and_tr(); enable_ac_for_splitlock(); + enable_gp_for_uclock(); init_pcpu_xsave(); diff --git a/hypervisor/arch/x86/guest/vmsr.c b/hypervisor/arch/x86/guest/vmsr.c index 195dd2567..ff1ad704f 100644 --- a/hypervisor/arch/x86/guest/vmsr.c +++ b/hypervisor/arch/x86/guest/vmsr.c @@ -589,7 +589,7 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu) /* If has MSR_TEST_CTL, give emulated value * If don't have MSR_TEST_CTL, trigger #GP */ - if (has_core_cap(1U << 5U)) { + if (has_core_cap(CORE_CAP_SPLIT_LOCK) || has_core_cap(CORE_CAP_UC_LOCK)) { v = vcpu_get_guest_msr(vcpu, MSR_TEST_CTL); } else { vcpu_inject_gp(vcpu, 0U); @@ -959,7 +959,7 @@ int32_t wrmsr_vmexit_handler(struct acrn_vcpu *vcpu) /* If VM has MSR_TEST_CTL, ignore write operation * If don't have MSR_TEST_CTL, trigger #GP */ - if (has_core_cap(1U << 5U)) { + if (has_core_cap(CORE_CAP_SPLIT_LOCK) || has_core_cap(CORE_CAP_UC_LOCK)) { vcpu_set_guest_msr(vcpu, MSR_TEST_CTL, v); pr_warn("Ignore writting 0x%llx to MSR_TEST_CTL from VM%d", v, vcpu->vm->vm_id); } else {