[PATCH kvm-unit-tests 10/10] vmalloc: convert to alloc_ops

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

 



The final step moves the vmalloc and vmap implementation to generic code,
rewriting vmalloc and vfree as an alloc_ops implementation that is
installed by setup_vm.

This way all architectures can benefit from it just by calling setup_vm
and providing the implementation of install_page.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 lib/alloc.c         |  5 ++---
 lib/alloc.h         |  2 --
 lib/vmalloc.c       | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/vmalloc.h       |  2 ++
 lib/x86/asm/page.h  |  1 +
 lib/x86/io.c        |  2 +-
 lib/x86/isr.c       |  5 +++--
 lib/x86/vm.c        | 50 +-------------------------------------------------
 lib/x86/vm.h        |  4 ----
 x86/Makefile.common |  1 +
 x86/asyncpf.c       |  4 +++-
 x86/pmu.c           |  4 ++--
 x86/sieve.c         |  6 +++---
 13 files changed, 72 insertions(+), 67 deletions(-)

diff --git a/lib/alloc.c b/lib/alloc.c
index 7ce61d2..9e5ae0a 100644
--- a/lib/alloc.c
+++ b/lib/alloc.c
@@ -1,8 +1,8 @@
 #include "alloc.h"
+#include "asm/page.h"
 
 void *malloc(size_t size)
 {
-	size = (size + sizeof(long) - 1) & -sizeof(long);
 	return memalign(sizeof(long), size);
 }
 
@@ -64,6 +64,5 @@ void *memalign(size_t alignment, size_t size)
 	/* Write the metadata */
 	*(uintptr_t *)(mem + OFS_SLACK) = slack;
 	*(uintptr_t *)(mem + OFS_SIZE) = size + slack;
-	return mem;
+	return (void *)mem;
 }
-
diff --git a/lib/alloc.h b/lib/alloc.h
index f560c4a..c44d459 100644
--- a/lib/alloc.h
+++ b/lib/alloc.h
@@ -35,6 +35,4 @@ void *calloc(size_t nmemb, size_t size);
 void free(void *ptr);
 void *memalign(size_t alignment, size_t size);
 
-extern struct alloc_ops *alloc_ops;
-
 #endif /* _ALLOC_H_ */
diff --git a/lib/vmalloc.c b/lib/vmalloc.c
index c2abe3c..5311b1a 100644
--- a/lib/vmalloc.c
+++ b/lib/vmalloc.c
@@ -8,6 +8,8 @@
 #include "libcflat.h"
 #include "asm/spinlock.h"
 #include "asm/page.h"
+#include "asm/io.h"
+#include "alloc.h"
 #include "alloc_phys.h"
 #include "alloc_page.h"
 
@@ -33,6 +35,56 @@ void init_alloc_vpage(void *top)
     vfree_top = top;
 }
 
+void *vmap(phys_addr_t phys, size_t size)
+{
+    void *mem, *p;
+    unsigned pages;
+
+    size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+    pages = size / PAGE_SIZE;
+    mem = p = alloc_vpages(pages);
+
+    phys &= ~(unsigned long long)(PAGE_SIZE - 1);
+    while (pages--) {
+	install_page(page_root, phys, p);
+	phys += PAGE_SIZE;
+	p += PAGE_SIZE;
+    }
+    return mem;
+}
+
+static void *vm_memalign(size_t alignment, size_t size)
+{
+    void *mem, *p;
+    unsigned pages;
+
+    assert(alignment <= PAGE_SIZE);
+    size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
+    pages = size / PAGE_SIZE;
+    mem = p = alloc_vpages(pages);
+    while (pages--) {
+        phys_addr_t pa = virt_to_phys(alloc_page());
+        install_page(page_root, pa, p);
+        p += PAGE_SIZE;
+    }
+    return mem;
+}
+
+static void vm_free(void *mem, size_t size)
+{
+    while (size) {
+	free_page(phys_to_virt(virt_to_pte_phys(page_root, mem)));
+	mem += PAGE_SIZE;
+	size -= PAGE_SIZE;
+    }
+}
+
+static struct alloc_ops vmalloc_ops = {
+    .memalign = vm_memalign,
+    .free = vm_free,
+    .page_size = PAGE_SIZE,
+};
+
 void setup_vm()
 {
     phys_addr_t base, top;
@@ -42,4 +94,5 @@ void setup_vm()
 
     free_pages((void *)base, top - base);
     page_root = setup_mmu(top);
+    alloc_ops = &vmalloc_ops;
 }
