Skip to content

Commit 88d5386

Browse files
ashok-rajIngo Molnar
authored andcommitted
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>
1 parent bc12edb commit 88d5386

File tree

4 files changed

+54
-0
lines changed

4 files changed

+54
-0
lines changed

Documentation/x86/x86_64/boot-options.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ Machine check
3131
(e.g. BIOS or hardware monitoring applications), conflicting
3232
with OS's error handling, and you cannot deactivate the agent,
3333
then this option will be a help.
34+
mce=no_lmce
35+
Do not opt-in to Local MCE delivery. Use legacy method
36+
to broadcast MCEs.
3437
mce=bootlog
3538
Enable logging of machine checks left over from booting.
3639
Disabled by default on AMD because some BIOS leave bogus ones.

arch/x86/include/asm/mce.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ struct mce_log {
109109
struct mca_config {
110110
bool dont_log_ce;
111111
bool cmci_disabled;
112+
bool lmce_disabled;
112113
bool ignore_ce;
113114
bool disabled;
114115
bool ser;
@@ -184,12 +185,16 @@ void cmci_clear(void);
184185
void cmci_reenable(void);
185186
void cmci_rediscover(void);
186187
void cmci_recheck(void);
188+
void lmce_clear(void);
189+
void lmce_enable(void);
187190
#else
188191
static inline void mce_intel_feature_init(struct cpuinfo_x86 *c) { }
189192
static inline void cmci_clear(void) {}
190193
static inline void cmci_reenable(void) {}
191194
static inline void cmci_rediscover(void) {}
192195
static inline void cmci_recheck(void) {}
196+
static inline void lmce_clear(void) {}
197+
static inline void lmce_enable(void) {}
193198
#endif
194199

195200
#ifdef CONFIG_X86_MCE_AMD

arch/x86/kernel/cpu/mcheck/mce.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1982,6 +1982,7 @@ void mce_disable_bank(int bank)
19821982
/*
19831983
* mce=off Disables machine check
19841984
* mce=no_cmci Disables CMCI
1985+
* mce=no_lmce Disables LMCE
19851986
* mce=dont_log_ce Clears corrected events silently, no log created for CEs.
19861987
* mce=ignore_ce Disables polling and CMCI, corrected events are not cleared.
19871988
* mce=TOLERANCELEVEL[,monarchtimeout] (number, see above)
@@ -2005,6 +2006,8 @@ static int __init mcheck_enable(char *str)
20052006
cfg->disabled = true;
20062007
else if (!strcmp(str, "no_cmci"))
20072008
cfg->cmci_disabled = true;
2009+
else if (!strcmp(str, "no_lmce"))
2010+
cfg->lmce_disabled = true;
20082011
else if (!strcmp(str, "dont_log_ce"))
20092012
cfg->dont_log_ce = true;
20102013
else if (!strcmp(str, "ignore_ce"))

arch/x86/kernel/cpu/mcheck/mce_intel.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,36 @@ static int cmci_supported(int *banks)
9191
return !!(cap & MCG_CMCI_P);
9292
}
9393

94+
static bool lmce_supported(void)
95+
{
96+
u64 tmp;
97+
98+
if (mca_cfg.lmce_disabled)
99+
return false;
100+
101+
rdmsrl(MSR_IA32_MCG_CAP, tmp);
102+
103+
/*
104+
* LMCE depends on recovery support in the processor. Hence both
105+
* MCG_SER_P and MCG_LMCE_P should be present in MCG_CAP.
106+
*/
107+
if ((tmp & (MCG_SER_P | MCG_LMCE_P)) !=
108+
(MCG_SER_P | MCG_LMCE_P))
109+
return false;
110+
111+
/*
112+
* BIOS should indicate support for LMCE by setting bit 20 in
113+
* IA32_FEATURE_CONTROL without which touching MCG_EXT_CTL will
114+
* generate a #GP fault.
115+
*/
116+
rdmsrl(MSR_IA32_FEATURE_CONTROL, tmp);
117+
if ((tmp & (FEATURE_CONTROL_LOCKED | FEATURE_CONTROL_LMCE)) ==
118+
(FEATURE_CONTROL_LOCKED | FEATURE_CONTROL_LMCE))
119+
return true;
120+
121+
return false;
122+
}
123+
94124
bool mce_intel_cmci_poll(void)
95125
{
96126
if (__this_cpu_read(cmci_storm_state) == CMCI_STORM_NONE)
@@ -405,6 +435,19 @@ static void intel_init_cmci(void)
405435
cmci_recheck();
406436
}
407437

438+
void intel_init_lmce(void)
439+
{
440+
u64 val;
441+
442+
if (!lmce_supported())
443+
return;
444+
445+
rdmsrl(MSR_IA32_MCG_EXT_CTL, val);
446+
447+
if (!(val & MCG_EXT_CTL_LMCE_EN))
448+
wrmsrl(MSR_IA32_MCG_EXT_CTL, val | MCG_EXT_CTL_LMCE_EN);
449+
}
450+
408451
void mce_intel_feature_init(struct cpuinfo_x86 *c)
409452
{
410453
intel_init_thermal(c);

0 commit comments

Comments
 (0)