merge linus into release branch
[powerpc.git] / arch / powerpc / kernel / traps.c
index 52f5659..fa6bd97 100644 (file)
 #include <asm/firmware.h>
 #include <asm/processor.h>
 #endif
+#include <asm/kexec.h>
 
 #ifdef CONFIG_PPC64    /* XXX */
 #define _IO_BASE       pci_io_base
+#ifdef CONFIG_KEXEC
+cpumask_t cpus_in_sr = CPU_MASK_NONE;
+#endif
 #endif
 
 #ifdef CONFIG_DEBUGGER
@@ -97,7 +101,7 @@ static DEFINE_SPINLOCK(die_lock);
 
 int die(const char *str, struct pt_regs *regs, long err)
 {
-       static int die_counter, crash_dump_start = 0;
+       static int die_counter;
 
        if (debugger(regs))
                return 1;
@@ -137,21 +141,12 @@ int die(const char *str, struct pt_regs *regs, long err)
        print_modules();
        show_regs(regs);
        bust_spinlocks(0);
+       spin_unlock_irq(&die_lock);
 
-       if (!crash_dump_start && kexec_should_crash(current)) {
-               crash_dump_start = 1;
-               spin_unlock_irq(&die_lock);
+       if (kexec_should_crash(current) ||
+               kexec_sr_activated(smp_processor_id()))
                crash_kexec(regs);
-               /* NOTREACHED */
-       }
-       spin_unlock_irq(&die_lock);
-       if (crash_dump_start)
-               /*
-                * Only for soft-reset: Other CPUs will be responded to an IPI
-                * sent by first kexec CPU.
-                */
-               for(;;)
-                       ;
+       crash_kexec_secondary(regs);
 
        if (in_interrupt())
                panic("Fatal exception in interrupt");
@@ -215,6 +210,10 @@ void system_reset_exception(struct pt_regs *regs)
                        return;
        }
 
+#ifdef CONFIG_KEXEC
+       cpu_set(smp_processor_id(), cpus_in_sr);
+#endif
+
        die("System Reset", regs, SIGABRT);
 
        /* Must die if the interrupt is not recoverable */