All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] efi: disentangle the generic EFI stub from FDT
@ 2022-09-18 21:35 Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 01/12] efi: libstub: drop pointless get_memory_map() call Ard Biesheuvel
                   ` (11 more replies)
  0 siblings, 12 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

EFI architectures other than x86 rely on FDT to pass information between
the stub and the core kernel. In hindsight, this is probably a mistake,
given the issues around abuse of the internal ABI, and potential
inconsistencies between two sources of information that both originate
in the firmware (memory map, command line, etc)

Another reason for avoiding updates to the DT is the fact that it
interferes with secure boot and measured boot. Even if we measure the
original firmware provided DT into the TPM, the DT that the kernel
receives is a completely different blob, and verifying it against the
TPM event log is currently impossible.

So let's start hacking away at this, and refactor the generic stub so
that all the FDT pieces are isolated in a singe source file, and rely on
generic EFI config tables for passing the initrd base and size.
Ultimately, this should permit all EFI architectures doing DT boot to
perform the handover to the core kernel in a different way, and pass on
the firmware provided DT unmodified, but this requires some future work
for ARM/arm64 and RISC-V.

However, we can easily convert the newly added LoongArch code to adopt
this approach, and to consume the DT strictly for hardware descriptions
(if not doing ACPI boot), and pass the initrd, memory map and everything
else via EFI config tables. Generating empty DTBs on ACPI platforms will
no longer be needed.

The first six patches as well as patch #10 are general cleanup, and can
be merged separately. The remaining patches refactor the FDT code in the
EFI stub so that we can avoid it on platforms that don't need it for
other reasons. Finally, LoongArch is updated to use DT only for hardware
descriptions when doing EFI boot.

Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Cc: Huacai Chen <chenhuacai@loongson.cn>
Cc: Xi Ruoyao <xry111@xry111.site>

Ard Biesheuvel (12):
  efi: libstub: drop pointless get_memory_map() call
  efi/arm: libstub: move ARM specific code out of generic routines
  efi: libstub: fix up the last remaining open coded boot service call
  efi: libstub: fix type confusion for load_options_size
  efi: libstub: avoid efi_get_memory_map() for allocating the virt map
  efi: libstub: simplify efi_get_memory_map() and struct efi_boot_memmap
  efi: libstub: unify initrd loading between architectures
  efi: libstub: remove DT dependency from generic stub
  efi: libstub: install boot-time memory map as config table
  efi: libstub: remove pointless goto kludge
  efi/loongarch: libstub: remove dependency on flattened DT
  efi: loongarch: add support for DT hardware descriptions

 Documentation/arm/uefi.rst                     |   4 -
 arch/arm/include/asm/efi.h                     |   3 +-
 arch/arm/kernel/efi.c                          |  79 +++++++++
 arch/arm/kernel/setup.c                        |   2 +-
 arch/loongarch/Kconfig                         |   1 -
 arch/loongarch/include/asm/bootinfo.h          |   2 +-
 arch/loongarch/kernel/efi.c                    |  44 ++++-
 arch/loongarch/kernel/env.c                    |  24 +--
 arch/loongarch/kernel/head.S                   |   2 +
 arch/loongarch/kernel/setup.c                  |   4 +-
 drivers/firmware/efi/efi-init.c                |  61 +------
 drivers/firmware/efi/efi.c                     |  15 ++
 drivers/firmware/efi/libstub/Makefile          |  13 +-
 drivers/firmware/efi/libstub/arm64-stub.c      |  19 +--
 drivers/firmware/efi/libstub/efi-stub-helper.c | 127 +++++++-------
 drivers/firmware/efi/libstub/efi-stub.c        |  94 ++++-------
 drivers/firmware/efi/libstub/efistub.h         |  32 +---
 drivers/firmware/efi/libstub/fdt.c             | 175 +++++++++++---------
 drivers/firmware/efi/libstub/loongarch-stub.c  |  56 ++++++-
 drivers/firmware/efi/libstub/mem.c             |  85 +++++-----
 drivers/firmware/efi/libstub/randomalloc.c     |  25 +--
 drivers/firmware/efi/libstub/relocate.c        |  21 +--
 drivers/firmware/efi/libstub/x86-stub.c        |  30 +---
 include/linux/efi.h                            |  15 ++
 24 files changed, 492 insertions(+), 441 deletions(-)

-- 
2.35.1


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 01/12] efi: libstub: drop pointless get_memory_map() call
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 02/12] efi/arm: libstub: move ARM specific code out of generic routines Ard Biesheuvel
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao, stable

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: <stable@vger.kernel.org> # v4.14+
Fixes: 24d7c494ce46 ("efi/arm-stub: Round up FDT allocation to mapping size")
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 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);
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 02/12] efi/arm: libstub: move ARM specific code out of generic routines
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 01/12] efi: libstub: drop pointless get_memory_map() call Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 03/12] efi: libstub: fix up the last remaining open coded boot service call Ard Biesheuvel
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

Move some code that is only reachable when IS_ENABLED(CONFIG_ARM) into
the ARM EFI arch code.

Cc: Russell King <linux@armlinux.org.uk>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 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 <linux/efi.h>
+#include <linux/memblock.h>
 #include <asm/efi.h>
 #include <asm/mach/map.h>
 #include <asm/mmu_context.h>
@@ -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
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 03/12] efi: libstub: fix up the last remaining open coded boot service call
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 01/12] efi: libstub: drop pointless get_memory_map() call Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 02/12] efi/arm: libstub: move ARM specific code out of generic routines Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 04/12] efi: libstub: fix type confusion for load_options_size Ard Biesheuvel
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

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 <ardb@kernel.org>
---
 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;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 04/12] efi: libstub: fix type confusion for load_options_size
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
                   ` (2 preceding siblings ...)
  2022-09-18 21:35 ` [PATCH 03/12] efi: libstub: fix up the last remaining open coded boot service call Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 05/12] efi: libstub: avoid efi_get_memory_map() for allocating the virt map Ard Biesheuvel
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

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 <ardb@kernel.org>
---
 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);
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 05/12] efi: libstub: avoid efi_get_memory_map() for allocating the virt map
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
                   ` (3 preceding siblings ...)
  2022-09-18 21:35 ` [PATCH 04/12] efi: libstub: fix type confusion for load_options_size Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 06/12] efi: libstub: simplify efi_get_memory_map() and struct efi_boot_memmap Ard Biesheuvel
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

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 <ardb@kernel.org>
---
 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;
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 06/12] efi: libstub: simplify efi_get_memory_map() and struct efi_boot_memmap
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
                   ` (4 preceding siblings ...)
  2022-09-18 21:35 ` [PATCH 05/12] efi: libstub: avoid efi_get_memory_map() for allocating the virt map Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 07/12] efi: libstub: unify initrd loading between architectures Ard Biesheuvel
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

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 <ardb@kernel.org>
---
 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		= &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
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 07/12] efi: libstub: unify initrd loading between architectures
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
                   ` (5 preceding siblings ...)
  2022-09-18 21:35 ` [PATCH 06/12] efi: libstub: simplify efi_get_memory_map() and struct efi_boot_memmap Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 08/12] efi: libstub: remove DT dependency from generic stub Ard Biesheuvel
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

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 <ardb@kernel.org>
---
 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 <linux/device.h>
 #include <linux/efi.h>
 #include <linux/of.h>
+#include <linux/initrd.h>
 #include <linux/io.h>
 #include <linux/kexec.h>
 #include <linux/platform_device.h>
@@ -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)
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 08/12] efi: libstub: remove DT dependency from generic stub
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
                   ` (6 preceding siblings ...)
  2022-09-18 21:35 ` [PATCH 07/12] efi: libstub: unify initrd loading between architectures Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 09/12] efi: libstub: install boot-time memory map as config table Ard Biesheuvel
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

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 <ardb@kernel.org>
---
 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 <linux/efi.h>
-#include <linux/libfdt.h>
 #include <asm/efi.h>
 
 #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;
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 09/12] efi: libstub: install boot-time memory map as config table
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
                   ` (7 preceding siblings ...)
  2022-09-18 21:35 ` [PATCH 08/12] efi: libstub: remove DT dependency from generic stub Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  2022-09-20 10:40   ` Joey Gouly
  2022-09-18 21:35 ` [PATCH 10/12] efi: libstub: remove pointless goto kludge Ard Biesheuvel
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

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 <ardb@kernel.org>
---
 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)
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 10/12] efi: libstub: remove pointless goto kludge
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
                   ` (8 preceding siblings ...)
  2022-09-18 21:35 ` [PATCH 09/12] efi: libstub: install boot-time memory map as config table Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT Ard Biesheuvel
  2022-09-18 21:35 ` [PATCH 12/12] efi: loongarch: add support for DT hardware descriptions Ard Biesheuvel
  11 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

Remove some goto cruft that serves no purpose and obfuscates the code.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 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;
 }
 
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
                   ` (9 preceding siblings ...)
  2022-09-18 21:35 ` [PATCH 10/12] efi: libstub: remove pointless goto kludge Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  2022-09-19  1:58   ` Huacai Chen
  2022-09-18 21:35 ` [PATCH 12/12] efi: loongarch: add support for DT hardware descriptions Ard Biesheuvel
  11 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

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 <ardb@kernel.org>
---
 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 <linux/efi.h>
 #include <linux/export.h>
 #include <linux/memblock.h>
-#include <linux/of_fdt.h>
 #include <asm/early_ioremap.h>
 #include <asm/bootinfo.h>
 #include <asm/loongson.h>
@@ -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 <asm/addrspace.h>
 #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);
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH 12/12] efi: loongarch: add support for DT hardware descriptions
  2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
                   ` (10 preceding siblings ...)
  2022-09-18 21:35 ` [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT Ard Biesheuvel
@ 2022-09-18 21:35 ` Ard Biesheuvel
  11 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-18 21:35 UTC (permalink / raw)
  To: linux-efi
  Cc: loongarch, linux, Ard Biesheuvel, Arnd Bergmann,
	Ilias Apalodimas, Huacai Chen, Xi Ruoyao

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 <ardb@kernel.org>
---
 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 <linux/io.h>
 #include <linux/kobject.h>
 #include <linux/memblock.h>
+#include <linux/of_fdt.h>
 #include <linux/reboot.h>
 #include <linux/uaccess.h>
 
@@ -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 <linux/efi.h>
 #include <linux/export.h>
 #include <linux/memblock.h>
+#include <linux/of_fdt.h>
 #include <asm/early_ioremap.h>
 #include <asm/bootinfo.h>
 #include <asm/loongson.h>
@@ -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);
 	}
 }
-- 
2.35.1


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-18 21:35 ` [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT Ard Biesheuvel
@ 2022-09-19  1:58   ` Huacai Chen
  2022-09-19  5:15     ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-19  1:58 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

Hi, Ard,

I think the parameters passed to the core kernel need to be discussed.
The old way (so-called old world):
a0=argc, a1=argv, a1=bpi

The current way (so-called new world):
a0=efi boot flag, a1=fdt pointer

The new way (in this patchset):
a0=efi boot flag, a1=systemtable, a2=cmdline

I prefer to use the current way, there are 3 reasons:
1, both acpi system and dt system can use the same parameters passing method;
2, arm64, riscv and loongarch can use similar logics (light FDT);
3, out-of-tree patches can make compatibility with the old world
easier by just judging whether a2 is zero.

Huacai

On Mon, Sep 19, 2022 at 5:36 AM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> 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 <ardb@kernel.org>
> ---
>  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 <linux/efi.h>
>  #include <linux/export.h>
>  #include <linux/memblock.h>
> -#include <linux/of_fdt.h>
>  #include <asm/early_ioremap.h>
>  #include <asm/bootinfo.h>
>  #include <asm/loongson.h>
> @@ -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 <asm/addrspace.h>
>  #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);
>  }
> --
> 2.35.1
>
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19  1:58   ` Huacai Chen
@ 2022-09-19  5:15     ` Ard Biesheuvel
  2022-09-19  6:06       ` Huacai Chen
  0 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-19  5:15 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
>
> Hi, Ard,
>
> I think the parameters passed to the core kernel need to be discussed.
> The old way (so-called old world):
> a0=argc, a1=argv, a1=bpi
>
> The current way (so-called new world):
> a0=efi boot flag, a1=fdt pointer
>
> The new way (in this patchset):
> a0=efi boot flag, a1=systemtable, a2=cmdline
>
> I prefer to use the current way, there are 3 reasons:
> 1, both acpi system and dt system can use the same parameters passing method;

DT systems will use this too. The distinction is between EFI boot and
non-EFI boot. We *really* should keep these separate, given the
experience on ARM, where other projects invent ways to pass those
values to the kernel without going through the stub.

> 2, arm64, riscv and loongarch can use similar logics (light FDT);

No need to repeat a mistake. I intend to fix RISC-V next.

> 3, out-of-tree patches can make compatibility with the old world
> easier by just judging whether a2 is zero.
>

The whole point of this series is that the EFI stub should not be
touching the DT at all. In other words, there is no DT pointer, so the
current method needs to be revised.

What we might do is

a0=systemtable, a1=cmdline

as any non-zero value is treated as logic true. That way, your logic
to test a2 is zero will still work.


>
> On Mon, Sep 19, 2022 at 5:36 AM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > 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 <ardb@kernel.org>
> > ---
> >  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 <linux/efi.h>
> >  #include <linux/export.h>
> >  #include <linux/memblock.h>
> > -#include <linux/of_fdt.h>
> >  #include <asm/early_ioremap.h>
> >  #include <asm/bootinfo.h>
> >  #include <asm/loongson.h>
> > @@ -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 <asm/addrspace.h>
> >  #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);
> >  }
> > --
> > 2.35.1
> >
> >

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19  5:15     ` Ard Biesheuvel
@ 2022-09-19  6:06       ` Huacai Chen
  2022-09-19  6:22         ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-19  6:06 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

 Hi, Ard,

On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > Hi, Ard,
> >
> > I think the parameters passed to the core kernel need to be discussed.
> > The old way (so-called old world):
> > a0=argc, a1=argv, a1=bpi
> >
> > The current way (so-called new world):
> > a0=efi boot flag, a1=fdt pointer
> >
> > The new way (in this patchset):
> > a0=efi boot flag, a1=systemtable, a2=cmdline
> >
> > I prefer to use the current way, there are 3 reasons:
> > 1, both acpi system and dt system can use the same parameters passing method;
>
> DT systems will use this too. The distinction is between EFI boot and
> non-EFI boot. We *really* should keep these separate, given the
> experience on ARM, where other projects invent ways to pass those
> values to the kernel without going through the stub.
In the last patch I see:
+               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);
So I suppose for the DT system that means a0=efi boot flag, a1=fdt
pointer, a2=cmdline? Then it is not exactly the same as the ACPI
system, but similar.

>
> > 2, arm64, riscv and loongarch can use similar logics (light FDT);
>
> No need to repeat a mistake. I intend to fix RISC-V next.
>
> > 3, out-of-tree patches can make compatibility with the old world
> > easier by just judging whether a2 is zero.
> >
>
> The whole point of this series is that the EFI stub should not be
> touching the DT at all. In other words, there is no DT pointer, so the
> current method needs to be revised.
>
> What we might do is
>
> a0=systemtable, a1=cmdline
>
> as any non-zero value is treated as logic true. That way, your logic
> to test a2 is zero will still work.
I think the efi boot flag is still needed, even boot from efistub.
Because if boot with "efi=novamap", the efi runtime should be
disabled. Then we need efi_enabled(EFI_BOOT) to be false in
efi_init().

Huacai

>
>
> >
> > On Mon, Sep 19, 2022 at 5:36 AM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > 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 <ardb@kernel.org>
> > > ---
> > >  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 <linux/efi.h>
> > >  #include <linux/export.h>
> > >  #include <linux/memblock.h>
> > > -#include <linux/of_fdt.h>
> > >  #include <asm/early_ioremap.h>
> > >  #include <asm/bootinfo.h>
> > >  #include <asm/loongson.h>
> > > @@ -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 <asm/addrspace.h>
> > >  #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);
> > >  }
> > > --
> > > 2.35.1
> > >
> > >

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19  6:06       ` Huacai Chen
@ 2022-09-19  6:22         ` Ard Biesheuvel
  2022-09-19  6:33           ` Ard Biesheuvel
  2022-09-19 10:33           ` Huacai Chen
  0 siblings, 2 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-19  6:22 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
>
>  Hi, Ard,
>
> On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > >
> > > Hi, Ard,
> > >
> > > I think the parameters passed to the core kernel need to be discussed.
> > > The old way (so-called old world):
> > > a0=argc, a1=argv, a1=bpi
> > >
> > > The current way (so-called new world):
> > > a0=efi boot flag, a1=fdt pointer
> > >
> > > The new way (in this patchset):
> > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > >
> > > I prefer to use the current way, there are 3 reasons:
> > > 1, both acpi system and dt system can use the same parameters passing method;
> >
> > DT systems will use this too. The distinction is between EFI boot and
> > non-EFI boot. We *really* should keep these separate, given the
> > experience on ARM, where other projects invent ways to pass those
> > values to the kernel without going through the stub.
> In the last patch I see:
> +               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);
> So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> system, but similar.
>

No, for non-EFI DT boot, the command line is passed via the DT, so
a0=0x0 (non-efi), a1=DT, a2=0x0

Do you intend to support non-EFI DT boot by the way?

So

a2  != 0x0 means old world
a0 != 0x0 means EFI boot, a1 is the command line
a0 == 0x0 means !EFI boot, a1 is the DT

> >
> > > 2, arm64, riscv and loongarch can use similar logics (light FDT);
> >
> > No need to repeat a mistake. I intend to fix RISC-V next.
> >
> > > 3, out-of-tree patches can make compatibility with the old world
> > > easier by just judging whether a2 is zero.
> > >
> >
> > The whole point of this series is that the EFI stub should not be
> > touching the DT at all. In other words, there is no DT pointer, so the
> > current method needs to be revised.
> >
> > What we might do is
> >
> > a0=systemtable, a1=cmdline
> >
> > as any non-zero value is treated as logic true. That way, your logic
> > to test a2 is zero will still work.
> I think the efi boot flag is still needed, even boot from efistub.
> Because if boot with "efi=novamap", the efi runtime should be
> disabled. Then we need efi_enabled(EFI_BOOT) to be false in
> efi_init().
>

I don't think it makes sense to allow efi=novamap on LoongArch, given
that we cannot make use of the runtime services that way. So in my
code, efi_novamap is set to false unconditionally.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19  6:22         ` Ard Biesheuvel
@ 2022-09-19  6:33           ` Ard Biesheuvel
  2022-09-19 10:33           ` Huacai Chen
  1 sibling, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-19  6:33 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, 19 Sept 2022 at 08:22, Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> >  Hi, Ard,
> >
> > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > > Hi, Ard,
> > > >
> > > > I think the parameters passed to the core kernel need to be discussed.
> > > > The old way (so-called old world):
> > > > a0=argc, a1=argv, a1=bpi
> > > >
> > > > The current way (so-called new world):
> > > > a0=efi boot flag, a1=fdt pointer
> > > >
> > > > The new way (in this patchset):
> > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > >
> > > > I prefer to use the current way, there are 3 reasons:
> > > > 1, both acpi system and dt system can use the same parameters passing method;
> > >
> > > DT systems will use this too. The distinction is between EFI boot and
> > > non-EFI boot. We *really* should keep these separate, given the
> > > experience on ARM, where other projects invent ways to pass those
> > > values to the kernel without going through the stub.
> > In the last patch I see:
> > +               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);
> > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > system, but similar.
> >
>
> No, for non-EFI DT boot, the command line is passed via the DT, so
> a0=0x0 (non-efi), a1=DT, a2=0x0
>
> Do you intend to support non-EFI DT boot by the way?
>
> So
>
> a2  != 0x0 means old world
> a0 != 0x0 means EFI boot, a1 is the command line
> a0 == 0x0 means !EFI boot, a1 is the DT
>

Note: the above applies if we decide to merge the EFI boolean and the
system table pointer into register #0.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19  6:22         ` Ard Biesheuvel
  2022-09-19  6:33           ` Ard Biesheuvel
@ 2022-09-19 10:33           ` Huacai Chen
  2022-09-19 10:37             ` Ard Biesheuvel
  1 sibling, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-19 10:33 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

Hi, Ard,

On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> >  Hi, Ard,
> >
> > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > > Hi, Ard,
> > > >
> > > > I think the parameters passed to the core kernel need to be discussed.
> > > > The old way (so-called old world):
> > > > a0=argc, a1=argv, a1=bpi
> > > >
> > > > The current way (so-called new world):
> > > > a0=efi boot flag, a1=fdt pointer
> > > >
> > > > The new way (in this patchset):
> > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > >
> > > > I prefer to use the current way, there are 3 reasons:
> > > > 1, both acpi system and dt system can use the same parameters passing method;
> > >
> > > DT systems will use this too. The distinction is between EFI boot and
> > > non-EFI boot. We *really* should keep these separate, given the
> > > experience on ARM, where other projects invent ways to pass those
> > > values to the kernel without going through the stub.
> > In the last patch I see:
> > +               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);
> > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > system, but similar.
> >
>
> No, for non-EFI DT boot, the command line is passed via the DT, so
> a0=0x0 (non-efi), a1=DT, a2=0x0
>
> Do you intend to support non-EFI DT boot by the way?
I think we needn't support non-EFI DT boot, so a0=efi boot flag,
a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
which looks similar to the old-world). But I have another question: is
it early enough to get DT from systemtable for DT boot (in the current
way DT is the earliest thing)?

>
> So
>
> a2  != 0x0 means old world
> a0 != 0x0 means EFI boot, a1 is the command line
> a0 == 0x0 means !EFI boot, a1 is the DT
>
> > >
> > > > 2, arm64, riscv and loongarch can use similar logics (light FDT);
> > >
> > > No need to repeat a mistake. I intend to fix RISC-V next.
> > >
> > > > 3, out-of-tree patches can make compatibility with the old world
> > > > easier by just judging whether a2 is zero.
> > > >
> > >
> > > The whole point of this series is that the EFI stub should not be
> > > touching the DT at all. In other words, there is no DT pointer, so the
> > > current method needs to be revised.
> > >
> > > What we might do is
> > >
> > > a0=systemtable, a1=cmdline
> > >
> > > as any non-zero value is treated as logic true. That way, your logic
> > > to test a2 is zero will still work.
> > I think the efi boot flag is still needed, even boot from efistub.
> > Because if boot with "efi=novamap", the efi runtime should be
> > disabled. Then we need efi_enabled(EFI_BOOT) to be false in
> > efi_init().
> >
>
> I don't think it makes sense to allow efi=novamap on LoongArch, given
> that we cannot make use of the runtime services that way. So in my
> code, efi_novamap is set to false unconditionally.
Emm, I prefer to support "efi=novamap", the core kernel has already
supported "noefi" to disable runtime, I don't want to hack
efi_novamap. So please keep the efi boot flag, thanks.

Huacai

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 10:33           ` Huacai Chen
@ 2022-09-19 10:37             ` Ard Biesheuvel
  2022-09-19 10:47               ` Huacai Chen
  0 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-19 10:37 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
>
> Hi, Ard,
>
> On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > >
> > >  Hi, Ard,
> > >
> > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > >
> > > > > Hi, Ard,
> > > > >
> > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > The old way (so-called old world):
> > > > > a0=argc, a1=argv, a1=bpi
> > > > >
> > > > > The current way (so-called new world):
> > > > > a0=efi boot flag, a1=fdt pointer
> > > > >
> > > > > The new way (in this patchset):
> > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > >
> > > > > I prefer to use the current way, there are 3 reasons:
> > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > >
> > > > DT systems will use this too. The distinction is between EFI boot and
> > > > non-EFI boot. We *really* should keep these separate, given the
> > > > experience on ARM, where other projects invent ways to pass those
> > > > values to the kernel without going through the stub.
> > > In the last patch I see:
> > > +               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);
> > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > system, but similar.
> > >
> >
> > No, for non-EFI DT boot, the command line is passed via the DT, so
> > a0=0x0 (non-efi), a1=DT, a2=0x0
> >
> > Do you intend to support non-EFI DT boot by the way?
> I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> which looks similar to the old-world).

Excellent. If non-EFI boot is not supported, we can drop the code that
deals with that.

> But I have another question: is
> it early enough to get DT from systemtable for DT boot (in the current
> way DT is the earliest thing)?
>

If you rely on DT only for the hardware description, then loading it
from efi_init() should be fine.

> >
> > So
> >
> > a2  != 0x0 means old world
> > a0 != 0x0 means EFI boot, a1 is the command line
> > a0 == 0x0 means !EFI boot, a1 is the DT
> >
> > > >
> > > > > 2, arm64, riscv and loongarch can use similar logics (light FDT);
> > > >
> > > > No need to repeat a mistake. I intend to fix RISC-V next.
> > > >
> > > > > 3, out-of-tree patches can make compatibility with the old world
> > > > > easier by just judging whether a2 is zero.
> > > > >
> > > >
> > > > The whole point of this series is that the EFI stub should not be
> > > > touching the DT at all. In other words, there is no DT pointer, so the
> > > > current method needs to be revised.
> > > >
> > > > What we might do is
> > > >
> > > > a0=systemtable, a1=cmdline
> > > >
> > > > as any non-zero value is treated as logic true. That way, your logic
> > > > to test a2 is zero will still work.
> > > I think the efi boot flag is still needed, even boot from efistub.
> > > Because if boot with "efi=novamap", the efi runtime should be
> > > disabled. Then we need efi_enabled(EFI_BOOT) to be false in
> > > efi_init().
> > >
> >
> > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > that we cannot make use of the runtime services that way. So in my
> > code, efi_novamap is set to false unconditionally.
> Emm, I prefer to support "efi=novamap", the core kernel has already
> supported "noefi" to disable runtime, I don't want to hack
> efi_novamap. So please keep the efi boot flag, thanks.
>

Fair enough. Do you have any uses for efi_novamap in mind?

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 10:37             ` Ard Biesheuvel
@ 2022-09-19 10:47               ` Huacai Chen
  2022-09-19 10:49                 ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-19 10:47 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > Hi, Ard,
> >
> > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > >  Hi, Ard,
> > > >
> > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > >
> > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > >
> > > > > > Hi, Ard,
> > > > > >
> > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > The old way (so-called old world):
> > > > > > a0=argc, a1=argv, a1=bpi
> > > > > >
> > > > > > The current way (so-called new world):
> > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > >
> > > > > > The new way (in this patchset):
> > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > >
> > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > >
> > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > experience on ARM, where other projects invent ways to pass those
> > > > > values to the kernel without going through the stub.
> > > > In the last patch I see:
> > > > +               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);
> > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > system, but similar.
> > > >
> > >
> > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > >
> > > Do you intend to support non-EFI DT boot by the way?
> > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > which looks similar to the old-world).
>
> Excellent. If non-EFI boot is not supported, we can drop the code that
> deals with that.
>
> > But I have another question: is
> > it early enough to get DT from systemtable for DT boot (in the current
> > way DT is the earliest thing)?
> >
>
> If you rely on DT only for the hardware description, then loading it
> from efi_init() should be fine.
OK, then please drop patch #12 at this time. It can be added when we
add Loongson-2K support.

>
> > >
> > > So
> > >
> > > a2  != 0x0 means old world
> > > a0 != 0x0 means EFI boot, a1 is the command line
> > > a0 == 0x0 means !EFI boot, a1 is the DT
> > >
> > > > >
> > > > > > 2, arm64, riscv and loongarch can use similar logics (light FDT);
> > > > >
> > > > > No need to repeat a mistake. I intend to fix RISC-V next.
> > > > >
> > > > > > 3, out-of-tree patches can make compatibility with the old world
> > > > > > easier by just judging whether a2 is zero.
> > > > > >
> > > > >
> > > > > The whole point of this series is that the EFI stub should not be
> > > > > touching the DT at all. In other words, there is no DT pointer, so the
> > > > > current method needs to be revised.
> > > > >
> > > > > What we might do is
> > > > >
> > > > > a0=systemtable, a1=cmdline
> > > > >
> > > > > as any non-zero value is treated as logic true. That way, your logic
> > > > > to test a2 is zero will still work.
> > > > I think the efi boot flag is still needed, even boot from efistub.
> > > > Because if boot with "efi=novamap", the efi runtime should be
> > > > disabled. Then we need efi_enabled(EFI_BOOT) to be false in
> > > > efi_init().
> > > >
> > >
> > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > that we cannot make use of the runtime services that way. So in my
> > > code, efi_novamap is set to false unconditionally.
> > Emm, I prefer to support "efi=novamap", the core kernel has already
> > supported "noefi" to disable runtime, I don't want to hack
> > efi_novamap. So please keep the efi boot flag, thanks.
> >
>
> Fair enough. Do you have any uses for efi_novamap in mind?
I usually use "efi=novamap" in EFI shell to see whether it can work
well without runtime. And I think I will modify this patch these days
because in another thread you said that this series cannot boot.

