From patchwork Thu Feb 9 10:16:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 93690 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp174376qgi; Thu, 9 Feb 2017 02:17:13 -0800 (PST) X-Received: by 10.98.73.74 with SMTP id w71mr2870453pfa.52.1486635433025; Thu, 09 Feb 2017 02:17:13 -0800 (PST) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r74si9674479pfg.146.2017.02.09.02.17.12; Thu, 09 Feb 2017 02:17:13 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-efi-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-efi-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752003AbdBIKRG (ORCPT + 2 others); Thu, 9 Feb 2017 05:17:06 -0500 Received: from mail-wm0-f53.google.com ([74.125.82.53]:38474 "EHLO mail-wm0-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751777AbdBIKRD (ORCPT ); Thu, 9 Feb 2017 05:17:03 -0500 Received: by mail-wm0-f53.google.com with SMTP id r141so14143970wmg.1 for ; Thu, 09 Feb 2017 02:16:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=Insxk6nearRT5o9y2Aoxag1lNYIccXwmeEzEktltUo0=; b=PTuvad2NzzuiRm1d/pRluFHLe7jSd4BJzsbgjQEERxnHl3uspC0kfjDaGA1Ve5EUix NurZmBdsuXd4q5pfnh/Rbkyh22TLz3z//ve812FV2UESigVKPQzvL7gXYLdY8HT7yHnu OiqzPT5T9eS9ROQWjWsmHIpxutd/F5i+1hn1w= 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; bh=Insxk6nearRT5o9y2Aoxag1lNYIccXwmeEzEktltUo0=; b=Nw2h1OcZ/FpnBDAYmRLJ8k6VFX5yuFote02lKABHKTOJA75rgjcN3aQyhFMG2lV05G ZhYaRajqZRZeVLvy67+jPKIttCr49DLFZxvJNpBG7PQ/6fv2ASeosqf2LO7i9XZiFod5 iFdNTjJaDMCFX4uWMlosgx01ttAlNav/bmk7q4Xc0E3/OYHbmjv3TxzSeZ4r5kc7C36Q NsH2r8nXcXjkxFUIupO63Vfal3P1VyfWTo7aOr6kLs+WVq4GLeJZrM+MJEz7dljTTJia r1yT0KOYrybqMCioCHi72MCRPPT+HeTZ8CQmQP04qqSx/89NbU2FBTiWHeu5m6f6E+Zd UHLg== X-Gm-Message-State: AMke39mHYySnwfCIGAJcr+LJrZUJj90tK5pZo/37I7+aBiAFS30Wg34c93Of9e1MpJsXsNpF X-Received: by 10.28.191.139 with SMTP id o11mr23120187wmi.97.1486635400584; Thu, 09 Feb 2017 02:16:40 -0800 (PST) Received: from localhost.localdomain ([160.169.163.122]) by smtp.gmail.com with ESMTPSA id o42sm17683755wrb.18.2017.02.09.02.16.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 09 Feb 2017 02:16:39 -0800 (PST) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, matt@codeblueprint.co.uk, mark.rutland@arm.com Cc: timur@codeaurora.org, jhugo@codeaurora.org, leif.lindholm@linaro.org, catalin.marinas@arm.com, Ard Biesheuvel Subject: [PATCH] efi: arm-stub: Correct FDT and initrd allocation rules for arm64 Date: Thu, 9 Feb 2017 10:16:29 +0000 Message-Id: <1486635389-26974-1-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 Sender: linux-efi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org On arm64, we have made some changes over the past year to the way the kernel itself is allocated and to how it deals with the initrd and FDT. This patch brings the allocation logic in the EFI stub in line with that, which is necessary because the introduction of KASLR has created the possibility for the initrd to be allocated in a place where the kernel may not be able to map it. (This is currently a theoretical scenario, since it only affects systems where the size of RAM exceeds the size of the linear mapping.) So adhere to the arm64 boot protocol, and make sure that the initrd is fully inside a 1GB aligned 32 GB window that covers the kernel as well. The FDT may be anywhere in memory on arm64 now that we map it via the fixmap, so we can lift the address restriction there completely. Signed-off-by: Ard Biesheuvel --- arch/arm/include/asm/efi.h | 14 +++++++++++++- arch/arm64/include/asm/efi.h | 19 ++++++++++++++++++- drivers/firmware/efi/libstub/arm-stub.c | 7 ++++--- 3 files changed, 35 insertions(+), 5 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Tested-by: Richard Ruigrok diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index 0b06f5341b45..62620451f60b 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -84,6 +84,18 @@ static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) */ #define ZIMAGE_OFFSET_LIMIT SZ_128M #define MIN_ZIMAGE_OFFSET MAX_UNCOMP_KERNEL_SIZE -#define MAX_FDT_OFFSET ZIMAGE_OFFSET_LIMIT + +/* on ARM, the FDT should be located in the first 128 MB of RAM */ +static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) +{ + return dram_base + ZIMAGE_OFFSET_LIMIT; +} + +/* on ARM, the initrd should be loaded in a lowmem region */ +static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, + unsigned long image_addr) +{ + return dram_base + SZ_512M; +} #endif /* _ASM_ARM_EFI_H */ diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 0b6b1633017f..6a6c8a0d1424 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -46,7 +46,24 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); * 2MiB so we know it won't cross a 2MiB boundary. */ #define EFI_FDT_ALIGN SZ_2M /* used by allocate_new_fdt_and_exit_boot() */ -#define MAX_FDT_OFFSET SZ_512M + +/* on arm64, the FDT may be located anywhere in system RAM */ +static inline unsigned long efi_get_max_fdt_addr(unsigned long dram_base) +{ + return ULONG_MAX; +} + +/* + * On arm64, the initrd must be completely inside a 1 GB aligned 32 GB window + * that covers Image as well. Since we allocate from the top down, set a max + * address that is virtually guaranteed to produce a suitable allocation even + * when the physical address of Image is randomized. + */ +static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, + unsigned long image_addr) +{ + return ALIGN(image_addr, SZ_1G) + 31UL * SZ_1G; +} #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) #define __efi_call_early(f, ...) f(__VA_ARGS__) diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index b4f7d78f9e8b..557281fe375f 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -333,8 +333,9 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table, if (!fdt_addr) pr_efi(sys_table, "Generating empty DTB\n"); - status = handle_cmdline_files(sys_table, image, cmdline_ptr, - "initrd=", dram_base + SZ_512M, + status = handle_cmdline_files(sys_table, image, cmdline_ptr, "initrd=", + efi_get_max_initrd_addr(dram_base, + *image_addr), (unsigned long *)&initrd_addr, (unsigned long *)&initrd_size); if (status != EFI_SUCCESS) @@ -344,7 +345,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table, new_fdt_addr = fdt_addr; status = allocate_new_fdt_and_exit_boot(sys_table, handle, - &new_fdt_addr, dram_base + MAX_FDT_OFFSET, + &new_fdt_addr, efi_get_max_fdt_addr(dram_base), initrd_addr, initrd_size, cmdline_ptr, fdt_addr, fdt_size);