Skip to content

Commit 80d194c

Browse files
lifeixjren1
authored andcommitted
hv: vmx_capability: add cpu_has_vmx_ept/vpid_cap API
Refine and simple vmx_capability API defination. Signed-off-by: Li, Fei1 <fei1.li@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent d7d2ef8 commit 80d194c

File tree

3 files changed

+54
-63
lines changed

3 files changed

+54
-63
lines changed

hypervisor/arch/x86/mmu.c

Lines changed: 26 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,15 @@ enum mem_map_request_type {
4444
PAGING_REQUEST_TYPE_UNKNOWN,
4545
};
4646

47-
struct mm_capability {
48-
bool ept_x_only_supported;
49-
/* EPT and MMU 1-GByte page supported flag */
50-
bool ept_1gb_page_supported;
51-
bool invept_supported;
52-
bool invept_single_context_supported;
53-
bool invept_global_context_supported;
54-
bool invvpid_supported;
55-
bool invvpid_single_context_supported;
56-
bool invvpid_global_context_supported;
47+
static struct vmx_capability {
48+
uint32_t ept;
49+
uint32_t vpid;
50+
} vmx_caps;
51+
52+
static struct mm_capability {
53+
/* MMU 1-GByte page supported flag */
5754
bool mmu_1gb_page_supported;
58-
};
59-
static struct mm_capability mm_caps;
55+
} mm_caps;
6056

6157
#define INVEPT_TYPE_SINGLE_CONTEXT 1UL
6258
#define INVEPT_TYPE_ALL_CONTEXTS 2UL
@@ -93,31 +89,25 @@ static inline void inv_tlb_one_page(void *addr)
9389
asm volatile ("invlpg (%0)" : : "r" (addr) : "memory");
9490
}
9591

