From patchwork Tue Apr 4 16:02:37 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 96748 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp264170qgd; Tue, 4 Apr 2017 09:05:16 -0700 (PDT) X-Received: by 10.99.216.85 with SMTP id k21mr24612043pgj.10.1491321916098; Tue, 04 Apr 2017 09:05:16 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 17si5954615pfn.224.2017.04.04.09.05.16; Tue, 04 Apr 2017 09:05:16 -0700 (PDT) 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 S1754907AbdDDQDW (ORCPT + 2 others); Tue, 4 Apr 2017 12:03:22 -0400 Received: from mail-wm0-f43.google.com ([74.125.82.43]:37241 "EHLO mail-wm0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754887AbdDDQDU (ORCPT ); Tue, 4 Apr 2017 12:03:20 -0400 Received: by mail-wm0-f43.google.com with SMTP id x124so32344285wmf.0 for ; Tue, 04 Apr 2017 09:03:14 -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; bh=WHa8GRUoWJyy8G5yx9gH6yXurdlfa1ibiftTFMobKOk=; b=FQ2H9SGxp7I+OMLYb7qdyRMzyX3MprsFvnyeHGotPSmjJghluQPVc/zEm8ydGKXGTM q381w6w6j+ZCFDGtJpgHnkBKivlYb7u3ch9EOYQojh8vTtpOIhJq3GQdEW396tGakenx I2VzjcAdx4kAeZq1eQ7FCsTKg366HEcAoDztQ= 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; bh=WHa8GRUoWJyy8G5yx9gH6yXurdlfa1ibiftTFMobKOk=; b=gNpxBq0MIBMn+SUf0E9S9y1XHEUc2Qjg9EghL0pV4yZkPxy5DoUkVgV/wWGeEhGJ+X k3r3N6i275Ccuyai/otVeV+VlKkjOWf47OEFyBKeZJEH7LevrIVnZG/XVyINQSfKYtqf YapqsN0tNRfpENwEJTROWwwiYW2KkxKmtJnVoDiX0Bs6ePC4S31QRwTiC2kEzoa2kik9 xxZIE6s+5mmvRvldvVLfYeKrj8icmAgADjSZk0dqtJQYOujeN6E62eZIexbtea26sBoT 5mx7oxyGTMAlzXON8/sMOqEspKPRb2EjuQSLyz8ji0FnznxyTQvf6Iwkba6Ur/OdXLSj jOvw== X-Gm-Message-State: AFeK/H19vb/4C87LubDr6yWmXsIAZDuOz8aC14kj2P2HMDrujFLF97+o0gTd3/u1P9zcd7y2 X-Received: by 10.28.140.19 with SMTP id o19mr15647456wmd.123.1491321794033; Tue, 04 Apr 2017 09:03:14 -0700 (PDT) Received: from localhost.localdomain ([160.163.145.113]) by smtp.gmail.com with ESMTPSA id z88sm19686465wrb.1.2017.04.04.09.03.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Apr 2017 09:03:13 -0700 (PDT) From: Ard Biesheuvel To: linux-efi@vger.kernel.org, Ingo Molnar , Thomas Gleixner , "H . Peter Anvin" Cc: Ard Biesheuvel , linux-kernel@vger.kernel.org Subject: [PATCH 02/12] efi: arm-stub: Correct FDT and initrd allocation rules for arm64 Date: Tue, 4 Apr 2017 17:02:37 +0100 Message-Id: <20170404160245.27812-4-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170404160245.27812-1-ard.biesheuvel@linaro.org> References: <20170404160245.27812-1-ard.biesheuvel@linaro.org> 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 mostly a theoretical scenario, since it only affects systems where the physical memory footprint exceeds the size of the linear mapping.) Since we know the kernel itself will be covered by the linear mapping, choose a suitably sized window (i.e., based on the size of the linear region) covering the kernel when allocating memory for the initrd. 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. Cc: Matt Fleming Tested-by: Richard Ruigrok Reviewed-by: Jeffrey Hugo Signed-off-by: Ard Biesheuvel --- arch/arm/include/asm/efi.h | 14 +++++++++++++- arch/arm64/include/asm/efi.h | 23 ++++++++++++++++++++++- drivers/firmware/efi/libstub/arm-stub.c | 7 ++++--- 3 files changed, 39 insertions(+), 5 deletions(-) -- 2.9.3 -- 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 diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index e4e6a9d6a825..17f1f1a814ff 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -85,6 +85,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 e7445281e534..083a52d3b59f 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h @@ -46,7 +46,28 @@ 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, we have to ensure that the initrd ends up in the linear region, + * which is a 1 GB aligned region of size '1UL << (VA_BITS - 1)' that is + * guaranteed to cover the kernel Image. + * + * Since the EFI stub is part of the kernel Image, we can relax the + * usual requirements in Documentation/arm64/booting.txt, which still + * apply to other bootloaders, and are required for some kernel + * configurations. + */ +static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base, + unsigned long image_addr) +{ + return (image_addr & ~(SZ_1G - 1UL)) + (1UL << (VA_BITS - 1)); +} #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 d4056c6be1ec..02049ff25c6b 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -213,8 +213,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) @@ -224,7 +225,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);