]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86_64/kernel/mce.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-bugfix
[linux-2.6-omap-h63xx.git] / arch / x86_64 / kernel / mce.c
index 183dc61054295426fcf12262cf94c66ab6df0a0b..b8b9529fa89e0db08b90cc6d6bea4da6fa7e0afb 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/sysdev.h>
 #include <linux/miscdevice.h>
 #include <linux/fs.h>
+#include <linux/capability.h>
 #include <linux/cpu.h>
 #include <linux/percpu.h>
 #include <linux/ctype.h>
 #include <asm/mce.h>
 #include <asm/kdebug.h>
 #include <asm/uaccess.h>
+#include <asm/smp.h>
 
 #define MISC_MCELOG_MINOR 227
-#define NR_BANKS 5
+#define NR_BANKS 6
 
 static int mce_dont_init;
 
@@ -91,6 +93,7 @@ void mce_log(struct mce *mce)
 static void print_mce(struct mce *m)
 {
        printk(KERN_EMERG "\n"
+              KERN_EMERG "HARDWARE ERROR\n"
               KERN_EMERG
               "CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n",
               m->cpu, m->mcgstatus, m->bank, m->status);
@@ -109,6 +112,9 @@ static void print_mce(struct mce *m)
        if (m->misc)
                printk("MISC %Lx ", m->misc);   
        printk("\n");
+       printk(KERN_EMERG "This is not a software problem!\n");
+        printk(KERN_EMERG
+    "Run through mcelog --ascii to decode and contact your hardware vendor\n");
 }
 
 static void mce_panic(char *msg, struct mce *backup, unsigned long start)
@@ -168,12 +174,12 @@ void do_machine_check(struct pt_regs * regs, long error_code)
        int panicm_found = 0;
 
        if (regs)
-               notify_die(DIE_NMI, "machine check", regs, error_code, 255, SIGKILL);
+               notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL);
        if (!banks)
                return;
 
        memset(&m, 0, sizeof(struct mce));
-       m.cpu = hard_smp_processor_id();
+       m.cpu = safe_smp_processor_id();
        rdmsrl(MSR_IA32_MCG_STATUS, m.mcgstatus);
        if (!(m.mcgstatus & MCG_STATUS_RIPV))
                kill_it = 1;
@@ -374,7 +380,7 @@ static void __cpuinit mce_cpu_features(struct cpuinfo_x86 *c)
  */
 void __cpuinit mcheck_init(struct cpuinfo_x86 *c)
 {
-       static cpumask_t mce_cpus __initdata = CPU_MASK_NONE;
+       static cpumask_t mce_cpus = CPU_MASK_NONE;
 
        mce_cpu_quirks(c); 
 
@@ -573,6 +579,10 @@ ACCESSOR(bank1ctl,bank[1],mce_restart())
 ACCESSOR(bank2ctl,bank[2],mce_restart())
 ACCESSOR(bank3ctl,bank[3],mce_restart())
 ACCESSOR(bank4ctl,bank[4],mce_restart())
+ACCESSOR(bank5ctl,bank[5],mce_restart())
+static struct sysdev_attribute * bank_attributes[NR_BANKS] = {
+       &attr_bank0ctl, &attr_bank1ctl, &attr_bank2ctl,
+       &attr_bank3ctl, &attr_bank4ctl, &attr_bank5ctl};
 ACCESSOR(tolerant,tolerant,)
 ACCESSOR(check_interval,check_interval,mce_restart())
 
@@ -580,6 +590,7 @@ ACCESSOR(check_interval,check_interval,mce_restart())
 static __cpuinit int mce_create_device(unsigned int cpu)
 {
        int err;
+       int i;
        if (!mce_available(&cpu_data[cpu]))
                return -EIO;
 
@@ -589,11 +600,9 @@ static __cpuinit int mce_create_device(unsigned int cpu)
        err = sysdev_register(&per_cpu(device_mce,cpu));
 
        if (!err) {
-               sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank0ctl);
-               sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank1ctl);
-               sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank2ctl);
-               sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank3ctl);
-               sysdev_create_file(&per_cpu(device_mce,cpu), &attr_bank4ctl);
+               for (i = 0; i < banks; i++)
+                       sysdev_create_file(&per_cpu(device_mce,cpu),
+                               bank_attributes[i]);
                sysdev_create_file(&per_cpu(device_mce,cpu), &attr_tolerant);
                sysdev_create_file(&per_cpu(device_mce,cpu), &attr_check_interval);
        }
@@ -603,11 +612,11 @@ static __cpuinit int mce_create_device(unsigned int cpu)
 #ifdef CONFIG_HOTPLUG_CPU
 static __cpuinit void mce_remove_device(unsigned int cpu)
 {
-       sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank0ctl);
-       sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank1ctl);
-       sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank2ctl);
-       sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank3ctl);
-       sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_bank4ctl);
+       int i;
+
+       for (i = 0; i < banks; i++)
+               sysdev_remove_file(&per_cpu(device_mce,cpu),
+                       bank_attributes[i]);
        sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_tolerant);
        sysdev_remove_file(&per_cpu(device_mce,cpu), &attr_check_interval);
        sysdev_unregister(&per_cpu(device_mce,cpu));