@@ -162,7 +162,6 @@ static int cf_check parse_ept_param_runt
/* Dynamic (run-time adjusted) execution control flags. */
struct vmx_caps __ro_after_init vmx_caps;
-u64 vmx_ept_vpid_cap __read_mostly;
static uint64_t __read_mostly vmx_vmfunc;
static DEFINE_PER_CPU_READ_MOSTLY(paddr_t, vmxon_region);
@@ -256,7 +255,6 @@ static int vmx_init_vmcs_config(bool bsp
{
u32 vmx_basic_msr_low, vmx_basic_msr_high, min, opt;
struct vmx_caps caps = {};
- u64 _vmx_ept_vpid_cap = 0;
u64 _vmx_misc_cap = 0;
u64 _vmx_vmfunc = 0;
bool mismatch = false;
@@ -365,10 +363,10 @@ static int vmx_init_vmcs_config(bool bsp
if ( caps.secondary_exec_control & (SECONDARY_EXEC_ENABLE_EPT |
SECONDARY_EXEC_ENABLE_VPID) )
{
- rdmsrl(MSR_IA32_VMX_EPT_VPID_CAP, _vmx_ept_vpid_cap);
+ rdmsr(MSR_IA32_VMX_EPT_VPID_CAP, caps.ept, caps.vpid);
if ( !opt_ept_ad )
- _vmx_ept_vpid_cap &= ~VMX_EPT_AD_BIT;
+ caps.ept &= ~VMX_EPT_AD_BIT;
/*
* Additional sanity checking before using EPT:
@@ -381,9 +379,9 @@ static int vmx_init_vmcs_config(bool bsp
*
* Or we just don't use EPT.
*/
- if ( !(_vmx_ept_vpid_cap & VMX_EPT_MEMORY_TYPE_WB) ||
- !(_vmx_ept_vpid_cap & VMX_EPT_WALK_LENGTH_4_SUPPORTED) ||
- !(_vmx_ept_vpid_cap & VMX_EPT_INVEPT_ALL_CONTEXT) )
+ if ( !(caps.ept & VMX_EPT_MEMORY_TYPE_WB) ||
+ !(caps.ept & VMX_EPT_WALK_LENGTH_4_SUPPORTED) ||
+ !(caps.ept & VMX_EPT_INVEPT_ALL_CONTEXT) )
caps.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT;
/*
@@ -392,11 +390,11 @@ static int vmx_init_vmcs_config(bool bsp
*
* Or we just don't use VPID.
*/
- if ( !(_vmx_ept_vpid_cap & VMX_VPID_INVVPID_ALL_CONTEXT) )
+ if ( !(caps.vpid & VMX_VPID_INVVPID_ALL_CONTEXT) )
caps.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
/* EPT A/D bits is required for PML */
- if ( !(_vmx_ept_vpid_cap & VMX_EPT_AD_BIT) )
+ if ( !(caps.ept & VMX_EPT_AD_BIT) )
caps.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_PML;
}
@@ -488,7 +486,6 @@ static int vmx_init_vmcs_config(bool bsp
{
/* First time through. */
vmx_caps = caps;
- vmx_ept_vpid_cap = _vmx_ept_vpid_cap;
vmx_caps.basic_msr = ((uint64_t)vmx_basic_msr_high << 32) |
vmx_basic_msr_low;
vmx_vmfunc = _vmx_vmfunc;
@@ -529,9 +526,8 @@ static int vmx_init_vmcs_config(bool bsp
mismatch |= cap_check(
"VMEntry Control",
vmx_caps.vmentry_control, caps.vmentry_control);
- mismatch |= cap_check(
- "EPT and VPID Capability",
- vmx_ept_vpid_cap, _vmx_ept_vpid_cap);
+ mismatch |= cap_check("EPT Capability", vmx_caps.ept, caps.ept);
+ mismatch |= cap_check("VPID Capability", vmx_caps.vpid, caps.vpid);
mismatch |= cap_check(
"VMFUNC Capability",
vmx_vmfunc, _vmx_vmfunc);
@@ -2199,7 +2195,6 @@ int __init vmx_vmcs_init(void)
* Make sure all dependent features are off as well.
*/
memset(&vmx_caps, 0, sizeof(vmx_caps));
- vmx_ept_vpid_cap = 0;
vmx_vmfunc = 0;
}
@@ -274,12 +274,11 @@ void vmx_vmcs_reload(struct vcpu *v);
#define VMX_EPT_AD_BIT 0x00200000
#define VMX_EPT_INVEPT_SINGLE_CONTEXT 0x02000000
#define VMX_EPT_INVEPT_ALL_CONTEXT 0x04000000
-#define VMX_VPID_INVVPID_INSTRUCTION 0x00100000000ULL
-#define VMX_VPID_INVVPID_INDIVIDUAL_ADDR 0x10000000000ULL
-#define VMX_VPID_INVVPID_SINGLE_CONTEXT 0x20000000000ULL
-#define VMX_VPID_INVVPID_ALL_CONTEXT 0x40000000000ULL
-#define VMX_VPID_INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL 0x80000000000ULL
-extern u64 vmx_ept_vpid_cap;
+#define VMX_VPID_INVVPID_INSTRUCTION 0x00000001
+#define VMX_VPID_INVVPID_INDIVIDUAL_ADDR 0x00000100
+#define VMX_VPID_INVVPID_SINGLE_CONTEXT 0x00000200
+#define VMX_VPID_INVVPID_ALL_CONTEXT 0x00000400
+#define VMX_VPID_INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL 0x00000800
#define VMX_MISC_ACTIVITY_MASK 0x000001c0
#define VMX_MISC_PROC_TRACE 0x00004000
@@ -297,6 +296,8 @@ struct vmx_caps {
uint64_t tertiary_exec_control;
uint32_t vmexit_control;
uint32_t vmentry_control;
+ uint32_t ept;
+ uint32_t vpid;
};
extern struct vmx_caps vmx_caps;
@@ -279,17 +279,17 @@ typedef union cr_access_qual {
extern uint8_t posted_intr_vector;
#define cpu_has_vmx_ept_exec_only_supported \
- (vmx_ept_vpid_cap & VMX_EPT_EXEC_ONLY_SUPPORTED)
+ (vmx_caps.ept & VMX_EPT_EXEC_ONLY_SUPPORTED)
#define cpu_has_vmx_ept_wl4_supported \
- (vmx_ept_vpid_cap & VMX_EPT_WALK_LENGTH_4_SUPPORTED)
-#define cpu_has_vmx_ept_mt_uc (vmx_ept_vpid_cap & VMX_EPT_MEMORY_TYPE_UC)
-#define cpu_has_vmx_ept_mt_wb (vmx_ept_vpid_cap & VMX_EPT_MEMORY_TYPE_WB)
-#define cpu_has_vmx_ept_2mb (vmx_ept_vpid_cap & VMX_EPT_SUPERPAGE_2MB)
-#define cpu_has_vmx_ept_1gb (vmx_ept_vpid_cap & VMX_EPT_SUPERPAGE_1GB)
-#define cpu_has_vmx_ept_ad (vmx_ept_vpid_cap & VMX_EPT_AD_BIT)
+ (vmx_caps.ept & VMX_EPT_WALK_LENGTH_4_SUPPORTED)
+#define cpu_has_vmx_ept_mt_uc (vmx_caps.ept & VMX_EPT_MEMORY_TYPE_UC)
+#define cpu_has_vmx_ept_mt_wb (vmx_caps.ept & VMX_EPT_MEMORY_TYPE_WB)
+#define cpu_has_vmx_ept_2mb (vmx_caps.ept & VMX_EPT_SUPERPAGE_2MB)
+#define cpu_has_vmx_ept_1gb (vmx_caps.ept & VMX_EPT_SUPERPAGE_1GB)
+#define cpu_has_vmx_ept_ad (vmx_caps.ept & VMX_EPT_AD_BIT)
#define cpu_has_vmx_ept_invept_single_context \
- (vmx_ept_vpid_cap & VMX_EPT_INVEPT_SINGLE_CONTEXT)
+ (vmx_caps.ept & VMX_EPT_INVEPT_SINGLE_CONTEXT)
#define EPT_2MB_SHIFT 16
#define EPT_1GB_SHIFT 17
@@ -300,11 +300,11 @@ extern uint8_t posted_intr_vector;
#define INVEPT_ALL_CONTEXT 2
#define cpu_has_vmx_vpid_invvpid_individual_addr \
- (vmx_ept_vpid_cap & VMX_VPID_INVVPID_INDIVIDUAL_ADDR)
+ (vmx_caps.vpid & VMX_VPID_INVVPID_INDIVIDUAL_ADDR)
#define cpu_has_vmx_vpid_invvpid_single_context \
- (vmx_ept_vpid_cap & VMX_VPID_INVVPID_SINGLE_CONTEXT)
+ (vmx_caps.vpid & VMX_VPID_INVVPID_SINGLE_CONTEXT)
#define cpu_has_vmx_vpid_invvpid_single_context_retaining_global \
- (vmx_ept_vpid_cap & VMX_VPID_INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL)
+ (vmx_caps.vpid & VMX_VPID_INVVPID_SINGLE_CONTEXT_RETAINING_GLOBAL)
#define INVVPID_INDIVIDUAL_ADDR 0
#define INVVPID_SINGLE_CONTEXT 1
... to fields in the capability/controls struct: Take the opportunity and split the two halves into separate EPT and VPID fields. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- v3: Re-base. v2: New.