From patchwork Sat Jun 2 19:29:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 162443 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id F11D2B6FA5 for ; Sun, 3 Jun 2012 05:30:31 +1000 (EST) Received: from localhost ([::1]:46854 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sau1t-0007F2-Ol for incoming@patchwork.ozlabs.org; Sat, 02 Jun 2012 15:30:29 -0400 Received: from eggs.gnu.org ([208.118.235.92]:39885) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sau1a-00079b-0U for qemu-devel@nongnu.org; Sat, 02 Jun 2012 15:30:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Sau1Y-00016s-5F for qemu-devel@nongnu.org; Sat, 02 Jun 2012 15:30:09 -0400 Received: from mail-pb0-f45.google.com ([209.85.160.45]:51433) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sau1X-000106-TL for qemu-devel@nongnu.org; Sat, 02 Jun 2012 15:30:08 -0400 Received: by mail-pb0-f45.google.com with SMTP id ro12so4727782pbb.4 for ; Sat, 02 Jun 2012 12:30:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=1brU2RWSZY/nnob3Hl1Ue3LooEatPmYFkeHWE8/dJcY=; b=DyqY9YNHlqr0E0CK3f1/5fzgMnacOqac+e2D2DOvqlEfzSGHgJdEXzFkmUaB6+ypTy XpDqASZ/UHOolQ8N1CG34ZyswtbcLm45F6hMNRLTf0sU/KtBqGc/nnjF7B23gbpofR9R psB/5F+WbYzIv2c/rS8ypKM4Yn/O4ObFrGxiiioQ0wS0vOjxJwnbr+yFOz5EivQ0RSyP pgz7vvki41/hEzs/3VHjvuT80Nb33mynXZfRO9xDfbjN1fyyyfEI9s4mzuLv0uOZ4uuz ykxOdO6iFfRN41DyjV6Iwy9IRUh7sB9Iem+jbjjyuTD40KHar9Yv3NiY5eeTh5u8V4rH 0iiw== Received: by 10.68.234.35 with SMTP id ub3mr23360359pbc.8.1338665407060; Sat, 02 Jun 2012 12:30:07 -0700 (PDT) Received: from anchor.twiddle.home ([173.160.232.49]) by mx.google.com with ESMTPS id z2sm7176147pbv.34.2012.06.02.12.30.06 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 02 Jun 2012 12:30:06 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Sat, 2 Jun 2012 12:29:56 -0700 Message-Id: <1338665397-20917-6-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 1.7.7.6 In-Reply-To: <1338665397-20917-1-git-send-email-rth@twiddle.net> References: <1338665397-20917-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.160.45 Cc: Riku Voipio Subject: [Qemu-devel] [PATCH 5/6] linux-user: Allocate the right amount of space for non-fixed file maps X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org If we let the kernel handle the implementation of mmap_find_vma, via an anon mmap, we must use the size as indicated by the user and not the size truncated to the filesize. This happens often in ld.so, where we initially mmap the file to the size of the text+data+bss to reserve an area, then mmap+fixed over the top to properly handle data and bss. Signed-off-by: Richard Henderson --- linux-user/mmap.c | 30 +++++++++++++++++++----------- 1 files changed, 19 insertions(+), 11 deletions(-) diff --git a/linux-user/mmap.c b/linux-user/mmap.c index d9468fe..b412e3f 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -382,7 +382,6 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, int flags, int fd, abi_ulong offset) { abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len; - unsigned long host_start; mmap_lock(); #ifdef DEBUG_MMAP @@ -421,6 +420,19 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, if (len == 0) goto the_end; real_start = start & qemu_host_page_mask; + host_offset = offset & qemu_host_page_mask; + + /* If the user is asking for the kernel to find a location, do that + before we truncate the length for mapping files below. */ + if (!(flags & MAP_FIXED)) { + host_len = len + offset - host_offset; + host_len = HOST_PAGE_ALIGN(host_len); + start = mmap_find_vma(real_start, host_len); + if (start == (abi_ulong)-1) { + errno = ENOMEM; + goto fail; + } + } /* When mapping files into a memory area larger than the file, accesses to pages beyond the file size will cause a SIGBUS. @@ -453,27 +465,23 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, } if (!(flags & MAP_FIXED)) { - abi_ulong mmap_start; + unsigned long host_start; void *p; - host_offset = offset & qemu_host_page_mask; + host_len = len + offset - host_offset; host_len = HOST_PAGE_ALIGN(host_len); - mmap_start = mmap_find_vma(real_start, host_len); - if (mmap_start == (abi_ulong)-1) { - errno = ENOMEM; - goto fail; - } + /* Note: we prefer to control the mapping address. It is especially important if qemu_host_page_size > qemu_real_host_page_size */ - p = mmap(g2h(mmap_start), - host_len, prot, flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0); + p = mmap(g2h(start), host_len, prot, + flags | MAP_FIXED | MAP_ANONYMOUS, -1, 0); if (p == MAP_FAILED) goto fail; /* update start so that it points to the file position at 'offset' */ host_start = (unsigned long)p; if (!(flags & MAP_ANONYMOUS)) { - p = mmap(g2h(mmap_start), len, prot, + p = mmap(g2h(start), len, prot, flags | MAP_FIXED, fd, host_offset); host_start += offset - host_offset; }