From b2893e22e6927821d3b079e88e14a8c165e7f329 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 15 Jul 2023 01:47:04 +0200 Subject: [PATCH] memrange: Honor `limit` in the last step of top-down stealing We only checked that the resource fits below the given `limit` in memranges_find_entry(), but then accidentally placed it at the top of the found memrange. As most resources have only a coarse limit, e.g. the 4G barrier of 32-bit space, this became only visible when artificially setting an unusual, lower limit on a resource. So, for the final placement, use `MIN(limit, range end)` instead of the range's end alone. Change-Id: I3cc62ac3d427683c00ba0ac9f991fca62e99ce44 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/76480 Tested-by: build bot (Jenkins) Reviewed-by: Martin L Roth --- src/lib/memrange.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib/memrange.c b/src/lib/memrange.c index b68b86e2f8..9ae3e3e541 100644 --- a/src/lib/memrange.c +++ b/src/lib/memrange.c @@ -427,11 +427,12 @@ bool memranges_steal(struct memranges *ranges, resource_t limit, resource_t size return false; if (from_top) { + limit = MIN(limit, r->end); /* Ensure we're within the range, even aligned down. Proof is simple: If ALIGN_UP(r->begin) would be higher, the stolen range wouldn't fit.*/ - assert(r->begin <= ALIGN_DOWN(range_entry_end(r) - size, POWER_OF_2(align))); - *stolen_base = ALIGN_DOWN(range_entry_end(r) - size, POWER_OF_2(align)); + assert(r->begin <= ALIGN_DOWN(limit - size + 1, POWER_OF_2(align))); + *stolen_base = ALIGN_DOWN(limit - size + 1, POWER_OF_2(align)); } else { *stolen_base = ALIGN_UP(r->begin, POWER_OF_2(align)); }