[PATCH v2 1/6] efi/libstub: add a helper for the top of usable RAM

From: Breno Leitao

Date: Fri Aug 21 2026 - 06:48:19 EST


The stub has no way to ask how far RAM reaches, which is useful to
create a bitmap that covers the whole memory.

max_pfn answers that for the kernel, but it is only set in
setup_arch(), long after the stub has handed off, so, unfortunately we
cannot use it here..

Add efi_get_ram_top(), which returns the highest address reached by the
entry types that become usable RAM. Unaccepted memory is counted as
well, as suggested by Kiryl.

Memory the firmware hot-adds later is *not* in the memory map, so it is
not covered; that matches max_pfn, which is likewise the top of the
memory present at boot.

Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx>
---
drivers/firmware/efi/libstub/efistub.h | 2 ++
drivers/firmware/efi/libstub/mem.c | 53 ++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+)

diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index fd91fc15ec810..77ba576779aca 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1094,6 +1094,8 @@ char *efi_convert_cmdline(efi_loaded_image_t *image);
efi_status_t efi_get_memory_map(struct efi_boot_memmap **map,
bool install_cfg_tbl);

+efi_status_t efi_get_ram_top(u64 *top);
+
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 59f3f83de50c2..777f1f180c66e 100644
--- a/drivers/firmware/efi/libstub/mem.c
+++ b/drivers/firmware/efi/libstub/mem.c
@@ -64,6 +64,59 @@ efi_status_t efi_get_memory_map(struct efi_boot_memmap **map,
return EFI_SUCCESS;
}

+/**
+ * efi_get_ram_top() - find the top of usable RAM
+ * @top: on return, the end of the highest memory map entry that becomes
+ * usable RAM
+ *
+ * Walk the UEFI memory map for the entry types that become usable RAM, the set
+ * setup_e820() maps to E820_TYPE_RAM, and return the highest address any of
+ * them reaches. Memory a confidential guest has not accepted yet counts as
+ * well, since it becomes RAM once accepted. This is what the stub has in place
+ * of max_pfn, which is only set once the kernel proper is up.
+ *
+ * Memory the firmware hot-adds later is not described by the memory map and so
+ * is not accounted for here.
+ *
+ * Return: status code
+ */
+efi_status_t efi_get_ram_top(u64 *top)
+{
+ struct efi_boot_memmap *map __free(efi_pool) = NULL;
+ efi_status_t status;
+ u64 ram_top = 0;
+ int i, nr_desc;
+
+ status = efi_get_memory_map(&map, false);
+ if (status != EFI_SUCCESS)
+ return status;
+
+ nr_desc = map->map_size / map->desc_size;
+ for (i = 0; i < nr_desc; i++) {
+ efi_memory_desc_t *d;
+
+ d = efi_memdesc_ptr((unsigned long)map->map, map->desc_size, i);
+ switch (d->type) {
+ case EFI_LOADER_CODE:
+ case EFI_LOADER_DATA:
+ case EFI_BOOT_SERVICES_CODE:
+ case EFI_BOOT_SERVICES_DATA:
+ case EFI_CONVENTIONAL_MEMORY:
+ case EFI_UNACCEPTED_MEMORY:
+ ram_top = max(ram_top,
+ d->phys_addr + d->num_pages * EFI_PAGE_SIZE);
+ break;
+ default:
+ break;
+ }
+ }
+ if (!ram_top)
+ return EFI_NOT_FOUND;
+
+ *top = ram_top;
+ return EFI_SUCCESS;
+}
+
/**
* efi_allocate_pages() - Allocate memory pages
* @size: minimum number of bytes to allocate

--
2.53.0-Meta