[PATCH kvm-unit-tests 09/18] x86: introduce pgd_t and pteval_t

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

 



Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 lib/x86/asm/page.h |  3 +++
 lib/x86/vm.c       | 60 ++++++++++++++++++++++++------------------------------
 lib/x86/vm.h       | 30 +++++++++++++--------------
 3 files changed, 44 insertions(+), 49 deletions(-)

diff --git a/lib/x86/asm/page.h b/lib/x86/asm/page.h
index 562594d..073580a 100644
--- a/lib/x86/asm/page.h
+++ b/lib/x86/asm/page.h
@@ -10,6 +10,9 @@
 #include <linux/const.h>
 #include <bitops.h>
 
+typedef unsigned long pteval_t;
+typedef unsigned long pgd_t;
+
 #define PAGE_SHIFT	12
 #define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK	(~(PAGE_SIZE-1))
diff --git a/lib/x86/vm.c b/lib/x86/vm.c
index a5d3aeb..0fcc94c 100644
--- a/lib/x86/vm.c
+++ b/lib/x86/vm.c
@@ -3,20 +3,20 @@
 #include "vmalloc.h"
 #include "alloc_page.h"
 
-unsigned long *install_pte(unsigned long *cr3,
-			   int pte_level,
-			   void *virt,
-			   unsigned long pte,
-			   unsigned long *pt_page)
+pteval_t *install_pte(pgd_t *cr3,
+		      int pte_level,
+		      void *virt,
+		      pteval_t pte,
+		      pteval_t *pt_page)
 {
     int level;
-    unsigned long *pt = cr3;
+    pteval_t *pt = cr3;
     unsigned offset;
 
     for (level = PAGE_LEVEL; level > pte_level; --level) {
-	offset = PGDIR_OFFSET((unsigned long)virt, level);
+	offset = PGDIR_OFFSET((uintptr_t)virt, level);
 	if (!(pt[offset] & PT_PRESENT_MASK)) {
-	    unsigned long *new_pt = pt_page;
+	    pteval_t *new_pt = pt_page;
             if (!new_pt)
                 new_pt = alloc_page();
             else
@@ -26,7 +26,7 @@ unsigned long *install_pte(unsigned long *cr3,
 	}
 	pt = phys_to_virt(pt[offset] & PT_ADDR_MASK);
     }
-    offset = PGDIR_OFFSET((unsigned long)virt, level);
+    offset = PGDIR_OFFSET((uintptr_t)virt, level);
     pt[offset] = pte;
     return &pt[offset];
 }
@@ -35,19 +35,19 @@ unsigned long *install_pte(unsigned long *cr3,
  * Finds last PTE in the mapping of @virt that's at or above @lowest_level. The
  * returned PTE isn't necessarily present, but its parent is.
  */
-struct pte_search find_pte_level(unsigned long *cr3, void *virt,
+struct pte_search find_pte_level(pgd_t *cr3, void *virt,
 				 int lowest_level)
 {
-	unsigned long *pt = cr3, pte;
+	pteval_t *pt = cr3, pte;
 	unsigned offset;
-	unsigned long shift;
+	unsigned shift;
 	struct pte_search r;
 
 	assert(lowest_level >= 1 && lowest_level <= PAGE_LEVEL);
 
 	for (r.level = PAGE_LEVEL;; --r.level) {
 		shift = (r.level - 1) * PGDIR_WIDTH + 12;
-		offset = ((unsigned long)virt >> shift) & PGDIR_MASK;
+		offset = ((uintptr_t)virt >> shift) & PGDIR_MASK;
 		r.pte = &pt[offset];
 		pte = *r.pte;
 
@@ -68,7 +68,7 @@ struct pte_search find_pte_level(unsigned long *cr3, void *virt,
  * Returns the leaf PTE in the mapping of @virt (i.e., 4K PTE or a present huge
  * PTE). Returns NULL if no leaf PTE exists.
  */
-unsigned long *get_pte(unsigned long *cr3, void *virt)
+pteval_t *get_pte(pgd_t *cr3, void *virt)
 {
 	struct pte_search search;
 
@@ -81,7 +81,7 @@ unsigned long *get_pte(unsigned long *cr3, void *virt)
  * Returns NULL if the PT at @pte_level isn't present (i.e., the mapping at
  * @pte_level - 1 isn't present).
  */
-unsigned long *get_pte_level(unsigned long *cr3, void *virt, int pte_level)
+pteval_t *get_pte_level(pgd_t *cr3, void *virt, int pte_level)
 {
 	struct pte_search search;
 
@@ -89,27 +89,22 @@ unsigned long *get_pte_level(unsigned long *cr3, void *virt, int pte_level)
 	return search.level == pte_level ? search.pte : NULL;
 }
 
-unsigned long *install_large_page(unsigned long *cr3,
-				  unsigned long phys,
-				  void *virt)
+pteval_t *install_large_page(pgd_t *cr3, phys_addr_t phys, void *virt)
 {
     return install_pte(cr3, 2, virt,
 		       phys | PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK | PT_PAGE_SIZE_MASK, 0);
 }
 
-unsigned long *install_page(unsigned long *cr3,
-			    unsigned long phys,
-			    void *virt)
+pteval_t *install_page(pgd_t *cr3, phys_addr_t phys, void *virt)
 {
     return install_pte(cr3, 1, virt, phys | PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK, 0);
 }
 
-void install_pages(unsigned long *cr3, unsigned long phys, unsigned long len,
-		   void *virt)
+void install_pages(pgd_t *cr3, phys_addr_t phys, size_t len, void *virt)
 {
-	unsigned long max = (u64)len + (u64)phys;
+	phys_addr_t max = (u64)len + (u64)phys;
 	assert(phys % PAGE_SIZE == 0);
-	assert((unsigned long) virt % PAGE_SIZE == 0);
+	assert((uintptr_t) virt % PAGE_SIZE == 0);
 	assert(len % PAGE_SIZE == 0);
 
 	while (phys + PAGE_SIZE <= max) {
@@ -119,21 +114,20 @@ void install_pages(unsigned long *cr3, unsigned long phys, unsigned long len,
 	}
 }
 
-bool any_present_pages(unsigned long *cr3, void *virt, unsigned long len)
+bool any_present_pages(pgd_t *cr3, void *virt, size_t len)
 {
-	unsigned long max = (unsigned long) virt + len;
-	unsigned long curr;
+	uintptr_t max = (uintptr_t) virt + len;
+	uintptr_t curr;
 
-	for (curr = (unsigned long) virt; curr < max; curr += PAGE_SIZE) {
-		unsigned long *ptep = get_pte(cr3, (void *) curr);
+	for (curr = (uintptr_t) virt; curr < max; curr += PAGE_SIZE) {
+		pteval_t *ptep = get_pte(cr3, (void *) curr);
 		if (ptep && (*ptep & PT_PRESENT_MASK))
 			return true;
 	}
 	return false;
 }
 
-static void setup_mmu_range(unsigned long *cr3, unsigned long start,
-			    unsigned long len)
+static void setup_mmu_range(pgd_t *cr3, phys_addr_t start, size_t len)
 {
 	u64 max = (u64)len + (u64)start;
 	u64 phys = start;
@@ -147,7 +141,7 @@ static void setup_mmu_range(unsigned long *cr3, unsigned long start,
 
 void *setup_mmu(phys_addr_t end_of_memory)
 {
-    unsigned long *cr3 = alloc_page();
+    pgd_t *cr3 = alloc_page();
 
     memset(cr3, 0, PAGE_SIZE);
 
diff --git a/lib/x86/vm.h b/lib/x86/vm.h
index c3211eb..ac0529a 100644
--- a/lib/x86/vm.h
+++ b/lib/x86/vm.h
@@ -14,7 +14,7 @@ uint64_t virt_to_phys_cr3(void *mem);
 
 struct pte_search {
 	int level;
-	unsigned long *pte;
+	pteval_t *pte;
 };
 
 static inline bool found_huge_pte(struct pte_search search)
@@ -29,22 +29,20 @@ static inline bool found_leaf_pte(struct pte_search search)
 	return search.level == 1 || found_huge_pte(search);
 }
 
-struct pte_search find_pte_level(unsigned long *cr3, void *virt,
+struct pte_search find_pte_level(pgd_t *cr3, void *virt,
 				 int lowest_level);
-unsigned long *get_pte(unsigned long *cr3, void *virt);
-unsigned long *get_pte_level(unsigned long *cr3, void *virt, int pte_level);
-unsigned long *install_pte(unsigned long *cr3,
-                           int pte_level,
-                           void *virt,
-                           unsigned long pte,
-                           unsigned long *pt_page);
-
-unsigned long *install_large_page(unsigned long *cr3,unsigned long phys,
-                                  void *virt);
-unsigned long *install_page(unsigned long *cr3, unsigned long phys, void *virt);
-void install_pages(unsigned long *cr3, unsigned long phys, unsigned long len,
-		   void *virt);
-bool any_present_pages(unsigned long *cr3, void *virt, unsigned long len);
+pteval_t *get_pte(pgd_t *cr3, void *virt);
+pteval_t *get_pte_level(pgd_t *cr3, void *virt, int pte_level);
+pteval_t *install_pte(pgd_t *cr3,
+		      int pte_level,
+		      void *virt,
+		      pteval_t pte,
+		      pteval_t *pt_page);
+
+pteval_t *install_large_page(pgd_t *cr3, phys_addr_t phys, void *virt);
+pteval_t *install_page(pgd_t *cr3, phys_addr_t phys, void *virt);
+void install_pages(pgd_t *cr3, phys_addr_t phys, size_t len, void *virt);
+bool any_present_pages(pgd_t *cr3, void *virt, size_t len);
 
 static inline void *current_page_table(void)
 {
-- 
2.14.2






[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