Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * Non Fatal Machine Check Exception Reporting
  3  *
  4  * (C) Copyright 2002 Dave Jones. <davej@codemonkey.org.uk>
  5  *
  6  * This file contains routines to check for non-fatal MCEs every 15s
  7  *
  8  */
  9 
 10 #include <linux/init.h>
 11 #include <linux/types.h>
 12 #include <linux/kernel.h>
 13 #include <linux/jiffies.h>
 14 #include <linux/workqueue.h>
 15 #include <linux/interrupt.h>
 16 #include <linux/smp.h>
 17 #include <linux/module.h>
 18 
 19 #include <asm/processor.h> 
 20 #include <asm/system.h>
 21 #include <asm/msr.h>
 22 
 23 #include "mce.h"
 24 
 25 static int firstbank;
 26 
 27 #define MCE_RATE        15*HZ   /* timer rate is 15s */
 28 
 29 static void mce_checkregs (void *info)
 30 {
 31         u32 low, high;
 32         int i;
 33 
 34         for (i=firstbank; i<nr_mce_banks; i++) {
 35                 rdmsr (MSR_IA32_MC0_STATUS+i*4, low, high);
 36 
 37                 if (high & (1<<31)) {
 38                         printk(KERN_INFO "MCE: The hardware reports a non "
 39                                 "fatal, correctable incident occurred on "
 40                                 "CPU %d.\n",
 41                                 smp_processor_id());
 42                         printk (KERN_INFO "Bank %d: %08x%08x\n", i, high, low);
 43 
 44                         /* Scrub the error so we don't pick it up in MCE_RATE seconds time. */
 45                         wrmsr (MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
 46 
 47                         /* Serialize */
 48                         wmb();
 49                         add_taint(TAINT_MACHINE_CHECK);
 50                 }
 51         }
 52 }
 53 
 54 static void mce_work_fn(struct work_struct *work);
 55 static DECLARE_DELAYED_WORK(mce_work, mce_work_fn);
 56 
 57 static void mce_work_fn(struct work_struct *work)
 58 { 
 59         on_each_cpu(mce_checkregs, NULL, 1, 1);
 60         schedule_delayed_work(&mce_work, round_jiffies_relative(MCE_RATE));
 61 } 
 62 
 63 static int __init init_nonfatal_mce_checker(void)
 64 {
 65         struct cpuinfo_x86 *c = &boot_cpu_data;
 66 
 67         /* Check for MCE support */
 68         if (!cpu_has(c, X86_FEATURE_MCE))
 69                 return -ENODEV;
 70 
 71         /* Check for PPro style MCA */
 72         if (!cpu_has(c, X86_FEATURE_MCA))
 73                 return -ENODEV;
 74 
 75         /* Some Athlons misbehave when we frob bank 0 */
 76         if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
 77                 boot_cpu_data.x86 == 6)
 78                         firstbank = 1;
 79         else
 80                         firstbank = 0;
 81 
 82         /*
 83          * Check for non-fatal errors every MCE_RATE s
 84          */
 85         schedule_delayed_work(&mce_work, round_jiffies_relative(MCE_RATE));
 86         printk(KERN_INFO "Machine check exception polling timer started.\n");
 87         return 0;
 88 }
 89 module_init(init_nonfatal_mce_checker);
 90 
 91 MODULE_LICENSE("GPL");
 92 
  This page was automatically generated by the LXR engine.