Skip to contentSkip to conversation

x86/mce fixes

PATCH In review Tony Luck 6 participants 28 messages May 25, 2018 – Jun 22, 2018

Subsystems (3)
lore
Share & tools
lore

Tony Luck

author maintainer
#0 lore raw

cover x86/mce fixes

The first two just get better error messages when we refuse to recover from an error that the h/w says is recoverable because the error occurred in a non-recoverable part of the kernel.

The third improves identification of Skylake SKUs that support recovery.

Tony Luck (3):
x86/mce: Improve error message when kernel cannot recover. x86/mce: Fix incorrect "Machine check from unknown source" message x86/mce: Check for alternate indication of machine check recovery on
Skylake

 arch/x86/kernel/cpu/mcheck/mce-severity.c |  5 +++++
 arch/x86/kernel/cpu/mcheck/mce.c          | 26 ++++++++++++++++-------
 arch/x86/kernel/quirks.c                  | 11 ++++++++--
 3 files changed, 32 insertions(+), 10 deletions(-)
Signature · 1 line
2.17.0
author maintainer
#1 lore raw

PATCH 1/3 x86/mce: Improve error message when kernel cannot recover.

Since we added support to add recovery from some errors inside the kernel in:

commit b2f9d678e28c ("x86/mce: Check for faults tagged in EXTABLE_CLASS_FAULT exception table entries")

we have done a less than stellar job at reporting the cause of recoverable machine checks that occur in other parts of the kernel. The user just gets the unhelpful message:

mce: [Hardware Error]: Machine check: Action required: unknown MCACOD

doubly unhelpful when they check the manual for the reported IA32_MSR_STATUS.MCACOD and see that it is listed as one of the standard recoverable values.

Add an extra rule to the MCE severity table to catch this case and report it as:

mce: [Hardware Error]: Machine check: Data load in unrecoverable area of kernel

---
 arch/x86/kernel/cpu/mcheck/mce-severity.c | 5 +++++
 1 file changed, 5 insertions(+)
arch/x86/kernel/cpu/mcheck/mce-severity.c +5 -0
index 5bbd06f38ff6..f34d89c01edc 100644
@@ -160,6 +160,11 @@ static struct severity {
 		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_INSTR),
 		USER
 		),
+	MCESEV(
+		PANIC, "Data load in unrecoverable area of kernel",
+		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA),
+		KERNEL
+		),
 #endif
 	MCESEV(
 		PANIC, "Action required: unknown MCACOD",
Signature · 1 line
2.17.0
#2 lore raw

[tip:ras/urgent] x86/mce: Improve error message when kernel cannot recover

x86/mce: Improve error message when kernel cannot recover
Commit-ID:  c7d606f560e4c698884697fef503e4abacdd8c25
Gitweb:     https://git.kernel.org/tip/c7d606f560e4c698884697fef503e4abacdd8c25
Author:     Tony Luck <[email protected]>
AuthorDate: Fri, 25 May 2018 14:41:39 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Thu, 7 Jun 2018 22:22:12 +0200

x86/mce: Improve error message when kernel cannot recover

Since we added support to add recovery from some errors inside the kernel in:

commit b2f9d678e28c ("x86/mce: Check for faults tagged in EXTABLE_CLASS_FAULT exception table entries")

we have done a less than stellar job at reporting the cause of recoverable machine checks that occur in other parts of the kernel. The user just gets the unhelpful message:

mce: [Hardware Error]: Machine check: Action required: unknown MCACOD

doubly unhelpful when they check the manual for the reported IA32_MSR_STATUS.MCACOD and see that it is listed as one of the standard recoverable values.

Add an extra rule to the MCE severity table to catch this case and report it as:

mce: [Hardware Error]: Machine check: Data load in unrecoverable area of kernel

Fixes b2f9d678e28c ("x86/mce: Check for faults tagged in EXTABLE_CLASS_FAULT exception table entries")
Cc Qiuxu Zhuo <[email protected]>
Cc Ashok Raj <[email protected]>
Cc Dan Williams <[email protected]>
Cc Borislav Petkov <[email protected]>
---
 arch/x86/kernel/cpu/mcheck/mce-severity.c | 5 +++++
 1 file changed, 5 insertions(+)
arch/x86/kernel/cpu/mcheck/mce-severity.c +5 -0
index 5bbd06f38ff6..f34d89c01edc 100644
@@ -160,6 +160,11 @@ static struct severity {
 		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_INSTR),
 		USER
 		),
