diff -r 45981aefbe48 xen/arch/x86/nmi.c --- a/xen/arch/x86/nmi.c Fri Jul 17 12:25:06 2009 +0100 +++ b/xen/arch/x86/nmi.c Fri Jul 17 12:51:43 2009 +0100 @@ -383,10 +383,38 @@ } } +static atomic_t all_panic = ATOMIC_INIT(0); +static DEFINE_SPINLOCK(panic_lock); + +static void do_nmi_trigger_cpu(int cpu) +{ + u32 id = cpu_physical_id(cpu); + + printk("Triggering NMI on APIC ID %x\n", id); + debugtrace_dump(); + + local_irq_disable(); + apic_wait_icr_idle(); + apic_icr_write(APIC_DM_NMI | APIC_DEST_PHYSICAL, id); + local_irq_enable(); +} + void nmi_watchdog_tick(struct cpu_user_regs * regs) { unsigned int sum = this_cpu(nmi_timer_ticks); + if ( atomic_read(&all_panic) ) + { + spin_lock(&panic_lock); + console_force_unlock(); + printk("Sibling watchdog timer fired! Printing state for CPU%d\n", + smp_processor_id()); + show_execution_state(regs); + debugtrace_dump(); + spin_unlock(&panic_lock); + while(1); + } + if ( (this_cpu(last_irq_sums) == sum) && !atomic_read(&watchdog_disable_count) ) { @@ -400,7 +428,22 @@ console_force_unlock(); printk("Watchdog timer detects that CPU%d is stuck!\n", smp_processor_id()); - fatal_trap(TRAP_nmi, regs); + show_execution_state(regs); + debugtrace_dump(); + atomic_inc(&all_panic); + { + int cpu; + spin_lock(&panic_lock); + for_each_cpu(cpu) + { + if ( cpu == smp_processor_id()) + continue; + do_nmi_trigger_cpu(cpu); + } + spin_unlock(&panic_lock); + } + while(1); + //fatal_trap(TRAP_nmi, regs); } } else