[PATCH v5 9/9] efi: Keep early allocations to the U-Boot region

Simon Glass sjg at chromium.org
Sun Dec 1 16:28:11 CET 2024


Adjust EFI_LOADER to use the provided region for early memory
allocations, to avoid going outside the U-Boot region.

Expand the available memory when efi_init_obj_list() is called.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v5:
- Rebase on top of efil and efik series
- Reword cover letter a little

Changes in v4:
- Use a different technique to keep the memory-usage in place
- Drop changes to pool allocation
- Reorder the patches
- Rewrite the cover letter
- Make it a debug message for now

Changes in v2:
- Drop patch 'Show more information in efi index'
- Drop patch 'Avoid pool allocation in efi_get_memory_map_alloc()'
- Add the word 'warning', use log_warning() and show the end address

 include/efi_loader.h        | 13 +++++++++++++
 lib/efi_loader/efi_memory.c | 24 ++++++++++++++++++++++--
 lib/efi_loader/efi_setup.c  |  5 +++++
 3 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/include/efi_loader.h b/include/efi_loader.h
index a0af0db6262..600dfc2b48c 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -871,6 +871,19 @@ int efi_disk_probe(void *ctx, struct event *event);
 int efi_disk_remove(void *ctx, struct event *event);
 /* Called by board init to initialize the EFI memory map */
 int efi_memory_init(void);
+
+/**
+ * efi_memory_coop() - Allow EFI to use all available memory
+ *
+ * Up until this function is called, only a small portion of memory is available
+ * for use by the EFI memory-allocator. This function is called at the
+ * 'point of cooperation', before jumping into an EFI app, which needs to be
+ * able to make use of all the memory in the machine
+ *
+ * Return: efi_status_t (EFI_SUCCESS on success)
+ */
+int efi_memory_coop(void);
+
 /* Adds new or overrides configuration table entry to the system table */
 efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table);
 /* Sets up a loaded image */
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index 344656c4eb0..88ef111dc70 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -32,6 +32,9 @@ DECLARE_GLOBAL_DATA_PTR;
  */
 #define EFI_EARLY_REGION_SIZE	SZ_256K
 
+/* Set when all memory has been added for use by EFI */
+static bool efi_full_memory;
+
 efi_uintn_t efi_memory_map_key;
 
 /**
@@ -832,8 +835,25 @@ static void add_u_boot_and_runtime(void)
 
 int efi_memory_init(void)
 {
-	efi_add_known_memory();
+	efi_status_t ret;
+
+	/* restrict EFI to its own region until efi_memory_coop() is called */
+	ret = efi_add_memory_map_pg(gd->efi_region,
+				    EFI_EARLY_REGION_SIZE >> EFI_PAGE_SHIFT,
+				    EFI_CONVENTIONAL_MEMORY, false);
+
+	return ret;
+}
 
+int efi_memory_coop(void)
+{
+	if (efi_full_memory)
+		return 0;
+	log_debug("Enabling coop memory\n");
+
+	efi_full_memory = true;
+
+	efi_add_known_memory();
 	add_u_boot_and_runtime();
 
 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
@@ -843,7 +863,7 @@ int efi_memory_init(void)
 	if (efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, EFI_BOOT_SERVICES_DATA,
 			       (64 * 1024 * 1024) >> EFI_PAGE_SHIFT,
 			       &efi_bounce_buffer_addr) != EFI_SUCCESS)
-		return -1;
+		return -ENOMEM;
 
 	efi_bounce_buffer = (void*)(uintptr_t)efi_bounce_buffer_addr;
 #endif
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index 468156db813..c68f3ff0748 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -228,6 +228,11 @@ efi_status_t efi_init_obj_list(void)
 	if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
 		return efi_obj_list_initialized;
 
+	/* Allow EFI to use all memory */
+	ret = efi_memory_coop();
+	if (ret != EFI_SUCCESS)
+		goto out;
+
 	/* Set up console modes */
 	efi_setup_console_size();
 
-- 
2.43.0



More information about the U-Boot mailing list