+	MCESEV(
+		PANIC, "Data load in unrecoverable area of kernel",
+		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|MCACOD_DATA),
+		KERNEL
+		),
 #endif
 	MCESEV(
 		PANIC, "Action required: unknown MCACOD",
author maintainer
#3 lore raw

PATCH 2/3 x86/mce: Fix incorrect "Machine check from unknown source" message

In reply to Tony Luck

Some injection testing resulted in the following console log:

mce: [Hardware Error]: CPU 22: Machine Check Exception: f Bank 1: bd80000000100134
mce: [Hardware Error]: RIP 10:<ffffffffc05292dd> {pmem_do_bvec+0x11d/0x330 [nd_pmem]}
mce: [Hardware Error]: TSC c51a63035d52 ADDR 3234bc4000 MISC 88
mce: [Hardware Error]: PROCESSOR 0:50654 TIME 1526502199 SOCKET 0 APIC 38 microcode 2000043
mce: [Hardware Error]: Run the above through 'mcelog --ascii'

 Kernel panic - not syncing: Machine check from unknown source

This confused everybody because the first line quite clearly shows that we found a logged error in "Bank 1", while the last line says "unknown source".

The problem is that the Linux code doesn't do the right thing for a local machine check that results in a fatal error.

It turns out that we know very early in the handler whether the machine check is fatal. The call to mce_no_way_out() has checked all the banks for the CPU that took the local machine check. If it says we must crash, we can do so right away with the right messages.

We do scan all the banks again. This means that we might initially not see a problem, but during the second scan find something fatal. If this happens we print a slightly different message (so I can see if it actually every happens).

---
 arch/x86/kernel/cpu/mcheck/mce.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)
arch/x86/kernel/cpu/mcheck/mce.c +18 -8
index 42cf2880d0ed..f013d97abd5f 100644
@@ -1205,13 +1205,18 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 		lmce = m.mcgstatus & MCG_STATUS_LMCES;
 
 	/*
+	 * Local machine check may already know that we have to panic.
+	 * Broadcast machine check begins rendezvous in mce_start()
 	 * Go through all banks in exclusion of the other CPUs. This way we
 	 * don't report duplicated events on shared banks because the first one
-	 * to see it will clear it. If this is a Local MCE, then no need to
-	 * perform rendezvous.
+	 * to see it will clear it.
 	 */
-	if (!lmce)
+	if (lmce) {
+		if (no_way_out)
+			mce_panic("Fatal local machine check", &m, msg);
+	} else {
 		order = mce_start(&no_way_out);
+	}
 
 	for (i = 0; i < cfg->banks; i++) {
 		__clear_bit(i, toclear);
@@ -1287,12 +1292,17 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 			no_way_out = worst >= MCE_PANIC_SEVERITY;
 	} else {
 		/*
-		 * Local MCE skipped calling mce_reign()
-		 * If we found a fatal error, we need to panic here.
+		 * If there was a fatal machine check we should have
+		 * already called mce_panic earlier in this function.
+		 * Since we re-read the banks, we might have found
+		 * something new. Check again to see if we found a
+		 * fatal error. We call "mce_severity()" again to
+		 * make sure we have the right "msg".
 		 */
-		 if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)
-			mce_panic("Machine check from unknown source",
-				NULL, NULL);
+		if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) {
+			severity = mce_severity(&m, cfg->tolerant, &msg, true);
+			mce_panic("Local fatal machine check!", &m, msg);
+		}
 	}
 
 	/*
Signature · 1 line
2.17.0
#4 lore raw

Re: [PATCH 2/3] x86/mce: Fix incorrect "Machine check from unknown source" message

Quoted 9 lines · Tony Luck
arch/x86/kernel/cpu/mcheck/mce.c +3 -2
@@ -1287,12 +1292,17 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 			no_way_out = worst >= MCE_PANIC_SEVERITY;
 	} else {
 		/*
-		 * Local MCE skipped calling mce_reign()
-		 * If we found a fatal error, we need to panic here.
+		 * If there was a fatal machine check we should have
+		 * already called mce_panic earlier in this function.
+		 * Since we re-read the banks, we might have found

arch/x86/kernel/cpu/mcheck/mce.c void do_machine_check(struct pt_regs *regs, long error_code) · line 1304

Quoted 10 lines
arch/x86/kernel/cpu/mcheck/mce.c +6 -3
+		 * something new. Check again to see if we found a
+		 * fatal error. We call "mce_severity()" again to
+		 * make sure we have the right "msg".
 		 */
-		 if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)
-			mce_panic("Machine check from unknown source",
-				NULL, NULL);
+		if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) {
+			severity = mce_severity(&m, cfg->tolerant, &msg, true);
+			mce_panic("Local fatal machine check!", &m, msg);

Haha, this would still make you look at the code to remember was it "fatal local" or "local fatal" the second one. Yeah, there's the "!" but still.

How about:

"Fatal local machine check after banks scan"

or so.

Btw, the code in do_machine_check() has become one helluva spaghetti mess. It could use some clean up a bit... :)

Signature · 5 lines
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 
author maintainer
#5 lore raw

PATCH v2 2/3 x86/mce: Fix incorrect "Machine check from unknown source" message

Some injection testing resulted in the following console log:

mce: [Hardware Error]: CPU 22: Machine Check Exception: f Bank 1: bd80000000100134
mce: [Hardware Error]: RIP 10:<ffffffffc05292dd> {pmem_do_bvec+0x11d/0x330 [nd_pmem]}
mce: [Hardware Error]: TSC c51a63035d52 ADDR 3234bc4000 MISC 88
mce: [Hardware Error]: PROCESSOR 0:50654 TIME 1526502199 SOCKET 0 APIC 38 microcode 2000043
mce: [Hardware Error]: Run the above through 'mcelog --ascii'

 Kernel panic - not syncing: Machine check from unknown source

This confused everybody because the first line quite clearly shows that we found a logged error in "Bank 1", while the last line says "unknown source".

The problem is that the Linux code doesn't do the right thing for a local machine check that results in a fatal error.

