[kvm-unit-tests PATCH 25/32] x86: ept assertions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Peter Feiner <pfeiner@xxxxxxxxxx>

The upper bounds on level in set_ept_pte and install_ept_entry were
just wrong. There's nothing wrong with setting an EPT PTE at the
highest (512GiB) level.

Got rid of unused error return values and replaced them with
assertions. Nobody was checking the return values, so these functions
were silently failing.

Change-Id: I4db1e1c2a0c050f5f69cce28df460b4c8ce10d1c
Signed-off-by: David Matlack <dmatlack@xxxxxxxxxx>
---
 x86/vmx.c | 23 ++++++++++++-----------
 x86/vmx.h |  2 +-
 2 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/x86/vmx.c b/x86/vmx.c
index cae650ae2e68..c003d5d11e63 100644
--- a/x86/vmx.c
+++ b/x86/vmx.c
@@ -724,6 +724,9 @@ void install_ept_entry(unsigned long *pml4,
 	unsigned long *pt = pml4;
 	unsigned offset;
 
+	/* EPT only uses 48 bits of GPA. */
+	assert(guest_addr < (1ul << 48));
+
 	for (level = EPT_PAGE_LEVEL; level > pte_level; --level) {
 		offset = (guest_addr >> EPT_LEVEL_SHIFT(level))
 				& EPT_PGDIR_MASK;
@@ -813,17 +816,17 @@ unsigned long get_ept_pte(unsigned long *pml4,
 	unsigned long *pt = pml4, pte;
 	unsigned offset;
 
-	if (level < 1 || level > 3)
-		return -1;
+	assert(level >= 1 && level <= 4);
+
 	for (l = EPT_PAGE_LEVEL; ; --l) {
 		offset = (guest_addr >> EPT_LEVEL_SHIFT(l)) & EPT_PGDIR_MASK;
 		pte = pt[offset];
 		if (!(pte & (EPT_PRESENT)))
-			return 0;
+			return -1;
 		if (l == level)
 			break;
 		if (l < 4 && (pte & EPT_LARGE_PAGE))
-			return pte;
+			return -1;
 		pt = (unsigned long *)(pte & EPT_ADDR_MASK);
 	}
 	offset = (guest_addr >> EPT_LEVEL_SHIFT(l)) & EPT_PGDIR_MASK;
@@ -950,26 +953,24 @@ void ept_sync(int type, u64 eptp)
 	}
 }
 
-int set_ept_pte(unsigned long *pml4, unsigned long guest_addr,
-		int level, u64 pte_val)
+void set_ept_pte(unsigned long *pml4, unsigned long guest_addr,
+		 int level, u64 pte_val)
 {
 	int l;
 	unsigned long *pt = pml4;
 	unsigned offset;
 
-	if (level < 1 || level > 3)
-		return -1;
+	assert(level >= 1 && level <= 4);
+
 	for (l = EPT_PAGE_LEVEL; ; --l) {
 		offset = (guest_addr >> EPT_LEVEL_SHIFT(l)) & EPT_PGDIR_MASK;
 		if (l == level)
 			break;
-		if (!(pt[offset] & (EPT_PRESENT)))
-			return -1;
+		assert(pt[offset] & EPT_PRESENT);
 		pt = (unsigned long *)(pt[offset] & EPT_ADDR_MASK);
 	}
 	offset = (guest_addr >> EPT_LEVEL_SHIFT(l)) & EPT_PGDIR_MASK;
 	pt[offset] = pte_val;
-	return 0;
 }
 
 void vpid_sync(int type, u16 vpid)
diff --git a/x86/vmx.h b/x86/vmx.h
index 966fff653561..4b899aa69145 100644
--- a/x86/vmx.h
+++ b/x86/vmx.h
@@ -691,7 +691,7 @@ void setup_ept_range(unsigned long *pml4, unsigned long start,
 		     unsigned long len, int map_1g, int map_2m, u64 perm);
 unsigned long get_ept_pte(unsigned long *pml4,
 		unsigned long guest_addr, int level);
-int set_ept_pte(unsigned long *pml4, unsigned long guest_addr,
+void set_ept_pte(unsigned long *pml4, unsigned long guest_addr,
 		int level, u64 pte_val);
 void check_ept_ad(unsigned long *pml4, u64 guest_cr3,
 		  unsigned long guest_addr, int expected_gpa_ad,
-- 
2.12.2.816.g2cccc81164-goog




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux