[PATCH kvm-unit-tests 16/18] x86: vm: export get_pte and return a pointer to it

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

 



This lets us modify the flags for the PTE corresponding to a virtual address.
The SMAP testcase will use this to build supervisor-mode pages.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 lib/x86/vm.c | 41 +++++++++++++++++++++--------------------
 lib/x86/vm.h | 17 +++++++++--------
 2 files changed, 30 insertions(+), 28 deletions(-)

diff --git a/lib/x86/vm.c b/lib/x86/vm.c
index 93aea71..3e7ca97 100644
--- a/lib/x86/vm.c
+++ b/lib/x86/vm.c
@@ -54,11 +54,11 @@ static unsigned long end_of_memory;
 #define	PGDIR_MASK	1023
 #endif
 
-void install_pte(unsigned long *cr3,
-		 int pte_level,
-		 void *virt,
-		 unsigned long pte,
-		 unsigned long *pt_page)
+unsigned long *install_pte(unsigned long *cr3,
+			   int pte_level,
+			   void *virt,
+			   unsigned long pte,
+			   unsigned long *pt_page)
 {
     int level;
     unsigned long *pt = cr3;
@@ -79,9 +79,10 @@ void install_pte(unsigned long *cr3,
     }
     offset = ((unsigned long)virt >> ((level-1) * PGDIR_WIDTH + 12)) & PGDIR_MASK;
     pt[offset] = pte;
+    return &pt[offset];
 }
 
-static unsigned long get_pte(unsigned long *cr3, void *virt)
+unsigned long *get_pte(unsigned long *cr3, void *virt)
 {
     int level;
     unsigned long *pt = cr3, pte;
@@ -91,28 +92,28 @@ static unsigned long get_pte(unsigned long *cr3, void *virt)
 	offset = ((unsigned long)virt >> (((level-1) * PGDIR_WIDTH) + 12)) & PGDIR_MASK;
 	pte = pt[offset];
 	if (!(pte & PTE_PRESENT))
-	    return 0;
+	    return NULL;
 	if (level == 2 && (pte & PTE_PSE))
-	    return pte;
+	    return &pt[offset];
 	pt = phys_to_virt(pte & 0xffffffffff000ull);
     }
     offset = ((unsigned long)virt >> (((level-1) * PGDIR_WIDTH) + 12)) & PGDIR_MASK;
-    pte = pt[offset];
-    return pte;
+    return &pt[offset];
 }
 
-void install_large_page(unsigned long *cr3,
-                              unsigned long phys,
-                              void *virt)
+unsigned long *install_large_page(unsigned long *cr3,
+				  unsigned long phys,
+				  void *virt)
 {
-    install_pte(cr3, 2, virt, phys | PTE_PRESENT | PTE_WRITE | PTE_USER | PTE_PSE, 0);
+    return install_pte(cr3, 2, virt,
+		       phys | PTE_PRESENT | PTE_WRITE | PTE_USER | PTE_PSE, 0);
 }
 
-void install_page(unsigned long *cr3,
-                  unsigned long phys,
-                  void *virt)
+unsigned long *install_page(unsigned long *cr3,
+			    unsigned long phys,
+			    void *virt)
 {
-    install_pte(cr3, 1, virt, phys | PTE_PRESENT | PTE_WRITE | PTE_USER, 0);
+    return install_pte(cr3, 1, virt, phys | PTE_PRESENT | PTE_WRITE | PTE_USER, 0);
 }
 
 
@@ -194,7 +195,7 @@ void *vmalloc(unsigned long size)
 
 uint64_t virt_to_phys_cr3(void *mem)
 {
-    return (get_pte(phys_to_virt(read_cr3()), mem) & PTE_ADDR) + ((ulong)mem & (PAGE_SIZE - 1));
+    return (*get_pte(phys_to_virt(read_cr3()), mem) & PTE_ADDR) + ((ulong)mem & (PAGE_SIZE - 1));
 }
 
 void vfree(void *mem)
@@ -202,7 +203,7 @@ void vfree(void *mem)
     unsigned long size = ((unsigned long *)mem)[-1];
 
     while (size) {
-	free_page(phys_to_virt(get_pte(phys_to_virt(read_cr3()), mem) & PTE_ADDR));
+	free_page(phys_to_virt(*get_pte(phys_to_virt(read_cr3()), mem) & PTE_ADDR));
 	mem += PAGE_SIZE;
 	size -= PAGE_SIZE;
     }
diff --git a/lib/x86/vm.h b/lib/x86/vm.h
index 0b5b5c7..bd73840 100644
--- a/lib/x86/vm.h
+++ b/lib/x86/vm.h
@@ -25,17 +25,18 @@ void *alloc_vpage(void);
 void *alloc_vpages(ulong nr);
 uint64_t virt_to_phys_cr3(void *mem);
 
-void install_pte(unsigned long *cr3,
-                        int pte_level,
-                        void *virt,
-                        unsigned long pte,
-                        unsigned long *pt_page);
+unsigned long *get_pte(unsigned long *cr3, void *virt);
+unsigned long *install_pte(unsigned long *cr3,
+                           int pte_level,
+                           void *virt,
+                           unsigned long pte,
+                           unsigned long *pt_page);
 
 void *alloc_page();
 
-void install_large_page(unsigned long *cr3,unsigned long phys,
-                               void *virt);
-void install_page(unsigned long *cr3, unsigned long phys, void *virt);
+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);
 
 static inline unsigned long virt_to_phys(const void *virt)
 {
-- 
1.8.3.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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