It turns out that we know very early in the handler whether the machine check is fatal. The call to mce_no_way_out() has checked all the banks for the CPU that took the local machine check. If it says we must crash, we can do so right away with the right messages.

We do scan all the banks again. This means that we might initially not see a problem, but during the second scan find something fatal. If this happens we print a different message (so I can see if it actually every happens).

---

V2: Boris:
1) make the "different message" more descriptive.
2) don't bother reassigning "severity" variable.

 arch/x86/kernel/cpu/mcheck/mce.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)
arch/x86/kernel/cpu/mcheck/mce.c +18 -8
index 42cf2880d0ed..f013d97abd5f 100644
@@ -1205,13 +1205,18 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 		lmce = m.mcgstatus & MCG_STATUS_LMCES;
 
 	/*
+	 * Local machine check may already know that we have to panic.
+	 * Broadcast machine check begins rendezvous in mce_start()
 	 * Go through all banks in exclusion of the other CPUs. This way we
 	 * don't report duplicated events on shared banks because the first one
-	 * to see it will clear it. If this is a Local MCE, then no need to
-	 * perform rendezvous.
+	 * to see it will clear it.
 	 */
-	if (!lmce)
+	if (lmce) {
+		if (no_way_out)
+			mce_panic("Fatal local machine check", &m, msg);
+	} else {
 		order = mce_start(&no_way_out);
+	}
 
 	for (i = 0; i < cfg->banks; i++) {
 		__clear_bit(i, toclear);
@@ -1287,12 +1292,17 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 			no_way_out = worst >= MCE_PANIC_SEVERITY;
 	} else {
 		/*
-		 * Local MCE skipped calling mce_reign()
-		 * If we found a fatal error, we need to panic here.
+		 * If there was a fatal machine check we should have
+		 * already called mce_panic earlier in this function.
+		 * Since we re-read the banks, we might have found
+		 * something new. Check again to see if we found a
+		 * fatal error. We call "mce_severity()" again to
+		 * make sure we have the right "msg".
 		 */
-		 if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)
-			mce_panic("Machine check from unknown source",
-				NULL, NULL);
+		if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) {
+			severity = mce_severity(&m, cfg->tolerant, &msg, true);
+			mce_panic("Local fatal machine check!", &m, msg);
+		}
 	}
 
 	/*
Signature · 1 line
2.17.0
#6 lore raw

Re: [PATCH 2/3 V2] x86/mce: Fix incorrect "Machine check from unknown source" message

Quoted 11 lines · Tony
arch/x86/kernel/cpu/mcheck/mce.c +5 -2
@@ -1287,12 +1292,17 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 			no_way_out = worst >= MCE_PANIC_SEVERITY;
 	} else {
 		/*
-		 * Local MCE skipped calling mce_reign()
-		 * If we found a fatal error, we need to panic here.
+		 * If there was a fatal machine check we should have
+		 * already called mce_panic earlier in this function.
+		 * Since we re-read the banks, we might have found
+		 * something new. Check again to see if we found a
+		 * fatal error. We call "mce_severity()" again to

arch/x86/kernel/cpu/mcheck/mce.c void do_machine_check(struct pt_regs *regs, long error_code) · line 1306

Quoted 10 lines
arch/x86/kernel/cpu/mcheck/mce.c +5 -3
+		 * make sure we have the right "msg".
 		 */
-		 if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)
-			mce_panic("Machine check from unknown source",
-				NULL, NULL);
+		if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) {
+			severity = mce_severity(&m, cfg->tolerant, &msg, true);
+			mce_panic("Local fatal machine check!", &m, msg);
+		}
 	}

It is still assigning. I'll simply do:

       if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) {
               mce_severity(&m, cfg->tolerant, &msg, true);
               mce_panic("Local fatal machine check!", &m, msg);
       }

when committing.

Btw, I did some cleaning up ontop. Please have a look and let me know if it is too ugly to live... :)

https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=rc7%2b0-ras

Thx.

Signature · 5 lines
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 
author maintainer
#7 lore raw

RE: [PATCH 2/3 V2] x86/mce: Fix incorrect "Machine check from unknown source" message

Quoted 1 line

It is still assigning.

Ah. That would be because I forgot to "git add" before "git commit --amend" :-(

Quoted 8 lines

I'll simply do:

      if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) {
              mce_severity(&m, cfg->tolerant, &msg, true);
              mce_panic("Local fatal machine check!", &m, msg);
      }

when committing.

I had put:

		(void) mce_severity(&m, cfg->tolerant, &msg, true);

but either works.

Quoted 4 lines

Btw, I did some cleaning up ontop. Please have a look and let me know if it is too ugly to live... :)

https://git.kernel.org/pub/scm/linux/kernel/git/bp/bp.git/log/?h=rc7%2b0-ras

Will look. I hope you didn't do too much to make the stable backport more difficult.

-Tony

#8 lore raw

Re: [PATCH 2/3 V2] x86/mce: Fix incorrect "Machine check from unknown source" message

Quoted 1 line · Tony

Ah. That would be because I forgot to "git add" before "git commit --amend" :-(

Oh, I know the situation very well. :)

Quoted 5 lines

I had put:

		(void) mce_severity(&m, cfg->tolerant, &msg, true);

but either works.

Right.

Quoted 1 line

Will look. I hope you didn't do too much to make the stable backport more difficult.

