WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-ppc-devel

[XenPPC] [xenppc-unstable] [POWERPC] add show_backtrace()

To: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Subject: [XenPPC] [xenppc-unstable] [POWERPC] add show_backtrace()
From: Xen patchbot-xenppc-unstable <patchbot-xenppc-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 23 Aug 2006 10:30:32 +0000
Delivery-date: Wed, 23 Aug 2006 03:36:34 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-ppc-devel-request@lists.xensource.com?subject=help>
List-id: Xen PPC development <xen-ppc-devel.lists.xensource.com>
List-post: <mailto:xen-ppc-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-ppc-devel>, <mailto:xen-ppc-devel-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-ppc-devel-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Jimi Xenidis <jimix@xxxxxxxxxxxxxx>
# Node ID 877560e56eabbc7f05f650fba912fd0611b930f6
# Parent  e06e2cca9f39d56344ec96b90ad4a2405b247996
[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>
---
 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 e06e2cca9f39 -r 877560e56eab xen/arch/powerpc/Makefile
--- a/xen/arch/powerpc/Makefile Tue Aug 22 17:26:36 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 e06e2cca9f39 -r 877560e56eab xen/arch/powerpc/exceptions.c
--- a/xen/arch/powerpc/exceptions.c     Tue Aug 22 17:26:36 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 e06e2cca9f39 -r 877560e56eab xen/arch/powerpc/memory.c
--- a/xen/arch/powerpc/memory.c Tue Aug 22 17:26:36 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 e06e2cca9f39 -r 877560e56eab xen/arch/powerpc/setup.c
--- a/xen/arch/powerpc/setup.c  Tue Aug 22 17:26:36 2006 -0400
+++ b/xen/arch/powerpc/setup.c  Wed Aug 23 04:59:10 2006 -0400
@@ -296,6 +296,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 e06e2cca9f39 -r 877560e56eab xen/include/asm-powerpc/processor.h
--- a/xen/include/asm-powerpc/processor.h       Tue Aug 22 17:26:36 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 e06e2cca9f39 -r 877560e56eab 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-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [XenPPC] [xenppc-unstable] [POWERPC] add show_backtrace(), Xen patchbot-xenppc-unstable <=