summaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2005-06-25 14:58:01 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-25 16:24:50 -0700
commit1bc3b91aeed71a904e431d12ca90e9b6bcb42c91 (patch)
tree58e139e6a348dfe06fb62bf9cd5b40cd6a6f8bad /arch/i386
parent63d30298efc387c72557d11e2a7b467554c05a64 (diff)
downloadlinux-stable-1bc3b91aeed71a904e431d12ca90e9b6bcb42c91.tar.gz
linux-stable-1bc3b91aeed71a904e431d12ca90e9b6bcb42c91.tar.bz2
linux-stable-1bc3b91aeed71a904e431d12ca90e9b6bcb42c91.zip
[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: Eric Biederman <ebiederm@xmission.com> Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/efi.c4
-rw-r--r--arch/i386/kernel/setup.c32
-rw-r--r--arch/i386/mm/discontig.c2
3 files changed, 38 insertions, 0 deletions
diff --git a/arch/i386/kernel/efi.c b/arch/i386/kernel/efi.c
index f732f427b418..385883ea8c19 100644
--- a/arch/i386/kernel/efi.c
+++ b/arch/i386/kernel/efi.c
@@ -30,6 +30,7 @@
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/efi.h>
+#include <linux/kexec.h>
#include <asm/setup.h>
#include <asm/io.h>
@@ -598,6 +599,9 @@ efi_initialize_iomem_resources(struct resource *code_resource,
if (md->type == EFI_CONVENTIONAL_MEMORY) {
request_resource(res, code_resource);
request_resource(res, data_resource);
+#ifdef CONFIG_KEXEC
+ request_resource(res, &crashk_res);
+#endif
}
}
}
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 6337157f5df3..d88ebdfa6ccd 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -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
}
}
}
diff --git a/arch/i386/mm/discontig.c b/arch/i386/mm/discontig.c
index f429c871e845..b358f0702a44 100644
--- a/arch/i386/mm/discontig.c
+++ b/arch/i386/mm/discontig.c
@@ -30,6 +30,8 @@
#include <linux/initrd.h>
#include <linux/nodemask.h>
#include <linux/module.h>
+#include <linux/kexec.h>
+
#include <asm/e820.h>
#include <asm/setup.h>
#include <asm/mmzone.h>