Huacai

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 10:47               ` Huacai Chen
@ 2022-09-19 10:49                 ` Ard Biesheuvel
  2022-09-19 11:15                   ` Huacai Chen
  0 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-19 10:49 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
>
> On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > >
> > > Hi, Ard,
> > >
> > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > >
> > > > >  Hi, Ard,
> > > > >
> > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > >
> > > > > > > Hi, Ard,
> > > > > > >
> > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > The old way (so-called old world):
> > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > >
> > > > > > > The current way (so-called new world):
> > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > >
> > > > > > > The new way (in this patchset):
> > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > >
> > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > >
> > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > values to the kernel without going through the stub.
> > > > > In the last patch I see:
> > > > > +               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);
> > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > system, but similar.
> > > > >
> > > >
> > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > >
> > > > Do you intend to support non-EFI DT boot by the way?
> > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > which looks similar to the old-world).
> >
> > Excellent. If non-EFI boot is not supported, we can drop the code that
> > deals with that.
> >
> > > But I have another question: is
> > > it early enough to get DT from systemtable for DT boot (in the current
> > > way DT is the earliest thing)?
> > >
> >
> > If you rely on DT only for the hardware description, then loading it
> > from efi_init() should be fine.
> OK, then please drop patch #12 at this time. It can be added when we
> add Loongson-2K support.
>

OK

> > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > that we cannot make use of the runtime services that way. So in my
> > > > code, efi_novamap is set to false unconditionally.
> > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > supported "noefi" to disable runtime, I don't want to hack
> > > efi_novamap. So please keep the efi boot flag, thanks.
> > >
> >
> > Fair enough. Do you have any uses for efi_novamap in mind?
> I usually use "efi=novamap" in EFI shell to see whether it can work
> well without runtime. And I think I will modify this patch these days
> because in another thread you said that this series cannot boot.

It works fine now.

However, clearing the EFI_BOOT flag is not the correct way to disable
runtime services only. And note that we also have efi=noruntime - does
that currently work on LoongArch?

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 10:49                 ` Ard Biesheuvel
@ 2022-09-19 11:15                   ` Huacai Chen
  2022-09-19 11:21                     ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-19 11:15 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > > Hi, Ard,
> > > >
> > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > >
> > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > >
> > > > > >  Hi, Ard,
> > > > > >
> > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > >
> > > > > > > > Hi, Ard,
> > > > > > > >
> > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > The old way (so-called old world):
> > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > >
> > > > > > > > The current way (so-called new world):
> > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > >
> > > > > > > > The new way (in this patchset):
> > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > >
> > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > >
> > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > values to the kernel without going through the stub.
> > > > > > In the last patch I see:
> > > > > > +               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);
> > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > system, but similar.
> > > > > >
> > > > >
> > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > >
> > > > > Do you intend to support non-EFI DT boot by the way?
> > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > which looks similar to the old-world).
> > >
> > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > deals with that.
> > >
> > > > But I have another question: is
> > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > way DT is the earliest thing)?
> > > >
> > >
> > > If you rely on DT only for the hardware description, then loading it
> > > from efi_init() should be fine.
> > OK, then please drop patch #12 at this time. It can be added when we
> > add Loongson-2K support.
> >
>
> OK
>
> > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > that we cannot make use of the runtime services that way. So in my
> > > > > code, efi_novamap is set to false unconditionally.
> > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > supported "noefi" to disable runtime, I don't want to hack
> > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > >
> > >
> > > Fair enough. Do you have any uses for efi_novamap in mind?
> > I usually use "efi=novamap" in EFI shell to see whether it can work
> > well without runtime. And I think I will modify this patch these days
> > because in another thread you said that this series cannot boot.
>
> It works fine now.
>
> However, clearing the EFI_BOOT flag is not the correct way to disable
> runtime services only. And note that we also have efi=noruntime - does
> that currently work on LoongArch?
OK, but we don't need to add a new "efi=noruntime" parameter, I can
use "noefi" instead. But I think support "efi=novamap" is not a bad
idea (maybe I misunderstood its usage).

Huacai

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 11:15                   ` Huacai Chen
@ 2022-09-19 11:21                     ` Ard Biesheuvel
  2022-09-19 11:57                       ` Huacai Chen
  0 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-19 11:21 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
>
> On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > >
> > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > >
> > > > > Hi, Ard,
> > > > >
> > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > >
> > > > > > >  Hi, Ard,
> > > > > > >
> > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > Hi, Ard,
> > > > > > > > >
> > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > The old way (so-called old world):
> > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > >
> > > > > > > > > The current way (so-called new world):
> > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > >
> > > > > > > > > The new way (in this patchset):
> > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > >
> > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > >
> > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > values to the kernel without going through the stub.
> > > > > > > In the last patch I see:
> > > > > > > +               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);
> > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > system, but similar.
> > > > > > >
> > > > > >
> > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > >
> > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > which looks similar to the old-world).
> > > >
> > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > deals with that.
> > > >
> > > > > But I have another question: is
> > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > way DT is the earliest thing)?
> > > > >
> > > >
> > > > If you rely on DT only for the hardware description, then loading it
> > > > from efi_init() should be fine.
> > > OK, then please drop patch #12 at this time. It can be added when we
> > > add Loongson-2K support.
> > >
> >
> > OK
> >
> > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > code, efi_novamap is set to false unconditionally.
> > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > >
> > > >
> > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > well without runtime. And I think I will modify this patch these days
> > > because in another thread you said that this series cannot boot.
> >
> > It works fine now.
> >
> > However, clearing the EFI_BOOT flag is not the correct way to disable
> > runtime services only. And note that we also have efi=noruntime - does
> > that currently work on LoongArch?
> OK, but we don't need to add a new "efi=noruntime" parameter, I can
> use "noefi" instead.

OK

> But I think support "efi=novamap" is not a bad
> idea (maybe I misunderstood its usage).
>

It basically exists to deal with broken EFI firmware on ARM laptops
that were only intended to run Windows. Windows calls
SetVirtualAddressMap() *after* creating the new mappings, and some
broken firmware drivers will access those regions too early.

On Linux, we install the mapping first, and then much later, we
actually create the mappings and only activate them on a single CPU
while the EFI runtime service call is in progress.

In any case, I will reinstate the efi_novamap logic for now - we can
always revisit it later.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 11:21                     ` Ard Biesheuvel
@ 2022-09-19 11:57                       ` Huacai Chen
  2022-09-19 12:10                         ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-19 11:57 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, Sep 19, 2022 at 7:21 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > >
> > > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > >
> > > > > > Hi, Ard,
> > > > > >
> > > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > >
> > > > > > > >  Hi, Ard,
> > > > > > > >
> > > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > Hi, Ard,
> > > > > > > > > >
> > > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > > The old way (so-called old world):
> > > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > > >
> > > > > > > > > > The current way (so-called new world):
> > > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > > >
> > > > > > > > > > The new way (in this patchset):
> > > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > > >
> > > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > > >
> > > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > > values to the kernel without going through the stub.
> > > > > > > > In the last patch I see:
> > > > > > > > +               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);
> > > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > > system, but similar.
> > > > > > > >
> > > > > > >
> > > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > > >
> > > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > > which looks similar to the old-world).
> > > > >
> > > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > > deals with that.
> > > > >
> > > > > > But I have another question: is
> > > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > > way DT is the earliest thing)?
> > > > > >
> > > > >
> > > > > If you rely on DT only for the hardware description, then loading it
> > > > > from efi_init() should be fine.
> > > > OK, then please drop patch #12 at this time. It can be added when we
> > > > add Loongson-2K support.
> > > >
> > >
> > > OK
> > >
> > > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > > code, efi_novamap is set to false unconditionally.
> > > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > > >
> > > > >
> > > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > > well without runtime. And I think I will modify this patch these days
> > > > because in another thread you said that this series cannot boot.
> > >
> > > It works fine now.
> > >
> > > However, clearing the EFI_BOOT flag is not the correct way to disable
> > > runtime services only. And note that we also have efi=noruntime - does
> > > that currently work on LoongArch?
> > OK, but we don't need to add a new "efi=noruntime" parameter, I can
> > use "noefi" instead.
>
> OK
>
> > But I think support "efi=novamap" is not a bad
> > idea (maybe I misunderstood its usage).
> >
>
> It basically exists to deal with broken EFI firmware on ARM laptops
> that were only intended to run Windows. Windows calls
> SetVirtualAddressMap() *after* creating the new mappings, and some
> broken firmware drivers will access those regions too early.
>
> On Linux, we install the mapping first, and then much later, we
> actually create the mappings and only activate them on a single CPU
> while the EFI runtime service call is in progress.
>
> In any case, I will reinstate the efi_novamap logic for now - we can
> always revisit it later.
OK, now I think there are no big problems. Only some bikesheddings:
1, Please use "a0=efi boot flag, a1=cmdline a2=systemtable" to pass
boot information, it looks most similar to the old-world, and we can
distinguish old-world/new-world by judging whether a0 is greater than
1.
2, I prefer "early return" in efi_init, i.e., if (boot_memmap ==
EFI_INVALID_TABLE_ADDR) then return immediately, this makes
indentation look better.
3, Declare "cmdline" out of the if() condition in init_environ() looks better.
4, I prefer "kernel_addr" rather than "image_addr" in efi_boot_kernel().
5, It seems that one line is enough for the last statement in efi_boot_kernel().

Hope this series will be stable as soon as possible, our kexec/kdump
work needs to adjust because of this change. :)

Huacai

>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 11:57                       ` Huacai Chen
@ 2022-09-19 12:10                         ` Ard Biesheuvel
  2022-09-19 12:14                           ` Huacai Chen
  0 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-19 12:10 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, 19 Sept 2022 at 13:58, Huacai Chen <chenhuacai@kernel.org> wrote:
>
> On Mon, Sep 19, 2022 at 7:21 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > >
> > > On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > >
> > > > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > >
> > > > > > > Hi, Ard,
> > > > > > >
> > > > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > >  Hi, Ard,
> > > > > > > > >
> > > > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > Hi, Ard,
> > > > > > > > > > >
> > > > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > > > The old way (so-called old world):
> > > > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > > > >
> > > > > > > > > > > The current way (so-called new world):
> > > > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > > > >
> > > > > > > > > > > The new way (in this patchset):
> > > > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > > > >
> > > > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > > > >
> > > > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > > > values to the kernel without going through the stub.
> > > > > > > > > In the last patch I see:
> > > > > > > > > +               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);
> > > > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > > > system, but similar.
> > > > > > > > >
> > > > > > > >
> > > > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > > > >
> > > > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > > > which looks similar to the old-world).
> > > > > >
> > > > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > > > deals with that.
> > > > > >
> > > > > > > But I have another question: is
> > > > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > > > way DT is the earliest thing)?
> > > > > > >
> > > > > >
> > > > > > If you rely on DT only for the hardware description, then loading it
> > > > > > from efi_init() should be fine.
> > > > > OK, then please drop patch #12 at this time. It can be added when we
> > > > > add Loongson-2K support.
> > > > >
> > > >
> > > > OK
> > > >
> > > > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > > > code, efi_novamap is set to false unconditionally.
> > > > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > > > >
> > > > > >
> > > > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > > > well without runtime. And I think I will modify this patch these days
> > > > > because in another thread you said that this series cannot boot.
> > > >
> > > > It works fine now.
> > > >
> > > > However, clearing the EFI_BOOT flag is not the correct way to disable
> > > > runtime services only. And note that we also have efi=noruntime - does
> > > > that currently work on LoongArch?
> > > OK, but we don't need to add a new "efi=noruntime" parameter, I can
> > > use "noefi" instead.
> >
> > OK
> >
> > > But I think support "efi=novamap" is not a bad
> > > idea (maybe I misunderstood its usage).
> > >
> >
> > It basically exists to deal with broken EFI firmware on ARM laptops
> > that were only intended to run Windows. Windows calls
> > SetVirtualAddressMap() *after* creating the new mappings, and some
> > broken firmware drivers will access those regions too early.
> >
> > On Linux, we install the mapping first, and then much later, we
> > actually create the mappings and only activate them on a single CPU
> > while the EFI runtime service call is in progress.
> >
> > In any case, I will reinstate the efi_novamap logic for now - we can
> > always revisit it later.
> OK, now I think there are no big problems. Only some bikesheddings:
> 1, Please use "a0=efi boot flag, a1=cmdline a2=systemtable" to pass
> boot information, it looks most similar to the old-world, and we can
> distinguish old-world/new-world by judging whether a0 is greater than
> 1.
> 2, I prefer "early return" in efi_init, i.e., if (boot_memmap ==
> EFI_INVALID_TABLE_ADDR) then return immediately, this makes
> indentation look better.
> 3, Declare "cmdline" out of the if() condition in init_environ() looks better.
> 4, I prefer "kernel_addr" rather than "image_addr" in efi_boot_kernel().
> 5, It seems that one line is enough for the last statement in efi_boot_kernel().
>

OK

> Hope this series will be stable as soon as possible, our kexec/kdump
> work needs to adjust because of this change. :)
>

Do you have a link to those patches?

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 12:10                         ` Ard Biesheuvel
@ 2022-09-19 12:14                           ` Huacai Chen
  2022-09-19 12:27                             ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-19 12:14 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, Sep 19, 2022 at 8:11 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 19 Sept 2022 at 13:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > On Mon, Sep 19, 2022 at 7:21 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > > On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > >
> > > > > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > >
> > > > > > > > Hi, Ard,
> > > > > > > >
> > > > > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > >  Hi, Ard,
> > > > > > > > > >
> > > > > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > >
> > > > > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > > > > The old way (so-called old world):
> > > > > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > > > > >
> > > > > > > > > > > > The current way (so-called new world):
> > > > > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > > > > >
> > > > > > > > > > > > The new way (in this patchset):
> > > > > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > > > > >
> > > > > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > > > > >
> > > > > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > > > > values to the kernel without going through the stub.
> > > > > > > > > > In the last patch I see:
> > > > > > > > > > +               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);
> > > > > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > > > > system, but similar.
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > > > > >
> > > > > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > > > > which looks similar to the old-world).
> > > > > > >
> > > > > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > > > > deals with that.
> > > > > > >
> > > > > > > > But I have another question: is
> > > > > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > > > > way DT is the earliest thing)?
> > > > > > > >
> > > > > > >
> > > > > > > If you rely on DT only for the hardware description, then loading it
> > > > > > > from efi_init() should be fine.
> > > > > > OK, then please drop patch #12 at this time. It can be added when we
> > > > > > add Loongson-2K support.
> > > > > >
> > > > >
> > > > > OK
> > > > >
> > > > > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > > > > code, efi_novamap is set to false unconditionally.
> > > > > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > > > > >
> > > > > > >
> > > > > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > > > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > > > > well without runtime. And I think I will modify this patch these days
> > > > > > because in another thread you said that this series cannot boot.
> > > > >
> > > > > It works fine now.
> > > > >
> > > > > However, clearing the EFI_BOOT flag is not the correct way to disable
> > > > > runtime services only. And note that we also have efi=noruntime - does
> > > > > that currently work on LoongArch?
> > > > OK, but we don't need to add a new "efi=noruntime" parameter, I can
> > > > use "noefi" instead.
> > >
> > > OK
> > >
> > > > But I think support "efi=novamap" is not a bad
> > > > idea (maybe I misunderstood its usage).
> > > >
> > >
> > > It basically exists to deal with broken EFI firmware on ARM laptops
> > > that were only intended to run Windows. Windows calls
> > > SetVirtualAddressMap() *after* creating the new mappings, and some
> > > broken firmware drivers will access those regions too early.
> > >
> > > On Linux, we install the mapping first, and then much later, we
> > > actually create the mappings and only activate them on a single CPU
> > > while the EFI runtime service call is in progress.
> > >
> > > In any case, I will reinstate the efi_novamap logic for now - we can
> > > always revisit it later.
> > OK, now I think there are no big problems. Only some bikesheddings:
> > 1, Please use "a0=efi boot flag, a1=cmdline a2=systemtable" to pass
> > boot information, it looks most similar to the old-world, and we can
> > distinguish old-world/new-world by judging whether a0 is greater than
> > 1.
> > 2, I prefer "early return" in efi_init, i.e., if (boot_memmap ==
> > EFI_INVALID_TABLE_ADDR) then return immediately, this makes
> > indentation look better.
> > 3, Declare "cmdline" out of the if() condition in init_environ() looks better.
> > 4, I prefer "kernel_addr" rather than "image_addr" in efi_boot_kernel().
> > 5, It seems that one line is enough for the last statement in efi_boot_kernel().
> >
>
> OK
>
> > Hope this series will be stable as soon as possible, our kexec/kdump
> > work needs to adjust because of this change. :)
> >
>
> Do you have a link to those patches?
There is a snapshot for patches pending for 6.1:
https://github.com/loongson/linux/commits/loongarch-next

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 12:14                           ` Huacai Chen
@ 2022-09-19 12:27                             ` Ard Biesheuvel
  2022-09-19 14:25                               ` Huacai Chen
  0 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-19 12:27 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, 19 Sept 2022 at 14:15, Huacai Chen <chenhuacai@kernel.org> wrote:
