|
@@ -43,7 +43,10 @@
|
|
|
#include <linux/init.h>
|
|
|
#include <linux/edd.h>
|
|
|
#include <linux/nodemask.h>
|
|
|
+#include <linux/kexec.h>
|
|
|
+
|
|
|
#include <video/edid.h>
|
|
|
+
|
|
|
#include <asm/apic.h>
|
|
|
#include <asm/e820.h>
|
|
|
#include <asm/mpspec.h>
|
|
@@ -846,6 +849,27 @@ static void __init parse_cmdline_early (char ** cmdline_p)
|
|
|
lapic_disable();
|
|
|
#endif /* CONFIG_X86_LOCAL_APIC */
|
|
|
|
|
|
+#ifdef CONFIG_KEXEC
|
|
|
+ /* crashkernel=size@addr specifies the location to reserve for
|
|
|
+ * a crash kernel. By reserving this memory we guarantee
|
|
|
+ * that linux never set's it up as a DMA target.
|
|
|
+ * Useful for holding code to do something appropriate
|
|
|
+ * after a kernel panic.
|
|
|
+ */
|
|
|
+ else if (!memcmp(from, "crashkernel=", 12)) {
|
|
|
+ unsigned long size, base;
|
|
|
+ size = memparse(from+12, &from);
|
|
|
+ if (*from == '@') {
|
|
|
+ base = memparse(from+1, &from);
|
|
|
+ /* FIXME: Do I want a sanity check
|
|
|
+ * to validate the memory range?
|
|
|
+ */
|
|
|
+ crashk_res.start = base;
|
|
|
+ crashk_res.end = base + size - 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
/*
|
|
|
* highmem=size forces highmem to be exactly 'size' bytes.
|
|
|
* This works even on boxes that have no highmem otherwise.
|
|
@@ -1181,6 +1205,11 @@ void __init setup_bootmem_allocator(void)
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
+#ifdef CONFIG_KEXEC
|
|
|
+ if (crashk_res.start != crashk_res.end)
|
|
|
+ reserve_bootmem(crashk_res.start,
|
|
|
+ crashk_res.end - crashk_res.start + 1);
|
|
|
+#endif
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -1234,6 +1263,9 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
|
|
|
*/
|
|
|
request_resource(res, code_resource);
|
|
|
request_resource(res, data_resource);
|
|
|
+#ifdef CONFIG_KEXEC
|
|
|
+ request_resource(res, &crashk_res);
|
|
|
+#endif
|
|
|
}
|
|
|
}
|
|
|
}
|