summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorHari Bathini <hbathini@linux.vnet.ibm.com>2017-03-16 22:05:26 +0100
committerMichael Ellerman <mpe@ellerman.id.au>2017-03-31 13:34:29 +0200
commitf6e6bedb773118713a8eb3736a4c99c71144275e (patch)
treeb1b1ddecd30a969dcb4a587453d5ca0ca9c4e226 /arch/powerpc/kernel
parentpowerpc/powernv: Handle OPAL_WRONG_STATE in opal_get_sensor_data() (diff)
downloadlinux-f6e6bedb773118713a8eb3736a4c99c71144275e.tar.xz
linux-f6e6bedb773118713a8eb3736a4c99c71144275e.zip
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: Hari Bathini <hbathini@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/fadump.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 8ff0dd4e77a7..33b2da302730 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -319,15 +319,34 @@ int __init fadump_reserve_mem(void)
pr_debug("fadumphdr_addr = %p\n",
(void *) fw_dump.fadumphdr_addr);
} else {
- /* Reserve the memory at the top of memory. */
size = get_fadump_area_size();
- base = memory_boundary - size;
- memblock_reserve(base, size);
- printk(KERN_INFO "Reserved %ldMB of memory at %ldMB "
- "for firmware-assisted dump\n",
- (unsigned long)(size >> 20),
- (unsigned long)(base >> 20));
+
+ /*
+ * Reserve memory at an offset closer to bottom of the RAM to
+ * 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)(base >> 20),
+ (unsigned long)(memblock_phys_mem_size() >> 20));
}
+
fw_dump.reserve_dump_area_start = base;
fw_dump.reserve_dump_area_size = size;
return 1;