|
1 | 1 | /*
|
2 | 2 | * Device tree based initialization code for reserved memory.
|
3 | 3 | *
|
4 |
| - * Copyright (c) 2013, The Linux Foundation. All Rights Reserved. |
| 4 | + * Copyright (c) 2013, 2015 The Linux Foundation. All Rights Reserved. |
5 | 5 | * Copyright (c) 2013,2014 Samsung Electronics Co., Ltd.
|
6 | 6 | * http://www.samsung.com
|
7 | 7 | * Author: Marek Szyprowski <m.szyprowski@samsung.com>
|
|
20 | 20 | #include <linux/mm.h>
|
21 | 21 | #include <linux/sizes.h>
|
22 | 22 | #include <linux/of_reserved_mem.h>
|
| 23 | +#include <linux/sort.h> |
23 | 24 |
|
24 | 25 | #define MAX_RESERVED_REGIONS 16
|
25 | 26 | static struct reserved_mem reserved_mem[MAX_RESERVED_REGIONS];
|
@@ -197,12 +198,52 @@ static int __init __reserved_mem_init_node(struct reserved_mem *rmem)
|
197 | 198 | return -ENOENT;
|
198 | 199 | }
|
199 | 200 |
|
| 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 | + |
200 | 237 | /**
|
201 | 238 | * fdt_init_reserved_mem - allocate and init all saved reserved memory regions
|
202 | 239 | */
|
203 | 240 | void __init fdt_init_reserved_mem(void)
|
204 | 241 | {
|
205 | 242 | int i;
|
| 243 | + |
| 244 | + /* check for overlapping reserved regions */ |
| 245 | + __rmem_check_for_overlap(); |
| 246 | + |
206 | 247 | for (i = 0; i < reserved_mem_count; i++) {
|
207 | 248 | struct reserved_mem *rmem = &reserved_mem[i];
|
208 | 249 | unsigned long node = rmem->fdt_node;
|
|
0 commit comments