diff --git a/lib/vmalloc.h b/lib/vmalloc.h
index d4dd880..2a89c33 100644
--- a/lib/vmalloc.h
+++ b/lib/vmalloc.h
@@ -6,4 +6,6 @@ void *alloc_vpage(void);
 void init_alloc_vpage(void *top);
 void setup_vm();
 
+void *vmap(phys_addr_t phys, size_t size);
+
 #endif
diff --git a/lib/x86/asm/page.h b/lib/x86/asm/page.h
index 1e6d1a2..1971770 100644
--- a/lib/x86/asm/page.h
+++ b/lib/x86/asm/page.h
@@ -47,6 +47,7 @@
 #define PGDIR_OFFSET(va, lvl)  (((va) >> PGDIR_BITS(lvl)) & PGDIR_MASK)
 
 extern void *setup_mmu(unsigned long top);
+unsigned long *install_page(unsigned long *cr3, phys_addr_t phys, void *virt);
 phys_addr_t virt_to_pte_phys(void *cr3, void *virt);
 
 #endif /* !__ASSEMBLY__ */
diff --git a/lib/x86/io.c b/lib/x86/io.c
index cc5ac58..7e1c16d 100644
--- a/lib/x86/io.c
+++ b/lib/x86/io.c
@@ -1,8 +1,8 @@
 #include "libcflat.h"
-#include "vm.h"
 #include "smp.h"
 #include "asm/io.h"
 #include "asm/page.h"
+#include "vmalloc.h"
 #ifndef USE_SERIAL
 #define USE_SERIAL
 #endif
diff --git a/lib/x86/isr.c b/lib/x86/isr.c
index 9b1d505..53c0c2b 100644
--- a/lib/x86/isr.c
+++ b/lib/x86/isr.c
@@ -1,6 +1,7 @@
 #include "libcflat.h"
+#include "processor.h"
 #include "isr.h"
-#include "vm.h"
+#include "alloc.h"
 #include "desc.h"
 
 extern char isr_entry_point[];
@@ -65,7 +66,7 @@ asm (
 
 void handle_irq(unsigned vec, void (*func)(isr_regs_t *regs))
 {
-    u8 *thunk = vmalloc(50);
+    u8 *thunk = malloc(50);
 
     set_idt_entry(vec, thunk, 0);
 
diff --git a/lib/x86/vm.c b/lib/x86/vm.c
index 9dd7d79..29aaee3 100644
--- a/lib/x86/vm.c
+++ b/lib/x86/vm.c
@@ -98,7 +98,7 @@ unsigned long *install_large_page(unsigned long *cr3,
 }
 
 unsigned long *install_page(unsigned long *cr3,
-			    unsigned long phys,
+			    phys_addr_t phys,
 			    void *virt)
 {
     return install_pte(cr3, 1, virt, phys | PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK, 0);
@@ -179,55 +179,7 @@ void *setup_mmu(unsigned long end_of_memory)
     return cr3;
 }
 
-void *vmalloc(unsigned long size)
-{
-    void *mem, *p;
-    unsigned pages;
-
-    size += sizeof(unsigned long);
-
-    size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
-    pages = size / PAGE_SIZE;
-    mem = p = alloc_vpages(pages);
-    while (pages--) {
-	install_page(phys_to_virt(read_cr3()), virt_to_phys(alloc_page()), p);
-	p += PAGE_SIZE;
-    }
-    *(unsigned long *)mem = size;
-    mem += sizeof(unsigned long);
-    return mem;
-}
-
 phys_addr_t virt_to_pte_phys(void *cr3, void *mem)
 {
     return (*get_pte(cr3, mem) & PT_ADDR_MASK) + ((ulong)mem & (PAGE_SIZE - 1));
 }
-
-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) & PT_ADDR_MASK));
-	mem += PAGE_SIZE;
-	size -= PAGE_SIZE;
-    }
-}
-
-void *vmap(unsigned long long phys, unsigned long size)
-{
-    void *mem, *p;
-    unsigned pages;
-
-    size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
-    pages = size / PAGE_SIZE;
-    mem = p = alloc_vpages(pages);
-
-    phys &= ~(unsigned long long)(PAGE_SIZE - 1);
-    while (pages--) {
-	install_page(phys_to_virt(read_cr3()), phys, p);
-	phys += PAGE_SIZE;
-	p += PAGE_SIZE;
-    }
-    return mem;
-}
diff --git a/lib/x86/vm.h b/lib/x86/vm.h
index 9f668c6..9026293 100644
--- a/lib/x86/vm.h
+++ b/lib/x86/vm.h
@@ -7,10 +7,6 @@
 
 void setup_5level_page_table();
 
