From: Peter Feiner <pfeiner@xxxxxxxxxx> Signed-off-by: Peter Feiner <pfeiner@xxxxxxxxxx> Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx> --- x86/vmx.c | 30 ++++++++++++++++++++++++++++++ x86/vmx.h | 6 ++++++ x86/vmx_tests.c | 6 ++---- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/x86/vmx.c b/x86/vmx.c index c003d5d11e63..f7a34d20ab6a 100644 --- a/x86/vmx.c +++ b/x86/vmx.c @@ -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) { diff --git a/x86/vmx.h b/x86/vmx.h index 4b899aa69145..890cdcc9e67f 100644 --- a/x86/vmx.h +++ b/x86/vmx.h @@ -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); diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index be01709d3057..bf45bd2566ca 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -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; } -- 2.12.2.816.g2cccc81164-goog