Commit f6e6bedb authored by Hari Bathini's avatar Hari Bathini Committed by Michael Ellerman

powerpc/fadump: Reserve memory at an offset closer to bottom of RAM

Currently, the area to preserve boot memory is reserved at the top of
RAM. This leaves fadump vulnerable to memory hot-remove operations. As
memory for fadump has to be reserved early in the boot process, fadump
can't be registered after a memory hot-remove operation. Though this
problem can't be eleminated completely, the impact can be minimized by
reserving memory at an offset closer to bottom of the RAM. The offset
for fadump memory reservation can be any value greater than fadump boot
memory size.
Signed-off-by: default avatarHari Bathini <hbathini@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 17bb6951
...@@ -319,15 +319,34 @@ int __init fadump_reserve_mem(void) ...@@ -319,15 +319,34 @@ int __init fadump_reserve_mem(void)
pr_debug("fadumphdr_addr = %p\n", pr_debug("fadumphdr_addr = %p\n",
(void *) fw_dump.fadumphdr_addr); (void *) fw_dump.fadumphdr_addr);
} else { } else {
/* Reserve the memory at the top of memory. */
size = get_fadump_area_size(); size = get_fadump_area_size();
base = memory_boundary - size;
memblock_reserve(base, size); /*
printk(KERN_INFO "Reserved %ldMB of memory at %ldMB " * Reserve memory at an offset closer to bottom of the RAM to
"for firmware-assisted dump\n", * minimize the impact of memory hot-remove operation. We can't
* use memblock_find_in_range() here since it doesn't allocate
* from bottom to top.
*/
for (base = fw_dump.boot_memory_size;
base <= (memory_boundary - size);
base += size) {
if (memblock_is_region_memory(base, size) &&
!memblock_is_region_reserved(base, size))
break;
}
if ((base > (memory_boundary - size)) ||
memblock_reserve(base, size)) {
pr_err("Failed to reserve memory\n");
return 0;
}
pr_info("Reserved %ldMB of memory at %ldMB for firmware-"
"assisted dump (System RAM: %ldMB)\n",
(unsigned long)(size >> 20), (unsigned long)(size >> 20),
(unsigned long)(base >> 20)); (unsigned long)(base >> 20),
(unsigned long)(memblock_phys_mem_size() >> 20));
} }
fw_dump.reserve_dump_area_start = base; fw_dump.reserve_dump_area_start = base;
fw_dump.reserve_dump_area_size = size; fw_dump.reserve_dump_area_size = size;
return 1; return 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment