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 <yuhong.tao@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Tao Yuhong 2021-03-05 06:18:18 -05:00 committed by wenlingz
parent 2aba7f31db
commit 8360c3dfe6
2 changed files with 18 additions and 4 deletions

View File

@ -113,14 +113,27 @@ static void enable_ac_for_splitlock(void)
#ifndef CONFIG_ENFORCE_TURNOFF_AC #ifndef CONFIG_ENFORCE_TURNOFF_AC
uint64_t test_ctl; 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 = msr_read(MSR_TEST_CTL);
test_ctl |= (1U << 29U); test_ctl |= MSR_TEST_CTL_AC_SPLITLOCK;
msr_write(MSR_TEST_CTL, test_ctl); msr_write(MSR_TEST_CTL, test_ctl);
} }
#endif /*CONFIG_ENFORCE_TURNOFF_AC*/ #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) void init_pcpu_pre(bool is_bsp)
{ {
uint16_t pcpu_id; uint16_t pcpu_id;
@ -210,6 +223,7 @@ void init_pcpu_post(uint16_t pcpu_id)
load_gdtr_and_tr(); load_gdtr_and_tr();
enable_ac_for_splitlock(); enable_ac_for_splitlock();
enable_gp_for_uclock();
init_pcpu_xsave(); init_pcpu_xsave();

View File

@ -589,7 +589,7 @@ int32_t rdmsr_vmexit_handler(struct acrn_vcpu *vcpu)
/* If has MSR_TEST_CTL, give emulated value /* If has MSR_TEST_CTL, give emulated value
* If don't have MSR_TEST_CTL, trigger #GP * 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); v = vcpu_get_guest_msr(vcpu, MSR_TEST_CTL);
} else { } else {
vcpu_inject_gp(vcpu, 0U); 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 VM has MSR_TEST_CTL, ignore write operation
* If don't have MSR_TEST_CTL, trigger #GP * 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); 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); pr_warn("Ignore writting 0x%llx to MSR_TEST_CTL from VM%d", v, vcpu->vm->vm_id);
} else { } else {