Commit 1bc3b91a authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Linus Torvalds

[PATCH] crashdump: x86 crashkernel option

This is the x86 implementation of the crashkernel option.  It reserves a
window of memory very early in the bootup process, so we never use it for
anything but the kernel to switch to when the running kernel panics.

In addition to reserving this memory a resource structure is registered so
looking at /proc/iomem it is clear what happened to that memory.

ISSUES:
Is it possible to implement this in a architecture generic way?
What should be done with architectures that always use an iommu and
thus don't report their RAM memory resources in /proc/iomem?
Signed-off-by: default avatarEric Biederman <ebiederm@xmission.com>
Signed-off-by: default avatarVivek Goyal <vgoyal@in.ibm.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 63d30298
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/kexec.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -598,6 +599,9 @@ efi_initialize_iomem_resources(struct resource *code_resource, ...@@ -598,6 +599,9 @@ efi_initialize_iomem_resources(struct resource *code_resource,
if (md->type == EFI_CONVENTIONAL_MEMORY) { if (md->type == EFI_CONVENTIONAL_MEMORY) {
request_resource(res, code_resource); request_resource(res, code_resource);
request_resource(res, data_resource); request_resource(res, data_resource);
#ifdef CONFIG_KEXEC
request_resource(res, &crashk_res);
#endif
} }
} }
} }
......
...@@ -43,7 +43,10 @@ ...@@ -43,7 +43,10 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/edd.h> #include <linux/edd.h>
#include <linux/nodemask.h> #include <linux/nodemask.h>
#include <linux/kexec.h>
#include <video/edid.h> #include <video/edid.h>
#include <asm/apic.h> #include <asm/apic.h>
#include <asm/e820.h> #include <asm/e820.h>
#include <asm/mpspec.h> #include <asm/mpspec.h>
...@@ -846,6 +849,27 @@ static void __init parse_cmdline_early (char ** cmdline_p) ...@@ -846,6 +849,27 @@ static void __init parse_cmdline_early (char ** cmdline_p)
lapic_disable(); lapic_disable();
#endif /* CONFIG_X86_LOCAL_APIC */ #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. * highmem=size forces highmem to be exactly 'size' bytes.
* This works even on boxes that have no highmem otherwise. * This works even on boxes that have no highmem otherwise.
...@@ -1181,6 +1205,11 @@ void __init setup_bootmem_allocator(void) ...@@ -1181,6 +1205,11 @@ void __init setup_bootmem_allocator(void)
} }
} }
#endif #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 ...@@ -1234,6 +1263,9 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
*/ */
request_resource(res, code_resource); request_resource(res, code_resource);
request_resource(res, data_resource); request_resource(res, data_resource);
#ifdef CONFIG_KEXEC
request_resource(res, &crashk_res);
#endif
} }
} }
} }
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <linux/initrd.h> #include <linux/initrd.h>
#include <linux/nodemask.h> #include <linux/nodemask.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kexec.h>
#include <asm/e820.h> #include <asm/e820.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mmzone.h> #include <asm/mmzone.h>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment