Jayaraman, Bhaskar wrote:
Hi i want to run crash on a dom0 or paravirtualized guest. Please let me know if there's a patch which I can include with the linux source to build the /dev/crash driver with the xen kernel. Also is there any specific way to build crash command line to be used on a xen kernel. Any pointers to documentation also will be very useful. Thanks in advance. Bhaskar.
A bit of background would help here, such as what architecture, what distribution, and what kernel version you're running with. Since you're asking, I'm presuming that you're running with something other than RHEL5. But just in case you are running RHEL5, dom0 hosts and paravirtualized x86 and x86_64 guests have the /dev/crash driver built in. So, for a live system, either dom0 or domU, and presuming that you've got the appropriate kernel debuginfo package installed, you can just enter: $ crash and it will look for the correct vmlinux file based upon what it sees in /proc/version. If it can't find it, you can just enter it: $ crash /path/to/vmlinux For dom0/hypervisor kdumps, or for domU xendumps, you have to enter both the vmlinux and vmcore arguments, as in: $ crash /path/to/vmlinux /path/to/vmcore Also, for dom0/hypervisor kdumps, you can alternatively look at the vmcore from the perspective of the xen hypervisor: $ crash /path/to/xen-syms /path/to/vmcore Now, for architectures other than x86 and x86_64 on RHEL5, the /dev/mem driver will most because it is not restricted to the first 256 pages (1MB). For 32-bit kernels, however, you will run into the /dev/mem restriction that only allows lowmem access. But your session should come up, although it may run into some command errors if highmem access is required for mapped virtual-to-physical address translation of user or kernel vmalloc virtual addresses. And then recently the upstream kernel has adopted the new CONFIG_STRICT_DEVMEM option, which cripples the use of /dev/mem by crash in the same way that RHEL kernels do. If you have no control of your kernel, and it has the CONFIG_STRICT_DEVMEM restriction, then you either have to roll your own kernel memory access driver (like the /dev/crash driver), or if you're really adventurous, you can write a kprobe module that modifies the return value of devmem_is_allowed(). In any case, it would be nice if the RHEL5 /dev/crash driver could be packaged such that anybody could simply build it externally for any kernel without any modifications to the kernel source tree -- in a similar manner to the way the kprobes developers show how to build their modules do in the RHEL5 "Documentation/kprobes.txt" file, or in the upstream "samples/kprobes" directory. But the /dev/crash driver does require small modifications to the kernel source, primarily to EXPORT_SYMBOL_GPL() the page_is_ram() function. I can't help much more than attaching the two patches to the RHEL5 tree that implement the /dev/crash driver, linux-2.6-crash-driver.patch and linux-2.6-crash-driver-xen.patch, and letting you run with them: $ lsdiff linux-2.6-crash-driver.patch linux-1050/arch/i386/mm/init.c linux-1050/arch/ia64/kernel/ia64_ksyms.c linux-1050/arch/x86_64/mm/init.c linux-1050/drivers/char/crash.c linux-1050/drivers/char/Kconfig linux-2.6.16.noarch/drivers/char/Makefile linux-1050/include/asm-i386/crash.h linux-1050/include/asm-ia64/crash.h linux-1050/include/asm-x86_64/crash.h $ lsdiff linux-2.6-crash-driver-xen.patch a/arch/i386/mm/init-xen.c a/arch/x86_64/mm/init-xen.c $ and depending upon how your distro is built, you'll need to turn on CONFIG_CRASH so the Makefile will build it. Note that the ia64 stuff in the patch is cruft, won't compile, and is unnecessary since the /dev/mem driver for that architecture still works just fine. That all being said, if you're only dealing with x86_64, then the simplest route would be to remove any /dev/mem restrictions, because then that driver will also work just fine. You can do the same for x86, but just be aware that you may run into some bumps in the road if you need to access any highmem physical addresses. But the basic crash session should come up OK. Dave
diff -urNp --exclude-from=/home/davej/.exclude linux-1050/arch/i386/mm/init.c linux-1060/arch/i386/mm/init.c --- linux-1050/arch/i386/mm/init.c +++ linux-1060/arch/i386/mm/init.c @@ -248,6 +248,8 @@ int devmem_is_allowed(unsigned long page return 0; } +EXPORT_SYMBOL_GPL(page_is_ram); + #ifdef CONFIG_HIGHMEM pte_t *kmap_pte; pgprot_t kmap_prot; diff -urNp --exclude-from=/home/davej/.exclude linux-1050/arch/ia64/kernel/ia64_ksyms.c linux-1060/arch/ia64/kernel/ia64_ksyms.c --- linux-1050/arch/ia64/kernel/ia64_ksyms.c +++ linux-1060/arch/ia64/kernel/ia64_ksyms.c @@ -106,6 +106,9 @@ EXPORT_SYMBOL(ia64_save_scratch_fpregs); #include <asm/unwind.h> EXPORT_SYMBOL(unw_init_running); +#include <linux/efi.h> +EXPORT_SYMBOL_GPL(efi_mem_type); + #ifdef ASM_SUPPORTED # ifdef CONFIG_SMP # if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) diff -urNp --exclude-from=/home/davej/.exclude linux-1050/arch/x86_64/mm/init.c linux-1060/arch/x86_64/mm/init.c --- linux-1050/arch/x86_64/mm/init.c +++ linux-1060/arch/x86_64/mm/init.c @@ -6,5 +6,6 @@ */ +#include <linux/module.h> #include <linux/signal.h> #include <linux/sched.h> #include <linux/kernel.h> @@ -417,6 +418,8 @@ int devmem_is_allowed(unsigned long page } +EXPORT_SYMBOL_GPL(page_is_ram); + static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules, kcore_vsyscall; diff -urNp --exclude-from=/home/davej/.exclude linux-1050/drivers/char/crash.c linux-1060/drivers/char/crash.c --- linux-1050/drivers/char/crash.c +++ linux-1060/drivers/char/crash.c @@ -0,0 +1,128 @@ +/* + * linux/drivers/char/crash.c + * + * Copyright (C) 2004 Dave Anderson <anderson@xxxxxxxxxx> + * Copyright (C) 2004 Red Hat, Inc. + */ + +/****************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + *****************************************************************************/ + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/miscdevice.h> +#include <linux/init.h> +#include <asm/io.h> +#include <asm/uaccess.h> +#include <asm/types.h> +#include <asm/crash.h> + +#define CRASH_VERSION "1.0" + +/* + * These are the file operation functions that allow crash utility + * access to physical memory. + */ + +static loff_t +crash_llseek(struct file * file, loff_t offset, int orig) +{ + switch (orig) { + case 0: + file->f_pos = offset; + return file->f_pos; + case 1: + file->f_pos += offset; + return file->f_pos; + default: + return -EINVAL; + } +} + +/* + * Determine the page address for an address offset value, + * get a virtual address for it, and copy it out. + * Accesses must fit within a page. + */ +static ssize_t +crash_read(struct file *file, char *buf, size_t count, loff_t *poff) +{ + void *vaddr; + struct page *page; + u64 offset; + ssize_t read; + + offset = *poff; + if (offset >> PAGE_SHIFT != (offset+count-1) >> PAGE_SHIFT) + return -EINVAL; + + vaddr = map_virtual(offset, &page); + if (!vaddr) + return -EFAULT; + + if (copy_to_user(buf, vaddr, count)) { + unmap_virtual(page); + return -EFAULT; + } + unmap_virtual(page); + + read = count; + *poff += read; + return read; +} + +static struct file_operations crash_fops = { + .owner = THIS_MODULE, + .llseek = crash_llseek, + .read = crash_read, +}; + +static struct miscdevice crash_dev = { + MISC_DYNAMIC_MINOR, + "crash", + &crash_fops +}; + +static int __init +crash_init(void) +{ + int ret; + + ret = misc_register(&crash_dev); + if (ret) { + printk(KERN_ERR + "crash memory driver: cannot misc_register (MISC_DYNAMIC_MINOR)\n"); + goto out; + } + + ret = 0; + printk(KERN_INFO "crash memory driver: version %s\n", CRASH_VERSION); +out: + return ret; +} + +static void __exit +crash_cleanup_module(void) +{ + misc_deregister(&crash_dev); +} + +module_init(crash_init); +module_exit(crash_cleanup_module); + +MODULE_LICENSE("GPL"); diff -urNp --exclude-from=/home/davej/.exclude linux-1050/drivers/char/Kconfig linux-1060/drivers/char/Kconfig --- linux-1050/drivers/char/Kconfig +++ linux-1060/drivers/char/Kconfig @@ -441,6 +441,8 @@ config LEGACY_PTYS security. This option enables these legacy devices; on most systems, it is safe to say N. +config CRASH + tristate "Crash Utility memory driver" config LEGACY_PTY_COUNT int "Maximum number of legacy PTY in use" --- linux-2.6.16.noarch/drivers/char/Makefile~ 2006-03-25 18:50:42.000000000 -0500 +++ linux-2.6.16.noarch/drivers/char/Makefile 2006-03-25 18:50:59.000000000 -0500 @@ -95,6 +95,7 @@ obj-$(CONFIG_IPMI_HANDLER) += ipmi/ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o obj-$(CONFIG_TCG_TPM) += tpm/ +obj-$(CONFIG_CRASH) += crash.o # Files generated that shall be removed upon make clean clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c diff -urNp --exclude-from=/home/davej/.exclude linux-1050/include/asm-i386/crash.h linux-1060/include/asm-i386/crash.h --- linux-1050/include/asm-i386/crash.h +++ linux-1060/include/asm-i386/crash.h @@ -0,0 +1,75 @@ +#ifndef _ASM_I386_CRASH_H +#define _ASM_I386_CRASH_H + +/* + * linux/include/asm-i386/crash.h + * + * Copyright (c) 2004 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifdef __KERNEL__ + +#include <linux/mm.h> +#include <linux/highmem.h> +#include <asm/mmzone.h> + +extern int page_is_ram(unsigned long); + +static inline void * +map_virtual(u64 offset, struct page **pp) +{ + struct page *page; + unsigned long pfn; + void *vaddr; + + pfn = (unsigned long)(offset >> PAGE_SHIFT); + + if (!page_is_ram(pfn)) { + printk(KERN_INFO + "crash memory driver: !page_is_ram(pfn: %lx)\n", pfn); + return NULL; + } + + if (!pfn_valid(pfn)) { + printk(KERN_INFO + "crash memory driver: invalid pfn: %lx )\n", pfn); + return NULL; + } + + page = pfn_to_page(pfn); + + vaddr = kmap(page); + if (!vaddr) { + printk(KERN_INFO + "crash memory driver: pfn: %lx kmap(page: %lx) failed\n", + pfn, (unsigned long)page); + return NULL; + } + + *pp = page; + return (vaddr + (offset & (PAGE_SIZE-1))); +} + +static inline void unmap_virtual(struct page *page) +{ + kunmap(page); +} + +#endif /* __KERNEL__ */ + +#endif /* _ASM_I386_CRASH_H */ diff -urNp --exclude-from=/home/davej/.exclude linux-1050/include/asm-ia64/crash.h linux-1060/include/asm-ia64/crash.h --- linux-1050/include/asm-ia64/crash.h +++ linux-1060/include/asm-ia64/crash.h @@ -0,0 +1,90 @@ +#ifndef _ASM_IA64_CRASH_H +#define _ASM_IA64_CRASH_H + +/* + * linux/include/asm-ia64/crash.h + * + * Copyright (c) 2004 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifdef __KERNEL__ + +#include <linux/efi.h> +#include <linux/mm.h> +#include <asm/mmzone.h> + +static inline void * +map_virtual(u64 offset, struct page **pp) +{ + struct page *page; + unsigned long pfn; + u32 type; + + if (REGION_NUMBER(offset) == 5) { + char byte; + + if (__get_user(byte, (char *)offset) == 0) + return (void *)offset; + else + return NULL; + } + + switch (type = efi_mem_type(offset)) + { + case EFI_LOADER_CODE: + case EFI_LOADER_DATA: + case EFI_BOOT_SERVICES_CODE: + case EFI_BOOT_SERVICES_DATA: + case EFI_CONVENTIONAL_MEMORY: + break; + + default: + printk(KERN_INFO + "crash memory driver: invalid memory type for %lx: %d\n", + offset, type); + return NULL; + } + + pfn = offset >> PAGE_SHIFT; + + if (!pfn_valid(pfn)) { + printk(KERN_INFO + "crash memory driver: invalid pfn: %lx )\n", pfn); + return NULL; + } + + page = pfn_to_page(pfn); + + if (!page->virtual) { + printk(KERN_INFO + "crash memory driver: offset: %lx page: %lx page->virtual: NULL\n", + offset, (unsigned long)page); + return NULL; + } + + return (page->virtual + (offset & (PAGE_SIZE-1))); +} + +static inline void unmap_virtual(struct page *page) +{ + return; +} + +#endif /* __KERNEL__ */ + +#endif /* _ASM_IA64_CRASH_H */ diff -urNp --exclude-from=/home/davej/.exclude linux-1050/include/asm-x86_64/crash.h linux-1060/include/asm-x86_64/crash.h --- linux-1050/include/asm-x86_64/crash.h +++ linux-1060/include/asm-x86_64/crash.h @@ -0,0 +1,75 @@ +#ifndef _ASM_X86_64_CRASH_H +#define _ASM_X86_64_CRASH_H + +/* + * linux/include/asm-x86_64/crash.h + * + * Copyright (c) 2004 Red Hat, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifdef __KERNEL__ + +#include <linux/mm.h> +#include <linux/highmem.h> +#include <asm/mmzone.h> + +extern int page_is_ram(unsigned long); + +static inline void * +map_virtual(u64 offset, struct page **pp) +{ + struct page *page; + unsigned long pfn; + void *vaddr; + + pfn = (unsigned long)(offset >> PAGE_SHIFT); + + if (!page_is_ram(pfn)) { + printk(KERN_INFO + "crash memory driver: !page_is_ram(pfn: %lx)\n", pfn); + return NULL; + } + + if (!pfn_valid(pfn)) { + printk(KERN_INFO + "crash memory driver: invalid pfn: %lx )\n", pfn); + return NULL; + } + + page = pfn_to_page(pfn); + + vaddr = kmap(page); + if (!vaddr) { + printk(KERN_INFO + "crash memory driver: pfn: %lx kmap(page: %lx) failed\n", + pfn, (unsigned long)page); + return NULL; + } + + *pp = page; + return (vaddr + (offset & (PAGE_SIZE-1))); +} + +static inline void unmap_virtual(struct page *page) +{ + kunmap(page); +} + +#endif /* __KERNEL__ */ + +#endif /* _ASM_X86_64_CRASH_H */
# HG changeset patch # User quintela@xxxxxxxxxxx # Node ID ed87076d010ee2f549658308cf2298fd888ba94a # Parent 7bad01eaf8f795b08be97187c9ed41891cca9bab crash xen bits diff -r 7bad01eaf8f7 -r ed87076d010e arch/i386/mm/init-xen.c --- a/arch/i386/mm/init-xen.c Thu Jul 27 02:44:10 2006 +0200 +++ b/arch/i386/mm/init-xen.c Thu Jul 27 02:50:45 2006 +0200 @@ -275,6 +275,7 @@ int page_is_ram(unsigned long pagenr) } return 0; } +EXPORT_SYMBOL_GPL(page_is_ram); /* * devmem_is_allowed() checks to see if /dev/mem access to a certain address is diff -r 7bad01eaf8f7 -r ed87076d010e arch/x86_64/mm/init-xen.c --- a/arch/x86_64/mm/init-xen.c Thu Jul 27 02:44:10 2006 +0200 +++ b/arch/x86_64/mm/init-xen.c Thu Jul 27 02:50:45 2006 +0200 @@ -964,6 +964,7 @@ static inline int page_is_ram (unsigned { return 1; } +EXPORT_SYMBOL_GPL(page_is_ram); /* * devmem_is_allowed() checks to see if /dev/mem access to a certain address is
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility