For now, vmalloc provides a primitive that allocates contiguous virtual address. Together with a page allocator that allocates single physical memory pages, it will provide an implementation of "morecore" for when an MMU is enabled. Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- lib/vmalloc.c | 31 +++++++++++++++++++++++++++++++ lib/vmalloc.h | 8 ++++++++ lib/x86/vm.c | 25 ++++++------------------- lib/x86/vm.h | 2 -- x86/Makefile.common | 1 + x86/emulator.c | 1 + x86/eventinj.c | 1 + x86/taskswitch.c | 1 + x86/vmx_tests.c | 1 + 9 files changed, 50 insertions(+), 21 deletions(-) create mode 100644 lib/vmalloc.c create mode 100644 lib/vmalloc.h diff --git a/lib/vmalloc.c b/lib/vmalloc.c new file mode 100644 index 0000000..877c883 --- /dev/null +++ b/lib/vmalloc.c @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2012, 2017, Red Hat Inc. + * + * This allocator provides contiguous physical addresses with page + * granularity. + */ + +#include "libcflat.h" +#include "asm/spinlock.h" +#include "asm/page.h" + +static struct spinlock lock; +static void *vfree_top = 0; + +void *alloc_vpages(ulong nr) +{ + spin_lock(&lock); + vfree_top -= PAGE_SIZE * nr; + spin_unlock(&lock); + return vfree_top; +} + +void *alloc_vpage(void) +{ + return alloc_vpages(1); +} + +void init_alloc_vpage(void *top) +{ + vfree_top = top; +} diff --git a/lib/vmalloc.h b/lib/vmalloc.h new file mode 100644 index 0000000..2060f3a --- /dev/null +++ b/lib/vmalloc.h @@ -0,0 +1,8 @@ +#ifndef VMALLOC_H +#define VMALLOC_H 1 + +void *alloc_vpages(ulong nr); +void *alloc_vpage(void); +void init_alloc_vpage(void *top); + +#endif diff --git a/lib/x86/vm.c b/lib/x86/vm.c index 9b5f922..b975a73 100644 --- a/lib/x86/vm.c +++ b/lib/x86/vm.c @@ -1,9 +1,9 @@ #include "fwcfg.h" #include "vm.h" #include "libcflat.h" +#include "vmalloc.h" static void *free = 0; -static void *vfree_top = 0; static void free_memory(void *mem, unsigned long size) { @@ -271,7 +271,7 @@ static void setup_mmu(unsigned long len) /* 0 - 2G memory, 2G-3G valloc area, 3G-4G mmio */ setup_mmu_range(cr3, 0, len); setup_mmu_range(cr3, 3ul << 30, (1ul << 30)); - vfree_top = (void*)(3ul << 30); + init_alloc_vpage((void*)(3ul << 30)); #endif write_cr3(virt_to_phys(cr3)); @@ -302,9 +302,8 @@ void *vmalloc(unsigned long size) size += sizeof(unsigned long); size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); - vfree_top -= size; - mem = p = vfree_top; 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; @@ -336,11 +335,10 @@ void *vmap(unsigned long long phys, unsigned long size) unsigned pages; size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); - vfree_top -= size; - phys &= ~(unsigned long long)(PAGE_SIZE - 1); - - mem = p = vfree_top; 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; @@ -348,14 +346,3 @@ void *vmap(unsigned long long phys, unsigned long size) } return mem; } - -void *alloc_vpages(ulong nr) -{ - vfree_top -= PAGE_SIZE * nr; - return vfree_top; -} - -void *alloc_vpage(void) -{ - return alloc_vpages(1); -} diff --git a/lib/x86/vm.h b/lib/x86/vm.h index 7457b70..543da33 100644 --- a/lib/x86/vm.h +++ b/lib/x86/vm.h @@ -11,8 +11,6 @@ void setup_5level_page_table(); void *vmalloc(unsigned long size); void vfree(void *mem); void *vmap(unsigned long long phys, unsigned long size); -void *alloc_vpage(void); -void *alloc_vpages(ulong nr); uint64_t virt_to_phys_cr3(void *mem); struct pte_search { diff --git a/x86/Makefile.common b/x86/Makefile.common index e96812b..f3f3742 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/vmalloc.o cflatobjs += lib/x86/setup.o cflatobjs += lib/x86/io.o cflatobjs += lib/x86/smp.o diff --git a/x86/emulator.c b/x86/emulator.c index 8d262d8..4fb0f32 100644 --- a/x86/emulator.c +++ b/x86/emulator.c @@ -4,6 +4,7 @@ #include "desc.h" #include "types.h" #include "processor.h" +#include "vmalloc.h" #define memset __builtin_memset #define TESTDEV_IO_PORT 0xe0 diff --git a/x86/eventinj.c b/x86/eventinj.c index 665eb61..61e1b96 100644 --- a/x86/eventinj.c +++ b/x86/eventinj.c @@ -5,6 +5,7 @@ #include "isr.h" #include "apic.h" #include "apic-defs.h" +#include "vmalloc.h" #ifdef __x86_64__ # define R "r" diff --git a/x86/taskswitch.c b/x86/taskswitch.c index 01483a1..889831e 100644 --- a/x86/taskswitch.c +++ b/x86/taskswitch.c @@ -7,6 +7,7 @@ #include "libcflat.h" #include "x86/desc.h" +#include "vmalloc.h" #define TSS_RETURN (FIRST_SPARE_SEL) diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index 4a3e94b..d9bbe10 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -12,6 +12,7 @@ #include "desc.h" #include "apic.h" #include "types.h" +#include "vmalloc.h" #define NONCANONICAL 0xaaaaaaaaaaaaaaaaull -- 2.14.2