non-fatal.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. #include <linux/init.h>
  10. #include <linux/types.h>
  11. #include <linux/kernel.h>
  12. #include <linux/jiffies.h>
  13. #include <linux/config.h>
  14. #include <linux/irq.h>
  15. #include <linux/workqueue.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/smp.h>
  18. #include <linux/module.h>
  19. #include <asm/processor.h>
  20. #include <asm/system.h>
  21. #include <asm/msr.h>
  22. #include "mce.h"
  23. static int firstbank;
  24. #define MCE_RATE 15*HZ /* timer rate is 15s */
  25. static void mce_checkregs (void *info)
  26. {
  27. u32 low, high;
  28. int i;
  29. for (i=firstbank; i<nr_mce_banks; i++) {
  30. rdmsr (MSR_IA32_MC0_STATUS+i*4, low, high);
  31. if (high & (1<<31)) {
  32. printk(KERN_INFO "MCE: The hardware reports a non "
  33. "fatal, correctable incident occurred on "
  34. "CPU %d.\n",
  35. smp_processor_id());
  36. printk (KERN_INFO "Bank %d: %08x%08x\n", i, high, low);
  37. /* Scrub the error so we don't pick it up in MCE_RATE seconds time. */
  38. wrmsr (MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
  39. /* Serialize */
  40. wmb();
  41. add_taint(TAINT_MACHINE_CHECK);
  42. }
  43. }
  44. }
  45. static void mce_work_fn(void *data);
  46. static DECLARE_WORK(mce_work, mce_work_fn, NULL);
  47. static void mce_work_fn(void *data)
  48. {
  49. on_each_cpu(mce_checkregs, NULL, 1, 1);
  50. schedule_delayed_work(&mce_work, MCE_RATE);
  51. }
  52. static int __init init_nonfatal_mce_checker(void)
  53. {
  54. struct cpuinfo_x86 *c = &boot_cpu_data;
  55. /* Check for MCE support */
  56. if (!cpu_has(c, X86_FEATURE_MCE))
  57. return -ENODEV;
  58. /* Check for PPro style MCA */
  59. if (!cpu_has(c, X86_FEATURE_MCA))
  60. return -ENODEV;
  61. /* Some Athlons misbehave when we frob bank 0 */
  62. if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
  63. boot_cpu_data.x86 == 6)
  64. firstbank = 1;
  65. else
  66. firstbank = 0;
  67. /*
  68. * Check for non-fatal errors every MCE_RATE s
  69. */
  70. schedule_delayed_work(&mce_work, MCE_RATE);
  71. printk(KERN_INFO "Machine check exception polling timer started.\n");
  72. return 0;
  73. }
  74. module_init(init_nonfatal_mce_checker);
  75. MODULE_LICENSE("GPL");