@@ -973,6 +973,36 @@ void set_ept_pte(unsigned long *pml4, unsigned long guest_addr,
pt[offset] = pte_val;
}
+bool ept_2m_supported(void)
+{
+ return ept_vpid.val & EPT_CAP_2M_PAGE;
+}
+
+bool ept_1g_supported(void)
+{
+ return ept_vpid.val & EPT_CAP_1G_PAGE;
+}
+
+bool ept_huge_pages_supported(int level)
+{
+ if (level == 2)
+ return ept_2m_supported();
+ else if (level == 3)
+ return ept_1g_supported();
+ else
+ return false;
+}
+
+bool ept_execute_only_supported(void)
+{
+ return ept_vpid.val & EPT_CAP_WT;
+}
+
+bool ept_ad_bits_supported(void)
+{
+ return ept_vpid.val & EPT_CAP_AD_FLAG;
+}
+
void vpid_sync(int type, u16 vpid)
{
switch(type) {
@@ -699,6 +699,12 @@ void check_ept_ad(unsigned long *pml4, u64 guest_cr3,
void clear_ept_ad(unsigned long *pml4, u64 guest_cr3,
unsigned long guest_addr);
+bool ept_2m_supported(void);
+bool ept_1g_supported(void);
+bool ept_huge_pages_supported(int level);
+bool ept_execute_only_supported(void);
+bool ept_ad_bits_supported(void);
+
void enter_guest(void);
typedef void (*test_guest_func)(void);
@@ -943,7 +943,6 @@ static int insn_intercept_exit_handler()
/* Enables EPT and sets up the identity map. */
static int setup_ept(bool enable_ad)
{
- int support_2m;
unsigned long end_of_memory;
u32 ctrl_cpu[2];
@@ -983,15 +982,14 @@ static int setup_ept(bool enable_ad)
if (enable_ad)
eptp |= EPTP_AD_FLAG;
vmcs_write(EPTP, eptp);
- support_2m = !!(ept_vpid.val & EPT_CAP_2M_PAGE);
end_of_memory = fwcfg_get_u64(FW_CFG_RAM_SIZE);
if (end_of_memory < (1ul << 32))
end_of_memory = (1ul << 32);
/* Cannot use large EPT pages if we need to track EPT
* accessed/dirty bits at 4K granularity.
*/
- setup_ept_range(pml4, 0, end_of_memory,
- 0, !enable_ad && support_2m,
+ setup_ept_range(pml4, 0, end_of_memory, 0,
+ !enable_ad && ept_2m_supported(),
EPT_WA | EPT_RA | EPT_EA);
return 0;
}