* [PATCH 0/3] efi: Simply DT handoff from stub to kernel
@ 2026-08-13 7:45 Ard Biesheuvel
2026-08-13 7:45 ` [PATCH 1/3] efi: Turn boot memmap handling into shared code Ard Biesheuvel
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: Ard Biesheuvel @ 2026-08-13 7:45 UTC (permalink / raw)
To: linux-efi
Cc: linux-arm-kernel, Ard Biesheuvel, Huacai Chen, WANG Xuerui,
loongarch
Currently, 4 separate DT properties are used as an internal ABI to hand
over the EFI memory map from the EFI stub to the kernel proper.
This information is redundant, as the same information is already made
available via a EFI configuration table.
So replace those 4 DT properties with a single one that carries the
address of this config table, and make it optional, so that it can be
omitted in cases where the kernel is able to locate the table directly
via its GUID.
Cc: Huacai Chen <chenhuacai@kernel.org>
Cc: WANG Xuerui <kernel@xen0n.name>
Cc: loongarch@lists.linux.dev
Ard Biesheuvel (3):
efi: Turn boot memmap handling into shared code
efi: Pass EFI boot memmap struct address to core kernel
efi: Make the 'linux,uefi-boot-memmap' DT property optional
Documentation/arch/arm/uefi.rst | 10 +--
arch/loongarch/kernel/efi.c | 10 +--
drivers/firmware/efi/efi.c | 4 +
drivers/firmware/efi/fdtparams.c | 77 ++++++++++++++++++--
drivers/firmware/efi/libstub/fdt.c | 40 +---------
include/linux/efi.h | 3 +
6 files changed, 84 insertions(+), 60 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 13+ messages in thread* [PATCH 1/3] efi: Turn boot memmap handling into shared code 2026-08-13 7:45 [PATCH 0/3] efi: Simply DT handoff from stub to kernel Ard Biesheuvel @ 2026-08-13 7:45 ` Ard Biesheuvel 2026-08-13 8:24 ` Richard Lyu 2026-08-13 7:45 ` [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel Ard Biesheuvel 2026-08-13 7:45 ` [PATCH 3/3] efi: Make the 'linux,uefi-boot-memmap' DT property optional Ard Biesheuvel 2 siblings, 1 reply; 13+ messages in thread From: Ard Biesheuvel @ 2026-08-13 7:45 UTC (permalink / raw) To: linux-efi Cc: linux-arm-kernel, Ard Biesheuvel, Huacai Chen, WANG Xuerui, loongarch Move the handling of the boot memmap config table from loongarch specific code to code that is shared between all architectures that select EFI_GENERIC_STUB (all EFI archs except x86). This will be used in a subsequent patch to replace the clunky FDT based passing of the memmap parameters. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> --- arch/loongarch/kernel/efi.c | 10 ++++------ drivers/firmware/efi/efi.c | 4 ++++ include/linux/efi.h | 3 +++ 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index 69dd83f8082f..089378856bab 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -28,12 +28,10 @@ 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 fdt_pointer = 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, &fdt_pointer, "FDTPTR" }, {}, }; @@ -132,14 +130,14 @@ void __init efi_init(void) if (IS_ENABLED(CONFIG_EFI_EARLYCON) || IS_ENABLED(CONFIG_SYSFB)) init_primary_display(); - if (boot_memmap == EFI_INVALID_TABLE_ADDR) + if (efi.boot_memmap == EFI_INVALID_TABLE_ADDR) return; - tbl = early_memremap_ro(boot_memmap, sizeof(*tbl)); + tbl = early_memremap_ro(efi.boot_memmap, sizeof(*tbl)); if (tbl) { struct efi_memory_map_data data; - data.phys_map = boot_memmap + sizeof(*tbl); + data.phys_map = efi.boot_memmap + sizeof(*tbl); data.size = tbl->map_size; data.desc_size = tbl->desc_size; data.desc_version = tbl->desc_ver; @@ -156,7 +154,7 @@ void __init efi_init(void) * Also, set the EFI_PRESERVE_BS_REGIONS flag to indicate that * critical boot services code/data regions like this are preserved. */ - memblock_reserve((phys_addr_t)boot_memmap, sizeof(*tbl) + data.size); + memblock_reserve((phys_addr_t)efi.boot_memmap, sizeof(*tbl) + data.size); set_bit(EFI_PRESERVE_BS_REGIONS, &efi.flags); early_memunmap(tbl, sizeof(*tbl)); diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 0327a39d31fa..d33760d6a527 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c @@ -55,6 +55,9 @@ struct efi __read_mostly efi = { #ifdef CONFIG_UNACCEPTED_MEMORY .unaccepted = EFI_INVALID_TABLE_ADDR, #endif +#ifdef CONFIG_EFI_GENERIC_STUB + .boot_memmap = EFI_INVALID_TABLE_ADDR, +#endif }; EXPORT_SYMBOL(efi); @@ -647,6 +650,7 @@ static const efi_config_table_type_t common_tables[] __initconst = { {LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID, &efi.unaccepted, "Unaccepted" }, #endif #ifdef CONFIG_EFI_GENERIC_STUB + {LINUX_EFI_BOOT_MEMMAP_GUID, &efi.boot_memmap, "MEMMAP" }, {LINUX_EFI_PRIMARY_DISPLAY_TABLE_GUID, &primary_display_table }, #endif {}, diff --git a/include/linux/efi.h b/include/linux/efi.h index aa15ff88539b..bc1cd005ca0f 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -650,6 +650,9 @@ extern struct efi { unsigned long mokvar_table; /* MOK variable config table */ unsigned long coco_secret; /* Confidential computing secret table */ unsigned long unaccepted; /* Unaccepted memory table */ +#ifdef CONFIG_EFI_GENERIC_STUB + unsigned long boot_memmap; /* The EFI memory map captured by the stub */ +#endif efi_get_time_t *get_time; efi_set_time_t *set_time; -- 2.47.3 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3] efi: Turn boot memmap handling into shared code 2026-08-13 7:45 ` [PATCH 1/3] efi: Turn boot memmap handling into shared code Ard Biesheuvel @ 2026-08-13 8:24 ` Richard Lyu 0 siblings, 0 replies; 13+ messages in thread From: Richard Lyu @ 2026-08-13 8:24 UTC (permalink / raw) To: Ard Biesheuvel Cc: linux-efi, linux-arm-kernel, Huacai Chen, WANG Xuerui, loongarch On 2026/08/13 09:45, Ard Biesheuvel wrote: >Move the handling of the boot memmap config table from loongarch >specific code to code that is shared between all architectures that >select EFI_GENERIC_STUB (all EFI archs except x86). > >This will be used in a subsequent patch to replace the clunky FDT based >passing of the memmap parameters. > >Signed-off-by: Ard Biesheuvel <ardb@kernel.org> >--- > arch/loongarch/kernel/efi.c | 10 ++++------ > drivers/firmware/efi/efi.c | 4 ++++ > include/linux/efi.h | 3 +++ > 3 files changed, 11 insertions(+), 6 deletions(-) > >diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c >index 69dd83f8082f..089378856bab 100644 >--- a/arch/loongarch/kernel/efi.c >+++ b/arch/loongarch/kernel/efi.c >@@ -28,12 +28,10 @@ > 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 fdt_pointer = 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, &fdt_pointer, "FDTPTR" }, > {}, > }; >@@ -132,14 +130,14 @@ void __init efi_init(void) > if (IS_ENABLED(CONFIG_EFI_EARLYCON) || IS_ENABLED(CONFIG_SYSFB)) > init_primary_display(); > >- if (boot_memmap == EFI_INVALID_TABLE_ADDR) >+ if (efi.boot_memmap == EFI_INVALID_TABLE_ADDR) > return; > >- tbl = early_memremap_ro(boot_memmap, sizeof(*tbl)); >+ tbl = early_memremap_ro(efi.boot_memmap, sizeof(*tbl)); > if (tbl) { > struct efi_memory_map_data data; > >- data.phys_map = boot_memmap + sizeof(*tbl); >+ data.phys_map = efi.boot_memmap + sizeof(*tbl); > data.size = tbl->map_size; > data.desc_size = tbl->desc_size; > data.desc_version = tbl->desc_ver; >@@ -156,7 +154,7 @@ void __init efi_init(void) > * Also, set the EFI_PRESERVE_BS_REGIONS flag to indicate that > * critical boot services code/data regions like this are preserved. > */ >- memblock_reserve((phys_addr_t)boot_memmap, sizeof(*tbl) + data.size); >+ memblock_reserve((phys_addr_t)efi.boot_memmap, sizeof(*tbl) + data.size); > set_bit(EFI_PRESERVE_BS_REGIONS, &efi.flags); > > early_memunmap(tbl, sizeof(*tbl)); >diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c >index 0327a39d31fa..d33760d6a527 100644 >--- a/drivers/firmware/efi/efi.c >+++ b/drivers/firmware/efi/efi.c >@@ -55,6 +55,9 @@ struct efi __read_mostly efi = { > #ifdef CONFIG_UNACCEPTED_MEMORY > .unaccepted = EFI_INVALID_TABLE_ADDR, > #endif >+#ifdef CONFIG_EFI_GENERIC_STUB >+ .boot_memmap = EFI_INVALID_TABLE_ADDR, >+#endif > }; > EXPORT_SYMBOL(efi); > >@@ -647,6 +650,7 @@ static const efi_config_table_type_t common_tables[] __initconst = { > {LINUX_EFI_UNACCEPTED_MEM_TABLE_GUID, &efi.unaccepted, "Unaccepted" }, > #endif > #ifdef CONFIG_EFI_GENERIC_STUB >+ {LINUX_EFI_BOOT_MEMMAP_GUID, &efi.boot_memmap, "MEMMAP" }, > {LINUX_EFI_PRIMARY_DISPLAY_TABLE_GUID, &primary_display_table }, > #endif > {}, >diff --git a/include/linux/efi.h b/include/linux/efi.h >index aa15ff88539b..bc1cd005ca0f 100644 >--- a/include/linux/efi.h >+++ b/include/linux/efi.h >@@ -650,6 +650,9 @@ extern struct efi { > unsigned long mokvar_table; /* MOK variable config table */ > unsigned long coco_secret; /* Confidential computing secret table */ > unsigned long unaccepted; /* Unaccepted memory table */ >+#ifdef CONFIG_EFI_GENERIC_STUB >+ unsigned long boot_memmap; /* The EFI memory map captured by the stub */ >+#endif > > efi_get_time_t *get_time; > efi_set_time_t *set_time; >-- >2.47.3 > > Reviewed-by: Richard Lyu <richard.lyu@suse.com> ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel 2026-08-13 7:45 [PATCH 0/3] efi: Simply DT handoff from stub to kernel Ard Biesheuvel 2026-08-13 7:45 ` [PATCH 1/3] efi: Turn boot memmap handling into shared code Ard Biesheuvel @ 2026-08-13 7:45 ` Ard Biesheuvel 2026-08-13 8:25 ` Richard Lyu 2026-08-14 15:16 ` Leif Lindholm 2026-08-13 7:45 ` [PATCH 3/3] efi: Make the 'linux,uefi-boot-memmap' DT property optional Ard Biesheuvel 2 siblings, 2 replies; 13+ messages in thread From: Ard Biesheuvel @ 2026-08-13 7:45 UTC (permalink / raw) To: linux-efi Cc: linux-arm-kernel, Ard Biesheuvel, Huacai Chen, WANG Xuerui, loongarch The EFI stub already passes a struct efi_boot_memmap populated with the information of the EFI memory map as a configuration table, and so passing the physical address, size, descriptor size and descriptor version via 4 different DT properties is kind of redundant. Instead, pass the physical address of this struct in memory so that the kernel can just retrieve the values directly. Unfortunately, the scheme with four separate properties is boot ABI for Xen, and so this needs to remain supported. But for the EFI stub itself, this is just an internal ABI that can be modified. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> --- Documentation/arch/arm/uefi.rst | 10 +---- drivers/firmware/efi/fdtparams.c | 39 ++++++++++++++++--- drivers/firmware/efi/libstub/fdt.c | 40 ++------------------ 3 files changed, 37 insertions(+), 52 deletions(-) diff --git a/Documentation/arch/arm/uefi.rst b/Documentation/arch/arm/uefi.rst index 2b7ad9bd7cd2..c19cf3720f27 100644 --- a/Documentation/arch/arm/uefi.rst +++ b/Documentation/arch/arm/uefi.rst @@ -54,17 +54,9 @@ Name Type Description ========================== ====== =========================================== linux,uefi-system-table 64-bit Physical address of the UEFI System Table. -linux,uefi-mmap-start 64-bit Physical address of the UEFI memory map, +linux,uefi-boot-memmap 64-bit Physical address of a struct efi_boot_memmap populated by the UEFI GetMemoryMap() call. -linux,uefi-mmap-size 32-bit Size in bytes of the UEFI memory map - pointed to in previous entry. - -linux,uefi-mmap-desc-size 32-bit Size in bytes of each entry in the UEFI - memory map. - -linux,uefi-mmap-desc-ver 32-bit Version of the mmap descriptor format. - kaslr-seed 64-bit Entropy used to randomize the kernel image base address location. diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c index b815d2a754ee..a54a76a6aaeb 100644 --- a/drivers/firmware/efi/fdtparams.c +++ b/drivers/firmware/efi/fdtparams.c @@ -10,22 +10,30 @@ #include <linux/unaligned.h> +#include <asm/early_ioremap.h> + enum { SYSTAB, + MEMMAP, +#ifdef CONFIG_XEN MMBASE, MMSIZE, DCSIZE, DCVERS, +#endif PARAMCOUNT }; static __initconst const char name[][22] = { [SYSTAB] = "System Table ", + [MEMMAP] = "Boot Memory Map ", +#ifdef CONFIG_XEN [MMBASE] = "MemMap Address ", [MMSIZE] = "MemMap Size ", [DCSIZE] = "MemMap Desc. Size ", [DCVERS] = "MemMap Desc. Version ", +#endif }; static __initconst const struct { @@ -49,10 +57,7 @@ static __initconst const struct { .path = "/chosen", .params = { // <-----------26-----------> [SYSTAB] = "linux,uefi-system-table", - [MMBASE] = "linux,uefi-mmap-start", - [MMSIZE] = "linux,uefi-mmap-size", - [DCSIZE] = "linux,uefi-mmap-desc-size", - [DCVERS] = "linux,uefi-mmap-desc-ver", + [MEMMAP] = "linux,uefi-boot-memmap", } } }; @@ -84,17 +89,20 @@ static int __init efi_get_fdt_prop(const void *fdt, int node, const char *pname, u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) { const void *fdt = initial_boot_params; - unsigned long systab; + unsigned long systab, memmap; int i, j, node; struct { void *var; int size; } target[] = { [SYSTAB] = { &systab, sizeof(systab) }, + [MEMMAP] = { &memmap, sizeof(memmap) }, +#ifdef CONFIG_XEN [MMBASE] = { &mm->phys_map, sizeof(mm->phys_map) }, [MMSIZE] = { &mm->size, sizeof(mm->size) }, [DCSIZE] = { &mm->desc_size, sizeof(mm->desc_size) }, [DCVERS] = { &mm->desc_version, sizeof(mm->desc_version) }, +#endif }; BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name)); @@ -115,6 +123,9 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) for (j = 0; j < ARRAY_SIZE(target); j++) { const char *pname = dt_params[i].params[j]; + if (pname[0] == '\0') + continue; + if (!efi_get_fdt_prop(fdt, node, pname, name[j], target[j].var, target[j].size)) continue; @@ -123,8 +134,24 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) pr_err("Can't find property '%s' in DT!\n", pname); return 0; } - if (dt_params[i].paravirt) + if (IS_ENABLED(CONFIG_XEN) && dt_params[i].paravirt) { set_bit(EFI_PARAVIRT, &efi.flags); + } else { + struct efi_boot_memmap *bm; + + bm = early_memremap_ro(memmap, sizeof(*bm)); + if (!bm) { + pr_err("Cannot remap EFI boot memory map\n"); + return 0; + } + + mm->phys_map = memmap + sizeof(*bm); + mm->size = bm->map_size; + mm->desc_size = bm->desc_size; + mm->desc_version = bm->desc_ver; + + early_memunmap(bm, sizeof(*bm)); + } return systab; } notfound: diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c index 23b3543d3041..417b1344bdd8 100644 --- a/drivers/firmware/efi/libstub/fdt.c +++ b/drivers/firmware/efi/libstub/fdt.c @@ -32,7 +32,6 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, { int node, num_rsv; int status; - fdt32_t fdt_val32; fdt64_t fdt_val64; /* Do some checks on provided FDT, if it exists: */ @@ -102,21 +101,7 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, fdt_val64 = cpu_to_fdt64(U64_MAX); /* placeholder */ - status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-start", fdt_val64); - if (status) - goto fdt_set_fail; - - fdt_val32 = cpu_to_fdt32(U32_MAX); /* placeholder */ - - status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-size", fdt_val32); - if (status) - goto fdt_set_fail; - - status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-desc-size", fdt_val32); - if (status) - goto fdt_set_fail; - - status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32); + status = fdt_setprop_var(fdt, node, "linux,uefi-boot-memmap", fdt_val64); if (status) goto fdt_set_fail; @@ -148,33 +133,14 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map) { int node = fdt_path_offset(fdt, "/chosen"); fdt64_t fdt_val64; - fdt32_t fdt_val32; int err; if (node < 0) return EFI_LOAD_ERROR; - 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); - - 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); - - 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_val64 = cpu_to_fdt64((unsigned long)map); - err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32); + err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-boot-memmap", fdt_val64); if (err) return EFI_LOAD_ERROR; -- 2.47.3 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel 2026-08-13 7:45 ` [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel Ard Biesheuvel @ 2026-08-13 8:25 ` Richard Lyu 2026-08-14 15:16 ` Leif Lindholm 1 sibling, 0 replies; 13+ messages in thread From: Richard Lyu @ 2026-08-13 8:25 UTC (permalink / raw) To: Ard Biesheuvel Cc: linux-efi, linux-arm-kernel, Huacai Chen, WANG Xuerui, loongarch On 2026/08/13 09:45, Ard Biesheuvel wrote: >The EFI stub already passes a struct efi_boot_memmap populated with the >information of the EFI memory map as a configuration table, and so >passing the physical address, size, descriptor size and descriptor >version via 4 different DT properties is kind of redundant. > >Instead, pass the physical address of this struct in memory so that the >kernel can just retrieve the values directly. > >Unfortunately, the scheme with four separate properties is boot ABI for >Xen, and so this needs to remain supported. But for the EFI stub itself, >this is just an internal ABI that can be modified. > >Signed-off-by: Ard Biesheuvel <ardb@kernel.org> >--- > Documentation/arch/arm/uefi.rst | 10 +---- > drivers/firmware/efi/fdtparams.c | 39 ++++++++++++++++--- > drivers/firmware/efi/libstub/fdt.c | 40 ++------------------ > 3 files changed, 37 insertions(+), 52 deletions(-) > >diff --git a/Documentation/arch/arm/uefi.rst b/Documentation/arch/arm/uefi.rst >index 2b7ad9bd7cd2..c19cf3720f27 100644 >--- a/Documentation/arch/arm/uefi.rst >+++ b/Documentation/arch/arm/uefi.rst >@@ -54,17 +54,9 @@ Name Type Description > ========================== ====== =========================================== > linux,uefi-system-table 64-bit Physical address of the UEFI System Table. > >-linux,uefi-mmap-start 64-bit Physical address of the UEFI memory map, >+linux,uefi-boot-memmap 64-bit Physical address of a struct efi_boot_memmap > populated by the UEFI GetMemoryMap() call. > >-linux,uefi-mmap-size 32-bit Size in bytes of the UEFI memory map >- pointed to in previous entry. >- >-linux,uefi-mmap-desc-size 32-bit Size in bytes of each entry in the UEFI >- memory map. >- >-linux,uefi-mmap-desc-ver 32-bit Version of the mmap descriptor format. >- > kaslr-seed 64-bit Entropy used to randomize the kernel image > base address location. > >diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c >index b815d2a754ee..a54a76a6aaeb 100644 >--- a/drivers/firmware/efi/fdtparams.c >+++ b/drivers/firmware/efi/fdtparams.c >@@ -10,22 +10,30 @@ > > #include <linux/unaligned.h> > >+#include <asm/early_ioremap.h> >+ > enum { > SYSTAB, >+ MEMMAP, >+#ifdef CONFIG_XEN > MMBASE, > MMSIZE, > DCSIZE, > DCVERS, >+#endif > > PARAMCOUNT > }; > > static __initconst const char name[][22] = { > [SYSTAB] = "System Table ", >+ [MEMMAP] = "Boot Memory Map ", >+#ifdef CONFIG_XEN > [MMBASE] = "MemMap Address ", > [MMSIZE] = "MemMap Size ", > [DCSIZE] = "MemMap Desc. Size ", > [DCVERS] = "MemMap Desc. Version ", >+#endif > }; > > static __initconst const struct { >@@ -49,10 +57,7 @@ static __initconst const struct { > .path = "/chosen", > .params = { // <-----------26-----------> > [SYSTAB] = "linux,uefi-system-table", >- [MMBASE] = "linux,uefi-mmap-start", >- [MMSIZE] = "linux,uefi-mmap-size", >- [DCSIZE] = "linux,uefi-mmap-desc-size", >- [DCVERS] = "linux,uefi-mmap-desc-ver", >+ [MEMMAP] = "linux,uefi-boot-memmap", > } > } > }; >@@ -84,17 +89,20 @@ static int __init efi_get_fdt_prop(const void *fdt, int node, const char *pname, > u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) > { > const void *fdt = initial_boot_params; >- unsigned long systab; >+ unsigned long systab, memmap; > int i, j, node; > struct { > void *var; > int size; > } target[] = { > [SYSTAB] = { &systab, sizeof(systab) }, >+ [MEMMAP] = { &memmap, sizeof(memmap) }, >+#ifdef CONFIG_XEN > [MMBASE] = { &mm->phys_map, sizeof(mm->phys_map) }, > [MMSIZE] = { &mm->size, sizeof(mm->size) }, > [DCSIZE] = { &mm->desc_size, sizeof(mm->desc_size) }, > [DCVERS] = { &mm->desc_version, sizeof(mm->desc_version) }, >+#endif > }; > > BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name)); >@@ -115,6 +123,9 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) > for (j = 0; j < ARRAY_SIZE(target); j++) { > const char *pname = dt_params[i].params[j]; > >+ if (pname[0] == '\0') >+ continue; >+ > if (!efi_get_fdt_prop(fdt, node, pname, name[j], > target[j].var, target[j].size)) > continue; >@@ -123,8 +134,24 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) > pr_err("Can't find property '%s' in DT!\n", pname); > return 0; > } >- if (dt_params[i].paravirt) >+ if (IS_ENABLED(CONFIG_XEN) && dt_params[i].paravirt) { > set_bit(EFI_PARAVIRT, &efi.flags); >+ } else { >+ struct efi_boot_memmap *bm; >+ >+ bm = early_memremap_ro(memmap, sizeof(*bm)); >+ if (!bm) { >+ pr_err("Cannot remap EFI boot memory map\n"); >+ return 0; >+ } >+ >+ mm->phys_map = memmap + sizeof(*bm); >+ mm->size = bm->map_size; >+ mm->desc_size = bm->desc_size; >+ mm->desc_version = bm->desc_ver; >+ >+ early_memunmap(bm, sizeof(*bm)); >+ } > return systab; > } > notfound: >diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c >index 23b3543d3041..417b1344bdd8 100644 >--- a/drivers/firmware/efi/libstub/fdt.c >+++ b/drivers/firmware/efi/libstub/fdt.c >@@ -32,7 +32,6 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, > { > int node, num_rsv; > int status; >- fdt32_t fdt_val32; > fdt64_t fdt_val64; > > /* Do some checks on provided FDT, if it exists: */ >@@ -102,21 +101,7 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, > > fdt_val64 = cpu_to_fdt64(U64_MAX); /* placeholder */ > >- status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-start", fdt_val64); >- if (status) >- goto fdt_set_fail; >- >- fdt_val32 = cpu_to_fdt32(U32_MAX); /* placeholder */ >- >- status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-size", fdt_val32); >- if (status) >- goto fdt_set_fail; >- >- status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-desc-size", fdt_val32); >- if (status) >- goto fdt_set_fail; >- >- status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32); >+ status = fdt_setprop_var(fdt, node, "linux,uefi-boot-memmap", fdt_val64); > if (status) > goto fdt_set_fail; > >@@ -148,33 +133,14 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map) > { > int node = fdt_path_offset(fdt, "/chosen"); > fdt64_t fdt_val64; >- fdt32_t fdt_val32; > int err; > > if (node < 0) > return EFI_LOAD_ERROR; > >- 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); >- >- 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); >- >- 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_val64 = cpu_to_fdt64((unsigned long)map); > >- err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32); >+ err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-boot-memmap", fdt_val64); > if (err) > return EFI_LOAD_ERROR; > >-- >2.47.3 > > Reviewed-by: Richard Lyu <richard.lyu@suse.com> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel 2026-08-13 7:45 ` [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel Ard Biesheuvel 2026-08-13 8:25 ` Richard Lyu @ 2026-08-14 15:16 ` Leif Lindholm 2026-08-17 8:41 ` Ard Biesheuvel 1 sibling, 1 reply; 13+ messages in thread From: Leif Lindholm @ 2026-08-14 15:16 UTC (permalink / raw) To: Ard Biesheuvel Cc: linux-efi, linux-arm-kernel, Huacai Chen, WANG Xuerui, loongarch On Thu, Aug 13, 2026 at 09:45:09 +0200, Ard Biesheuvel wrote: > The EFI stub already passes a struct efi_boot_memmap populated with the > information of the EFI memory map as a configuration table, and so > passing the physical address, size, descriptor size and descriptor > version via 4 different DT properties is kind of redundant. > > Instead, pass the physical address of this struct in memory so that the > kernel can just retrieve the values directly. > > Unfortunately, the scheme with four separate properties is boot ABI for > Xen, and so this needs to remain supported. To clarify, you mean boot ABI when running under Xen? > But for the EFI stub itself, > this is just an internal ABI that can be modified. Hmm... So this leaves only three properties that cannot be derived from the System Table: - The System Table address itself - kaslr-seed - bootargs The latter two could also be given the config table treatment. Is it time to update the boot ABI to say x0 will hold the physical address of "device tree blob (dtb) or EFI System Table in system RAM"? They can be distinguished by 0xd00dfeed / "IBI SYST". The use of a generated DT when none was provided by firmware has led to both confusion and shenanigans, and might be nice to get rid of? Either way, it would be nice to get rid of all four of the linux,uefi-mmap nodes if they're now completely redundant. Minor bikeshedding below. > Signed-off-by: Ard Biesheuvel <ardb@kernel.org> > --- > Documentation/arch/arm/uefi.rst | 10 +---- > drivers/firmware/efi/fdtparams.c | 39 ++++++++++++++++--- > drivers/firmware/efi/libstub/fdt.c | 40 ++------------------ > 3 files changed, 37 insertions(+), 52 deletions(-) > > diff --git a/Documentation/arch/arm/uefi.rst b/Documentation/arch/arm/uefi.rst > index 2b7ad9bd7cd2..c19cf3720f27 100644 > --- a/Documentation/arch/arm/uefi.rst > +++ b/Documentation/arch/arm/uefi.rst > @@ -54,17 +54,9 @@ Name Type Description > ========================== ====== =========================================== > linux,uefi-system-table 64-bit Physical address of the UEFI System Table. > > -linux,uefi-mmap-start 64-bit Physical address of the UEFI memory map, > +linux,uefi-boot-memmap 64-bit Physical address of a struct efi_boot_memmap > populated by the UEFI GetMemoryMap() call. > > -linux,uefi-mmap-size 32-bit Size in bytes of the UEFI memory map > - pointed to in previous entry. > - > -linux,uefi-mmap-desc-size 32-bit Size in bytes of each entry in the UEFI > - memory map. > - > -linux,uefi-mmap-desc-ver 32-bit Version of the mmap descriptor format. > - > kaslr-seed 64-bit Entropy used to randomize the kernel image > base address location. > > diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c > index b815d2a754ee..a54a76a6aaeb 100644 > --- a/drivers/firmware/efi/fdtparams.c > +++ b/drivers/firmware/efi/fdtparams.c > @@ -10,22 +10,30 @@ > > #include <linux/unaligned.h> > > +#include <asm/early_ioremap.h> > + > enum { > SYSTAB, > + MEMMAP, > +#ifdef CONFIG_XEN > MMBASE, > MMSIZE, > DCSIZE, > DCVERS, > +#endif > > PARAMCOUNT > }; > > static __initconst const char name[][22] = { > [SYSTAB] = "System Table ", > + [MEMMAP] = "Boot Memory Map ", > +#ifdef CONFIG_XEN > [MMBASE] = "MemMap Address ", > [MMSIZE] = "MemMap Size ", > [DCSIZE] = "MemMap Desc. Size ", > [DCVERS] = "MemMap Desc. Version ", > +#endif > }; > > static __initconst const struct { > @@ -49,10 +57,7 @@ static __initconst const struct { > .path = "/chosen", > .params = { // <-----------26-----------> > [SYSTAB] = "linux,uefi-system-table", > - [MMBASE] = "linux,uefi-mmap-start", > - [MMSIZE] = "linux,uefi-mmap-size", > - [DCSIZE] = "linux,uefi-mmap-desc-size", > - [DCVERS] = "linux,uefi-mmap-desc-ver", > + [MEMMAP] = "linux,uefi-boot-memmap", > } > } > }; > @@ -84,17 +89,20 @@ static int __init efi_get_fdt_prop(const void *fdt, int node, const char *pname, > u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) > { > const void *fdt = initial_boot_params; > - unsigned long systab; > + unsigned long systab, memmap; > int i, j, node; > struct { > void *var; > int size; > } target[] = { > [SYSTAB] = { &systab, sizeof(systab) }, > + [MEMMAP] = { &memmap, sizeof(memmap) }, > +#ifdef CONFIG_XEN > [MMBASE] = { &mm->phys_map, sizeof(mm->phys_map) }, > [MMSIZE] = { &mm->size, sizeof(mm->size) }, > [DCSIZE] = { &mm->desc_size, sizeof(mm->desc_size) }, > [DCVERS] = { &mm->desc_version, sizeof(mm->desc_version) }, > +#endif > }; > > BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name)); > @@ -115,6 +123,9 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) > for (j = 0; j < ARRAY_SIZE(target); j++) { > const char *pname = dt_params[i].params[j]; > > + if (pname[0] == '\0') > + continue; > + > if (!efi_get_fdt_prop(fdt, node, pname, name[j], > target[j].var, target[j].size)) > continue; > @@ -123,8 +134,24 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) > pr_err("Can't find property '%s' in DT!\n", pname); > return 0; > } > - if (dt_params[i].paravirt) > + if (IS_ENABLED(CONFIG_XEN) && dt_params[i].paravirt) { > set_bit(EFI_PARAVIRT, &efi.flags); > + } else { This condition branch doesn't in fact have anything to do with the fdt. Should it still live in fdtparams.c? / Leif > + struct efi_boot_memmap *bm; > + > + bm = early_memremap_ro(memmap, sizeof(*bm)); > + if (!bm) { > + pr_err("Cannot remap EFI boot memory map\n"); > + return 0; > + } > + > + mm->phys_map = memmap + sizeof(*bm); > + mm->size = bm->map_size; > + mm->desc_size = bm->desc_size; > + mm->desc_version = bm->desc_ver; > + > + early_memunmap(bm, sizeof(*bm)); > + } > return systab; > } > notfound: > diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c > index 23b3543d3041..417b1344bdd8 100644 > --- a/drivers/firmware/efi/libstub/fdt.c > +++ b/drivers/firmware/efi/libstub/fdt.c > @@ -32,7 +32,6 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, > { > int node, num_rsv; > int status; > - fdt32_t fdt_val32; > fdt64_t fdt_val64; > > /* Do some checks on provided FDT, if it exists: */ > @@ -102,21 +101,7 @@ static efi_status_t update_fdt(void *orig_fdt, unsigned long orig_fdt_size, > > fdt_val64 = cpu_to_fdt64(U64_MAX); /* placeholder */ > > - status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-start", fdt_val64); > - if (status) > - goto fdt_set_fail; > - > - fdt_val32 = cpu_to_fdt32(U32_MAX); /* placeholder */ > - > - status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-size", fdt_val32); > - if (status) > - goto fdt_set_fail; > - > - status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-desc-size", fdt_val32); > - if (status) > - goto fdt_set_fail; > - > - status = fdt_setprop_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32); > + status = fdt_setprop_var(fdt, node, "linux,uefi-boot-memmap", fdt_val64); > if (status) > goto fdt_set_fail; > > @@ -148,33 +133,14 @@ static efi_status_t update_fdt_memmap(void *fdt, struct efi_boot_memmap *map) > { > int node = fdt_path_offset(fdt, "/chosen"); > fdt64_t fdt_val64; > - fdt32_t fdt_val32; > int err; > > if (node < 0) > return EFI_LOAD_ERROR; > > - 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); > - > - 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); > - > - 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_val64 = cpu_to_fdt64((unsigned long)map); > > - err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-mmap-desc-ver", fdt_val32); > + err = fdt_setprop_inplace_var(fdt, node, "linux,uefi-boot-memmap", fdt_val64); > if (err) > return EFI_LOAD_ERROR; > > -- > 2.47.3 > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel 2026-08-14 15:16 ` Leif Lindholm @ 2026-08-17 8:41 ` Ard Biesheuvel 2026-08-17 9:18 ` Leif Lindholm 0 siblings, 1 reply; 13+ messages in thread From: Ard Biesheuvel @ 2026-08-17 8:41 UTC (permalink / raw) To: Leif Lindholm Cc: linux-efi, linux-arm-kernel, Huacai Chen, WANG Xuerui, loongarch On Fri, 14 Aug 2026, at 18:16, Leif Lindholm wrote: > On Thu, Aug 13, 2026 at 09:45:09 +0200, Ard Biesheuvel wrote: >> The EFI stub already passes a struct efi_boot_memmap populated with the >> information of the EFI memory map as a configuration table, and so >> passing the physical address, size, descriptor size and descriptor >> version via 4 different DT properties is kind of redundant. >> >> Instead, pass the physical address of this struct in memory so that the >> kernel can just retrieve the values directly. >> >> Unfortunately, the scheme with four separate properties is boot ABI for >> Xen, and so this needs to remain supported. > > To clarify, you mean boot ABI when running under Xen? > Yes. We've allowed Xen dom0 to omit the EFI stub entirely, and boot the kernel proper in EFI mode, passing the EFI system table and memory map addresses via these special DT properties. >> But for the EFI stub itself, >> this is just an internal ABI that can be modified. > > Hmm... > > So this leaves only three properties that cannot be derived from the > System Table: > - The System Table address itself > - kaslr-seed > - bootargs > > The latter two could also be given the config table treatment. > The latter two are generic boot ABI for the arm64 kernel, and there is no need to treat them differently for EFI boot. Note that we also support passing the initrd directly via DT when doing EFI boot, rather than via the EFI specific device path. > Is it time to update the boot ABI to say x0 will hold the physical > address of "device tree blob (dtb) or EFI System Table in system RAM"? > They can be distinguished by 0xd00dfeed / "IBI SYST". > Let's avoid 'boot ABI' here, given that we are talking about an internal interface between the EFI stub and the kernel proper. This internal interface uses DT under the hood, even on ACPI platforms, because it simplifies the early boot code. I don't think we should change this. Also, the DT provided by the bootloader (if any) may differ from the one passed by the EFI stub, and so discovering the DT from the EFI system table is not straight-forward - they are not the same, and making them the same may have unintended side effects. > The use of a generated DT when none was provided by firmware has led > to both confusion and shenanigans, and might be nice to get rid of? > I don't disagree with that. But that would imply adding new code to the early startup code doing command line parsing and KASLR randomization to reason about whether these assets are passed via DT or via some other means. What would make sense imo is to pass the EFI system table address via X1 when doing EFI boot, so we don't have to get anything at all from the DT. > Either way, it would be nice to get rid of all four of the > linux,uefi-mmap nodes if they're now completely redundant. > Indeed. > Minor bikeshedding below. > >> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> >> --- >> Documentation/arch/arm/uefi.rst | 10 +---- >> drivers/firmware/efi/fdtparams.c | 39 ++++++++++++++++--- >> drivers/firmware/efi/libstub/fdt.c | 40 ++------------------ >> 3 files changed, 37 insertions(+), 52 deletions(-) >> >> diff --git a/Documentation/arch/arm/uefi.rst b/Documentation/arch/arm/uefi.rst >> index 2b7ad9bd7cd2..c19cf3720f27 100644 >> --- a/Documentation/arch/arm/uefi.rst >> +++ b/Documentation/arch/arm/uefi.rst >> @@ -54,17 +54,9 @@ Name Type Description >> ========================== ====== =========================================== >> linux,uefi-system-table 64-bit Physical address of the UEFI System Table. >> >> -linux,uefi-mmap-start 64-bit Physical address of the UEFI memory map, >> +linux,uefi-boot-memmap 64-bit Physical address of a struct efi_boot_memmap >> populated by the UEFI GetMemoryMap() call. >> >> -linux,uefi-mmap-size 32-bit Size in bytes of the UEFI memory map >> - pointed to in previous entry. >> - >> -linux,uefi-mmap-desc-size 32-bit Size in bytes of each entry in the UEFI >> - memory map. >> - >> -linux,uefi-mmap-desc-ver 32-bit Version of the mmap descriptor format. >> - >> kaslr-seed 64-bit Entropy used to randomize the kernel image >> base address location. >> >> diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c >> index b815d2a754ee..a54a76a6aaeb 100644 >> --- a/drivers/firmware/efi/fdtparams.c >> +++ b/drivers/firmware/efi/fdtparams.c >> @@ -10,22 +10,30 @@ >> >> #include <linux/unaligned.h> >> >> +#include <asm/early_ioremap.h> >> + >> enum { >> SYSTAB, >> + MEMMAP, >> +#ifdef CONFIG_XEN >> MMBASE, >> MMSIZE, >> DCSIZE, >> DCVERS, >> +#endif >> >> PARAMCOUNT >> }; >> >> static __initconst const char name[][22] = { >> [SYSTAB] = "System Table ", >> + [MEMMAP] = "Boot Memory Map ", >> +#ifdef CONFIG_XEN >> [MMBASE] = "MemMap Address ", >> [MMSIZE] = "MemMap Size ", >> [DCSIZE] = "MemMap Desc. Size ", >> [DCVERS] = "MemMap Desc. Version ", >> +#endif >> }; >> >> static __initconst const struct { >> @@ -49,10 +57,7 @@ static __initconst const struct { >> .path = "/chosen", >> .params = { // <-----------26-----------> >> [SYSTAB] = "linux,uefi-system-table", >> - [MMBASE] = "linux,uefi-mmap-start", >> - [MMSIZE] = "linux,uefi-mmap-size", >> - [DCSIZE] = "linux,uefi-mmap-desc-size", >> - [DCVERS] = "linux,uefi-mmap-desc-ver", >> + [MEMMAP] = "linux,uefi-boot-memmap", >> } >> } >> }; >> @@ -84,17 +89,20 @@ static int __init efi_get_fdt_prop(const void *fdt, int node, const char *pname, >> u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) >> { >> const void *fdt = initial_boot_params; >> - unsigned long systab; >> + unsigned long systab, memmap; >> int i, j, node; >> struct { >> void *var; >> int size; >> } target[] = { >> [SYSTAB] = { &systab, sizeof(systab) }, >> + [MEMMAP] = { &memmap, sizeof(memmap) }, >> +#ifdef CONFIG_XEN >> [MMBASE] = { &mm->phys_map, sizeof(mm->phys_map) }, >> [MMSIZE] = { &mm->size, sizeof(mm->size) }, >> [DCSIZE] = { &mm->desc_size, sizeof(mm->desc_size) }, >> [DCVERS] = { &mm->desc_version, sizeof(mm->desc_version) }, >> +#endif >> }; >> >> BUILD_BUG_ON(ARRAY_SIZE(target) != ARRAY_SIZE(name)); >> @@ -115,6 +123,9 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) >> for (j = 0; j < ARRAY_SIZE(target); j++) { >> const char *pname = dt_params[i].params[j]; >> >> + if (pname[0] == '\0') >> + continue; >> + >> if (!efi_get_fdt_prop(fdt, node, pname, name[j], >> target[j].var, target[j].size)) >> continue; >> @@ -123,8 +134,24 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) >> pr_err("Can't find property '%s' in DT!\n", pname); >> return 0; >> } >> - if (dt_params[i].paravirt) >> + if (IS_ENABLED(CONFIG_XEN) && dt_params[i].paravirt) { >> set_bit(EFI_PARAVIRT, &efi.flags); >> + } else { > > This condition branch doesn't in fact have anything to do with the fdt. > Should it still live in fdtparams.c? > I don't follow. The EFI_PARAVIRT flag is set based on whether we are using the generic or the Xen-specific set of DT properties. What would be a better place to decide this? ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel 2026-08-17 8:41 ` Ard Biesheuvel @ 2026-08-17 9:18 ` Leif Lindholm 2026-08-17 11:00 ` Ard Biesheuvel 0 siblings, 1 reply; 13+ messages in thread From: Leif Lindholm @ 2026-08-17 9:18 UTC (permalink / raw) To: Ard Biesheuvel Cc: linux-efi, linux-arm-kernel, Huacai Chen, WANG Xuerui, loongarch On Mon, Aug 17, 2026 at 11:41:51 +0300, Ard Biesheuvel wrote: > On Fri, 14 Aug 2026, at 18:16, Leif Lindholm wrote: > > On Thu, Aug 13, 2026 at 09:45:09 +0200, Ard Biesheuvel wrote: > >> The EFI stub already passes a struct efi_boot_memmap populated with the > >> information of the EFI memory map as a configuration table, and so > >> passing the physical address, size, descriptor size and descriptor > >> version via 4 different DT properties is kind of redundant. > >> > >> Instead, pass the physical address of this struct in memory so that the > >> kernel can just retrieve the values directly. > >> > >> Unfortunately, the scheme with four separate properties is boot ABI for > >> Xen, and so this needs to remain supported. > > > > To clarify, you mean boot ABI when running under Xen? > > > > Yes. We've allowed Xen dom0 to omit the EFI stub entirely, and boot the > kernel proper in EFI mode, passing the EFI system table and memory map > addresses via these special DT properties. > > >> But for the EFI stub itself, > >> this is just an internal ABI that can be modified. > > > > Hmm... > > > > So this leaves only three properties that cannot be derived from the > > System Table: > > - The System Table address itself > > - kaslr-seed > > - bootargs > > > > The latter two could also be given the config table treatment. > > > > The latter two are generic boot ABI for the arm64 kernel, and there > is no need to treat them differently for EFI boot. Note that we also > support passing the initrd directly via DT when doing EFI boot, rather > than via the EFI specific device path. Ah, yes, noted. > > Is it time to update the boot ABI to say x0 will hold the physical > > address of "device tree blob (dtb) or EFI System Table in system RAM"? > > They can be distinguished by 0xd00dfeed / "IBI SYST". > > Let's avoid 'boot ABI' here, given that we are talking about an internal > interface between the EFI stub and the kernel proper. It's an internal business in the topic under discussion, but if we were to change it, that would mean updating booting.rst, which I consider an ABI. > This internal interface uses DT under the hood, even on ACPI platforms, > because it simplifies the early boot code. I don't think we should change > this. > > Also, the DT provided by the bootloader (if any) may differ from the one > passed by the EFI stub, and so discovering the DT from the EFI system > table is not straight-forward - they are not the same, and making them > the same may have unintended side effects. Right, but this confusion exists precisely because of the two ways the device tree can be accessed with the curreent design. > > The use of a generated DT when none was provided by firmware has led > > to both confusion and shenanigans, and might be nice to get rid of? > > > > I don't disagree with that. But that would imply adding new code to the > early startup code doing command line parsing and KASLR randomization to > reason about whether these assets are passed via DT or via some other means. I take your point about the invasiveness, so won't pursue that further at this time. But I can't promise I won't bring it up again eventually :) > What would make sense imo is to pass the EFI system table address via X1 > when doing EFI boot, so we don't have to get anything at all from the DT. That certainly sounds like a clear improvement. > > Either way, it would be nice to get rid of all four of the > > linux,uefi-mmap nodes if they're now completely redundant. > > > > Indeed. > > > Minor bikeshedding below. > > > >> @@ -123,8 +134,24 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) > >> pr_err("Can't find property '%s' in DT!\n", pname); > >> return 0; > >> } > >> - if (dt_params[i].paravirt) > >> + if (IS_ENABLED(CONFIG_XEN) && dt_params[i].paravirt) { > >> set_bit(EFI_PARAVIRT, &efi.flags); > >> + } else { > > > > This condition branch doesn't in fact have anything to do with the fdt. > > Should it still live in fdtparams.c? > > > > I don't follow. The EFI_PARAVIRT flag is set based on whether we are > using the generic or the Xen-specific set of DT properties. What would > be a better place to decide this? Apologies, I may have commented confusingly - my comment was about the else branch: + + bm = early_memremap_ro(memmap, sizeof(*bm)); + if (!bm) { + pr_err("Cannot remap EFI boot memory map\n"); + return 0; + } + + mm->phys_map = memmap + sizeof(*bm); + mm->size = bm->map_size; + mm->desc_size = bm->desc_size; + mm->desc_version = bm->desc_ver; + + early_memunmap(bm, sizeof(*bm)); So to restate - this function is called from efi_init(): --- /* Grab UEFI information placed in FDT by stub */ efi_system_table = efi_get_fdt_params(&data); if (!efi_system_table) return; --- Before this set, this function called get_fdt_params() indeed gets "params" from a device tree. After this set, this function gets params from a device tree in some instances, and not in others. Which feels suboptimal. We could rename the function, but then there's still DT-unrelated code held in fdtparams.c. If we go down the route of passing the system table in x1 on boot, then I guess the effect of assigning efi_system_table will already be broken out. But should we then split the mm struct initialisation into separate DT and config table helper functions? / Leif ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel 2026-08-17 9:18 ` Leif Lindholm @ 2026-08-17 11:00 ` Ard Biesheuvel 2026-08-17 14:08 ` Leif Lindholm 0 siblings, 1 reply; 13+ messages in thread From: Ard Biesheuvel @ 2026-08-17 11:00 UTC (permalink / raw) To: Leif Lindholm Cc: linux-efi, linux-arm-kernel, Huacai Chen, WANG Xuerui, loongarch On Mon, 17 Aug 2026, at 12:18, Leif Lindholm wrote: > On Mon, Aug 17, 2026 at 11:41:51 +0300, Ard Biesheuvel wrote: >> On Fri, 14 Aug 2026, at 18:16, Leif Lindholm wrote: >> > On Thu, Aug 13, 2026 at 09:45:09 +0200, Ard Biesheuvel wrote: >> >> The EFI stub already passes a struct efi_boot_memmap populated with the >> >> information of the EFI memory map as a configuration table, and so >> >> passing the physical address, size, descriptor size and descriptor >> >> version via 4 different DT properties is kind of redundant. >> >> >> >> Instead, pass the physical address of this struct in memory so that the >> >> kernel can just retrieve the values directly. >> >> >> >> Unfortunately, the scheme with four separate properties is boot ABI for >> >> Xen, and so this needs to remain supported. >> > >> > To clarify, you mean boot ABI when running under Xen? >> > >> >> Yes. We've allowed Xen dom0 to omit the EFI stub entirely, and boot the >> kernel proper in EFI mode, passing the EFI system table and memory map >> addresses via these special DT properties. >> >> >> But for the EFI stub itself, >> >> this is just an internal ABI that can be modified. >> > >> > Hmm... >> > >> > So this leaves only three properties that cannot be derived from the >> > System Table: >> > - The System Table address itself >> > - kaslr-seed >> > - bootargs >> > >> > The latter two could also be given the config table treatment. >> > >> >> The latter two are generic boot ABI for the arm64 kernel, and there >> is no need to treat them differently for EFI boot. Note that we also >> support passing the initrd directly via DT when doing EFI boot, rather >> than via the EFI specific device path. > > Ah, yes, noted. > >> > Is it time to update the boot ABI to say x0 will hold the physical >> > address of "device tree blob (dtb) or EFI System Table in system RAM"? >> > They can be distinguished by 0xd00dfeed / "IBI SYST". >> >> Let's avoid 'boot ABI' here, given that we are talking about an internal >> interface between the EFI stub and the kernel proper. > > It's an internal business in the topic under discussion, but if we > were to change it, that would mean updating booting.rst, which I > consider an ABI. > But not an external ABI. It documents specifically how the EFI stub interfaces with the kernel proper. This might change at any point, without any obligation whatsoever to remain compatible with the previous method. >> This internal interface uses DT under the hood, even on ACPI platforms, >> because it simplifies the early boot code. I don't think we should change >> this. >> >> Also, the DT provided by the bootloader (if any) may differ from the one >> passed by the EFI stub, and so discovering the DT from the EFI system >> table is not straight-forward - they are not the same, and making them >> the same may have unintended side effects. > > Right, but this confusion exists precisely because of the two ways the > device tree can be accessed with the curreent design. > Both the EFI stub and the kernel have precisely one way to access the platform provided device tree each: the EFI stub uses the config table, and the kernel proper uses what is passed via X0. I don't think that should change, whatever we decide wrt passing the EFI system table pointer. The whole point of the EFI stub is impedance matching between the EFI loading/calling convention and the Linux/arm64 boot ABI, and so passing the DTB, iff received via a EFI config table, on to the kernel in register X0 is literally its purpose in life. It would be nice if the EFI stub could pass the pristine DT without modifying it, so there is less ambiguity about where certain DT properties came from, but I don't think it justifies deviating from the above. >> > The use of a generated DT when none was provided by firmware has led >> > to both confusion and shenanigans, and might be nice to get rid of? >> > >> >> I don't disagree with that. But that would imply adding new code to the >> early startup code doing command line parsing and KASLR randomization to >> reason about whether these assets are passed via DT or via some other means. > > I take your point about the invasiveness, so won't pursue that further > at this time. But I can't promise I won't bring it up again eventually :) > Happy to debate this further at any point in the future :-) >> What would make sense imo is to pass the EFI system table address via X1 >> when doing EFI boot, so we don't have to get anything at all from the DT. > > That certainly sounds like a clear improvement. > Ack. I'll prototype that to see how it looks. ... >> > Minor bikeshedding below. >> > >> >> @@ -123,8 +134,24 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) >> >> pr_err("Can't find property '%s' in DT!\n", pname); >> >> return 0; >> >> } >> >> - if (dt_params[i].paravirt) >> >> + if (IS_ENABLED(CONFIG_XEN) && dt_params[i].paravirt) { >> >> set_bit(EFI_PARAVIRT, &efi.flags); >> >> + } else { >> > >> > This condition branch doesn't in fact have anything to do with the fdt. >> > Should it still live in fdtparams.c? >> > >> >> I don't follow. The EFI_PARAVIRT flag is set based on whether we are >> using the generic or the Xen-specific set of DT properties. What would >> be a better place to decide this? > > Apologies, I may have commented confusingly - my comment was about the > else branch: > > + > + bm = early_memremap_ro(memmap, sizeof(*bm)); > + if (!bm) { > + pr_err("Cannot remap EFI boot memory map\n"); > + return 0; > + } > + > + mm->phys_map = memmap + sizeof(*bm); > + mm->size = bm->map_size; > + mm->desc_size = bm->desc_size; > + mm->desc_version = bm->desc_ver; > + > + early_memunmap(bm, sizeof(*bm)); > > So to restate - this function is called from efi_init(): > --- > /* Grab UEFI information placed in FDT by stub */ > efi_system_table = efi_get_fdt_params(&data); > if (!efi_system_table) > return; > --- > > Before this set, this function called get_fdt_params() indeed gets > "params" from a device tree. After this set, this function gets params > from a device tree in some instances, and not in others. > Which feels suboptimal. > > We could rename the function, but then there's still DT-unrelated > code held in fdtparams.c. > > If we go down the route of passing the system table in x1 on boot, > then I guess the effect of assigning efi_system_table will already be > broken out. But should we then split the mm struct initialisation into > separate DT and config table helper functions? > Not disagreeing but I think it is fine to leave it as I suggested at this point. Some additional work is needed to get rid of linux,uefi-boot-memmap entirely, and until that happens, passing the EFI system table via X1 and linux,uefi-boot-memmap via DT is not a huge improvement. linux,uefi-boot-memmap is needed when SetVirtualAddressMap() is called [with a non-1:1 mapping], as the EFI system table contains a remapped address of the config table array in that case. There are currently two remaining reasons why calling SetVirtualAddressMap() is required: - some Ampere boxes crash otherwise (but these systems tolerate SVAM being called with a 1:1 mapping) - kernel configs with a VA space < 48 bits are not guaranteed to be able to map the EFI runtime services 1:1, so there, SVAM is still needed as well. Both can be fixed, and I have been meaning to address the latter by always making the EFI runtime map (which is essentially a 1:1 map) use 48 bits of VA in all configs. (The ID map already does the same) Then, the former can be addressed by installing a 1:1 mapping when calling SVAM. That would remove the need entirely to ever call SVAM() on arm64, and therefore the need to pass the address of the EFI memory map separately. ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel 2026-08-17 11:00 ` Ard Biesheuvel @ 2026-08-17 14:08 ` Leif Lindholm 2026-08-17 16:59 ` Ard Biesheuvel 0 siblings, 1 reply; 13+ messages in thread From: Leif Lindholm @ 2026-08-17 14:08 UTC (permalink / raw) To: Ard Biesheuvel Cc: linux-efi, linux-arm-kernel, Huacai Chen, WANG Xuerui, loongarch On Mon, Aug 17, 2026 at 14:00:16 +0300, Ard Biesheuvel wrote: > >> > Is it time to update the boot ABI to say x0 will hold the physical > >> > address of "device tree blob (dtb) or EFI System Table in system RAM"? > >> > They can be distinguished by 0xd00dfeed / "IBI SYST". > >> > >> Let's avoid 'boot ABI' here, given that we are talking about an internal > >> interface between the EFI stub and the kernel proper. > > > > It's an internal business in the topic under discussion, but if we > > were to change it, that would mean updating booting.rst, which I > > consider an ABI. > > > > But not an external ABI. It documents specifically how the EFI stub > interfaces with the kernel proper. This might change at any point, > without any obligation whatsoever to remain compatible with the > previous method. So you're saying if the kernel proper decides to use x1 for something else, we'll move to x2? I agree that in the context of how the stub calls the kernel proper, this is not ABI, but x1 is one of the registers currently marked as "reserved for future use" in booting.rst. So it feels weird for me to allocate one of those registers for this internal use then not mention it. In that case, couldn't we instead pick a register outside of the reserved ones? > ... > >> > Minor bikeshedding below. > >> > > >> >> @@ -123,8 +134,24 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) > >> >> pr_err("Can't find property '%s' in DT!\n", pname); > >> >> return 0; > >> >> } > >> >> - if (dt_params[i].paravirt) > >> >> + if (IS_ENABLED(CONFIG_XEN) && dt_params[i].paravirt) { > >> >> set_bit(EFI_PARAVIRT, &efi.flags); > >> >> + } else { > >> > > >> > This condition branch doesn't in fact have anything to do with the fdt. > >> > Should it still live in fdtparams.c? > >> > > >> > >> I don't follow. The EFI_PARAVIRT flag is set based on whether we are > >> using the generic or the Xen-specific set of DT properties. What would > >> be a better place to decide this? > > > > Apologies, I may have commented confusingly - my comment was about the > > else branch: > > > > + > > + bm = early_memremap_ro(memmap, sizeof(*bm)); > > + if (!bm) { > > + pr_err("Cannot remap EFI boot memory map\n"); > > + return 0; > > + } > > + > > + mm->phys_map = memmap + sizeof(*bm); > > + mm->size = bm->map_size; > > + mm->desc_size = bm->desc_size; > > + mm->desc_version = bm->desc_ver; > > + > > + early_memunmap(bm, sizeof(*bm)); > > > > So to restate - this function is called from efi_init(): > > --- > > /* Grab UEFI information placed in FDT by stub */ > > efi_system_table = efi_get_fdt_params(&data); > > if (!efi_system_table) > > return; > > --- > > > > Before this set, this function called get_fdt_params() indeed gets > > "params" from a device tree. After this set, this function gets params > > from a device tree in some instances, and not in others. > > Which feels suboptimal. > > > > We could rename the function, but then there's still DT-unrelated > > code held in fdtparams.c. > > > > If we go down the route of passing the system table in x1 on boot, > > then I guess the effect of assigning efi_system_table will already be > > broken out. But should we then split the mm struct initialisation into > > separate DT and config table helper functions? > > > > Not disagreeing but I think it is fine to leave it as I suggested at this > point. > > Some additional work is needed to get rid of linux,uefi-boot-memmap > entirely, and until that happens, passing the EFI system table via > X1 and linux,uefi-boot-memmap via DT is not a huge improvement. > > linux,uefi-boot-memmap is needed when SetVirtualAddressMap() is called > [with a non-1:1 mapping], as the EFI system table contains a remapped > address of the config table array in that case. Of course, the devil on my shoulder suggests the stub could always add an address fixup handler for the config table too... > There are currently two remaining reasons why calling > SetVirtualAddressMap() is required: > - some Ampere boxes crash otherwise (but these systems tolerate SVAM > being called with a 1:1 mapping) > - kernel configs with a VA space < 48 bits are not guaranteed to be > able to map the EFI runtime services 1:1, so there, SVAM is still > needed as well. > > Both can be fixed, and I have been meaning to address the latter by > always making the EFI runtime map (which is essentially a 1:1 map) > use 48 bits of VA in all configs. (The ID map already does the same) > > Then, the former can be addressed by installing a 1:1 mapping when > calling SVAM. > > That would remove the need entirely to ever call SVAM() on arm64, > and therefore the need to pass the address of the EFI memory map > separately. Makes sense. / Leif ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel 2026-08-17 14:08 ` Leif Lindholm @ 2026-08-17 16:59 ` Ard Biesheuvel 0 siblings, 0 replies; 13+ messages in thread From: Ard Biesheuvel @ 2026-08-17 16:59 UTC (permalink / raw) To: Leif Lindholm Cc: linux-efi, linux-arm-kernel, Huacai Chen, WANG Xuerui, loongarch On Mon, 17 Aug 2026, at 17:08, Leif Lindholm wrote: > On Mon, Aug 17, 2026 at 14:00:16 +0300, Ard Biesheuvel wrote: >> >> > Is it time to update the boot ABI to say x0 will hold the physical >> >> > address of "device tree blob (dtb) or EFI System Table in system RAM"? >> >> > They can be distinguished by 0xd00dfeed / "IBI SYST". >> >> >> >> Let's avoid 'boot ABI' here, given that we are talking about an internal >> >> interface between the EFI stub and the kernel proper. >> > >> > It's an internal business in the topic under discussion, but if we >> > were to change it, that would mean updating booting.rst, which I >> > consider an ABI. >> > >> >> But not an external ABI. It documents specifically how the EFI stub >> interfaces with the kernel proper. This might change at any point, >> without any obligation whatsoever to remain compatible with the >> previous method. > > So you're saying if the kernel proper decides to use x1 for something > else, we'll move to x2? > > I agree that in the context of how the stub calls the kernel proper, > this is not ABI, but x1 is one of the registers currently marked as > "reserved for future use" in booting.rst. So it feels weird for me to > allocate one of those registers for this internal use then not mention > it. > Whether we mention it or not is irrelevant: the only thing that matters is that this allocation is not something that OS loaders other than the EFI stub are able to rely upon, given that EFI boot on arm64 requires booting via the stub (except for Xen dom0). > In that case, couldn't we instead pick a register outside of the > reserved ones? > It has to be a reserved one, given that the state of other registers is unspecified at boot. Otherwise, we'd have to reason about whether a non-zero value is accidental, or represents a physical address that we can map and dereference, which is needed even to check the system table's magin >> ... >> >> > Minor bikeshedding below. >> >> > >> >> >> @@ -123,8 +134,24 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) >> >> >> pr_err("Can't find property '%s' in DT!\n", pname); >> >> >> return 0; >> >> >> } >> >> >> - if (dt_params[i].paravirt) >> >> >> + if (IS_ENABLED(CONFIG_XEN) && dt_params[i].paravirt) { >> >> >> set_bit(EFI_PARAVIRT, &efi.flags); >> >> >> + } else { >> >> > >> >> > This condition branch doesn't in fact have anything to do with the fdt. >> >> > Should it still live in fdtparams.c? >> >> > >> >> >> >> I don't follow. The EFI_PARAVIRT flag is set based on whether we are >> >> using the generic or the Xen-specific set of DT properties. What would >> >> be a better place to decide this? >> > >> > Apologies, I may have commented confusingly - my comment was about the >> > else branch: >> > >> > + >> > + bm = early_memremap_ro(memmap, sizeof(*bm)); >> > + if (!bm) { >> > + pr_err("Cannot remap EFI boot memory map\n"); >> > + return 0; >> > + } >> > + >> > + mm->phys_map = memmap + sizeof(*bm); >> > + mm->size = bm->map_size; >> > + mm->desc_size = bm->desc_size; >> > + mm->desc_version = bm->desc_ver; >> > + >> > + early_memunmap(bm, sizeof(*bm)); >> > >> > So to restate - this function is called from efi_init(): >> > --- >> > /* Grab UEFI information placed in FDT by stub */ >> > efi_system_table = efi_get_fdt_params(&data); >> > if (!efi_system_table) >> > return; >> > --- >> > >> > Before this set, this function called get_fdt_params() indeed gets >> > "params" from a device tree. After this set, this function gets params >> > from a device tree in some instances, and not in others. >> > Which feels suboptimal. >> > >> > We could rename the function, but then there's still DT-unrelated >> > code held in fdtparams.c. >> > >> > If we go down the route of passing the system table in x1 on boot, >> > then I guess the effect of assigning efi_system_table will already be >> > broken out. But should we then split the mm struct initialisation into >> > separate DT and config table helper functions? >> > >> >> Not disagreeing but I think it is fine to leave it as I suggested at this >> point. >> >> Some additional work is needed to get rid of linux,uefi-boot-memmap >> entirely, and until that happens, passing the EFI system table via >> X1 and linux,uefi-boot-memmap via DT is not a huge improvement. >> >> linux,uefi-boot-memmap is needed when SetVirtualAddressMap() is called >> [with a non-1:1 mapping], as the EFI system table contains a remapped >> address of the config table array in that case. > > Of course, the devil on my shoulder suggests the stub could always > add an address fixup handler for the config table too... > What is an address fixup handler? We cannot change this value back, as that might break the runtime services. ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/3] efi: Make the 'linux,uefi-boot-memmap' DT property optional 2026-08-13 7:45 [PATCH 0/3] efi: Simply DT handoff from stub to kernel Ard Biesheuvel 2026-08-13 7:45 ` [PATCH 1/3] efi: Turn boot memmap handling into shared code Ard Biesheuvel 2026-08-13 7:45 ` [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel Ard Biesheuvel @ 2026-08-13 7:45 ` Ard Biesheuvel 2026-08-13 8:25 ` Richard Lyu 2 siblings, 1 reply; 13+ messages in thread From: Ard Biesheuvel @ 2026-08-13 7:45 UTC (permalink / raw) To: linux-efi Cc: linux-arm-kernel, Ard Biesheuvel, Huacai Chen, WANG Xuerui, loongarch The 'linux,uefi-boot-memmap DT property' is redundant in principle, given that it carries a physical address that is also passed via a EFI config table entry. However, if SetVirtualAddressMap() has been called, the address of the config table array has been translated to virtual, and so the memory map is needed to translate it back to physical before it can be located. This means that passing the linux,uefi-boot-memmap DT property is only needed if SetVirtualAddressMap() has been called, which is a terrible idea anyway, and if it has not been called, the config table array can simply be parsed to look for LINUX_EFI_BOOT_MEMMAP_TABLE_GUID, and the address taken from there. So permit this, and make the boot memmap property optional. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> --- drivers/firmware/efi/fdtparams.c | 42 ++++++++++++++++++-- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c index a54a76a6aaeb..89ffccf35fd7 100644 --- a/drivers/firmware/efi/fdtparams.c +++ b/drivers/firmware/efi/fdtparams.c @@ -89,14 +89,15 @@ static int __init efi_get_fdt_prop(const void *fdt, int node, const char *pname, u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) { const void *fdt = initial_boot_params; - unsigned long systab, memmap; + unsigned long systab, memmap = 0; int i, j, node; struct { void *var; int size; + int optional; } target[] = { [SYSTAB] = { &systab, sizeof(systab) }, - [MEMMAP] = { &memmap, sizeof(memmap) }, + [MEMMAP] = { &memmap, sizeof(memmap), 1 }, #ifdef CONFIG_XEN [MMBASE] = { &mm->phys_map, sizeof(mm->phys_map) }, [MMSIZE] = { &mm->size, sizeof(mm->size) }, @@ -131,14 +132,47 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) continue; if (!j) goto notfound; - pr_err("Can't find property '%s' in DT!\n", pname); - return 0; + if (!target[j].optional) { + pr_err("Can't find property '%s' in DT!\n", pname); + return 0; + } } if (IS_ENABLED(CONFIG_XEN) && dt_params[i].paravirt) { set_bit(EFI_PARAVIRT, &efi.flags); } else { struct efi_boot_memmap *bm; + if (!memmap) { + unsigned long tables, nr_tables; + efi_system_table_t *st; + efi_config_table_t *tbl; + + st = early_memremap_ro(systab, sizeof(*st)); + if (!st) { + pr_err("Cannot remap EFI system table\n"); + return 0; + } + + tables = st->tables; + nr_tables = st->nr_tables; + + early_memunmap(st, sizeof(*st)); + + tbl = early_memremap_ro(tables, sizeof(*tbl) * nr_tables); + if (!tbl) { + pr_err("Cannot remap EFI config table array\n"); + return 0; + } + + for (int i = 0; i < nr_tables; i++) { + if (!efi_guidcmp(tbl[i].guid, LINUX_EFI_BOOT_MEMMAP_GUID)) { + memmap = (unsigned long)tbl[i].table; + break; + } + } + early_memunmap(tbl, sizeof(*tbl) * nr_tables); + } + bm = early_memremap_ro(memmap, sizeof(*bm)); if (!bm) { pr_err("Cannot remap EFI boot memory map\n"); -- 2.47.3 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 3/3] efi: Make the 'linux,uefi-boot-memmap' DT property optional 2026-08-13 7:45 ` [PATCH 3/3] efi: Make the 'linux,uefi-boot-memmap' DT property optional Ard Biesheuvel @ 2026-08-13 8:25 ` Richard Lyu 0 siblings, 0 replies; 13+ messages in thread From: Richard Lyu @ 2026-08-13 8:25 UTC (permalink / raw) To: Ard Biesheuvel Cc: linux-efi, linux-arm-kernel, Huacai Chen, WANG Xuerui, loongarch On 2026/08/13 09:45, Ard Biesheuvel wrote: >The 'linux,uefi-boot-memmap DT property' is redundant in principle, >given that it carries a physical address that is also passed via a EFI >config table entry. > >However, if SetVirtualAddressMap() has been called, the address of the >config table array has been translated to virtual, and so the memory map >is needed to translate it back to physical before it can be located. > >This means that passing the linux,uefi-boot-memmap DT property is only >needed if SetVirtualAddressMap() has been called, which is a terrible >idea anyway, and if it has not been called, the config table array can >simply be parsed to look for LINUX_EFI_BOOT_MEMMAP_TABLE_GUID, and the >address taken from there. > >So permit this, and make the boot memmap property optional. > >Signed-off-by: Ard Biesheuvel <ardb@kernel.org> >--- > drivers/firmware/efi/fdtparams.c | 42 ++++++++++++++++++-- > 1 file changed, 38 insertions(+), 4 deletions(-) > >diff --git a/drivers/firmware/efi/fdtparams.c b/drivers/firmware/efi/fdtparams.c >index a54a76a6aaeb..89ffccf35fd7 100644 >--- a/drivers/firmware/efi/fdtparams.c >+++ b/drivers/firmware/efi/fdtparams.c >@@ -89,14 +89,15 @@ static int __init efi_get_fdt_prop(const void *fdt, int node, const char *pname, > u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) > { > const void *fdt = initial_boot_params; >- unsigned long systab, memmap; >+ unsigned long systab, memmap = 0; > int i, j, node; > struct { > void *var; > int size; >+ int optional; > } target[] = { > [SYSTAB] = { &systab, sizeof(systab) }, >- [MEMMAP] = { &memmap, sizeof(memmap) }, >+ [MEMMAP] = { &memmap, sizeof(memmap), 1 }, > #ifdef CONFIG_XEN > [MMBASE] = { &mm->phys_map, sizeof(mm->phys_map) }, > [MMSIZE] = { &mm->size, sizeof(mm->size) }, >@@ -131,14 +132,47 @@ u64 __init efi_get_fdt_params(struct efi_memory_map_data *mm) > continue; > if (!j) > goto notfound; >- pr_err("Can't find property '%s' in DT!\n", pname); >- return 0; >+ if (!target[j].optional) { >+ pr_err("Can't find property '%s' in DT!\n", pname); >+ return 0; >+ } > } > if (IS_ENABLED(CONFIG_XEN) && dt_params[i].paravirt) { > set_bit(EFI_PARAVIRT, &efi.flags); > } else { > struct efi_boot_memmap *bm; > >+ if (!memmap) { >+ unsigned long tables, nr_tables; >+ efi_system_table_t *st; >+ efi_config_table_t *tbl; >+ >+ st = early_memremap_ro(systab, sizeof(*st)); >+ if (!st) { >+ pr_err("Cannot remap EFI system table\n"); >+ return 0; >+ } >+ >+ tables = st->tables; >+ nr_tables = st->nr_tables; >+ >+ early_memunmap(st, sizeof(*st)); >+ >+ tbl = early_memremap_ro(tables, sizeof(*tbl) * nr_tables); >+ if (!tbl) { >+ pr_err("Cannot remap EFI config table array\n"); >+ return 0; >+ } >+ >+ for (int i = 0; i < nr_tables; i++) { >+ if (!efi_guidcmp(tbl[i].guid, LINUX_EFI_BOOT_MEMMAP_GUID)) { >+ memmap = (unsigned long)tbl[i].table; >+ break; >+ } >+ } >+ early_memunmap(tbl, sizeof(*tbl) * nr_tables); >+ } >+ > bm = early_memremap_ro(memmap, sizeof(*bm)); > if (!bm) { > pr_err("Cannot remap EFI boot memory map\n"); >-- >2.47.3 > > Reviewed-by: Richard Lyu <richard.lyu@suse.com> ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-08-17 16:59 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-13 7:45 [PATCH 0/3] efi: Simply DT handoff from stub to kernel Ard Biesheuvel 2026-08-13 7:45 ` [PATCH 1/3] efi: Turn boot memmap handling into shared code Ard Biesheuvel 2026-08-13 8:24 ` Richard Lyu 2026-08-13 7:45 ` [PATCH 2/3] efi: Pass EFI boot memmap struct address to core kernel Ard Biesheuvel 2026-08-13 8:25 ` Richard Lyu 2026-08-14 15:16 ` Leif Lindholm 2026-08-17 8:41 ` Ard Biesheuvel 2026-08-17 9:18 ` Leif Lindholm 2026-08-17 11:00 ` Ard Biesheuvel 2026-08-17 14:08 ` Leif Lindholm 2026-08-17 16:59 ` Ard Biesheuvel 2026-08-13 7:45 ` [PATCH 3/3] efi: Make the 'linux,uefi-boot-memmap' DT property optional Ard Biesheuvel 2026-08-13 8:25 ` Richard Lyu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox