diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 61160cb504..fb454043eb 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -345,16 +345,26 @@ char *trapstr(int trapnr) */ asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs) { - watchdog_disable(); - console_start_sync(); + static DEFINE_PER_CPU(char, depth); - show_execution_state(regs); - - if ( trapnr == TRAP_page_fault ) + /* + * In some cases, we can end up in a vicious cycle of fatal_trap()s + * within fatal_trap()s. We give the problem a couple of iterations to + * bottom out, and then we just panic. + */ + if ( ++this_cpu(depth) < 3 ) { - unsigned long cr2 = read_cr2(); - printk("Faulting linear address: %p\n", _p(cr2)); - show_page_walk(cr2); + watchdog_disable(); + console_start_sync(); + + show_execution_state(regs); + + if ( trapnr == TRAP_page_fault ) + { + unsigned long cr2 = read_cr2(); + printk("Faulting linear address: %p\n", _p(cr2)); + show_page_walk(cr2); + } } panic("FATAL TRAP: vector = %d (%s)\n"