From patchwork Wed Mar 18 17:05:07 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 45979 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wg0-f72.google.com (mail-wg0-f72.google.com [74.125.82.72]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 4854C2153C for ; Wed, 18 Mar 2015 17:09:50 +0000 (UTC) Received: by wghk14 with SMTP id k14sf8407486wgh.3 for ; Wed, 18 Mar 2015 10:09:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:subject:date:message-id :in-reply-to:references:cc:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version :content-type:content-transfer-encoding:sender:errors-to :x-original-sender:x-original-authentication-results:mailing-list; bh=nb4j+3BcpzgzDnMBHBoFH7zOza87pvynYoRChmgl1wA=; b=I/F8wWjwhvr4hBrDfeRxQsham7oaaeXjENwDrp+jyGXbL7c9PKW8tXzfjgrnKtJxCZ L75ElL/E31yRLjMzgVzrTJXxI2RqYgT5noPsahtdCp0NnsTMqoO9BPrrpTYjyVdsOc52 FnLMqSgOQNlzq8iOqOXE4OUEKfaSgLReJugH3K+7imgWKWcjsiC+7P09AhaYzghNayxB DEHw2SUTtgi9SLkppH+mxMxun6pUXHfawYJtUGOkPFfJKf/DCdTBmZ2Zf4sTNnvHXjZ5 dZ0oMvpIPEfbpKdCQHvKAOHU8veg0ZTxVn8qMZT+V4iBHxZ1CpHF4guU1r7Sg+uteV3L P/7g== X-Gm-Message-State: ALoCoQnq9zaeVKW1xvzsF/ja2b2xR7uvzvetClmx42PxW4Gi4OKAtOC3YwEda49cQbqOuRM2NomN X-Received: by 10.152.8.73 with SMTP id p9mr6914356laa.6.1426698589222; Wed, 18 Mar 2015 10:09:49 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.45.98 with SMTP id l2ls165280lam.28.gmail; Wed, 18 Mar 2015 10:09:48 -0700 (PDT) X-Received: by 10.112.171.65 with SMTP id as1mr65484124lbc.45.1426698588690; Wed, 18 Mar 2015 10:09:48 -0700 (PDT) Received: from mail-la0-f48.google.com (mail-la0-f48.google.com. [209.85.215.48]) by mx.google.com with ESMTPS id cn5si1025258lbd.77.2015.03.18.10.09.48 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 18 Mar 2015 10:09:48 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.48 as permitted sender) client-ip=209.85.215.48; Received: by lamx15 with SMTP id x15so41658818lam.3 for ; Wed, 18 Mar 2015 10:09:48 -0700 (PDT) X-Received: by 10.152.28.5 with SMTP id x5mr64134004lag.112.1426698588375; Wed, 18 Mar 2015 10:09:48 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.35.133 with SMTP id h5csp1287544lbj; Wed, 18 Mar 2015 10:09:47 -0700 (PDT) X-Received: by 10.70.54.103 with SMTP id i7mr103473207pdp.114.1426698586586; Wed, 18 Mar 2015 10:09:46 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id ij1si37170338pac.198.2015.03.18.10.09.45 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 18 Mar 2015 10:09:46 -0700 (PDT) Received-SPF: none (google.com: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org does not designate permitted sender hosts) client-ip=2001:1868:205::9; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YYHRc-0000mJ-U8; Wed, 18 Mar 2015 17:07:48 +0000 Received: from mail-we0-f170.google.com ([74.125.82.170]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YYHPp-0008GM-Rt for linux-arm-kernel@lists.infradead.org; Wed, 18 Mar 2015 17:05:59 +0000 Received: by webcq43 with SMTP id cq43so37438937web.2 for ; Wed, 18 Mar 2015 10:05:34 -0700 (PDT) X-Received: by 10.194.94.164 with SMTP id dd4mr146909964wjb.56.1426698334812; Wed, 18 Mar 2015 10:05:34 -0700 (PDT) Received: from ards-macbook-pro.local ([84.78.25.113]) by mx.google.com with ESMTPSA id dc9sm3972217wib.9.2015.03.18.10.05.32 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 18 Mar 2015 10:05:34 -0700 (PDT) From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org, linux@arm.linux.org.uk, will.deacon@arm.com, mark.rutland@arm.com, catalin.marinas@arm.com, robh@kernel.org Subject: [PATCH v3 4/5] arm64/efi: ensure that Image does not cross a 512 MB boundary Date: Wed, 18 Mar 2015 18:05:07 +0100 Message-Id: <1426698308-726-5-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1426698308-726-1-git-send-email-ard.biesheuvel@linaro.org> References: <1426698308-726-1-git-send-email-ard.biesheuvel@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150318_100558_122899_AE916645 X-CRM114-Status: GOOD ( 18.60 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [74.125.82.170 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [74.125.82.170 listed in wl.mailspike.net] -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders Cc: Ard Biesheuvel X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ard.biesheuvel@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.48 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 Update the Image placement logic used by the stub to make absolutely sure that the Image is placed such that the early init code will always be able to map it. This means the entire static memory footprint of the Image should be inside the same naturally aligned 512 MB region. First of all, the preferred offset of dram_base + TEXT_OFFSET is only suitable if it doesn't result in the Image crossing a 512 MB alignment boundary, which could be the case if dram_base itself is close to the end of a naturally aligned 512 MB region. Also, when moving the kernel Image, we need to verify that the new destination region does not cross a 512 MB alignment boundary either. If that is the case, we retry the allocation with the alignment chosen such that the resulting region will always be suitable. Signed-off-by: Ard Biesheuvel --- arch/arm64/kernel/efi-stub.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c index f5374065ad53..3b67ca4e2f2e 100644 --- a/arch/arm64/kernel/efi-stub.c +++ b/arch/arm64/kernel/efi-stub.c @@ -21,15 +21,40 @@ efi_status_t __init handle_kernel_image(efi_system_table_t *sys_table, unsigned long dram_base, efi_loaded_image_t *image) { + const unsigned long kernel_size = _edata - _text; + const unsigned long kernel_memsize = _end - _text; + unsigned long preferred_offset; efi_status_t status; - unsigned long kernel_size, kernel_memsize = 0; - - /* Relocate the image, if required. */ - kernel_size = _edata - _text; - if (*image_addr != (dram_base + TEXT_OFFSET)) { - kernel_memsize = kernel_size + (_end - _edata); - status = efi_low_alloc(sys_table, kernel_memsize + TEXT_OFFSET, - SZ_2M, reserve_addr); + + /* + * The kernel Image should be located as close as possible to the + * base of system RAM, but its static memory footprint must not + * cross a 512 MB alignment boundary. + */ + preferred_offset = dram_base + TEXT_OFFSET; + if ((preferred_offset & (SZ_512M - 1)) + kernel_memsize > SZ_512M) + preferred_offset = round_up(dram_base, SZ_512M) + TEXT_OFFSET; + + if (*image_addr != preferred_offset) { + const unsigned long alloc_size = kernel_memsize + TEXT_OFFSET; + + status = efi_low_alloc(sys_table, alloc_size, SZ_2M, + reserve_addr); + + /* + * Check whether the new allocation crosses a 512 MB alignment + * boundary. If so, retry with the alignment set to a power of + * two upper bound of the allocation size. That is guaranteed + * to produce a suitable allocation, but may waste more memory. + */ + if (status == EFI_SUCCESS && + ((*reserve_addr & (SZ_512M - 1)) + alloc_size) > SZ_512M) { + efi_free(sys_table, alloc_size, *reserve_addr); + + status = efi_low_alloc(sys_table, alloc_size, + roundup_pow_of_two(alloc_size), + reserve_addr); + } if (status != EFI_SUCCESS) { pr_efi_err(sys_table, "Failed to relocate kernel\n"); return status;