>
> On Mon, Sep 19, 2022 at 8:11 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Mon, 19 Sept 2022 at 13:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > >
> > > On Mon, Sep 19, 2022 at 7:21 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > >
> > > > > On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > Hi, Ard,
> > > > > > > > >
> > > > > > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > >  Hi, Ard,
> > > > > > > > > > >
> > > > > > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > >
> > > > > > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > > > > > The old way (so-called old world):
> > > > > > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > > > > > >
> > > > > > > > > > > > > The current way (so-called new world):
> > > > > > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > > > > > >
> > > > > > > > > > > > > The new way (in this patchset):
> > > > > > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > > > > > >
> > > > > > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > > > > > >
> > > > > > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > > > > > values to the kernel without going through the stub.
> > > > > > > > > > > In the last patch I see:
> > > > > > > > > > > +               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);
> > > > > > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > > > > > system, but similar.
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > > > > > >
> > > > > > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > > > > > which looks similar to the old-world).
> > > > > > > >
> > > > > > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > > > > > deals with that.
> > > > > > > >
> > > > > > > > > But I have another question: is
> > > > > > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > > > > > way DT is the earliest thing)?
> > > > > > > > >
> > > > > > > >
> > > > > > > > If you rely on DT only for the hardware description, then loading it
> > > > > > > > from efi_init() should be fine.
> > > > > > > OK, then please drop patch #12 at this time. It can be added when we
> > > > > > > add Loongson-2K support.
> > > > > > >
> > > > > >
> > > > > > OK
> > > > > >
> > > > > > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > > > > > code, efi_novamap is set to false unconditionally.
> > > > > > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > > > > > >
> > > > > > > >
> > > > > > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > > > > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > > > > > well without runtime. And I think I will modify this patch these days
> > > > > > > because in another thread you said that this series cannot boot.
> > > > > >
> > > > > > It works fine now.
> > > > > >
> > > > > > However, clearing the EFI_BOOT flag is not the correct way to disable
> > > > > > runtime services only. And note that we also have efi=noruntime - does
> > > > > > that currently work on LoongArch?
> > > > > OK, but we don't need to add a new "efi=noruntime" parameter, I can
> > > > > use "noefi" instead.
> > > >
> > > > OK
> > > >
> > > > > But I think support "efi=novamap" is not a bad
> > > > > idea (maybe I misunderstood its usage).
> > > > >
> > > >
> > > > It basically exists to deal with broken EFI firmware on ARM laptops
> > > > that were only intended to run Windows. Windows calls
> > > > SetVirtualAddressMap() *after* creating the new mappings, and some
> > > > broken firmware drivers will access those regions too early.
> > > >
> > > > On Linux, we install the mapping first, and then much later, we
> > > > actually create the mappings and only activate them on a single CPU
> > > > while the EFI runtime service call is in progress.
> > > >
> > > > In any case, I will reinstate the efi_novamap logic for now - we can
> > > > always revisit it later.
> > > OK, now I think there are no big problems. Only some bikesheddings:
> > > 1, Please use "a0=efi boot flag, a1=cmdline a2=systemtable" to pass
> > > boot information, it looks most similar to the old-world, and we can
> > > distinguish old-world/new-world by judging whether a0 is greater than
> > > 1.
> > > 2, I prefer "early return" in efi_init, i.e., if (boot_memmap ==
> > > EFI_INVALID_TABLE_ADDR) then return immediately, this makes
> > > indentation look better.
> > > 3, Declare "cmdline" out of the if() condition in init_environ() looks better.
> > > 4, I prefer "kernel_addr" rather than "image_addr" in efi_boot_kernel().
> > > 5, It seems that one line is enough for the last statement in efi_boot_kernel().
> > >
> >
> > OK
> >
> > > Hope this series will be stable as soon as possible, our kexec/kdump
> > > work needs to adjust because of this change. :)
> > >
> >
> > Do you have a link to those patches?
> There is a snapshot for patches pending for 6.1:
> https://github.com/loongson/linux/commits/loongarch-next

Thanks. I already spotted an issue there which is exactly the kind of
thing I am trying to avoid with this series.

diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c
index 7423361b0ebc9b..c68c88e40cc0b9 100644
--- a/arch/loongarch/kernel/mem.c
+++ b/arch/loongarch/kernel/mem.c
@@ -61,4 +62,9 @@ void __init memblock_init(void)

  /* Reserve the initrd */
  reserve_initrd_mem();
+
+ /* Main reserved memory for the elf core head */
+ early_init_fdt_scan_reserved_mem();
+ /* Parse linux,usable-memory-range for crash dump kernel */
+ early_init_dt_check_for_usable_mem_range();
 }

So here, we are adding support for DT memory reservations, which kdump
apparently needs.

However, this parsing of the DT not only happens on kexec boot: all
ACPI and DT kernels will now honour FDT memory reservations passed in
via a DT when booting the first kernel, and external projects may use
this and start to depend on this.

Once something like this hits the upstream kernel, it is *very*
difficult to change or remove.

If you only need to pass the usable memory range for kcrash/kdump,
it's probably better to use a command line option for that, instead of
relying on DT memory reservations.

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 12:27                             ` Ard Biesheuvel
@ 2022-09-19 14:25                               ` Huacai Chen
  2022-09-19 14:32                                 ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-19 14:25 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

Hi, Ard,

On Mon, Sep 19, 2022 at 8:27 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 19 Sept 2022 at 14:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > On Mon, Sep 19, 2022 at 8:11 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Mon, 19 Sept 2022 at 13:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > > On Mon, Sep 19, 2022 at 7:21 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > >
> > > > > On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > Hi, Ard,
> > > > > > > > > >
> > > > > > > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > >  Hi, Ard,
> > > > > > > > > > > >
> > > > > > > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > > > > > > The old way (so-called old world):
> > > > > > > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > The current way (so-called new world):
> > > > > > > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > The new way (in this patchset):
> > > > > > > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > > > > > > >
> > > > > > > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > > > > > > values to the kernel without going through the stub.
> > > > > > > > > > > > In the last patch I see:
> > > > > > > > > > > > +               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);
> > > > > > > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > > > > > > system, but similar.
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > > > > > > >
> > > > > > > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > > > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > > > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > > > > > > which looks similar to the old-world).
> > > > > > > > >
> > > > > > > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > > > > > > deals with that.
> > > > > > > > >
> > > > > > > > > > But I have another question: is
> > > > > > > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > > > > > > way DT is the earliest thing)?
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > If you rely on DT only for the hardware description, then loading it
> > > > > > > > > from efi_init() should be fine.
> > > > > > > > OK, then please drop patch #12 at this time. It can be added when we
> > > > > > > > add Loongson-2K support.
> > > > > > > >
> > > > > > >
> > > > > > > OK
> > > > > > >
> > > > > > > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > > > > > > code, efi_novamap is set to false unconditionally.
> > > > > > > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > > > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > > > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > > > > > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > > > > > > well without runtime. And I think I will modify this patch these days
> > > > > > > > because in another thread you said that this series cannot boot.
> > > > > > >
> > > > > > > It works fine now.
> > > > > > >
> > > > > > > However, clearing the EFI_BOOT flag is not the correct way to disable
> > > > > > > runtime services only. And note that we also have efi=noruntime - does
> > > > > > > that currently work on LoongArch?
> > > > > > OK, but we don't need to add a new "efi=noruntime" parameter, I can
> > > > > > use "noefi" instead.
> > > > >
> > > > > OK
> > > > >
> > > > > > But I think support "efi=novamap" is not a bad
> > > > > > idea (maybe I misunderstood its usage).
> > > > > >
> > > > >
> > > > > It basically exists to deal with broken EFI firmware on ARM laptops
> > > > > that were only intended to run Windows. Windows calls
> > > > > SetVirtualAddressMap() *after* creating the new mappings, and some
> > > > > broken firmware drivers will access those regions too early.
> > > > >
> > > > > On Linux, we install the mapping first, and then much later, we
> > > > > actually create the mappings and only activate them on a single CPU
> > > > > while the EFI runtime service call is in progress.
> > > > >
> > > > > In any case, I will reinstate the efi_novamap logic for now - we can
> > > > > always revisit it later.
> > > > OK, now I think there are no big problems. Only some bikesheddings:
> > > > 1, Please use "a0=efi boot flag, a1=cmdline a2=systemtable" to pass
> > > > boot information, it looks most similar to the old-world, and we can
> > > > distinguish old-world/new-world by judging whether a0 is greater than
> > > > 1.
> > > > 2, I prefer "early return" in efi_init, i.e., if (boot_memmap ==
> > > > EFI_INVALID_TABLE_ADDR) then return immediately, this makes
> > > > indentation look better.
> > > > 3, Declare "cmdline" out of the if() condition in init_environ() looks better.
> > > > 4, I prefer "kernel_addr" rather than "image_addr" in efi_boot_kernel().
> > > > 5, It seems that one line is enough for the last statement in efi_boot_kernel().
> > > >
> > >
> > > OK
> > >
> > > > Hope this series will be stable as soon as possible, our kexec/kdump
> > > > work needs to adjust because of this change. :)
> > > >
> > >
> > > Do you have a link to those patches?
> > There is a snapshot for patches pending for 6.1:
> > https://github.com/loongson/linux/commits/loongarch-next
>
> Thanks. I already spotted an issue there which is exactly the kind of
> thing I am trying to avoid with this series.
>
> diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c
> index 7423361b0ebc9b..c68c88e40cc0b9 100644
> --- a/arch/loongarch/kernel/mem.c
> +++ b/arch/loongarch/kernel/mem.c
> @@ -61,4 +62,9 @@ void __init memblock_init(void)
>
>   /* Reserve the initrd */
>   reserve_initrd_mem();
> +
> + /* Main reserved memory for the elf core head */
> + early_init_fdt_scan_reserved_mem();
> + /* Parse linux,usable-memory-range for crash dump kernel */
> + early_init_dt_check_for_usable_mem_range();
>  }
>
> So here, we are adding support for DT memory reservations, which kdump
> apparently needs.
>
> However, this parsing of the DT not only happens on kexec boot: all
> ACPI and DT kernels will now honour FDT memory reservations passed in
> via a DT when booting the first kernel, and external projects may use
> this and start to depend on this.
>
> Once something like this hits the upstream kernel, it is *very*
> difficult to change or remove.
>
> If you only need to pass the usable memory range for kcrash/kdump,
> it's probably better to use a command line option for that, instead of
> relying on DT memory reservations.
Thank you for your suggestion, but we found some trouble when handle
initrd in kexec.
In current implementation, we generate a fdt in kexec-tools, then fill
"linux,usable-memory-range", "linux,elfcorehdr" and initrd information
in it. After this series, we can use "mem=xxx" "elfcorehdr=" in
cmdline, but how to handle initrd information which is stored in a
system table?

