[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] xen/x86: Better BUG back traces.



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1171972626 0
# Node ID 4990b2236f066983271587241c7b267297164bf3
# Parent  266d203d7f39d69b14a5c020974cd843802592e8
xen/x86: Better BUG back traces.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
 xen/arch/x86/mm/shadow/common.c  |   87 +++++++++++++++++++--------------------
 xen/arch/x86/mm/shadow/multi.c   |    7 +--
 xen/arch/x86/traps.c             |   25 +++++++----
 xen/include/asm-ia64/bug.h       |    6 ++
 xen/include/asm-powerpc/bug.h    |    6 ++
 xen/include/asm-x86/bug.h        |   13 +++++
 xen/include/asm-x86/processor.h  |    5 --
 xen/include/asm-x86/x86_32/bug.h |   19 ++++++++
 xen/include/asm-x86/x86_64/bug.h |   19 ++++++++
 xen/include/xen/lib.h            |    5 +-
 10 files changed, 130 insertions(+), 62 deletions(-)

diff -r 266d203d7f39 -r 4990b2236f06 xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c   Tue Feb 20 11:51:40 2007 +0000
+++ b/xen/arch/x86/mm/shadow/common.c   Tue Feb 20 11:57:06 2007 +0000
@@ -929,49 +929,7 @@ mfn_t shadow_alloc(struct domain *d,
     /* Find smallest order which can satisfy the request. */
     for ( i = order; i <= SHADOW_MAX_ORDER; i++ )
         if ( !list_empty(&d->arch.paging.shadow.freelists[i]) )
-        {
-            sp = list_entry(d->arch.paging.shadow.freelists[i].next, 
-                            struct shadow_page_info, list);
-            list_del(&sp->list);
-            
-            /* We may have to halve the chunk a number of times. */
-            while ( i != order )
-            {
-                i--;
-                sp->order = i;
-                list_add_tail(&sp->list, &d->arch.paging.shadow.freelists[i]);
-                sp += 1 << i;
-            }
-            d->arch.paging.shadow.free_pages -= 1 << order;
-
-            /* Init page info fields and clear the pages */
-            for ( i = 0; i < 1<<order ; i++ ) 
-            {
-                /* Before we overwrite the old contents of this page, 
-                 * we need to be sure that no TLB holds a pointer to it. */
-                mask = d->domain_dirty_cpumask;
-                tlbflush_filter(mask, sp[i].tlbflush_timestamp);
-                if ( unlikely(!cpus_empty(mask)) )
-                {
-                    perfc_incrc(shadow_alloc_tlbflush);
-                    flush_tlb_mask(mask);
-                }
-                /* Now safe to clear the page for reuse */
-                p = sh_map_domain_page(shadow_page_to_mfn(sp+i));
-                ASSERT(p != NULL);
-                clear_page(p);
-                sh_unmap_domain_page(p);
-                INIT_LIST_HEAD(&sp[i].list);
-                sp[i].type = shadow_type;
-                sp[i].pinned = 0;
-                sp[i].logdirty = 0;
-                sp[i].count = 0;
-                sp[i].backpointer = backpointer;
-                sp[i].next_shadow = NULL;
-                perfc_incr(shadow_alloc_count);
-            }
-            return shadow_page_to_mfn(sp);
-        }
+            goto found;
     
     /* If we get here, we failed to allocate. This should never happen.
      * It means that we didn't call shadow_prealloc() correctly before
@@ -979,6 +937,49 @@ mfn_t shadow_alloc(struct domain *d,
      * we might free up higher-level pages that the caller is working on. */
     SHADOW_PRINTK("Can't allocate %i shadow pages!\n", 1 << order);
     BUG();
+
+ found:
+    sp = list_entry(d->arch.paging.shadow.freelists[i].next, 
+                    struct shadow_page_info, list);
+    list_del(&sp->list);
+            
+    /* We may have to halve the chunk a number of times. */
+    while ( i != order )
+    {
+        i--;
+        sp->order = i;
+        list_add_tail(&sp->list, &d->arch.paging.shadow.freelists[i]);
+        sp += 1 << i;
+    }
+    d->arch.paging.shadow.free_pages -= 1 << order;
+
+    /* Init page info fields and clear the pages */
+    for ( i = 0; i < 1<<order ; i++ ) 
+    {
+        /* Before we overwrite the old contents of this page, 
+         * we need to be sure that no TLB holds a pointer to it. */
+        mask = d->domain_dirty_cpumask;
+        tlbflush_filter(mask, sp[i].tlbflush_timestamp);
+        if ( unlikely(!cpus_empty(mask)) )
+        {
+            perfc_incrc(shadow_alloc_tlbflush);
+            flush_tlb_mask(mask);
+        }
+        /* Now safe to clear the page for reuse */
+        p = sh_map_domain_page(shadow_page_to_mfn(sp+i));
+        ASSERT(p != NULL);
+        clear_page(p);
+        sh_unmap_domain_page(p);
+        INIT_LIST_HEAD(&sp[i].list);
+        sp[i].type = shadow_type;
+        sp[i].pinned = 0;
+        sp[i].logdirty = 0;
+        sp[i].count = 0;
+        sp[i].backpointer = backpointer;
+        sp[i].next_shadow = NULL;
+        perfc_incr(shadow_alloc_count);
+    }
+    return shadow_page_to_mfn(sp);
 }
 
 
