From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KpKND-00041K-1x for qemu-devel@nongnu.org; Mon, 13 Oct 2008 06:09:59 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KpKNC-00040x-6B for qemu-devel@nongnu.org; Mon, 13 Oct 2008 06:09:58 -0400 Received: from [199.232.76.173] (port=47869 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KpKNB-00040r-UC for qemu-devel@nongnu.org; Mon, 13 Oct 2008 06:09:58 -0400 Received: from nf-out-0910.google.com ([64.233.182.186]:12144) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KpKNB-00078m-JH for qemu-devel@nongnu.org; Mon, 13 Oct 2008 06:09:57 -0400 Received: by nf-out-0910.google.com with SMTP id b2so792482nfb.12 for ; Mon, 13 Oct 2008 03:09:57 -0700 (PDT) From: "Kirill A. Shutemov" Date: Mon, 13 Oct 2008 13:10:39 +0300 Message-Id: <1223892640-15545-12-git-send-email-kirill@shutemov.name> In-Reply-To: <1223892640-15545-11-git-send-email-kirill@shutemov.name> References: <1223892640-15545-1-git-send-email-kirill@shutemov.name> <1223892640-15545-2-git-send-email-kirill@shutemov.name> <1223892640-15545-3-git-send-email-kirill@shutemov.name> <1223892640-15545-4-git-send-email-kirill@shutemov.name> <1223892640-15545-5-git-send-email-kirill@shutemov.name> <1223892640-15545-6-git-send-email-kirill@shutemov.name> <1223892640-15545-7-git-send-email-kirill@shutemov.name> <1223892640-15545-8-git-send-email-kirill@shutemov.name> <1223892640-15545-9-git-send-email-kirill@shutemov.name> <1223892640-15545-10-git-send-email-kirill@shutemov.name> <1223892640-15545-11-git-send-email-kirill@shutemov.name> Subject: [Qemu-devel] [PATCH] mremap(): handle MREMAP_FIXED and MREMAP_MAYMOVE correctly Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: "Kirill A. Shutemov" , Paul Brook Signed-off-by: Kirill A. Shutemov --- linux-user/mmap.c | 35 +++++++++++++++++++++++++++++------ 1 files changed, 29 insertions(+), 6 deletions(-) diff --git a/linux-user/mmap.c b/linux-user/mmap.c index 19434a2..bc20f4b 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -533,19 +533,41 @@ int target_munmap(abi_ulong start, abi_ulong len) return ret; } -/* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED - blocks which have been allocated starting on a host page */ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, abi_ulong new_size, unsigned long flags, abi_ulong new_addr) { int prot; - unsigned long host_addr; + void *host_addr; mmap_lock(); - /* XXX: use 5 args syscall */ - host_addr = (long)mremap(g2h(old_addr), old_size, new_size, flags); - if (host_addr == -1) { + + if (flags & MREMAP_FIXED) + host_addr = mremap(g2h(old_addr), old_size, new_size, + flags, new_addr); + else if (flags & MREMAP_MAYMOVE) { + abi_ulong mmap_start; + + mmap_start = mmap_find_vma(0, new_size); + + if (mmap_start == -1) { + errno = ENOMEM; + host_addr = MAP_FAILED; + } else + host_addr = mremap(g2h(old_addr), old_size, new_size, + flags | MREMAP_FIXED, g2h(mmap_start)); + } else { + host_addr = mremap(g2h(old_addr), old_size, new_size, flags); + /* Check if address fits target address space */ + if ((unsigned long)host_addr + new_size > (abi_ulong)-1) { + /* Revert mremap() changes */ + host_addr = mremap(g2h(old_addr), new_size, old_size, flags); + errno = ENOMEM; + host_addr = MAP_FAILED; + } + } + + if (host_addr == MAP_FAILED) { new_addr = -1; } else { new_addr = h2g(host_addr); @@ -553,6 +575,7 @@ abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, page_set_flags(old_addr, old_addr + old_size, 0); page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID); } + mmap_unlock(); return new_addr; } -- 1.5.6.5.GIT