From patchwork Tue Jun 9 10:38:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Alex_Benn=C3=A9e?= X-Patchwork-Id: 187663 Delivered-To: patch@linaro.org Received: by 2002:a92:cf06:0:0:0:0:0 with SMTP id c6csp407444ilo; Tue, 9 Jun 2020 03:50:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJySrRle/OpURheuQpoNOK7nMFwCRvtWqSGZOx9Z/L32Vasq1beqe95oNBnCgQbcPEa5FBa0 X-Received: by 2002:a25:8b05:: with SMTP id i5mr5084781ybl.65.1591699816693; Tue, 09 Jun 2020 03:50:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1591699816; cv=none; d=google.com; s=arc-20160816; b=AbGC560ITVOuZJCjH8CwddhBPXH5BWrppWyPD83MfbDKjSix7ynugkWobQRJA75KiR ipq4ofXxtVttUiPCP2Oxd+NwJG/r2ve7bYF2Dj7lonnT9V0/U3F7i1mL/Baa8qlJL21q Lj4CCEHBM0ERIO//m6OFM8KSF6MOfwMJY3Nu1SjyhyqM8RgnGafw0ZLw9q+3ue3W/ugA onteSb0P1sNw7gMnF12SXwv8GBPcE2cwxqf1NDLiynqMEBhFw9nFi04ScF4jxIR7fqNk bGUI4OXXDDpxvB41p0xeEwrZ2R7SfFgd51SJfA+jxGned9ZQio8T1RuSAU9p16WE1aAi 6ymg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=zZed/y7QNny6kF0a14GXywWS17AGkkgGYqHaLimRe4g=; b=PnbJ496mQtfv13iRsucHVpEy19FZ+g9w6kCEzBzlU6DsQFv92LbzZv5Clr4mxZBEN7 ETW0kG4S1S45II5rKwdO6pjc5pUfvI3+1thVZRwzicfp7FBEsvYeGFJKbsOzoDttT4IP zg7dNCrLQATQFMB9c80lHq/OCQRKO0DQjuj9v43Cw//dozDxPTPZSLYB1y5j9+r9KKkl BgAQUozPLLdCdprVxLJMkyZDI2J3+IEX7EbcuUpXPlRoeKtaWvy0uWaGQAVa5gN7+hvk VESIAAx/5C8P3USMAAiipvz9I8g25t17XoxeIBQgl3lkVe0a4RtpLnfysHpJwXcrOrDb 0IDQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=MfMbn4rE; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id k205si2307119ybk.51.2020.06.09.03.50.16 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 09 Jun 2020 03:50:16 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=MfMbn4rE; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:39654 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jibpg-0006BM-36 for patch@linaro.org; Tue, 09 Jun 2020 06:50:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59322) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jibeH-0007qU-UI for qemu-devel@nongnu.org; Tue, 09 Jun 2020 06:38:29 -0400 Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]:42176) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jibeG-0004Pz-QB for qemu-devel@nongnu.org; Tue, 09 Jun 2020 06:38:29 -0400 Received: by mail-wr1-x443.google.com with SMTP id p5so20691678wrw.9 for ; Tue, 09 Jun 2020 03:38:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=zZed/y7QNny6kF0a14GXywWS17AGkkgGYqHaLimRe4g=; b=MfMbn4rEJRBBEYQmbyHlgeHjmEgYadWZC5Z4oQkHw3p8L1ahRn5cknwXJEkUQoOiiw 4Cr6743DQDdthweo06PKIO0rzlkCA2Gh5suvp1bvRYMJw1xolMxKtOeDSrSM8VltLDW3 S1u8uImQ0VQlziJ8sR9RDlbGmAUfyiHCikSXvlZ3Vt4RzouZ7xA2rkmbA0gBjhBQ1BQ/ 4g9Hhzq4xCHb5bHzkXCcQ4p5fAaqkl06aZWqxICsntovoslqOXSuvZudZ+aLMsFAe+hj mwRBzYmEqJL1QM7uzjf3VuoRBeWWSNMqCzfGVPFcaZ+HwkL8yQgHzxLigT+yAtBIo7Kk 77+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=zZed/y7QNny6kF0a14GXywWS17AGkkgGYqHaLimRe4g=; b=i7jNI1GylDRCUCI6ow+zPwvpCtq2LAWKCRqDlzS+VZCVm+VL+HuyC/MrP8vfsGCOLl sn2QettwR9l/whfxCZ54ufKOfpf9EX3miS7tnkWWPxPXjho8uYMpF3Z6Fpmp+ONS3A05 HCR3PsbpitYPBhE2NEm1XBRaeafUKXhC6+i7DAC8OwjcZqumTa21Zrqv66HAhHaZv5YC x8Mr8oRzDrOK71aVX7QRCoDxbix7f6TiwQ+Wmt5wkkKByPR4/BGYVtwK2mzMuqOZ67W2 bkhLw2k7fxx/J7iN7upjodE6WpP9NIbUK0abEdB3eEtsngVKjV7KQvnP8ygvFLyuYU/6 RE+A== X-Gm-Message-State: AOAM531otV1bLOv1wlqZ4xfRN3LOU55fKMqv7UhjgL8M9Gy3wcQmqZYT h4mVe4yfEuQ1gVqa2CnPq/sohw== X-Received: by 2002:adf:e58c:: with SMTP id l12mr3717353wrm.34.1591699107336; Tue, 09 Jun 2020 03:38:27 -0700 (PDT) Received: from zen.linaroharston ([51.148.130.216]) by smtp.gmail.com with ESMTPSA id a15sm2947032wra.86.2020.06.09.03.38.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jun 2020 03:38:19 -0700 (PDT) Received: from zen.lan (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id B504B1FF9A; Tue, 9 Jun 2020 11:38:11 +0100 (BST) From: =?utf-8?q?Alex_Benn=C3=A9e?= To: peter.maydell@linaro.org Subject: [PULL 11/17] linux-user: deal with address wrap for ARM_COMMPAGE on 32 bit Date: Tue, 9 Jun 2020 11:38:03 +0100 Message-Id: <20200609103809.23443-12-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200609103809.23443-1-alex.bennee@linaro.org> References: <20200609103809.23443-1-alex.bennee@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::443; envelope-from=alex.bennee@linaro.org; helo=mail-wr1-x443.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Bug 1880225 <1880225@bugs.launchpad.net>, Riku Voipio , Richard Henderson , qemu-devel@nongnu.org, Laurent Vivier , Aleksandar Markovic , =?utf-8?q?Alex_Benn=C3=A9e?= Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" We rely on the pointer to wrap when accessing the high address of the COMMPAGE so it lands somewhere reasonable. However on 32 bit hosts we cannot afford just to map the entire 4gb address range. The old mmap trial and error code handled this by just checking we could map both the guest_base and the computed COMMPAGE address. We can't just manipulate loadaddr to get what we want so we introduce an offset which pgb_find_hole can apply when looking for a gap for guest_base that ensures there is space left to map the COMMPAGE afterwards. This is arguably a little inefficient for the one 32 bit value (kuser_helper_version) we need to keep there given all the actual code entries are picked up during the translation phase. Fixes: ee94743034b Bug: https://bugs.launchpad.net/qemu/+bug/1880225 Cc: Bug 1880225 <1880225@bugs.launchpad.net> Signed-off-by: Alex Bennée Tested-by: Aleksandar Markovic Cc: Richard Henderson Cc: Peter Maydell Message-Id: <20200605154929.26910-13-alex.bennee@linaro.org> -- 2.20.1 diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 475d243f3bd..b5cb21384a1 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -389,7 +389,7 @@ static bool init_guest_commpage(void) { void *want = g2h(ARM_COMMPAGE & -qemu_host_page_size); void *addr = mmap(want, qemu_host_page_size, PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0); if (addr == MAP_FAILED) { perror("Allocating guest commpage"); @@ -2113,7 +2113,8 @@ static void pgb_have_guest_base(const char *image_name, abi_ulong guest_loaddr, * only dumbly iterate up the host address space seeing if the * allocation would work. */ -static uintptr_t pgd_find_hole_fallback(uintptr_t guest_size, uintptr_t brk, long align) +static uintptr_t pgd_find_hole_fallback(uintptr_t guest_size, uintptr_t brk, + long align, uintptr_t offset) { uintptr_t base; @@ -2123,7 +2124,7 @@ static uintptr_t pgd_find_hole_fallback(uintptr_t guest_size, uintptr_t brk, lon while (true) { uintptr_t align_start, end; align_start = ROUND_UP(base, align); - end = align_start + guest_size; + end = align_start + guest_size + offset; /* if brk is anywhere in the range give ourselves some room to grow. */ if (align_start <= brk && brk < end) { @@ -2138,7 +2139,7 @@ static uintptr_t pgd_find_hole_fallback(uintptr_t guest_size, uintptr_t brk, lon PROT_NONE, flags, -1, 0); if (mmap_start != MAP_FAILED) { munmap((void *) align_start, guest_size); - return (uintptr_t) mmap_start; + return (uintptr_t) mmap_start + offset; } base += qemu_host_page_size; } @@ -2147,7 +2148,7 @@ static uintptr_t pgd_find_hole_fallback(uintptr_t guest_size, uintptr_t brk, lon /* Return value for guest_base, or -1 if no hole found. */ static uintptr_t pgb_find_hole(uintptr_t guest_loaddr, uintptr_t guest_size, - long align) + long align, uintptr_t offset) { GSList *maps, *iter; uintptr_t this_start, this_end, next_start, brk; @@ -2161,7 +2162,7 @@ static uintptr_t pgb_find_hole(uintptr_t guest_loaddr, uintptr_t guest_size, brk = (uintptr_t)sbrk(0); if (!maps) { - return pgd_find_hole_fallback(guest_size, brk, align); + return pgd_find_hole_fallback(guest_size, brk, align, offset); } /* The first hole is before the first map entry. */ @@ -2173,7 +2174,7 @@ static uintptr_t pgb_find_hole(uintptr_t guest_loaddr, uintptr_t guest_size, this_end = ((MapInfo *)iter->data)->start; next_start = ((MapInfo *)iter->data)->end; - align_start = ROUND_UP(this_start, align); + align_start = ROUND_UP(this_start + offset, align); /* Skip holes that are too small. */ if (align_start >= this_end) { @@ -2223,6 +2224,7 @@ static void pgb_static(const char *image_name, abi_ulong orig_loaddr, { uintptr_t loaddr = orig_loaddr; uintptr_t hiaddr = orig_hiaddr; + uintptr_t offset = 0; uintptr_t addr; if (hiaddr != orig_hiaddr) { @@ -2236,18 +2238,19 @@ static void pgb_static(const char *image_name, abi_ulong orig_loaddr, if (ARM_COMMPAGE) { /* * Extend the allocation to include the commpage. - * For a 64-bit host, this is just 4GiB; for a 32-bit host, - * the address arithmetic will wrap around, but the difference - * will produce the correct allocation size. + * For a 64-bit host, this is just 4GiB; for a 32-bit host we + * need to ensure there is space bellow the guest_base so we + * can map the commpage in the place needed when the address + * arithmetic wraps around. */ if (sizeof(uintptr_t) == 8 || loaddr >= 0x80000000u) { - hiaddr = (uintptr_t)4 << 30; + hiaddr = (uintptr_t) 4 << 30; } else { - loaddr = ARM_COMMPAGE & -align; + offset = -(ARM_COMMPAGE & -align); } } - addr = pgb_find_hole(loaddr, hiaddr - loaddr, align); + addr = pgb_find_hole(loaddr, hiaddr - loaddr, align, offset); if (addr == -1) { /* * If ARM_COMMPAGE, there *might* be a non-consecutive allocation @@ -2282,7 +2285,7 @@ static void pgb_dynamic(const char *image_name, long align) * just above that, and maximises the positive guest addresses. */ commpage = ARM_COMMPAGE & -align; - addr = pgb_find_hole(commpage, -commpage, align); + addr = pgb_find_hole(commpage, -commpage, align, 0); assert(addr != -1); guest_base = addr; }