# 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
|