Skip to content

Commit ae1add2

Browse files
Mitchel Humpherysrobherring
authored andcommitted
of: Check for overlap in reserved memory regions
Any overlap in the reserved memory regions (those specified in the reserved-memory DT node) is a bug. These bugs might go undetected as long as the contested region isn't used simultaneously by multiple software agents, which makes such bugs hard to debug. Fix this by printing a scary warning during boot if overlap is detected. Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org> Signed-off-by: Rob Herring <robh@kernel.org>
1 parent 4f59d71 commit ae1add2

File tree

1 file changed

+42
-1
lines changed

1 file changed

+42
-1
lines changed

drivers/of/of_reserved_mem.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* Device tree based initialization code for reserved memory.
33
*
4-
* Copyright (c) 2013, The Linux Foundation. All Rights Reserved.
4+
* Copyright (c) 2013, 2015 The Linux Foundation. All Rights Reserved.
55
* Copyright (c) 2013,2014 Samsung Electronics Co., Ltd.
66
* http://www.samsung.com
77
* Author: Marek Szyprowski <m.szyprowski@samsung.com>
@@ -20,6 +20,7 @@
2020
#include <linux/mm.h>
2121
#include <linux/sizes.h>
2222
#include <linux/of_reserved_mem.h>
23+
#include <linux/sort.h>
2324

2425
#define MAX_RESERVED_REGIONS 16
2526
static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
@@ -197,12 +198,52 @@ static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
197198
return -ENOENT;
198199
}
199200

201+
static int __init __rmem_cmp(const void *a, const void *b)
202+
{
203+
const struct reserved_mem *ra = a, *rb = b;
204+
205+
return ra->base - rb->base;
206+
}
207+
208+
static void __init __rmem_check_for_overlap(void)
209+
{
210+
int i;
211+
212+
if (reserved_mem_count < 2)
213+
return;
214+
215+
sort(reserved_mem, reserved_mem_count, sizeof(reserved_mem[0]),
216+
__rmem_cmp, NULL);
217+
for (i = 0; i < reserved_mem_count - 1; i++) {
218+
struct reserved_mem *this, *next;
219+
220+
this = &reserved_mem[i];
221+
next = &reserved_mem[i + 1];
222+
if (!(this->base && next->base))
223+
continue;
224+
if (this->base + this->size > next->base) {
225+
phys_addr_t this_end, next_end;
226+
227+
this_end = this->base + this->size;
228+
next_end = next->base + next->size;
229+
WARN(1,
230+
"Reserved memory: OVERLAP DETECTED!\n%s (%pa--%pa) overlaps with %s (%pa--%pa)\n",
231+
this->name, &this->base, &this_end,
232+
next->name, &next->base, &next_end);
233+
}
234+
}
235+
}
236+
200237
/**
201238
* fdt_init_reserved_mem - allocate and init all saved reserved memory regions
202239
*/
203240
void __init fdt_init_reserved_mem(void)
204241
{
205242
int i;
243+
244+
/* check for overlapping reserved regions */
245+
__rmem_check_for_overlap();
246+
206247
for (i = 0; i < reserved_mem_count; i++) {
207248
struct reserved_mem *rmem = &reserved_mem[i];
208249
unsigned long node = rmem->fdt_node;

0 commit comments

Comments
 (0)