Browse Source

x86: EDAC: carve out AMD MCE decoding logic

This converts the MCE decoding logic into a standalone config
option which can be built-in or a module, the first one being the
default for MCEs happening early on in the boot process.

This, beyond being separated in a cleaner way, also saves RAM by
making the decoding logic modular.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andi Kleen <andi@firstfloor.org>
LKML-Reference: <20091002133148.GD28682@aftab>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Borislav Petkov 15 years ago
parent
commit
0d18b2e34b
3 changed files with 32 additions and 6 deletions
  1. 13 1
      drivers/edac/Kconfig
  2. 1 4
      drivers/edac/Makefile
  3. 18 1
      drivers/edac/edac_mce_amd.c

+ 13 - 1
drivers/edac/Kconfig

@@ -47,6 +47,18 @@ config EDAC_DEBUG_VERBOSE
 	  Source file name and line number where debugging message
 	  Source file name and line number where debugging message
 	  printed will be added to debugging message.
 	  printed will be added to debugging message.
 
 
+ config EDAC_DECODE_MCE
+	tristate "Decode MCEs in human-readable form (only on AMD for now)"
+	depends on CPU_SUP_AMD && X86_MCE
+	default y
+	---help---
+	  Enable this option if you want to decode Machine Check Exceptions
+	  occuring on your machine in human-readable form.
+
+	  You should definitely say Y here in case you want to decode MCEs
+	  which occur really early upon boot, before the module infrastructure
+	  has been initialized.
+
 config EDAC_MM_EDAC
 config EDAC_MM_EDAC
 	tristate "Main Memory EDAC (Error Detection And Correction) reporting"
 	tristate "Main Memory EDAC (Error Detection And Correction) reporting"
 	help
 	help
@@ -59,7 +71,7 @@ config EDAC_MM_EDAC
 
 
 config EDAC_AMD64
 config EDAC_AMD64
 	tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
 	tristate "AMD64 (Opteron, Athlon64) K8, F10h, F11h"
-	depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && CPU_SUP_AMD
+	depends on EDAC_MM_EDAC && K8_NB && X86_64 && PCI && EDAC_DECODE_MCE
 	help
 	help
 	  Support for error detection and correction on the AMD 64
 	  Support for error detection and correction on the AMD 64
 	  Families of Memory Controllers (K8, F10h and F11h)
 	  Families of Memory Controllers (K8, F10h and F11h)

+ 1 - 4
drivers/edac/Makefile

@@ -6,7 +6,6 @@
 # GNU General Public License.
 # GNU General Public License.
 #
 #
 
 
-
 obj-$(CONFIG_EDAC)			:= edac_stub.o
 obj-$(CONFIG_EDAC)			:= edac_stub.o
 obj-$(CONFIG_EDAC_MM_EDAC)		+= edac_core.o
 obj-$(CONFIG_EDAC_MM_EDAC)		+= edac_core.o
 
 
@@ -17,9 +16,7 @@ ifdef CONFIG_PCI
 edac_core-objs	+= edac_pci.o edac_pci_sysfs.o
 edac_core-objs	+= edac_pci.o edac_pci_sysfs.o
 endif
 endif
 
 
-ifdef CONFIG_CPU_SUP_AMD
-obj-$(CONFIG_X86_MCE)			+= edac_mce_amd.o
-endif
+obj-$(CONFIG_EDAC_DECODE_MCE)		+= edac_mce_amd.o
 
 
 obj-$(CONFIG_EDAC_AMD76X)		+= amd76x_edac.o
 obj-$(CONFIG_EDAC_AMD76X)		+= amd76x_edac.o
 obj-$(CONFIG_EDAC_CPC925)		+= cpc925_edac.o
 obj-$(CONFIG_EDAC_CPC925)		+= cpc925_edac.o

+ 18 - 1
drivers/edac/edac_mce_amd.c

@@ -3,6 +3,7 @@
 
 
 static bool report_gart_errors;
 static bool report_gart_errors;
 static void (*nb_bus_decoder)(int node_id, struct err_regs *regs);
 static void (*nb_bus_decoder)(int node_id, struct err_regs *regs);
+static void (*orig_mce_callback)(struct mce *m);
 
 
 void amd_report_gart_errors(bool v)
 void amd_report_gart_errors(bool v)
 {
 {
@@ -427,9 +428,25 @@ static int __init mce_amd_init(void)
 	 * We can decode MCEs for Opteron and later CPUs:
 	 * We can decode MCEs for Opteron and later CPUs:
 	 */
 	 */
 	if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
 	if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
-	    (boot_cpu_data.x86 >= 0xf))
+	    (boot_cpu_data.x86 >= 0xf)) {
+		/* safe the default decode mce callback */
+		orig_mce_callback = x86_mce_decode_callback;
+
 		x86_mce_decode_callback = amd_decode_mce;
 		x86_mce_decode_callback = amd_decode_mce;
+	}
 
 
 	return 0;
 	return 0;
 }
 }
 early_initcall(mce_amd_init);
 early_initcall(mce_amd_init);
+
+#ifdef MODULE
+static void __exit mce_amd_exit(void)
+{
+	x86_mce_decode_callback = orig_mce_callback;
+}
+
+MODULE_DESCRIPTION("AMD MCE decoder");
+MODULE_ALIAS("edac-mce-amd");
+MODULE_LICENSE("GPL");
+module_exit(mce_amd_exit);
+#endif