[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN][POWERPC] add show_backtrace()
# HG changeset patch # User Jimi Xenidis <jimix@xxxxxxxxxxxxxx> # Node ID 20c988c92bee7afb2438952c520721213ce278b1 # Parent 980ff112544672926aab7baa81381b4f6000eba0 [XEN][POWERPC] add show_backtrace() Total rip off of xmon_show_stack() from Linux:arch/powerpc/xmon/xmon.c. This will allow a numeric only stack traceback of Xen exectution. Currently only triggered by BUG() et.al. Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx> --- xen/arch/powerpc/Makefile | 1 xen/arch/powerpc/backtrace.c | 194 ++++++++++++++++++++++++++++++++++++ xen/arch/powerpc/exceptions.c | 2 xen/arch/powerpc/memory.c | 3 xen/arch/powerpc/setup.c | 3 xen/include/asm-powerpc/processor.h | 1 6 files changed, 201 insertions(+), 3 deletions(-) diff -r 980ff1125446 -r 20c988c92bee xen/arch/powerpc/Makefile --- a/xen/arch/powerpc/Makefile Tue Aug 22 17:20:58 2006 -0400 +++ b/xen/arch/powerpc/Makefile Wed Aug 23 04:59:10 2006 -0400 @@ -6,6 +6,7 @@ subdir-y += papr subdir-y += papr obj-y += audit.o +obj-y += backtrace.o obj-y += bitops.o obj-y += boot_of.o obj-y += dart.o diff -r 980ff1125446 -r 20c988c92bee xen/arch/powerpc/exceptions.c --- a/xen/arch/powerpc/exceptions.c Tue Aug 22 17:20:58 2006 -0400 +++ b/xen/arch/powerpc/exceptions.c Wed Aug 23 04:59:10 2006 -0400 @@ -82,6 +82,8 @@ void program_exception(struct cpu_user_r show_registers(regs); printk("dar 0x%016lx, dsisr 0x%08x\n", mfdar(), mfdsisr()); printk("hid4 0x%016lx\n", regs->hid4); + printk("---[ backtrace ]---\n"); + show_backtrace(regs->gprs[1], regs->lr, regs->pc); panic("%s: 0x%lx\n", __func__, cookie); #endif /* CRASH_DEBUG */ } diff -r 980ff1125446 -r 20c988c92bee xen/arch/powerpc/memory.c --- a/xen/arch/powerpc/memory.c Tue Aug 22 17:20:58 2006 -0400 +++ b/xen/arch/powerpc/memory.c Wed Aug 23 04:59:10 2006 -0400 @@ -176,9 +176,6 @@ void memory_init(module_t *mod, int mcou "for heap (0x%lx)\n", _start, heap_start); } - /* we give the first RMA to the hypervisor */ - xenheap_phys_end = rma_size(cpu_rma_order()); - /* allow everything else to be allocated */ total_pages = 0; ofd_walk_mem((void *)oftree, heap_init); diff -r 980ff1125446 -r 20c988c92bee xen/arch/powerpc/setup.c --- a/xen/arch/powerpc/setup.c Tue Aug 22 17:20:58 2006 -0400 +++ b/xen/arch/powerpc/setup.c Wed Aug 23 04:59:10 2006 -0400 @@ -295,6 +295,9 @@ static void __init __start_xen(multiboot console_start_sync(); #endif + /* we give the first RMA to the hypervisor */ + xenheap_phys_end = rma_size(cpu_rma_order()); + /* Check that we have at least one Multiboot module. */ if (!(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0)) { panic("FATAL ERROR: Require at least one Multiboot module.\n"); diff -r 980ff1125446 -r 20c988c92bee xen/include/asm-powerpc/processor.h --- a/xen/include/asm-powerpc/processor.h Tue Aug 22 17:20:58 2006 -0400 +++ b/xen/include/asm-powerpc/processor.h Wed Aug 23 04:59:10 2006 -0400 @@ -39,6 +39,7 @@ struct cpu_user_regs; struct cpu_user_regs; extern void show_registers(struct cpu_user_regs *); extern void show_execution_state(struct cpu_user_regs *); +extern void show_backtrace(ulong sp, ulong lr, ulong pc); extern unsigned int cpu_rma_order(void); extern void cpu_initialize(int cpuid); extern void cpu_init_vcpu(struct vcpu *); diff -r 980ff1125446 -r 20c988c92bee xen/arch/powerpc/backtrace.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/powerpc/backtrace.c Wed Aug 23 04:59:10 2006 -0400 @@ -0,0 +1,194 @@ +/* + * Routines providing a simple monitor for use on the PowerMac. + * + * Copyright (C) 1996-2005 Paul Mackerras. + * + * 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 of the License, or (at your option) any later version. + */ + +#include <xen/config.h> +#include <xen/lib.h> +#include <xen/console.h> +#include <xen/sched.h> + +/* Shamelessly lifted from Linux Xmon try to keep pristene */ +#ifdef __powerpc64__ +#define LRSAVE_OFFSET 0x10 +#define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */ +#define MARKER_OFFSET 0x60 +#define REGS_OFFSET 0x70 +#define REG "%016lX" +#else +#define LRSAVE_OFFSET 4 +#define REG_FRAME_MARKER 0x72656773 +#define MARKER_OFFSET 8 +#define REGS_OFFSET 16 +#define REG "%08lX" +#endif + +#define TRAP(regs) ((regs)->entry_vector & ~0xF) +static int xmon_depth_to_print = 64; + +/* Very cheap human name for vector lookup. */ +static +const char *getvecname(unsigned long vec) +{ + char *ret; + + switch (vec) { + case 0x100: ret = "(System Reset)"; break; + case 0x200: ret = "(Machine Check)"; break; + case 0x300: ret = "(Data Access)"; break; + case 0x380: ret = "(Data SLB Access)"; break; + case 0x400: ret = "(Instruction Access)"; break; + case 0x480: ret = "(Instruction SLB Access)"; break; + case 0x500: ret = "(Hardware Interrupt)"; break; + case 0x600: ret = "(Alignment)"; break; + case 0x700: ret = "(Program Check)"; break; + case 0x800: ret = "(FPU Unavailable)"; break; + case 0x900: ret = "(Decrementer)"; break; + case 0xc00: ret = "(System Call)"; break; + case 0xd00: ret = "(Single Step)"; break; + case 0xf00: ret = "(Performance Monitor)"; break; + case 0xf20: ret = "(Altivec Unavailable)"; break; + case 0x1300: ret = "(Instruction Breakpoint)"; break; + default: ret = ""; + } + return ret; +} + +static int mread(unsigned long adrs, void *buf, int size) +{ + memcpy(buf, (void *)adrs, size); + return size; +} + +static void get_function_bounds(unsigned long pc, unsigned long *startp, + unsigned long *endp) +{ + *startp = pc; + *endp = pc; +} + +/* Print an address in numeric and symbolic form (if possible) */ +static void xmon_print_symbol(unsigned long address, const char *mid, + const char *after) +{ + char *modname; + const char *name = NULL; + unsigned long offset, size; + + printf(REG, address); +#if 0 + if (setjmp(bus_error_jmp) == 0) { + catch_memory_errors = 1; + sync(); + name = kallsyms_lookup(address, &size, &offset, &modname, + tmpstr); + sync(); + /* wait a little while to see if we get a machine check */ + __delay(200); + } + + catch_memory_errors = 0; +#endif + if (name) { + printf("%s%s+%#lx/%#lx", mid, name, offset, size); + if (modname) + printf(" [%s]", modname); + } + printf("%s", after); +} + +static void backtrace( + unsigned long sp, unsigned long lr, unsigned long pc) +{ + unsigned long ip; + unsigned long newsp; + unsigned long marker; + int count = 0; + struct cpu_user_regs regs; + + do { + if (sp > xenheap_phys_end) { + if (sp != 0) + printf("SP (%lx) is not in xen space\n", sp); + break; + } + + if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long)) + || !mread(sp, &newsp, sizeof(unsigned long))) { + printf("Couldn't read stack frame at %lx\n", sp); + break; + } + + /* + * For the first stack frame, try to work out if + * LR and/or the saved LR value in the bottommost + * stack frame are valid. + */ + if ((pc | lr) != 0) { + unsigned long fnstart, fnend; + unsigned long nextip; + int printip = 1; + + get_function_bounds(pc, &fnstart, &fnend); + nextip = 0; + if (newsp > sp) + mread(newsp + LRSAVE_OFFSET, &nextip, + sizeof(unsigned long)); + if (lr == ip) { + if (lr >= xenheap_phys_end + || (fnstart <= lr && lr < fnend)) + printip = 0; + } else if (lr == nextip) { + printip = 0; + } else if (lr < xenheap_phys_end + && !(fnstart <= lr && lr < fnend)) { + printf("[link register ] "); + xmon_print_symbol(lr, " ", "\n"); + } + if (printip) { + printf("["REG"] ", sp); + xmon_print_symbol(ip, " ", " (unreliable)\n"); + } + pc = lr = 0; + + } else { + printf("["REG"] ", sp); + xmon_print_symbol(ip, " ", "\n"); + } + + /* Look for "regshere" marker to see if this is + an exception frame. */ + if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long)) + && marker == REG_FRAME_MARKER) { + if (mread(sp + REGS_OFFSET, ®s, sizeof(regs)) + != sizeof(regs)) { + printf("Couldn't read registers at %lx\n", + sp + REGS_OFFSET); + break; + } + printf("--- Exception: %x %s at ", regs.entry_vector, + getvecname(TRAP(®s))); + pc = regs.pc; + lr = regs.lr; + xmon_print_symbol(pc, " ", "\n"); + } + + if (newsp == 0) + break; + + sp = newsp; + } while (count++ < xmon_depth_to_print); +} + +void show_backtrace(ulong sp, ulong lr, ulong pc) +{ + console_start_sync(); + backtrace(sp, lr, pc); + console_end_sync(); +} _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |