Skip to content

Commit c2f9b0a

Browse files
author
Ingo Molnar
committed
Merge branch 'x86/ras' into x86/core, to fix conflicts
Conflicts: arch/x86/include/asm/irq_vectors.h Signed-off-by: Ingo Molnar <mingo@kernel.org>
2 parents c8e56d2 + 243d657 commit c2f9b0a

File tree

16 files changed

+271
-52
lines changed

16 files changed

+271
-52
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/entry_arch.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,7 @@ BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR)
5252
BUILD_INTERRUPT(threshold_interrupt,THRESHOLD_APIC_VECTOR)
5353
#endif
5454

55+
#ifdef CONFIG_X86_MCE_AMD
56+
BUILD_INTERRUPT(deferred_error_interrupt, DEFERRED_ERROR_VECTOR)
57+
#endif
5558
#endif

arch/x86/include/asm/hardirq.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ typedef struct {
3434
#ifdef CONFIG_X86_MCE_THRESHOLD
3535
unsigned int irq_threshold_count;
3636
#endif
37+
#ifdef CONFIG_X86_MCE_AMD
38+
unsigned int irq_deferred_error_count;
39+
#endif
3740
#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
3841
unsigned int irq_hv_callback_count;
3942
#endif

arch/x86/include/asm/hw_irq.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ extern asmlinkage void reschedule_interrupt(void);
4040
extern asmlinkage void irq_move_cleanup_interrupt(void);
4141
extern asmlinkage void reboot_interrupt(void);
4242
extern asmlinkage void threshold_interrupt(void);
43+
extern asmlinkage void deferred_error_interrupt(void);
4344

4445
extern asmlinkage void call_function_interrupt(void);
4546
extern asmlinkage void call_function_single_interrupt(void);
@@ -54,6 +55,7 @@ extern void trace_spurious_interrupt(void);
5455
extern void trace_thermal_interrupt(void);
5556
extern void trace_reschedule_interrupt(void);
5657
extern void trace_threshold_interrupt(void);
58+
extern void trace_deferred_error_interrupt(void);
5759
extern void trace_call_function_interrupt(void);
5860
extern void trace_call_function_single_interrupt(void);
5961
#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt

arch/x86/include/asm/irq_vectors.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,23 @@
8383
*/
8484
#define X86_PLATFORM_IPI_VECTOR 0xf7
8585

86-
/* Vector for KVM to deliver posted interrupt IPI */
87-
#ifdef CONFIG_HAVE_KVM
88-
#define POSTED_INTR_VECTOR 0xf2
8986
#define POSTED_INTR_WAKEUP_VECTOR 0xf1
90-
#endif
91-
9287
/*
9388
* IRQ work vector:
9489
*/
9590
#define IRQ_WORK_VECTOR 0xf6
9691

9792
#define UV_BAU_MESSAGE 0xf5
93+
#define DEFERRED_ERROR_VECTOR 0xf4
9894

9995
/* Vector on which hypervisor callbacks will be delivered */
10096
#define HYPERVISOR_CALLBACK_VECTOR 0xf3
10197

98+
/* Vector for KVM to deliver posted interrupt IPI */
99+
#ifdef CONFIG_HAVE_KVM
100+
#define POSTED_INTR_VECTOR 0xf2
101+
#endif
102+
102103
/*
103104
* Local APIC timer IRQ vector is on a different priority level,
104105
* to work around the 'lost local interrupt if more than 2 IRQ

arch/x86/include/asm/mce.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,16 @@
1717
#define MCG_EXT_CNT(c) (((c) & MCG_EXT_CNT_MASK) >> MCG_EXT_CNT_SHIFT)
1818
#define MCG_SER_P (1ULL<<24) /* MCA recovery/new status bits */
1919
#define MCG_ELOG_P (1ULL<<26) /* Extended error log supported */
20+
#define MCG_LMCE_P (1ULL<<27) /* Local machine check supported */
2021

2122
/* MCG_STATUS register defines */
2223
#define MCG_STATUS_RIPV (1ULL<<0) /* restart ip valid */
2324
#define MCG_STATUS_EIPV (1ULL<<1) /* ip points to correct instruction */
2425
#define MCG_STATUS_MCIP (1ULL<<2) /* machine check in progress */
26+
#define MCG_STATUS_LMCES (1ULL<<3) /* LMCE signaled */
27+
28+
/* MCG_EXT_CTL register defines */
29+
#define MCG_EXT_CTL_LMCE_EN (1ULL<<0) /* Enable LMCE */
2530

2631
/* MCi_STATUS register defines */
2732
#define MCI_STATUS_VAL (1ULL<<63) /* valid error */
@@ -104,6 +109,7 @@ struct mce_log {
104109
struct mca_config {
105110
bool dont_log_ce;
106111
bool cmci_disabled;
112+
bool lmce_disabled;
107113
bool ignore_ce;
108114
bool disabled;
109115
bool ser;
@@ -117,8 +123,19 @@ struct mca_config {
117123
};
118124

119125
struct mce_vendor_flags {
120-
__u64 overflow_recov : 1, /* cpuid_ebx(80000007) */
121-
__reserved_0 : 63;
126+
/*
127+
* overflow recovery cpuid bit indicates that overflow
128+
* conditions are not fatal
129+
*/
130+
__u64 overflow_recov : 1,
131+
132+
/*
133+
* SUCCOR stands for S/W UnCorrectable error COntainment
134+
* and Recovery. It indicates support for data poisoning
135+
* in HW and deferred error interrupts.
136+
*/
137+
succor : 1,
138+
__reserved_0 : 62;
122139
};
123140
extern struct mce_vendor_flags mce_flags;
124141

@@ -168,12 +185,16 @@ void cmci_clear(void);
168185
void cmci_reenable(void);
169186
void cmci_rediscover(void);
170187
void cmci_recheck(void);
188+
void lmce_clear(void);
189+
void lmce_enable(void);
171190
#else
172191
static inline void mce_intel_feature_init(struct cpuinfo_x86 *c) { }
173192
static inline void cmci_clear(void) {}
174193
static inline void cmci_reenable(void) {}
175194
static inline void cmci_rediscover(void) {}
176195
static inline void cmci_recheck(void) {}
196+
static inline void lmce_clear(void) {}
197+
static inline void lmce_enable(void) {}
177198
#endif
178199

179200
#ifdef CONFIG_X86_MCE_AMD
@@ -223,6 +244,9 @@ void do_machine_check(struct pt_regs *, long);
223244
extern void (*mce_threshold_vector)(void);
224245
extern void (*threshold_cpu_callback)(unsigned long action, unsigned int cpu);
225246

247+
/* Deferred error interrupt handler */
248+
extern void (*deferred_error_int_vector)(void);
249+
226250
/*
227251
* Thermal handler
228252
*/

arch/x86/include/asm/trace/irq_vectors.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@ DEFINE_IRQ_VECTOR_EVENT(call_function_single);
100100
*/
101101
DEFINE_IRQ_VECTOR_EVENT(threshold_apic);
102102

103+
/*
104+
* deferred_error_apic - called when entering/exiting a deferred apic interrupt
105+
* vector handler
106+
*/
107+
DEFINE_IRQ_VECTOR_EVENT(deferred_error_apic);
108+
103109
/*
104110
* thermal_apic - called when entering/exiting a thermal apic interrupt
105111
* vector handler

arch/x86/include/asm/traps.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ extern int panic_on_unrecovered_nmi;
108108
void math_emulate(struct math_emu_info *);
109109
#ifndef CONFIG_X86_32
110110
asmlinkage void smp_thermal_interrupt(void);
111-
asmlinkage void mce_threshold_interrupt(void);
111+
asmlinkage void smp_threshold_interrupt(void);
112+
asmlinkage void smp_deferred_error_interrupt(void);
112113
#endif
113114

114115
extern enum ctx_state ist_enter(struct pt_regs *regs);

arch/x86/include/uapi/asm/msr-index.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#define MSR_IA32_MCG_CAP 0x00000179
5757
#define MSR_IA32_MCG_STATUS 0x0000017a
5858
#define MSR_IA32_MCG_CTL 0x0000017b
59+
#define MSR_IA32_MCG_EXT_CTL 0x000004d0
5960

6061
#define MSR_OFFCORE_RSP_0 0x000001a6
6162
#define MSR_OFFCORE_RSP_1 0x000001a7
@@ -380,6 +381,7 @@
380381
#define FEATURE_CONTROL_LOCKED (1<<0)
381382
#define FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX (1<<1)
382383
#define FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX (1<<2)
384+
#define FEATURE_CONTROL_LMCE (1<<20)
383385

384386
#define MSR_IA32_APICBASE 0x0000001b
385387
#define MSR_IA32_APICBASE_BSP (1<<8)

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

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
10501050
char *msg = "Unknown";
10511051
u64 recover_paddr = ~0ull;
10521052
int flags = MF_ACTION_REQUIRED;
1053+
int lmce = 0;
10531054

10541055
prev_state = ist_enter(regs);
10551056

@@ -1077,11 +1078,20 @@ void do_machine_check(struct pt_regs *regs, long error_code)
10771078
kill_it = 1;
10781079

10791080
/*
1080-
* Go through all the banks in exclusion of the other CPUs.
1081-
* This way we don't report duplicated events on shared banks
1082-
* because the first one to see it will clear it.
1081+
* Check if this MCE is signaled to only this logical processor
10831082
*/
1084-
order = mce_start(&no_way_out);
1083+
if (m.mcgstatus & MCG_STATUS_LMCES)
1084+
lmce = 1;
1085+
else {
1086+
/*
1087+
* Go through all the banks in exclusion of the other CPUs.
1088+
* This way we don't report duplicated events on shared banks
1089+
* because the first one to see it will clear it.
1090+
* If this is a Local MCE, then no need to perform rendezvous.
1091+
*/
1092+
order = mce_start(&no_way_out);
1093+
}
1094+
10851095
for (i = 0; i < cfg->banks; i++) {
10861096
__clear_bit(i, toclear);
10871097
if (!test_bit(i, valid_banks))
@@ -1158,8 +1168,18 @@ void do_machine_check(struct pt_regs *regs, long error_code)
11581168
* Do most of the synchronization with other CPUs.
11591169
* When there's any problem use only local no_way_out state.
11601170
*/
1161-
if (mce_end(order) < 0)
1162-
no_way_out = worst >= MCE_PANIC_SEVERITY;
1171+
if (!lmce) {
1172+
if (mce_end(order) < 0)
1173+
no_way_out = worst >= MCE_PANIC_SEVERITY;
1174+
} else {
1175+
/*
1176+
* Local MCE skipped calling mce_reign()
1177+
* If we found a fatal error, we need to panic here.
1178+
*/
1179+
if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)
1180+
mce_panic("Machine check from unknown source",
1181+
NULL, NULL);
1182+
}
11631183

11641184
/*
11651185
* At insane "tolerant" levels we take no action. Otherwise
@@ -1640,10 +1660,16 @@ static void __mcheck_cpu_init_vendor(struct cpuinfo_x86 *c)
16401660
mce_intel_feature_init(c);
16411661
mce_adjust_timer = cmci_intel_adjust_timer;
16421662
break;
1643-
case X86_VENDOR_AMD:
1663+
1664+
case X86_VENDOR_AMD: {
1665+
u32 ebx = cpuid_ebx(0x80000007);
1666+
16441667
mce_amd_feature_init(c);
1645-
mce_flags.overflow_recov = cpuid_ebx(0x80000007) & 0x1;
1668+
mce_flags.overflow_recov = !!(ebx & BIT(0));
1669+
mce_flags.succor = !!(ebx & BIT(1));
16461670
break;
1671+
}
1672+
16471673
default:
16481674
break;
16491675
}
@@ -1979,6 +2005,7 @@ void mce_disable_bank(int bank)
19792005
/*
19802006
* mce=off Disables machine check
19812007
* mce=no_cmci Disables CMCI
2008+
* mce=no_lmce Disables LMCE
19822009
* mce=dont_log_ce Clears corrected events silently, no log created for CEs.
19832010
* mce=ignore_ce Disables polling and CMCI, corrected events are not cleared.
19842011
* mce=TOLERANCELEVEL[,monarchtimeout] (number, see above)
@@ -2002,6 +2029,8 @@ static int __init mcheck_enable(char *str)
20022029
cfg->disabled = true;
20032030
else if (!strcmp(str, "no_cmci"))
20042031
cfg->cmci_disabled = true;
2032+
else if (!strcmp(str, "no_lmce"))
2033+
cfg->lmce_disabled = true;
20052034
else if (!strcmp(str, "dont_log_ce"))
20062035
cfg->dont_log_ce = true;
20072036
else if (!strcmp(str, "ignore_ce"))
@@ -2011,11 +2040,8 @@ static int __init mcheck_enable(char *str)
20112040
else if (!strcmp(str, "bios_cmci_threshold"))
20122041
cfg->bios_cmci_threshold = true;
20132042
else if (isdigit(str[0])) {
2014-
get_option(&str, &(cfg->tolerant));
2015-
if (*str == ',') {
2016-
++str;
2043+
if (get_option(&str, &cfg->tolerant) == 2)
20172044
get_option(&str, &(cfg->monarch_timeout));
2018-
}
20192045
} else {
20202046
pr_info("mce argument %s ignored. Please use /sys\n", str);
20212047
return 0;

0 commit comments

Comments
 (0)