Skip to content

Commit 5b82826

Browse files
committed
Merge tag 'ras_core_for_v5.19_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 RAS updates from Borislav Petkov: - Simplification of the AMD MCE error severity grading logic along with supplying critical panic MCEs with accompanying error messages for more human-friendly diagnostics. - Misc fixes * tag 'ras_core_for_v5.19_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/mce: Add messages for panic errors in AMD's MCE grading x86/mce: Simplify AMD severity grading logic x86/MCE/AMD: Fix memory leak when threshold_create_bank() fails x86/mce: Avoid unnecessary padding in struct mce_bank
2 parents eb39e37 + fa619f5 commit 5b82826

File tree

3 files changed

+67
-79
lines changed

3 files changed

+67
-79
lines changed

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

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,10 +1294,23 @@ static void threshold_remove_bank(struct threshold_bank *bank)
12941294
kfree(bank);
12951295
}
12961296

1297+
static void __threshold_remove_device(struct threshold_bank **bp)
1298+
{
1299+
unsigned int bank, numbanks = this_cpu_read(mce_num_banks);
1300+
1301+
for (bank = 0; bank < numbanks; bank++) {
1302+
if (!bp[bank])
1303+
continue;
1304+
1305+
threshold_remove_bank(bp[bank]);
1306+
bp[bank] = NULL;
1307+
}
1308+
kfree(bp);
1309+
}
1310+
12971311
int mce_threshold_remove_device(unsigned int cpu)
12981312
{
12991313
struct threshold_bank **bp = this_cpu_read(threshold_banks);
1300-
unsigned int bank, numbanks = this_cpu_read(mce_num_banks);
13011314

13021315
if (!bp)
13031316
return 0;
@@ -1308,13 +1321,7 @@ int mce_threshold_remove_device(unsigned int cpu)
13081321
*/
13091322
this_cpu_write(threshold_banks, NULL);
13101323

1311-
for (bank = 0; bank < numbanks; bank++) {
1312-
if (bp[bank]) {
1313-
threshold_remove_bank(bp[bank]);
1314-
bp[bank] = NULL;
1315-
}
1316-
}
1317-
kfree(bp);
1324+
__threshold_remove_device(bp);
13181325
return 0;
13191326
}
13201327

@@ -1351,15 +1358,14 @@ int mce_threshold_create_device(unsigned int cpu)
13511358
if (!(this_cpu_read(bank_map) & (1 << bank)))
13521359
continue;
13531360
err = threshold_create_bank(bp, cpu, bank);
1354-
if (err)
1355-
goto out_err;
1361+
if (err) {
1362+
__threshold_remove_device(bp);
1363+
return err;
1364+
}
13561365
}
13571366
this_cpu_write(threshold_banks, bp);
13581367

13591368
if (thresholding_irq_en)
13601369
mce_threshold_vector = amd_threshold_interrupt;
13611370
return 0;
1362-
out_err:
1363-
mce_threshold_remove_device(cpu);
1364-
return err;
13651371
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ DEFINE_PER_CPU_READ_MOSTLY(unsigned int, mce_num_banks);
6969

7070
struct mce_bank {
7171
u64 ctl; /* subevents to enable */
72-
bool init; /* initialise bank? */
72+
73+
__u64 init : 1, /* initialise bank? */
74+
__reserved_1 : 63;
7375
};
7476
static DEFINE_PER_CPU_READ_MOSTLY(struct mce_bank[MAX_NR_BANKS], mce_banks_array);
7577

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

Lines changed: 45 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -301,85 +301,65 @@ static noinstr int error_context(struct mce *m, struct pt_regs *regs)
301301
}
302302
}
303303

304-
static __always_inline int mce_severity_amd_smca(struct mce *m, enum context err_ctx)
304+
/* See AMD PPR(s) section Machine Check Error Handling. */
305+
static noinstr int mce_severity_amd(struct mce *m, struct pt_regs *regs, char **msg, bool is_excp)
305306
{
306-
u64 mcx_cfg;
307+
char *panic_msg = NULL;
308+
int ret;
307309

308310
/*
309-
* We need to look at the following bits:
310-
* - "succor" bit (data poisoning support), and
311-
* - TCC bit (Task Context Corrupt)
312-
* in MCi_STATUS to determine error severity.
311+
* Default return value: Action required, the error must be handled
312+
* immediately.
313313
*/
314-
if (!mce_flags.succor)
315-
return MCE_PANIC_SEVERITY;
316-
317-
mcx_cfg = mce_rdmsrl(MSR_AMD64_SMCA_MCx_CONFIG(m->bank));
318-
319-
/* TCC (Task context corrupt). If set and if IN_KERNEL, panic. */
320-
if ((mcx_cfg & MCI_CONFIG_MCAX) &&
321-
(m->status & MCI_STATUS_TCC) &&
322-
(err_ctx == IN_KERNEL))
323-
return MCE_PANIC_SEVERITY;
324-
325-
/* ...otherwise invoke hwpoison handler. */
326-
return MCE_AR_SEVERITY;
327-
}
328-
329-
/*
330-
* See AMD Error Scope Hierarchy table in a newer BKDG. For example
331-
* 49125_15h_Models_30h-3Fh_BKDG.pdf, section "RAS Features"
332-
*/
333-
static noinstr int mce_severity_amd(struct mce *m, struct pt_regs *regs, char **msg, bool is_excp)
334-
{
335-
enum context ctx = error_context(m, regs);
314+
ret = MCE_AR_SEVERITY;
336315

337316
/* Processor Context Corrupt, no need to fumble too much, die! */
338-
if (m->status & MCI_STATUS_PCC)
339-
return MCE_PANIC_SEVERITY;
340-
341-
if (m->status & MCI_STATUS_UC) {
342-
343-
if (ctx == IN_KERNEL)
344-
return MCE_PANIC_SEVERITY;
317+
if (m->status & MCI_STATUS_PCC) {
318+
panic_msg = "Processor Context Corrupt";
319+
ret = MCE_PANIC_SEVERITY;
320+
goto out;
321+
}
345322

346-
/*
347-
* On older systems where overflow_recov flag is not present, we
348-
* should simply panic if an error overflow occurs. If
349-
* overflow_recov flag is present and set, then software can try
350-
* to at least kill process to prolong system operation.
351-
*/
352-
if (mce_flags.overflow_recov) {
353-
if (mce_flags.smca)
354-
return mce_severity_amd_smca(m, ctx);
355-
356-
/* kill current process */
357-
return MCE_AR_SEVERITY;
358-
} else {
359-
/* at least one error was not logged */
360-
if (m->status & MCI_STATUS_OVER)
361-
return MCE_PANIC_SEVERITY;
362-
}
363-
364-
/*
365-
* For any other case, return MCE_UC_SEVERITY so that we log the
366-
* error and exit #MC handler.
367-
*/
368-
return MCE_UC_SEVERITY;
323+
if (m->status & MCI_STATUS_DEFERRED) {
324+
ret = MCE_DEFERRED_SEVERITY;
325+
goto out;
369326
}
370327

371328
/*
372-
* deferred error: poll handler catches these and adds to mce_ring so
373-
* memory-failure can take recovery actions.
329+
* If the UC bit is not set, the system either corrected or deferred
330+
* the error. No action will be required after logging the error.
374331
*/
375-
if (m->status & MCI_STATUS_DEFERRED)
376-
return MCE_DEFERRED_SEVERITY;
332+
if (!(m->status & MCI_STATUS_UC)) {
333+
ret = MCE_KEEP_SEVERITY;
334+
goto out;
335+
}
377336

378337
/*
379-
* corrected error: poll handler catches these and passes responsibility
380-
* of decoding the error to EDAC
338+
* On MCA overflow, without the MCA overflow recovery feature the
339+
* system will not be able to recover, panic.
381340
*/
382-
return MCE_KEEP_SEVERITY;
341+
if ((m->status & MCI_STATUS_OVER) && !mce_flags.overflow_recov) {
342+
panic_msg = "Overflowed uncorrected error without MCA Overflow Recovery";
343+
ret = MCE_PANIC_SEVERITY;
344+
goto out;
345+
}
346+
347+
if (!mce_flags.succor) {
348+
panic_msg = "Uncorrected error without MCA Recovery";
349+
ret = MCE_PANIC_SEVERITY;
350+
goto out;
351+
}
352+
353+
if (error_context(m, regs) == IN_KERNEL) {
354+
panic_msg = "Uncorrected unrecoverable error in kernel context";
355+
ret = MCE_PANIC_SEVERITY;
356+
}
357+
358+
out:
359+
if (msg && panic_msg)
360+
*msg = panic_msg;
361+
362+
return ret;
383363
}
384364

385365
static noinstr int mce_severity_intel(struct mce *m, struct pt_regs *regs, char **msg, bool is_excp)

0 commit comments

Comments
 (0)