x86/mce: Add infrastructure to support Local MCE
Initialize and prepare for handling LMCEs. Add a boot-time option to disable LMCEs. Signed-off-by: Ashok Raj <ashok.raj@intel.com> [ Simplify stuff, align statements for better readability, reflow comments; kill unused lmce_clear(); save us an MSR write if LMCE is already enabled. ] Signed-off-by: Borislav Petkov <bp@suse.de> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Tony Luck <tony.luck@intel.com> Cc: linux-edac <linux-edac@vger.kernel.org> Link: http://lkml.kernel.org/r/1433436928-31903-16-git-send-email-bp@alien8.de Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -1982,6 +1982,7 @@ void mce_disable_bank(int bank)
|
||||
/*
|
||||
* mce=off Disables machine check
|
||||
* mce=no_cmci Disables CMCI
|
||||
* mce=no_lmce Disables LMCE
|
||||
* mce=dont_log_ce Clears corrected events silently, no log created for CEs.
|
||||
* mce=ignore_ce Disables polling and CMCI, corrected events are not cleared.
|
||||
* mce=TOLERANCELEVEL[,monarchtimeout] (number, see above)
|
||||
@@ -2005,6 +2006,8 @@ static int __init mcheck_enable(char *str)
|
||||
cfg->disabled = true;
|
||||
else if (!strcmp(str, "no_cmci"))
|
||||
cfg->cmci_disabled = true;
|
||||
else if (!strcmp(str, "no_lmce"))
|
||||
cfg->lmce_disabled = true;
|
||||
else if (!strcmp(str, "dont_log_ce"))
|
||||
cfg->dont_log_ce = true;
|
||||
else if (!strcmp(str, "ignore_ce"))
|
||||
|
@@ -91,6 +91,36 @@ static int cmci_supported(int *banks)
|
||||
return !!(cap & MCG_CMCI_P);
|
||||
}
|
||||
|
||||
static bool lmce_supported(void)
|
||||
{
|
||||
u64 tmp;
|
||||
|
||||
if (mca_cfg.lmce_disabled)
|
||||
return false;
|
||||
|
||||
rdmsrl(MSR_IA32_MCG_CAP, tmp);
|
||||
|
||||
/*
|
||||
* LMCE depends on recovery support in the processor. Hence both
|
||||
* MCG_SER_P and MCG_LMCE_P should be present in MCG_CAP.
|
||||
*/
|
||||
if ((tmp & (MCG_SER_P | MCG_LMCE_P)) !=
|
||||
(MCG_SER_P | MCG_LMCE_P))
|
||||
return false;
|
||||
|
||||
/*
|
||||
* BIOS should indicate support for LMCE by setting bit 20 in
|
||||
* IA32_FEATURE_CONTROL without which touching MCG_EXT_CTL will
|
||||
* generate a #GP fault.
|
||||
*/
|
||||
rdmsrl(MSR_IA32_FEATURE_CONTROL, tmp);
|
||||
if ((tmp & (FEATURE_CONTROL_LOCKED | FEATURE_CONTROL_LMCE)) ==
|
||||
(FEATURE_CONTROL_LOCKED | FEATURE_CONTROL_LMCE))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mce_intel_cmci_poll(void)
|
||||
{
|
||||
if (__this_cpu_read(cmci_storm_state) == CMCI_STORM_NONE)
|
||||
@@ -405,6 +435,19 @@ static void intel_init_cmci(void)
|
||||
cmci_recheck();
|
||||
}
|
||||
|
||||
void intel_init_lmce(void)
|
||||
{
|
||||
u64 val;
|
||||
|
||||
if (!lmce_supported())
|
||||
return;
|
||||
|
||||
rdmsrl(MSR_IA32_MCG_EXT_CTL, val);
|
||||
|
||||
if (!(val & MCG_EXT_CTL_LMCE_EN))
|
||||
wrmsrl(MSR_IA32_MCG_EXT_CTL, val | MCG_EXT_CTL_LMCE_EN);
|
||||
}
|
||||
|
||||
void mce_intel_feature_init(struct cpuinfo_x86 *c)
|
||||
{
|
||||
intel_init_thermal(c);
|
||||
|
Reference in New Issue
Block a user