qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Kirill A. Shutemov" <kirill@shutemov.name>
To: qemu-devel@nongnu.org
Cc: "Kirill A. Shutemov" <kirill@shutemov.name>
Subject: [Qemu-devel] [PATCH, v3] Rewrite mmap_find_vma() to work fine on 64-bit hosts with 32-bit targets
Date: Mon, 10 Nov 2008 09:07:15 +0200	[thread overview]
Message-ID: <1226300835-4117-1-git-send-email-kirill@shutemov.name> (raw)
In-Reply-To: <1225129768-11603-1-git-send-email-kirill@shutemov.name>

qemu's page table can be incomple if /proc/self/maps is unavailable or
host allocating a memory with mmap(), so we can't use it to find free
memory area.

New version mmap_find_vma() uses mmap() without MAP_FIXED to find free
memory.

Signed-off-by: Kirill A. Shutemov <kirill@shutemov.name>
---
 linux-user/mmap.c |   79 +++++++++++++++++++++++++++++------------------------
 1 files changed, 43 insertions(+), 36 deletions(-)

diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index d5f22b8..f3ad2eb 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -255,52 +255,59 @@ static abi_ulong mmap_next_start = 0x40000000;
 
 unsigned long last_brk;
 
-/* find a free memory area of size 'size'. The search starts at
-   'start'. If 'start' == 0, then a default start address is used.
-   Return -1 if error.
-*/
-/* page_init() marks pages used by the host as reserved to be sure not
-   to use them. */
-static abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
+/*
+ * Find and reserve a free memory area of size 'size'. The search
+ * starts at 'start'.
+ * It must be called with mmap_lock() held.
+ * Return -1 if error.
+ */
+abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size)
 {
-    abi_ulong addr, addr1, addr_start;
-    int prot;
-    unsigned long new_brk;
-
-    new_brk = (unsigned long)sbrk(0);
-    if (last_brk && last_brk < new_brk && last_brk == (target_ulong)last_brk) {
-        /* This is a hack to catch the host allocating memory with brk().
-           If it uses mmap then we loose.
-           FIXME: We really want to avoid the host allocating memory in
-           the first place, and maybe leave some slack to avoid switching
-           to mmap.  */
-        page_set_flags(last_brk & TARGET_PAGE_MASK,
-                       TARGET_PAGE_ALIGN(new_brk),
-                       PAGE_RESERVED); 
-    }
-    last_brk = new_brk;
+    void *ptr;
+    abi_ulong addr;
 
     size = HOST_PAGE_ALIGN(size);
-    start = start & qemu_host_page_mask;
+    start &= qemu_host_page_mask;
+
+    /* If 'start' == 0, then a default start address is used. */
+    if (start == 0)
+        start = mmap_next_start;
+
     addr = start;
-    if (addr == 0)
-        addr = mmap_next_start;
-    addr_start = addr;
+
     for(;;) {
-        prot = 0;
-        for(addr1 = addr; addr1 < (addr + size); addr1 += TARGET_PAGE_SIZE) {
-            prot |= page_get_flags(addr1);
-        }
-        if (prot == 0)
+        /*
+         * Reserve needed memory area to avoid a race.
+         * It should be discarded using:
+         *  - mmap() with MAP_FIXED flag
+         *  - mremap() with MREMAP_FIXED flag
+         *  - shmat() with SHM_REMAP flag
+         */
+        ptr = mmap((void *)(unsigned long)addr, size, PROT_NONE,
+                   MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
+
+        /* ENOMEM, if host address space has no memory */
+        if (ptr == MAP_FAILED)
+            return (abi_ulong)-1;
+
+        /* If address fits target address space we've found what we need */
+        if ((unsigned long)ptr + size - 1 <= (abi_ulong)-1)
             break;
+
+        /* Unmap and try again with new page */
+        munmap(ptr, size);
         addr += qemu_host_page_size;
-        /* we found nothing */
-        if (addr == addr_start)
+
+        /* ENOMEM if we check whole of target address space */
+        if (addr == start)
             return (abi_ulong)-1;
     }
+
+    /* Update default start address */
     if (start == 0)
-        mmap_next_start = addr + size;
-    return addr;
+        mmap_next_start = (unsigned long)ptr + size;
+
+    return h2g(ptr);
 }
 
 /* NOTE: all the constants are the HOST ones */
-- 
1.6.0.2.GIT

  parent reply	other threads:[~2008-11-10  7:05 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-13 10:10 [Qemu-devel] [PATCH] Add readahead syscall Kirill A. Shutemov
2008-10-13 10:10 ` [Qemu-devel] [PATCH] Fix getdents* syscalls Kirill A. Shutemov
2008-10-13 10:10   ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_msg* ipc calls handling Kirill A. Shutemov
2008-10-13 10:10     ` [Qemu-devel] [PATCH] Implement msg* syscalls Kirill A. Shutemov
2008-10-13 10:10       ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_sem* ipc calls handling Kirill A. Shutemov
2008-10-13 10:10         ` [Qemu-devel] [PATCH] Implement sem* syscalls Kirill A. Shutemov
2008-10-13 10:10           ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_shm* ipc calls handling Kirill A. Shutemov
2008-10-13 10:10             ` [Qemu-devel] [PATCH] Implement shm* syscalls Kirill A. Shutemov
2008-10-13 10:10               ` [Qemu-devel] [PATCH] Fix fstatat64()/newfstatat() syscall implementation Kirill A. Shutemov
2008-10-13 10:10                 ` [Qemu-devel] [PATCH] Introduce --enable-binfmt-misc configure option Kirill A. Shutemov
2008-10-13 10:10                   ` [Qemu-devel] [PATCH] Rewrite mmap_find_vma() to work fine on 64-bit hosts with 32-bit targets Kirill A. Shutemov
2008-10-13 10:10                     ` [Qemu-devel] [PATCH] mremap(): handle MREMAP_FIXED and MREMAP_MAYMOVE correctly Kirill A. Shutemov
2008-10-13 10:10                       ` [Qemu-devel] [PATCH] shmat(): use mmap_find_vma to find free memory area Kirill A. Shutemov
2008-10-17  6:34                         ` [Qemu-devel] [PATCH] mmap: add check if requested memory area fits target address space Kirill A. Shutemov
2008-10-17  6:34                           ` [Qemu-devel] [PATCH] linux-user, x86: use target_mmap() to allocate idt, gdt and ldt tables Kirill A. Shutemov
2008-11-01  9:33                             ` [Qemu-devel] " Jan Kiszka
2008-11-01 10:27                               ` Kirill A. Shutemov
2008-11-01 10:54                                 ` Jan Kiszka
2008-11-01 11:12                                   ` Kirill A. Shutemov
2008-11-01 11:16                                     ` Kirill A. Shutemov
2008-11-02 19:36                                       ` Jan Kiszka
2008-11-01 11:34                               ` Laurent Desnogues
2008-11-01 10:06                             ` [Qemu-devel] [PATCH, v2] " Kirill A. Shutemov
2008-10-27 13:08                           ` [Qemu-devel] [PATCH] mmap: add check if requested memory area fits target address space andrzej zaborowski
2008-10-27 15:48                             ` Kirill A. Shutemov
2008-10-27 15:55                               ` Andreas Schwab
2008-10-27 17:32                                 ` Kirill A. Shutemov
2008-10-27 19:37                               ` andrzej zaborowski
2008-10-27 20:06                                 ` Kirill A. Shutemov
2008-11-10  3:30                                   ` andrzej zaborowski
2008-11-10  5:55                                     ` Kirill A. Shutemov
2008-11-10 12:45                                       ` andrzej zaborowski
2008-10-27 17:48                           ` [Qemu-devel] [PATCH, v2] " Kirill A. Shutemov
2008-11-10  7:11                             ` [Qemu-devel] [PATCH, v3] " Kirill A. Shutemov
2008-11-10  7:09                         ` [Qemu-devel] [PATCH, v3] shmat(): use mmap_find_vma to find free memory area Kirill A. Shutemov
2008-10-14  4:04                       ` [Qemu-devel] [PATCH] mremap(): handle MREMAP_FIXED and MREMAP_MAYMOVE correctly Vince Weaver
2008-10-14  5:22                         ` Kirill A. Shutemov
2008-10-26 16:14                     ` [Qemu-devel] [PATCH] Rewrite mmap_find_vma() to work fine on 64-bit hosts with 32-bit targets Vince Weaver
2008-10-27 17:49                     ` [Qemu-devel] [PATCH, v2] " Kirill A. Shutemov
2008-11-01 16:51                       ` Jamie Lokier
2008-11-01 16:55                         ` Kirill A. Shutemov
2008-11-10  3:54                           ` andrzej zaborowski
2008-11-10  6:07                             ` Kirill A. Shutemov
2008-11-10  8:02                             ` Jamie Lokier
2008-11-10 12:55                               ` andrzej zaborowski
2008-11-10 14:38                                 ` Kirill A. Shutemov
2008-11-11  0:53                                   ` Jamie Lokier
2008-11-14 12:23                                     ` Kirill A. Shutemov
2008-11-14 12:51                                       ` Paul Brook
2008-11-14 13:08                                         ` Jamie Lokier
2008-11-14 13:51                                           ` Kirill A. Shutemov
2008-11-10  7:07                       ` Kirill A. Shutemov [this message]
2008-11-14 13:57                         ` [Qemu-devel] [PATCH, v4] " Kirill A. Shutemov
2008-11-01 10:10                   ` [Qemu-devel] [PATCH, v2] Introduce --enable-binfmt-misc configure option Kirill A. Shutemov
2008-11-10 13:03                     ` andrzej zaborowski
2008-10-16 20:55               ` [Qemu-devel] [PATCH] Implement shm* syscalls + Implement sem* syscalls Martin Mohring
2008-10-17  4:09                 ` Kirill A. Shutemov
2008-10-17  8:27                   ` Martin Mohring
2008-10-17 10:12                     ` Kirill A. Shutemov
2008-11-01  9:56                 ` Aurelien Jarno
2008-11-01 10:08                   ` Kirill A. Shutemov
2008-10-24  7:24         ` [Qemu-devel] Re: [PATCH] Fix and cleanup IPCOP_sem* ipc calls handling Kirill A. Shutemov
2008-10-13 21:09       ` [Qemu-devel] [PATCH] Implement msg* syscalls Aurelien Jarno
2008-10-13 15:53     ` [Qemu-devel] [PATCH] Fix and cleanup IPCOP_msg* ipc calls handling Aurelien Jarno
2008-10-13 18:48       ` Kirill A. Shutemov
2008-10-13 20:52         ` Aurelien Jarno
2008-10-13 21:09     ` Aurelien Jarno
2008-10-13 12:48   ` [Qemu-devel] [PATCH] Fix getdents* syscalls Aurelien Jarno
2008-10-13 12:59     ` Kirill A. Shutemov
2008-10-13 13:10       ` Aurelien Jarno

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1226300835-4117-1-git-send-email-kirill@shutemov.name \
    --to=kirill@shutemov.name \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).