Patchwork [1/9] Export function for VA defined ram allocation

login
register
mail settings
Submitter Alexander Graf
Date Oct. 19, 2009, 2:37 p.m.
Message ID <1255963059-10298-2-git-send-email-agraf@suse.de>
Download mbox | patch
Permalink /patch/36384/
State New
Headers show

Comments

Alexander Graf - Oct. 19, 2009, 2:37 p.m.
S390 requires vmas for guests to be < 256 GB. So we need to directly export
mmaps "try to use this vma as start address" feature to not accidently get
over that limit.

Signed-off-by: Alexander Graf <agraf@suse.de>
---
 cpu-common.h |    1 +
 exec.c       |   15 +++++++++++++--
 2 files changed, 14 insertions(+), 2 deletions(-)
Carsten Otte - Oct. 20, 2009, 8:02 a.m.
Alexander Graf wrote:
> S390 requires vmas for guests to be < 256 GB. So we need to directly export
> mmaps "try to use this vma as start address" feature to not accidently get
> over that limit.
Hmmh, now that x86 has solved all the problems we should probably move 
away from using the same page table for userspace and guest too. That 
would make this "workaround" superfluous and memslots would work just 
the same on s390 as they do on x86. I've put it on my todo list.
For now, this looks good to me.

Patch

diff --git a/cpu-common.h b/cpu-common.h
index 6302372..ecaf9e3 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -30,6 +30,7 @@  static inline void cpu_register_physical_memory(target_phys_addr_t start_addr,
 
 ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr);
 ram_addr_t qemu_ram_alloc(ram_addr_t);
+ram_addr_t _qemu_ram_alloc(ram_addr_t size, void *map_at);
 void qemu_ram_free(ram_addr_t addr);
 /* This should only be used for ram local to a device.  */
 void *qemu_get_ram_ptr(ram_addr_t addr);
diff --git a/exec.c b/exec.c
index 076d26b..36c26cd 100644
--- a/exec.c
+++ b/exec.c
@@ -2404,14 +2404,20 @@  void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size)
         kvm_uncoalesce_mmio_region(addr, size);
 }
 
-ram_addr_t qemu_ram_alloc(ram_addr_t size)
+ram_addr_t _qemu_ram_alloc(ram_addr_t size, void *map_at)
 {
     RAMBlock *new_block;
 
     size = TARGET_PAGE_ALIGN(size);
     new_block = qemu_malloc(sizeof(*new_block));
 
-    new_block->host = qemu_vmalloc(size);
+    if (map_at) {
+        new_block->host = mmap(map_at, size, PROT_EXEC|PROT_READ|PROT_WRITE,
+                               MAP_SHARED | MAP_ANONYMOUS, -1, 0);
+
+    } else {
+        new_block->host = qemu_vmalloc(size);
+    }
 #ifdef MADV_MERGEABLE
     madvise(new_block->host, size, MADV_MERGEABLE);
 #endif
@@ -2434,6 +2440,11 @@  ram_addr_t qemu_ram_alloc(ram_addr_t size)
     return new_block->offset;
 }
 
+ram_addr_t qemu_ram_alloc(ram_addr_t size)
+{
+    return _qemu_ram_alloc(size, NULL);
+}
+
 void qemu_ram_free(ram_addr_t addr)
 {
     /* TODO: implement this.  */