x86: EDAC: MCE: Fix MCE decoding callback logic

Make decoding of MCEs happen only on AMD hardware by registering a
non-default callback only on CPU families which support it.

While looking at the interaction of decode_mce() with the other MCE
code i also noticed a few other things and made the following
cleanups/fixes:

 - Fixed the mce_decode() weak alias - a weak alias is really not
   good here, it should be a proper callback. A weak alias will be
   overriden if a piece of code is built into the kernel - not
   good, obviously.

 - The patch initializes the callback on AMD family 10h and 11h.

 - Added the more correct fallback printk of:

	No support for human readable MCE decoding on this CPU type.
	Transcribe the message and run it through 'mcelog --ascii' to decode.

   On CPUs that dont have a decoder.

 - Made the surrounding code more readable.

Note that the callback allows us to have a default fallback -
without having to check the CPU versions during the printout
itself. When an EDAC module registers itself, it can install the
decode-print function.

(there's no unregister needed as this is core code.)

version -v2 by Borislav Petkov:

 - add K8 to the set of supported CPUs

 - always build in edac_mce_amd since we use an early_initcall now

 - fix checkpatch warnings

Signed-off-by: Borislav Petkov <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Andi Kleen <[email protected]>
LKML-Reference: <20091001141432.GA11410@aftab>
Signed-off-by: Ingo Molnar <[email protected]>
This commit is contained in:
Ingo Molnar 2009-10-01 16:14:32 +02:00
commit f436f8bb73
4 changed files with 53 additions and 24 deletions

View file

@ -18,7 +18,7 @@ edac_core-objs += edac_pci.o edac_pci_sysfs.o
endif
ifdef CONFIG_CPU_SUP_AMD
edac_core-objs += edac_mce_amd.o
obj-$(CONFIG_X86_MCE) += edac_mce_amd.o
endif
obj-$(CONFIG_EDAC_AMD76X) += amd76x_edac.o

View file

@ -362,7 +362,7 @@ static inline void amd_decode_err_code(unsigned int ec)
pr_warning("Huh? Unknown MCE error 0x%x\n", ec);
}
void decode_mce(struct mce *m)
static void amd_decode_mce(struct mce *m)
{
struct err_regs regs;
int node, ecc;
@ -420,3 +420,16 @@ void decode_mce(struct mce *m)
amd_decode_err_code(m->status & 0xffff);
}
static int __init mce_amd_init(void)
{
/*
* We can decode MCEs for Opteron and later CPUs:
*/
if ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
(boot_cpu_data.x86 >= 0xf))
x86_mce_decode_callback = amd_decode_mce;
return 0;
}
early_initcall(mce_amd_init);