From: Vivek Goyal - Moving the crash_dump.c file to arch dependent part as kmap_atomic_pfn is specific to i386 and highmem may not exist in other archs. - Use ioremap for x86_64 to map the previous kernel memory. - In copy_oldmem_page(), we now directly copy to the user/kernel buffer and avoid the unneccesary copy to a kmalloc'd page. Signed-off-by: Rachita Kothiyal Signed-off-by: Vivek Goyal Cc: Andi Kleen Signed-off-by: Andrew Morton --- dev/null | 61 ---------------------------------------- arch/i386/kernel/Makefile | 1 arch/i386/kernel/crash_dump.c | 47 ++++++++++++++++++++++++++++++ arch/x86_64/kernel/Makefile | 1 arch/x86_64/kernel/crash_dump.c | 47 ++++++++++++++++++++++++++++++ fs/proc/vmcore.c | 3 + kernel/Makefile | 1 7 files changed, 99 insertions(+), 62 deletions(-) diff -puN /dev/null arch/i386/kernel/crash_dump.c --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/arch/i386/kernel/crash_dump.c Thu Nov 17 14:21:17 2005 @@ -0,0 +1,47 @@ +/* + * kernel/crash_dump.c - Memory preserving reboot related code. + * + * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) + * Copyright (C) IBM Corporation, 2004. All rights reserved + */ + +#include +#include +#include + +#include + +/** + * copy_oldmem_page - copy one page from "oldmem" + * @pfn: page frame number to be copied + * @buf: target memory address for the copy; this can be in kernel address + * space or user address space (see @userbuf) + * @csize: number of bytes to copy + * @offset: offset in bytes into the page (based on pfn) to begin the copy + * @userbuf: if set, @buf is in user address space, use copy_to_user(), + * otherwise @buf is in kernel address space, use memcpy(). + * + * 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. + */ +ssize_t copy_oldmem_page(unsigned long pfn, char *buf, + size_t csize, unsigned long offset, int userbuf) +{ + void *vaddr; + + if (!csize) + return 0; + + vaddr = kmap_atomic_pfn(pfn, KM_PTE0); + + if (userbuf) { + if (copy_to_user(buf, (vaddr + offset), csize)) { + kunmap_atomic(vaddr, KM_PTE0); + return -EFAULT; + } + } else + memcpy(buf, (vaddr + offset), csize); + + kunmap_atomic(vaddr, KM_PTE0); + return csize; +} diff -puN arch/i386/kernel/Makefile~kdump-read-previous-kernels-memory arch/i386/kernel/Makefile --- 25/arch/i386/kernel/Makefile~kdump-read-previous-kernels-memory Thu Nov 17 14:21:17 2005 +++ 25-akpm/arch/i386/kernel/Makefile Thu Nov 17 14:21:17 2005 @@ -25,6 +25,7 @@ obj-$(CONFIG_X86_LOCAL_APIC) += apic.o n obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o +obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_X86_NUMAQ) += numaq.o obj-$(CONFIG_X86_SUMMIT_NUMA) += summit.o obj-$(CONFIG_KPROBES) += kprobes.o diff -puN /dev/null arch/x86_64/kernel/crash_dump.c --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/arch/x86_64/kernel/crash_dump.c Thu Nov 17 14:21:17 2005 @@ -0,0 +1,47 @@ +/* + * kernel/crash_dump.c - Memory preserving reboot related code. + * + * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) + * Copyright (C) IBM Corporation, 2004. All rights reserved + */ + +#include +#include + +#include +#include + +/** + * copy_oldmem_page - copy one page from "oldmem" + * @pfn: page frame number to be copied + * @buf: target memory address for the copy; this can be in kernel address + * space or user address space (see @userbuf) + * @csize: number of bytes to copy + * @offset: offset in bytes into the page (based on pfn) to begin the copy + * @userbuf: if set, @buf is in user address space, use copy_to_user(), + * otherwise @buf is in kernel address space, use memcpy(). + * + * 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. + */ +ssize_t copy_oldmem_page(unsigned long pfn, char *buf, + size_t csize, unsigned long offset, int userbuf) +{ + void *vaddr; + + if (!csize) + return 0; + + vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE); + + if (userbuf) { + if (copy_to_user(buf, (vaddr + offset), csize)) { + iounmap(vaddr); + return -EFAULT; + } + } else + memcpy(buf, (vaddr + offset), csize); + + iounmap(vaddr); + return csize; +} diff -puN arch/x86_64/kernel/Makefile~kdump-read-previous-kernels-memory arch/x86_64/kernel/Makefile --- 25/arch/x86_64/kernel/Makefile~kdump-read-previous-kernels-memory Thu Nov 17 14:21:17 2005 +++ 25-akpm/arch/x86_64/kernel/Makefile Thu Nov 17 14:21:17 2005 @@ -22,6 +22,7 @@ obj-$(CONFIG_X86_LOCAL_APIC) += apic.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o \ genapic.o genapic_cluster.o genapic_flat.o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o crash.o +obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_PM) += suspend.o obj-$(CONFIG_SOFTWARE_SUSPEND) += suspend_asm.o obj-$(CONFIG_CPU_FREQ) += cpufreq/ diff -puN fs/proc/vmcore.c~kdump-read-previous-kernels-memory fs/proc/vmcore.c --- 25/fs/proc/vmcore.c~kdump-read-previous-kernels-memory Thu Nov 17 14:21:17 2005 +++ 25-akpm/fs/proc/vmcore.c Thu Nov 17 14:21:17 2005 @@ -35,6 +35,9 @@ static size_t elfcorebuf_sz; /* Total size of vmcore file. */ static u64 vmcore_size; +/* Stores the physical address of elf header of crash image. */ +unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; + struct proc_dir_entry *proc_vmcore = NULL; /* Reads a page from the oldmem device from given offset. */ diff -L kernel/crash_dump.c -puN kernel/crash_dump.c~kdump-read-previous-kernels-memory /dev/null --- 25/kernel/crash_dump.c +++ /dev/null Thu Apr 11 07:25:15 2002 @@ -1,61 +0,0 @@ -/* - * kernel/crash_dump.c - Memory preserving reboot related code. - * - * Created by: Hariprasad Nellitheertha (hari@in.ibm.com) - * Copyright (C) IBM Corporation, 2004. All rights reserved - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -/* Stores the physical address of elf header of crash image. */ -unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX; - -/** - * copy_oldmem_page - copy one page from "oldmem" - * @pfn: page frame number to be copied - * @buf: target memory address for the copy; this can be in kernel address - * space or user address space (see @userbuf) - * @csize: number of bytes to copy - * @offset: offset in bytes into the page (based on pfn) to begin the copy - * @userbuf: if set, @buf is in user address space, use copy_to_user(), - * otherwise @buf is in kernel address space, use memcpy(). - * - * 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. - */ -ssize_t copy_oldmem_page(unsigned long pfn, char *buf, - size_t csize, unsigned long offset, int userbuf) -{ - void *page, *vaddr; - - if (!csize) - return 0; - - page = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!page) - return -ENOMEM; - - vaddr = kmap_atomic_pfn(pfn, KM_PTE0); - copy_page(page, vaddr); - kunmap_atomic(vaddr, KM_PTE0); - - if (userbuf) { - if (copy_to_user(buf, (page + offset), csize)) { - kfree(page); - return -EFAULT; - } - } else { - memcpy(buf, (page + offset), csize); - } - - kfree(page); - return csize; -} diff -puN kernel/Makefile~kdump-read-previous-kernels-memory kernel/Makefile --- 25/kernel/Makefile~kdump-read-previous-kernels-memory Thu Nov 17 14:21:17 2005 +++ 25-akpm/kernel/Makefile Thu Nov 17 14:21:17 2005 @@ -29,7 +29,6 @@ obj-$(CONFIG_KPROBES) += kprobes.o obj-$(CONFIG_SYSFS) += ksysfs.o obj-$(CONFIG_DETECT_SOFTLOCKUP) += softlockup.o obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ -obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_SECCOMP) += seccomp.o obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o _