fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / powerpc / kernel / machine_kexec.c
index a81ca1b..e60a0c5 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/reboot.h>
 #include <linux/threads.h>
 #include <asm/machdep.h>
+#include <asm/lmb.h>
 
 void machine_crash_shutdown(struct pt_regs *regs)
 {
@@ -59,3 +60,58 @@ NORET_TYPE void machine_kexec(struct kimage *image)
        }
        for(;;);
 }
+
+static int __init early_parse_crashk(char *p)
+{
+       unsigned long size;
+
+       if (!p)
+               return 1;
+
+       size = memparse(p, &p);
+
+       if (*p == '@')
+               crashk_res.start = memparse(p + 1, &p);
+       else
+               crashk_res.start = KDUMP_KERNELBASE;
+
+       crashk_res.end = crashk_res.start + size - 1;
+
+       return 0;
+}
+early_param("crashkernel", early_parse_crashk);
+
+void __init reserve_crashkernel(void)
+{
+       unsigned long size;
+
+       if (crashk_res.start == 0)
+               return;
+
+       /* We might have got these values via the command line or the
+        * device tree, either way sanitise them now. */
+
+       size = crashk_res.end - crashk_res.start + 1;
+
+       if (crashk_res.start != KDUMP_KERNELBASE)
+               printk("Crash kernel location must be 0x%x\n",
+                               KDUMP_KERNELBASE);
+
+       crashk_res.start = KDUMP_KERNELBASE;
+       size = PAGE_ALIGN(size);
+       crashk_res.end = crashk_res.start + size - 1;
+
+       /* Crash kernel trumps memory limit */
+       if (memory_limit && memory_limit <= crashk_res.end) {
+               memory_limit = crashk_res.end + 1;
+               printk("Adjusted memory limit for crashkernel, now 0x%lx\n",
+                               memory_limit);
+       }
+
+       lmb_reserve(crashk_res.start, size);
+}
+
+int overlaps_crashkernel(unsigned long start, unsigned long size)
+{
+       return (start + size) > crashk_res.start && start <= crashk_res.end;
+}