From patchwork Sun Sep 18 21:35:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607494 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6817EECAAD8 for ; Sun, 18 Sep 2022 21:36:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229553AbiIRVgD (ORCPT ); Sun, 18 Sep 2022 17:36:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40488 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229458AbiIRVgC (ORCPT ); Sun, 18 Sep 2022 17:36:02 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA68813FA8; Sun, 18 Sep 2022 14:36:01 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 682C76124F; Sun, 18 Sep 2022 21:36:01 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E6280C433C1; Sun, 18 Sep 2022 21:35:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536960; bh=TJjBRuCFTW+TJ1tt9NdDPb5mim7RRsT5BJz/uob9soA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ouymYfWFPXrDhSVTKIcxCCgoerFV7LjGU/A48qK0PbAwS2c45hhtnVE8gztZVa+Lh Ib1diYe+z3LF/mLC4nWJ5yFBCaVC7h2dLAoIqHCjzMP9WGdTWTUP1rOGqVAkfJT5IU ZIhj84bitKoPZCyzBwdLNQ3xXOe8K9ZvaZ8ehf6BhCpEU9/jYwl2FLaVAS1xuz90eA RJr31dBkt4joc0N/CK3Y/xEholrB3zz8G3RdlUKhx5Vz0EOu2D1ZITOzDcZm2ljftl +6rltJoWsNl5XsXoMLxLTdRkIBKV1HZecT9cdRlt5Hq2Ih0ZTHC2P3oJsisReGGzhF ricYegAX7N2Bg== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao , stable@vger.kernel.org Subject: [PATCH 01/12] efi: libstub: drop pointless get_memory_map() call Date: Sun, 18 Sep 2022 23:35:33 +0200 Message-Id: <20220918213544.2176249-2-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1124; i=ardb@kernel.org; h=from:subject; bh=TJjBRuCFTW+TJ1tt9NdDPb5mim7RRsT5BJz/uob9soA=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48bKlM+G5MYutM2WkSBF4HCuh+vKaoUimCOFi8b OqVzWv6JAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePGwAKCRDDTyI5ktmPJCdHDA C+XpPZryd6JF0pxHF7VvkMPRMqZ/4CgyBiS4kQhzfaW8Hv9/ZNvJ5wM/dcQ1xPWHi4gSXn47CylTJI gJqPY9FaPFlS9Cy/cOwSEZuDN8JjxXlAzt5tk2VjS9U2iDBJa8Zx5y6hIgjBg1D8v/vfBEFAaBvTg7 EeVwfrO73C9qvZU/e2DsWrkwHQczHxgyqeObDc7khxJdANkdOnQ8cNsUuqsdX3DnKH1NflXFLf+Fw/ 1OekhLc+zJXmBx1nvZkrVuKROIKS+DPKV78CQnUAKOuDIvXKmIcDqXG0F1BNN/hJltJSf02r3ZZ3vc 45I8vQAt23P4Uo88bbNgRlJKlJ1SP9F5zXF2V/UJT9GNKh/jS5BRuW1PB7Rg4rBU31UNJdbT/WaKMj f92bBQ6DXgh0ReqDS9wJ3bkPs2//RNe23rlgVuzaPd4zup0wFov0C7v6rh0EMT9/JqhoCnSTA/KXMi yFZHXBlWQSEK/OMq5sfNAo31Ujf9jrGIMaEXmQWlBLFOM= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Currently, the non-x86 stub code calls get_memory_map() redundantly, given that the data it returns is never used anywhere. So drop the call. Cc: # v4.14+ Fixes: 24d7c494ce46 ("efi/arm-stub: Round up FDT allocation to mapping size") Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/fdt.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index fe567be0f118..804f542be3f2 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -280,14 +280,6 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, goto fail; } - /* - * Now that we have done our final memory allocation (and free) - * we can get the memory map key needed for exit_boot_services(). - */ - status = efi_get_memory_map(&map); - if (status != EFI_SUCCESS) - goto fail_free_new_fdt; - status = update_fdt((void *)fdt_addr, fdt_size, (void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr, initrd_addr, initrd_size); From patchwork Sun Sep 18 21:35:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607259 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DED2FC6FA82 for ; Sun, 18 Sep 2022 21:36:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229519AbiIRVgG (ORCPT ); Sun, 18 Sep 2022 17:36:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40498 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229458AbiIRVgF (ORCPT ); Sun, 18 Sep 2022 17:36:05 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0D07A13FA2 for ; Sun, 18 Sep 2022 14:36:04 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 9BFEE6124F for ; Sun, 18 Sep 2022 21:36:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 49071C4347C; Sun, 18 Sep 2022 21:36:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536963; bh=y3ippfakNziyrf/LXyt70wrU7kpfg7DaJewJBo4f+zA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y5tUNQ0AJ+N4eBRp0M81v+FxjAxdePU2CaXteQL1aWEmjQCnm5W/8yWFO4nYztMun TZ57K6Ddvxk6p9Aj+B+IzYsJoBPxFMNpFKmUT+pI2xrI7cLxG5kr2I12J3I+mW3oJ0 35vPQqTmHaHQeQARkhdKTky3oKFy5FvmjoPdvvUM8nT7qhqvVz8Fno5oKIJVRysaYV GQO6v8DeFHO6bXK3MkZJ/MzftH/4quDO99DLCtsdCQ4YdDp0XlmkGD2SuvVX30ITTR 4VnmXsT+yIi8tafrkQViMXoHPyUqn7i71DukrG3D348zQO5JrBtAok4AlK+M4/B1of UDd/s2zGnHnMA== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao Subject: [PATCH 02/12] efi/arm: libstub: move ARM specific code out of generic routines Date: Sun, 18 Sep 2022 23:35:34 +0200 Message-Id: <20220918213544.2176249-3-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7577; i=ardb@kernel.org; h=from:subject; bh=y3ippfakNziyrf/LXyt70wrU7kpfg7DaJewJBo4f+zA=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48dYtfo+7GQ6q0ijrKSkUAHnRY8FULUwMPZYMoS hU3l+YeJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePHQAKCRDDTyI5ktmPJALyC/ 9IMShjTAJ6ceHuIyWQl689tVJjMhtfjyKjht1SiNqoc+JhfWjYps/z5PukOHBnbCptyBeWoi8LkcGg Ty4chLjh/E37bkGSdrNsygT8q2zbL59+LUKMOgZc+gx/ijD9Q2uuKTcw7/L3Y4Ldxc9++BGscFJ3q1 0oUoe2wqJ8G7iMYdArQfK94O7yHTDizjlsuUCPyJCp3tmUx3Wwuw+CUpheJbtjBJBFnAdwgdS2L7h8 C7hb73L1DOf1uaL8CglBo5kUamRgT019LbRoDbd9wD1ntW/fSi9vMiDk+ENrg4nlhtR08eKbIHEJ14 rjFKBMr6LtSVhEXjMjjAYj5WJ8hcr7jdFvwUl9dLukZ+WDqplEmw8ndT9USqeX0eSZrMyEkSfB33F1 CtHgESUp/x/A5hziP28jv2qfDLZqnlt1IdET3l2nW9vH5q53pW/uRFZD5rDEHh7iXNeQZemjY1wGOw UWXYQEAiT0ivSJOePss3sDCZT8JIRS0dv0YG2q+StOWAA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Move some code that is only reachable when IS_ENABLED(CONFIG_ARM) into the ARM EFI arch code. Cc: Russell King Signed-off-by: Ard Biesheuvel --- arch/arm/include/asm/efi.h | 3 +- arch/arm/kernel/efi.c | 79 ++++++++++++++++++++ arch/arm/kernel/setup.c | 2 +- drivers/firmware/efi/efi-init.c | 61 +-------------- 4 files changed, 84 insertions(+), 61 deletions(-) diff --git a/arch/arm/include/asm/efi.h b/arch/arm/include/asm/efi.h index 3088ef72704e..4bdd930167c0 100644 --- a/arch/arm/include/asm/efi.h +++ b/arch/arm/include/asm/efi.h @@ -17,6 +17,7 @@ #ifdef CONFIG_EFI void efi_init(void); +void arm_efi_init(void); int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md); int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md); @@ -37,7 +38,7 @@ void efi_virtmap_load(void); void efi_virtmap_unload(void); #else -#define efi_init() +#define arm_efi_init() #endif /* CONFIG_EFI */ /* arch specific definitions used by the stub code */ diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c index e57dbcc89123..e50ad7eefc02 100644 --- a/arch/arm/kernel/efi.c +++ b/arch/arm/kernel/efi.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -73,3 +74,81 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) return efi_set_mapping_permissions(mm, md); return 0; } + +static unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; +static unsigned long __initdata cpu_state_table = EFI_INVALID_TABLE_ADDR; + +const efi_config_table_type_t efi_arch_tables[] __initconst = { + {LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, &screen_info_table}, + {LINUX_EFI_ARM_CPU_STATE_TABLE_GUID, &cpu_state_table}, + {} +}; + +static void __init load_screen_info_table(void) +{ + struct screen_info *si; + + if (screen_info_table != EFI_INVALID_TABLE_ADDR) { + si = early_memremap_ro(screen_info_table, sizeof(*si)); + if (!si) { + pr_err("Could not map screen_info config table\n"); + return; + } + screen_info = *si; + early_memunmap(si, sizeof(*si)); + + /* dummycon on ARM needs non-zero values for columns/lines */ + screen_info.orig_video_cols = 80; + screen_info.orig_video_lines = 25; + + if (memblock_is_map_memory(screen_info.lfb_base)) + memblock_mark_nomap(screen_info.lfb_base, + screen_info.lfb_size); + } +} + +static void __init load_cpu_state_table(void) +{ + if (cpu_state_table != EFI_INVALID_TABLE_ADDR) { + struct efi_arm_entry_state *state; + bool dump_state = true; + + state = early_memremap_ro(cpu_state_table, + sizeof(struct efi_arm_entry_state)); + if (state == NULL) { + pr_warn("Unable to map CPU entry state table.\n"); + return; + } + + if ((state->sctlr_before_ebs & 1) == 0) + pr_warn(FW_BUG "EFI stub was entered with MMU and Dcache disabled, please fix your firmware!\n"); + else if ((state->sctlr_after_ebs & 1) == 0) + pr_warn(FW_BUG "ExitBootServices() returned with MMU and Dcache disabled, please fix your firmware!\n"); + else + dump_state = false; + + if (dump_state || efi_enabled(EFI_DBG)) { + pr_info("CPSR at EFI stub entry : 0x%08x\n", + state->cpsr_before_ebs); + pr_info("SCTLR at EFI stub entry : 0x%08x\n", + state->sctlr_before_ebs); + pr_info("CPSR after ExitBootServices() : 0x%08x\n", + state->cpsr_after_ebs); + pr_info("SCTLR after ExitBootServices(): 0x%08x\n", + state->sctlr_after_ebs); + } + early_memunmap(state, sizeof(struct efi_arm_entry_state)); + } +} + +void __init arm_efi_init(void) +{ + efi_init(); + + load_screen_info_table(); + + /* ARM does not permit early mappings to persist across paging_init() */ + efi_memmap_unmap(); + + load_cpu_state_table(); +} diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 1e8a50a97edf..cb88c6e69377 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -1141,7 +1141,7 @@ void __init setup_arch(char **cmdline_p) #endif setup_dma_zone(mdesc); xen_early_init(); - efi_init(); + arm_efi_init(); /* * Make sure the calculation for lowmem/highmem is set appropriately * before reserving/allocating any memory diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c index 3928dbff76d0..2fd770b499a3 100644 --- a/drivers/firmware/efi/efi-init.c +++ b/drivers/firmware/efi/efi-init.c @@ -51,34 +51,10 @@ static phys_addr_t __init efi_to_phys(unsigned long addr) return addr; } -static __initdata unsigned long screen_info_table = EFI_INVALID_TABLE_ADDR; -static __initdata unsigned long cpu_state_table = EFI_INVALID_TABLE_ADDR; - -static const efi_config_table_type_t arch_tables[] __initconst = { - {LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID, &screen_info_table}, - {LINUX_EFI_ARM_CPU_STATE_TABLE_GUID, &cpu_state_table}, - {} -}; +extern __weak const efi_config_table_type_t efi_arch_tables[]; static void __init init_screen_info(void) { - struct screen_info *si; - - if (IS_ENABLED(CONFIG_ARM) && - screen_info_table != EFI_INVALID_TABLE_ADDR) { - si = early_memremap_ro(screen_info_table, sizeof(*si)); - if (!si) { - pr_err("Could not map screen_info config table\n"); - return; - } - screen_info = *si; - early_memunmap(si, sizeof(*si)); - - /* dummycon on ARM needs non-zero values for columns/lines */ - screen_info.orig_video_cols = 80; - screen_info.orig_video_lines = 25; - } - if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI && memblock_is_map_memory(screen_info.lfb_base)) memblock_mark_nomap(screen_info.lfb_base, screen_info.lfb_size); @@ -119,8 +95,7 @@ static int __init uefi_init(u64 efi_system_table) goto out; } retval = efi_config_parse_tables(config_tables, systab->nr_tables, - IS_ENABLED(CONFIG_ARM) ? arch_tables - : NULL); + efi_arch_tables); early_memunmap(config_tables, table_size); out: @@ -248,36 +223,4 @@ void __init efi_init(void) PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK))); init_screen_info(); - -#ifdef CONFIG_ARM - /* ARM does not permit early mappings to persist across paging_init() */ - efi_memmap_unmap(); - - if (cpu_state_table != EFI_INVALID_TABLE_ADDR) { - struct efi_arm_entry_state *state; - bool dump_state = true; - - state = early_memremap_ro(cpu_state_table, - sizeof(struct efi_arm_entry_state)); - if (state == NULL) { - pr_warn("Unable to map CPU entry state table.\n"); - return; - } - - if ((state->sctlr_before_ebs & 1) == 0) - pr_warn(FW_BUG "EFI stub was entered with MMU and Dcache disabled, please fix your firmware!\n"); - else if ((state->sctlr_after_ebs & 1) == 0) - pr_warn(FW_BUG "ExitBootServices() returned with MMU and Dcache disabled, please fix your firmware!\n"); - else - dump_state = false; - - if (dump_state || efi_enabled(EFI_DBG)) { - pr_info("CPSR at EFI stub entry : 0x%08x\n", state->cpsr_before_ebs); - pr_info("SCTLR at EFI stub entry : 0x%08x\n", state->sctlr_before_ebs); - pr_info("CPSR after ExitBootServices() : 0x%08x\n", state->cpsr_after_ebs); - pr_info("SCTLR after ExitBootServices(): 0x%08x\n", state->sctlr_after_ebs); - } - early_memunmap(state, sizeof(struct efi_arm_entry_state)); - } -#endif } From patchwork Sun Sep 18 21:35:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607493 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2A328C6FA86 for ; Sun, 18 Sep 2022 21:36:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229610AbiIRVgI (ORCPT ); Sun, 18 Sep 2022 17:36:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229541AbiIRVgH (ORCPT ); Sun, 18 Sep 2022 17:36:07 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5015413FAB for ; Sun, 18 Sep 2022 14:36:06 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id C26F66124F for ; Sun, 18 Sep 2022 21:36:05 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 74710C43142; Sun, 18 Sep 2022 21:36:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536965; bh=7HZgiqzu7o/tWfKhqeYeSjtgA75cQnUPmVMIgyCrRUE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=l0BUkew0BR5qICHyO8up2cUq6ReYUaXqUYpfc111WCRbYi5NTTTfrOqXsFJHO8RQB r+fyRR1Wbaw8H48yUPnJSSZogWhJ2Jpnaw7H75uUn3ihtAfwmtqWT7G4uB07qNgaVO Cu1hmMIyoD1kU2SNiy1BA8vqtyiYkaqxKmAgJxbUSwtxNIxcLagob4SWOCE3k/YSK/ 2xI2//k314qTJKFoAQoRfTfPHzm+vtOmmnH/XaFkTvic8G9OW3D81WfI31m75dpAK3 ZYn2yrUxYua8cPy53gf4hYgMO0C11g5KAEUvajJaVYN6YxanKqEvYI9dZI8iu/PP9D x/q0B932I2nRw== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao Subject: [PATCH 03/12] efi: libstub: fix up the last remaining open coded boot service call Date: Sun, 18 Sep 2022 23:35:35 +0200 Message-Id: <20220918213544.2176249-4-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1100; i=ardb@kernel.org; h=from:subject; bh=7HZgiqzu7o/tWfKhqeYeSjtgA75cQnUPmVMIgyCrRUE=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48fdgYWwLhjVcrl8sLqZFdaAlsdcvb39GlDuse6 YBIDQVuJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePHwAKCRDDTyI5ktmPJJXPDA C87CoWiqRDu3R9G8Bcdz0lK8RCp0qAaQS3eFYNfQg8A2vi/dNiDAjqE8CIlw9j2Mwxns4WpXG3G66l l62jCg+4fzHruQ6mnqXnZS/+Zwyu7KjcCqfaAC5aB0sTdLod8Y4+Rb2XcEaK+Zi/KAjZE+zJP5aVsi 0wUN38b9S9rGCbgoKu7FUy8ITQWBTpGJhnRU1h71o8+x9zdJqQTh2DpNL0yaIjD6WPBXahb2XdBgN4 sWXF73LWU75ahQVB+fWR3L/Uzp70yLqXZiXhwKuDGWn1554IrQ1BheGcSvlOKPhqg33z4r1JaE5Xxx +0Pf2XYchCVYeZWzN2z2aIZPbEqTTjdVLMZX1aM97GHJuXLP9OlkzWcwHlehZSFO1sJasHB6AvDSFu IwYpP1yag/9Yra3iPK7iIzXLrZBFNb7cr9W/MabGdFL9k4d4OVpzXyCtzYzf37i5JzxULMOR5dB3MS 4zJt9PeG7dduTD/m/np/MLwww2uo60Qx9uLUlPj2lRP6A= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org We use a macro efi_bs_call() to call boot services, which is more concise, and on x86, it encapsulates the mixed mode handling. This code does not run in mixed mode, but let's switch to the macro for general tidiness. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/efi-stub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index 57ea04378087..97eaa487fdfd 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -160,8 +160,8 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, * information about the running image, such as size and the command * line. */ - status = efi_system_table->boottime->handle_protocol(handle, - &loaded_image_proto, (void *)&image); + status = efi_bs_call(handle_protocol, handle, &loaded_image_proto, + (void *)&image); if (status != EFI_SUCCESS) { efi_err("Failed to get loaded image protocol\n"); goto fail; From patchwork Sun Sep 18 21:35:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607258 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 23D88ECAAD8 for ; Sun, 18 Sep 2022 21:36:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229541AbiIRVgL (ORCPT ); Sun, 18 Sep 2022 17:36:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40528 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229458AbiIRVgK (ORCPT ); Sun, 18 Sep 2022 17:36:10 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E431813FA8 for ; Sun, 18 Sep 2022 14:36:09 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id A043BB80C69 for ; Sun, 18 Sep 2022 21:36:08 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 9F587C433D6; Sun, 18 Sep 2022 21:36:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536967; bh=VE09phF7jVlYnv0dRexTiSFp+nZ5ke1ppI0z3Bh2ARU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uTWytO5PFPGA/zIqeNzlScFFMDDYgHMobrEJ4vJSM4v00Ipry+oCAD7OQTwX52TRx LQhx8aRupU19wju3HpXb6Xrri26HJM0uvf07PD0UX0fhIrYgtzVjR9ZnPS+A4/qo5Z sfZ0nAAvvr2s3Lw7HsJEcUbh/f41qSfWdqKPFjDwbg5+5o2Bi/4ql5oKmYxS0lfUMf eT/EB02h5byuZJnD0cnkTOwZZNXrIxr38o5EG728vyQh9OqxNSmaciYuBeU3a4BUh1 WS6hZn5Hmb8Ib9puPT3fv82LqJr5giarUrRghdD6H3ubGWjwfNfaPswKH/Kb5pWElP b3RtCQ5ZzLl5A== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao Subject: [PATCH 04/12] efi: libstub: fix type confusion for load_options_size Date: Sun, 18 Sep 2022 23:35:36 +0200 Message-Id: <20220918213544.2176249-5-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3306; i=ardb@kernel.org; h=from:subject; bh=VE09phF7jVlYnv0dRexTiSFp+nZ5ke1ppI0z3Bh2ARU=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48gvkz/HXZ76M7IpoKgmMeLspsTIBBbBmtljpCk Lu1HS6eJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePIAAKCRDDTyI5ktmPJISHC/ 9p+nKyqm6VEAGDJ48fcOUQegUEp/988wdpN7oDoCmCI2+1kN8ix4vMQXFSA3xMdYJMCfXvqYEHqeBa zNbd1xHCrYqrXzl+jfepS1z9Y1BL+2o0mhNqwUTpZihkulk05G+Y0jHjYoFai4Tk9uMN9OL0HWCuVD B7efOOT5fuLacbsxNOcmMqfzaL+JoJR1UvTWSu8msqau13eZPKRZDJ7ADNiSn4W2uWyzyHLR9oDeC2 TpFu6eFxy10C2/XjYvE/kZEXRZL9BLWYxRBFGA5aKNZH4bQ+YpigC4RivK2MlkKF4492Y46mamAibH 9DTQdZxb0njWNmr9/aqGvod7lU4PiF5DkwrsIW0caQcvlb6YdkArCPFrRLdaK3pYILzU6NaHLegf2S GBb6STv4zBGSvtBvEaMDxbbs4n1EHvpnzEmK9Bq2MODn3QPXRCvdoHw+A90ZclIZS+yfXIr7iqEMOp c65mTc8krmSmiXWQpFOrYdF9060FlJUhsCdGdgWfnVhu0= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Even though it is unlikely to ever make a difference, let's use u32 consistently for the size of the load_options provided by the firmware (aka the command line) While at it, do some general cleanup too: use efi_char16_t, avoid using options_chars in places where it really means options_size, etc. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/efi-stub-helper.c | 17 +++++++++-------- drivers/firmware/efi/libstub/efistub.h | 4 ++-- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index fb27f4cc6ce0..08b551b7eb32 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -310,7 +310,7 @@ bool efi_load_option_unpack(efi_load_option_unpacked_t *dest, * * Detect this case and extract OptionalData. */ -void efi_apply_loadoptions_quirk(const void **load_options, int *load_options_size) +void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_size) { const efi_load_option_t *load_option = *load_options; efi_load_option_unpacked_t load_option_unpacked; @@ -341,21 +341,22 @@ void efi_apply_loadoptions_quirk(const void **load_options, int *load_options_si */ char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len) { - const u16 *s2; - unsigned long cmdline_addr = 0; - int options_chars = efi_table_attr(image, load_options_size); - const u16 *options = efi_table_attr(image, load_options); + const efi_char16_t *options = efi_table_attr(image, load_options); + u32 options_size = efi_table_attr(image, load_options_size); int options_bytes = 0, safe_options_bytes = 0; /* UTF-8 bytes */ + unsigned long cmdline_addr = 0; + const efi_char16_t *s2; bool in_quote = false; efi_status_t status; + u32 options_chars; - efi_apply_loadoptions_quirk((const void **)&options, &options_chars); - options_chars /= sizeof(*options); + efi_apply_loadoptions_quirk((const void **)&options, &options_size); + options_chars = options_size / sizeof(efi_char16_t); if (options) { s2 = options; while (options_bytes < COMMAND_LINE_SIZE && options_chars--) { - u16 c = *s2++; + efi_char16_t c = *s2++; if (c < 0x80) { if (c == L'\0' || c == L'\n') diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 54f37e886be7..02fb5f7c8eff 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -861,7 +861,7 @@ typedef struct { u16 file_path_list_length; const efi_char16_t *description; const efi_device_path_protocol_t *file_path_list; - size_t optional_data_size; + u32 optional_data_size; const void *optional_data; } efi_load_option_unpacked_t; @@ -906,7 +906,7 @@ __printf(1, 2) int efi_printk(char const *fmt, ...); void efi_free(unsigned long size, unsigned long addr); -void efi_apply_loadoptions_quirk(const void **load_options, int *load_options_size); +void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_size); char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len); From patchwork Sun Sep 18 21:35:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607492 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D4473C6FA82 for ; Sun, 18 Sep 2022 21:36:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229458AbiIRVgO (ORCPT ); Sun, 18 Sep 2022 17:36:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229581AbiIRVgN (ORCPT ); Sun, 18 Sep 2022 17:36:13 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 481F813FAB for ; Sun, 18 Sep 2022 14:36:12 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id DABF4B812A8 for ; Sun, 18 Sep 2022 21:36:10 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CA597C43470; Sun, 18 Sep 2022 21:36:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536969; bh=pFFKtVvyGui788KkPIr8qCSZNOG59os7CxAM3GPqbwk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=P4PnawotcUkGyB9QJD7jlK0op0/HjDykGILMFdaAKFvNB1YVLzUNbpXdLh+z9p8Si mvvil3ib1z+aCg3hRJOvWXmaBMY6ObiXuPQuz2yxAOLAtOB+Py1IYOWjnUPMjtT9vl LDPnUh1Toh+W8OXg6u0ABOOr4BI5zK03Pg+kd6AAQN2UR5KBIrX/ciP2XBDh7HWPkn 21btCosjZNCvCfN75cZg2P5mhfevFCM7hkEqfYvntV7L2KppgOO8TDQ77Mpok3DB4u NUP3+1OOBaOH+Jexr7q2ZafDknUh4+VLuCNMmsDO/gItD4Urj1cMRvIIRAzUjmMh9N de0qY1LG9BrtQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao Subject: [PATCH 05/12] efi: libstub: avoid efi_get_memory_map() for allocating the virt map Date: Sun, 18 Sep 2022 23:35:37 +0200 Message-Id: <20220918213544.2176249-6-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6231; i=ardb@kernel.org; h=from:subject; bh=pFFKtVvyGui788KkPIr8qCSZNOG59os7CxAM3GPqbwk=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48ik3xeBegCYYbjhN1J/gEU0eF7jTfVCyGH6+ZJ ooX+UxaJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePIgAKCRDDTyI5ktmPJDSZC/ 9Zxb9vu5oQJ1rP8p3RhN3pWA2ge5cJEwFZEXxIFitUOEvGeOPpZcvY7wZUMsYItq+SqoRR1uy2h73x kUtARR3Me7jwELSlxV9jDKvRBsqq+F2pR+XOAFNvGmtJktCJP8pabIEYPcR7CTgFi7hTK1wnVEttML y7UWDvfF66AAdW2WfijDfBGGVf1c3TACzBQry7BQr9xgvL4xUCyXE79zNa0rduKgUbJD6oPLtedCim 39x0/tBll1OLbXbWnc15+kGehGij+nkJSicJxyLowuf91BhBzWYyN0M6fMi0j0yiHf+OZYT1xpwWh1 UXcKyL+3StieFd7Sbzp2IYiE78W4Y2tRpg88olY4/DxuECuhYP74GYlF7ceZWG0oWeg3KnoyWiEiGI g7IrqTxpCYD8qcNovCKty7kLsJGJPYiw/Eis35lTWDLv6ka8nHu7bm7bXh2nVxZpMI2eCGjUY9UV3L 7jAK6ZWT6q3qKbT/3y0ERkaK4rdOjXvxaXloHPp6pwnQE= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org The virt map is a set of efi_memory_desc_t descriptors that are passed to SetVirtualAddressMap() to inform the firmware about the desired virtual mapping of the regions marked as EFI_MEMORY_RUNTIME. The only reason we currently call the efi_get_memory_map() helper is that it gives us an allocation that is guaranteed to be of sufficient size. However, efi_get_memory_map() has grown some additional complexity over the years, and today, we're actually better off calling the EFI boot service directly with a zero size, which tells us how much memory should be enough for the virt map. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/efi-stub.c | 31 ++++++++++++++++++++ drivers/firmware/efi/libstub/efistub.h | 2 ++ drivers/firmware/efi/libstub/fdt.c | 27 +++++------------ 3 files changed, 41 insertions(+), 19 deletions(-) diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index 97eaa487fdfd..6d9ce2c89576 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -319,6 +319,35 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, return status; } +/* + * efi_allocate_virtmap() - create a pool allocation for the virtmap + * + * Create an allocation that is of sufficient size to hold all the memory + * descriptors that will be passed to SetVirtualAddressMap() to inform the + * firmware about the virtual mapping that will be used under the OS to call + * into the firmware. + */ +efi_status_t efi_alloc_virtmap(efi_memory_desc_t **virtmap, + unsigned long *desc_size, u32 *desc_ver) +{ + unsigned long size, mmap_key; + efi_status_t status; + + /* + * Use the size of the current memory map as an upper bound for the + * size of the buffer we need to pass to SetVirtualAddressMap() to + * cover all EFI_MEMORY_RUNTIME regions. + */ + size = 0; + status = efi_bs_call(get_memory_map, &size, NULL, &mmap_key, desc_size, + desc_ver); + if (status != EFI_BUFFER_TOO_SMALL) + return EFI_LOAD_ERROR; + + return efi_bs_call(allocate_pool, EFI_LOADER_DATA, size, + (void **)virtmap); +} + /* * efi_get_virtmap() - create a virtual mapping for the EFI memory map * @@ -334,6 +363,8 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, efi_memory_desc_t *in, *out = runtime_map; int l; + *count = 0; + for (l = 0; l < map_size; l += desc_size) { u64 paddr, size; diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 02fb5f7c8eff..20705712deff 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -885,6 +885,8 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, void *get_fdt(unsigned long *fdt_size); +efi_status_t efi_alloc_virtmap(efi_memory_desc_t **virtmap, + unsigned long *desc_size, u32 *desc_ver); void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, unsigned long desc_size, efi_memory_desc_t *runtime_map, int *count); diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index 804f542be3f2..ab59889c38f1 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -199,7 +199,7 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map) struct exit_boot_struct { efi_memory_desc_t *runtime_map; - int *runtime_entry_count; + int runtime_entry_count; void *new_fdt_addr; }; @@ -213,7 +213,7 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, * entries so that we can pass it straight to SetVirtualAddressMap() */ efi_get_virtmap(*map->map, *map->map_size, *map->desc_size, - p->runtime_map, p->runtime_entry_count); + p->runtime_map, &p->runtime_entry_count); return update_fdt_memmap(p->new_fdt_addr, map); } @@ -246,26 +246,18 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, unsigned long map_size, desc_size, buff_size; u32 desc_ver; unsigned long mmap_key; - efi_memory_desc_t *memory_map, *runtime_map; + efi_memory_desc_t *memory_map; efi_status_t status; - int runtime_entry_count; struct efi_boot_memmap map; struct exit_boot_struct priv; - map.map = &runtime_map; map.map_size = &map_size; map.desc_size = &desc_size; map.desc_ver = &desc_ver; map.key_ptr = &mmap_key; map.buff_size = &buff_size; - /* - * Get a copy of the current memory map that we will use to prepare - * the input for SetVirtualAddressMap(). We don't have to worry about - * subsequent allocations adding entries, since they could not affect - * the number of EFI_MEMORY_RUNTIME regions. - */ - status = efi_get_memory_map(&map); + status = efi_alloc_virtmap(&priv.runtime_map, &desc_size, &desc_ver); if (status != EFI_SUCCESS) { efi_err("Unable to retrieve UEFI memory map.\n"); return status; @@ -289,10 +281,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, goto fail_free_new_fdt; } - runtime_entry_count = 0; - priv.runtime_map = runtime_map; - priv.runtime_entry_count = &runtime_entry_count; - priv.new_fdt_addr = (void *)*new_fdt_addr; + priv.new_fdt_addr = (void *)*new_fdt_addr; status = efi_exit_boot_services(handle, &map, &priv, exit_boot_func); @@ -304,8 +293,8 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, /* Install the new virtual address map */ svam = efi_system_table->runtime->set_virtual_address_map; - status = svam(runtime_entry_count * desc_size, desc_size, - desc_ver, runtime_map); + status = svam(priv.runtime_entry_count * desc_size, desc_size, + desc_ver, priv.runtime_map); /* * We are beyond the point of no return here, so if the call to @@ -337,7 +326,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, efi_free(MAX_FDT_SIZE, *new_fdt_addr); fail: - efi_system_table->boottime->free_pool(runtime_map); + efi_bs_call(free_pool, priv.runtime_map); return EFI_LOAD_ERROR; } From patchwork Sun Sep 18 21:35:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607257 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1ABC3ECAAD8 for ; Sun, 18 Sep 2022 21:36:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229614AbiIRVgR (ORCPT ); Sun, 18 Sep 2022 17:36:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40574 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229581AbiIRVgQ (ORCPT ); Sun, 18 Sep 2022 17:36:16 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A053413FA8 for ; Sun, 18 Sep 2022 14:36:14 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 38684B81333 for ; Sun, 18 Sep 2022 21:36:13 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 028D3C433D6; Sun, 18 Sep 2022 21:36:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536971; bh=Ru0xfD16klS07tddkIVGAaa+CsTfftLp60yJwaNKzok=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UXde3L850xj+N8MgEH72nGy7x9IGsPz8Mno9MQ/hayPJOlnkhIAN6L80aFep8I+7i gOnI7k0TV8t8IgLRFk331EB1Vb4y33jR6w8seXIR8rVkEnw68SzU9l0REvRpAWFi54 VWQvQM7hTWWrxnjzvG18a2fvYCrUnKsq2sYhudtdKYRkZ/c46DxNOKltUbU3hLJ0ai V9q+n97E/kAu1/d0L5RzBo3TTO1aO3XyfkQR+25shZxo+T++HK1vFJkjbTXMQWft0A 0QHtKg8nN6ujpBAVEK3olXd0vGeJPJ4cdh84mMHR6spbZ7/7CUMJEGIZ9/tkRpmKJC Ys35FsBv6UUpw== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao Subject: [PATCH 06/12] efi: libstub: simplify efi_get_memory_map() and struct efi_boot_memmap Date: Sun, 18 Sep 2022 23:35:38 +0200 Message-Id: <20220918213544.2176249-7-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=20417; i=ardb@kernel.org; h=from:subject; bh=Ru0xfD16klS07tddkIVGAaa+CsTfftLp60yJwaNKzok=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48k85QXWFEKklRYXxDnxrVLTgKHe7S4Vdrlh5mJ HEne0qKJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePJAAKCRDDTyI5ktmPJIymC/ 9wKkKZ6Lh/CLaiMy5IQfxcYT4ODsTZF9hpNdtK6QiBVxBaImhqXbPOZ8m7ZhR9C0AjXlBzIpk/9i4e Xkcd53IoNx/RRsCvYHPjh/bbOIF0rPAckKina2WIsff9L5VTaDyNakH8JUFXAev3luqqS3w/Sbcymf DWeDzLQ4DY1CAUtjjaylkUI5Ux6bhS8abf1g9rATcjDed1s80FGAmKiOQtmd2TgZJwryB2nK+HGjpg l5BpzG7zm7FodxY6zt+86AKBWPQUSyNnOKGa5FTO+QW3vkEeyys0dmGz4uojUC0nQfnQkIBSDnQ9IQ mn9uO/UAzH/A1tszbY38EDcx3r3SvLgUfNTXUC0jnZyZf4BsuYXq85VWAF9JClsuqAqZZQEQhVyve1 jI6AChIQIfHZKi0uYvVxpcSVkUA6EWnV47THGZXcyapF9W0Z2spcMEXZnn6Qs7kkgEHMuMDSlDpoTs +FfNxlhWCkHsSX4LbpYALqBczDzKTIKHi666yENIDMl4s= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Currently, struct efi_boot_memmap is a struct that is passed around between callers of efi_get_memory_map() and the users of the resulting data, and which carries pointers to various variables whose values are provided by the EFI GetMemoryMap() boot service. This is overly complex, and it is much easier to carry these values in the struct itself. So turn the struct into one that carries these data items directly, including a flex array for the variable number of EFI memory descriptors that the boot service may return. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/arm64-stub.c | 17 ++--- drivers/firmware/efi/libstub/efi-stub-helper.c | 26 ++++---- drivers/firmware/efi/libstub/efistub.h | 15 +---- drivers/firmware/efi/libstub/fdt.c | 37 +++++------ drivers/firmware/efi/libstub/mem.c | 65 ++++++-------------- drivers/firmware/efi/libstub/randomalloc.c | 23 +++---- drivers/firmware/efi/libstub/relocate.c | 21 ++----- drivers/firmware/efi/libstub/x86-stub.c | 20 ++---- include/linux/efi.h | 9 +++ 9 files changed, 80 insertions(+), 153 deletions(-) diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c index 71289b9d5309..e9d516ad5f97 100644 --- a/drivers/firmware/efi/libstub/arm64-stub.c +++ b/drivers/firmware/efi/libstub/arm64-stub.c @@ -50,26 +50,17 @@ efi_status_t check_platform_features(void) */ static bool check_image_region(u64 base, u64 size) { - unsigned long map_size, desc_size, buff_size; - efi_memory_desc_t *memory_map; - struct efi_boot_memmap map; + struct efi_boot_memmap *map; efi_status_t status; bool ret = false; int map_offset; - map.map = &memory_map; - map.map_size = &map_size; - map.desc_size = &desc_size; - map.desc_ver = NULL; - map.key_ptr = NULL; - map.buff_size = &buff_size; - status = efi_get_memory_map(&map); if (status != EFI_SUCCESS) return false; - for (map_offset = 0; map_offset < map_size; map_offset += desc_size) { - efi_memory_desc_t *md = (void *)memory_map + map_offset; + for (map_offset = 0; map_offset < map->map_size; map_offset += map->desc_size) { + efi_memory_desc_t *md = (void *)map->map + map_offset; u64 end = md->phys_addr + md->num_pages * EFI_PAGE_SIZE; /* @@ -82,7 +73,7 @@ static bool check_image_region(u64 base, u64 size) } } - efi_bs_call(free_pool, memory_map); + efi_bs_call(free_pool, map); return ret; } diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 08b551b7eb32..e8af32377d75 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -420,7 +420,6 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len) /** * efi_exit_boot_services() - Exit boot services * @handle: handle of the exiting image - * @map: pointer to receive the memory map * @priv: argument to be passed to @priv_func * @priv_func: function to process the memory map before exiting boot services * @@ -433,14 +432,13 @@ char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len) * * Return: status code */ -efi_status_t efi_exit_boot_services(void *handle, - struct efi_boot_memmap *map, - void *priv, +efi_status_t efi_exit_boot_services(void *handle, void *priv, efi_exit_boot_map_processing priv_func) { + struct efi_boot_memmap *map; efi_status_t status; - status = efi_get_memory_map(map); + status = efi_get_memory_map(&map); if (status != EFI_SUCCESS) goto fail; @@ -452,7 +450,7 @@ efi_status_t efi_exit_boot_services(void *handle, if (efi_disable_pci_dma) efi_pci_disable_bridge_busmaster(); - status = efi_bs_call(exit_boot_services, handle, *map->key_ptr); + status = efi_bs_call(exit_boot_services, handle, map->map_key); if (status == EFI_INVALID_PARAMETER) { /* @@ -468,13 +466,13 @@ efi_status_t efi_exit_boot_services(void *handle, * buffer should account for any changes in the map so the call * to get_memory_map() is expected to succeed here. */ - *map->map_size = *map->buff_size; + map->map_size = map->buff_size; status = efi_bs_call(get_memory_map, - map->map_size, - *map->map, - map->key_ptr, - map->desc_size, - map->desc_ver); + &map->map_size, + &map->map, + &map->map_key, + &map->desc_size, + &map->desc_ver); /* exit_boot_services() was called, thus cannot free */ if (status != EFI_SUCCESS) @@ -485,7 +483,7 @@ efi_status_t efi_exit_boot_services(void *handle, if (status != EFI_SUCCESS) goto fail; - status = efi_bs_call(exit_boot_services, handle, *map->key_ptr); + status = efi_bs_call(exit_boot_services, handle, map->map_key); } /* exit_boot_services() was called, thus cannot free */ @@ -495,7 +493,7 @@ efi_status_t efi_exit_boot_services(void *handle, return EFI_SUCCESS; free_map: - efi_bs_call(free_pool, *map->map); + efi_bs_call(free_pool, map); fail: return status; } diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 20705712deff..2bd520b30192 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -160,15 +160,6 @@ void efi_set_u64_split(u64 data, u32 *lo, u32 *hi) */ #define EFI_MMAP_NR_SLACK_SLOTS 8 -struct efi_boot_memmap { - efi_memory_desc_t **map; - unsigned long *map_size; - unsigned long *desc_size; - u32 *desc_ver; - unsigned long *key_ptr; - unsigned long *buff_size; -}; - typedef struct efi_generic_dev_path efi_device_path_protocol_t; union efi_device_path_to_text_protocol { @@ -871,9 +862,7 @@ typedef efi_status_t (*efi_exit_boot_map_processing)( struct efi_boot_memmap *map, void *priv); -efi_status_t efi_exit_boot_services(void *handle, - struct efi_boot_memmap *map, - void *priv, +efi_status_t efi_exit_boot_services(void *handle, void *priv, efi_exit_boot_map_processing priv_func); efi_status_t allocate_new_fdt_and_exit_boot(void *handle, @@ -912,7 +901,7 @@ void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_si char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len); -efi_status_t efi_get_memory_map(struct efi_boot_memmap *map); +efi_status_t efi_get_memory_map(struct efi_boot_memmap **map); efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr, unsigned long max); diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index ab59889c38f1..91ca0c1597e5 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -170,25 +170,25 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map) if (node < 0) return EFI_LOAD_ERROR; - fdt_val64 = cpu_to_fdt64((unsigned long)*map->map); + fdt_val64 = cpu_to_fdt64((unsigned long)map->map); err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-start", fdt_val64); if (err) return EFI_LOAD_ERROR; - fdt_val32 = cpu_to_fdt32(*map->map_size); + fdt_val32 = cpu_to_fdt32(map->map_size); err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-size", fdt_val32); if (err) return EFI_LOAD_ERROR; - fdt_val32 = cpu_to_fdt32(*map->desc_size); + fdt_val32 = cpu_to_fdt32(map->desc_size); err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-size", fdt_val32); if (err) return EFI_LOAD_ERROR; - fdt_val32 = cpu_to_fdt32(*map->desc_ver); + fdt_val32 = cpu_to_fdt32(map->desc_ver); err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32); if (err) @@ -198,21 +198,24 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map) } struct exit_boot_struct { + struct efi_boot_memmap *boot_memmap; efi_memory_desc_t *runtime_map; int runtime_entry_count; void *new_fdt_addr; }; -static efi_status_t exit_boot_func(struct efi_boot_memmap *map, - void *priv) +static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv) { struct exit_boot_struct *p = priv; + + p->boot_memmap = map; + /* * Update the memory map with virtual addresses. The function will also * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME * entries so that we can pass it straight to SetVirtualAddressMap() */ - efi_get_virtmap(*map->map, *map->map_size, *map->desc_size, + efi_get_virtmap(map->map, map->map_size, map->desc_size, p->runtime_map, &p->runtime_entry_count); return update_fdt_memmap(p->new_fdt_addr, map); @@ -243,20 +246,11 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, unsigned long fdt_addr, unsigned long fdt_size) { - unsigned long map_size, desc_size, buff_size; + unsigned long desc_size; u32 desc_ver; - unsigned long mmap_key; - efi_memory_desc_t *memory_map; efi_status_t status; - struct efi_boot_memmap map; struct exit_boot_struct priv; - map.map_size = &map_size; - map.desc_size = &desc_size; - map.desc_ver = &desc_ver; - map.key_ptr = &mmap_key; - map.buff_size = &buff_size; - status = efi_alloc_virtmap(&priv.runtime_map, &desc_size, &desc_ver); if (status != EFI_SUCCESS) { efi_err("Unable to retrieve UEFI memory map.\n"); @@ -265,7 +259,6 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, efi_info("Exiting boot services...\n"); - map.map = &memory_map; status = efi_allocate_pages(MAX_FDT_SIZE, new_fdt_addr, ULONG_MAX); if (status != EFI_SUCCESS) { efi_err("Unable to allocate memory for new device tree.\n"); @@ -283,7 +276,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, priv.new_fdt_addr = (void *)*new_fdt_addr; - status = efi_exit_boot_services(handle, &map, &priv, exit_boot_func); + status = efi_exit_boot_services(handle, &priv, exit_boot_func); if (status == EFI_SUCCESS) { efi_set_virtual_address_map_t *svam; @@ -302,6 +295,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, * incoming kernel but proceed normally otherwise. */ if (status != EFI_SUCCESS) { + efi_memory_desc_t *p; int l; /* @@ -310,8 +304,9 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, * the incoming kernel that no virtual translation has * been installed. */ - for (l = 0; l < map_size; l += desc_size) { - efi_memory_desc_t *p = (void *)memory_map + l; + for (l = 0; l < priv.boot_memmap->map_size; + l += priv.boot_memmap->desc_size) { + p = (void *)priv.boot_memmap->map + l; if (p->attribute & EFI_MEMORY_RUNTIME) p->virt_addr = 0; diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c index feef8d4be113..40721573e494 100644 --- a/drivers/firmware/efi/libstub/mem.c +++ b/drivers/firmware/efi/libstub/mem.c @@ -5,71 +5,44 @@ #include "efistub.h" -static inline bool mmap_has_headroom(unsigned long buff_size, - unsigned long map_size, - unsigned long desc_size) -{ - unsigned long slack = buff_size - map_size; - - return slack / desc_size >= EFI_MMAP_NR_SLACK_SLOTS; -} - /** * efi_get_memory_map() - get memory map - * @map: on return pointer to memory map + * @map: pointer to memory map pointer to which to assign the + * newly allocated memory map * * Retrieve the UEFI memory map. The allocated memory leaves room for * up to EFI_MMAP_NR_SLACK_SLOTS additional memory map entries. * * Return: status code */ -efi_status_t efi_get_memory_map(struct efi_boot_memmap *map) +efi_status_t efi_get_memory_map(struct efi_boot_memmap **map) { - efi_memory_desc_t *m = NULL; + struct efi_boot_memmap *m, tmp; efi_status_t status; - unsigned long key; - u32 desc_version; + unsigned long size; - *map->desc_size = sizeof(*m); - *map->map_size = *map->desc_size * 32; - *map->buff_size = *map->map_size; -again: - status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, - *map->map_size, (void **)&m); + tmp.map_size = 0; + status = efi_bs_call(get_memory_map, &tmp.map_size, NULL, &tmp.map_key, + &tmp.desc_size, &tmp.desc_ver); + if (status != EFI_BUFFER_TOO_SMALL) + return EFI_LOAD_ERROR; + + size = tmp.map_size + tmp.desc_size * EFI_MMAP_NR_SLACK_SLOTS; + status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(*m) + size, + (void **)&m); if (status != EFI_SUCCESS) - goto fail; + return status; - *map->desc_size = 0; - key = 0; - status = efi_bs_call(get_memory_map, map->map_size, m, - &key, map->desc_size, &desc_version); - if (status == EFI_BUFFER_TOO_SMALL || - !mmap_has_headroom(*map->buff_size, *map->map_size, - *map->desc_size)) { - efi_bs_call(free_pool, m); - /* - * Make sure there is some entries of headroom so that the - * buffer can be reused for a new map after allocations are - * no longer permitted. Its unlikely that the map will grow to - * exceed this headroom once we are ready to trigger - * ExitBootServices() - */ - *map->map_size += *map->desc_size * EFI_MMAP_NR_SLACK_SLOTS; - *map->buff_size = *map->map_size; - goto again; - } + m->buff_size = m->map_size = size; + status = efi_bs_call(get_memory_map, &m->map_size, m->map, &m->map_key, + &m->desc_size, &m->desc_ver); if (status == EFI_SUCCESS) { - if (map->key_ptr) - *map->key_ptr = key; - if (map->desc_ver) - *map->desc_ver = desc_version; + *map = m; } else { efi_bs_call(free_pool, m); } -fail: - *map->map = m; return status; } diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c index 715f37479154..5d6000c717cc 100644 --- a/drivers/firmware/efi/libstub/randomalloc.c +++ b/drivers/firmware/efi/libstub/randomalloc.c @@ -55,20 +55,11 @@ efi_status_t efi_random_alloc(unsigned long size, unsigned long *addr, unsigned long random_seed) { - unsigned long map_size, desc_size, total_slots = 0, target_slot; + unsigned long total_slots = 0, target_slot; unsigned long total_mirrored_slots = 0; - unsigned long buff_size; + struct efi_boot_memmap *map; efi_status_t status; - efi_memory_desc_t *memory_map; int map_offset; - struct efi_boot_memmap map; - - map.map = &memory_map; - map.map_size = &map_size; - map.desc_size = &desc_size; - map.desc_ver = NULL; - map.key_ptr = NULL; - map.buff_size = &buff_size; status = efi_get_memory_map(&map); if (status != EFI_SUCCESS) @@ -80,8 +71,8 @@ efi_status_t efi_random_alloc(unsigned long size, size = round_up(size, EFI_ALLOC_ALIGN); /* count the suitable slots in each memory map entry */ - for (map_offset = 0; map_offset < map_size; map_offset += desc_size) { - efi_memory_desc_t *md = (void *)memory_map + map_offset; + for (map_offset = 0; map_offset < map->map_size; map_offset += map->desc_size) { + efi_memory_desc_t *md = (void *)map->map + map_offset; unsigned long slots; slots = get_entry_num_slots(md, size, ilog2(align)); @@ -109,8 +100,8 @@ efi_status_t efi_random_alloc(unsigned long size, * to calculate the randomly chosen address, and allocate it directly * using EFI_ALLOCATE_ADDRESS. */ - for (map_offset = 0; map_offset < map_size; map_offset += desc_size) { - efi_memory_desc_t *md = (void *)memory_map + map_offset; + for (map_offset = 0; map_offset < map->map_size; map_offset += map->desc_size) { + efi_memory_desc_t *md = (void *)map->map + map_offset; efi_physical_addr_t target; unsigned long pages; @@ -133,7 +124,7 @@ efi_status_t efi_random_alloc(unsigned long size, break; } - efi_bs_call(free_pool, memory_map); + efi_bs_call(free_pool, map); return status; } diff --git a/drivers/firmware/efi/libstub/relocate.c b/drivers/firmware/efi/libstub/relocate.c index 8ee9eb2b9039..cd80db33ab1e 100644 --- a/drivers/firmware/efi/libstub/relocate.c +++ b/drivers/firmware/efi/libstub/relocate.c @@ -23,21 +23,12 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align, unsigned long *addr, unsigned long min) { - unsigned long map_size, desc_size, buff_size; - efi_memory_desc_t *map; + struct efi_boot_memmap *map; efi_status_t status; unsigned long nr_pages; int i; - struct efi_boot_memmap boot_map; - boot_map.map = ↦ - boot_map.map_size = &map_size; - boot_map.desc_size = &desc_size; - boot_map.desc_ver = NULL; - boot_map.key_ptr = NULL; - boot_map.buff_size = &buff_size; - - status = efi_get_memory_map(&boot_map); + status = efi_get_memory_map(&map); if (status != EFI_SUCCESS) goto fail; @@ -52,12 +43,12 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align, size = round_up(size, EFI_ALLOC_ALIGN); nr_pages = size / EFI_PAGE_SIZE; - for (i = 0; i < map_size / desc_size; i++) { + for (i = 0; i < map->map_size / map->desc_size; i++) { efi_memory_desc_t *desc; - unsigned long m = (unsigned long)map; + unsigned long m = (unsigned long)map->map; u64 start, end; - desc = efi_early_memdesc_ptr(m, desc_size, i); + desc = efi_early_memdesc_ptr(m, map->desc_size, i); if (desc->type != EFI_CONVENTIONAL_MEMORY) continue; @@ -87,7 +78,7 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align, } } - if (i == map_size / desc_size) + if (i == map->map_size / map->desc_size) status = EFI_NOT_FOUND; efi_bs_call(free_pool, map); diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c index 05ae8bcc9d67..1ae1e7e576b9 100644 --- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -716,32 +716,22 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, efi_set_u64_split((unsigned long)efi_system_table, &p->efi->efi_systab, &p->efi->efi_systab_hi); - p->efi->efi_memdesc_size = *map->desc_size; - p->efi->efi_memdesc_version = *map->desc_ver; - efi_set_u64_split((unsigned long)*map->map, + p->efi->efi_memdesc_size = map->desc_size; + p->efi->efi_memdesc_version = map->desc_ver; + efi_set_u64_split((unsigned long)map->map, &p->efi->efi_memmap, &p->efi->efi_memmap_hi); - p->efi->efi_memmap_size = *map->map_size; + p->efi->efi_memmap_size = map->map_size; return EFI_SUCCESS; } static efi_status_t exit_boot(struct boot_params *boot_params, void *handle) { - unsigned long map_sz, key, desc_size, buff_size; - efi_memory_desc_t *mem_map; struct setup_data *e820ext = NULL; __u32 e820ext_size = 0; efi_status_t status; - __u32 desc_version; - struct efi_boot_memmap map; struct exit_boot_struct priv; - map.map = &mem_map; - map.map_size = &map_sz; - map.desc_size = &desc_size; - map.desc_ver = &desc_version; - map.key_ptr = &key; - map.buff_size = &buff_size; priv.boot_params = boot_params; priv.efi = &boot_params->efi_info; @@ -750,7 +740,7 @@ static efi_status_t exit_boot(struct boot_params *boot_params, void *handle) return status; /* Might as well exit boot services now */ - status = efi_exit_boot_services(handle, &map, &priv, exit_boot_func); + status = efi_exit_boot_services(handle, &priv, exit_boot_func); if (status != EFI_SUCCESS) return status; diff --git a/include/linux/efi.h b/include/linux/efi.h index 5efc3105f8e0..6ad8eda0de7d 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -522,6 +522,15 @@ typedef union { efi_system_table_32_t mixed_mode; } efi_system_table_t; +struct efi_boot_memmap { + unsigned long map_size; + unsigned long desc_size; + u32 desc_ver; + unsigned long map_key; + unsigned long buff_size; + efi_memory_desc_t map[]; +}; + /* * Architecture independent structure for describing a memory map for the * benefit of efi_memmap_init_early(), and for passing context between From patchwork Sun Sep 18 21:35:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607491 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 030E2C6FA82 for ; Sun, 18 Sep 2022 21:36:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229568AbiIRVgS (ORCPT ); Sun, 18 Sep 2022 17:36:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40582 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229609AbiIRVgR (ORCPT ); Sun, 18 Sep 2022 17:36:17 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 267BC13FB7 for ; Sun, 18 Sep 2022 14:36:15 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id A8CF1612A3 for ; Sun, 18 Sep 2022 21:36:14 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5A846C433B5; Sun, 18 Sep 2022 21:36:12 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536974; bh=4IQCCp85/a9TbrSEYrwJOPa+sZS2yTCwU9hWVkII4gw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=qqUgldACNBxS9W3H2oFaX5Gi6GbJUfFF/uYQGexaTEJVH4iQFkeweYRS0zdlZSdQ5 /6bM6kDTiTRasmis1WjiXfAf/5TkEkrsCF7Wl5/XTm4DiLylElBDTzAWZiBYXXXtT/ KR8MfnvEJq161LmzRkYkgQZOZwWNw+WgEaU6ehNlMGo7oeTV/JHDJ7E2vE/di9PWpI NIZEPEF4OlI9N55sz+UZ7yYBmoI3FiMWgzHb3xta9g8yeZawVc0opuFui5j92j0XKx 2Gifu3zmcgkyU/0+YkTIiiGewbGEIEyqe7EnSWV7YHIVfiimk8Gj49PAsAJz+dPVqC MGVO/5ni9JHAQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao Subject: [PATCH 07/12] efi: libstub: unify initrd loading between architectures Date: Sun, 18 Sep 2022 23:35:39 +0200 Message-Id: <20220918213544.2176249-8-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=16521; i=ardb@kernel.org; h=from:subject; bh=4IQCCp85/a9TbrSEYrwJOPa+sZS2yTCwU9hWVkII4gw=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48mmt4RTTOmDpsKtlySDVyqEe18HipGQwZayROG Qw4eu2GJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePJgAKCRDDTyI5ktmPJJWfC/ 4qMUPjfJpdpwYup2oxOH/XJIX9FLAjcLoRj210zSio7s+tWQrsjQSZQnKZ6k/LuZ6aIMMSfvFZgeVQ yidsFFrwQ9TjHnUYiQoUQmIJ3JVzIxrxMXENhdqTgBGpDYF2B9NTjjlkyCcmlwjaq7tdr3GwkHKNqp Fc4ul31aZuzNEX95C7oVCzS6GUF8MREWY0uuaveufoprxbi6uEGJeXDG8OS1yYykf83/csclBtOEm2 sPdwvXlot7hjr4TeUliHzhN7970TQMlzagWWjguTlrsTWqaF5zeHBSmWjw+ElsfpU9KTwhL4/h1jrB /xPNW4Ae50JWNzPouWPKCRSUZIsgsGWOebxdbjDRI1u69/mL5fgpBzDbIuZF1/i9IDaie388lBoYzY qfuhrYLzDvPzkmQNDau2g4UT4fRT8xOPRMaL1zDsM7fsJXmKvg9KZTTT23cgFNUmQ01vJtrpuZbRYP PRaOLMKBiOJcrTFro3Z9+iGHoeBJj/Zkn/XQOO6sF10x0= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Use a EFI configuration table to pass the initrd to the core kernel, instead of per-arch methods. This cleans up the code considerably, and should make it easier for architectures to get rid of their reliance on DT for doing EFI boot in the future. Signed-off-by: Ard Biesheuvel --- Documentation/arm/uefi.rst | 4 -- drivers/firmware/efi/efi.c | 15 +++++ drivers/firmware/efi/libstub/efi-stub-helper.c | 64 ++++++++++---------- drivers/firmware/efi/libstub/efi-stub.c | 14 ++--- drivers/firmware/efi/libstub/efistub.h | 3 - drivers/firmware/efi/libstub/fdt.c | 41 +++---------- drivers/firmware/efi/libstub/x86-stub.c | 10 +-- include/linux/efi.h | 5 ++ 8 files changed, 67 insertions(+), 89 deletions(-) diff --git a/Documentation/arm/uefi.rst b/Documentation/arm/uefi.rst index 9b0b5e458a1e..baebe688a006 100644 --- a/Documentation/arm/uefi.rst +++ b/Documentation/arm/uefi.rst @@ -65,10 +65,6 @@ linux,uefi-mmap-desc-size 32-bit Size in bytes of each entry in the UEFI linux,uefi-mmap-desc-ver 32-bit Version of the mmap descriptor format. -linux,initrd-start 64-bit Physical start address of an initrd - -linux,initrd-end 64-bit Physical end address of an initrd - kaslr-seed 64-bit Entropy used to randomize the kernel image base address location. ========================== ====== =========================================== diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index e4080ad96089..f0c776916b9c 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ EXPORT_SYMBOL(efi); unsigned long __ro_after_init efi_rng_seed = EFI_INVALID_TABLE_ADDR; static unsigned long __initdata mem_reserve = EFI_INVALID_TABLE_ADDR; static unsigned long __initdata rt_prop = EFI_INVALID_TABLE_ADDR; +static unsigned long __initdata initrd = EFI_INVALID_TABLE_ADDR; struct mm_struct efi_mm = { .mm_rb = RB_ROOT, @@ -532,6 +534,7 @@ static const efi_config_table_type_t common_tables[] __initconst = { {LINUX_EFI_TPM_EVENT_LOG_GUID, &efi.tpm_log, "TPMEventLog" }, {LINUX_EFI_TPM_FINAL_LOG_GUID, &efi.tpm_final_log, "TPMFinalLog" }, {LINUX_EFI_MEMRESERVE_TABLE_GUID, &mem_reserve, "MEMRESERVE" }, + {LINUX_EFI_INITRD_MEDIA_GUID, &initrd, "INITRD" }, {EFI_RT_PROPERTIES_TABLE_GUID, &rt_prop, "RTPROP" }, #ifdef CONFIG_EFI_RCI2_TABLE {DELLEMC_EFI_RCI2_TABLE_GUID, &rci2_table_phys }, @@ -674,6 +677,18 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables, } } + if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && + initrd != EFI_INVALID_TABLE_ADDR) { + struct linux_efi_initrd *tbl; + + tbl = early_memremap(initrd, sizeof(*tbl)); + if (tbl) { + phys_initrd_start = tbl->base; + phys_initrd_size = tbl->size; + early_memunmap(tbl, sizeof(*tbl)); + } + } + return 0; } diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index e8af32377d75..742ecd9e0df3 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -559,20 +559,16 @@ static const struct { * * %EFI_SUCCESS if the initrd was loaded successfully, in which * case @load_addr and @load_size are assigned accordingly * * %EFI_NOT_FOUND if no LoadFile2 protocol exists on the initrd device path - * * %EFI_INVALID_PARAMETER if load_addr == NULL or load_size == NULL * * %EFI_OUT_OF_RESOURCES if memory allocation failed * * %EFI_LOAD_ERROR in all other cases */ static -efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr, - unsigned long *load_size, +efi_status_t efi_load_initrd_dev_path(struct linux_efi_initrd *initrd, unsigned long max) { efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID; efi_device_path_protocol_t *dp; efi_load_file2_protocol_t *lf2; - unsigned long initrd_addr; - unsigned long initrd_size; efi_handle_t handle; efi_status_t status; @@ -586,42 +582,39 @@ efi_status_t efi_load_initrd_dev_path(unsigned long *load_addr, if (status != EFI_SUCCESS) return status; - status = efi_call_proto(lf2, load_file, dp, false, &initrd_size, NULL); + initrd->size = 0; + status = efi_call_proto(lf2, load_file, dp, false, &initrd->size, NULL); if (status != EFI_BUFFER_TOO_SMALL) return EFI_LOAD_ERROR; - status = efi_allocate_pages(initrd_size, &initrd_addr, max); + status = efi_allocate_pages(initrd->size, &initrd->base, max); if (status != EFI_SUCCESS) return status; - status = efi_call_proto(lf2, load_file, dp, false, &initrd_size, - (void *)initrd_addr); + status = efi_call_proto(lf2, load_file, dp, false, &initrd->size, + (void *)initrd->base); if (status != EFI_SUCCESS) { - efi_free(initrd_size, initrd_addr); + efi_free(initrd->size, initrd->base); return EFI_LOAD_ERROR; } - - *load_addr = initrd_addr; - *load_size = initrd_size; return EFI_SUCCESS; } static efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image, - unsigned long *load_addr, - unsigned long *load_size, + struct linux_efi_initrd *initrd, unsigned long soft_limit, unsigned long hard_limit) { if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER) || (IS_ENABLED(CONFIG_X86) && (!efi_is_native() || image == NULL))) { - *load_addr = *load_size = 0; + initrd->size = 0; return EFI_SUCCESS; } return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2, soft_limit, hard_limit, - load_addr, load_size); + &initrd->base, &initrd->size); } static const struct { @@ -645,7 +638,7 @@ static const struct { { "Linux initrd" }, }; -static void efi_measure_initrd(unsigned long load_addr, unsigned long load_size) +static void efi_measure_initrd(struct linux_efi_initrd *initrd) { efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID; efi_tcg2_protocol_t *tcg2 = NULL; @@ -654,7 +647,7 @@ static void efi_measure_initrd(unsigned long load_addr, unsigned long load_size) efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2); if (tcg2) { status = efi_call_proto(tcg2, hash_log_extend_event, - 0, load_addr, load_size, + 0, initrd->base, initrd->size, &initrd_tcg2_event.event_data); if (status != EFI_SUCCESS) efi_warn("Failed to measure initrd data: 0x%lx\n", @@ -676,34 +669,39 @@ static void efi_measure_initrd(unsigned long load_addr, unsigned long load_size) * Return: status code */ efi_status_t efi_load_initrd(efi_loaded_image_t *image, - unsigned long *load_addr, - unsigned long *load_size, unsigned long soft_limit, unsigned long hard_limit) { - efi_status_t status; + efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID; + efi_status_t status = EFI_SUCCESS; + struct linux_efi_initrd *initrd; + + if (!efi_noinitrd) { + status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, + sizeof(*initrd), (void **)&initrd); + if (status != EFI_SUCCESS) + return status; - if (efi_noinitrd) { - *load_addr = *load_size = 0; - status = EFI_SUCCESS; - } else { - status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit); + status = efi_load_initrd_dev_path(initrd, hard_limit); if (status == EFI_SUCCESS) { efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n"); - if (*load_size > 0) - efi_measure_initrd(*load_addr, *load_size); + if (initrd->size > 0) + efi_measure_initrd(initrd); } else if (status == EFI_NOT_FOUND) { - status = efi_load_initrd_cmdline(image, load_addr, load_size, + status = efi_load_initrd_cmdline(image, initrd, soft_limit, hard_limit); - if (status == EFI_SUCCESS && *load_size > 0) + if (status == EFI_SUCCESS && initrd->size > 0) efi_info("Loaded initrd from command line option\n"); } if (status != EFI_SUCCESS) { efi_err("Failed to load initrd: 0x%lx\n", status); - *load_addr = *load_size = 0; + efi_bs_call(free_pool, initrd); + return status; } - } + status = efi_bs_call(install_configuration_table, &tbl_guid, + initrd); + } return status; } diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index 6d9ce2c89576..88bdd0a6b488 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -130,8 +130,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, unsigned long image_addr; unsigned long image_size = 0; /* addr/point and size pairs for memory management*/ - unsigned long initrd_addr = 0; - unsigned long initrd_size = 0; unsigned long fdt_addr = 0; /* Original DTB */ unsigned long fdt_size = 0; char *cmdline_ptr = NULL; @@ -247,7 +245,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, if (!fdt_addr) efi_info("Generating empty DTB\n"); - efi_load_initrd(image, &initrd_addr, &initrd_size, ULONG_MAX, + efi_load_initrd(image, ULONG_MAX, efi_get_max_initrd_addr(image_addr)); efi_random_get_seed(); @@ -290,11 +288,10 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, install_memreserve_table(); - status = allocate_new_fdt_and_exit_boot(handle, &fdt_addr, - initrd_addr, initrd_size, - cmdline_ptr, fdt_addr, fdt_size); + status = allocate_new_fdt_and_exit_boot(handle, &fdt_addr, cmdline_ptr, + fdt_addr, fdt_size); if (status != EFI_SUCCESS) - goto fail_free_initrd; + goto fail_free_fdt; if (IS_ENABLED(CONFIG_ARM)) efi_handle_post_ebs_state(); @@ -302,10 +299,9 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, efi_enter_kernel(image_addr, fdt_addr, fdt_totalsize((void *)fdt_addr)); /* not reached */ -fail_free_initrd: +fail_free_fdt: efi_err("Failed to update FDT and exit boot services\n"); - efi_free(initrd_size, initrd_addr); efi_free(fdt_size, fdt_addr); fail_free_image: diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 2bd520b30192..82cff342da05 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -867,7 +867,6 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv, efi_status_t allocate_new_fdt_and_exit_boot(void *handle, unsigned long *new_fdt_addr, - u64 initrd_addr, u64 initrd_size, char *cmdline_ptr, unsigned long fdt_addr, unsigned long fdt_size); @@ -944,8 +943,6 @@ static inline efi_status_t efi_load_dtb(efi_loaded_image_t *image, } efi_status_t efi_load_initrd(efi_loaded_image_t *image, - unsigned long *load_addr, - unsigned long *load_size, unsigned long soft_limit, unsigned long hard_limit); /* diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index 91ca0c1597e5..a3cd603ea484 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -28,8 +28,7 @@ static void fdt_update_cell_size(void *fdt) } static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, - void *fdt, int new_fdt_size, char *cmdline_ptr, - u64 initrd_addr, u64 initrd_size) + void *fdt, int new_fdt_size, char *cmdline_ptr) { int node, num_rsv; int status; @@ -93,21 +92,6 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, goto fdt_set_fail; } - /* Set initrd address/end in device tree, if present */ - if (initrd_size != 0) { - u64 initrd_image_end; - u64 initrd_image_start = cpu_to_fdt64(initrd_addr); - - status = fdt_setprop_var(fdt, node, "linux,initrd-start", initrd_image_start); - if (status) - goto fdt_set_fail; - - initrd_image_end = cpu_to_fdt64(initrd_addr + initrd_size); - status = fdt_setprop_var(fdt, node, "linux,initrd-end", initrd_image_end); - if (status) - goto fdt_set_fail; - } - /* Add FDT entries for EFI runtime services in chosen node. */ node = fdt_subnode_offset(fdt, 0, "chosen"); fdt_val64 = cpu_to_fdt64((u64)(unsigned long)efi_system_table); @@ -226,22 +210,18 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv) #endif /* - * Allocate memory for a new FDT, then add EFI, commandline, and - * initrd related fields to the FDT. This routine increases the - * FDT allocation size until the allocated memory is large - * enough. EFI allocations are in EFI_PAGE_SIZE granules, - * which are fixed at 4K bytes, so in most cases the first - * allocation should succeed. - * EFI boot services are exited at the end of this function. - * There must be no allocations between the get_memory_map() - * call and the exit_boot_services() call, so the exiting of - * boot services is very tightly tied to the creation of the FDT - * with the final memory map in it. + * Allocate memory for a new FDT, then add EFI and commandline related fields + * to the FDT. This routine increases the FDT allocation size until the + * allocated memory is large enough. EFI allocations are in EFI_PAGE_SIZE + * granules, which are fixed at 4K bytes, so in most cases the first allocation + * should succeed. EFI boot services are exited at the end of this function. + * There must be no allocations between the get_memory_map() call and the + * exit_boot_services() call, so the exiting of boot services is very tightly + * tied to the creation of the FDT with the final memory map in it. */ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, unsigned long *new_fdt_addr, - u64 initrd_addr, u64 initrd_size, char *cmdline_ptr, unsigned long fdt_addr, unsigned long fdt_size) @@ -266,8 +246,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, } status = update_fdt((void *)fdt_addr, fdt_size, - (void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr, - initrd_addr, initrd_size); + (void *)*new_fdt_addr, MAX_FDT_SIZE, cmdline_ptr); if (status != EFI_SUCCESS) { efi_err("Unable to construct new device tree.\n"); diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c index 1ae1e7e576b9..8c67aa69fb7a 100644 --- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -766,7 +766,6 @@ unsigned long efi_main(efi_handle_t handle, unsigned long bzimage_addr = (unsigned long)startup_32; unsigned long buffer_start, buffer_end; struct setup_header *hdr = &boot_params->hdr; - unsigned long addr, size; efi_status_t status; efi_system_table = sys_table_arg; @@ -861,16 +860,9 @@ unsigned long efi_main(efi_handle_t handle, * arguments will be processed only if image is not NULL, which will be * the case only if we were loaded via the PE entry point. */ - status = efi_load_initrd(image, &addr, &size, hdr->initrd_addr_max, - ULONG_MAX); + status = efi_load_initrd(image, hdr->initrd_addr_max, ULONG_MAX); if (status != EFI_SUCCESS) goto fail; - if (size > 0) { - efi_set_u64_split(addr, &hdr->ramdisk_image, - &boot_params->ext_ramdisk_image); - efi_set_u64_split(size, &hdr->ramdisk_size, - &boot_params->ext_ramdisk_size); - } /* * If the boot loader gave us a value for secure_boot then we use that, diff --git a/include/linux/efi.h b/include/linux/efi.h index 6ad8eda0de7d..8668d9769bb0 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -1343,6 +1343,11 @@ struct linux_efi_coco_secret_area { u64 size; }; +struct linux_efi_initrd { + unsigned long base; + unsigned long size; +}; + /* Header of a populated EFI secret area */ #define EFI_SECRET_TABLE_HEADER_GUID EFI_GUID(0x1e74f542, 0x71dd, 0x4d66, 0x96, 0x3e, 0xef, 0x42, 0x87, 0xff, 0x17, 0x3b) From patchwork Sun Sep 18 21:35:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607256 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5B811C6FA8B for ; Sun, 18 Sep 2022 21:36:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229533AbiIRVgT (ORCPT ); Sun, 18 Sep 2022 17:36:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40590 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229561AbiIRVgS (ORCPT ); Sun, 18 Sep 2022 17:36:18 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4DA5113FA8 for ; Sun, 18 Sep 2022 14:36:17 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id D5239612AC for ; Sun, 18 Sep 2022 21:36:16 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 86327C43470; Sun, 18 Sep 2022 21:36:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536976; bh=ay6ANRnQboi0NxXKHvifHtY18HiC0iKwDUCc7TAOKyk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TkoQZhyPdXem6+IsM4vC41g0FhxE8TV7TOVYR7OXjZ/UMTir1oHRrtZFxAhaUbanZ Bst/tocNNwK6Y/6mGOXk0SZXiZ6dpJuiQM/VN4cupJ9chxB3FfP+N8pd2tbWDVnLSG vwbtjJsW3e280aBH19TA9MOrWgtsaXVTsUsT8S1Zfo3HX5xUM5GmVQS95N/ahgFXaO ujyl9gV8Bp7oFDniy7LIX+uop9ypWVHvYnjkAiskXbqX1a0xdlrOotrgvwZGKLHUZE LjNWN2SEi5B7MfqmsQe1WYoCsdlexlIrOq5OFbW/9rmKS1PDv6W1nwOczSyc8jJLYo 4vU5RGj7AmHUA== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao Subject: [PATCH 08/12] efi: libstub: remove DT dependency from generic stub Date: Sun, 18 Sep 2022 23:35:40 +0200 Message-Id: <20220918213544.2176249-9-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=7450; i=ardb@kernel.org; h=from:subject; bh=ay6ANRnQboi0NxXKHvifHtY18HiC0iKwDUCc7TAOKyk=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48oQGwHYzRZQ0QbBxEQVVwJZmnB+PB+Oy3Eumk8 92zU3VqJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePKAAKCRDDTyI5ktmPJM2UDA CqrhE3945MA9gAe3NGX5BLlC58E6OSAkaQDF0yAAhz7RMR7Ixp/3qDgdCJQfO3gqZpXLY2+yPX9mVx u48w9gCDXr2QLBO0ygpW1GP6sjCgK1bLuAVKiyjiVpsoRzOvxRXY9o4ux1XIdnexSw9+34XT7A6bwt UsbOKW70Ul3e1RenIdpQwtCd6JN9AAoC2NZb5ZK7hjiwDdeL2WTvX5iI7MHMwoRkzCkoIZ0fd+Sx1p T+zdUadBRUR1N3BdSofx4FU67VvNJeys5yA0oc6sGYIpG4fg5IplKXztkBqBVeySz+elOWWIT8bdVg g4ftxqxDEN5hHVhevbXiNLqGZWfM4A7RoxJ8jWEdLtvxa0EaunAyxLVAr5oZSRiIqq5jIHOkqrTBYr PuTLUX/RimC+jJlTWOz28r4bYT3ljOFD4yNt+Auf6EHUudEWKjjM8BkleI/phaRK6GVQpsuhIZzVnf kvGQnejOa35HQFtpFQfniWxkepdbIcopsgjKZRTwv2Bgo= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Refactor the generic EFI stub entry code so that all the dependencies on device tree are abstracted and hidden behind a generic efi_boot_kernel() routine that can also be implemented in other ways. This allows users of the generic stub to avoid using FDT for passing information to the core kernel. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/efi-stub.c | 53 +--------------- drivers/firmware/efi/libstub/efistub.h | 7 +-- drivers/firmware/efi/libstub/fdt.c | 64 ++++++++++++++++++-- 3 files changed, 63 insertions(+), 61 deletions(-) diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index 88bdd0a6b488..8715f5a36b92 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -10,7 +10,6 @@ */ #include -#include #include #include "efistub.h" @@ -130,14 +129,11 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, unsigned long image_addr; unsigned long image_size = 0; /* addr/point and size pairs for memory management*/ - unsigned long fdt_addr = 0; /* Original DTB */ - unsigned long fdt_size = 0; char *cmdline_ptr = NULL; int cmdline_size = 0; efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID; unsigned long reserve_addr = 0; unsigned long reserve_size = 0; - enum efi_secureboot_mode secure_boot; struct screen_info *si; efi_properties_table_t *prop_tbl; @@ -213,38 +209,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, /* Ask the firmware to clear memory on unclean shutdown */ efi_enable_reset_attack_mitigation(); - secure_boot = efi_get_secureboot(); - - /* - * Unauthenticated device tree data is a security hazard, so ignore - * 'dtb=' unless UEFI Secure Boot is disabled. We assume that secure - * boot is enabled if we can't determine its state. - */ - if (!IS_ENABLED(CONFIG_EFI_ARMSTUB_DTB_LOADER) || - secure_boot != efi_secureboot_mode_disabled) { - if (strstr(cmdline_ptr, "dtb=")) - efi_err("Ignoring DTB from command line.\n"); - } else { - status = efi_load_dtb(image, &fdt_addr, &fdt_size); - - if (status != EFI_SUCCESS) { - efi_err("Failed to load device tree!\n"); - goto fail_free_image; - } - } - - if (fdt_addr) { - efi_info("Using DTB from command line\n"); - } else { - /* Look for a device tree configuration table entry. */ - fdt_addr = (uintptr_t)get_fdt(&fdt_size); - if (fdt_addr) - efi_info("Using DTB from configuration table\n"); - } - - if (!fdt_addr) - efi_info("Generating empty DTB\n"); - efi_load_initrd(image, ULONG_MAX, efi_get_max_initrd_addr(image_addr)); @@ -288,23 +252,8 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, install_memreserve_table(); - status = allocate_new_fdt_and_exit_boot(handle, &fdt_addr, cmdline_ptr, - fdt_addr, fdt_size); - if (status != EFI_SUCCESS) - goto fail_free_fdt; - - if (IS_ENABLED(CONFIG_ARM)) - efi_handle_post_ebs_state(); - - efi_enter_kernel(image_addr, fdt_addr, fdt_totalsize((void *)fdt_addr)); - /* not reached */ - -fail_free_fdt: - efi_err("Failed to update FDT and exit boot services\n"); - - efi_free(fdt_size, fdt_addr); + status = efi_boot_kernel(handle, image, image_addr, cmdline_ptr); -fail_free_image: efi_free(image_size, image_addr); efi_free(reserve_size, reserve_addr); fail_free_screeninfo: diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index 82cff342da05..f65a8a3844b8 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -865,11 +865,8 @@ typedef efi_status_t (*efi_exit_boot_map_processing)( efi_status_t efi_exit_boot_services(void *handle, void *priv, efi_exit_boot_map_processing priv_func); -efi_status_t allocate_new_fdt_and_exit_boot(void *handle, - unsigned long *new_fdt_addr, - char *cmdline_ptr, - unsigned long fdt_addr, - unsigned long fdt_size); +efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image, + unsigned long image_addr, char *cmdline_ptr); void *get_fdt(unsigned long *fdt_size); diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index a3cd603ea484..8251c9c8463d 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -219,17 +219,19 @@ static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv) * exit_boot_services() call, so the exiting of boot services is very tightly * tied to the creation of the FDT with the final memory map in it. */ - +static efi_status_t allocate_new_fdt_and_exit_boot(void *handle, + efi_loaded_image_t *image, unsigned long *new_fdt_addr, - char *cmdline_ptr, - unsigned long fdt_addr, - unsigned long fdt_size) + char *cmdline_ptr) { unsigned long desc_size; u32 desc_ver; efi_status_t status; + enum efi_secureboot_mode secure_boot; struct exit_boot_struct priv; + unsigned long fdt_addr = 0; + unsigned long fdt_size = 0; status = efi_alloc_virtmap(&priv.runtime_map, &desc_size, &desc_ver); if (status != EFI_SUCCESS) { @@ -237,6 +239,38 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, return status; } + secure_boot = efi_get_secureboot(); + + /* + * Unauthenticated device tree data is a security hazard, so ignore + * 'dtb=' unless UEFI Secure Boot is disabled. We assume that secure + * boot is enabled if we can't determine its state. + */ + if (!IS_ENABLED(CONFIG_EFI_ARMSTUB_DTB_LOADER) || + secure_boot != efi_secureboot_mode_disabled) { + if (strstr(cmdline_ptr, "dtb=")) + efi_err("Ignoring DTB from command line.\n"); + } else { + status = efi_load_dtb(image, &fdt_addr, &fdt_size); + + if (status != EFI_SUCCESS) { + efi_err("Failed to load device tree!\n"); + goto fail; + } + } + + if (fdt_addr) { + efi_info("Using DTB from command line\n"); + } else { + /* Look for a device tree configuration table entry. */ + fdt_addr = (uintptr_t)get_fdt(&fdt_size); + if (fdt_addr) + efi_info("Using DTB from configuration table\n"); + } + + if (!fdt_addr) + efi_info("Generating empty DTB\n"); + efi_info("Exiting boot services...\n"); status = efi_allocate_pages(MAX_FDT_SIZE, new_fdt_addr, ULONG_MAX); @@ -300,11 +334,33 @@ efi_status_t allocate_new_fdt_and_exit_boot(void *handle, efi_free(MAX_FDT_SIZE, *new_fdt_addr); fail: + efi_free(fdt_size, fdt_addr); + efi_bs_call(free_pool, priv.runtime_map); return EFI_LOAD_ERROR; } +efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image, + unsigned long image_addr, char *cmdline_ptr) +{ + unsigned long fdt_addr; + efi_status_t status; + + status = allocate_new_fdt_and_exit_boot(handle, image, &fdt_addr, + cmdline_ptr); + if (status != EFI_SUCCESS) { + efi_err("Failed to update FDT and exit boot services\n"); + return status; + } + + if (IS_ENABLED(CONFIG_ARM)) + efi_handle_post_ebs_state(); + + efi_enter_kernel(image_addr, fdt_addr, fdt_totalsize((void *)fdt_addr)); + /* not reached */ +} + void *get_fdt(unsigned long *fdt_size) { void *fdt; From patchwork Sun Sep 18 21:35:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607490 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8EC62C6FA82 for ; Sun, 18 Sep 2022 21:36:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229586AbiIRVgW (ORCPT ); Sun, 18 Sep 2022 17:36:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40610 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229561AbiIRVgW (ORCPT ); Sun, 18 Sep 2022 17:36:22 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB1AF13FA2 for ; Sun, 18 Sep 2022 14:36:20 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id A3125B81330 for ; Sun, 18 Sep 2022 21:36:19 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id B2C6EC433C1; Sun, 18 Sep 2022 21:36:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536978; bh=e2Iqplw0yzG3w2OvmovsVI5QKe97+qAlA9sWqfYGy+g=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QXNlShTlVDH3VpyDrZmv2sSBTnHCwdsqBf4dN8zCLeq/oqeJqmPRvKhRaT/XNH1rH o0jmqvjEb1C/TJvUfwU8lI6gc4meQwJWREdIuRozSYNwR+IEEEMloUe8WBMzjPQYpP ZXntaBRyuEl795ZdKgyOORvT5L3MWuEcmF+s9CgsLo6owLsbo1ZjdqTd03jo7a4aGt fSd+z31P7SdI+8LqAxiwu2KFj1DnBnmGmy+Jcc4GSWyst/001jKNJpDZasvm9+ibRH mWzTFTuHxzPPaDygfkhDU59G3m2GokKBqWEHTk38Qc0DbNkzaougcI5G2PHeQMzHJk qmvwSLnvijTEg== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao Subject: [PATCH 09/12] efi: libstub: install boot-time memory map as config table Date: Sun, 18 Sep 2022 23:35:41 +0200 Message-Id: <20220918213544.2176249-10-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6542; i=ardb@kernel.org; h=from:subject; bh=e2Iqplw0yzG3w2OvmovsVI5QKe97+qAlA9sWqfYGy+g=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48p8Tg+X93WLpbB7UKaWHk+2RveAozj2ZDdoGkp 9ha4xU+JAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePKQAKCRDDTyI5ktmPJI/PC/ 4wuuZSvomTMUW3cTd9Xv5tWssa625ULpO+KgA9AZfx36e/IhTvAqUf4N1HBy+LcsCFJHbOw1Ax79p4 9t6rCy6CGDrQi7nMgmPBCAiunfwzBS/SR2aP/9QLZ5YFdW9JeQzXhqyxHcSQoCKYLGwV8aQc8kN2U4 oYQdlqoCDLV3EpBf0Auql8BpW2A0g/RPbNxn6BKSOVRhFd+RrWxOWHVUu9z1vrsAYIBOdGik5PG2Fd sTQVeOXjl9fUUc9/D3FM+wTqaUf4VRwiuYppeUYNzFKUDsZAieIbYuS8cS3HIwUkofbUsxBbZ8Kgsh tiJBaghWZxEKi794pfWyRMkIROK2uJCYv1Il+jM/65hjKPTBmhcQuVgrod0q67GU35vEgZdOVkXLt9 qoD62USu/j+L4uBbBBnkEuafPsf7en2gVZPsR1olA/x0iNrnTRo5K6Kr5bIgO8vE7D25eWL82QxQ6X rhSMKcW43HlJ24vmxSUEBWEIFIyssD5Zn05RglLWa0lyA= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Expose the EFI boot time memory map to the kernel via a configuration table. This is arch agnostic and enables future changes that remove the dependency on DT on architectures that don't otherwise rely on it. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/arm64-stub.c | 2 +- drivers/firmware/efi/libstub/efi-stub-helper.c | 2 +- drivers/firmware/efi/libstub/efistub.h | 3 ++- drivers/firmware/efi/libstub/mem.c | 26 ++++++++++++++++++-- drivers/firmware/efi/libstub/randomalloc.c | 2 +- drivers/firmware/efi/libstub/relocate.c | 2 +- include/linux/efi.h | 1 + 7 files changed, 31 insertions(+), 7 deletions(-) diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c index e9d516ad5f97..df05c53baa23 100644 --- a/drivers/firmware/efi/libstub/arm64-stub.c +++ b/drivers/firmware/efi/libstub/arm64-stub.c @@ -55,7 +55,7 @@ static bool check_image_region(u64 base, u64 size) bool ret = false; int map_offset; - status = efi_get_memory_map(&map); + status = efi_get_memory_map(&map, false); if (status != EFI_SUCCESS) return false; diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index 742ecd9e0df3..f1f7a823be17 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -438,7 +438,7 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv, struct efi_boot_memmap *map; efi_status_t status; - status = efi_get_memory_map(&map); + status = efi_get_memory_map(&map, true); if (status != EFI_SUCCESS) goto fail; diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index f65a8a3844b8..b4fb6d4e8a59 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -897,7 +897,8 @@ void efi_apply_loadoptions_quirk(const void **load_options, u32 *load_options_si char *efi_convert_cmdline(efi_loaded_image_t *image, int *cmd_line_len); -efi_status_t efi_get_memory_map(struct efi_boot_memmap **map); +efi_status_t efi_get_memory_map(struct efi_boot_memmap **map, + bool install_cfg_tbl); efi_status_t efi_allocate_pages(unsigned long size, unsigned long *addr, unsigned long max); diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c index 40721573e494..ed4c145afe11 100644 --- a/drivers/firmware/efi/libstub/mem.c +++ b/drivers/firmware/efi/libstub/mem.c @@ -9,14 +9,20 @@ * efi_get_memory_map() - get memory map * @map: pointer to memory map pointer to which to assign the * newly allocated memory map + * @install_cfg_tbl: whether or not to install the boot memory map as a + * configuration table * * Retrieve the UEFI memory map. The allocated memory leaves room for * up to EFI_MMAP_NR_SLACK_SLOTS additional memory map entries. * * Return: status code */ -efi_status_t efi_get_memory_map(struct efi_boot_memmap **map) +efi_status_t efi_get_memory_map(struct efi_boot_memmap **map, + bool install_cfg_tbl) { + int memtype = install_cfg_tbl ? EFI_ACPI_RECLAIM_MEMORY + : EFI_LOADER_DATA; + efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID; struct efi_boot_memmap *m, tmp; efi_status_t status; unsigned long size; @@ -28,11 +34,23 @@ efi_status_t efi_get_memory_map(struct efi_boot_memmap **map) return EFI_LOAD_ERROR; size = tmp.map_size + tmp.desc_size * EFI_MMAP_NR_SLACK_SLOTS; - status = efi_bs_call(allocate_pool, EFI_LOADER_DATA, sizeof(*m) + size, + status = efi_bs_call(allocate_pool, memtype, sizeof(*m) + size, (void **)&m); if (status != EFI_SUCCESS) return status; + if (install_cfg_tbl) { + /* + * Installing a configuration table might allocate memory, and + * this may modify the memory map. This means we should install + * the configuration table first, and re-install or delete it + * as needed. + */ + status = efi_bs_call(install_configuration_table, &tbl_guid, m); + if (status != EFI_SUCCESS) + goto free_map; + } + m->buff_size = m->map_size = size; status = efi_bs_call(get_memory_map, &m->map_size, m->map, &m->map_key, &m->desc_size, &m->desc_ver); @@ -40,6 +58,10 @@ efi_status_t efi_get_memory_map(struct efi_boot_memmap **map) if (status == EFI_SUCCESS) { *map = m; } else { + if (install_cfg_tbl) + efi_bs_call(install_configuration_table, &tbl_guid, + NULL); +free_map: efi_bs_call(free_pool, m); } diff --git a/drivers/firmware/efi/libstub/randomalloc.c b/drivers/firmware/efi/libstub/randomalloc.c index 5d6000c717cc..9fb5869896be 100644 --- a/drivers/firmware/efi/libstub/randomalloc.c +++ b/drivers/firmware/efi/libstub/randomalloc.c @@ -61,7 +61,7 @@ efi_status_t efi_random_alloc(unsigned long size, efi_status_t status; int map_offset; - status = efi_get_memory_map(&map); + status = efi_get_memory_map(&map, false); if (status != EFI_SUCCESS) return status; diff --git a/drivers/firmware/efi/libstub/relocate.c b/drivers/firmware/efi/libstub/relocate.c index cd80db33ab1e..bf6fbd5d22a1 100644 --- a/drivers/firmware/efi/libstub/relocate.c +++ b/drivers/firmware/efi/libstub/relocate.c @@ -28,7 +28,7 @@ efi_status_t efi_low_alloc_above(unsigned long size, unsigned long align, unsigned long nr_pages; int i; - status = efi_get_memory_map(&map); + status = efi_get_memory_map(&map, false); if (status != EFI_SUCCESS) goto fail; diff --git a/include/linux/efi.h b/include/linux/efi.h index 8668d9769bb0..89f16ec3ebab 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -414,6 +414,7 @@ void efi_native_runtime_setup(void); #define LINUX_EFI_ZBOOT_MEDIA_GUID EFI_GUID(0xe565a30d, 0x47da, 0x4dbd, 0xb3, 0x54, 0x9b, 0xb5, 0xc8, 0x4f, 0x8b, 0xe2) #define LINUX_EFI_MOK_VARIABLE_TABLE_GUID EFI_GUID(0xc451ed2b, 0x9694, 0x45d3, 0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89) #define LINUX_EFI_COCO_SECRET_AREA_GUID EFI_GUID(0xadf956ad, 0xe98c, 0x484c, 0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47) +#define LINUX_EFI_BOOT_MEMMAP_GUID EFI_GUID(0x800f683f, 0xd08b, 0x423a, 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4) #define RISCV_EFI_BOOT_PROTOCOL_GUID EFI_GUID(0xccd15fec, 0x6f73, 0x4eec, 0x83, 0x95, 0x3e, 0x69, 0xe4, 0xb9, 0x40, 0xbf) From patchwork Sun Sep 18 21:35:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607255 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1A916ECAAD8 for ; Sun, 18 Sep 2022 21:36:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229551AbiIRVgX (ORCPT ); Sun, 18 Sep 2022 17:36:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40614 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229581AbiIRVgW (ORCPT ); Sun, 18 Sep 2022 17:36:22 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A06A913FAB for ; Sun, 18 Sep 2022 14:36:21 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 3DA5D612AC for ; Sun, 18 Sep 2022 21:36:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id DF854C433D7; Sun, 18 Sep 2022 21:36:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536980; bh=RXnNlaksocyhUCf1TtF0nCIv72jfeLTz6q5C8n0AChA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uEd4qGpaydhAQZM4Eh/z8tvEwtXPV6dry7iBPzVXVad6Q/UttBdQi4U0wPFOMXZJj du2Zcub3ND9c0w+xkYkYrPJnRmtgZgFIydrLhkuFhoh0r+mdGR0HLkynJA59Utmsmu TJtYbRquddob9HEHvKP/JQuN02qVihWAkHuLIpR+cjJtU+rDNR0KUb1c6Q+RFlb+qu gs/0tpsABEsQ9ff9hjlIOeDRjXETpKUyobLnGHRqaK4BZOOAGgAeINKRqQpw82S789 WJNh4C4GNBJufoYUKOgF6Zt4gvwiZeYWUIyQ2kbt7Z8u03o2xpjzRcXpA6Xe49/RZD lPTMjmQexvDCQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao Subject: [PATCH 10/12] efi: libstub: remove pointless goto kludge Date: Sun, 18 Sep 2022 23:35:42 +0200 Message-Id: <20220918213544.2176249-11-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1666; i=ardb@kernel.org; h=from:subject; bh=RXnNlaksocyhUCf1TtF0nCIv72jfeLTz6q5C8n0AChA=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48rArpB44oOut+AD+EXPPAeJWwXajGeoY705IPX GHglvjmJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePKwAKCRDDTyI5ktmPJOJGC/ 9DEPaBJRIdXZQRWuiEk5KEatwI3jwBhslPT98LZnUlBqiZuVnfLhfzAvEydp7o0Ztf4ctowibWBCcI Hu21WWZNPHT4FxUQGSYxwfyJiCrSl/N305v2GuMydhD9Jr2VWqMFsfrGgaDIF83aoaNgpYVGfGNpB/ QiBjp62e+GmAM6gMYUG0Q2IS1CdW8hLtGbAw/+IMy16GfK3MnP3Ab7FaTfF9bqHgYLpGnKOvScU5Vw x+vUFpz81Rar3s28ZQ3XTiUuUhWnvSH0snWgGg79vLeakx7urMyB3YU8khuQ7ZesVzb+/18qihXvGZ uNf5hq6n7tvPPDRCesgvLPeZUMc/3INCtUT2t+ZPnUAS7ki4kaQAqh71r8qZkudMzCzXxnfslGEzau 2o0hii7SuFMFhvBFzBDycTQr3zxFM7v0fJ1+ABcpc5lwlKGzKY94ZG3QCmXWcwcH5U57sFuQ9Tz1XR WMqTfKXcJh1Bwc7hPqzSFvpQBXRPDN0ZsU3ZMyW/DWhag= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Remove some goto cruft that serves no purpose and obfuscates the code. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/efi-stub-helper.c | 22 +++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index f1f7a823be17..76a1a395fad4 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -439,13 +439,14 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv, efi_status_t status; status = efi_get_memory_map(&map, true); - if (status != EFI_SUCCESS) - goto fail; + return status; status = priv_func(map, priv); - if (status != EFI_SUCCESS) - goto free_map; + if (status != EFI_SUCCESS) { + efi_bs_call(free_pool, map); + return status; + } if (efi_disable_pci_dma) efi_pci_disable_bridge_busmaster(); @@ -476,25 +477,16 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv, /* exit_boot_services() was called, thus cannot free */ if (status != EFI_SUCCESS) - goto fail; + return status; status = priv_func(map, priv); /* exit_boot_services() was called, thus cannot free */ if (status != EFI_SUCCESS) - goto fail; + return status; status = efi_bs_call(exit_boot_services, handle, map->map_key); } - /* exit_boot_services() was called, thus cannot free */ - if (status != EFI_SUCCESS) - goto fail; - - return EFI_SUCCESS; - -free_map: - efi_bs_call(free_pool, map); -fail: return status; } From patchwork Sun Sep 18 21:35:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607254 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 53134C6FA86 for ; Sun, 18 Sep 2022 21:36:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229606AbiIRVg1 (ORCPT ); Sun, 18 Sep 2022 17:36:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40638 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229581AbiIRVg0 (ORCPT ); Sun, 18 Sep 2022 17:36:26 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 987E113FA8 for ; Sun, 18 Sep 2022 14:36:25 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 26D83B81333 for ; Sun, 18 Sep 2022 21:36:24 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1720BC433C1; Sun, 18 Sep 2022 21:36:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536982; bh=xWzCcuDcIbk2EunYOTQ7Gfzh2AHn/lco5BFilNl5klA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dsUy66T9eCUfVe+Mf4TXMebKHd24+ecwi4qRagCAqOMj9jyNBBj5+3Pkw8slLGFBc 5+x6QFouAKkSxLPIT++B8u/1sUIkoCCIw5y6jwdurwlOR+FUi+MF8fbHFQDO9K5iCa 6s2t3nLNqY8YqZdIkHWHaETlicJ2XsHkAu/z0arlxs0r6mpeaMCe93AYYmmQdbkvDM JAU9mLwlgFRZ0YVseNBkKWeiGs6R/5BSmsO07eeXHA4NcmMTdLWHFeUWfdS2zh9JUF YscIhU2h40hQhukM5MYBzLOXH3ioK64Org10NKuJBP8tlDtDbjcHKpoGZDo3xhRRCK 15kUoXhIbqrnw== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao Subject: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT Date: Sun, 18 Sep 2022 23:35:43 +0200 Message-Id: <20220918213544.2176249-12-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=12172; i=ardb@kernel.org; h=from:subject; bh=xWzCcuDcIbk2EunYOTQ7Gfzh2AHn/lco5BFilNl5klA=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48tGincx1LSqGgCdOY4VCJFW6PB8dzHcyzcBeKJ a7+4gXaJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePLQAKCRDDTyI5ktmPJGPODA CA9NBQXALfzWxyxzXnnOlLNlLvIltm9oxAX3NWfOjfKM9M27B60rKjNyKZmNSfRr/ezKNQDIve5DUw /ZlwZ0mHLkOpXSe05MCMDHUXSaDoudlX4V85esr+VuCcfbxTanIeCnqqXKunQJIiKXy1Yb0G2V3FmJ 1QnSHsnFA0A5YAOa+4P5eKuf2mDo7QI4NKdXKRuS/FLobGYquVPMq1fZQGvOygvUZNGkAbVwF4XurL nPzV7UyvnZwvBtZEyE09X+La0P4lr469fF4E3QN25+9V2cFm+6sEQNk0cnhDktBpkwPptqKhemsQ2J cT+2PxaU1j0LaKGVRBYkOIabCKl+aqFE3jk/jIJ0a/E7IUefl1G8uoJ55KA3yTurPrlXbKom+OJh7X dgYukkCqWkKHHibn9s8zE+aU0ACwvte1wKOmEgDm2IYV1B/v6DF8ASTrRh334pJ/+QzpDV0iZUwpYm 5hPiydtjVlPnJg1r8Vi/aSxX5pa7dILXqcD7ToEdDCTI0= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org LoongArch does not use FDT or DT natively [yet], and the only reason it currently uses it is so that it can reuse the existing EFI stub code. Overloading the DT with data passed between the EFI stub and the core kernel has been a source of problems: there is the overlap between information provided by EFI which DT can also provide (initrd base/size, command line, memory descriptions), requiring us to reason about which is which and what to prioritize. It has also resulted in ABI leaks, i.e., internal ABI being promoted to external ABI inadvertently because the bootloader can set the EFI stub's DT properties as well (e.g., "kaslr-seed"). This has become especially problematic with boot environments that want to pretend that EFI boot is being done (to access ACPI and SMBIOS tables, for instance) but have no ability to execute the EFI stub, and so the environment that the EFI stub creates is emulated [poorly, in some cases]. Another downside of treating DT like this is that the DT binary that the kernel receives is different from the one created by the firmware, which is undesirable in the context of secure and measured boot. Given that LoongArch support in Linux is brand new, we can avoid these pitfalls, and treat the DT strictly as a hardware description, and use a separate handover method between the EFI stub and the kernel. Now that initrd loading and passing the EFI memory map have been refactored into pure EFI routines that use EFI configuration tables, the only thing we need to pass directly is the kernel command line (even if we could pass this via a config table as well, it is used extremely early, so passing it directly is preferred in this case.) Signed-off-by: Ard Biesheuvel --- arch/loongarch/Kconfig | 3 -- arch/loongarch/include/asm/bootinfo.h | 2 +- arch/loongarch/kernel/efi.c | 30 ++++++++++- arch/loongarch/kernel/env.c | 22 ++++---- arch/loongarch/kernel/head.S | 2 + arch/loongarch/kernel/setup.c | 4 +- drivers/firmware/efi/libstub/Makefile | 13 +++-- drivers/firmware/efi/libstub/loongarch-stub.c | 56 +++++++++++++++++--- 8 files changed, 100 insertions(+), 32 deletions(-) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index fca106a8b8af..14a2a1ec8561 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -104,8 +104,6 @@ config LOONGARCH select MODULES_USE_ELF_RELA if MODULES select NEED_PER_CPU_EMBED_FIRST_CHUNK select NEED_PER_CPU_PAGE_FIRST_CHUNK - select OF - select OF_EARLY_FLATTREE select PCI select PCI_DOMAINS_GENERIC select PCI_ECAM if ACPI @@ -311,7 +309,6 @@ config DMI config EFI bool "EFI runtime service support" select UCS2_STRING - select EFI_PARAMS_FROM_FDT select EFI_RUNTIME_WRAPPERS help This enables the kernel to use EFI runtime services that are diff --git a/arch/loongarch/include/asm/bootinfo.h b/arch/loongarch/include/asm/bootinfo.h index e02ac4af7f6e..8e5881bc5ad1 100644 --- a/arch/loongarch/include/asm/bootinfo.h +++ b/arch/loongarch/include/asm/bootinfo.h @@ -36,7 +36,7 @@ struct loongson_system_configuration { }; extern u64 efi_system_table; -extern unsigned long fw_arg0, fw_arg1; +extern unsigned long fw_arg0, fw_arg1, fw_arg2; extern struct loongson_board_info b_info; extern struct loongson_system_configuration loongson_sysconf; diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index 1f1f755fb425..3b80675726ec 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -27,8 +27,13 @@ static unsigned long efi_nr_tables; static unsigned long efi_config_table; +static unsigned long __initdata boot_memmap = EFI_INVALID_TABLE_ADDR; + static efi_system_table_t *efi_systab; -static efi_config_table_type_t arch_tables[] __initdata = {{},}; +static efi_config_table_type_t arch_tables[] __initdata = { + {LINUX_EFI_BOOT_MEMMAP_GUID, &boot_memmap, "MEMMAP" }, + {}, +}; void __init efi_runtime_init(void) { @@ -61,6 +66,8 @@ void __init efi_init(void) return; } + efi_systab_report_header(&efi_systab->hdr, efi_systab->fw_vendor); + set_bit(EFI_64BIT, &efi.flags); efi_nr_tables = efi_systab->nr_tables; efi_config_table = (unsigned long)efi_systab->tables; @@ -72,4 +79,25 @@ void __init efi_init(void) if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) memblock_reserve(screen_info.lfb_base, screen_info.lfb_size); + + if (boot_memmap != EFI_INVALID_TABLE_ADDR) { + struct efi_memory_map_data data; + struct efi_boot_memmap *tbl; + + tbl = early_memremap_ro(boot_memmap, sizeof(*tbl)); + if (tbl) { + data.phys_map = boot_memmap + sizeof(*tbl); + data.size = tbl->map_size; + data.desc_size = tbl->desc_size; + data.desc_version = tbl->desc_ver; + + if (efi_memmap_init_early(&data) < 0) + panic("Unable to map EFI memory map.\n"); + + memblock_reserve(data.phys_map & PAGE_MASK, + PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK))); + + early_memunmap(tbl, sizeof(*tbl)); + } + } } diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c index 82b478a5c665..05c38d28476e 100644 --- a/arch/loongarch/kernel/env.c +++ b/arch/loongarch/kernel/env.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -20,21 +19,18 @@ EXPORT_SYMBOL(loongson_sysconf); void __init init_environ(void) { int efi_boot = fw_arg0; - struct efi_memory_map_data data; - void *fdt_ptr = early_memremap_ro(fw_arg1, SZ_64K); - if (efi_boot) - set_bit(EFI_BOOT, &efi.flags); - else - clear_bit(EFI_BOOT, &efi.flags); + if (efi_boot) { + char *cmdline = early_memremap_ro(fw_arg2, COMMAND_LINE_SIZE); - early_init_dt_scan(fdt_ptr); - early_init_fdt_reserve_self(); - efi_system_table = efi_get_fdt_params(&data); + strscpy(boot_command_line, cmdline, COMMAND_LINE_SIZE); + early_memunmap(cmdline, COMMAND_LINE_SIZE); - efi_memmap_init_early(&data); - memblock_reserve(data.phys_map & PAGE_MASK, - PAGE_ALIGN(data.size + (data.phys_map & ~PAGE_MASK))); + efi_system_table = fw_arg1; + set_bit(EFI_BOOT, &efi.flags); + } else { + clear_bit(EFI_BOOT, &efi.flags); + } } static int __init init_cpu_fullname(void) diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S index 01bac62a6442..8f89f39fd31b 100644 --- a/arch/loongarch/kernel/head.S +++ b/arch/loongarch/kernel/head.S @@ -67,6 +67,8 @@ SYM_CODE_START(kernel_entry) # kernel entry point st.d a0, t0, 0 # firmware arguments la t0, fw_arg1 st.d a1, t0, 0 + la t0, fw_arg2 + st.d a2, t0, 0 /* KSave3 used for percpu base, initialized as 0 */ csrwr zero, PERCPU_BASE_KS diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index e8714b1d94c8..7fabf2306e80 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -51,7 +51,7 @@ struct screen_info screen_info __section(".data"); -unsigned long fw_arg0, fw_arg1; +unsigned long fw_arg0, fw_arg1, fw_arg2; DEFINE_PER_CPU(unsigned long, kernelsp); struct cpuinfo_loongarch cpu_data[NR_CPUS] __read_mostly; @@ -187,7 +187,6 @@ early_param("mem", early_parse_mem); void __init platform_init(void) { - efi_init(); #ifdef CONFIG_ACPI_TABLE_UPGRADE acpi_table_upgrade(); #endif @@ -347,6 +346,7 @@ void __init setup_arch(char **cmdline_p) *cmdline_p = boot_command_line; init_environ(); + efi_init(); memblock_init(); parse_early_param(); diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index 0dbc6d93f2e6..d8d6657e6277 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -29,7 +29,7 @@ cflags-$(CONFIG_RISCV) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ cflags-$(CONFIG_LOONGARCH) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ -fpie -cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt +cflags-$(CONFIG_EFI_PARAMS_FROM_FDT) += -I$(srctree)/scripts/dtc/libfdt KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \ -include $(srctree)/include/linux/hidden.h \ @@ -60,14 +60,17 @@ lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o \ alignedmem.o relocate.o vsprintf.o \ systable.o -# include the stub's generic dependencies from lib/ when building for ARM/arm64 -efi-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c +# include the stub's libfdt dependencies from lib/ when needed +libfdt-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c \ + fdt_empty_tree.c fdt_sw.c + +lib-$(CONFIG_EFI_PARAMS_FROM_FDT) += fdt.o \ + $(patsubst %.c,lib-%.o,$(libfdt-deps)) $(obj)/lib-%.o: $(srctree)/lib/%.c FORCE $(call if_changed_rule,cc_o_c) -lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o fdt.o string.o intrinsics.o \ - $(patsubst %.c,lib-%.o,$(efi-deps-y)) +lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o lib-$(CONFIG_ARM) += arm32-stub.o lib-$(CONFIG_ARM64) += arm64-stub.o diff --git a/drivers/firmware/efi/libstub/loongarch-stub.c b/drivers/firmware/efi/libstub/loongarch-stub.c index b7ef8d2df59e..7c684d10f936 100644 --- a/drivers/firmware/efi/libstub/loongarch-stub.c +++ b/drivers/firmware/efi/libstub/loongarch-stub.c @@ -9,7 +9,8 @@ #include #include "efistub.h" -typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long fdt); +typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long systab, + unsigned long cmdline); extern int kernel_asize; extern int kernel_fsize; @@ -42,19 +43,60 @@ efi_status_t handle_kernel_image(unsigned long *image_addr, return status; } -void __noreturn efi_enter_kernel(unsigned long entrypoint, unsigned long fdt, unsigned long fdt_size) +struct exit_boot_struct { + efi_memory_desc_t *runtime_map; + int runtime_entry_count; +}; + +static efi_status_t exit_boot_func(struct efi_boot_memmap *map, void *priv) +{ + struct exit_boot_struct *p = priv; + + /* + * Update the memory map with virtual addresses. The function will also + * populate @runtime_map with copies of just the EFI_MEMORY_RUNTIME + * entries so that we can pass it straight to SetVirtualAddressMap() + */ + efi_get_virtmap(map->map, map->map_size, map->desc_size, + p->runtime_map, &p->runtime_entry_count); + + return EFI_SUCCESS; +} + +efi_status_t efi_boot_kernel(void *handle, efi_loaded_image_t *image, + unsigned long image_addr, char *cmdline_ptr) { kernel_entry_t real_kernel_entry; + struct exit_boot_struct priv; + unsigned long desc_size; + efi_status_t status; + u32 desc_ver; + + status = efi_alloc_virtmap(&priv.runtime_map, &desc_size, &desc_ver); + if (status != EFI_SUCCESS) { + efi_err("Unable to retrieve UEFI memory map.\n"); + return status; + } + + efi_info("Exiting boot services\n"); + + efi_novamap = false; + status = efi_exit_boot_services(handle, &priv, exit_boot_func); + if (status != EFI_SUCCESS) + return status; + + /* Install the new virtual address map */ + efi_rt_call(set_virtual_address_map, + priv.runtime_entry_count * desc_size, desc_size, + desc_ver, priv.runtime_map); /* Config Direct Mapping */ csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0); csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1); real_kernel_entry = (kernel_entry_t) - ((unsigned long)&kernel_entry - entrypoint + VMLINUX_LOAD_ADDRESS); + ((unsigned long)&kernel_entry - image_addr + VMLINUX_LOAD_ADDRESS); - if (!efi_novamap) - real_kernel_entry(true, fdt); - else - real_kernel_entry(false, fdt); + real_kernel_entry(true, (unsigned long)efi_system_table, + (unsigned long)cmdline_ptr); } From patchwork Sun Sep 18 21:35:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 607489 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E32B5ECAAD8 for ; Sun, 18 Sep 2022 21:36:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229601AbiIRVg1 (ORCPT ); Sun, 18 Sep 2022 17:36:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40636 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229561AbiIRVg0 (ORCPT ); Sun, 18 Sep 2022 17:36:26 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F3B7313FAB for ; Sun, 18 Sep 2022 14:36:25 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8FCF561599 for ; Sun, 18 Sep 2022 21:36:25 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 41E1AC433B5; Sun, 18 Sep 2022 21:36:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1663536985; bh=MJHabceJjCWQVg/sduyUYpKDir7hmmzhm7sjKN5i5A4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZGDAcSsxvgf7t8oouaGalmV/SGj6kjO3ox+b67ik27jhDfRWgssRORUDNcl7hgDll e5mnjyms0aj1ClU+N1y/2zFWzjVspM/dUmOdKGNJbp+3j9FqRNBKjswP37iD4l7p6h KeV7YNF1giOzSfoL+1TjfYWchsE5Ctvfs1VPvZOMDRM+3hMNGiLKC1loRrKy9X2KUb X6J11JcfYA8/d1BSydySj+K47gS8PFmut7fzl2U+DaPvuoMOkelJ1wn/G7gIsxso90 9djYvCHQCdTAiSdgNuP4cYncOVg15jtlw3qxCDExvAT8dzTeMJ0hmY+kT5P9fKmQpv kjaY1uKvRXaDQ== From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: loongarch@lists.linux.dev, linux@armlinux.org.uk, Ard Biesheuvel , Arnd Bergmann , Ilias Apalodimas , Huacai Chen , Xi Ruoyao Subject: [PATCH 12/12] efi: loongarch: add support for DT hardware descriptions Date: Sun, 18 Sep 2022 23:35:44 +0200 Message-Id: <20220918213544.2176249-13-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220918213544.2176249-1-ardb@kernel.org> References: <20220918213544.2176249-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3282; i=ardb@kernel.org; h=from:subject; bh=MJHabceJjCWQVg/sduyUYpKDir7hmmzhm7sjKN5i5A4=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjJ48v8zXv8FfbQcQtAcYHvMvFjY74Go4gdwo8EnV2 25O2DWuJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCYyePLwAKCRDDTyI5ktmPJHZ5C/ 4xPhD5tRO6GsKh08CLM2v/WGfIinP5OnGhqyVMiRKdYZH38r9Hjnp0hJw0MxSnwLIPj1uWYIlRpjLY ntHC/HRYvUIBUJCESsnMPgxBv4WBsuSr27QidBgh7sP/f75E7h9cWc9swGOdEr8IUzEBzek8RQN+x6 dArD1fYyNI2ssKdv3Xq7D5apO0tXD70zd9Bcung/TexMt/CHcYuGYcYN/r+aqjYrLpU4gM9GYH542A RMjqo+ZvQ9QrcpnC/64VOFt8EqOwTq3aAsSyKevBuOxber8hNH+es70YOTzo9TGCf9bgM3twOixT6H TYQoKv4XwZXcZp6IUrbbKgNfIQ6y5EpStmEgNBwZcklhNv9dXT9nrpVBOBtclDD43bfMSTm4cAhO7f QtNaD0cwWMJ33UWr81juJAvL5uQarltTqa9ItPm6scp49CsmXXoKM8szeVZKZkeOE153Cj0IZPOXEZ waKhLYd7SL/17nfyGAi5Aqf+GgfSgkwXqOExSg4V6jMqo= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 Precedence: bulk List-ID: X-Mailing-List: linux-efi@vger.kernel.org Treat device tree data in the same way as we treat ACPI tables: discover them from the EFI configuration table array, and parse the properties that describe hardware. This means we omit /chosen and the /memory nodes, which carry information that we should be receiving from EFI. not from the device tree. On the non-EFI boot path, parse the DT passed via the boot entrypoint as usual: things like bootargs, initrd and other bootloader generated data are all loaded from the DT /chosen node, along with memory descriptions and other things we would otherwise get from EFI. Note that this approach is similar to x86, which also supports FDT for hardware descriptions but not for boottime generated data. Signed-off-by: Ard Biesheuvel --- arch/loongarch/Kconfig | 2 ++ arch/loongarch/kernel/efi.c | 14 ++++++++++++++ arch/loongarch/kernel/env.c | 6 ++++++ 3 files changed, 22 insertions(+) diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 14a2a1ec8561..721b1dc38bdf 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -104,6 +104,8 @@ config LOONGARCH select MODULES_USE_ELF_RELA if MODULES select NEED_PER_CPU_EMBED_FIRST_CHUNK select NEED_PER_CPU_PAGE_FIRST_CHUNK + select OF + select OF_EARLY_FLATTREE select PCI select PCI_DOMAINS_GENERIC select PCI_ECAM if ACPI diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index 3b80675726ec..96c8621da2ba 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -28,10 +29,12 @@ static unsigned long efi_nr_tables; static unsigned long efi_config_table; static unsigned long __initdata boot_memmap = EFI_INVALID_TABLE_ADDR; +static unsigned long __initdata boot_fdt = EFI_INVALID_TABLE_ADDR; static efi_system_table_t *efi_systab; static efi_config_table_type_t arch_tables[] __initdata = { {LINUX_EFI_BOOT_MEMMAP_GUID, &boot_memmap, "MEMMAP" }, + {DEVICE_TREE_GUID, &boot_fdt, "FDT" }, {}, }; @@ -100,4 +103,15 @@ void __init efi_init(void) early_memunmap(tbl, sizeof(*tbl)); } } + + if (boot_fdt != EFI_INVALID_TABLE_ADDR) { + void *tbl; + + tbl = early_memremap_ro(boot_fdt, sizeof(*tbl)); + if (tbl) { + early_init_dt_verify(tbl); + early_init_dt_scan_root(); + early_init_fdt_reserve_self(); + } + } } diff --git a/arch/loongarch/kernel/env.c b/arch/loongarch/kernel/env.c index 05c38d28476e..3267063df1f9 100644 --- a/arch/loongarch/kernel/env.c +++ b/arch/loongarch/kernel/env.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,11 @@ void __init init_environ(void) efi_system_table = fw_arg1; set_bit(EFI_BOOT, &efi.flags); } else { + void *fdt_ptr = early_memremap_ro(fw_arg1, SZ_64K); + + early_init_dt_scan(fdt_ptr); + early_init_fdt_reserve_self(); + clear_bit(EFI_BOOT, &efi.flags); } }