[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |