From: Chali Anis <chalianis1@gmail.com>
To: Sascha Hauer <s.hauer@pengutronix.de>,
BAREBOX <barebox@lists.infradead.org>
Cc: Chali Anis <chalianis1@gmail.com>
Subject: [PATCH 11/15] malloc: tlsf: efi: add a fallback for allocate more memory when we are in efi.
Date: Fri, 19 Sep 2025 23:03:20 -0400 [thread overview]
Message-ID: <20250919-efi-loader-v1-11-dd8cdafb9067@gmail.com> (raw)
In-Reply-To: <20250919-efi-loader-v1-0-dd8cdafb9067@gmail.com>
this will fix the OOM issues for when barebox is running on top of efi.
the OOM were unpredictble since we can't determine the size required in
advance for initrd or kernel. with this patch we don't need anymore to
increase memory in efi early mem, we allocate only what barebox needs
to relocate itself and have what it needs to manage peripherls, at any
OOM we fallback to efi to give us more memory. So we get a more
deterministic behaviour and more generic efi payload and finally
a huge speedup for the boot time. and the most important a clean code.
Signed-off-by: Chali Anis <chalianis1@gmail.com>
---
common/Kconfig | 9 ++++++
common/Makefile | 1 +
common/efi_malloc.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++
common/tlsf_malloc.c | 22 +++++++++++++--
include/malloc.h | 19 +++++++++++++
5 files changed, 129 insertions(+), 2 deletions(-)
diff --git a/common/Kconfig b/common/Kconfig
index eb2fb1da1e0919b6e7d5e868c48ad2e195cd8aa8..5e2251ff7821f14556b19816a51eb8d7e9133a6f 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -317,6 +317,15 @@ config EXPERIMENTAL
bool
prompt "Prompt for experimental code"
+config MALLOC_EFI
+ bool "efi malloc fallback"
+ depends on EFI_PAYLOAD
+ help
+ select this option to use efi malloc fallback, it will permit,
+ when we use barebox as an efi payload to automaticlly allocate
+ more memory from efi as needed, permits to be more resilient with
+ OOM and support what ever we have to boot or execute as efi app.
+
choice
prompt "malloc implementation"
default MALLOC_TLSF
diff --git a/common/Makefile b/common/Makefile
index d501a6a2755a113fac3ac632806d4a92b741d6e2..aa693b4c31b66aecb76192579466972fb8c351b3 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -53,6 +53,7 @@ obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-$(CONFIG_MALLOC_TLSF) += tlsf_malloc.o tlsf.o calloc.o
KASAN_SANITIZE_tlsf.o := n
obj-$(CONFIG_MALLOC_DUMMY) += dummy_malloc.o calloc.o
+obj-$(CONFIG_MALLOC_EFI) += efi_malloc.o
obj-y += malloc.o
obj-$(CONFIG_MEMINFO) += meminfo.o
obj-$(CONFIG_MENU) += menu.o
diff --git a/common/efi_malloc.c b/common/efi_malloc.c
new file mode 100644
index 0000000000000000000000000000000000000000..fcd97794f2d6e08d41acd9f2a4d4fc0252b6caf2
--- /dev/null
+++ b/common/efi_malloc.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Sascha Hauer <s.hauer@pengutronix.de>
+ */
+#include <linux/sizes.h>
+#include <common.h>
+#include <malloc.h>
+#include <efi.h>
+#include <efi/efi-util.h>
+#include <string.h>
+#include <errno.h>
+
+struct alloc_header {
+ size_t size; /* requested size */
+};
+
+void *efi_malloc(size_t size)
+{
+ efi_status_t efiret;
+ efi_physical_addr_t mem;
+ struct alloc_header *hdr;
+ size_t pages;
+
+ if (!size)
+ return ZERO_SIZE_PTR;
+
+ pages = DIV_ROUND_UP(size, EFI_PAGE_SIZE);
+ efiret = BS->allocate_pages(EFI_ALLOCATE_ANY_PAGES, EFI_LOADER_DATA,
+ pages, &mem);
+ if (EFI_ERROR(efiret)) {
+ errno = efi_errno(efiret);
+ return NULL;
+ }
+
+ hdr = (struct alloc_header *)efi_phys_to_virt(mem);
+ hdr->size = size;
+ return (void *)(hdr + 1);
+}
+
+void efi_free(void *ptr)
+{
+ efi_physical_addr_t phys;
+ struct alloc_header *hdr;
+
+ if (!ptr)
+ return;
+
+ hdr = (struct alloc_header *)ptr - 1;
+ phys = efi_virt_to_phys(hdr);
+ BS->free_pages(phys, DIV_ROUND_UP(hdr->size, EFI_PAGE_SIZE));
+}
+
+void *efi_realloc(void *ptr, size_t size)
+{
+ struct alloc_header *hdr;
+ void *n_mem;
+ size_t old_sz;
+
+ if (!ptr)
+ return efi_malloc(size);
+
+ if (!size) {
+ efi_free(ptr);
+ return NULL;
+ }
+
+ hdr = (struct alloc_header *)ptr - 1;
+ old_sz = hdr->size;
+
+ n_mem = efi_malloc(size);
+ if (!n_mem) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ memcpy(n_mem, ptr, (old_sz < size) ? old_sz : size);
+ efi_free(ptr);
+
+ return n_mem;
+}
diff --git a/common/tlsf_malloc.c b/common/tlsf_malloc.c
index 6e9d48af26bbf05573fda04f616412c895342593..25ae40e455528a318fc150dba4ea7bc2ce27f3e3 100644
--- a/common/tlsf_malloc.c
+++ b/common/tlsf_malloc.c
@@ -6,6 +6,8 @@
*/
#include <malloc.h>
+#include <efi.h>
+#include <memory.h>
#include <string.h>
#include <stdio.h>
@@ -29,8 +31,12 @@ void *malloc(size_t bytes)
void *mem;
mem = tlsf_malloc(tlsf_mem_pool, bytes);
- if (!mem)
+ if (!mem) {
+ if (IS_ENABLED(CONFIG_MALLOC_EFI))
+ return efi_malloc(bytes);
+
errno = ENOMEM;
+ }
return mem;
}
@@ -38,6 +44,14 @@ EXPORT_SYMBOL(malloc);
void free(void *mem)
{
+ if (IS_ENABLED(CONFIG_MALLOC_EFI)) {
+ if (efi_virt_to_phys(mem) < mem_malloc_start() &&
+ efi_virt_to_phys(mem) > mem_malloc_end()) {
+ efi_free(mem);
+ return;
+ }
+ }
+
tlsf_free(tlsf_mem_pool, mem);
}
EXPORT_SYMBOL(free);
@@ -51,8 +65,12 @@ EXPORT_SYMBOL(malloc_usable_size);
void *realloc(void *oldmem, size_t bytes)
{
void *mem = tlsf_realloc(tlsf_mem_pool, oldmem, bytes);
- if (!mem)
+ if (!mem) {
+ if (IS_ENABLED(CONFIG_MALLOC_EFI))
+ return efi_realloc(oldmem, bytes);
+
errno = ENOMEM;
+ }
return mem;
}
diff --git a/include/malloc.h b/include/malloc.h
index 35551250324ee1d3c8ddc06f49a06ce07d2855bd..2294d129838829955ffc08c5ecb9df91d05073c9 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -24,6 +24,25 @@
#ifdef CONFIG_MALLOC_TLSF
void *malloc_add_pool(void *mem, size_t bytes);
#endif
+void *efi_malloc(size_t size);
+void efi_free(void *ptr);
+void *efi_realloc(void *ptr, size_t size);
+#ifdef MALLOC_EFI
+static inline void *efi_malloc(size_t size)
+{
+ errno = -ENOMEM;
+ return NULL;
+}
+
+static inline void efi_free(void *ptr) {}
+
+static inline void *efi_realloc(void *ptr, size_t size)
+{
+ errno = -ENOMEM;
+ return NULL;
+}
+#else
+#endif
#if IN_PROPER
void *malloc(size_t) __alloc_size(1);
--
2.34.1
next prev parent reply other threads:[~2025-09-20 3:04 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-20 3:03 [PATCH 00/15] Implement efi loader to run barebox as efi payload app and then load efi stubed application/kernels chalianis1
2025-09-20 3:03 ` [PATCH 01/15] efi: payload: split image handling from legacy handover boot support chalianis1
2025-09-20 3:03 ` [PATCH 02/15] efi: payload: add support for efi stub boot chalianis1
2025-09-20 3:03 ` [PATCH 03/15] efi: payload: add support for fit image chalianis1
2025-09-20 3:03 ` [PATCH 04/15] efi: payload: make selectable without COMPILE_TEST chalianis1
2025-09-20 3:03 ` [PATCH 05/15] arm: efi: add a generic defconfig for v8 efi payload, Chali Anis
2025-09-20 3:03 ` [PATCH 06/15] efi: payload: initrd: implement efi initrd media protocol Chali Anis
2025-09-20 3:03 ` [PATCH 07/15] common: filetype: add x86 linux filetype Chali Anis
2025-09-20 3:03 ` [PATCH 08/15] efi: payload: early-mem: helps to correctly boot x86 linux Chali Anis
2025-09-20 3:03 ` [PATCH 09/15] efi: payload: bootm: add x86 efi stub boot support Chali Anis
2025-09-20 3:03 ` [PATCH 10/15] efi: payload: x86: enable the possibility to efi stub bootm for x86 Chali Anis
2025-09-20 3:03 ` Chali Anis [this message]
2025-09-20 3:03 ` [PATCH 12/15] configs: efi: arm64: x86: enable the use of efi malloc fallback Chali Anis
2025-09-20 3:03 ` [PATCH 13/15] efi: payload: earlymem: allocate only the barebox needs in term of memory Chali Anis
2025-09-20 3:03 ` [PATCH 14/15] ARM: cpu: allow selecting CPU_V7/CPU_V8 directly chalianis1
2025-09-20 3:03 ` [PATCH 15/15] efi: payload: bootm: remove redundant reallocations in image loader Chali Anis
2025-09-22 7:37 ` [PATCH 00/15] Implement efi loader to run barebox as efi payload app and then load efi stubed application/kernels Ahmad Fatoum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250919-efi-loader-v1-11-dd8cdafb9067@gmail.com \
--to=chalianis1@gmail.com \
--cc=barebox@lists.infradead.org \
--cc=s.hauer@pengutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox