region: Turn region_end() into an inclusive region_last()

The current region_end() implementation is susceptible to overflow
if the region is at the end of the addressable space. A common case
with the memory-mapped flash of x86 directly below the 32-bit limit.

Note: This patch also changes console output to inclusive limits.
IMO, to the better.

Change-Id: Ic4bd6eced638745b7e845504da74542e4220554a
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/79946
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
Nico Huber 2024-01-14 14:26:37 +01:00 committed by Julius Werner
commit 41feb32559
8 changed files with 23 additions and 27 deletions

View file

@ -124,15 +124,15 @@ static inline size_t region_sz(const struct region *r)
return r->size;
}
static inline size_t region_end(const struct region *r)
static inline size_t region_last(const struct region *r)
{
return region_offset(r) + region_sz(r);
return region_offset(r) + (region_sz(r) - 1);
}
static inline bool region_overlap(const struct region *r1, const struct region *r2)
{
return (region_end(r1) > region_offset(r2)) &&
(region_offset(r1) < region_end(r2));
return (region_last(r1) >= region_offset(r2)) &&
(region_offset(r1) <= region_last(r2));
}
/* Helper to dynamically initialize region device. */
@ -156,9 +156,9 @@ static inline size_t region_device_offset(const struct region_device *rdev)
return region_offset(region_device_region(rdev));
}
static inline size_t region_device_end(const struct region_device *rdev)
static inline size_t region_device_last(const struct region_device *rdev)
{
return region_end(region_device_region(rdev));
return region_last(region_device_region(rdev));
}
/* Memory map entire region device. Same semantics as rdev_mmap() above. */

View file

@ -10,10 +10,10 @@ int region_is_subregion(const struct region *p, const struct region *c)
if (region_offset(c) < region_offset(p))
return 0;
if (region_end(c) > region_end(p))
if (region_last(c) > region_last(p))
return 0;
if (region_end(c) < region_offset(c))
if (region_last(c) < region_offset(c))
return 0;
return 1;