s390/kdump: Add PM notifier for kdump
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>
Thu, 4 Apr 2013 17:49:53 +0000 (19:49 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 15 Apr 2013 11:34:44 +0000 (13:34 +0200)
For s390 the page table mapping for the crashkernel memory is removed to
protect the pre-loaded kdump kernel and ramdisk. Because the crashkernel
memory is not included in the page tables for suspend/resume it is not
included in the suspend image. Therefore after resume the resumed system
does no longer contain the pre-loaded kdump kernel and when kdump is
triggered it fails.

This patch adds a PM notifier that creates the page tables before suspend
is done and removes them for resume. This ensures that the kdump kernel
is included in the suspend image.

Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/kernel/machine_kexec.c

index b3de27700016a18c8a3764db54d6a5cae5e77d5d..ac2178161ec3b80bae5324728e62ead072f97c91 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/reboot.h>
 #include <linux/ftrace.h>
 #include <linux/debug_locks.h>
+#include <linux/suspend.h>
 #include <asm/cio.h>
 #include <asm/setup.h>
 #include <asm/pgtable.h>
@@ -67,6 +68,35 @@ void setup_regs(void)
        memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area));
 }
 
+/*
+ * PM notifier callback for kdump
+ */
+static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action,
+                              void *ptr)
+{
+       switch (action) {
+       case PM_SUSPEND_PREPARE:
+       case PM_HIBERNATION_PREPARE:
+               if (crashk_res.start)
+                       crash_map_reserved_pages();
+               break;
+       case PM_POST_SUSPEND:
+       case PM_POST_HIBERNATION:
+               if (crashk_res.start)
+                       crash_unmap_reserved_pages();
+               break;
+       default:
+               return NOTIFY_DONE;
+       }
+       return NOTIFY_OK;
+}
+
+static int __init machine_kdump_pm_init(void)
+{
+       pm_notifier(machine_kdump_pm_cb, 0);
+       return 0;
+}
+arch_initcall(machine_kdump_pm_init);
 #endif
 
 /*