From a431cff94ed1649ce4a3fa89b9679fb0b0eba96f Mon Sep 17 00:00:00 2001 From: Shuo A Liu Date: Mon, 28 Jun 2021 16:02:05 +0800 Subject: [PATCH] hv: Use 64 bits definition for 64 bits MSR_IA32_VMX_EPT_VPID_CAP operation MSR_IA32_VMX_EPT_VPID_CAP is 64 bits. Using 32 bits MACROs with it may cause the bit expression wrong. Unify the MSR_IA32_VMX_EPT_VPID_CAP operation with 64 bits definition. Tracked-On: #5923 Signed-off-by: Shuo A Liu Acked-by: Eddie Dong --- hypervisor/arch/x86/cpu_caps.c | 32 ++++++++-------------- hypervisor/arch/x86/guest/ept.c | 2 +- hypervisor/arch/x86/guest/vept.c | 2 +- hypervisor/arch/x86/mmu.c | 6 ++-- hypervisor/include/arch/x86/asm/cpu_caps.h | 3 +- hypervisor/include/arch/x86/asm/vmx.h | 32 +++++++++++----------- 6 files changed, 33 insertions(+), 44 deletions(-) diff --git a/hypervisor/arch/x86/cpu_caps.c b/hypervisor/arch/x86/cpu_caps.c index 8a6753620..87b141f82 100644 --- a/hypervisor/arch/x86/cpu_caps.c +++ b/hypervisor/arch/x86/cpu_caps.c @@ -35,8 +35,7 @@ static struct cpu_capability { uint8_t apicv_features; uint8_t ept_features; - uint32_t vmx_ept; - uint32_t vmx_vpid; + uint64_t vmx_ept_vpid; uint32_t core_caps; /* value of MSR_IA32_CORE_CAPABLITIES */ } cpu_caps; @@ -229,12 +228,8 @@ static void detect_apicv_cap(void) static void detect_vmx_mmu_cap(void) { - uint64_t val; - /* Read the MSR register of EPT and VPID Capability - SDM A.10 */ - val = msr_read(MSR_IA32_VMX_EPT_VPID_CAP); - cpu_caps.vmx_ept = (uint32_t) val; - cpu_caps.vmx_vpid = (uint32_t) (val >> 32U); + cpu_caps.vmx_ept_vpid = msr_read(MSR_IA32_VMX_EPT_VPID_CAP); } static bool pcpu_vmx_set_32bit_addr_width(void) @@ -360,14 +355,9 @@ bool is_apicv_advanced_feature_supported(void) return ((cpu_caps.apicv_features & APICV_ADVANCED_FEATURE) == APICV_ADVANCED_FEATURE); } -bool pcpu_has_vmx_ept_cap(uint32_t bit_mask) +bool pcpu_has_vmx_ept_vpid_cap(uint64_t bit_mask) { - return ((cpu_caps.vmx_ept & bit_mask) != 0U); -} - -bool pcpu_has_vmx_vpid_cap(uint32_t bit_mask) -{ - return ((cpu_caps.vmx_vpid & bit_mask) != 0U); + return ((cpu_caps.vmx_ept_vpid & bit_mask) != 0U); } void init_pcpu_model_name(void) @@ -417,18 +407,18 @@ static int32_t check_vmx_mmu_cap(void) { int32_t ret = 0; - if (!pcpu_has_vmx_ept_cap(VMX_EPT_INVEPT)) { + if (!pcpu_has_vmx_ept_vpid_cap(VMX_EPT_INVEPT)) { printf("%s, invept not supported\n", __func__); ret = -ENODEV; - } else if (!pcpu_has_vmx_vpid_cap(VMX_VPID_INVVPID) || - !pcpu_has_vmx_vpid_cap(VMX_VPID_INVVPID_SINGLE_CONTEXT) || - !pcpu_has_vmx_vpid_cap(VMX_VPID_INVVPID_GLOBAL_CONTEXT)) { + } else if (!pcpu_has_vmx_ept_vpid_cap(VMX_VPID_INVVPID) || + !pcpu_has_vmx_ept_vpid_cap(VMX_VPID_INVVPID_SINGLE_CONTEXT) || + !pcpu_has_vmx_ept_vpid_cap(VMX_VPID_INVVPID_GLOBAL_CONTEXT)) { printf("%s, invvpid not supported\n", __func__); ret = -ENODEV; - } else if (!pcpu_has_vmx_ept_cap(VMX_EPT_2MB_PAGE)) { + } else if (!pcpu_has_vmx_ept_vpid_cap(VMX_EPT_2MB_PAGE)) { printf("%s, ept not support 2MB large page\n", __func__); ret = -ENODEV; - } else if (pcpu_has_vmx_ept_cap(VMX_EPT_1GB_PAGE) != + } else if (pcpu_has_vmx_ept_vpid_cap(VMX_EPT_1GB_PAGE) != pcpu_has_cap(X86_FEATURE_PAGE1GB)) { /* This just for simple large_page_support in arch/x86/page.c */ ret = -ENODEV; @@ -463,7 +453,7 @@ int32_t detect_hardware_support(void) __func__, boot_cpu_data.phys_bits, MAXIMUM_PA_WIDTH); ret = -ENODEV; } else if ((boot_cpu_data.phys_bits > 39U) && (!pcpu_has_cap(X86_FEATURE_PAGE1GB) || - !pcpu_has_vmx_ept_cap(VMX_EPT_1GB_PAGE))) { + !pcpu_has_vmx_ept_vpid_cap(VMX_EPT_1GB_PAGE))) { printf("%s, physical-address width %d over 39 bits must support 1GB large page\n", __func__, boot_cpu_data.phys_bits); ret = -ENODEV; diff --git a/hypervisor/arch/x86/guest/ept.c b/hypervisor/arch/x86/guest/ept.c index 50c1cf6b8..3e24c8a0b 100644 --- a/hypervisor/arch/x86/guest/ept.c +++ b/hypervisor/arch/x86/guest/ept.c @@ -100,7 +100,7 @@ static inline bool ept_large_page_support(enum _page_table_level level, __unused if (level == IA32E_PD) { support = true; } else if (level == IA32E_PDPT) { - support = pcpu_has_vmx_ept_cap(VMX_EPT_1GB_PAGE); + support = pcpu_has_vmx_ept_vpid_cap(VMX_EPT_1GB_PAGE); } else { support = false; } diff --git a/hypervisor/arch/x86/guest/vept.c b/hypervisor/arch/x86/guest/vept.c index a45eddcdb..9d9af6209 100644 --- a/hypervisor/arch/x86/guest/vept.c +++ b/hypervisor/arch/x86/guest/vept.c @@ -302,7 +302,7 @@ static bool is_ept_entry_misconfig(uint64_t ept_entry, enum _page_table_level pt is_misconfig = ((ept_entry & (EPT_RD | EPT_WR)) == EPT_WR); /* Execute-only is not supported */ - if (!pcpu_has_vmx_ept_cap(VMX_EPT_EXECUTE_ONLY)) { + if (!pcpu_has_vmx_ept_vpid_cap(VMX_EPT_EXECUTE_ONLY)) { /* Execute w/o Read, misconfigured */ is_misconfig = is_misconfig || ((ept_entry & (EPT_RD | EPT_EXE)) == EPT_EXE); /* diff --git a/hypervisor/arch/x86/mmu.c b/hypervisor/arch/x86/mmu.c index b372bc9de..ef35c4eb7 100644 --- a/hypervisor/arch/x86/mmu.c +++ b/hypervisor/arch/x86/mmu.c @@ -72,7 +72,7 @@ static inline bool ppt_large_page_support(enum _page_table_level level, __unused if (level == IA32E_PD) { support = true; } else if (level == IA32E_PDPT) { - support = pcpu_has_vmx_ept_cap(VMX_EPT_1GB_PAGE); + support = pcpu_has_vmx_ept_vpid_cap(VMX_EPT_1GB_PAGE); } else { support = false; } @@ -140,10 +140,10 @@ void invept(const void *eptp) { struct invept_desc desc = {0}; - if (pcpu_has_vmx_ept_cap(VMX_EPT_INVEPT_SINGLE_CONTEXT)) { + if (pcpu_has_vmx_ept_vpid_cap(VMX_EPT_INVEPT_SINGLE_CONTEXT)) { desc.eptp = hva2hpa(eptp) | (3UL << 3U) | 6UL; local_invept(INVEPT_TYPE_SINGLE_CONTEXT, desc); - } else if (pcpu_has_vmx_ept_cap(VMX_EPT_INVEPT_GLOBAL_CONTEXT)) { + } else if (pcpu_has_vmx_ept_vpid_cap(VMX_EPT_INVEPT_GLOBAL_CONTEXT)) { local_invept(INVEPT_TYPE_ALL_CONTEXTS, desc); } else { /* Neither type of INVEPT is supported. Skip. */ diff --git a/hypervisor/include/arch/x86/asm/cpu_caps.h b/hypervisor/include/arch/x86/asm/cpu_caps.h index 5559eef51..87ed8c011 100644 --- a/hypervisor/include/arch/x86/asm/cpu_caps.h +++ b/hypervisor/include/arch/x86/asm/cpu_caps.h @@ -50,8 +50,7 @@ bool disable_host_monitor_wait(void); bool is_apl_platform(void); bool is_apicv_advanced_feature_supported(void); 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 pcpu_has_vmx_ept_vpid_cap(uint64_t bit_mask); bool is_apl_platform(void); bool has_core_cap(uint32_t bit_mask); bool is_ac_enabled(void); diff --git a/hypervisor/include/arch/x86/asm/vmx.h b/hypervisor/include/arch/x86/asm/vmx.h index 2404f2cc6..bd9f856b8 100644 --- a/hypervisor/include/arch/x86/asm/vmx.h +++ b/hypervisor/include/arch/x86/asm/vmx.h @@ -341,28 +341,28 @@ #define VMX_PROCBASED_CTLS3_LOADIWKEY (1U<<0U) /* MSR_IA32_VMX_EPT_VPID_CAP: EPT and VPID capability bits */ -#define VMX_EPT_EXECUTE_ONLY (1U << 0U) -#define VMX_EPT_PAGE_WALK_4 (1U << 6U) -#define VMX_EPT_PAGE_WALK_5 (1U << 7U) -#define VMX_EPTP_UC (1U << 8U) -#define VMX_EPTP_WB (1U << 14U) -#define VMX_EPT_2MB_PAGE (1U << 16U) -#define VMX_EPT_1GB_PAGE (1U << 17U) -#define VMX_EPT_INVEPT (1U << 20U) -#define VMX_EPT_AD (1U << 21U) -#define VMX_EPT_INVEPT_SINGLE_CONTEXT (1U << 25U) -#define VMX_EPT_INVEPT_GLOBAL_CONTEXT (1U << 26U) +#define VMX_EPT_EXECUTE_ONLY (1UL << 0U) +#define VMX_EPT_PAGE_WALK_4 (1UL << 6U) +#define VMX_EPT_PAGE_WALK_5 (1UL << 7U) +#define VMX_EPTP_UC (1UL << 8U) +#define VMX_EPTP_WB (1UL << 14U) +#define VMX_EPT_2MB_PAGE (1UL << 16U) +#define VMX_EPT_1GB_PAGE (1UL << 17U) +#define VMX_EPT_INVEPT (1UL << 20U) +#define VMX_EPT_AD (1UL << 21U) +#define VMX_EPT_INVEPT_SINGLE_CONTEXT (1UL << 25U) +#define VMX_EPT_INVEPT_GLOBAL_CONTEXT (1UL << 26U) #define VMX_VPID_TYPE_INDIVIDUAL_ADDR 0UL #define VMX_VPID_TYPE_SINGLE_CONTEXT 1UL #define VMX_VPID_TYPE_ALL_CONTEXT 2UL #define VMX_VPID_TYPE_SINGLE_NON_GLOBAL 3UL -#define VMX_VPID_INVVPID (1U << 0U) /* (32 - 32) */ -#define VMX_VPID_INVVPID_INDIVIDUAL_ADDR (1U << 8U) /* (40 - 32) */ -#define VMX_VPID_INVVPID_SINGLE_CONTEXT (1U << 9U) /* (41 - 32) */ -#define VMX_VPID_INVVPID_GLOBAL_CONTEXT (1U << 10U) /* (42 - 32) */ -#define VMX_VPID_INVVPID_SINGLE_NON_GLOBAL (1U << 11U) /* (43 - 32) */ +#define VMX_VPID_INVVPID (1UL << 32U) +#define VMX_VPID_INVVPID_INDIVIDUAL_ADDR (1UL << 40U) +#define VMX_VPID_INVVPID_SINGLE_CONTEXT (1UL << 41U) +#define VMX_VPID_INVVPID_GLOBAL_CONTEXT (1UL << 42U) +#define VMX_VPID_INVVPID_SINGLE_NON_GLOBAL (1UL << 43U) #define VMX_EPT_MT_EPTE_SHIFT 3U #define VMX_EPTP_PWL_MASK 0x38UL