Pull novell-bugzilla-156426 into release branch
[pandora-kernel.git] / arch / x86_64 / kernel / nmi.c
index 8be407a..4e6357f 100644 (file)
@@ -34,6 +34,7 @@
 #include <asm/proto.h>
 #include <asm/kdebug.h>
 #include <asm/local.h>
+#include <asm/mce.h>
 
 /*
  * lapic_nmi_owner tracks the ownership of the lapic NMI hardware:
@@ -162,9 +163,7 @@ int __init check_nmi_watchdog (void)
        local_irq_enable();
        mdelay((10*1000)/nmi_hz); // wait 10 ticks
 
-       for (cpu = 0; cpu < NR_CPUS; cpu++) {
-               if (!cpu_online(cpu))
-                       continue;
+       for_each_online_cpu(cpu) {
                if (cpu_pda(cpu)->__nmi_count - counts[cpu] <= 5) {
                        endflag = 1;
                        printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
@@ -236,6 +235,7 @@ static void enable_lapic_nmi_watchdog(void)
 {
        if (nmi_active < 0) {
                nmi_watchdog = NMI_LOCAL_APIC;
+               touch_nmi_watchdog();
                setup_apic_nmi_watchdog();
        }
 }
@@ -456,15 +456,17 @@ static DEFINE_PER_CPU(int, nmi_touch);
 
 void touch_nmi_watchdog (void)
 {
-       int i;
+       if (nmi_watchdog > 0) {
+               unsigned cpu;
 
-       /*
-        * Tell other CPUs to reset their alert counters. We cannot
-        * do it ourselves because the alert count increase is not
-        * atomic.
-        */
-       for (i = 0; i < NR_CPUS; i++)
-               per_cpu(nmi_touch, i) = 1;
+               /*
+                * Tell other CPUs to reset their alert counters. We cannot
+                * do it ourselves because the alert count increase is not
+                * atomic.
+                */
+               for_each_present_cpu (cpu)
+                       per_cpu(nmi_touch, cpu) = 1;
+       }
 
        touch_softlockup_watchdog();
 }
@@ -479,6 +481,12 @@ void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
                __get_cpu_var(nmi_touch) = 0;
                touched = 1;
        }
+#ifdef CONFIG_X86_MCE
+       /* Could check oops_in_progress here too, but it's safer
+          not too */
+       if (atomic_read(&mce_entry) > 0)
+               touched = 1;
+#endif
        if (!touched && __get_cpu_var(last_irq_sum) == sum) {
                /*
                 * Ayiee, looks like this CPU is stuck ...
@@ -533,6 +541,7 @@ asmlinkage __kprobes void do_nmi(struct pt_regs * regs, long error_code)
 
 void set_nmi_callback(nmi_callback_t callback)
 {
+       vmalloc_sync_all();
        rcu_assign_pointer(nmi_callback, callback);
 }