[PATCH v2 15/19] x86/efi: Use iterator API when mapping EFI regions for runtime
From: Ard Biesheuvel
Date: Thu Mar 19 2026 - 05:18:37 EST
From: Ard Biesheuvel <ardb@xxxxxxxxxx>
Use the generic EFI memory map iterators to invoke efi_map_region() on
each entry in the map. x86_64 and i386 traverse the map in opposite
order, so the two cases are handled separately.
Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx>
---
arch/x86/platform/efi/efi.c | 90 +++++---------------
1 file changed, 21 insertions(+), 69 deletions(-)
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 44d106879120..8778ad441c42 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -498,73 +498,6 @@ void __init efi_init(void)
efi_print_memmap();
}
-/*
- * Iterate the EFI memory map in reverse order because the regions
- * will be mapped top-down. The end result is the same as if we had
- * mapped things forward, but doesn't require us to change the
- * existing implementation of efi_map_region().
- */
-static inline void *efi_map_next_entry_reverse(void *entry)
-{
- /* Initial call */
- if (!entry)
- return efi_memdesc_ptr(efi.memmap.map, efi.memmap.desc_size,
- efi.memmap.num_valid_entries - 1);
-
- entry -= efi.memmap.desc_size;
- if (entry < efi.memmap.map)
- return NULL;
-
- return entry;
-}
-
-/*
- * efi_map_next_entry - Return the next EFI memory map descriptor
- * @entry: Previous EFI memory map descriptor
- *
- * This is a helper function to iterate over the EFI memory map, which
- * we do in different orders depending on the current configuration.
- *
- * To begin traversing the memory map @entry must be %NULL.
- *
- * Returns %NULL when we reach the end of the memory map.
- */
-static void *efi_map_next_entry(void *entry)
-{
- if (efi_enabled(EFI_64BIT)) {
- /*
- * Starting in UEFI v2.5 the EFI_PROPERTIES_TABLE
- * config table feature requires us to map all entries
- * in the same order as they appear in the EFI memory
- * map. That is to say, entry N must have a lower
- * virtual address than entry N+1. This is because the
- * firmware toolchain leaves relative references in
- * the code/data sections, which are split and become
- * separate EFI memory regions. Mapping things
- * out-of-order leads to the firmware accessing
- * unmapped addresses.
- *
- * Since we need to map things this way whether or not
- * the kernel actually makes use of
- * EFI_PROPERTIES_TABLE, let's just switch to this
- * scheme by default for 64-bit.
- */
- return efi_map_next_entry_reverse(entry);
- }
-
- /* Initial call */
- if (!entry)
- return efi.memmap.map;
-
- entry += efi.memmap.desc_size;
- if (entry >= (void *)efi_memdesc_ptr(efi.memmap.map,
- efi.memmap.desc_size,
- efi.memmap.num_valid_entries))
- return NULL;
-
- return entry;
-}
-
static bool should_map_region(const efi_memory_desc_t *md, int unused)
{
/*
@@ -624,8 +557,27 @@ static void __init efi_map_regions(void)
efi_memmap_filter_entries(should_map_region);
- while ((md = efi_map_next_entry(md)))
- efi_map_region(md);
+ /*
+ * Starting in UEFI v2.5 the EFI_PROPERTIES_TABLE config table feature
+ * requires us to map all entries in the same order as they appear in
+ * the EFI memory map. That is to say, entry N must have a lower
+ * virtual address than entry N+1. This is because the firmware
+ * toolchain leaves relative references in the code/data sections,
+ * which are split and become separate EFI memory regions. Mapping
+ * things out-of-order leads to the firmware accessing unmapped
+ * addresses.
+ *
+ * Since we need to map things this way whether or not the kernel
+ * actually makes use of EFI_PROPERTIES_TABLE, let's just switch to
+ * this scheme by default for 64-bit.
+ */
+ if (efi_enabled(EFI_64BIT)) {
+ for_each_efi_memory_desc_rev(md)
+ efi_map_region(md);
+ } else {
+ for_each_efi_memory_desc(md)
+ efi_map_region(md);
+ }
}
static void __init kexec_enter_virtual_mode(void)
--
2.53.0.851.ga537e3e6e9-goog