summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/fadump.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/fadump.c')
-rw-r--r--arch/powerpc/kernel/fadump.c40
1 files changed, 34 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c
index 3c2c2688918ff..07e8396d472bd 100644
--- a/arch/powerpc/kernel/fadump.c
+++ b/arch/powerpc/kernel/fadump.c
@@ -335,6 +335,26 @@ static unsigned long get_fadump_area_size(void)
return size;
}
+static void __init fadump_reserve_crash_area(unsigned long base,
+ unsigned long size)
+{
+ struct memblock_region *reg;
+ unsigned long mstart, mend, msize;
+
+ for_each_memblock(memory, reg) {
+ mstart = max_t(unsigned long, base, reg->base);
+ mend = reg->base + reg->size;
+ mend = min(base + size, mend);
+
+ if (mstart < mend) {
+ msize = mend - mstart;
+ memblock_reserve(mstart, msize);
+ pr_info("Reserved %ldMB of memory at %#016lx for saving crash dump\n",
+ (msize >> 20), mstart);
+ }
+ }
+}
+
int __init fadump_reserve_mem(void)
{
unsigned long base, size, memory_boundary;
@@ -380,7 +400,16 @@ int __init fadump_reserve_mem(void)
memory_boundary = memblock_end_of_DRAM();
if (fw_dump.dump_active) {
- printk(KERN_INFO "Firmware-assisted dump is active.\n");
+ pr_info("Firmware-assisted dump is active.\n");
+
+#ifdef CONFIG_HUGETLB_PAGE
+ /*
+ * FADump capture kernel doesn't care much about hugepages.
+ * In fact, handling hugepages in capture kernel is asking for
+ * trouble. So, disable HugeTLB support when fadump is active.
+ */
+ hugetlb_disabled = true;
+#endif
/*
* If last boot has crashed then reserve all the memory
* above boot_memory_size so that we don't touch it until
@@ -389,11 +418,7 @@ int __init fadump_reserve_mem(void)
*/
base = fw_dump.boot_memory_size;
size = memory_boundary - base;
- memblock_reserve(base, size);
- printk(KERN_INFO "Reserved %ldMB of memory at %ldMB "
- "for saving crash dump\n",
- (unsigned long)(size >> 20),
- (unsigned long)(base >> 20));
+ fadump_reserve_crash_area(base, size);
fw_dump.fadumphdr_addr =
be64_to_cpu(fdm_active->rmr_region.destination_address) +
@@ -1155,6 +1180,9 @@ void fadump_cleanup(void)
init_fadump_mem_struct(&fdm,
be64_to_cpu(fdm_active->cpu_state_data.destination_address));
fadump_invalidate_dump(&fdm);
+ } else if (fw_dump.dump_registered) {
+ /* Un-register Firmware-assisted dump if it was registered. */
+ fadump_unregister_dump(&fdm);
}
}