non-fatal.c 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. * Non Fatal Machine Check Exception Reporting
  3. *
  4. * (C) Copyright 2002 Dave Jones. <davej@redhat.com>
  5. *
  6. * This file contains routines to check for non-fatal MCEs every 15s
  7. *
  8. */
  9. #include <linux/interrupt.h>
  10. #include <linux/workqueue.h>
  11. #include <linux/jiffies.h>
  12. #include <linux/kernel.h>
  13. #include <linux/module.h>
  14. #include <linux/types.h>
  15. #include <linux/init.h>
  16. #include <linux/smp.h>
  17. #include <asm/processor.h>
  18. #include <asm/system.h>
  19. #include <asm/msr.h>
  20. #include "mce.h"
  21. static int firstbank;
  22. #define MCE_RATE (15*HZ) /* timer rate is 15s */
  23. static void mce_checkregs(void *info)
  24. {
  25. u32 low, high;
  26. int i;
  27. for (i = firstbank; i < nr_mce_banks; i++) {
  28. rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high);
  29. if (!(high & (1<<31)))
  30. continue;
  31. printk(KERN_INFO "MCE: The hardware reports a non fatal, "
  32. "correctable incident occurred on CPU %d.\n",
  33. smp_processor_id());
  34. printk(KERN_INFO "Bank %d: %08x%08x\n", i, high, low);
  35. /*
  36. * Scrub the error so we don't pick it up in MCE_RATE
  37. * seconds time:
  38. */
  39. wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);
  40. /* Serialize: */
  41. wmb();
  42. add_taint(TAINT_MACHINE_CHECK);
  43. }
  44. }
  45. static void mce_work_fn(struct work_struct *work);
  46. static DECLARE_DELAYED_WORK(mce_work, mce_work_fn);
  47. static void mce_work_fn(struct work_struct *work)
  48. {
  49. on_each_cpu(mce_checkregs, NULL, 1);
  50. schedule_delayed_work(&mce_work, round_jiffies_relative(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, round_jiffies_relative(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");