ia64/xen-unstable

changeset 14021:4990b2236f06

xen/x86: Better BUG back traces.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Feb 20 11:57:06 2007 +0000 (2007-02-20)
parents 266d203d7f39
children 0a348e9ecedb
files xen/arch/x86/mm/shadow/common.c xen/arch/x86/mm/shadow/multi.c xen/arch/x86/traps.c xen/include/asm-ia64/bug.h xen/include/asm-powerpc/bug.h xen/include/asm-x86/bug.h xen/include/asm-x86/processor.h xen/include/asm-x86/x86_32/bug.h xen/include/asm-x86/x86_64/bug.h xen/include/xen/lib.h
line diff
     1.1 --- a/xen/arch/x86/mm/shadow/common.c	Tue Feb 20 11:51:40 2007 +0000
     1.2 +++ b/xen/arch/x86/mm/shadow/common.c	Tue Feb 20 11:57:06 2007 +0000
     1.3 @@ -929,49 +929,7 @@ mfn_t shadow_alloc(struct domain *d,
     1.4      /* Find smallest order which can satisfy the request. */
     1.5      for ( i = order; i <= SHADOW_MAX_ORDER; i++ )
     1.6          if ( !list_empty(&d->arch.paging.shadow.freelists[i]) )
     1.7 -        {
     1.8 -            sp = list_entry(d->arch.paging.shadow.freelists[i].next, 
     1.9 -                            struct shadow_page_info, list);
    1.10 -            list_del(&sp->list);
    1.11 -            
    1.12 -            /* We may have to halve the chunk a number of times. */
    1.13 -            while ( i != order )
    1.14 -            {
    1.15 -                i--;
    1.16 -                sp->order = i;
    1.17 -                list_add_tail(&sp->list, &d->arch.paging.shadow.freelists[i]);
    1.18 -                sp += 1 << i;
    1.19 -            }
    1.20 -            d->arch.paging.shadow.free_pages -= 1 << order;
    1.21 -
    1.22 -            /* Init page info fields and clear the pages */
    1.23 -            for ( i = 0; i < 1<<order ; i++ ) 
    1.24 -            {
    1.25 -                /* Before we overwrite the old contents of this page, 
    1.26 -                 * we need to be sure that no TLB holds a pointer to it. */
    1.27 -                mask = d->domain_dirty_cpumask;
    1.28 -                tlbflush_filter(mask, sp[i].tlbflush_timestamp);
    1.29 -                if ( unlikely(!cpus_empty(mask)) )
    1.30 -                {
    1.31 -                    perfc_incrc(shadow_alloc_tlbflush);
    1.32 -                    flush_tlb_mask(mask);
    1.33 -                }
    1.34 -                /* Now safe to clear the page for reuse */
    1.35 -                p = sh_map_domain_page(shadow_page_to_mfn(sp+i));
    1.36 -                ASSERT(p != NULL);
    1.37 -                clear_page(p);
    1.38 -                sh_unmap_domain_page(p);
    1.39 -                INIT_LIST_HEAD(&sp[i].list);
    1.40 -                sp[i].type = shadow_type;
    1.41 -                sp[i].pinned = 0;
    1.42 -                sp[i].logdirty = 0;
    1.43 -                sp[i].count = 0;
    1.44 -                sp[i].backpointer = backpointer;
    1.45 -                sp[i].next_shadow = NULL;
    1.46 -                perfc_incr(shadow_alloc_count);
    1.47 -            }
    1.48 -            return shadow_page_to_mfn(sp);
    1.49 -        }
    1.50 +            goto found;
    1.51      
    1.52      /* If we get here, we failed to allocate. This should never happen.
    1.53       * It means that we didn't call shadow_prealloc() correctly before
    1.54 @@ -979,6 +937,49 @@ mfn_t shadow_alloc(struct domain *d,
    1.55       * we might free up higher-level pages that the caller is working on. */
    1.56      SHADOW_PRINTK("Can't allocate %i shadow pages!\n", 1 << order);
    1.57      BUG();
    1.58 +
    1.59 + found:
    1.60 +    sp = list_entry(d->arch.paging.shadow.freelists[i].next, 
    1.61 +                    struct shadow_page_info, list);
    1.62 +    list_del(&sp->list);
    1.63 +            
    1.64 +    /* We may have to halve the chunk a number of times. */
    1.65 +    while ( i != order )
    1.66 +    {
    1.67 +        i--;
    1.68 +        sp->order = i;
    1.69 +        list_add_tail(&sp->list, &d->arch.paging.shadow.freelists[i]);
    1.70 +        sp += 1 << i;
    1.71 +    }
    1.72 +    d->arch.paging.shadow.free_pages -= 1 << order;
    1.73 +
    1.74 +    /* Init page info fields and clear the pages */
    1.75 +    for ( i = 0; i < 1<<order ; i++ ) 
    1.76 +    {
    1.77 +        /* Before we overwrite the old contents of this page, 
    1.78 +         * we need to be sure that no TLB holds a pointer to it. */
    1.79 +        mask = d->domain_dirty_cpumask;
    1.80 +        tlbflush_filter(mask, sp[i].tlbflush_timestamp);
    1.81 +        if ( unlikely(!cpus_empty(mask)) )
    1.82 +        {
    1.83 +            perfc_incrc(shadow_alloc_tlbflush);
    1.84 +            flush_tlb_mask(mask);
    1.85 +        }
    1.86 +        /* Now safe to clear the page for reuse */
    1.87 +        p = sh_map_domain_page(shadow_page_to_mfn(sp+i));
    1.88 +        ASSERT(p != NULL);
    1.89 +        clear_page(p);
    1.90 +        sh_unmap_domain_page(p);
    1.91 +        INIT_LIST_HEAD(&sp[i].list);
    1.92 +        sp[i].type = shadow_type;
    1.93 +        sp[i].pinned = 0;
    1.94 +        sp[i].logdirty = 0;
    1.95 +        sp[i].count = 0;
    1.96 +        sp[i].backpointer = backpointer;
    1.97 +        sp[i].next_shadow = NULL;
    1.98 +        perfc_incr(shadow_alloc_count);
    1.99 +    }
   1.100 +    return shadow_page_to_mfn(sp);
   1.101  }
   1.102  
   1.103  
     2.1 --- a/xen/arch/x86/mm/shadow/multi.c	Tue Feb 20 11:51:40 2007 +0000
     2.2 +++ b/xen/arch/x86/mm/shadow/multi.c	Tue Feb 20 11:57:06 2007 +0000
     2.3 @@ -3196,11 +3196,10 @@ sh_update_linear_entries(struct vcpu *v)
     2.4          int unmap_l2e = 0;
     2.5  
     2.6  #if GUEST_PAGING_LEVELS == 2
     2.7 +
     2.8          /* Shadow l3 tables were built by sh_update_cr3 */
     2.9 -        if ( shadow_mode_external(d) )
    2.10 -            shadow_l3e = (shadow_l3e_t *)&v->arch.paging.shadow.l3table;
    2.11 -        else
    2.12 -            BUG(); /* PV 2-on-3 is not supported yet */
    2.13 +        BUG_ON(!shadow_mode_external(d)); /* PV 2-on-3 is unsupported */
    2.14 +        shadow_l3e = (shadow_l3e_t *)&v->arch.paging.shadow.l3table;
    2.15          
    2.16  #else /* GUEST_PAGING_LEVELS == 3 */
    2.17          
     3.1 --- a/xen/arch/x86/traps.c	Tue Feb 20 11:51:40 2007 +0000
     3.2 +++ b/xen/arch/x86/traps.c	Tue Feb 20 11:57:06 2007 +0000
     3.3 @@ -624,14 +624,23 @@ asmlinkage int do_invalid_op(struct cpu_
     3.4  
     3.5      if ( unlikely(!guest_mode(regs)) )
     3.6      {
     3.7 -        char sig[5];
     3.8 -        /* Signature (ud2; .ascii "dbg") indicates dump state and continue. */
     3.9 -        if ( (__copy_from_user(sig, (char *)regs->eip, sizeof(sig)) == 0) &&
    3.10 -             (memcmp(sig, "\xf\xb""dbg", sizeof(sig)) == 0) )
    3.11 +        struct bug_frame bug;
    3.12 +        if ( (__copy_from_user(&bug, (char *)regs->eip, sizeof(bug)) == 0) &&
    3.13 +             (memcmp(bug.ud2, "\xf\xb",    sizeof(bug.ud2)) == 0) &&
    3.14 +             (memcmp(bug.mov, BUG_MOV_STR, sizeof(bug.mov)) == 0) &&
    3.15 +             (bug.ret == 0xc2) )
    3.16          {
    3.17 -            show_execution_state(regs);
    3.18 -            regs->eip += sizeof(sig);
    3.19 -            return EXCRET_fault_fixed;
    3.20 +            char *filename = (char *)bug.filename;
    3.21 +            unsigned int line = bug.line & 0x7fff;
    3.22 +            int is_bug = !(bug.line & 0x8000);
    3.23 +            printk("Xen %s at %.50s:%d\n",
    3.24 +                   is_bug ? "BUG" : "State Dump", filename, line);
    3.25 +            if ( !is_bug )
    3.26 +            {
    3.27 +                show_execution_state(regs);
    3.28 +                regs->eip += sizeof(bug);
    3.29 +                return EXCRET_fault_fixed;
    3.30 +            }
    3.31          }
    3.32          DEBUGGER_trap_fatal(TRAP_invalid_op, regs);
    3.33          show_execution_state(regs);
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/include/asm-ia64/bug.h	Tue Feb 20 11:57:06 2007 +0000
     4.3 @@ -0,0 +1,6 @@
     4.4 +#ifndef __IA64_BUG_H__
     4.5 +#define __IA64_BUG_H__
     4.6 +
     4.7 +#define BUG() __bug(__FILE__, __LINE__)
     4.8 +
     4.9 +#endif /* __IA64_BUG_H__ */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xen/include/asm-powerpc/bug.h	Tue Feb 20 11:57:06 2007 +0000
     5.3 @@ -0,0 +1,6 @@
     5.4 +#ifndef __POWERPC_BUG_H__
     5.5 +#define __POWERPC_BUG_H__
     5.6 +
     5.7 +#define BUG() __bug(__FILE__, __LINE__)
     5.8 +
     5.9 +#endif /* __POWERPC_BUG_H__ */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xen/include/asm-x86/bug.h	Tue Feb 20 11:57:06 2007 +0000
     6.3 @@ -0,0 +1,13 @@
     6.4 +#ifndef __X86_BUG_H__
     6.5 +#define __X86_BUG_H__
     6.6 +
     6.7 +#ifdef __x86_64__
     6.8 +#include <asm/x86_64/bug.h>
     6.9 +#else
    6.10 +#include <asm/x86_32/bug.h>
    6.11 +#endif
    6.12 +
    6.13 +#define BUG()                  __BUG(__FILE__, __LINE__)
    6.14 +#define dump_execution_state() __BUG(__FILE__, __LINE__ | 0x8000)
    6.15 +
    6.16 +#endif /* __X86_BUG_H__ */
     7.1 --- a/xen/include/asm-x86/processor.h	Tue Feb 20 11:51:40 2007 +0000
     7.2 +++ b/xen/include/asm-x86/processor.h	Tue Feb 20 11:57:06 2007 +0000
     7.3 @@ -565,11 +565,6 @@ void compat_show_guest_stack(struct cpu_
     7.4  #define compat_show_guest_stack(regs, lines) ((void)0)
     7.5  #endif
     7.6  
     7.7 -/* Dumps current register and stack state. */
     7.8 -#define dump_execution_state()                                              \
     7.9 -    /* NB. Needs interrupts enabled else we end up in fatal_trap(). */      \
    7.10 -    __asm__ __volatile__ ( "pushf ; sti ; ud2 ; .ascii \"dbg\" ; popf" )
    7.11 -
    7.12  extern void mtrr_ap_init(void);
    7.13  extern void mtrr_bp_init(void);
    7.14  
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xen/include/asm-x86/x86_32/bug.h	Tue Feb 20 11:57:06 2007 +0000
     8.3 @@ -0,0 +1,19 @@
     8.4 +#ifndef __X86_32_BUG_H__
     8.5 +#define __X86_32_BUG_H__
     8.6 +
     8.7 +struct bug_frame {
     8.8 +    unsigned char ud2[2];
     8.9 +    unsigned char mov[1];
    8.10 +    unsigned long filename;
    8.11 +    unsigned char ret;
    8.12 +    unsigned short line;
    8.13 +} __attribute__((packed));
    8.14 +
    8.15 +#define BUG_MOV_STR "\xbc"
    8.16 +
    8.17 +#define __BUG(file, line)                               \
    8.18 +    asm volatile (                                      \
    8.19 +        "ud2 ; .byte 0xbc ; .long %c1 ; ret $%c0"       \
    8.20 +        : : "i" (line), "i" (file) )
    8.21 +
    8.22 +#endif /* __X86_32_BUG_H__ */
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/xen/include/asm-x86/x86_64/bug.h	Tue Feb 20 11:57:06 2007 +0000
     9.3 @@ -0,0 +1,19 @@
     9.4 +#ifndef __X86_64_BUG_H__
     9.5 +#define __X86_64_BUG_H__
     9.6 +
     9.7 +struct bug_frame {
     9.8 +    unsigned char ud2[2];
     9.9 +    unsigned char mov[2];
    9.10 +    unsigned long filename;
    9.11 +    unsigned char ret;
    9.12 +    unsigned short line;
    9.13 +} __attribute__((packed));
    9.14 +
    9.15 +#define BUG_MOV_STR "\x48\xbc"
    9.16 +
    9.17 +#define __BUG(file, line)                               \
    9.18 +    asm volatile (                                      \
    9.19 +        "ud2 ; .byte 0x48,0xbc ; .quad %c1 ; ret $%c0"  \
    9.20 +        : : "i" (line), "i" (file) )
    9.21 +
    9.22 +#endif /* __X86_64_BUG_H__ */
    10.1 --- a/xen/include/xen/lib.h	Tue Feb 20 11:51:40 2007 +0000
    10.2 +++ b/xen/include/xen/lib.h	Tue Feb 20 11:57:06 2007 +0000
    10.3 @@ -7,9 +7,10 @@
    10.4  #include <xen/types.h>
    10.5  #include <xen/xmalloc.h>
    10.6  #include <xen/string.h>
    10.7 +#include <asm/bug.h>
    10.8  
    10.9 -extern void __bug(char *file, int line) __attribute__((noreturn));
   10.10 -#define BUG() __bug(__FILE__, __LINE__)
   10.11 +void __bug(char *file, int line) __attribute__((noreturn));
   10.12 +
   10.13  #define BUG_ON(_p) do { if (_p) BUG(); } while ( 0 )
   10.14  
   10.15  /* Force a compilation error if condition is true */