[PATCH V3 1/4] HV: enumerate capability of #AC for Splitlock Access #ac


Tao, Yuhong
 

When the destination of an atomic memory operation located in 2
cache lines, it is called a Splitlock Access. LOCK# bus signal is
asserted for splitlock access which may lead to long latency. #AC
for Splitlock Access is a CPU feature, it allows rise alignment
check exception #AC(0) instead of asserting LOCK#, that is helpful
to detect Splitlock Access.

This feature is enumarted by MSR(0xcf) IA32_CORE_CAPABILITIES[bit5]
Add helper function:
bool has_core_cap(uint32_t bitmask)

Tracked-On: #4496
Signed-off-by: Tao Yuhong <yuhong.tao@intel.com>
---
hypervisor/arch/x86/cpu_caps.c | 14 ++++++++++++++
hypervisor/include/arch/x86/cpu_caps.h | 1 +
hypervisor/include/arch/x86/cpufeatures.h | 1 +
hypervisor/include/arch/x86/msr.h | 1 +
4 files changed, 17 insertions(+)

diff --git a/hypervisor/arch/x86/cpu_caps.c b/hypervisor/arch/x86/cpu_caps.c
index 33e311e..4fdffd8 100644
--- a/hypervisor/arch/x86/cpu_caps.c
+++ b/hypervisor/arch/x86/cpu_caps.c
@@ -37,6 +37,7 @@ static struct cpu_capability {

uint32_t vmx_ept;
uint32_t vmx_vpid;
+ uint32_t core_caps; /* value of MSR_IA32_CORE_CAPABLITIES */
} cpu_caps;

static struct cpuinfo_x86 boot_cpu_data;
@@ -124,6 +125,11 @@ bool is_apl_platform(void)
return ret;
}

+bool has_core_cap(uint32_t bit_mask)
+{
+ return ((cpu_caps.core_caps & bit_mask) != 0U);
+}
+
static void detect_ept_cap(void)
{
uint64_t msr_val;
@@ -216,12 +222,20 @@ static void detect_xsave_cap(void)
&boot_cpu_data.cpuid_leaves[FEAT_D_1_EDX]);
}

+static void detect_core_caps(void)
+{
+ if (pcpu_has_cap(X86_FEATURE_CORE_CAP)) {
+ cpu_caps.core_caps = msr_read(MSR_IA32_CORE_CAPABILITIES);
+ }
+}
+
static void detect_pcpu_cap(void)
{
detect_apicv_cap();
detect_ept_cap();
detect_vmx_mmu_cap();
detect_xsave_cap();
+ detect_core_caps();
}

static uint64_t get_address_mask(uint8_t limit)
diff --git a/hypervisor/include/arch/x86/cpu_caps.h b/hypervisor/include/arch/x86/cpu_caps.h
index 3f650ac..1e608e4 100644
--- a/hypervisor/include/arch/x86/cpu_caps.h
+++ b/hypervisor/include/arch/x86/cpu_caps.h
@@ -49,6 +49,7 @@ bool pcpu_has_cap(uint32_t bit);
bool pcpu_has_vmx_ept_cap(uint32_t bit_mask);
bool pcpu_has_vmx_vpid_cap(uint32_t bit_mask);
bool is_apl_platform(void);
+bool has_core_cap(uint32_t bit_mask);
void init_pcpu_capabilities(void);
void init_pcpu_model_name(void);
int32_t detect_hardware_support(void);
diff --git a/hypervisor/include/arch/x86/cpufeatures.h b/hypervisor/include/arch/x86/cpufeatures.h
index 6a7f87e..e865b00 100644
--- a/hypervisor/include/arch/x86/cpufeatures.h
+++ b/hypervisor/include/arch/x86/cpufeatures.h
@@ -84,6 +84,7 @@
#define X86_FEATURE_STIBP ((FEAT_7_0_EDX << 5U) + 27U)
#define X86_FEATURE_L1D_FLUSH ((FEAT_7_0_EDX << 5U) + 28U)
#define X86_FEATURE_ARCH_CAP ((FEAT_7_0_EDX << 5U) + 29U)
+#define X86_FEATURE_CORE_CAP ((FEAT_7_0_EDX << 5U) + 30U)
#define X86_FEATURE_SSBD ((FEAT_7_0_EDX << 5U) + 31U)

/* Intel-defined CPU features, CPUID level 0x80000001 (EDX)*/
diff --git a/hypervisor/include/arch/x86/msr.h b/hypervisor/include/arch/x86/msr.h
index 70becbe..39c161f 100644
--- a/hypervisor/include/arch/x86/msr.h
+++ b/hypervisor/include/arch/x86/msr.h
@@ -40,6 +40,7 @@
#define MSR_IA32_PMC5 0x000000C6U
#define MSR_IA32_PMC6 0x000000C7U
#define MSR_IA32_PMC7 0x000000C8U
+#define MSR_IA32_CORE_CAPABILITIES 0x000000CFU
/* Max. qualified performance clock counter */
#define MSR_IA32_MPERF 0x000000E7U
/* Actual performance clock counter */
--
2.7.4