linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / x86_64 / kernel / nmi.c
index 5baa0c7..5bf17e4 100644 (file)
  *  Mikael Pettersson  : PM converted to driver model. Disable/enable API.
  */
 
+#include <linux/config.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/smp_lock.h>
 #include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/kernel_stat.h>
 #include <linux/module.h>
 #include <linux/sysdev.h>
 #include <linux/nmi.h>
 #include <linux/kprobes.h>
 
 #include <asm/smp.h>
+#include <asm/mtrr.h>
+#include <asm/mpspec.h>
 #include <asm/nmi.h>
+#include <asm/msr.h>
 #include <asm/proto.h>
 #include <asm/kdebug.h>
-#include <asm/mce.h>
-#include <asm/intel_arch_perfmon.h>
+#include <asm/local.h>
 
 /*
  * lapic_nmi_owner tracks the ownership of the lapic NMI hardware:
@@ -66,9 +73,6 @@ static unsigned int nmi_p4_cccr_val;
 #define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING   0x76
 #define K7_NMI_EVENT           K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING
 
-#define ARCH_PERFMON_NMI_EVENT_SEL     ARCH_PERFMON_UNHALTED_CORE_CYCLES_SEL
-#define ARCH_PERFMON_NMI_EVENT_UMASK   ARCH_PERFMON_UNHALTED_CORE_CYCLES_UMASK
-
 #define MSR_P4_MISC_ENABLE     0x1A0
 #define MSR_P4_MISC_ENABLE_PERF_AVAIL  (1<<7)
 #define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL        (1<<12)
@@ -100,10 +104,7 @@ static __cpuinit inline int nmi_known_cpu(void)
        case X86_VENDOR_AMD:
                return boot_cpu_data.x86 == 15;
        case X86_VENDOR_INTEL:
-               if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON))
-                       return 1;
-               else
-                       return (boot_cpu_data.x86 == 15);
+               return boot_cpu_data.x86 == 15;
        }
        return 0;
 }
@@ -127,7 +128,7 @@ void __cpuinit nmi_watchdog_default(void)
 static __init void nmi_cpu_busy(void *data)
 {
        volatile int *endflag = data;
-       local_irq_enable_in_hardirq();
+       local_irq_enable();
        /* Intentionally don't use cpu_relax here. This is
           to make sure that the performance counter really ticks,
           even if there is a simulator or similar that catches the
@@ -161,7 +162,9 @@ int __init check_nmi_watchdog (void)
        local_irq_enable();
        mdelay((10*1000)/nmi_hz); // wait 10 ticks
 
-       for_each_online_cpu(cpu) {
+       for (cpu = 0; cpu < NR_CPUS; cpu++) {
+               if (!cpu_online(cpu))
+                       continue;
                if (cpu_pda(cpu)->__nmi_count - counts[cpu] <= 5) {
                        endflag = 1;
                        printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n",
@@ -209,8 +212,6 @@ int __init setup_nmi_watchdog(char *str)
 
 __setup("nmi_watchdog=", setup_nmi_watchdog);
 
-static void disable_intel_arch_watchdog(void);
-
 static void disable_lapic_nmi_watchdog(void)
 {
        if (nmi_active <= 0)
@@ -223,8 +224,6 @@ static void disable_lapic_nmi_watchdog(void)
                if (boot_cpu_data.x86 == 15) {
                        wrmsr(MSR_P4_IQ_CCCR0, 0, 0);
                        wrmsr(MSR_P4_CRU_ESCR0, 0, 0);
-               } else if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
-                       disable_intel_arch_watchdog();
                }
                break;
        }
@@ -377,53 +376,6 @@ static void setup_k7_watchdog(void)
        wrmsr(MSR_K7_EVNTSEL0, evntsel, 0);
 }
 
-static void disable_intel_arch_watchdog(void)
-{
-       unsigned ebx;
-
-       /*
-        * Check whether the Architectural PerfMon supports
-        * Unhalted Core Cycles Event or not.
-        * NOTE: Corresponding bit = 0 in ebp indicates event present.
-        */
-       ebx = cpuid_ebx(10);
-       if (!(ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT))
-               wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, 0, 0);
-}
-
-static int setup_intel_arch_watchdog(void)
-{
-       unsigned int evntsel;
-       unsigned ebx;
-
-       /*
-        * Check whether the Architectural PerfMon supports
-        * Unhalted Core Cycles Event or not.
-        * NOTE: Corresponding bit = 0 in ebp indicates event present.
-        */
-       ebx = cpuid_ebx(10);
-       if ((ebx & ARCH_PERFMON_UNHALTED_CORE_CYCLES_PRESENT))
-               return 0;
-
-       nmi_perfctr_msr = MSR_ARCH_PERFMON_PERFCTR0;
-
-       clear_msr_range(MSR_ARCH_PERFMON_EVENTSEL0, 2);
-       clear_msr_range(MSR_ARCH_PERFMON_PERFCTR0, 2);
-
-       evntsel = ARCH_PERFMON_EVENTSEL_INT
-               | ARCH_PERFMON_EVENTSEL_OS
-               | ARCH_PERFMON_EVENTSEL_USR
-               | ARCH_PERFMON_NMI_EVENT_SEL
-               | ARCH_PERFMON_NMI_EVENT_UMASK;
-
-       wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0);
-       wrmsrl(MSR_ARCH_PERFMON_PERFCTR0, -((u64)cpu_khz * 1000 / nmi_hz));
-       apic_write(APIC_LVTPC, APIC_DM_NMI);
-       evntsel |= ARCH_PERFMON_EVENTSEL0_ENABLE;
-       wrmsr(MSR_ARCH_PERFMON_EVENTSEL0, evntsel, 0);
-       return 1;
-}
-
 
 static int setup_p4_watchdog(void)
 {
@@ -477,16 +429,10 @@ void setup_apic_nmi_watchdog(void)
                setup_k7_watchdog();
                break;
        case X86_VENDOR_INTEL:
-               if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
-                       if (!setup_intel_arch_watchdog())
-                               return;
-               } else if (boot_cpu_data.x86 == 15) {
-                       if (!setup_p4_watchdog())
-                               return;
-               } else {
+               if (boot_cpu_data.x86 != 15)
+                       return;
+               if (!setup_p4_watchdog())
                        return;
-               }
-
                break;
 
        default:
@@ -536,12 +482,6 @@ 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 ...
@@ -571,14 +511,7 @@ void __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason)
                         */
                        wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0);
                        apic_write(APIC_LVTPC, APIC_DM_NMI);
-               } else if (nmi_perfctr_msr == MSR_ARCH_PERFMON_PERFCTR0) {
-                       /*
-                        * For Intel based architectural perfmon
-                        * - LVTPC is masked on interrupt and must be
-                        *   unmasked by the LVTPC handler.
-                        */
-                       apic_write(APIC_LVTPC, APIC_DM_NMI);
-               }
+               }
                wrmsrl(nmi_perfctr_msr, -((u64)cpu_khz * 1000 / nmi_hz));
        }
 }
@@ -603,16 +536,13 @@ 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);
 }
-EXPORT_SYMBOL_GPL(set_nmi_callback);
 
 void unset_nmi_callback(void)
 {
        nmi_callback = dummy_nmi_callback;
 }
-EXPORT_SYMBOL_GPL(unset_nmi_callback);
 
 #ifdef CONFIG_SYSCTL