fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / i386 / kernel / cpu / mcheck / p4.c
index abb817f..504434a 100644 (file)
@@ -5,8 +5,6 @@
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/kernel.h>
-#include <linux/config.h>
-#include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/smp.h>
 
@@ -15,6 +13,8 @@
 #include <asm/msr.h>
 #include <asm/apic.h>
 
+#include <asm/therm_throt.h>
+
 #include "mce.h"
 
 /* as supported by the P4/Xeon family */
@@ -38,38 +38,34 @@ static int mce_num_extended_msrs = 0;
 #ifdef CONFIG_X86_MCE_P4THERMAL
 static void unexpected_thermal_interrupt(struct pt_regs *regs)
 {      
-       printk(KERN_ERR "CPU#%d: Unexpected LVT TMR interrupt!\n", smp_processor_id());
+       printk(KERN_ERR "CPU%d: Unexpected LVT TMR interrupt!\n",
+                       smp_processor_id());
+       add_taint(TAINT_MACHINE_CHECK);
 }
 
 /* P4/Xeon Thermal transition interrupt handler */
 static void intel_thermal_interrupt(struct pt_regs *regs)
 {
-       u32 l, h;
-       unsigned int cpu = smp_processor_id();
+       __u64 msr_val;
 
        ack_APIC_irq();
 
-       rdmsr (MSR_IA32_THERM_STATUS, l, h);
-       if (l & 1) {
-               printk(KERN_EMERG "CPU#%d: Temperature above threshold\n", cpu);
-               printk(KERN_EMERG "CPU#%d: Running in modulated clock mode\n", cpu);
-       } else {
-               printk(KERN_INFO "CPU#%d: Temperature/speed normal\n", cpu);
-       }
+       rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
+       therm_throt_process(msr_val & 0x1);
 }
 
 /* Thermal interrupt handler for this CPU setup */
 static void (*vendor_thermal_interrupt)(struct pt_regs *regs) = unexpected_thermal_interrupt;
 
-asmlinkage void smp_thermal_interrupt(struct pt_regs regs)
+fastcall void smp_thermal_interrupt(struct pt_regs *regs)
 {
        irq_enter();
-       vendor_thermal_interrupt(&regs);
+       vendor_thermal_interrupt(regs);
        irq_exit();
 }
 
 /* P4/Xeon Thermal regulation detect and init */
-static void __init intel_init_thermal(struct cpuinfo_x86 *c)
+static void intel_init_thermal(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        unsigned int cpu = smp_processor_id();
@@ -89,13 +85,15 @@ static void __init intel_init_thermal(struct cpuinfo_x86 *c)
        rdmsr (MSR_IA32_MISC_ENABLE, l, h);
        h = apic_read(APIC_LVTTHMR);
        if ((l & (1<<3)) && (h & APIC_DM_SMI)) {
-               printk(KERN_DEBUG "CPU#%d: Thermal monitoring handled by SMI\n", cpu);
+               printk(KERN_DEBUG "CPU%d: Thermal monitoring handled by SMI\n",
+                               cpu);
                return; /* -EBUSY */
        }
 
        /* check whether a vector already exists, temporarily masked? */        
        if (h & APIC_VECTOR_MASK) {
-               printk(KERN_DEBUG "CPU#%d: Thermal LVT vector (%#x) already installed\n",
+               printk(KERN_DEBUG "CPU%d: Thermal LVT vector (%#x) already "
+                               "installed\n",
                        cpu, (h & APIC_VECTOR_MASK));
                return; /* -EBUSY */
        }
@@ -113,10 +111,13 @@ static void __init intel_init_thermal(struct cpuinfo_x86 *c)
        
        rdmsr (MSR_IA32_MISC_ENABLE, l, h);
        wrmsr (MSR_IA32_MISC_ENABLE, l | (1<<3), h);
-       
+
        l = apic_read (APIC_LVTTHMR);
        apic_write_around (APIC_LVTTHMR, l & ~APIC_LVT_MASKED);
-       printk (KERN_INFO "CPU#%d: Thermal monitoring enabled\n", cpu);
+       printk (KERN_INFO "CPU%d: Thermal monitoring enabled\n", cpu);
+
+       /* enable thermal throttle processing */
+       atomic_set(&therm_throt_en, 1);
        return;
 }
 #endif /* CONFIG_X86_MCE_P4THERMAL */
@@ -148,7 +149,7 @@ done:
        return mce_num_extended_msrs;
 }
 
-static asmlinkage void intel_machine_check(struct pt_regs * regs, long error_code)
+static fastcall void intel_machine_check(struct pt_regs * regs, long error_code)
 {
        int recover=1;
        u32 alow, ahigh, high, low;
@@ -213,6 +214,7 @@ static asmlinkage void intel_machine_check(struct pt_regs * regs, long error_cod
                        wrmsr(msr, 0UL, 0UL);
                        /* Serialize */
                        wmb();
+                       add_taint(TAINT_MACHINE_CHECK);
                }
        }
        mcgstl &= ~(1<<2);
@@ -220,7 +222,7 @@ static asmlinkage void intel_machine_check(struct pt_regs * regs, long error_cod
 }
 
 
-void __init intel_p4_mcheck_init(struct cpuinfo_x86 *c)
+void intel_p4_mcheck_init(struct cpuinfo_x86 *c)
 {
        u32 l, h;
        int i;
@@ -247,7 +249,8 @@ void __init intel_p4_mcheck_init(struct cpuinfo_x86 *c)
        rdmsr (MSR_IA32_MCG_CAP, l, h);
        if (l & (1<<9)) {/* MCG_EXT_P */
                mce_num_extended_msrs = (l >> 16) & 0xff;
-               printk (KERN_INFO "CPU#%d: Intel P4/Xeon Extended MCE MSRs (%d) available\n",
+               printk (KERN_INFO "CPU%d: Intel P4/Xeon Extended MCE MSRs (%d)"
+                               " available\n",
                        smp_processor_id(), mce_num_extended_msrs);
 
 #ifdef CONFIG_X86_MCE_P4THERMAL