---
xen/arch/arm/bootfdt.c | 13 ++++----
xen/arch/arm/include/asm/setup.h | 2 ++
xen/arch/arm/setup.c | 52 ++++++++++++++++++++++++++++++++
3 files changed, 60 insertions(+), 7 deletions(-)
diff --git a/xen/arch/arm/bootfdt.c b/xen/arch/arm/bootfdt.c
index 6014c0f852..b31379b9ac 100644
--- a/xen/arch/arm/bootfdt.c
+++ b/xen/arch/arm/bootfdt.c
@@ -91,6 +91,9 @@ static int __init device_tree_get_meminfo(const void *fdt,
int node,
for ( i = 0; i < banks && mem->nr_banks < NR_MEM_BANKS; i++ )
{
device_tree_get_reg(&cell, address_cells, size_cells, &start, &size);
+ if ( mem == &bootinfo.reserved_mem &&
+ check_reserved_regions_overlap(start, size) )
+ return -EINVAL;
/* Some DT may describe empty bank, ignore them */
if ( !size )
continue;
@@ -485,7 +488,9 @@ static int __init process_shm_node(const void *fdt, int
node,
return -EINVAL;
}
- if ( (end <= mem->bank[i].start) || (paddr >= bank_end) )
+ if ( check_reserved_regions_overlap(paddr, size) )
+ return -EINVAL;
+ else
{
if ( strcmp(shm_id, mem->bank[i].shm_id) != 0 )
continue;
@@ -496,12 +501,6 @@ static int __init process_shm_node(const void *fdt, int
node,
return -EINVAL;
}
}
- else
- {
- printk("fdt: shared memory region overlap with an existing entry %#"PRIpaddr"
- %#"PRIpaddr"\n",
- mem->bank[i].start, bank_end);
- return -EINVAL;
- }
}
}
diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h
index fdbf68aadc..6a9f88ecbb 100644
--- a/xen/arch/arm/include/asm/setup.h
+++ b/xen/arch/arm/include/asm/setup.h
@@ -143,6 +143,8 @@ void fw_unreserved_regions(paddr_t s, paddr_t e,
size_t boot_fdt_info(const void *fdt, paddr_t paddr);
const char *boot_fdt_cmdline(const void *fdt);
+int check_reserved_regions_overlap(paddr_t region_start, paddr_t region_size);
+
struct bootmodule *add_boot_module(bootmodule_kind kind,
paddr_t start, paddr_t size, bool domU);
struct bootmodule *boot_module_find_by_kind(bootmodule_kind kind);
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 4395640019..94d232605e 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -270,6 +270,42 @@ static void __init dt_unreserved_regions(paddr_t s,
paddr_t e,
cb(s, e);
}
+static int __init overlap_check(void *bootinfo_type,
+ paddr_t region_start, paddr_t region_end)
+{
+ unsigned int i, num = 0;
+ paddr_t bank_start = INVALID_PADDR, bank_end = 0;
+ char *type_str = "NONAME";
+
+ if ( bootinfo_type == &bootinfo.reserved_mem )
+ {
+ num = bootinfo.reserved_mem.nr_banks;
+ type_str = "reserved_mem";
+ }
+ else
+ panic("Invalid bootinfo type passed to overlap check\n");
+
+ for ( i = 0; i < num; i++ )
+ {
+ if ( bootinfo_type == &bootinfo.reserved_mem )
+ {
+ bank_start = bootinfo.reserved_mem.bank[i].start;
+ bank_end = bank_start + bootinfo.reserved_mem.bank[i].size;
+ }
+
+ if ( region_end <= bank_start || region_start >= bank_end )
+ continue;
+ else
+ {
+ printk("%s: Region %#"PRIpaddr" - %#"PRIpaddr" overlapping with bank[%u]
%#"PRIpaddr" - %#"PRIpaddr"\n",
+ type_str, region_start, region_end, i, bank_start,
bank_end);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}