From patchwork Tue Mar 20 20:43:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 888430 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=vivier.eu Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 405Q1Z2wNHz9ryG for ; Wed, 21 Mar 2018 07:45:38 +1100 (AEDT) Received: from localhost ([::1]:51652 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eyO8W-0003sY-7m for incoming@patchwork.ozlabs.org; Tue, 20 Mar 2018 16:45:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:44908) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eyO7S-0003VR-IS for qemu-devel@nongnu.org; Tue, 20 Mar 2018 16:44:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eyO7P-0004eg-Ck for qemu-devel@nongnu.org; Tue, 20 Mar 2018 16:44:30 -0400 Received: from mout.kundenserver.de ([212.227.126.187]:35061) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eyO7P-0004e5-1X for qemu-devel@nongnu.org; Tue, 20 Mar 2018 16:44:27 -0400 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue002 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MClSU-1eq6OJ42La-009S03; Tue, 20 Mar 2018 21:44:10 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 20 Mar 2018 21:43:51 +0100 Message-Id: <20180320204351.28167-2-laurent@vivier.eu> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180320204351.28167-1-laurent@vivier.eu> References: <20180320204351.28167-1-laurent@vivier.eu> X-Provags-ID: V03:K0:2JC+fEinFu7ucbdGzRsJqFCYSpTxIalvMhBVgsHGair6m1dvWxg T8JtgwhRr1t7KdRUeNxRwM03rkFx004vvSznhMeUMQjepg6Asy5OmGFt+nT6uh7vqHCBeFH pl3HGTz10v7TDsOb2orqRwwFAIg3dI0hcSyO6BXMXyuy/ZF4oAjQaHQ5PrXSc4LcqqM7uqd cncHLcn0rzVDuHFCd2Y0g== X-UI-Out-Filterresults: notjunk:1; V01:K0:Qj/lOE1kERM=:KGQRimEV5IyaLxOOPZkw4D T59kpOLXyp61hY7AXjmDMaqDZ4R1qRSI/bAc3hNzIeCXzVBU6lAaO0dXa/C7cw/A+G/1W4T/I 6+At1QxTdZT/faTc4cgT0UZHoI2829BWKNoegDYJZ87l/rIDYNU5rNDQIgDkirPJ8x2sgrE/Z 9HfUKV42NDHf0QQOE/TwJoPQyFjkYvUk6xS9h6a+YN5figMqy7s035SWwqVBRrNPzMZy5JofN edbEhVaZFE7FRbRkZc7LDcOAnx/JWBZMJESPsJLDpLoZehNBRZb1t/gKHPTTkgCnrMrkq/87w eW7Mg0UWKajyaVcRr0abTJxOPsAx8RzlmMt/tz+lU4V3gPFbzeZoO51kSl8J5aCLFYE6s+ie+ mJyOrtAGuTt0hcbMIIiN/2z37ZrZfv55lZLeS/Xpjeg1i84XBhXX8uPd5WmASEuSM+9FRweR0 MMEZpZzQukmCPHtTLDvV5RcrfQpMMP2xD8HpbQBDASyqkSkQBnPypT/nG2olpAYFPJ7SGQFDd zLisfFzTkUEFaCgwioeDdTCc6faFWwS15eqK0bau1EUFunbt8JLZW0qlJeBjkBR7xgMe6AatV ZRFFtpXGcEXw0Ry3fyOMfhshiuE96B3EA1wgOVPzrXlHY1JNdWpIi2FpgHTI7+AROwvOlXfWW m5nq9/nOeZMlQo7dp7v9IxbXCDM6cI1WuPgiHfQSlKXumMZrz1drZXFDhQrr+ASCUFhApx1Te 0/XHHqlyYi+Oid65B6yDvD4MJzqCl3bKfla2nw== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.187 Subject: [Qemu-devel] [PULL 1/1] linux-user: init_guest_space: Try to make ARM space+commpage continuous X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Luke Shumaker , Riku Voipio , Laurent Vivier Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Luke Shumaker At a fixed distance after the usable memory that init_guest_space maps, for 32-bit ARM targets we also need to map a commpage. The normal init_guest_space logic doesn't keep this in mind when searching for an address range. If !host_start, then try to find a big continuous segment where we can put both the usable memory and the commpage; we then munmap that segment and set current_start to that address; and let the normal code mmap the usable memory and the commpage separately. That is: if we don't have hint of where to start looking for memory, come up with one that is better than NULL. Depending on host_size and guest_start, there may or may not be a gap between the usable memory and the commpage, so this is slightly more restrictive than it needs to be; but it's only a hint, so that's OK. We only do that for !host start, because if host_start, then either: - we got an address passed in with -B, in which case we don't want to interfere with what the user said; - or host_start is based off of the ELF image's loaddr. The check "if (host_start && real_start != current_start)" suggests that we really want lowest available address that is >= loaddr. I don't know why that is, but I'm trusting that Paul Brook knew what he was doing when he wrote the original version of that check in c581deda322080e8beb88b2e468d4af54454e4b3 way back in 2010. Signed-off-by: Luke Shumaker Message-Id: <20171228180814.9749-11-lukeshu@lukeshu.com> Signed-off-by: Laurent Vivier --- linux-user/elfload.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 4563a3190b..23e34957f9 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1889,6 +1889,55 @@ unsigned long init_guest_space(unsigned long host_start, /* Otherwise, a non-zero size region of memory needs to be mapped * and validated. */ + +#if defined(TARGET_ARM) && !defined(TARGET_AARCH64) + /* On 32-bit ARM, we need to map not just the usable memory, but + * also the commpage. Try to find a suitable place by allocating + * a big chunk for all of it. If host_start, then the naive + * strategy probably does good enough. + */ + if (!host_start) { + unsigned long guest_full_size, host_full_size, real_start; + + guest_full_size = + (0xffff0f00 & qemu_host_page_mask) + qemu_host_page_size; + host_full_size = guest_full_size - guest_start; + real_start = (unsigned long) + mmap(NULL, host_full_size, PROT_NONE, flags, -1, 0); + if (real_start == (unsigned long)-1) { + if (host_size < host_full_size - qemu_host_page_size) { + /* We failed to map a continous segment, but we're + * allowed to have a gap between the usable memory and + * the commpage where other things can be mapped. + * This sparseness gives us more flexibility to find + * an address range. + */ + goto naive; + } + return (unsigned long)-1; + } + munmap((void *)real_start, host_full_size); + if (real_start & ~qemu_host_page_mask) { + /* The same thing again, but with an extra qemu_host_page_size + * so that we can shift around alignment. + */ + unsigned long real_size = host_full_size + qemu_host_page_size; + real_start = (unsigned long) + mmap(NULL, real_size, PROT_NONE, flags, -1, 0); + if (real_start == (unsigned long)-1) { + if (host_size < host_full_size - qemu_host_page_size) { + goto naive; + } + return (unsigned long)-1; + } + munmap((void *)real_start, real_size); + real_start = HOST_PAGE_ALIGN(real_start); + } + current_start = real_start; + } + naive: +#endif + while (1) { unsigned long real_start, real_size, aligned_size; aligned_size = real_size = host_size;