[PATCHv2 1/5] lmb: add LMB_FDT for fdt reserved regions

Heinrich Schuchardt xypron.glpk at gmx.de
Thu Apr 9 21:15:20 CEST 2026


Am 2. April 2026 22:50:34 MESZ schrieb rs at ti.com:
>From: Randolph Sapp <rs at ti.com>
>
>Add an LMB_FDT bit for fdt reserved regions, so we can reclaim them when
>parsing a new device tree and properly warn people when a reservation
>overlaps with an existing allocation.
>
>If we don't at least warn the user of these reservation failures,
>there's a chance that this region could be freed and reallocated for
>something important later.
>
>This useful warning mechanism was broken in:
>5a6aa7d5913 ("boot: fdt: Handle already reserved memory in boot_fdt_reserve_region()")
>
>Signed-off-by: Randolph Sapp <rs at ti.com>
>---
> boot/image-fdt.c |  5 ++++-
> include/lmb.h    |  7 +++++++
> lib/lmb.c        | 25 +++++++++++++++++++++++++
> 3 files changed, 36 insertions(+), 1 deletion(-)
>
>diff --git a/boot/image-fdt.c b/boot/image-fdt.c
>index a3a4fb8b558..0f5857f24d2 100644
>--- a/boot/image-fdt.c
>+++ b/boot/image-fdt.c
>@@ -73,6 +73,7 @@ static void boot_fdt_reserve_region(u64 addr, u64 size, u32 flags)
> {
> 	long ret;
> 	phys_addr_t rsv_addr;
>+	flags |= LMB_FDT;
> 
> 	rsv_addr = (phys_addr_t)addr;
> 	ret = lmb_alloc_mem(LMB_MEM_ALLOC_ADDR, 0, &rsv_addr, size, flags);
>@@ -80,7 +81,7 @@ static void boot_fdt_reserve_region(u64 addr, u64 size, u32 flags)
> 		debug("   reserving fdt memory region: addr=%llx size=%llx flags=%x\n",
> 		      (unsigned long long)addr,
> 		      (unsigned long long)size, flags);
>-	} else if (ret != -EEXIST && ret != -EINVAL) {
>+	} else if (ret != -EINVAL) {
> 		puts("ERROR: reserving fdt memory region failed ");
> 		printf("(addr=%llx size=%llx flags=%x)\n",
> 		       (unsigned long long)addr,
>@@ -108,6 +109,8 @@ void boot_fdt_add_mem_rsv_regions(void *fdt_blob)
> 	if (fdt_check_header(fdt_blob) != 0)
> 		return;
> 
>+	lmb_free_fdt_regions();
>+
> 	/* process memreserve sections */
> 	total = fdt_num_mem_rsv(fdt_blob);
> 	for (i = 0; i < total; i++) {
>diff --git a/include/lmb.h b/include/lmb.h
>index 5d5f037ccb9..1b59a63f61d 100644
>--- a/include/lmb.h
>+++ b/include/lmb.h
>@@ -25,11 +25,13 @@
>  * %LMB_NOMAP: Don't add to MMU configuration
>  * %LMB_NOOVERWRITE: The memory region cannot be overwritten/re-reserved
>  * %LMB_NONOTIFY: Do not notify other modules of changes to this memory region
>+ * %LMB_FDT: A FDT reserved region that can be reclaimed if the FDT changes
>  */
> #define LMB_NONE 0
> #define LMB_NOMAP BIT(1)
> #define LMB_NOOVERWRITE BIT(2)
> #define LMB_NONOTIFY BIT(3)
>+#define LMB_FDT BIT(4)

Please, document the constants according to https://docs.kernel.org/doc-guide/kernel-doc.html#object-like-macro-documentation .  This allows Sphinx to generate the API documentation.

Best regards

Heinrich

> 
> /**
>  * enum lmb_mem_type - type of memory allocation request
>@@ -215,6 +217,11 @@ phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align);
>  */
> long io_lmb_free(struct lmb *io_lmb, phys_addr_t base, phys_size_t size);
> 
>+/**
>+ * lmb_free_fdt_regions() - Reclaim all LMB_FDT tagged reserved regions
>+ */
>+void lmb_free_fdt_regions(void);
>+
> #endif /* __KERNEL__ */
> 
> #endif /* _LINUX_LMB_H */
>diff --git a/lib/lmb.c b/lib/lmb.c
>index e2d9fe86c14..18703212afb 100644
>--- a/lib/lmb.c
>+++ b/lib/lmb.c
>@@ -669,6 +669,31 @@ long lmb_free(phys_addr_t base, phys_size_t size, u32 flags)
> 	return lmb_map_update_notify(base, size, LMB_MAP_OP_FREE, flags);
> }
> 
>+void lmb_free_fdt_regions(void)
>+{
>+	struct alist *lmb_rgn_lst = &lmb.used_mem;
>+	struct lmb_region *rgn = lmb_rgn_lst->data;
>+	long ret;
>+	int i = 0;
>+
>+	while (i < lmb_rgn_lst->count) {
>+		phys_addr_t base = rgn[i].base;
>+		phys_size_t size = rgn[i].size;
>+		u32 flags = rgn[i].flags;
>+
>+		if (flags & LMB_FDT) {
>+			ret = lmb_free(base, size, flags);
>+			if (ret < 0) {
>+				printf("Unable to free FDT memory at 0x%08lx",
>+				       (ulong)base);
>+				i++;
>+			}
>+		} else {
>+			i++;
>+		}
>+	}
>+}
>+
> static int _lmb_alloc_base(phys_size_t size, ulong align,
> 			   phys_addr_t *addr, u32 flags)
> {



More information about the U-Boot mailing list