提交 0ec7ec75 编写于 作者: R Ralf Baechle

MIPS: Merge overlapping bootmem ranges

Without this, we may end up with something like this in /proc/iomem:

01100000-014fffff : System RAM
  01100000-013bf48f : Kernel code
  013bf490-0149e01f : Kernel data
01500000-0c0fffff : System RAM

but the two System RAM ranges should be one single range.  This particular
case will result in kexec failure on Octeon systems if the kernel being
loaded by kexec is bigger than the already running kernel.
Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
上级 f4a75d2e
......@@ -79,7 +79,7 @@ static struct resource data_resource = { .name = "Kernel data", };
void __init add_memory_region(phys_t start, phys_t size, long type)
{
int x = boot_mem_map.nr_map;
struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1;
int i;
/* Sanity check */
if (start + size < start) {
......@@ -88,15 +88,29 @@ void __init add_memory_region(phys_t start, phys_t size, long type)
}
/*
* Try to merge with previous entry if any. This is far less than
* perfect but is sufficient for most real world cases.
* Try to merge with existing entry, if any.
*/
if (x && prev->addr + prev->size == start && prev->type == type) {
prev->size += size;
for (i = 0; i < boot_mem_map.nr_map; i++) {
struct boot_mem_map_entry *entry = boot_mem_map.map + i;
unsigned long top;
if (entry->type != type)
continue;
if (start + size < entry->addr)
continue; /* no overlap */
if (entry->addr + entry->size < start)
continue; /* no overlap */
top = max(entry->addr + entry->size, start + size);
entry->addr = min(entry->addr, start);
entry->size = top - entry->addr;
return;
}
if (x == BOOT_MEM_MAP_MAX) {
if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) {
pr_err("Ooops! Too many entries in the memory map!\n");
return;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册