aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2005-06-25 17:58:01 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-25 19:24:50 -0400
commit1bc3b91aeed71a904e431d12ca90e9b6bcb42c91 (patch)
tree58e139e6a348dfe06fb62bf9cd5b40cd6a6f8bad
parent63d30298efc387c72557d11e2a7b467554c05a64 (diff)
[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>
-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 @@
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/efi.h> 32#include <linux/efi.h>
33#include <linux/kexec.h>
33 34
34#include <asm/setup.h> 35#include <asm/setup.h>
35#include <asm/io.h> 36#include <asm/io.h>
@@ -598,6 +599,9 @@ efi_initialize_iomem_resources(struct resource *code_resource,
598 if (md->type == EFI_CONVENTIONAL_MEMORY) { 599 if (md->type == EFI_CONVENTIONAL_MEMORY) {
599 request_resource(res, code_resource); 600 request_resource(res, code_resource);
600 request_resource(res, data_resource); 601 request_resource(res, data_resource);
602#ifdef CONFIG_KEXEC
603 request_resource(res, &crashk_res);
604#endif
601 } 605 }
602 } 606 }
603} 607}
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 @@
43#include <linux/init.h> 43#include <linux/init.h>
44#include <linux/edd.h> 44#include <linux/edd.h>
45#include <linux/nodemask.h> 45#include <linux/nodemask.h>
46#include <linux/kexec.h>
47
46#include <video/edid.h> 48#include <video/edid.h>
49
47#include <asm/apic.h> 50#include <asm/apic.h>
48#include <asm/e820.h> 51#include <asm/e820.h>
49#include <asm/mpspec.h> 52#include <asm/mpspec.h>
@@ -846,6 +849,27 @@ static void __init parse_cmdline_early (char ** cmdline_p)
846 lapic_disable(); 849 lapic_disable();
847#endif /* CONFIG_X86_LOCAL_APIC */ 850#endif /* CONFIG_X86_LOCAL_APIC */
848 851
852#ifdef CONFIG_KEXEC
853 /* crashkernel=size@addr specifies the location to reserve for
854 * a crash kernel. By reserving this memory we guarantee
855 * that linux never set's it up as a DMA target.
856 * Useful for holding code to do something appropriate
857 * after a kernel panic.
858 */
859 else if (!memcmp(from, "crashkernel=", 12)) {
860 unsigned long size, base;
861 size = memparse(from+12, &from);
862 if (*from == '@') {
863 base = memparse(from+1, &from);
864 /* FIXME: Do I want a sanity check
865 * to validate the memory range?
866 */
867 crashk_res.start = base;
868 crashk_res.end = base + size - 1;
869 }
870 }
871#endif
872
849 /* 873 /*
850 * highmem=size forces highmem to be exactly 'size' bytes. 874 * highmem=size forces highmem to be exactly 'size' bytes.
851 * This works even on boxes that have no highmem otherwise. 875 * This works even on boxes that have no highmem otherwise.
@@ -1181,6 +1205,11 @@ void __init setup_bootmem_allocator(void)
1181 } 1205 }
1182 } 1206 }
1183#endif 1207#endif
1208#ifdef CONFIG_KEXEC
1209 if (crashk_res.start != crashk_res.end)
1210 reserve_bootmem(crashk_res.start,
1211 crashk_res.end - crashk_res.start + 1);
1212#endif
1184} 1213}
1185 1214
1186/* 1215/*
@@ -1234,6 +1263,9 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
1234 */ 1263 */
1235 request_resource(res, code_resource); 1264 request_resource(res, code_resource);
1236 request_resource(res, data_resource); 1265 request_resource(res, data_resource);
1266#ifdef CONFIG_KEXEC
1267 request_resource(res, &crashk_res);
1268#endif
1237 } 1269 }
1238 } 1270 }
1239} 1271}
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 @@
30#include <linux/initrd.h> 30#include <linux/initrd.h>
31#include <linux/nodemask.h> 31#include <linux/nodemask.h>
32#include <linux/module.h> 32#include <linux/module.h>
33#include <linux/kexec.h>
34
33#include <asm/e820.h> 35#include <asm/e820.h>
34#include <asm/setup.h> 36#include <asm/setup.h>
35#include <asm/mmzone.h> 37#include <asm/mmzone.h>