[PATCH 04/11] boot: imagemap: free the reservation a replaced record owned

Daniel Golle daniel at makrotopia.org
Mon Sep 28 17:05:12 PDT 2026


imagemap_record() overwrites an entry that already covers the same image
offset, including its lmb_reserved flag. When imagemap_map_to() replaces
a region that imagemap_map() had allocated from LMB, the reservation is
forgotten with the address that owned it, so imagemap_cleanup() walks a
table that no longer mentions it and the memory stays reserved for the
rest of the boot.

Release the reservation before the entry is pointed at different memory.

Fixes: 9b41c7dbee96 ("boot: add imagemap on-demand loading from storage")
Signed-off-by: Daniel Golle <daniel at makrotopia.org>
---
 boot/imagemap.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/boot/imagemap.c b/boot/imagemap.c
index 9e77ed25d00..89396a03730 100644
--- a/boot/imagemap.c
+++ b/boot/imagemap.c
@@ -114,12 +114,22 @@ imagemap_record(struct udevice *dev, loff_t img_offset, ulong size,
 
 	/* Check for an existing entry at the same base that we can extend */
 	alist_for_each(r, &priv->regions) {
-		if (r->img_offset == img_offset) {
-			r->size = size;
-			r->ram = ram;
-			r->lmb_reserved = lmb_reserved;
-			return r;
-		}
+		if (r->img_offset != img_offset)
+			continue;
+
+		/*
+		 * The entry is about to describe different memory, so give up
+		 * the reservation it owns while its address is still known.
+		 */
+		if (r->lmb_reserved && r->ram != ram)
+			lmb_free(map_to_sysmem(r->ram),
+				 ALIGN(r->size, ARCH_DMA_MINALIGN), LMB_NONE);
+
+		r->size = size;
+		r->ram = ram;
+		r->lmb_reserved = lmb_reserved;
+
+		return r;
 	}
 
 	/* Append new region */
-- 
2.55.0



More information about the openwrt-devel mailing list