[PATCH v4 5/5] efi: Keep early allocations to the U-Boot region
Simon Glass
sjg at chromium.org
Tue Oct 15 15:26:05 CEST 2024
Hi Ilias,
On Mon, 14 Oct 2024 at 22:26, Ilias Apalodimas
<ilias.apalodimas at linaro.org> wrote:
>
> Hi Simon,
>
> On Sat, 12 Oct 2024 at 00:23, Simon Glass <sjg at chromium.org> wrote:
> >
> > 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.
>
> efi_init_obj_list() is not called when an EFI app is called. It's
> called when the EFI subsystem comes up.
Indeed.
>
> >
> > Signed-off-by: Simon Glass <sjg at chromium.org>
> > ---
> >
> > 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 08e27e61b06..aa464e9d754 100644
> > --- a/include/efi_loader.h
> > +++ b/include/efi_loader.h
> > @@ -805,6 +805,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
>
> As above, this is called when the EFI subsystem comes up. Not when an
> application is called. For example doing a 'printenv -e' to print EFI
> variables would trigger this.
Yes. At that point we know we are using an EFI feature. We can
certainly extend the intent of this patch to cover that, but I am
trying to take baby steps here.
> The funtion call you are removing just adds all memory all memory as
> EFI_CONVENTIONAL_MEMORY, which basically means free memory. I can't
> understand what this patch is supposed to fix
Basically it feeds a small amount of memory to EFI initially, within
the U-Boot region. That is enough to deal with the few allocations
that are done before efi_init_obj_list() is called.
So if you don't use any EFI features, EFI's memory usage is limited to
the U-Boot region.
>
> > + *
> > + * 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 9cc33397371..2cd0b00e9eb 100644
> > --- a/lib/efi_loader/efi_memory.c
> > +++ b/lib/efi_loader/efi_memory.c
> > @@ -30,6 +30,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;
> >
> > struct efi_mem_list {
> > @@ -932,8 +935,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((ulong)map_sysmem(gd->efi_region, 0),
> > + 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
> > @@ -943,7 +963,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 a610e032d2f..40e23ca104c 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.34.1
> >
>
> Thanks
> /Ilias
Regards,
SImon
More information about the U-Boot
mailing list