[PATCH 5/6] efi_memory: backfill EFI_CONVENTIONAL_MEMORY

rs at ti.com rs at ti.com
Thu Apr 2 02:14:09 CEST 2026


From: Randolph Sapp <rs at ti.com>

Backfill any fragmented EFI_CONVENTIONAL_MEMORY when LMB allocations
start to fail. This may be a low memory environment, or maybe LMB is
running up against a tricky reserved region.

Signed-off-by: Randolph Sapp <rs at ti.com>
---
 lib/efi_loader/efi_memory.c | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 882366a9f8a..f07cc39b157 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -441,6 +441,27 @@ static efi_status_t efi_check_allocated(u64 addr, bool must_be_allocated)
 	return EFI_NOT_FOUND;
 }
 
+/**
+ * efi_get_conventional_start - find the highest conventional region start
+ *                              address with at least the specified number of
+ *                              pages
+ *
+ * @pages:                      number of pages required to be in that carveout
+ * Return:                      starting address of the give carveout
+ */
+static u64 efi_get_conventional_start(u64 pages)
+{
+	struct efi_mem_list *item;
+
+	list_for_each_entry(item, &efi_mem, link) {
+		if (item->desc.type != EFI_CONVENTIONAL_MEMORY)
+			continue;
+		if (item->desc.num_pages >= pages)
+			return item->desc.physical_start;
+	}
+	return 0;
+}
+
 /**
  * efi_allocate_pages - allocate memory pages
  *
@@ -507,10 +528,20 @@ efi_status_t efi_allocate_pages(enum efi_allocate_type type,
 	/* Reserve that map in our memory maps */
 	ret = efi_update_memory_map(efi_addr, pages, memory_type, true, false);
 	if (ret != EFI_SUCCESS) {
-		/* Map would overlap, bail out */
+		/* Map would overlap, try something else */
 		lmb_free(addr, (u64)pages << EFI_PAGE_SHIFT, flags);
 		unmap_sysmem((void *)(uintptr_t)efi_addr);
-		return  EFI_OUT_OF_RESOURCES;
+
+		/* See if there is any EFI_CONVENTIONAL_MEMORY allocations */
+		if (type != EFI_ALLOCATE_ADDRESS) {
+			*memory = efi_get_conventional_start(pages);
+			if (*memory != 0)
+				return efi_allocate_pages(EFI_ALLOCATE_ADDRESS,
+							  memory_type, pages,
+							  memory);
+		}
+
+		return EFI_OUT_OF_RESOURCES;
 	}
 
 	*memory = efi_addr;
-- 
2.53.0



More information about the U-Boot mailing list