-void *vmalloc(unsigned long size);
-void vfree(void *mem);
-void *vmap(unsigned long long phys, unsigned long size);
-
 struct pte_search {
 	int level;
 	unsigned long *pte;
diff --git a/x86/Makefile.common b/x86/Makefile.common
index f0fbadf..5f7eac4 100644
--- a/x86/Makefile.common
+++ b/x86/Makefile.common
@@ -4,6 +4,7 @@ all: directories test_cases
 
 cflatobjs += lib/pci.o
 cflatobjs += lib/pci-edu.o
+cflatobjs += lib/alloc.o
 cflatobjs += lib/vmalloc.o
 cflatobjs += lib/alloc_page.o
 cflatobjs += lib/alloc_phys.o
diff --git a/x86/asyncpf.c b/x86/asyncpf.c
index 3b5b4b7..0db5732 100644
--- a/x86/asyncpf.c
+++ b/x86/asyncpf.c
@@ -22,6 +22,8 @@
 #include "x86/isr.h"
 #include "x86/vm.h"
 
+#include "asm/page.h"
+#include "alloc.h"
 #include "libcflat.h"
 #include <stdint.h>
 
@@ -94,7 +96,7 @@ int main(int ac, char **av)
 	wrmsr(MSR_KVM_ASYNC_PF_EN, virt_to_phys((void*)&apf_reason) |
 			KVM_ASYNC_PF_SEND_ALWAYS | KVM_ASYNC_PF_ENABLED);
 	printf("alloc memory\n");
-	buf = vmalloc(MEM);
+	buf = malloc(MEM);
 	irq_enable();
 	while(loop--) {
 		printf("start loop\n");
diff --git a/x86/pmu.c b/x86/pmu.c
index b56b61e..12a5880 100644
--- a/x86/pmu.c
+++ b/x86/pmu.c
@@ -5,7 +5,7 @@
 #include "x86/apic.h"
 #include "x86/desc.h"
 #include "x86/isr.h"
-#include "x86/vm.h"
+#include "alloc.h"
 
 #include "libcflat.h"
 #include <stdint.h>
@@ -380,7 +380,7 @@ int main(int ac, char **av)
 	setup_vm();
 	setup_idt();
 	handle_irq(PC_VECTOR, cnt_overflow);
-	buf = vmalloc(N*64);
+	buf = malloc(N*64);
 
 	eax.full = id.a;
 	ebx.full = id.b;
diff --git a/x86/sieve.c b/x86/sieve.c
index 6cbcd6d..2ee2919 100644
--- a/x86/sieve.c
+++ b/x86/sieve.c
@@ -1,4 +1,4 @@
-#include "vm.h"
+#include "alloc.h"
 #include "libcflat.h"
 
 int sieve(char* data, int size)
@@ -42,9 +42,9 @@ int main()
     setup_vm();
     test_sieve("mapped", static_data, STATIC_SIZE);
     for (i = 0; i < 3; ++i) {
-	v = vmalloc(VSIZE);
+	v = malloc(VSIZE);
 	test_sieve("virtual", v, VSIZE);
-	vfree(v);
+	free(v);
     }
 
     return 0;
-- 
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