92+
static inline bool cpu_has_vmx_ept_cap(uint32_t bit_mask)
93+
{
94+
return !!(vmx_caps.ept & bit_mask);
95+
}
96+
97+
static inline bool cpu_has_vmx_vpid_cap(uint32_t bit_mask)
98+
{
99+
return !!(vmx_caps.vpid & bit_mask);
100+
}
101+
96102
static void check_mmu_capability(void)
97103
{
98104
uint64_t val;
99105
uint32_t eax, ebx, ecx, edx;
100106

101-
memset(&mm_caps, 0, sizeof(struct mm_capability));
102-
103107
/* Read the MSR register of EPT and VPID Capability - SDM A.10 */
104108
val = msr_read(MSR_IA32_VMX_EPT_VPID_CAP);
105-
mm_caps.ept_x_only_supported = (val & MSR_VMX_EPT_X_ONLY)
106-
? (true) : (false);
107-
mm_caps.ept_1gb_page_supported = (val & MSR_VMX_EPT_VPID_CAP_1GB)
108-
? (true) : (false);
109-
mm_caps.invept_supported =
110-
(val & MSR_VMX_INVEPT) ? (true) : (false);
111-
mm_caps.invept_single_context_supported =
112-
(val & MSR_VMX_INVEPT_SINGLE_CONTEXT) ? (true) : (false);
113-
mm_caps.invept_global_context_supported =
114-
(val & MSR_VMX_INVEPT_GLOBAL_CONTEXT) ? (true) : (false);
115-
mm_caps.invvpid_supported =
116-
(val & MSR_VMX_INVVPID) ? (true) : (false);
117-
mm_caps.invvpid_single_context_supported =
118-
(val & MSR_VMX_INVVPID_SINGLE_CONTEXT) ? (true) : (false);
119-
mm_caps.invvpid_global_context_supported =
120-
(val & MSR_VMX_INVVPID_GLOBAL_CONTEXT) ? (true) : (false);
109+
vmx_caps.ept = (uint32_t) val;
110+
vmx_caps.vpid = (uint32_t) (val >> 32);
121111

122112
/* Read CPUID to check if PAGE1GB is supported
123113
* SDM 4.1.4 If CPUID.80000001H:EDX.Page1GB[bit26]=1,
@@ -127,32 +117,15 @@ static void check_mmu_capability(void)
127117
mm_caps.mmu_1gb_page_supported = (edx & CPUID_EDX_PAGE1GB) ?
128118
(true) : (false);
129119

130-
if (!mm_caps.invept_supported)
120+
if (!cpu_has_vmx_ept_cap(VMX_EPT_INVEPT))
131121
panic("invept must be supported");
132122
}
133123

134-
static inline bool check_ept_x_only_support(void)
135-
{
136-
return mm_caps.ept_x_only_supported;
137-
}
138-
139-
static inline bool check_invept_single_support(void)
140-
{
141-
return mm_caps.invept_supported &&
142-
mm_caps.invept_single_context_supported;
143-
}
144-
145-
static inline bool check_invept_global_support(void)
146-
{
147-
return mm_caps.invept_supported &&
148-
mm_caps.invept_global_context_supported;
149-
}
150-
151124
void invept(struct vcpu *vcpu)
152125
{
153126
struct invept_desc desc = {0};
154127

155-
if (check_invept_single_support()) {
128+
if (cpu_has_vmx_ept_cap(VMX_EPT_INVEPT_SINGLE_CONTEXT)) {
156129
desc.eptp = vcpu->vm->arch_vm.nworld_eptp | (3 << 3) | 6;
157130
_invept(INVEPT_TYPE_SINGLE_CONTEXT, desc);
158131
if (vcpu->vm->sworld_control.sworld_enabled) {
@@ -161,7 +134,7 @@ void invept(struct vcpu *vcpu)
161134
_invept(INVEPT_TYPE_SINGLE_CONTEXT, desc);
162135

163136
}
164-
} else if (check_invept_global_support())
137+
} else if (cpu_has_vmx_ept_cap(VMX_EPT_INVEPT_GLOBAL_CONTEXT))
165138
_invept(INVEPT_TYPE_ALL_CONTEXTS, desc);
166139
}
167140

@@ -170,7 +143,7 @@ static bool check_mmu_1gb_support(struct map_params *map_params)
170143
bool status = false;
171144

172145
if (map_params->page_table_type == PTT_EPT)
173-
status = mm_caps.ept_1gb_page_supported;
146+
status = cpu_has_vmx_ept_cap(VMX_EPT_1GB_PAGE);
174147
else
175148
status = mm_caps.mmu_1gb_page_supported;
176149
return status;
@@ -191,7 +164,7 @@ static inline uint32_t check_page_table_present(int page_table_type,
191164
if ((table_entry == IA32E_EPT_W_BIT) ||
192165
(table_entry == (IA32E_EPT_W_BIT | IA32E_EPT_X_BIT)) ||
193166
((table_entry == IA32E_EPT_X_BIT) &&
194-
!check_ept_x_only_support()))
167+
!cpu_has_vmx_ept_cap(VMX_EPT_EXECUTE_ONLY)))
195168
return PT_MISCFG_PRESENT;
196169
} else {
197170
table_entry &= (IA32E_COMM_P_BIT);
@@ -905,7 +878,7 @@ static uint64_t break_page_table(struct map_params *map_params, void *paddr,
905878
* current page size, obtain the starting physical address
906879
* aligned of current page size
907880
*/
908-
pa = ((((uint64_t)paddr) / page_size) * page_size);
881+
pa = ((uint64_t)paddr) & ~(page_size - 1);
909882
if (map_params->page_table_type == PTT_EPT) {
910883
/* Keep original attribute(here &0x3f)
911884
* bit 0(R) bit1(W) bit2(X) bit3~5 MT

hypervisor/include/arch/x86/msr.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -515,16 +515,6 @@
515515
/* LINCROFT specific MSRs */
516516
#define MSR_LNC_BIOS_CACHE_AS_RAM 0x000002E0 /* Configure CAR */
517517

518-
/* MSR_IA32_VMX_EPT_VPID_CAP: EPT and VPID capability bits */
519-
#define MSR_VMX_EPT_X_ONLY (1UL << 0)/* Execute Only */
520-
#define MSR_VMX_EPT_VPID_CAP_1GB (1UL << 17)/* EPT 1GB page */
521-
#define MSR_VMX_INVEPT (1UL << 20)/* INVEPT */
522-
#define MSR_VMX_INVEPT_SINGLE_CONTEXT (1UL << 25)/* INVEPT Single */
523-
#define MSR_VMX_INVEPT_GLOBAL_CONTEXT (1UL << 26)/* INVEPT Global */
524-
#define MSR_VMX_INVVPID (1UL << 32)/* INVVPID */
525-
#define MSR_VMX_INVVPID_SINGLE_CONTEXT (1UL << 41)/* INVVPID Single */
526-
#define MSR_VMX_INVVPID_GLOBAL_CONTEXT (1UL << 42)/* INVVPID Global */
527-
528518
/* EFER bits */
529519
#define MSR_IA32_EFER_SCE_BIT (1<<0)
530520
#define MSR_IA32_EFER_LME_BIT (1<<8) /* IA32e mode enable */

hypervisor/include/arch/x86/vmx.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,34 @@
325325
#define VMX_PROCBASED_CTLS2_EPT_VE (1<<18)
326326
#define VMX_PROCBASED_CTLS2_XSVE_XRSTR (1<<20)
327327

328+
/* MSR_IA32_VMX_EPT_VPID_CAP: EPT and VPID capability bits */
329+
#define VMX_EPT_EXECUTE_ONLY (1 << 0)
330+
#define VMX_EPT_PAGE_WALK_4 (1 << 6)
331+
#define VMX_EPT_PAGE_WALK_5 (1 << 7)
332+
#define VMX_EPTP_UC (1 << 8)
333+
#define VMX_EPTP_WB (1 << 14)
334+
#define VMX_EPT_2MB_PAGE (1 << 16)
335+
#define VMX_EPT_1GB_PAGE (1 << 17)
336+
#define VMX_EPT_INVEPT (1 << 20)
337+
#define VMX_EPT_AD (1 << 21)
338+
#define VMX_EPT_INVEPT_SINGLE_CONTEXT (1 << 25)
339+
#define VMX_EPT_INVEPT_GLOBAL_CONTEXT (1 << 26)
340+
341+
#define VMX_VPID_INVVPID (1 << 0) /* (32 - 32) */
342+
#define VMX_VPID_INVVPID_INDIVIDUAL_ADDR (1 << 8) /* (40 - 32) */
343+
#define VMX_VPID_INVVPID_SINGLE_CONTEXT (1 << 9) /* (41 - 32) */
344+
#define VMX_VPID_INVVPID_GLOBAL_CONTEXT (1 << 10) /* (42 - 32) */
345+
#define VMX_VPID_INVVPID_SINGLE_NON_GLOBAL (1 << 11) /* (43 - 32) */
346+
347+
#define VMX_EPT_MT_EPTE_SHIFT 3
348+
#define VMX_EPTP_PWL_MASK 0x38
349+
#define VMX_EPTP_PWL_4 0x18
350+
#define VMX_EPTP_PWL_5 0x20
351+
#define VMX_EPTP_AD_ENABLE_BIT (1 << 6)
352+
#define VMX_EPTP_MT_MASK 0x7
353+
#define VMX_EPTP_MT_WB 0x6
354+
#define VMX_EPTP_MT_UC 0x0
355+
328356
/* VMX exit control bits */
329357
#define VMX_EXIT_CTLS_SAVE_DBG (1<<2)
330358
#define VMX_EXIT_CTLS_HOST_ADDR64 (1<<9)

0 commit comments

Comments
 (0)