From 5d1abb640e0bc400257233992956d430226b0d6b Mon Sep 17 00:00:00 2001 From: Oliver O'Halloran Date: Mon, 15 May 2017 13:40:38 +1000 Subject: core/mem_region: Print a useful error on overlap New memory regions need to be either fully contained by an existing region or completely disjoint. Right now we just fail silently or crash with an assert which is less than helpful. Printing some basic information, such as the names of the overlapping regions is helpful. Signed-off-by: Oliver O'Halloran Signed-off-by: Stewart Smith --- core/mem_region.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/core/mem_region.c b/core/mem_region.c index 567d260..a314558 100644 --- a/core/mem_region.c +++ b/core/mem_region.c @@ -689,6 +689,14 @@ static bool overlaps(const struct mem_region *r1, const struct mem_region *r2) && r1->start < r2->start + r2->len); } +static bool contains(const struct mem_region *r1, const struct mem_region *r2) +{ + u64 r1_end = r1->start + r1->len; + u64 r2_end = r2->start + r2->len; + + return (r1->start <= r2->start && r2_end <= r1_end); +} + static struct mem_region *get_overlap(const struct mem_region *region) { struct mem_region *i; @@ -711,10 +719,29 @@ static bool add_region(struct mem_region *region) } /* First split any regions which intersect. */ - list_for_each(®ions, r, list) + list_for_each(®ions, r, list) { + /* + * The new region should be fully contained by an existing one. + * If it's not then we have a problem where reservations + * partially overlap which is probably broken. + * + * NB: There *might* be situations where this is legitimate, + * but the region handling does not currently support this. + */ + if (overlaps(r, region) && !contains(r, region)) { + prerror("MEM: Partial overlap detected between regions:\n"); + prerror("MEM: %s [0x%"PRIx64"-0x%"PRIx64"] (new)\n", + region->name, region->start, + region->start + region->len); + prerror("MEM: %s [0x%"PRIx64"-0x%"PRIx64"]\n", + r->name, r->start, r->start + r->len); + return false; + } + if (!maybe_split(r, region->start) || !maybe_split(r, region->start + region->len)) return false; + } /* Now we have only whole overlaps, if any. */ while ((r = get_overlap(region)) != NULL) { -- cgit v1.1