non-fatal.c 2.0 KB

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