Huacai

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 14:25                               ` Huacai Chen
@ 2022-09-19 14:32                                 ` Ard Biesheuvel
  2022-09-19 14:43                                   ` Huacai Chen
  0 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-19 14:32 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, 19 Sept 2022 at 16:25, Huacai Chen <chenhuacai@kernel.org> wrote:
>
> Hi, Ard,
>
> On Mon, Sep 19, 2022 at 8:27 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Mon, 19 Sept 2022 at 14:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > >
> > > On Mon, Sep 19, 2022 at 8:11 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > On Mon, 19 Sept 2022 at 13:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > >
> > > > > On Mon, Sep 19, 2022 at 7:21 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > Hi, Ard,
> > > > > > > > > > >
> > > > > > > > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > >  Hi, Ard,
> > > > > > > > > > > > >
> > > > > > > > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > > > > > > > The old way (so-called old world):
> > > > > > > > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > The current way (so-called new world):
> > > > > > > > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > The new way (in this patchset):
> > > > > > > > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > > > > > > > values to the kernel without going through the stub.
> > > > > > > > > > > > > In the last patch I see:
> > > > > > > > > > > > > +               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);
> > > > > > > > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > > > > > > > system, but similar.
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > > > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > > > > > > > >
> > > > > > > > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > > > > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > > > > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > > > > > > > which looks similar to the old-world).
> > > > > > > > > >
> > > > > > > > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > > > > > > > deals with that.
> > > > > > > > > >
> > > > > > > > > > > But I have another question: is
> > > > > > > > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > > > > > > > way DT is the earliest thing)?
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > If you rely on DT only for the hardware description, then loading it
> > > > > > > > > > from efi_init() should be fine.
> > > > > > > > > OK, then please drop patch #12 at this time. It can be added when we
> > > > > > > > > add Loongson-2K support.
> > > > > > > > >
> > > > > > > >
> > > > > > > > OK
> > > > > > > >
> > > > > > > > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > > > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > > > > > > > code, efi_novamap is set to false unconditionally.
> > > > > > > > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > > > > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > > > > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > > > > > > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > > > > > > > well without runtime. And I think I will modify this patch these days
> > > > > > > > > because in another thread you said that this series cannot boot.
> > > > > > > >
> > > > > > > > It works fine now.
> > > > > > > >
> > > > > > > > However, clearing the EFI_BOOT flag is not the correct way to disable
> > > > > > > > runtime services only. And note that we also have efi=noruntime - does
> > > > > > > > that currently work on LoongArch?
> > > > > > > OK, but we don't need to add a new "efi=noruntime" parameter, I can
> > > > > > > use "noefi" instead.
> > > > > >
> > > > > > OK
> > > > > >
> > > > > > > But I think support "efi=novamap" is not a bad
> > > > > > > idea (maybe I misunderstood its usage).
> > > > > > >
> > > > > >
> > > > > > It basically exists to deal with broken EFI firmware on ARM laptops
> > > > > > that were only intended to run Windows. Windows calls
> > > > > > SetVirtualAddressMap() *after* creating the new mappings, and some
> > > > > > broken firmware drivers will access those regions too early.
> > > > > >
> > > > > > On Linux, we install the mapping first, and then much later, we
> > > > > > actually create the mappings and only activate them on a single CPU
> > > > > > while the EFI runtime service call is in progress.
> > > > > >
> > > > > > In any case, I will reinstate the efi_novamap logic for now - we can
> > > > > > always revisit it later.
> > > > > OK, now I think there are no big problems. Only some bikesheddings:
> > > > > 1, Please use "a0=efi boot flag, a1=cmdline a2=systemtable" to pass
> > > > > boot information, it looks most similar to the old-world, and we can
> > > > > distinguish old-world/new-world by judging whether a0 is greater than
> > > > > 1.
> > > > > 2, I prefer "early return" in efi_init, i.e., if (boot_memmap ==
> > > > > EFI_INVALID_TABLE_ADDR) then return immediately, this makes
> > > > > indentation look better.
> > > > > 3, Declare "cmdline" out of the if() condition in init_environ() looks better.
> > > > > 4, I prefer "kernel_addr" rather than "image_addr" in efi_boot_kernel().
> > > > > 5, It seems that one line is enough for the last statement in efi_boot_kernel().
> > > > >
> > > >
> > > > OK
> > > >
> > > > > Hope this series will be stable as soon as possible, our kexec/kdump
> > > > > work needs to adjust because of this change. :)
> > > > >
> > > >
> > > > Do you have a link to those patches?
> > > There is a snapshot for patches pending for 6.1:
> > > https://github.com/loongson/linux/commits/loongarch-next
> >
> > Thanks. I already spotted an issue there which is exactly the kind of
> > thing I am trying to avoid with this series.
> >
> > diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c
> > index 7423361b0ebc9b..c68c88e40cc0b9 100644
> > --- a/arch/loongarch/kernel/mem.c
> > +++ b/arch/loongarch/kernel/mem.c
> > @@ -61,4 +62,9 @@ void __init memblock_init(void)
> >
> >   /* Reserve the initrd */
> >   reserve_initrd_mem();
> > +
> > + /* Main reserved memory for the elf core head */
> > + early_init_fdt_scan_reserved_mem();
> > + /* Parse linux,usable-memory-range for crash dump kernel */
> > + early_init_dt_check_for_usable_mem_range();
> >  }
> >
> > So here, we are adding support for DT memory reservations, which kdump
> > apparently needs.
> >
> > However, this parsing of the DT not only happens on kexec boot: all
> > ACPI and DT kernels will now honour FDT memory reservations passed in
> > via a DT when booting the first kernel, and external projects may use
> > this and start to depend on this.
> >
> > Once something like this hits the upstream kernel, it is *very*
> > difficult to change or remove.
> >
> > If you only need to pass the usable memory range for kcrash/kdump,
> > it's probably better to use a command line option for that, instead of
> > relying on DT memory reservations.
> Thank you for your suggestion, but we found some trouble when handle
> initrd in kexec.
> In current implementation, we generate a fdt in kexec-tools, then fill
> "linux,usable-memory-range", "linux,elfcorehdr" and initrd information
> in it. After this series, we can use "mem=xxx" "elfcorehdr=" in
> cmdline, but how to handle initrd information which is stored in a
> system table?
>

There are two options:
- use initrdmem= on the command line
- update the INITRD config table in memory (i.e., update the base and
size to refer to the new initrd image)

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 14:32                                 ` Ard Biesheuvel
@ 2022-09-19 14:43                                   ` Huacai Chen
  2022-09-19 14:44                                     ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-19 14:43 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, Sep 19, 2022 at 10:32 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 19 Sept 2022 at 16:25, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > Hi, Ard,
> >
> > On Mon, Sep 19, 2022 at 8:27 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Mon, 19 Sept 2022 at 14:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > > On Mon, Sep 19, 2022 at 8:11 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > >
> > > > > On Mon, 19 Sept 2022 at 13:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, Sep 19, 2022 at 7:21 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > >
> > > > > > > > > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > >  Hi, Ard,
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > > > > > > > > The old way (so-called old world):
> > > > > > > > > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > The current way (so-called new world):
> > > > > > > > > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > The new way (in this patchset):
> > > > > > > > > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > > > > > > > > values to the kernel without going through the stub.
> > > > > > > > > > > > > > In the last patch I see:
> > > > > > > > > > > > > > +               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);
> > > > > > > > > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > > > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > > > > > > > > system, but similar.
> > > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > > > > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > > > > > > > > >
> > > > > > > > > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > > > > > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > > > > > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > > > > > > > > which looks similar to the old-world).
> > > > > > > > > > >
> > > > > > > > > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > > > > > > > > deals with that.
> > > > > > > > > > >
> > > > > > > > > > > > But I have another question: is
> > > > > > > > > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > > > > > > > > way DT is the earliest thing)?
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > If you rely on DT only for the hardware description, then loading it
> > > > > > > > > > > from efi_init() should be fine.
> > > > > > > > > > OK, then please drop patch #12 at this time. It can be added when we
> > > > > > > > > > add Loongson-2K support.
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > OK
> > > > > > > > >
> > > > > > > > > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > > > > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > > > > > > > > code, efi_novamap is set to false unconditionally.
> > > > > > > > > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > > > > > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > > > > > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > > > > > > > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > > > > > > > > well without runtime. And I think I will modify this patch these days
> > > > > > > > > > because in another thread you said that this series cannot boot.
> > > > > > > > >
> > > > > > > > > It works fine now.
> > > > > > > > >
> > > > > > > > > However, clearing the EFI_BOOT flag is not the correct way to disable
> > > > > > > > > runtime services only. And note that we also have efi=noruntime - does
> > > > > > > > > that currently work on LoongArch?
> > > > > > > > OK, but we don't need to add a new "efi=noruntime" parameter, I can
> > > > > > > > use "noefi" instead.
> > > > > > >
> > > > > > > OK
> > > > > > >
> > > > > > > > But I think support "efi=novamap" is not a bad
> > > > > > > > idea (maybe I misunderstood its usage).
> > > > > > > >
> > > > > > >
> > > > > > > It basically exists to deal with broken EFI firmware on ARM laptops
> > > > > > > that were only intended to run Windows. Windows calls
> > > > > > > SetVirtualAddressMap() *after* creating the new mappings, and some
> > > > > > > broken firmware drivers will access those regions too early.
> > > > > > >
> > > > > > > On Linux, we install the mapping first, and then much later, we
> > > > > > > actually create the mappings and only activate them on a single CPU
> > > > > > > while the EFI runtime service call is in progress.
> > > > > > >
> > > > > > > In any case, I will reinstate the efi_novamap logic for now - we can
> > > > > > > always revisit it later.
> > > > > > OK, now I think there are no big problems. Only some bikesheddings:
> > > > > > 1, Please use "a0=efi boot flag, a1=cmdline a2=systemtable" to pass
> > > > > > boot information, it looks most similar to the old-world, and we can
> > > > > > distinguish old-world/new-world by judging whether a0 is greater than
> > > > > > 1.
> > > > > > 2, I prefer "early return" in efi_init, i.e., if (boot_memmap ==
> > > > > > EFI_INVALID_TABLE_ADDR) then return immediately, this makes
> > > > > > indentation look better.
> > > > > > 3, Declare "cmdline" out of the if() condition in init_environ() looks better.
> > > > > > 4, I prefer "kernel_addr" rather than "image_addr" in efi_boot_kernel().
> > > > > > 5, It seems that one line is enough for the last statement in efi_boot_kernel().
> > > > > >
> > > > >
> > > > > OK
> > > > >
> > > > > > Hope this series will be stable as soon as possible, our kexec/kdump
> > > > > > work needs to adjust because of this change. :)
> > > > > >
> > > > >
> > > > > Do you have a link to those patches?
> > > > There is a snapshot for patches pending for 6.1:
> > > > https://github.com/loongson/linux/commits/loongarch-next
> > >
> > > Thanks. I already spotted an issue there which is exactly the kind of
> > > thing I am trying to avoid with this series.
> > >
> > > diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c
> > > index 7423361b0ebc9b..c68c88e40cc0b9 100644
> > > --- a/arch/loongarch/kernel/mem.c
> > > +++ b/arch/loongarch/kernel/mem.c
> > > @@ -61,4 +62,9 @@ void __init memblock_init(void)
> > >
> > >   /* Reserve the initrd */
> > >   reserve_initrd_mem();
> > > +
> > > + /* Main reserved memory for the elf core head */
> > > + early_init_fdt_scan_reserved_mem();
> > > + /* Parse linux,usable-memory-range for crash dump kernel */
> > > + early_init_dt_check_for_usable_mem_range();
> > >  }
> > >
> > > So here, we are adding support for DT memory reservations, which kdump
> > > apparently needs.
> > >
> > > However, this parsing of the DT not only happens on kexec boot: all
> > > ACPI and DT kernels will now honour FDT memory reservations passed in
> > > via a DT when booting the first kernel, and external projects may use
> > > this and start to depend on this.
> > >
> > > Once something like this hits the upstream kernel, it is *very*
> > > difficult to change or remove.
> > >
> > > If you only need to pass the usable memory range for kcrash/kdump,
> > > it's probably better to use a command line option for that, instead of
> > > relying on DT memory reservations.
> > Thank you for your suggestion, but we found some trouble when handle
> > initrd in kexec.
> > In current implementation, we generate a fdt in kexec-tools, then fill
> > "linux,usable-memory-range", "linux,elfcorehdr" and initrd information
> > in it. After this series, we can use "mem=xxx" "elfcorehdr=" in
> > cmdline, but how to handle initrd information which is stored in a
> > system table?
> >
>
> There are two options:
> - use initrdmem= on the command line
This is not a good way, even if the second kernel handle "initrdmem=",
it will conflict with the config table.

> - update the INITRD config table in memory (i.e., update the base and
> size to refer to the new initrd image)
This way seems practicable, but we don't know how to handle it in
kexec-tools. :(

Huacai

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 14:43                                   ` Huacai Chen
@ 2022-09-19 14:44                                     ` Ard Biesheuvel
  2022-09-19 15:08                                       ` Huacai Chen
  0 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-19 14:44 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, 19 Sept 2022 at 16:43, Huacai Chen <chenhuacai@kernel.org> wrote:
>
> On Mon, Sep 19, 2022 at 10:32 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Mon, 19 Sept 2022 at 16:25, Huacai Chen <chenhuacai@kernel.org> wrote:
> > >
> > > Hi, Ard,
> > >
> > > On Mon, Sep 19, 2022 at 8:27 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > On Mon, 19 Sept 2022 at 14:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > >
> > > > > On Mon, Sep 19, 2022 at 8:11 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, 19 Sept 2022 at 13:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, Sep 19, 2022 at 7:21 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > >
> > > > > > > > > > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > >  Hi, Ard,
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > > > > > > > > > The old way (so-called old world):
> > > > > > > > > > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > The current way (so-called new world):
> > > > > > > > > > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > The new way (in this patchset):
> > > > > > > > > > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > > > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > > > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > > > > > > > > > values to the kernel without going through the stub.
> > > > > > > > > > > > > > > In the last patch I see:
> > > > > > > > > > > > > > > +               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);
> > > > > > > > > > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > > > > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > > > > > > > > > system, but similar.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > > > > > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > > > > > > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > > > > > > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > > > > > > > > > which looks similar to the old-world).
> > > > > > > > > > > >
> > > > > > > > > > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > > > > > > > > > deals with that.
> > > > > > > > > > > >
> > > > > > > > > > > > > But I have another question: is
> > > > > > > > > > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > > > > > > > > > way DT is the earliest thing)?
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > If you rely on DT only for the hardware description, then loading it
> > > > > > > > > > > > from efi_init() should be fine.
> > > > > > > > > > > OK, then please drop patch #12 at this time. It can be added when we
> > > > > > > > > > > add Loongson-2K support.
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > OK
> > > > > > > > > >
> > > > > > > > > > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > > > > > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > > > > > > > > > code, efi_novamap is set to false unconditionally.
> > > > > > > > > > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > > > > > > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > > > > > > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > > > > > > > > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > > > > > > > > > well without runtime. And I think I will modify this patch these days
> > > > > > > > > > > because in another thread you said that this series cannot boot.
> > > > > > > > > >
> > > > > > > > > > It works fine now.
> > > > > > > > > >
> > > > > > > > > > However, clearing the EFI_BOOT flag is not the correct way to disable
> > > > > > > > > > runtime services only. And note that we also have efi=noruntime - does
> > > > > > > > > > that currently work on LoongArch?
> > > > > > > > > OK, but we don't need to add a new "efi=noruntime" parameter, I can
> > > > > > > > > use "noefi" instead.
> > > > > > > >
> > > > > > > > OK
> > > > > > > >
> > > > > > > > > But I think support "efi=novamap" is not a bad
> > > > > > > > > idea (maybe I misunderstood its usage).
> > > > > > > > >
> > > > > > > >
> > > > > > > > It basically exists to deal with broken EFI firmware on ARM laptops
> > > > > > > > that were only intended to run Windows. Windows calls
> > > > > > > > SetVirtualAddressMap() *after* creating the new mappings, and some
> > > > > > > > broken firmware drivers will access those regions too early.
> > > > > > > >
> > > > > > > > On Linux, we install the mapping first, and then much later, we
> > > > > > > > actually create the mappings and only activate them on a single CPU
> > > > > > > > while the EFI runtime service call is in progress.
> > > > > > > >
> > > > > > > > In any case, I will reinstate the efi_novamap logic for now - we can
> > > > > > > > always revisit it later.
> > > > > > > OK, now I think there are no big problems. Only some bikesheddings:
> > > > > > > 1, Please use "a0=efi boot flag, a1=cmdline a2=systemtable" to pass
> > > > > > > boot information, it looks most similar to the old-world, and we can
> > > > > > > distinguish old-world/new-world by judging whether a0 is greater than
> > > > > > > 1.
> > > > > > > 2, I prefer "early return" in efi_init, i.e., if (boot_memmap ==
> > > > > > > EFI_INVALID_TABLE_ADDR) then return immediately, this makes
> > > > > > > indentation look better.
> > > > > > > 3, Declare "cmdline" out of the if() condition in init_environ() looks better.
> > > > > > > 4, I prefer "kernel_addr" rather than "image_addr" in efi_boot_kernel().
> > > > > > > 5, It seems that one line is enough for the last statement in efi_boot_kernel().
> > > > > > >
> > > > > >
> > > > > > OK
> > > > > >
> > > > > > > Hope this series will be stable as soon as possible, our kexec/kdump
> > > > > > > work needs to adjust because of this change. :)
> > > > > > >
> > > > > >
> > > > > > Do you have a link to those patches?
> > > > > There is a snapshot for patches pending for 6.1:
> > > > > https://github.com/loongson/linux/commits/loongarch-next
> > > >
> > > > Thanks. I already spotted an issue there which is exactly the kind of
> > > > thing I am trying to avoid with this series.
> > > >
> > > > diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c
> > > > index 7423361b0ebc9b..c68c88e40cc0b9 100644
> > > > --- a/arch/loongarch/kernel/mem.c
> > > > +++ b/arch/loongarch/kernel/mem.c
> > > > @@ -61,4 +62,9 @@ void __init memblock_init(void)
> > > >
> > > >   /* Reserve the initrd */
> > > >   reserve_initrd_mem();
> > > > +
> > > > + /* Main reserved memory for the elf core head */
> > > > + early_init_fdt_scan_reserved_mem();
> > > > + /* Parse linux,usable-memory-range for crash dump kernel */
> > > > + early_init_dt_check_for_usable_mem_range();
> > > >  }
> > > >
> > > > So here, we are adding support for DT memory reservations, which kdump
> > > > apparently needs.
> > > >
> > > > However, this parsing of the DT not only happens on kexec boot: all
> > > > ACPI and DT kernels will now honour FDT memory reservations passed in
> > > > via a DT when booting the first kernel, and external projects may use
> > > > this and start to depend on this.
> > > >
> > > > Once something like this hits the upstream kernel, it is *very*
> > > > difficult to change or remove.
> > > >
> > > > If you only need to pass the usable memory range for kcrash/kdump,
> > > > it's probably better to use a command line option for that, instead of
> > > > relying on DT memory reservations.
> > > Thank you for your suggestion, but we found some trouble when handle
> > > initrd in kexec.
> > > In current implementation, we generate a fdt in kexec-tools, then fill
> > > "linux,usable-memory-range", "linux,elfcorehdr" and initrd information
> > > in it. After this series, we can use "mem=xxx" "elfcorehdr=" in
> > > cmdline, but how to handle initrd information which is stored in a
> > > system table?
> > >
> >
> > There are two options:
> > - use initrdmem= on the command line
> This is not a good way, even if the second kernel handle "initrdmem=",
> it will conflict with the config table.
>

