Merge branch 'linus' into x86/mce3
[pandora-kernel.git] / arch / x86 / kernel / smp.c
index 28f5fb4..ec1de97 100644 (file)
@@ -150,14 +150,40 @@ void native_send_call_func_ipi(const struct cpumask *mask)
  * this function calls the 'stop' function on all other CPUs in the system.
  */
 
+asmlinkage void smp_reboot_interrupt(void)
+{
+       ack_APIC_irq();
+       irq_enter();
+       stop_this_cpu(NULL);
+       irq_exit();
+}
+
 static void native_smp_send_stop(void)
 {
        unsigned long flags;
+       unsigned long wait;
 
        if (reboot_force)
                return;
 
-       smp_call_function(stop_this_cpu, NULL, 0);
+       /*
+        * Use an own vector here because smp_call_function
+        * does lots of things not suitable in a panic situation.
+        * On most systems we could also use an NMI here,
+        * but there are a few systems around where NMI
+        * is problematic so stay with an non NMI for now
+        * (this implies we cannot stop CPUs spinning with irq off
+        * currently)
+        */
+       if (num_online_cpus() > 1) {
+               apic->send_IPI_allbutself(REBOOT_VECTOR);
+
+               /* Don't wait longer than a second */
+               wait = USEC_PER_SEC;
+               while (num_online_cpus() > 1 && wait--)
+                       udelay(1);
+       }
+
        local_irq_save(flags);
        disable_local_APIC();
        local_irq_restore(flags);