[PATCH 1/6] lmb: add LMB_FDT for fdt reserved regions

Randolph Sapp rs at ti.com
Thu Apr 2 02:36:28 CEST 2026


On Wed Apr 1, 2026 at 7:14 PM CDT, rs wrote:
> 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        | 23 +++++++++++++++++++++++
>  3 files changed, 34 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)
>  
>  /**
>   * 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..542bb11dcf5 100644
> --- a/lib/lmb.c
> +++ b/lib/lmb.c
> @@ -669,6 +669,29 @@ 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;
> +
> +	for (int i = 0; i < lmb_rgn_lst->count; i++) {
> +		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);
> +				continue;
> +			}
> +			i--;
> +		}
> +	}
> +}
> +
>  static int _lmb_alloc_base(phys_size_t size, ulong align,
>  			   phys_addr_t *addr, u32 flags)
>  {

Ugh. Looking at that loop in lmb_free_fdt_regions more I really should have
written it differently to avoid the additional increments and decrements. I'll
fix that in v2.


More information about the U-Boot mailing list