diff mbox

[kvm-unit-tests,28/32] x86: ept capability utilities

Message ID 20170421005004.137260-29-dmatlack@google.com (mailing list archive)
State New, archived
Headers show

Commit Message

David Matlack April 21, 2017, 12:50 a.m. UTC
From: Peter Feiner <pfeiner@google.com>

Signed-off-by: Peter Feiner <pfeiner@google.com>
Signed-off-by: David Matlack <dmatlack@google.com>
---
 x86/vmx.c       | 30 ++++++++++++++++++++++++++++++
 x86/vmx.h       |  6 ++++++
 x86/vmx_tests.c |  6 ++----
 3 files changed, 38 insertions(+), 4 deletions(-)
diff mbox

Patch

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;
 }