[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, &regs, 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(&regs)));
+                       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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.