Nah, the cleanups will all go ontop. This is just a dirty branch to show my intention but yours go first and then the cleanup.

Signature · 5 lines
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 
author maintainer
#9 lore raw

Re: [PATCH 2/3 V2] x86/mce: Fix incorrect "Machine check from unknown source" message

Quoted 2 lines · Borislav Petkov

Nah, the cleanups will all go ontop. This is just a dirty branch to show my intention but yours go first and then the cleanup.

Couple of thoughts:

In "x86/mce: Carve out bank scanning code" you drop the extra call to mce_severity() that I just added:

@@ -1310,10 +1318,8 @@ void do_machine_check(struct pt_regs *regs, long error_code)
* fatal error. We call "mce_severity()" again to
* make sure we have the right "msg".
*/
- if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) {
- severity = mce_severity(&m, cfg->tolerant, &msg, true);
+ if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)
mce_panic("Local fatal machine check!", &m, msg);
- }
}

But "msg" won't have been filled in with the right message to match the error in "m" (__mc_scan_banks() doesn't update "msg").

In "x86/mce: Exit properly when no banks to poll" you leap right to the end. I'm wondering whether this can ever happen? I mean, if there are no machine check banks, then how did we get a machine check?

Both the original, and your new code, skip the:

	mce_wrmsrl(MSR_IA32_MCG_STATUS, 0);

which seems bad. That leaves MCG_STATUS.MCIP set ... so a second machine check would just reset the machine.

-Tony

P.S. What happened to my "part 3/3" (updating the Skylake quirk) ... does that belong in somebody else's tree?

#10 lore raw

Re: [PATCH 2/3 V2] x86/mce: Fix incorrect "Machine check from unknown source" message

Quoted 1 line · Tony

On Tue, May 29, 2018 at 07:53:14PM +0200, Borislav Petkov wrote:

[..]

Quoted 2 lines

P.S. What happened to my "part 3/3" (updating the Skylake quirk) ... does that belong in somebody else's tree?

I have no qualms taking it through the nvdimm tree with the rest of the pending memcpy_mcsafe() updates. Just need an x86 maintainer ack.

#11 lore raw

Re: [PATCH 2/3 V2] x86/mce: Fix incorrect "Machine check from unknown source" message

In reply to Luck, Tony
Quoted 1 line · Tony

Couple of thoughts:

Thanks for looking.

Quoted 2 lines

In "x86/mce: Carve out bank scanning code" you drop the extra call to mce_severity() that I just added:

Yeah, did that before we talked about it.

Quoted 4 lines

In "x86/mce: Exit properly when no banks to poll" you leap right to the end. I'm wondering whether this can ever happen? I mean, if there are no machine check banks, then how did we get a machine check?

Right, so this looks like some remnant from old times, lemme do some archeology...

/me goes and dusts off the full history linux repo...

I found this:

commit 7dd1e1d805d15ca63d05badf40026629ba75cbc8

Author: Andi Kleen <[email protected]>
Date:   Tue Feb 24 17:58:41 2004 -0800

[PATCH] New machine check handler for x86-64

and there's no mention why the !banks check is there.

I'm wondering if we should simply remove it. I mean, as you say, if there are no MCA banks, we won't be running in here in the first place...

Quoted 6 lines

Both the original, and your new code, skip the:

	mce_wrmsrl(MSR_IA32_MCG_STATUS, 0);

which seems bad. That leaves MCG_STATUS.MCIP set ... so a second machine check would just reset the machine.

That's a good point. It goes away as an issue if we simply drop the check.

Quoted 2 lines

P.S. What happened to my "part 3/3" (updating the Skylake quirk) ... does that belong in somebody else's tree?

Simply hadn't reached it yet. I will take it too, eventually.

Thx.

Signature · 5 lines
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 
#12 lore raw

Re: [PATCH 2/3 V2] x86/mce: Fix incorrect "Machine check from unknown source" message

Quoted 26 lines · Borislav Petkov
Quoted 4 lines

In "x86/mce: Exit properly when no banks to poll" you leap right to the end. I'm wondering whether this can ever happen? I mean, if there are no machine check banks, then how did we get a machine check?

Right, so this looks like some remnant from old times, lemme do some archeology...

/me goes and dusts off the full history linux repo...

I found this:

commit 7dd1e1d805d15ca63d05badf40026629ba75cbc8

Author: Andi Kleen <[email protected]>
Date:   Tue Feb 24 17:58:41 2004 -0800

[PATCH] New machine check handler for x86-64

and there's no mention why the !banks check is there.

I'm wondering if we should simply remove it. I mean, as you say, if there are no MCA banks, we won't be running in here in the first place...

Quoted 2 lines

Both the original, and your new code, skip the:

Quoted 7 lines
Quoted 4 lines
	mce_wrmsrl(MSR_IA32_MCG_STATUS, 0);

which seems bad. That leaves MCG_STATUS.MCIP set ... so a second machine check would just reset the machine.

That's a good point. It goes away as an issue if we simply drop the check.

...and gone it is.

---
From: Borislav Petkov <[email protected]>
Date: Tue, 19 Jun 2018 12:27:02 +0200
Subject: [PATCH] x86/mce: Remove !banks check

If we don't have MCA banks, we won't see machine checks anyway. Drop the check.

---
 arch/x86/kernel/cpu/mcheck/mce.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
arch/x86/kernel/cpu/mcheck/mce.c +1 -4
index ea1521ec7e5b..05d2d15a95bd 100644
@@ -1185,9 +1185,6 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 
 	this_cpu_inc(mce_exception_count);
 
-	if (!cfg->banks)
-		goto out;
-
 	mce_gather_info(&m, regs);
 	m.tsc = rdtsc();
 
@@ -1327,7 +1324,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 	if (worst > 0)
 		mce_report_event(regs);
 	mce_wrmsrl(MSR_IA32_MCG_STATUS, 0);
-out:
+
 	sync_core();
 
 	if (worst != MCE_AR_SEVERITY && !kill_it)
Signature · 4 lines
2.17.0.582.gccdcbd54c

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 
#13 lore raw

Re: [PATCH 2/3] x86/mce: Fix incorrect "Machine check from unknown source" message

In reply to Borislav Petkov
Quoted 12 lines · Borislav Petkov
Quoted 11 lines · Tony Luck
arch/x86/kernel/cpu/mcheck/mce.c +5 -2
@@ -1287,12 +1292,17 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 			no_way_out = worst >= MCE_PANIC_SEVERITY;
 	} else {
 		/*
-		 * Local MCE skipped calling mce_reign()
-		 * If we found a fatal error, we need to panic here.
+		 * If there was a fatal machine check we should have
+		 * already called mce_panic earlier in this function.
+		 * Since we re-read the banks, we might have found
+		 * something new. Check again to see if we found a
+		 * fatal error. We call "mce_severity()" again to
Quoted 8 lines

arch/x86/kernel/cpu/mcheck/mce.c void do_machine_check(struct pt_regs *regs, long error_code) · line 1304

Quoted 8 lines
arch/x86/kernel/cpu/mcheck/mce.c +4 -3
+		 * make sure we have the right "msg".
 		 */
-		 if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)
-			mce_panic("Machine check from unknown source",
-				NULL, NULL);
+		if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) {
+			severity = mce_severity(&m, cfg->tolerant, &msg, true);
+			mce_panic("Local fatal machine check!", &m, msg);

If this doesn't affect mcelog parsing, would it make sense to change this from "fatal" -> "Unrecoverable".. Fatal typically screams PCC=1 for x86, but some of these cases are its Software recoverable, but just that Kernel isn't able to perform recovery.

Quoted 20 lines

Haha, this would still make you look at the code to remember was it "fatal local" or "local fatal" the second one. Yeah, there's the "!" but still.

How about:

"Fatal local machine check after banks scan"

or so.

Btw, the code in do_machine_check() has become one helluva spaghetti mess. It could use some clean up a bit... :)

Signature · 5 lines
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 
#14 lore raw

Re: [PATCH 2/3] x86/mce: Fix incorrect "Machine check from unknown source" message

In reply to Tony Luck
Quoted 8 lines · Tony Luck
arch/x86/kernel/cpu/mcheck/mce.c +2 -2
@@ -1287,12 +1292,17 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 			no_way_out = worst >= MCE_PANIC_SEVERITY;
 	} else {
 		/*
-		 * Local MCE skipped calling mce_reign()
-		 * If we found a fatal error, we need to panic here.
+		 * If there was a fatal machine check we should have
+		 * already called mce_panic earlier in this function.

arch/x86/kernel/cpu/mcheck/mce.c void do_machine_check(struct pt_regs *regs, long error_code) · line 1303

Quoted 10 lines
arch/x86/kernel/cpu/mcheck/mce.c +6 -3
+		 * Since we re-read the banks, we might have found
+		 * something new. Check again to see if we found a
+		 * fatal error. We call "mce_severity()" again to
+		 * make sure we have the right "msg".
 		 */
-		 if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)
-			mce_panic("Machine check from unknown source",
-				NULL, NULL);
+		if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) {
+			severity = mce_severity(&m, cfg->tolerant, &msg, true);

Looking at this more while cleaning the whole thing up, that severity doesn't get read anywhere past this line, AFAICT...

Signature · 5 lines
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 
author maintainer
#15 lore raw

Re: [PATCH 2/3] x86/mce: Fix incorrect "Machine check from unknown source" message

Quoted 11 lines · Borislav Petkov

arch/x86/kernel/cpu/mcheck/mce.c void do_machine_check(struct pt_regs *regs, long error_code) · line 1303

Quoted 8 lines
arch/x86/kernel/cpu/mcheck/mce.c +4 -3
+		 * fatal error. We call "mce_severity()" again to
+		 * make sure we have the right "msg".
 		 */
-		 if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)
-			mce_panic("Machine check from unknown source",
-				NULL, NULL);
+		if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) {
+			severity = mce_severity(&m, cfg->tolerant, &msg, true);

Looking at this more while cleaning the whole thing up, that severity doesn't get read anywhere past this line, AFAICT...

Just making the call to update "msg" (see comment). But you are right that we don't need to update the severity variable. I'll fix that in the re-spin to make the messages more than slightly different.

-Tony

#16 lore raw

[tip:ras/core] x86/mce: Fix incorrect "Machine check from unknown source" message

In reply to Tony Luck
x86/mce: Fix incorrect "Machine check from unknown source" message
Commit-ID:  40c36e2741d7fe1e66d6ec55477ba5fd19c9c5d2
Gitweb:     https://git.kernel.org/tip/40c36e2741d7fe1e66d6ec55477ba5fd19c9c5d2
Author:     Tony Luck <[email protected]>
AuthorDate: Fri, 22 Jun 2018 11:54:23 +0200
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Fri, 22 Jun 2018 14:35:50 +0200

x86/mce: Fix incorrect "Machine check from unknown source" message

Some injection testing resulted in the following console log:

mce: [Hardware Error]: CPU 22: Machine Check Exception: f Bank 1: bd80000000100134
mce: [Hardware Error]: RIP 10:<ffffffffc05292dd> {pmem_do_bvec+0x11d/0x330 [nd_pmem]}
mce: [Hardware Error]: TSC c51a63035d52 ADDR 3234bc4000 MISC 88
mce: [Hardware Error]: PROCESSOR 0:50654 TIME 1526502199 SOCKET 0 APIC 38 microcode 2000043
mce: [Hardware Error]: Run the above through 'mcelog --ascii'

  Kernel panic - not syncing: Machine check from unknown source

This confused everybody because the first line quite clearly shows that we found a logged error in "Bank 1", while the last line says "unknown source".

The problem is that the Linux code doesn't do the right thing for a local machine check that results in a fatal error.

It turns out that we know very early in the handler whether the machine check is fatal. The call to mce_no_way_out() has checked all the banks for the CPU that took the local machine check. If it says we must crash, we can do so right away with the right messages.

We do scan all the banks again. This means that we might initially not see a problem, but during the second scan find something fatal. If this happens we print a slightly different message (so I can see if it actually every happens).

[ bp: Remove unneeded severity assignment. ]

---
 arch/x86/kernel/cpu/mcheck/mce.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-edac" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

arch/x86/kernel/cpu/mcheck/mce.c +18 -8
index 7e6f51a9d917..e93670d736a6 100644
@@ -1207,13 +1207,18 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 		lmce = m.mcgstatus & MCG_STATUS_LMCES;
 
 	/*
+	 * Local machine check may already know that we have to panic.
+	 * Broadcast machine check begins rendezvous in mce_start()
 	 * Go through all banks in exclusion of the other CPUs. This way we
 	 * don't report duplicated events on shared banks because the first one
-	 * to see it will clear it. If this is a Local MCE, then no need to
-	 * perform rendezvous.
+	 * to see it will clear it.
 	 */
-	if (!lmce)
+	if (lmce) {
+		if (no_way_out)
+			mce_panic("Fatal local machine check", &m, msg);
+	} else {
 		order = mce_start(&no_way_out);
+	}
 
 	for (i = 0; i < cfg->banks; i++) {
 		__clear_bit(i, toclear);
@@ -1289,12 +1294,17 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 			no_way_out = worst >= MCE_PANIC_SEVERITY;
 	} else {
 		/*
-		 * Local MCE skipped calling mce_reign()
-		 * If we found a fatal error, we need to panic here.
+		 * If there was a fatal machine check we should have
+		 * already called mce_panic earlier in this function.
+		 * Since we re-read the banks, we might have found
+		 * something new. Check again to see if we found a
+		 * fatal error. We call "mce_severity()" again to
+		 * make sure we have the right "msg".
 		 */
-		 if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3)
-			mce_panic("Machine check from unknown source",
-				NULL, NULL);
+		if (worst >= MCE_PANIC_SEVERITY && mca_cfg.tolerant < 3) {
+			mce_severity(&m, cfg->tolerant, &msg, true);
+			mce_panic("Local fatal machine check!", &m, msg);
+		}
 	}
 
 	/*
author maintainer
#17 lore raw

PATCH 3/3 x86/mce: Check for alternate indication of machine check recovery on Skylake

In reply to Tony Luck

Currently we just check the "CAPID0" register to see whether the CPU can recover from machine checks.

But there are also some special SKUs which do not have all advanced RAS features, but do enable machine check recovery for use with NVDIMMs.

Add a check for any of bits {8:5} in the "CAPID5" register (each reports some NVDIMM mode available, if any of them are set, then the system supports memory machine check recovery).

---
 arch/x86/kernel/quirks.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
arch/x86/kernel/quirks.c +9 -2
index 697a4ce04308..736348ead421 100644
@@ -645,12 +645,19 @@ static void quirk_intel_brickland_xeon_ras_cap(struct pci_dev *pdev)
 /* Skylake */
 static void quirk_intel_purley_xeon_ras_cap(struct pci_dev *pdev)
 {
-	u32 capid0;
+	u32 capid0, capid5;
 
 	pci_read_config_dword(pdev, 0x84, &capid0);
+	pci_read_config_dword(pdev, 0x98, &capid5);
 
-	if ((capid0 & 0xc0) == 0xc0)
+	/*
+	 * CAPID0{7:6} indicate whether this is an advanced RAS SKU
+	 * CAPID5{8:5} indicate that various NVDIMM usage modes are
+	 * enabled, so memory machine check recovery is also enabled.
+	 */
+	if ((capid0 & 0xc0) == 0xc0 || (capid5 & 0x1e0))
 		static_branch_inc(&mcsafe_key);
+
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0ec3, quirk_intel_brickland_xeon_ras_cap);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2fc0, quirk_intel_brickland_xeon_ras_cap);
Signature · 1 line
2.17.0
author maintainer
#18 lore raw

Re: [PATCH 3/3] x86/mce: Check for alternate indication of machine check recovery on Skylake

Quoted 6 lines · Tony Luck

Currently we just check the "CAPID0" register to see whether the CPU can recover from machine checks.

But there are also some special SKUs which do not have all advanced RAS features, but do enable machine check recovery for use with NVDIMMs.

Quoted 7 lines

Add a check for any of bits {8:5} in the "CAPID5" register (each reports some NVDIMM mode available, if any of them are set, then the system supports memory machine check recovery).

---

Has this stalled somewhere? I'd like to see this one go into the 4.18 merge because it unbreaks some real hardware.

Parts 1 & 2 are nice-to-have, but they just make for better error messages so aren't as critical.

Quoted 32 lines
 arch/x86/kernel/quirks.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
arch/x86/kernel/quirks.c +9 -2
index 697a4ce04308..736348ead421 100644
@@ -645,12 +645,19 @@ static void quirk_intel_brickland_xeon_ras_cap(struct pci_dev *pdev)
 /* Skylake */
 static void quirk_intel_purley_xeon_ras_cap(struct pci_dev *pdev)
 {
-	u32 capid0;
+	u32 capid0, capid5;
 
 	pci_read_config_dword(pdev, 0x84, &capid0);
+	pci_read_config_dword(pdev, 0x98, &capid5);
 
-	if ((capid0 & 0xc0) == 0xc0)
+	/*
+	 * CAPID0{7:6} indicate whether this is an advanced RAS SKU
+	 * CAPID5{8:5} indicate that various NVDIMM usage modes are
+	 * enabled, so memory machine check recovery is also enabled.
+	 */
+	if ((capid0 & 0xc0) == 0xc0 || (capid5 & 0x1e0))
 		static_branch_inc(&mcsafe_key);
+
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0ec3, quirk_intel_brickland_xeon_ras_cap);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2fc0, quirk_intel_brickland_xeon_ras_cap);
Signature · 1 line
2.17.0
#19 lore raw

Re: [PATCH 3/3] x86/mce: Check for alternate indication of machine check recovery on Skylake

Quoted 15 lines · Tony
Quoted 6 lines · Tony Luck

Currently we just check the "CAPID0" register to see whether the CPU can recover from machine checks.

But there are also some special SKUs which do not have all advanced RAS features, but do enable machine check recovery for use with NVDIMMs.

Quoted 7 lines

Add a check for any of bits {8:5} in the "CAPID5" register (each reports some NVDIMM mode available, if any of them are set, then the system supports memory machine check recovery).

---

Quoted 5 lines

Has this stalled somewhere? I'd like to see this one go into the 4.18 merge because it unbreaks some real hardware.

Parts 1 & 2 are nice-to-have, but they just make for better error messages so aren't as critical.

I'm making an effort to get all persistent memory error handling holes covered this cycle, so I think it makes sense for this to go through the nvdimm tree. This looks sufficiently non-controversial that I could justify sending it to Linus along with the other pmem updates.

#20 lore raw

Re: [PATCH 3/3] x86/mce: Check for alternate indication of machine check recovery on Skylake

Quoted 4 lines · Dan Williams

I'm making an effort to get all persistent memory error handling holes covered this cycle, so I think it makes sense for this to go through the nvdimm tree. This looks sufficiently non-controversial that I could justify sending it to Linus along with the other pmem updates.

tglx just took 1 and 3, 2/3 had a minor issue but the merge window happened so I'll send it later. It is nice to have anyway.

Signature · 5 lines
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 
author maintainer
#21 lore raw

Re: [PATCH 3/3] x86/mce: Check for alternate indication of machine check recovery on Skylake

Quoted 8 lines · Borislav Petkov
Quoted 4 lines · Dan Williams

I'm making an effort to get all persistent memory error handling holes covered this cycle, so I think it makes sense for this to go through the nvdimm tree. This looks sufficiently non-controversial that I could justify sending it to Linus along with the other pmem updates.

tglx just took 1 and 3, 2/3 had a minor issue but the merge window happened so I'll send it later. It is nice to have anyway.

Thanks Boris.

-Tony

author maintainer
#22 lore raw

Re: [PATCH 3/3] x86/mce: Check for alternate indication of machine check recovery on Skylake

In reply to Borislav Petkov
Quoted 2 lines · Borislav Petkov

tglx just took 1 and 3, 2/3 had a minor issue but the merge window happened so I'll send it later. It is nice to have anyway.

Did you fix up part 2/3? I see 1 & 3 were staged by Thomas in TIP ras/urgent and ras-urgent-for-linus but haven't gone into Linus' tree yet.

-Tony

#23 lore raw

Re: [PATCH 3/3] x86/mce: Check for alternate indication of machine check recovery on Skylake

Quoted 5 lines · Tony
Quoted 2 lines · Borislav Petkov

tglx just took 1 and 3, 2/3 had a minor issue but the merge window happened so I'll send it later. It is nice to have anyway.

Did you fix up part 2/3?

You said "Parts 1 & 2 are nice-to-have" and we have merge window now. So what exactly do you mean?

Quoted 2 lines

I see 1 & 3 were staged by Thomas in TIP ras/urgent and ras-urgent-for-linus but haven't gone into Linus' tree yet.

Merge window ain't over yet :)

Signature · 5 lines
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 
author maintainer
#24 lore raw

Re: [PATCH 3/3] x86/mce: Check for alternate indication of machine check recovery on Skylake

Quoted 7 lines · Borislav Petkov
Quoted 5 lines · Tony
Quoted 2 lines · Borislav Petkov

tglx just took 1 and 3, 2/3 had a minor issue but the merge window happened so I'll send it later. It is nice to have anyway.

Did you fix up part 2/3?

Quoted 7 lines

You said "Parts 1 & 2 are nice-to-have" and we have merge window now. So what exactly do you mean?

Quoted 2 lines

I see 1 & 3 were staged by Thomas in TIP ras/urgent and ras-urgent-for-linus but haven't gone into Linus' tree yet.

Merge window ain't over yet :)

"send it later" could be read a couple of ways.

I was just worried that Thomas is holding off asking Linus to pull because he's waiting for part 2/3, while you might be planning to hold onto part 2/3 for the next merge (and add the other cleanups you RFC'd).

I'm OK either way on part 2/3 (it just makes for better error messages, it doesn't fix any bugs).

-Tony

#25 lore raw

Re: [PATCH 3/3] x86/mce: Check for alternate indication of machine check recovery on Skylake

Quoted 7 lines · Tony

I was just worried that Thomas is holding off asking Linus to pull because he's waiting for part 2/3, while you might be planning to hold onto part 2/3 for the next merge (and add the other cleanups you RFC'd).

I'm OK either way on part 2/3 (it just makes for better error messages, it doesn't fix any bugs).

Yes, and this is my understanding too - 2/3 is not urgent material so no need to hurry that particular one.

Signature · 5 lines
Regards/Gruss,
    Boris.

SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- 
#26 lore raw

Re: [PATCH 3/3] x86/mce: Check for alternate indication of machine check recovery on Skylake

In reply to Dan Williams
Quoted 19 lines · Dan Williams
Quoted 18 lines · Tony
Quoted 6 lines · Tony Luck

Currently we just check the "CAPID0" register to see whether the CPU can recover from machine checks.

But there are also some special SKUs which do not have all advanced RAS features, but do enable machine check recovery for use with NVDIMMs.

Quoted 7 lines

Add a check for any of bits {8:5} in the "CAPID5" register (each reports some NVDIMM mode available, if any of them are set, then the system supports memory machine check recovery).

---

Has this stalled somewhere? I'd like to see this one go into the 4.18 merge because it unbreaks some real hardware.

Quoted 7 lines
Quoted 2 lines

Parts 1 & 2 are nice-to-have, but they just make for better error messages so aren't as critical.

I'm making an effort to get all persistent memory error handling holes covered this cycle, so I think it makes sense for this to go through the nvdimm tree. This looks sufficiently non-controversial that I could justify sending it to Linus along with the other pmem updates.

I've picked it up already and please can we let stuff go through the right trees? The worlds does not stop turning if a fix goes in 2 days later.

Thanks,

tglx

#27 lore raw

[tip:ras/urgent] x86/mce: Check for alternate indication of machine check recovery on Skylake

In reply to Tony Luck
x86/mce: Check for alternate indication of machine check recovery on Skylake
Commit-ID:  4c5717da1d021cf368eabb3cb1adcaead56c0d1e
Gitweb:     https://git.kernel.org/tip/4c5717da1d021cf368eabb3cb1adcaead56c0d1e
Author:     Tony Luck <[email protected]>
AuthorDate: Fri, 25 May 2018 14:42:09 -0700
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Thu, 7 Jun 2018 22:22:12 +0200

x86/mce: Check for alternate indication of machine check recovery on Skylake

Currently we just check the "CAPID0" register to see whether the CPU can recover from machine checks.

But there are also some special SKUs which do not have all advanced RAS features, but do enable machine check recovery for use with NVDIMMs.

Add a check for any of bits {8:5} in the "CAPID5" register (each reports some NVDIMM mode available, if any of them are set, then the system supports memory machine check recovery).

---
 arch/x86/kernel/quirks.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)
arch/x86/kernel/quirks.c +9 -2
index 697a4ce04308..736348ead421 100644
@@ -645,12 +645,19 @@ static void quirk_intel_brickland_xeon_ras_cap(struct pci_dev *pdev)
 /* Skylake */
 static void quirk_intel_purley_xeon_ras_cap(struct pci_dev *pdev)
 {
-	u32 capid0;
+	u32 capid0, capid5;
 
 	pci_read_config_dword(pdev, 0x84, &capid0);
+	pci_read_config_dword(pdev, 0x98, &capid5);
 
-	if ((capid0 & 0xc0) == 0xc0)
+	/*
+	 * CAPID0{7:6} indicate whether this is an advanced RAS SKU
+	 * CAPID5{8:5} indicate that various NVDIMM usage modes are
+	 * enabled, so memory machine check recovery is also enabled.
+	 */
+	if ((capid0 & 0xc0) == 0xc0 || (capid5 & 0x1e0))
 		static_branch_inc(&mcsafe_key);
+
 }
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0ec3, quirk_intel_brickland_xeon_ras_cap);
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2fc0, quirk_intel_brickland_xeon_ras_cap);