From ea1bce0cbfebaf27f9f79c5ec940a904ffb5b659 Mon Sep 17 00:00:00 2001 From: "yuhong.tao@intel.com" Date: Mon, 16 Mar 2020 21:41:23 +0800 Subject: [PATCH] HV: enumerate capability of #AC for Splitlock Access 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 enumerated 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 Reviewed-by: Yan, Like Acked-by: Eddie Dong --- 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 9738c4efb..68b10dc5e 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 = (uint32_t)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 3f650ac8b..1e608e401 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 6a7f87e49..e865b00b1 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 70becbe67..39c161f73 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 */