It will not conflict - initrdmem= supersedes the INITRD table because
early param passing happens after efi_init().

> > - update the INITRD config table in memory (i.e., update the base and
> > size to refer to the new initrd image)
> This way seems practicable, but we don't know how to handle it in
> kexec-tools. :(
>

Good point. Let me think a bit about this.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 14:44                                     ` Ard Biesheuvel
@ 2022-09-19 15:08                                       ` Huacai Chen
  2022-09-19 15:50                                         ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-19 15:08 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, Sep 19, 2022 at 10:44 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 19 Sept 2022 at 16:43, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > On Mon, Sep 19, 2022 at 10:32 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Mon, 19 Sept 2022 at 16:25, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > > Hi, Ard,
> > > >
> > > > On Mon, Sep 19, 2022 at 8:27 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > >
> > > > > On Mon, 19 Sept 2022 at 14:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, Sep 19, 2022 at 8:11 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, 19 Sept 2022 at 13:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Mon, Sep 19, 2022 at 7:21 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > >  Hi, Ard,
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > > > > > > > > > > The old way (so-called old world):
> > > > > > > > > > > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > The current way (so-called new world):
> > > > > > > > > > > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > The new way (in this patchset):
> > > > > > > > > > > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > > > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > > > > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > > > > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > > > > > > > > > > values to the kernel without going through the stub.
> > > > > > > > > > > > > > > > In the last patch I see:
> > > > > > > > > > > > > > > > +               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);
> > > > > > > > > > > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > > > > > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > > > > > > > > > > system, but similar.
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > > > > > > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > > > > > > > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > > > > > > > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > > > > > > > > > > which looks similar to the old-world).
> > > > > > > > > > > > >
> > > > > > > > > > > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > > > > > > > > > > deals with that.
> > > > > > > > > > > > >
> > > > > > > > > > > > > > But I have another question: is
> > > > > > > > > > > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > > > > > > > > > > way DT is the earliest thing)?
> > > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > If you rely on DT only for the hardware description, then loading it
> > > > > > > > > > > > > from efi_init() should be fine.
> > > > > > > > > > > > OK, then please drop patch #12 at this time. It can be added when we
> > > > > > > > > > > > add Loongson-2K support.
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > OK
> > > > > > > > > > >
> > > > > > > > > > > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > > > > > > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > > > > > > > > > > code, efi_novamap is set to false unconditionally.
> > > > > > > > > > > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > > > > > > > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > > > > > > > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > > > > > > > > > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > > > > > > > > > > well without runtime. And I think I will modify this patch these days
> > > > > > > > > > > > because in another thread you said that this series cannot boot.
> > > > > > > > > > >
> > > > > > > > > > > It works fine now.
> > > > > > > > > > >
> > > > > > > > > > > However, clearing the EFI_BOOT flag is not the correct way to disable
> > > > > > > > > > > runtime services only. And note that we also have efi=noruntime - does
> > > > > > > > > > > that currently work on LoongArch?
> > > > > > > > > > OK, but we don't need to add a new "efi=noruntime" parameter, I can
> > > > > > > > > > use "noefi" instead.
> > > > > > > > >
> > > > > > > > > OK
> > > > > > > > >
> > > > > > > > > > But I think support "efi=novamap" is not a bad
> > > > > > > > > > idea (maybe I misunderstood its usage).
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > It basically exists to deal with broken EFI firmware on ARM laptops
> > > > > > > > > that were only intended to run Windows. Windows calls
> > > > > > > > > SetVirtualAddressMap() *after* creating the new mappings, and some
> > > > > > > > > broken firmware drivers will access those regions too early.
> > > > > > > > >
> > > > > > > > > On Linux, we install the mapping first, and then much later, we
> > > > > > > > > actually create the mappings and only activate them on a single CPU
> > > > > > > > > while the EFI runtime service call is in progress.
> > > > > > > > >
> > > > > > > > > In any case, I will reinstate the efi_novamap logic for now - we can
> > > > > > > > > always revisit it later.
> > > > > > > > OK, now I think there are no big problems. Only some bikesheddings:
> > > > > > > > 1, Please use "a0=efi boot flag, a1=cmdline a2=systemtable" to pass
> > > > > > > > boot information, it looks most similar to the old-world, and we can
> > > > > > > > distinguish old-world/new-world by judging whether a0 is greater than
> > > > > > > > 1.
> > > > > > > > 2, I prefer "early return" in efi_init, i.e., if (boot_memmap ==
> > > > > > > > EFI_INVALID_TABLE_ADDR) then return immediately, this makes
> > > > > > > > indentation look better.
> > > > > > > > 3, Declare "cmdline" out of the if() condition in init_environ() looks better.
> > > > > > > > 4, I prefer "kernel_addr" rather than "image_addr" in efi_boot_kernel().
> > > > > > > > 5, It seems that one line is enough for the last statement in efi_boot_kernel().
> > > > > > > >
> > > > > > >
> > > > > > > OK
> > > > > > >
> > > > > > > > Hope this series will be stable as soon as possible, our kexec/kdump
> > > > > > > > work needs to adjust because of this change. :)
> > > > > > > >
> > > > > > >
> > > > > > > Do you have a link to those patches?
> > > > > > There is a snapshot for patches pending for 6.1:
> > > > > > https://github.com/loongson/linux/commits/loongarch-next
> > > > >
> > > > > Thanks. I already spotted an issue there which is exactly the kind of
> > > > > thing I am trying to avoid with this series.
> > > > >
> > > > > diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c
> > > > > index 7423361b0ebc9b..c68c88e40cc0b9 100644
> > > > > --- a/arch/loongarch/kernel/mem.c
> > > > > +++ b/arch/loongarch/kernel/mem.c
> > > > > @@ -61,4 +62,9 @@ void __init memblock_init(void)
> > > > >
> > > > >   /* Reserve the initrd */
> > > > >   reserve_initrd_mem();
> > > > > +
> > > > > + /* Main reserved memory for the elf core head */
> > > > > + early_init_fdt_scan_reserved_mem();
> > > > > + /* Parse linux,usable-memory-range for crash dump kernel */
> > > > > + early_init_dt_check_for_usable_mem_range();
> > > > >  }
> > > > >
> > > > > So here, we are adding support for DT memory reservations, which kdump
> > > > > apparently needs.
> > > > >
> > > > > However, this parsing of the DT not only happens on kexec boot: all
> > > > > ACPI and DT kernels will now honour FDT memory reservations passed in
> > > > > via a DT when booting the first kernel, and external projects may use
> > > > > this and start to depend on this.
> > > > >
> > > > > Once something like this hits the upstream kernel, it is *very*
> > > > > difficult to change or remove.
> > > > >
> > > > > If you only need to pass the usable memory range for kcrash/kdump,
> > > > > it's probably better to use a command line option for that, instead of
> > > > > relying on DT memory reservations.
> > > > Thank you for your suggestion, but we found some trouble when handle
> > > > initrd in kexec.
> > > > In current implementation, we generate a fdt in kexec-tools, then fill
> > > > "linux,usable-memory-range", "linux,elfcorehdr" and initrd information
> > > > in it. After this series, we can use "mem=xxx" "elfcorehdr=" in
> > > > cmdline, but how to handle initrd information which is stored in a
> > > > system table?
> > > >
> > >
> > > There are two options:
> > > - use initrdmem= on the command line
> > This is not a good way, even if the second kernel handle "initrdmem=",
> > it will conflict with the config table.
> >
>
> It will not conflict - initrdmem= supersedes the INITRD table because
> early param passing happens after efi_init().
>
> > > - update the INITRD config table in memory (i.e., update the base and
> > > size to refer to the new initrd image)
> > This way seems practicable, but we don't know how to handle it in
> > kexec-tools. :(
> >
>
> Good point. Let me think a bit about this.
OK, then let's go back to this series itself. :)

I have seen the latest code in your git repo, I don't think we need
efi_disable_rt. Instead, setting/clearing EFI_BOOT according to a0 as
before seems reasonable.

If efi_novamap breaks something, I can accept "set efi_novamap to
false" in the previous version, or just ignore its value in the
efistub, but a0 should clearly be the indicator of EFI_BOOT.

Huacai

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 15:08                                       ` Huacai Chen
@ 2022-09-19 15:50                                         ` Ard Biesheuvel
  2022-09-20  1:44                                           ` Huacai Chen
  0 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-19 15:50 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Mon, 19 Sept 2022 at 17:09, Huacai Chen <chenhuacai@kernel.org> wrote:
>
> On Mon, Sep 19, 2022 at 10:44 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Mon, 19 Sept 2022 at 16:43, Huacai Chen <chenhuacai@kernel.org> wrote:
> > >
> > > On Mon, Sep 19, 2022 at 10:32 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > >
> > > > On Mon, 19 Sept 2022 at 16:25, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > >
> > > > > Hi, Ard,
> > > > >
> > > > > On Mon, Sep 19, 2022 at 8:27 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > >
> > > > > > On Mon, 19 Sept 2022 at 14:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, Sep 19, 2022 at 8:11 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Mon, 19 Sept 2022 at 13:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > On Mon, Sep 19, 2022 at 7:21 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > >  Hi, Ard,
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > > > > > > > > > > > The old way (so-called old world):
> > > > > > > > > > > > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > The current way (so-called new world):
> > > > > > > > > > > > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > The new way (in this patchset):
> > > > > > > > > > > > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > > > > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > > > > > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > > > > > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > > > > > > > > > > > values to the kernel without going through the stub.
> > > > > > > > > > > > > > > > > In the last patch I see:
> > > > > > > > > > > > > > > > > +               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);
> > > > > > > > > > > > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > > > > > > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > > > > > > > > > > > system, but similar.
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > > > > > > > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > > > > > > > > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > > > > > > > > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > > > > > > > > > > > which looks similar to the old-world).
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > > > > > > > > > > > deals with that.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > > But I have another question: is
> > > > > > > > > > > > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > > > > > > > > > > > way DT is the earliest thing)?
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > If you rely on DT only for the hardware description, then loading it
> > > > > > > > > > > > > > from efi_init() should be fine.
> > > > > > > > > > > > > OK, then please drop patch #12 at this time. It can be added when we
> > > > > > > > > > > > > add Loongson-2K support.
> > > > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > OK
> > > > > > > > > > > >
> > > > > > > > > > > > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > > > > > > > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > > > > > > > > > > > code, efi_novamap is set to false unconditionally.
> > > > > > > > > > > > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > > > > > > > > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > > > > > > > > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > > > > > > > > > > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > > > > > > > > > > > well without runtime. And I think I will modify this patch these days
> > > > > > > > > > > > > because in another thread you said that this series cannot boot.
> > > > > > > > > > > >
> > > > > > > > > > > > It works fine now.
> > > > > > > > > > > >
> > > > > > > > > > > > However, clearing the EFI_BOOT flag is not the correct way to disable
> > > > > > > > > > > > runtime services only. And note that we also have efi=noruntime - does
> > > > > > > > > > > > that currently work on LoongArch?
> > > > > > > > > > > OK, but we don't need to add a new "efi=noruntime" parameter, I can
> > > > > > > > > > > use "noefi" instead.
> > > > > > > > > >
> > > > > > > > > > OK
> > > > > > > > > >
> > > > > > > > > > > But I think support "efi=novamap" is not a bad
> > > > > > > > > > > idea (maybe I misunderstood its usage).
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > It basically exists to deal with broken EFI firmware on ARM laptops
> > > > > > > > > > that were only intended to run Windows. Windows calls
> > > > > > > > > > SetVirtualAddressMap() *after* creating the new mappings, and some
> > > > > > > > > > broken firmware drivers will access those regions too early.
> > > > > > > > > >
> > > > > > > > > > On Linux, we install the mapping first, and then much later, we
> > > > > > > > > > actually create the mappings and only activate them on a single CPU
> > > > > > > > > > while the EFI runtime service call is in progress.
> > > > > > > > > >
> > > > > > > > > > In any case, I will reinstate the efi_novamap logic for now - we can
> > > > > > > > > > always revisit it later.
> > > > > > > > > OK, now I think there are no big problems. Only some bikesheddings:
> > > > > > > > > 1, Please use "a0=efi boot flag, a1=cmdline a2=systemtable" to pass
> > > > > > > > > boot information, it looks most similar to the old-world, and we can
> > > > > > > > > distinguish old-world/new-world by judging whether a0 is greater than
> > > > > > > > > 1.
> > > > > > > > > 2, I prefer "early return" in efi_init, i.e., if (boot_memmap ==
> > > > > > > > > EFI_INVALID_TABLE_ADDR) then return immediately, this makes
> > > > > > > > > indentation look better.
> > > > > > > > > 3, Declare "cmdline" out of the if() condition in init_environ() looks better.
> > > > > > > > > 4, I prefer "kernel_addr" rather than "image_addr" in efi_boot_kernel().
> > > > > > > > > 5, It seems that one line is enough for the last statement in efi_boot_kernel().
> > > > > > > > >
> > > > > > > >
> > > > > > > > OK
> > > > > > > >
> > > > > > > > > Hope this series will be stable as soon as possible, our kexec/kdump
> > > > > > > > > work needs to adjust because of this change. :)
> > > > > > > > >
> > > > > > > >
> > > > > > > > Do you have a link to those patches?
> > > > > > > There is a snapshot for patches pending for 6.1:
> > > > > > > https://github.com/loongson/linux/commits/loongarch-next
> > > > > >
> > > > > > Thanks. I already spotted an issue there which is exactly the kind of
> > > > > > thing I am trying to avoid with this series.
> > > > > >
> > > > > > diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c
> > > > > > index 7423361b0ebc9b..c68c88e40cc0b9 100644
> > > > > > --- a/arch/loongarch/kernel/mem.c
> > > > > > +++ b/arch/loongarch/kernel/mem.c
> > > > > > @@ -61,4 +62,9 @@ void __init memblock_init(void)
> > > > > >
> > > > > >   /* Reserve the initrd */
> > > > > >   reserve_initrd_mem();
> > > > > > +
> > > > > > + /* Main reserved memory for the elf core head */
> > > > > > + early_init_fdt_scan_reserved_mem();
> > > > > > + /* Parse linux,usable-memory-range for crash dump kernel */
> > > > > > + early_init_dt_check_for_usable_mem_range();
> > > > > >  }
> > > > > >
> > > > > > So here, we are adding support for DT memory reservations, which kdump
> > > > > > apparently needs.
> > > > > >
> > > > > > However, this parsing of the DT not only happens on kexec boot: all
> > > > > > ACPI and DT kernels will now honour FDT memory reservations passed in
> > > > > > via a DT when booting the first kernel, and external projects may use
> > > > > > this and start to depend on this.
> > > > > >
> > > > > > Once something like this hits the upstream kernel, it is *very*
> > > > > > difficult to change or remove.
> > > > > >
> > > > > > If you only need to pass the usable memory range for kcrash/kdump,
> > > > > > it's probably better to use a command line option for that, instead of
> > > > > > relying on DT memory reservations.
> > > > > Thank you for your suggestion, but we found some trouble when handle
> > > > > initrd in kexec.
> > > > > In current implementation, we generate a fdt in kexec-tools, then fill
> > > > > "linux,usable-memory-range", "linux,elfcorehdr" and initrd information
> > > > > in it. After this series, we can use "mem=xxx" "elfcorehdr=" in
> > > > > cmdline, but how to handle initrd information which is stored in a
> > > > > system table?
> > > > >
> > > >
> > > > There are two options:
> > > > - use initrdmem= on the command line
> > > This is not a good way, even if the second kernel handle "initrdmem=",
> > > it will conflict with the config table.
> > >
> >
> > It will not conflict - initrdmem= supersedes the INITRD table because
> > early param passing happens after efi_init().
> >
> > > > - update the INITRD config table in memory (i.e., update the base and
> > > > size to refer to the new initrd image)
> > > This way seems practicable, but we don't know how to handle it in
> > > kexec-tools. :(
> > >
> >
> > Good point. Let me think a bit about this.
> OK, then let's go back to this series itself. :)
>
> I have seen the latest code in your git repo, I don't think we need
> efi_disable_rt. Instead, setting/clearing EFI_BOOT according to a0 as
> before seems reasonable.
>

No, not really. EFI_BOOT basically means 'did I boot via EFI?' and
strictly, you should not be attempting to access the EFI system table
or parse EFI config tables unless EFI_BOOT is true.

Deviating from this makes it more difficult for generic code to reason
about what parts of EFI are active on a given system.

> If efi_novamap breaks something, I can accept "set efi_novamap to
> false" in the previous version, or just ignore its value in the
> efistub, but a0 should clearly be the indicator of EFI_BOOT.
>

I'm fine with keeping efi_novamap if you think it has a value. To me,
it seems rather pointless, because it prevents you from using the
runtime services.

If you want a0 to control the EFI boot flag, you should find another
way to control whether runtime services can be used, because they are
really two different things.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-19 15:50                                         ` Ard Biesheuvel
@ 2022-09-20  1:44                                           ` Huacai Chen
  2022-09-20  8:04                                             ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-20  1:44 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

Hi, Ard,

On Mon, Sep 19, 2022 at 11:50 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Mon, 19 Sept 2022 at 17:09, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > On Mon, Sep 19, 2022 at 10:44 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > >
> > > On Mon, 19 Sept 2022 at 16:43, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > >
> > > > On Mon, Sep 19, 2022 at 10:32 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > >
> > > > > On Mon, 19 Sept 2022 at 16:25, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > >
> > > > > > Hi, Ard,
> > > > > >
> > > > > > On Mon, Sep 19, 2022 at 8:27 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > >
> > > > > > > On Mon, 19 Sept 2022 at 14:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > >
> > > > > > > > On Mon, Sep 19, 2022 at 8:11 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > >
> > > > > > > > > On Mon, 19 Sept 2022 at 13:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > >
> > > > > > > > > > On Mon, Sep 19, 2022 at 7:21 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > >
> > > > > > > > > > > On Mon, 19 Sept 2022 at 13:15, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > >
> > > > > > > > > > > > On Mon, Sep 19, 2022 at 6:49 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > >
> > > > > > > > > > > > > On Mon, 19 Sept 2022 at 12:47, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > On Mon, Sep 19, 2022 at 6:37 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 12:33, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > On Mon, Sep 19, 2022 at 2:22 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 08:06, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > >  Hi, Ard,
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > On Mon, Sep 19, 2022 at 1:15 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > On Mon, 19 Sept 2022 at 03:58, Huacai Chen <chenhuacai@kernel.org> wrote:
> > > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > > Hi, Ard,
> > > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > > I think the parameters passed to the core kernel need to be discussed.
> > > > > > > > > > > > > > > > > > > > The old way (so-called old world):
> > > > > > > > > > > > > > > > > > > > a0=argc, a1=argv, a1=bpi
> > > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > > The current way (so-called new world):
> > > > > > > > > > > > > > > > > > > > a0=efi boot flag, a1=fdt pointer
> > > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > > The new way (in this patchset):
> > > > > > > > > > > > > > > > > > > > a0=efi boot flag, a1=systemtable, a2=cmdline
> > > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > > I prefer to use the current way, there are 3 reasons:
> > > > > > > > > > > > > > > > > > > > 1, both acpi system and dt system can use the same parameters passing method;
> > > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > > > DT systems will use this too. The distinction is between EFI boot and
> > > > > > > > > > > > > > > > > > > non-EFI boot. We *really* should keep these separate, given the
> > > > > > > > > > > > > > > > > > > experience on ARM, where other projects invent ways to pass those
> > > > > > > > > > > > > > > > > > > values to the kernel without going through the stub.
> > > > > > > > > > > > > > > > > > In the last patch I see:
> > > > > > > > > > > > > > > > > > +               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);
> > > > > > > > > > > > > > > > > > So I suppose for the DT system that means a0=efi boot flag, a1=fdt
> > > > > > > > > > > > > > > > > > pointer, a2=cmdline? Then it is not exactly the same as the ACPI
> > > > > > > > > > > > > > > > > > system, but similar.
> > > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > No, for non-EFI DT boot, the command line is passed via the DT, so
> > > > > > > > > > > > > > > > > a0=0x0 (non-efi), a1=DT, a2=0x0
> > > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > Do you intend to support non-EFI DT boot by the way?
> > > > > > > > > > > > > > > > I think we needn't support non-EFI DT boot, so a0=efi boot flag,
> > > > > > > > > > > > > > > > a1=systemtable, a2=cmdline is just OK (or maybe we can exchange a1/a2,
> > > > > > > > > > > > > > > > which looks similar to the old-world).
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Excellent. If non-EFI boot is not supported, we can drop the code that
> > > > > > > > > > > > > > > deals with that.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > But I have another question: is
> > > > > > > > > > > > > > > > it early enough to get DT from systemtable for DT boot (in the current
> > > > > > > > > > > > > > > > way DT is the earliest thing)?
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > If you rely on DT only for the hardware description, then loading it
> > > > > > > > > > > > > > > from efi_init() should be fine.
> > > > > > > > > > > > > > OK, then please drop patch #12 at this time. It can be added when we
> > > > > > > > > > > > > > add Loongson-2K support.
> > > > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > OK
> > > > > > > > > > > > >
> > > > > > > > > > > > > > > > > I don't think it makes sense to allow efi=novamap on LoongArch, given
> > > > > > > > > > > > > > > > > that we cannot make use of the runtime services that way. So in my
> > > > > > > > > > > > > > > > > code, efi_novamap is set to false unconditionally.
> > > > > > > > > > > > > > > > Emm, I prefer to support "efi=novamap", the core kernel has already
> > > > > > > > > > > > > > > > supported "noefi" to disable runtime, I don't want to hack
> > > > > > > > > > > > > > > > efi_novamap. So please keep the efi boot flag, thanks.
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Fair enough. Do you have any uses for efi_novamap in mind?
> > > > > > > > > > > > > > I usually use "efi=novamap" in EFI shell to see whether it can work
> > > > > > > > > > > > > > well without runtime. And I think I will modify this patch these days
> > > > > > > > > > > > > > because in another thread you said that this series cannot boot.
> > > > > > > > > > > > >
> > > > > > > > > > > > > It works fine now.
> > > > > > > > > > > > >
> > > > > > > > > > > > > However, clearing the EFI_BOOT flag is not the correct way to disable
> > > > > > > > > > > > > runtime services only. And note that we also have efi=noruntime - does
> > > > > > > > > > > > > that currently work on LoongArch?
> > > > > > > > > > > > OK, but we don't need to add a new "efi=noruntime" parameter, I can
> > > > > > > > > > > > use "noefi" instead.
> > > > > > > > > > >
> > > > > > > > > > > OK
> > > > > > > > > > >
> > > > > > > > > > > > But I think support "efi=novamap" is not a bad
> > > > > > > > > > > > idea (maybe I misunderstood its usage).
> > > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > It basically exists to deal with broken EFI firmware on ARM laptops
> > > > > > > > > > > that were only intended to run Windows. Windows calls
> > > > > > > > > > > SetVirtualAddressMap() *after* creating the new mappings, and some
> > > > > > > > > > > broken firmware drivers will access those regions too early.
> > > > > > > > > > >
> > > > > > > > > > > On Linux, we install the mapping first, and then much later, we
> > > > > > > > > > > actually create the mappings and only activate them on a single CPU
> > > > > > > > > > > while the EFI runtime service call is in progress.
> > > > > > > > > > >
> > > > > > > > > > > In any case, I will reinstate the efi_novamap logic for now - we can
> > > > > > > > > > > always revisit it later.
> > > > > > > > > > OK, now I think there are no big problems. Only some bikesheddings:
> > > > > > > > > > 1, Please use "a0=efi boot flag, a1=cmdline a2=systemtable" to pass
> > > > > > > > > > boot information, it looks most similar to the old-world, and we can
> > > > > > > > > > distinguish old-world/new-world by judging whether a0 is greater than
> > > > > > > > > > 1.
> > > > > > > > > > 2, I prefer "early return" in efi_init, i.e., if (boot_memmap ==
> > > > > > > > > > EFI_INVALID_TABLE_ADDR) then return immediately, this makes
> > > > > > > > > > indentation look better.
> > > > > > > > > > 3, Declare "cmdline" out of the if() condition in init_environ() looks better.
> > > > > > > > > > 4, I prefer "kernel_addr" rather than "image_addr" in efi_boot_kernel().
> > > > > > > > > > 5, It seems that one line is enough for the last statement in efi_boot_kernel().
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > OK
> > > > > > > > >
> > > > > > > > > > Hope this series will be stable as soon as possible, our kexec/kdump
> > > > > > > > > > work needs to adjust because of this change. :)
> > > > > > > > > >
> > > > > > > > >
> > > > > > > > > Do you have a link to those patches?
> > > > > > > > There is a snapshot for patches pending for 6.1:
> > > > > > > > https://github.com/loongson/linux/commits/loongarch-next
> > > > > > >
> > > > > > > Thanks. I already spotted an issue there which is exactly the kind of
> > > > > > > thing I am trying to avoid with this series.
> > > > > > >
> > > > > > > diff --git a/arch/loongarch/kernel/mem.c b/arch/loongarch/kernel/mem.c
> > > > > > > index 7423361b0ebc9b..c68c88e40cc0b9 100644
> > > > > > > --- a/arch/loongarch/kernel/mem.c
> > > > > > > +++ b/arch/loongarch/kernel/mem.c
> > > > > > > @@ -61,4 +62,9 @@ void __init memblock_init(void)
> > > > > > >
> > > > > > >   /* Reserve the initrd */
> > > > > > >   reserve_initrd_mem();
> > > > > > > +
> > > > > > > + /* Main reserved memory for the elf core head */
> > > > > > > + early_init_fdt_scan_reserved_mem();
> > > > > > > + /* Parse linux,usable-memory-range for crash dump kernel */
> > > > > > > + early_init_dt_check_for_usable_mem_range();
> > > > > > >  }
> > > > > > >
> > > > > > > So here, we are adding support for DT memory reservations, which kdump
> > > > > > > apparently needs.
> > > > > > >
> > > > > > > However, this parsing of the DT not only happens on kexec boot: all
> > > > > > > ACPI and DT kernels will now honour FDT memory reservations passed in
> > > > > > > via a DT when booting the first kernel, and external projects may use
> > > > > > > this and start to depend on this.
> > > > > > >
> > > > > > > Once something like this hits the upstream kernel, it is *very*
> > > > > > > difficult to change or remove.
> > > > > > >
> > > > > > > If you only need to pass the usable memory range for kcrash/kdump,
> > > > > > > it's probably better to use a command line option for that, instead of
> > > > > > > relying on DT memory reservations.
> > > > > > Thank you for your suggestion, but we found some trouble when handle
> > > > > > initrd in kexec.
> > > > > > In current implementation, we generate a fdt in kexec-tools, then fill
> > > > > > "linux,usable-memory-range", "linux,elfcorehdr" and initrd information
> > > > > > in it. After this series, we can use "mem=xxx" "elfcorehdr=" in
> > > > > > cmdline, but how to handle initrd information which is stored in a
> > > > > > system table?
> > > > > >
> > > > >
> > > > > There are two options:
> > > > > - use initrdmem= on the command line
> > > > This is not a good way, even if the second kernel handle "initrdmem=",
> > > > it will conflict with the config table.
> > > >
> > >
> > > It will not conflict - initrdmem= supersedes the INITRD table because
> > > early param passing happens after efi_init().
> > >
> > > > > - update the INITRD config table in memory (i.e., update the base and
> > > > > size to refer to the new initrd image)
> > > > This way seems practicable, but we don't know how to handle it in
> > > > kexec-tools. :(
> > > >
> > >
> > > Good point. Let me think a bit about this.
> > OK, then let's go back to this series itself. :)
> >
> > I have seen the latest code in your git repo, I don't think we need
> > efi_disable_rt. Instead, setting/clearing EFI_BOOT according to a0 as
> > before seems reasonable.
> >
>
> No, not really. EFI_BOOT basically means 'did I boot via EFI?' and
> strictly, you should not be attempting to access the EFI system table
> or parse EFI config tables unless EFI_BOOT is true.
>
> Deviating from this makes it more difficult for generic code to reason
> about what parts of EFI are active on a given system.
>
> > If efi_novamap breaks something, I can accept "set efi_novamap to
> > false" in the previous version, or just ignore its value in the
> > efistub, but a0 should clearly be the indicator of EFI_BOOT.
> >
>
> I'm fine with keeping efi_novamap if you think it has a value. To me,
> it seems rather pointless, because it prevents you from using the
> runtime services.
>
> If you want a0 to control the EFI boot flag, you should find another
> way to control whether runtime services can be used, because they are
> really two different things.
I'm very sorry, after an offline discussion with my colleagues,
non-EFI DT boot is still needed (very sadly, we want to drop non-EFI
firmware but we can't do that). However, for non-EFI DT boot we will
use the same parameter passing method (a0=efi boot flag, a1=cmdline,
a2=systemtable), firmware will generate a simple systemtable only for
DT. In this way all boot methods share the same logic, and also make
kexec easy to implement.

So, let's make a0 the real "efi boot flag" and let it control
EFI_BOOT, for efistub, we can just pass "true" unconditionally
(whether support efi_novamap is not as important as the efi boot flag
for us, as you said, efi_novamap is just for broken firmware).

Huacai

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-20  1:44                                           ` Huacai Chen
@ 2022-09-20  8:04                                             ` Ard Biesheuvel
  2022-09-20 13:12                                               ` Huacai Chen
  0 siblings, 1 reply; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-20  8:04 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Tue, 20 Sept 2022 at 03:45, Huacai Chen <chenhuacai@kernel.org> wrote:
>
> Hi, Ard,
>
...
> I'm very sorry, after an offline discussion with my colleagues,
> non-EFI DT boot is still needed (very sadly, we want to drop non-EFI
> firmware but we can't do that). However, for non-EFI DT boot we will
> use the same parameter passing method (a0=efi boot flag, a1=cmdline,
> a2=systemtable), firmware will generate a simple systemtable only for
> DT. In this way all boot methods share the same logic, and also make
> kexec easy to implement.
>

OK, that should work. So I suppose you create a EFI system table along
with EFI configuration tables for DT, SMBIOS, etc? In this case, I
suggest you omit the MEMMAP config table that I am adding here, so
that there is no ambiguity between the EFI provided memory map and the
one provided by DT.

I think that should be a clean way to implement this.

> So, let's make a0 the real "efi boot flag" and let it control
> EFI_BOOT, for efistub, we can just pass "true" unconditionally
> (whether support efi_novamap is not as important as the efi boot flag
> for us, as you said, efi_novamap is just for broken firmware).

Indeed. So as before, I will just set efi_novamap to false. You can
still use noefi or efi=noruntime to turn off the EFI runtime pieces if
needed (e.g., PREEMPT_RT tends to disable those by default to preserve
their bounded worst case latency)

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 09/12] efi: libstub: install boot-time memory map as config table
  2022-09-18 21:35 ` [PATCH 09/12] efi: libstub: install boot-time memory map as config table Ard Biesheuvel
@ 2022-09-20 10:40   ` Joey Gouly
  2022-09-20 11:37     ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Joey Gouly @ 2022-09-20 10:40 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, linux, Arnd Bergmann, Ilias Apalodimas,
	Huacai Chen, Xi Ruoyao, nd

Hi Ard,

On Sun, Sep 18, 2022 at 11:35:41PM +0200, Ard Biesheuvel wrote:
> 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 <ardb@kernel.org>
> ---
>  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/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);
>  	}