diff -r 266d203d7f39 -r 4990b2236f06 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c    Tue Feb 20 11:51:40 2007 +0000
+++ b/xen/arch/x86/mm/shadow/multi.c    Tue Feb 20 11:57:06 2007 +0000
@@ -3196,11 +3196,10 @@ sh_update_linear_entries(struct vcpu *v)
         int unmap_l2e = 0;
 
 #if GUEST_PAGING_LEVELS == 2
+
         /* Shadow l3 tables were built by sh_update_cr3 */
-        if ( shadow_mode_external(d) )
-            shadow_l3e = (shadow_l3e_t *)&v->arch.paging.shadow.l3table;
-        else
-            BUG(); /* PV 2-on-3 is not supported yet */
+        BUG_ON(!shadow_mode_external(d)); /* PV 2-on-3 is unsupported */
+        shadow_l3e = (shadow_l3e_t *)&v->arch.paging.shadow.l3table;
         
 #else /* GUEST_PAGING_LEVELS == 3 */
         
diff -r 266d203d7f39 -r 4990b2236f06 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c      Tue Feb 20 11:51:40 2007 +0000
+++ b/xen/arch/x86/traps.c      Tue Feb 20 11:57:06 2007 +0000
@@ -624,14 +624,23 @@ asmlinkage int do_invalid_op(struct cpu_
 
     if ( unlikely(!guest_mode(regs)) )
     {
-        char sig[5];
-        /* Signature (ud2; .ascii "dbg") indicates dump state and continue. */
-        if ( (__copy_from_user(sig, (char *)regs->eip, sizeof(sig)) == 0) &&
-             (memcmp(sig, "\xf\xb""dbg", sizeof(sig)) == 0) )
-        {
-            show_execution_state(regs);
-            regs->eip += sizeof(sig);
-            return EXCRET_fault_fixed;
+        struct bug_frame bug;
+        if ( (__copy_from_user(&bug, (char *)regs->eip, sizeof(bug)) == 0) &&
+             (memcmp(bug.ud2, "\xf\xb",    sizeof(bug.ud2)) == 0) &&
+             (memcmp(bug.mov, BUG_MOV_STR, sizeof(bug.mov)) == 0) &&
+             (bug.ret == 0xc2) )
+        {
+            char *filename = (char *)bug.filename;
+            unsigned int line = bug.line & 0x7fff;
+            int is_bug = !(bug.line & 0x8000);
+            printk("Xen %s at %.50s:%d\n",
+                   is_bug ? "BUG" : "State Dump", filename, line);
+            if ( !is_bug )
+            {
+                show_execution_state(regs);
+                regs->eip += sizeof(bug);
+                return EXCRET_fault_fixed;
+            }
         }
         DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
         show_execution_state(regs);
diff -r 266d203d7f39 -r 4990b2236f06 xen/include/asm-ia64/bug.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-ia64/bug.h        Tue Feb 20 11:57:06 2007 +0000
@@ -0,0 +1,6 @@
+#ifndef __IA64_BUG_H__
+#define __IA64_BUG_H__
+
+#define BUG() __bug(__FILE__, __LINE__)
+
+#endif /* __IA64_BUG_H__ */
diff -r 266d203d7f39 -r 4990b2236f06 xen/include/asm-powerpc/bug.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-powerpc/bug.h     Tue Feb 20 11:57:06 2007 +0000
@@ -0,0 +1,6 @@
+#ifndef __POWERPC_BUG_H__
+#define __POWERPC_BUG_H__
+
+#define BUG() __bug(__FILE__, __LINE__)
+
+#endif /* __POWERPC_BUG_H__ */
diff -r 266d203d7f39 -r 4990b2236f06 xen/include/asm-x86/bug.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/bug.h Tue Feb 20 11:57:06 2007 +0000
@@ -0,0 +1,13 @@
+#ifndef __X86_BUG_H__
+#define __X86_BUG_H__
+
+#ifdef __x86_64__
+#include <asm/x86_64/bug.h>
+#else
+#include <asm/x86_32/bug.h>
+#endif
+
+#define BUG()                  __BUG(__FILE__, __LINE__)
+#define dump_execution_state() __BUG(__FILE__, __LINE__ | 0x8000)
+
+#endif /* __X86_BUG_H__ */
diff -r 266d203d7f39 -r 4990b2236f06 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h   Tue Feb 20 11:51:40 2007 +0000
+++ b/xen/include/asm-x86/processor.h   Tue Feb 20 11:57:06 2007 +0000
@@ -565,11 +565,6 @@ void compat_show_guest_stack(struct cpu_
 #define compat_show_guest_stack(regs, lines) ((void)0)
 #endif
 
-/* Dumps current register and stack state. */
-#define dump_execution_state()                                              \
-    /* NB. Needs interrupts enabled else we end up in fatal_trap(). */      \
-    __asm__ __volatile__ ( "pushf ; sti ; ud2 ; .ascii \"dbg\" ; popf" )
-
 extern void mtrr_ap_init(void);
 extern void mtrr_bp_init(void);
 
diff -r 266d203d7f39 -r 4990b2236f06 xen/include/asm-x86/x86_32/bug.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/x86_32/bug.h  Tue Feb 20 11:57:06 2007 +0000
@@ -0,0 +1,19 @@
+#ifndef __X86_32_BUG_H__
+#define __X86_32_BUG_H__
+
+struct bug_frame {
+    unsigned char ud2[2];
+    unsigned char mov[1];
+    unsigned long filename;
+    unsigned char ret;
+    unsigned short line;
+} __attribute__((packed));
+
+#define BUG_MOV_STR "\xbc"
+
+#define __BUG(file, line)                               \
+    asm volatile (                                      \
+        "ud2 ; .byte 0xbc ; .long %c1 ; ret $%c0"       \
+        : : "i" (line), "i" (file) )
+
+#endif /* __X86_32_BUG_H__ */
diff -r 266d203d7f39 -r 4990b2236f06 xen/include/asm-x86/x86_64/bug.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/xen/include/asm-x86/x86_64/bug.h  Tue Feb 20 11:57:06 2007 +0000
@@ -0,0 +1,19 @@
+#ifndef __X86_64_BUG_H__
+#define __X86_64_BUG_H__
+
+struct bug_frame {
+    unsigned char ud2[2];
+    unsigned char mov[2];
+    unsigned long filename;
+    unsigned char ret;
+    unsigned short line;
+} __attribute__((packed));
+
+#define BUG_MOV_STR "\x48\xbc"
+
+#define __BUG(file, line)                               \
+    asm volatile (                                      \
+        "ud2 ; .byte 0x48,0xbc ; .quad %c1 ; ret $%c0"  \
+        : : "i" (line), "i" (file) )
+
+#endif /* __X86_64_BUG_H__ */
diff -r 266d203d7f39 -r 4990b2236f06 xen/include/xen/lib.h
--- a/xen/include/xen/lib.h     Tue Feb 20 11:51:40 2007 +0000
+++ b/xen/include/xen/lib.h     Tue Feb 20 11:57:06 2007 +0000
@@ -7,9 +7,10 @@
 #include <xen/types.h>
 #include <xen/xmalloc.h>
 #include <xen/string.h>
+#include <asm/bug.h>
 
-extern void __bug(char *file, int line) __attribute__((noreturn));
-#define BUG() __bug(__FILE__, __LINE__)
+void __bug(char *file, int line) __attribute__((noreturn));
+
 #define BUG_ON(_p) do { if (_p) BUG(); } while ( 0 )
 
 /* Force a compilation error if condition is true */

_______________________________________________
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®.