From: Vivek Goyal <vgoyal@in.ibm.com> This patch adds support for reserving 640k memory as backup region as required by crashdump kernel for x86. Signed-off-by: Vivek Goyal <vgoyal@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> --- 25-akpm/Documentation/kernel-parameters.txt | 5 +++++ 25-akpm/arch/i386/kernel/setup.c | 26 ++++++++++++++++++++++++-- 25-akpm/arch/i386/mm/discontig.c | 8 ++++++++ 25-akpm/include/linux/crash_dump.h | 1 + 25-akpm/include/linux/kexec.h | 6 +++++- 25-akpm/kernel/crash_dump.c | 3 +++ 25-akpm/kernel/kexec.c | 8 ++++++++ 7 files changed, 54 insertions(+), 3 deletions(-) diff -puN arch/i386/kernel/setup.c~crashdump-reserving-backup-region-for-kexec-based arch/i386/kernel/setup.c --- 25/arch/i386/kernel/setup.c~crashdump-reserving-backup-region-for-kexec-based 2005-01-23 01:51:11.604628880 -0800 +++ 25-akpm/arch/i386/kernel/setup.c 2005-01-23 01:51:11.617626904 -0800 @@ -41,6 +41,7 @@ #include <linux/init.h> #include <linux/edd.h> #include <linux/kexec.h> +#include <linux/crash_dump.h> #include <video/edid.h> #include <asm/apic.h> #include <asm/e820.h> @@ -51,7 +52,6 @@ #include <asm/io_apic.h> #include <asm/ist.h> #include <asm/io.h> -#include <asm/crash_dump.h> #include "setup_arch_pre.h" #include <bios_ebda.h> @@ -854,7 +854,20 @@ static void __init parse_cmdline_early ( } } #endif - +#ifdef CONFIG_CRASH_DUMP + /* crashbackup=size@addr specifies the location of backup + * region where, crashed kernel has stored some backup data. + */ + else if (!memcmp(from, "crashbackup=", 12)) { + unsigned long size, base; + size = memparse(from+12, &from); + if (*from == '@') { + base = memparse(from+1, &from); + crashbackup_start = base; + crashbackup_end = base + size - 1; + } + } +#endif /* * highmem=size forces highmem to be exactly 'size' bytes. * This works even on boxes that have no highmem otherwise. @@ -1161,6 +1174,14 @@ static unsigned long __init setup_memory #ifdef CONFIG_KEXEC if (crashk_res.start != crashk_res.end) { reserve_bootmem(crashk_res.start, crashk_res.end - crashk_res.start + 1); + +#define CRASHDUMP_BACKUP_SZ 0xa0000 + /* Steal 640K from top of reserved region for crash kernel */ + if ((crashk_res.end - crashk_res.start) > CRASHDUMP_BACKUP_SZ) { + crashdumpk_res.end = crashk_res.end; + crashk_res.end = crashk_res.end - CRASHDUMP_BACKUP_SZ; + crashdumpk_res.start = crashk_res.end + 1; + } } #endif return max_low_pfn; @@ -1204,6 +1225,7 @@ legacy_init_iomem_resources(struct resou request_resource(res, data_resource); #ifdef CONFIG_KEXEC request_resource(res, &crashk_res); + request_resource(res, &crashdumpk_res); #endif } } diff -puN arch/i386/mm/discontig.c~crashdump-reserving-backup-region-for-kexec-based arch/i386/mm/discontig.c --- 25/arch/i386/mm/discontig.c~crashdump-reserving-backup-region-for-kexec-based 2005-01-23 01:51:11.605628728 -0800 +++ 25-akpm/arch/i386/mm/discontig.c 2005-01-23 01:51:11.618626752 -0800 @@ -29,6 +29,7 @@ #include <linux/highmem.h> #include <linux/initrd.h> #include <linux/nodemask.h> +#include <linux/ioport.h> #include <linux/kexec.h> #include <asm/e820.h> #include <asm/setup.h> @@ -371,6 +372,13 @@ unsigned long __init setup_memory(void) #ifdef CONFIG_KEXEC if (crashk_res.start != crashk_res.end) { reserve_bootmem(crashk_res.start, crashk_res.end - crashk_res.start + 1); +#define CRASHDUMP_BACKUP_SZ 0xa0000 + /* Steal 640K from top of reserved region for crash kernel */ + if ((crashk_res.end - crashk_res.start) > CRASHDUMP_BACKUP_SZ) { + crashdumpk_res.end = crashk_res.end; + crashk_res.end = crashk_res.end - CRASHDUMP_BACKUP_SZ; + crashdumpk_res.start = crashk_res.end + 1; + } } #endif return system_max_low_pfn; diff -puN Documentation/kernel-parameters.txt~crashdump-reserving-backup-region-for-kexec-based Documentation/kernel-parameters.txt --- 25/Documentation/kernel-parameters.txt~crashdump-reserving-backup-region-for-kexec-based 2005-01-23 01:51:11.607628424 -0800 +++ 25-akpm/Documentation/kernel-parameters.txt 2005-01-23 01:51:11.619626600 -0800 @@ -27,6 +27,7 @@ restrictions referred to are that the re APM Advanced Power Management support is enabled. AX25 Appropriate AX.25 support is enabled. CD Appropriate CD support is enabled. + CRASHDUMP Crash Dump support is enabled. DEVFS devfs support is enabled. DRM Direct Rendering Management support is enabled. EDD BIOS Enhanced Disk Drive Services (EDD) is enabled @@ -345,6 +346,10 @@ running once the system is up. [KNL] Reserve a chunk of physical memory to hold a kernel to switch to with kexec on panic. + crashbackup=nn[KMG]@ss[KMG] + [KNL, CRASHDUMP] Specifies the location of crash data + backup region. + cs4232= [HW,OSS] Format: <io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq> diff -puN include/linux/crash_dump.h~crashdump-reserving-backup-region-for-kexec-based include/linux/crash_dump.h --- 25/include/linux/crash_dump.h~crashdump-reserving-backup-region-for-kexec-based 2005-01-23 01:51:11.609628120 -0800 +++ 25-akpm/include/linux/crash_dump.h 2005-01-23 01:51:11.619626600 -0800 @@ -15,6 +15,7 @@ extern void elf_kcore_store_hdr(char *, #ifdef CONFIG_CRASH_DUMP extern struct file_operations proc_vmcore_operations; extern struct proc_dir_entry *proc_vmcore; +extern unsigned long crashbackup_start, crashbackup_end; extern ssize_t copy_oldmem_page(unsigned long, char *, size_t, int); extern void crash_create_proc_entry(void); diff -puN include/linux/kexec.h~crashdump-reserving-backup-region-for-kexec-based include/linux/kexec.h --- 25/include/linux/kexec.h~crashdump-reserving-backup-region-for-kexec-based 2005-01-23 01:51:11.610627968 -0800 +++ 25-akpm/include/linux/kexec.h 2005-01-23 01:51:11.620626448 -0800 @@ -79,7 +79,7 @@ struct kimage { unsigned long control_page; /* Flags to indicate special processing */ - int type : 1; + unsigned int type : 1; #define KEXEC_TYPE_DEFAULT 0 #define KEXEC_TYPE_CRASH 1 }; @@ -122,6 +122,10 @@ extern struct kimage *kexec_crash_image; */ extern struct resource crashk_res; +/* Location of backup region to hold the crashdump kernel data. + */ +extern struct resource crashdumpk_res; + #else /* !CONFIG_KEXEC */ static inline void crash_kexec(void) { } #endif /* CONFIG_KEXEC */ diff -puN kernel/crash_dump.c~crashdump-reserving-backup-region-for-kexec-based kernel/crash_dump.c --- 25/kernel/crash_dump.c~crashdump-reserving-backup-region-for-kexec-based 2005-01-23 01:51:11.612627664 -0800 +++ 25-akpm/kernel/crash_dump.c 2005-01-23 01:51:11.620626448 -0800 @@ -15,6 +15,9 @@ #include <asm/io.h> #include <asm/uaccess.h> +/* Location of crashdump backup region if there is one. */ +unsigned long crashbackup_start, crashbackup_end; + /* * Copy a page from "oldmem". For this page, there is no pte mapped * in the current kernel. We stitch up a pte, similar to kmap_atomic. diff -puN kernel/kexec.c~crashdump-reserving-backup-region-for-kexec-based kernel/kexec.c --- 25/kernel/kexec.c~crashdump-reserving-backup-region-for-kexec-based 2005-01-23 01:51:11.613627512 -0800 +++ 25-akpm/kernel/kexec.c 2005-01-23 01:51:11.621626296 -0800 @@ -32,6 +32,14 @@ struct resource crashk_res = { .flags = IORESOURCE_BUSY | IORESOURCE_MEM }; +/* Location of the backup area for the crash dump kernel */ +struct resource crashdumpk_res = { + .name = "Crash Dump Backup", + .start = 0, + .end = 0, + .flags = IORESOURCE_BUSY | IORESOURCE_MEM +}; + /* * When kexec transitions to the new kernel there is a one-to-one * mapping between physical and virtual addresses. On processors _