You have another commit about removing goto kludges, so maybe write this like the following,
rather than a goto into an 'else' statement?

diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c
index feef8d4be113..2f22ef7c5232 100644
--- a/drivers/firmware/efi/libstub/mem.c
+++ b/drivers/firmware/efi/libstub/mem.c
@@ -64,10 +64,12 @@ efi_status_t efi_get_memory_map(struct efi_boot_memmap *map)
                        *map->key_ptr = key;
                if (map->desc_ver)
                        *map->desc_ver = desc_version;
-       } else {
-               efi_bs_call(free_pool, m);
        }
 
+free_map:
+       if (status != EFI_SUCCESS)
+               efi_bs_call(free_pool, m);
+
 fail:
        *map->map = m;
        return status;

(This is a diff against next-20220920, not your branch, but you get the idea)

Thanks,
Joey

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH 09/12] efi: libstub: install boot-time memory map as config table
  2022-09-20 10:40   ` Joey Gouly
@ 2022-09-20 11:37     ` Ard Biesheuvel
  0 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-20 11:37 UTC (permalink / raw)
  To: Joey Gouly
  Cc: linux-efi, loongarch, linux, Arnd Bergmann, Ilias Apalodimas,
	Huacai Chen, Xi Ruoyao, nd

On Tue, 20 Sept 2022 at 12:41, Joey Gouly <joey.gouly@arm.com> wrote:
>
> Hi Ard,
>
> On Sun, Sep 18, 2022 at 11:35:41PM +0200, Ard Biesheuvel wrote:
> > 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 <ardb@kernel.org>
> > ---
> >  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/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);
> >       }
>
> You have another commit about removing goto kludges, so maybe write this like the following,
> rather than a goto into an 'else' statement?
>
> diff --git a/drivers/firmware/efi/libstub/mem.c b/drivers/firmware/efi/libstub/mem.c
> index feef8d4be113..2f22ef7c5232 100644
> --- a/drivers/firmware/efi/libstub/mem.c
> +++ b/drivers/firmware/efi/libstub/mem.c
> @@ -64,10 +64,12 @@ efi_status_t efi_get_memory_map(struct efi_boot_memmap *map)
>                         *map->key_ptr = key;
>                 if (map->desc_ver)
>                         *map->desc_ver = desc_version;
> -       } else {
> -               efi_bs_call(free_pool, m);
>         }
>
> +free_map:
> +       if (status != EFI_SUCCESS)
> +               efi_bs_call(free_pool, m);
> +
>  fail:
>         *map->map = m;
>         return status;
>

