summary refs log tree commit diff stats
path: root/linux-user/mmap.c
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2008-06-09 13:47:45 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2008-06-09 13:47:45 +0000
commit17e2377abf16c3951d7d34521ceade4d7dc31d01 (patch)
treec6e540f435401b092933145541df335748b5fd58 /linux-user/mmap.c
parent82e671d9ecdf1422780e56182e9c228071493a22 (diff)
downloadfocaccia-qemu-17e2377abf16c3951d7d34521ceade4d7dc31d01.tar.gz
focaccia-qemu-17e2377abf16c3951d7d34521ceade4d7dc31d01.zip
Prevent guest reusing host memory allocations.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4710 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'linux-user/mmap.c')
-rw-r--r--linux-user/mmap.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index b4ca1074b3..be1ddb9f25 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -73,6 +73,52 @@ void mmap_unlock(void)
 }
 #endif
 
+void *qemu_vmalloc(size_t size)
+{
+    void *p;
+    unsigned long addr;
+    mmap_lock();
+    /* Use map and mark the pages as used.  */
+    p = mmap(NULL, size, PROT_READ | PROT_WRITE,
+             MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+    addr = (unsigned long)p;
+    if (addr == (target_ulong) addr) {
+        /* Allocated region overlaps guest address space.
+           This may recurse.  */
+        page_set_flags(addr & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(addr + size),
+                       PAGE_RESERVED);
+    }
+
+    mmap_unlock();
+    return p;
+}
+
+void *qemu_malloc(size_t size)
+{
+    char * p;
+    size += 16;
+    p = qemu_vmalloc(size);
+    *(size_t *)p = size;
+    return p + 16;
+}
+
+/* We use map, which is always zero initialized.  */
+void * qemu_mallocz(size_t size)
+{
+    return qemu_malloc(size);
+}
+
+void qemu_free(void *ptr)
+{
+    /* FIXME: We should unmark the reserved pages here.  However this gets
+       complicated when one target page spans multiple host pages, so we
+       don't bother.  */
+    size_t *p;
+    p = (size_t *)((char *)ptr - 16);
+    munmap(p, *p);
+}
+
 /* NOTE: all the constants are the HOST ones, but addresses are target. */
 int target_mprotect(abi_ulong start, abi_ulong len, int prot)
 {