[PATCH] HV: enable #GP for UC lock #gp


Tao, Yuhong
 

From: Tao Yuhong <yuhong.tao@intel.com>

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.
If MSR_IA32_CORE_CAPABILITIES[bit4] is 1, then CPU support rising #GP
for instructions which cause UC lock. This feature is controlled by
MSR_TEST_CTL[bit28].
Enable this feature if supported.

Signed-off-by: Tao Yuhong <yuhong.tao@intel.com>
---
hypervisor/arch/x86/Kconfig | 7 +++++++
hypervisor/arch/x86/cpu.c | 18 ++++++++++++++++--
hypervisor/arch/x86/guest/vmsr.c | 4 ++--
hypervisor/include/arch/x86/cpu_caps.h | 4 ++++
hypervisor/include/arch/x86/msr.h | 5 +++++
5 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/hypervisor/arch/x86/Kconfig b/hypervisor/arch/x86/Kconfig
index 0893098dc..5ab93d72c 100644
--- a/hypervisor/arch/x86/Kconfig
+++ b/hypervisor/arch/x86/Kconfig
@@ -343,6 +343,13 @@ config ENFORCE_TURNOFF_AC
If CPU has #AC for split-locked access, HV enable it and VMs can't disable.
Set this to enforce turn off that #AC, for community developer only.

+config ENFORCE_TURNOFF_GP
+ bool "Force to disable #GP for UC lock"
+ default n
+ help
+ If CPU has #GP for UC lock, HV enable it and VMs can't disable.
+ Set this to enforce turn off that #GP, for community developer only.
+
config IVSHMEM_ENABLED
bool "Enable ivshmem inter-vm communication based on hypervisor shared memory"
default n
diff --git a/hypervisor/arch/x86/cpu.c b/hypervisor/arch/x86/cpu.c
index ac9049826..515a4a367 100644
--- a/hypervisor/arch/x86/cpu.c
+++ b/hypervisor/arch/x86/cpu.c
@@ -106,14 +106,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;
@@ -203,6 +216,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 84e564e1a..1174982b8 100644
--- a/hypervisor/arch/x86/guest/vmsr.c
+++ b/hypervisor/arch/x86/guest/vmsr.c
@@ -556,7 +556,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);
@@ -916,7 +916,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 {
diff --git a/hypervisor/include/arch/x86/cpu_caps.h b/hypervisor/include/arch/x86/cpu_caps.h
index ba7a9b6c9..2831dfb61 100644
--- a/hypervisor/include/arch/x86/cpu_caps.h
+++ b/hypervisor/include/arch/x86/cpu_caps.h
@@ -59,4 +59,8 @@ void init_pcpu_model_name(void);
int32_t detect_hardware_support(void);
struct cpuinfo_x86 *get_pcpu_info(void);

+/* The bits of MSR IA32_CORE_CAPABILITIES */
+#define CORE_CAP_SPLIT_LOCK (1U << 5U) /* support #AC for Split-locked Access */
+#define CORE_CAP_UC_LOCK (1U << 4U) /* support #GP for non-guaranteed-atomic-locked access at Non-WB memory */
+
#endif /* CPUINFO_H */
diff --git a/hypervisor/include/arch/x86/msr.h b/hypervisor/include/arch/x86/msr.h
index 4ed2185a0..d497db695 100644
--- a/hypervisor/include/arch/x86/msr.h
+++ b/hypervisor/include/arch/x86/msr.h
@@ -595,6 +595,11 @@
/* 5 high-order bits in every field are reserved */
#define PAT_FIELD_RSV_BITS (0xF8UL)

+/* MSR_TEST_CTL bits */
+#define MSR_TEST_CTL_GP_UCLOCK (1U << 28U)
+#define MSR_TEST_CTL_AC_SPLITLOCK (1U << 29U)
+#define MSR_TEST_CTL_DISABLE_LOCK_ASSERTION (1U << 31U)
+
#ifndef ASSEMBLER
static inline bool is_pat_mem_type_invalid(uint64_t x)
{
--
2.17.1