Yeah that might be better. Thanks for the suggestion.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-20  8:04                                             ` Ard Biesheuvel
@ 2022-09-20 13:12                                               ` Huacai Chen
  2022-09-20 14:53                                                 ` Ard Biesheuvel
  0 siblings, 1 reply; 40+ messages in thread
From: Huacai Chen @ 2022-09-20 13:12 UTC (permalink / raw)
  To: Ard Biesheuvel
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

Hi, Ard,

On Tue, Sep 20, 2022 at 4:04 PM Ard Biesheuvel <ardb@kernel.org> wrote:
>
> On Tue, 20 Sept 2022 at 03:45, Huacai Chen <chenhuacai@kernel.org> wrote:
> >
> > Hi, Ard,
> >
> ...
> > I'm very sorry, after an offline discussion with my colleagues,
> > non-EFI DT boot is still needed (very sadly, we want to drop non-EFI
> > firmware but we can't do that). However, for non-EFI DT boot we will
> > use the same parameter passing method (a0=efi boot flag, a1=cmdline,
> > a2=systemtable), firmware will generate a simple systemtable only for
> > DT. In this way all boot methods share the same logic, and also make
> > kexec easy to implement.
> >
>
> OK, that should work. So I suppose you create a EFI system table along
> with EFI configuration tables for DT, SMBIOS, etc? In this case, I
> suggest you omit the MEMMAP config table that I am adding here, so
> that there is no ambiguity between the EFI provided memory map and the
> one provided by DT.
>
> I think that should be a clean way to implement this.
OK, thanks.

I have merged efi-cleanups-for-v6.1-v2 to
https://github.com/loongson/linux/commits/loongarch-next. It seems
everything work well except kexec.

Huacai
>
> > So, let's make a0 the real "efi boot flag" and let it control
> > EFI_BOOT, for efistub, we can just pass "true" unconditionally
> > (whether support efi_novamap is not as important as the efi boot flag
> > for us, as you said, efi_novamap is just for broken firmware).
>
> Indeed. So as before, I will just set efi_novamap to false. You can
> still use noefi or efi=noruntime to turn off the EFI runtime pieces if
> needed (e.g., PREEMPT_RT tends to disable those by default to preserve
> their bounded worst case latency)

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT
  2022-09-20 13:12                                               ` Huacai Chen
@ 2022-09-20 14:53                                                 ` Ard Biesheuvel
  0 siblings, 0 replies; 40+ messages in thread
From: Ard Biesheuvel @ 2022-09-20 14:53 UTC (permalink / raw)
  To: Huacai Chen
  Cc: linux-efi, loongarch, Russell King (Oracle),
	Arnd Bergmann, Ilias Apalodimas, Huacai Chen, Xi Ruoyao

On Tue, 20 Sept 2022 at 15:12, Huacai Chen <chenhuacai@kernel.org> wrote:
>
> Hi, Ard,
>
> On Tue, Sep 20, 2022 at 4:04 PM Ard Biesheuvel <ardb@kernel.org> wrote:
> >
> > On Tue, 20 Sept 2022 at 03:45, Huacai Chen <chenhuacai@kernel.org> wrote:
> > >
> > > Hi, Ard,
> > >
> > ...
> > > I'm very sorry, after an offline discussion with my colleagues,
> > > non-EFI DT boot is still needed (very sadly, we want to drop non-EFI
> > > firmware but we can't do that). However, for non-EFI DT boot we will
> > > use the same parameter passing method (a0=efi boot flag, a1=cmdline,
> > > a2=systemtable), firmware will generate a simple systemtable only for
> > > DT. In this way all boot methods share the same logic, and also make
> > > kexec easy to implement.
> > >
> >
> > OK, that should work. So I suppose you create a EFI system table along
> > with EFI configuration tables for DT, SMBIOS, etc? In this case, I
> > suggest you omit the MEMMAP config table that I am adding here, so
> > that there is no ambiguity between the EFI provided memory map and the
> > one provided by DT.
> >
> > I think that should be a clean way to implement this.
> OK, thanks.
>
> I have merged efi-cleanups-for-v6.1-v2 to
> https://github.com/loongson/linux/commits/loongarch-next. It seems
> everything work well except kexec.
>

OK thanks for testing. I will send out a v2 today and merge the
changes into efi/next tomorrow.

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2022-09-20 14:54 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-18 21:35 [PATCH 00/12] efi: disentangle the generic EFI stub from FDT Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 01/12] efi: libstub: drop pointless get_memory_map() call Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 02/12] efi/arm: libstub: move ARM specific code out of generic routines Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 03/12] efi: libstub: fix up the last remaining open coded boot service call Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 04/12] efi: libstub: fix type confusion for load_options_size Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 05/12] efi: libstub: avoid efi_get_memory_map() for allocating the virt map Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 06/12] efi: libstub: simplify efi_get_memory_map() and struct efi_boot_memmap Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 07/12] efi: libstub: unify initrd loading between architectures Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 08/12] efi: libstub: remove DT dependency from generic stub Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 09/12] efi: libstub: install boot-time memory map as config table Ard Biesheuvel
2022-09-20 10:40   ` Joey Gouly
2022-09-20 11:37     ` Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 10/12] efi: libstub: remove pointless goto kludge Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 11/12] efi/loongarch: libstub: remove dependency on flattened DT Ard Biesheuvel
2022-09-19  1:58   ` Huacai Chen
2022-09-19  5:15     ` Ard Biesheuvel
2022-09-19  6:06       ` Huacai Chen
2022-09-19  6:22         ` Ard Biesheuvel
2022-09-19  6:33           ` Ard Biesheuvel
2022-09-19 10:33           ` Huacai Chen
2022-09-19 10:37             ` Ard Biesheuvel
2022-09-19 10:47               ` Huacai Chen
2022-09-19 10:49                 ` Ard Biesheuvel
2022-09-19 11:15                   ` Huacai Chen
2022-09-19 11:21                     ` Ard Biesheuvel
2022-09-19 11:57                       ` Huacai Chen
2022-09-19 12:10                         ` Ard Biesheuvel
2022-09-19 12:14                           ` Huacai Chen
2022-09-19 12:27                             ` Ard Biesheuvel
2022-09-19 14:25                               ` Huacai Chen
2022-09-19 14:32                                 ` Ard Biesheuvel
2022-09-19 14:43                                   ` Huacai Chen
2022-09-19 14:44                                     ` Ard Biesheuvel
2022-09-19 15:08                                       ` Huacai Chen
2022-09-19 15:50                                         ` Ard Biesheuvel
2022-09-20  1:44                                           ` Huacai Chen
2022-09-20  8:04                                             ` Ard Biesheuvel
2022-09-20 13:12                                               ` Huacai Chen
2022-09-20 14:53                                                 ` Ard Biesheuvel
2022-09-18 21:35 ` [PATCH 12/12] efi: loongarch: add support for DT hardware descriptions Ard Biesheuvel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.