Skip to contentSkip to conversation

x86, mce: machine check recovery for applications

PATCH In review Tony Luck 5 participants 22 messages Dec 13, 2011 – Dec 16, 2011

Subsystems (7)
lore
Share & tools
lore

Tony Luck

author
#0 lore raw

cover x86, mce: machine check recovery for applications

Yet another version ...

Some bits should look familiar (hopefully pieces that were not too controversial from earlier versions). Other bits are all new (e.g. part 4/6 which sets up some functions that can safely save away the physical address of the faulting address in the machine check handler for later retrieval in a safer execution context).

Tony Luck (6):
HWPOISON: clean up memory_failure() vs. __memory_failure()
HWPOISON: Add code to handle "action required" errors. x86, mce: create helper function to save addr/misc when needed x86, mce: Add mechanism to safely save information in MCE handler x86, mce: handle "action required" errors
x86, mce: Recognise machine check bank signature for data path error

 arch/x86/kernel/cpu/mcheck/mce-severity.c |   14 +++-
 arch/x86/kernel/cpu/mcheck/mce.c          |  153 ++++++++++++++++++++++-------
 drivers/base/memory.c                     |    2 +-
 include/linux/mm.h                        |    4 +-
 mm/hwpoison-inject.c                      |    4 +-
 mm/madvise.c                              |    2 +-
 mm/memory-failure.c                       |   96 ++++++++++---------
 7 files changed, 186 insertions(+), 89 deletions(-)
Signature · 1 line
1.7.3.1
author
#1 lore raw

PATCH 1/6 HWPOISON: clean up memory_failure() vs. __memory_failure()

There is only one caller of memory_failure(), all other users call __memory_failure() and pass in the flags argument explicitly. The lone user of memory_failure() will soon need to pass flags too.

Add flags argument to the callsite in mce.c. Delete the old memory_failure() function, and then rename __memory_failure() without the leading "__".

---
 arch/x86/kernel/cpu/mcheck/mce.c |    9 +++++--
 drivers/base/memory.c            |    2 +-
 include/linux/mm.h               |    3 +-
 mm/hwpoison-inject.c             |    4 +-
 mm/madvise.c                     |    2 +-
 mm/memory-failure.c              |   46 +++++++++++++++++--------------------
 6 files changed, 32 insertions(+), 34 deletions(-)
arch/x86/kernel/cpu/mcheck/mce.c +6 -3
index 2af127d..265139d 100644
@@ -1046,11 +1046,14 @@ out:
 }
 EXPORT_SYMBOL_GPL(do_machine_check);
 
-/* dummy to break dependency. actual code is in mm/memory-failure.c */
-void __attribute__((weak)) memory_failure(unsigned long pfn, int vector)
+#ifndef CONFIG_MEMORY_FAILURE
+int memory_failure(unsigned long pfn, int vector, int flags)
 {
 	printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn);
+
+	return 0;
 }
+#endif
 
 /*
  * Called after mce notification in process context. This code
@@ -1068,7 +1071,7 @@ void mce_notify_process(void)
 	unsigned long pfn;
 	mce_notify_irq();
 	while (mce_ring_get(&pfn))
-		memory_failure(pfn, MCE_VECTOR);
+		memory_failure(pfn, MCE_VECTOR, 0);
 }
 
 static void mce_process_work(struct work_struct *dummy)
drivers/base/memory.c +1 -1
index 8272d92..9a92444 100644
@@ -474,7 +474,7 @@ store_hard_offline_page(struct class *class,
 	if (strict_strtoull(buf, 0, &pfn) < 0)
 		return -EINVAL;
 	pfn >>= PAGE_SHIFT;
-	ret = __memory_failure(pfn, 0, 0);
+	ret = memory_failure(pfn, 0, 0);
 	return ret ? ret : count;
 }
 
include/linux/mm.h +1 -2
index 4baadd1..bcc5234 100644
@@ -1607,8 +1607,7 @@ void vmemmap_populate_print_last(void);
 enum mf_flags {
 	MF_COUNT_INCREASED = 1 << 0,
 };
-extern void memory_failure(unsigned long pfn, int trapno);
-extern int __memory_failure(unsigned long pfn, int trapno, int flags);
+extern int memory_failure(unsigned long pfn, int trapno, int flags);
 extern void memory_failure_queue(unsigned long pfn, int trapno, int flags);
 extern int unpoison_memory(unsigned long pfn);
 extern int sysctl_memory_failure_early_kill;
mm/hwpoison-inject.c +2 -2
index c7fc7fd..cc448bb 100644
@@ -45,7 +45,7 @@ static int hwpoison_inject(void *data, u64 val)
 	 * do a racy check with elevated page count, to make sure PG_hwpoison
 	 * will only be set for the targeted owner (or on a free page).
 	 * We temporarily take page lock for try_get_mem_cgroup_from_page().
-	 * __memory_failure() will redo the check reliably inside page lock.
+	 * memory_failure() will redo the check reliably inside page lock.
 	 */
 	lock_page(hpage);
 	err = hwpoison_filter(hpage);
@@ -55,7 +55,7 @@ static int hwpoison_inject(void *data, u64 val)
 
 inject:
 	printk(KERN_INFO "Injecting memory failure at pfn %lx\n", pfn);
-	return __memory_failure(pfn, 18, MF_COUNT_INCREASED);
+	return memory_failure(pfn, 18, MF_COUNT_INCREASED);
 }
 
 static int hwpoison_unpoison(void *data, u64 val)
mm/madvise.c +1 -1
index 74bf193..f5ab745 100644
@@ -251,7 +251,7 @@ static int madvise_hwpoison(int bhv, unsigned long start, unsigned long end)
 		printk(KERN_INFO "Injecting memory failure for page %lx at %lx\n",
 		       page_to_pfn(p), start);
 		/* Ignore return value for now */
-		__memory_failure(page_to_pfn(p), 0, MF_COUNT_INCREASED);
+		memory_failure(page_to_pfn(p), 0, MF_COUNT_INCREASED);
 	}
 	return ret;
 }
mm/memory-failure.c +21 -25

64 lines not on this page · raw message

Signature · 1 line
1.7.3.1
#2 lore raw

Re: [PATCH 1/6] HWPOISON: clean up memory_failure() vs. __memory_failure()

Quoted 22 lines · Tony Luck

There is only one caller of memory_failure(), all other users call __memory_failure() and pass in the flags argument explicitly. The lone user of memory_failure() will soon need to pass flags too.

Add flags argument to the callsite in mce.c. Delete the old memory_failure() function, and then rename __memory_failure() without the leading "__".

---
 arch/x86/kernel/cpu/mcheck/mce.c |    9 +++++--
 drivers/base/memory.c            |    2 +-
 include/linux/mm.h               |    3 +-
 mm/hwpoison-inject.c             |    4 +-
 mm/madvise.c                     |    2 +-
 mm/memory-failure.c              |   46 +++++++++++++++++--------------------
 6 files changed, 32 insertions(+), 34 deletions(-)
arch/x86/kernel/cpu/mcheck/mce.c +0 -0
index 2af127d..265139d 100644

arch/x86/kernel/cpu/mcheck/mce.c out: · line 1052

Quoted 9 lines
arch/x86/kernel/cpu/mcheck/mce.c +2 -2
@@ -1046,11 +1046,14 @@ out:
 }
 EXPORT_SYMBOL_GPL(do_machine_check);
 
-/* dummy to break dependency. actual code is in mm/memory-failure.c */
-void __attribute__((weak)) memory_failure(unsigned long pfn, int vector)
+#ifndef CONFIG_MEMORY_FAILURE
+int memory_failure(unsigned long pfn, int vector, int flags)
 {
 	printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn);

Btw., while at it, could we phrase this message in a more obvious way to users, such as 'Non-fatal memory failure at %lx ignored'?

Thanks,

Ingo

#3 lore raw

Re: [PATCH 1/6] HWPOISON: clean up memory_failure() vs. __memory_failure()

Quoted 10 lines · Ingo Molnar

arch/x86/kernel/cpu/mcheck/mce.c out: · line 1052

Quoted 6 lines
arch/x86/kernel/cpu/mcheck/mce.c +2 -2
-/* dummy to break dependency. actual code is in mm/memory-failure.c */
-void __attribute__((weak)) memory_failure(unsigned long pfn, int vector)
+#ifndef CONFIG_MEMORY_FAILURE
+int memory_failure(unsigned long pfn, int vector, int flags)
 {
 	printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn);

Btw., while at it, could we phrase this message in a more obvious way to users, such as 'Non-fatal memory failure at %lx ignored'?

Yeah, that's might not be as correct as we want it to be. AO means it is an uncorrectable error, i.e. it will become fatal if we'd consumed it, but it isn't that now because we just saw it passing by in the cacheline...

Maybe "Fatal, unconsumed error ignored..."

Signature · 8 lines
Regards/Gruss,
Boris.

Advanced Micro Devices GmbH
Einsteinring 24, 85609 Dornach
GM: Alberto Bozzo
Reg: Dornach, Landkreis Muenchen
HRB Nr. 43632 WEEE Registernr: 129 19551
#4 lore raw

Re: [PATCH 1/6] HWPOISON: clean up memory_failure() vs. __memory_failure()

Quoted 12 lines · Borislav Petkov
Quoted 10 lines · Ingo Molnar

arch/x86/kernel/cpu/mcheck/mce.c out: · line 1052

Quoted 6 lines
arch/x86/kernel/cpu/mcheck/mce.c +2 -2
-/* dummy to break dependency. actual code is in mm/memory-failure.c */
-void __attribute__((weak)) memory_failure(unsigned long pfn, int vector)
+#ifndef CONFIG_MEMORY_FAILURE
+int memory_failure(unsigned long pfn, int vector, int flags)
 {
 	printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn);

Btw., while at it, could we phrase this message in a more obvious way to users, such as 'Non-fatal memory failure at %lx ignored'?

Quoted 6 lines

Yeah, that's might not be as correct as we want it to be. AO means it is an uncorrectable error, i.e. it will become fatal if we'd consumed it, but it isn't that now because we just saw it passing by in the cacheline...

Maybe "Fatal, unconsumed error ignored..."

There's also the distinction that tells us which context is affected by an error: the currently executing task/mm, or some other one.

So you can keep the terminology i guess lacking a better alternative, i just wanted to point out that it's likely confusing to users.

Thanks,

Ingo

author
#5 lore raw

RE: [PATCH 1/6] HWPOISON: clean up memory_failure() vs. __memory_failure()

Quoted 6 lines
Quoted 5 lines
Quoted 1 line

printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn);

Btw., while at it, could we phrase this message in a more obvious way to users, such as 'Non-fatal memory failure at %lx ignored'?

Quoted 6 lines

Yeah, that's might not be as correct as we want it to be. AO means it is an uncorrectable error, i.e. it will become fatal if we'd consumed it, but it isn't that now because we just saw it passing by in the cacheline...

Maybe "Fatal, unconsumed error ignored..."

The overall meaning is "land mine seen but not stepped on yet"

I'll see if I can wordsmith the message to convey that.

-Tony

#6 lore raw

Re: [PATCH 1/6] HWPOISON: clean up memory_failure() vs. __memory_failure()

Quoted 6 lines · Luck, Tony
Quoted 6 lines
Quoted 5 lines
Quoted 1 line

printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn);

Btw., while at it, could we phrase this message in a more obvious way to users, such as 'Non-fatal memory failure at %lx ignored'?

Quoted 8 lines
Quoted 6 lines

Yeah, that's might not be as correct as we want it to be. AO means it is an uncorrectable error, i.e. it will become fatal if we'd consumed it, but it isn't that now because we just saw it passing by in the cacheline...

Maybe "Fatal, unconsumed error ignored..."

The overall meaning is "land mine seen but not stepped on yet"

Perfect message!

Thanks,

Ingo

author
#7 lore raw

Re: [PATCH 1/6] HWPOISON: clean up memory_failure() vs. __memory_failure()

Quoted 3 lines · Ingo Molnar
Quoted 1 line

The overall meaning is "land mine seen but not stepped on yet"

Perfect message!

How about:

Uncorrected memory error in page 0x%lx ignored
Rebuild kernel with CONFIG_MEMORY_FAILURE=y for smarter handling

-Tony

#8 lore raw

Re: [PATCH 1/6] HWPOISON: clean up memory_failure() vs. __memory_failure()

Quoted 9 lines · Tony Luck
Quoted 3 lines · Ingo Molnar
Quoted 1 line

The overall meaning is "land mine seen but not stepped on yet"

Perfect message!

How about:

Uncorrected memory error in page 0x%lx ignored
Rebuild kernel with CONFIG_MEMORY_FAILURE=y for smarter handling

Yeah, sounds good.

Thanks,

Ingo

author
#9 lore raw

PATCH 2/6 HWPOISON: Add code to handle "action required" errors.

In reply to Tony Luck

Add new flag bit "MF_ACTION_REQUIRED" to be used by machine check code to force a signal with si_code = BUS_MCEERR_AR in the case where the error occurs in processor execution context. Pass the flags argument along call chain:

	memory_failure()
	  hwpoison_user_mappings()
	    kill_procs()
	      kill_proc()

Drop the "_ao" suffix from kill_procs_ao() and kill_proc_ao() since they can now handle "action required" as well as "action optional" errors.

---
 include/linux/mm.h  |    1 +
 mm/memory-failure.c |   50 +++++++++++++++++++++++++++++---------------------
 2 files changed, 30 insertions(+), 21 deletions(-)
include/linux/mm.h +1 -0
index bcc5234..bf169ca 100644
@@ -1606,6 +1606,7 @@ void vmemmap_populate_print_last(void);
 
 enum mf_flags {
 	MF_COUNT_INCREASED = 1 << 0,
+	MF_ACTION_REQUIRED = 1 << 1,
 };
 extern int memory_failure(unsigned long pfn, int trapno, int flags);
 extern void memory_failure_queue(unsigned long pfn, int trapno, int flags);
mm/memory-failure.c +29 -21

100 lines not on this page · raw message

Signature · 1 line
1.7.3.1
author
#10 lore raw

PATCH 3/6 x86, mce: create helper function to save addr/misc when needed

In reply to Tony Luck

The MCI_STATUS_MISCV and MCI_STATUS_ADDRV bits in the bank status registers define whether the MISC and ADDR registers respectively contain valid data - provide a helper function to check these bits and read the registers when needed.

In addition, processors that support software error recovery (as indicated by the MCG_SER_P bit in the MCG_CAP register) may include some undefined bits in the ADDR register - mask these out.

---
 arch/x86/kernel/cpu/mcheck/mce.c |   31 +++++++++++++++++++++++--------
 1 files changed, 23 insertions(+), 8 deletions(-)
arch/x86/kernel/cpu/mcheck/mce.c +23 -8
index 265139d..43f22c8 100644
@@ -492,6 +492,27 @@ static void mce_report_event(struct pt_regs *regs)
 	irq_work_queue(&__get_cpu_var(mce_irq_work));
 }
 
+/*
+ * Read ADDR and MISC registers.
+ */
+static void mce_read_aux(struct mce *m, int i)
+{
+	if (m->status & MCI_STATUS_MISCV)
+		m->misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
+	if (m->status & MCI_STATUS_ADDRV) {
+		m->addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
+
+		/*
+		 * Mask the reported address by the reported granularity.
+		 */
+		if (mce_ser && (m->status & MCI_STATUS_MISCV)) {
+			u8 shift = m->misc & 0x3f;
+			m->addr >>= shift;
+			m->addr <<= shift;
+		}
+	}
+}
+
 DEFINE_PER_CPU(unsigned, mce_poll_count);
 
 /*
@@ -542,10 +563,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
 		    (m.status & (mce_ser ? MCI_STATUS_S : MCI_STATUS_UC)))
 			continue;
 
-		if (m.status & MCI_STATUS_MISCV)
-			m.misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
-		if (m.status & MCI_STATUS_ADDRV)
-			m.addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
+		mce_read_aux(&m, i);
 
 		if (!(flags & MCP_TIMESTAMP))
 			m.tsc = 0;
@@ -981,10 +999,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 		if (severity == MCE_AR_SEVERITY)
 			kill_it = 1;
 
-		if (m.status & MCI_STATUS_MISCV)
-			m.misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
-		if (m.status & MCI_STATUS_ADDRV)
-			m.addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
+		mce_read_aux(&m, i);
 
 		/*
 		 * Action optional error. Queue address for later processing.
Signature · 1 line
1.7.3.1
#11 lore raw

Re: [PATCH 3/6] x86, mce: create helper function to save addr/misc when needed

Quoted 13 lines · Tony Luck
arch/x86/kernel/cpu/mcheck/mce.c +5 -0
index 265139d..43f22c8 100644
@@ -492,6 +492,27 @@ static void mce_report_event(struct pt_regs *regs)
 	irq_work_queue(&__get_cpu_var(mce_irq_work));
 }
 
+/*
+ * Read ADDR and MISC registers.
+ */
+static void mce_read_aux(struct mce *m, int i)
+{

arch/x86/kernel/cpu/mcheck/mce.c static void mce_report_event(struct pt_regs *regs) · line 509

Quoted 10 lines
arch/x86/kernel/cpu/mcheck/mce.c +10 -0
+	if (m->status & MCI_STATUS_MISCV)
+		m->misc = mce_rdmsrl(MSR_IA32_MCx_MISC(i));
+	if (m->status & MCI_STATUS_ADDRV) {
+		m->addr = mce_rdmsrl(MSR_IA32_MCx_ADDR(i));
+
+		/*
+		 * Mask the reported address by the reported granularity.
+		 */
+		if (mce_ser && (m->status & MCI_STATUS_MISCV)) {
+			u8 shift = m->misc & 0x3f;

(nitpick) You can use:

#define MCI_MISC_ADDR_LSB(m) ((m) & 0x3f)

arch/x86/kernel/cpu/mcheck/mce.c static void mce_report_event(struct pt_regs *regs) · line 518

Quoted 9 lines
arch/x86/kernel/cpu/mcheck/mce.c +6 -0
+			m->addr >>= shift;
+			m->addr <<= shift;
+		}
+	}
+}
+
 DEFINE_PER_CPU(unsigned, mce_poll_count);
 
 /*

Thanks,
H.Seto

author
#12 lore raw

PATCH 4/6 x86, mce: Add mechanism to safely save information in MCE handler

In reply to Tony Luck

Machine checks on Intel cpus interrupt execution on all cpus, regardless of interrupt masking. We have a need to save some data about the cause of the machine check (physical address) in the machine check handler that can be retrieved later to attempt recovery in a more flexible execution state.

---
 arch/x86/kernel/cpu/mcheck/mce.c |   51 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 51 insertions(+), 0 deletions(-)
arch/x86/kernel/cpu/mcheck/mce.c +51 -0
index 43f22c8..9b83b7d 100644
@@ -887,6 +887,57 @@ static void mce_clear_state(unsigned long *toclear)
 }
 
 /*
+ * Need to save faulting physical address associated with a process
+ * in the machine check handler some place where we can grab it back
+ * later in mce_notify_process()
+ */
+#define	MAX_MCE_INFO	16
+struct mce_info {
+	atomic_t		inuse;
+	struct task_struct	*t;
+	__u64			paddr;
+} mce_info[MAX_MCE_INFO];
+
+static void mce_save_info(__u64 addr)
+{
+	int	i;
+
+	for (i = 0; i < MAX_MCE_INFO; i++)
+		if (atomic_cmpxchg(&mce_info[i].inuse, 0, 1) == 0) {
+			mce_info[i].t = current;
+			mce_info[i].paddr = addr;
+			return;
+		}
+
+	mce_panic("Too many concurrent recoverable errors", NULL, NULL);
+}
+
+static int mce_find_info(__u64 *paddr)
+{
+	int	i;
+
+	for (i = 0; i < MAX_MCE_INFO; i++)
+		if (atomic_read(&mce_info[i].inuse) &&
+		    mce_info[i].t == current) {
+			*paddr = mce_info[i].paddr;
+			return 1;
+		}
+	return 0;
+}
+
+static void mce_clear_info(void)
+{
+	int	i;
+
+	for (i = 0; i < MAX_MCE_INFO; i++)
+		if (atomic_read(&mce_info[i].inuse) &&
+		    mce_info[i].t == current) {
+			atomic_set(&mce_info[i].inuse, 0);
+			return;
+		}
+}
+
+/*
  * The actual machine check handler. This only handles real
  * exceptions when something got corrupted coming in through int 18.
  *
Signature · 1 line
1.7.3.1
#13 lore raw

Re: [PATCH 4/6] x86, mce: Add mechanism to safely save information in MCE handler

Quoted 10 lines · Tony Luck

Machine checks on Intel cpus interrupt execution on all cpus, regardless of interrupt masking. We have a need to save some data about the cause of the machine check (physical address) in the machine check handler that can be retrieved later to attempt recovery in a more flexible execution state.

---
 arch/x86/kernel/cpu/mcheck/mce.c |   51 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 51 insertions(+), 0 deletions(-)

Just some cleanliness nits:

Quoted 5 lines
arch/x86/kernel/cpu/mcheck/mce.c +0 -0
index 43f22c8..9b83b7d 100644

arch/x86/kernel/cpu/mcheck/mce.c static void mce_clear_state(unsigned long *toclear) · line 895

Quoted 9 lines
arch/x86/kernel/cpu/mcheck/mce.c +6 -0
@@ -887,6 +887,57 @@ static void mce_clear_state(unsigned long *toclear)
 }
 
 /*
+ * Need to save faulting physical address associated with a process
+ * in the machine check handler some place where we can grab it back
+ * later in mce_notify_process()
+ */
+#define	MAX_MCE_INFO	16
+struct mce_info {

please separate non-bulk definitons by newlines.

arch/x86/kernel/cpu/mcheck/mce.c static void mce_clear_state(unsigned long *toclear) · line 903

Quoted 8 lines
arch/x86/kernel/cpu/mcheck/mce.c +8 -0
+	atomic_t		inuse;
+	struct task_struct	*t;
+	__u64			paddr;
+} mce_info[MAX_MCE_INFO];
+
+static void mce_save_info(__u64 addr)
+{
+	int	i;

that tab looks weird. [there's repeat occurances further below as well]

arch/x86/kernel/cpu/mcheck/mce.c static void mce_clear_state(unsigned long *toclear) · line 910

Quoted 7 lines
arch/x86/kernel/cpu/mcheck/mce.c +7 -0
+
+	for (i = 0; i < MAX_MCE_INFO; i++)
+		if (atomic_cmpxchg(&mce_info[i].inuse, 0, 1) == 0) {
+			mce_info[i].t = current;
+			mce_info[i].paddr = addr;
+			return;
+		}

We typically use curly braces for all multi-line statements - so two would be needed above.

Quoted 14 lines
arch/x86/kernel/cpu/mcheck/mce.c +14 -0
+
+	mce_panic("Too many concurrent recoverable errors", NULL, NULL);
+}
+
+static int mce_find_info(__u64 *paddr)
+{
+	int	i;
+
+	for (i = 0; i < MAX_MCE_INFO; i++)
+		if (atomic_read(&mce_info[i].inuse) &&
+		    mce_info[i].t == current) {
+			*paddr = mce_info[i].paddr;
+			return 1;
+		}

arch/x86/kernel/cpu/mcheck/mce.c static void mce_clear_state(unsigned long *toclear) · line 934

Quoted 10 lines
arch/x86/kernel/cpu/mcheck/mce.c +10 -0
+	return 0;
+}
+
+static void mce_clear_info(void)
+{
+	int	i;
+
+	for (i = 0; i < MAX_MCE_INFO; i++)
+		if (atomic_read(&mce_info[i].inuse) &&
+		    mce_info[i].t == current) {

the line-break shows that the code has complexit troubles. Doing this in the loop iterator:

	struct mce_info *mi = mce_info + i;

would help make it shorter and more readable.

Thanks,

Ingo

author
#14 lore raw

PATCH 5/6 x86, mce: handle "action required" errors

In reply to Tony Luck

All non-urgent actions (reporting low severity errors and handling "action-optional" errors) are now handled by a work queue. This means that TIF_MCE_NOTIFY can be used to block execution for a thread experiencing an "action-required" fault until we get all cpus out of the machine check handler (and the thread that hit the fault into mce_notify_process().

We use the new mce_{save,find,clear}_info() API to get information from do_machine_check() to mce_notify_process(), and then use the newly improved memory_failure(..., MF_ACTION_REQUIRED) to handle the error (possibly signalling the process).

---
 arch/x86/kernel/cpu/mcheck/mce.c |   64 ++++++++++++++++++++++---------------
 1 files changed, 38 insertions(+), 26 deletions(-)
arch/x86/kernel/cpu/mcheck/mce.c +38 -26
index 9b83b7d..66e3bfb 100644
@@ -1044,12 +1044,6 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 			continue;
 		}
 
-		/*
-		 * Kill on action required.
-		 */
-		if (severity == MCE_AR_SEVERITY)
-			kill_it = 1;
-
 		mce_read_aux(&m, i);
 
 		/*
@@ -1070,6 +1064,8 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 		}
 	}
 
+	m = *final;
+
 	if (!no_way_out)
 		mce_clear_state(toclear);
 
@@ -1088,7 +1084,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 	 * support MCE broadcasting or it has been disabled.
 	 */
 	if (no_way_out && tolerant < 3)
-		mce_panic("Fatal machine check on current CPU", final, msg);
+		mce_panic("Fatal machine check on current CPU", &m, msg);
 
 	/*
 	 * If the error seems to be unrecoverable, something should be
@@ -1097,11 +1093,13 @@ void do_machine_check(struct pt_regs *regs, long error_code)
 	 * high, don't try to do anything at all.
 	 */
 
-	if (kill_it && tolerant < 3)
+	if (worst != MCE_AR_SEVERITY && kill_it && tolerant < 3)
 		force_sig(SIGBUS, current);
 
-	/* notify userspace ASAP */
-	set_thread_flag(TIF_MCE_NOTIFY);
+	if (worst == MCE_AR_SEVERITY) {
+		mce_save_info(m.addr);
+		set_thread_flag(TIF_MCE_NOTIFY);
+	}
 
 	if (worst > 0)
 		mce_report_event(regs);
@@ -1115,34 +1113,50 @@ EXPORT_SYMBOL_GPL(do_machine_check);
 #ifndef CONFIG_MEMORY_FAILURE
 int memory_failure(unsigned long pfn, int vector, int flags)
 {
-	printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn);
+	if (flags & MF_ACTION_REQUIRED)
+		return -ENXIO; /* panic? */
+	else
+		printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn);
 
 	return 0;
 }
 #endif
 
 /*
- * Called after mce notification in process context. This code
- * is allowed to sleep. Call the high level VM handler to process
- * any corrupted pages.
- * Assume that the work queue code only calls this one at a time
- * per CPU.
- * Note we don't disable preemption, so this code might run on the wrong
- * CPU. In this case the event is picked up by the scheduled work queue.
- * This is merely a fast path to expedite processing in some common
- * cases.
+ * Called in process context that interrupted by MCE and marked with
+ * TIF_MCE_NOTFY, just before returning to errorneous userland.
+ * This code is allowed to sleep.
+ * Attempt possible recovery such as calling the high level VM handler to
+ * process any corrupted pages, and kill/signal current process if required.
  */
 void mce_notify_process(void)
 {
+	__u64	paddr = paddr;
 	unsigned long pfn;
-	mce_notify_irq();
-	while (mce_ring_get(&pfn))
-		memory_failure(pfn, MCE_VECTOR, 0);
+
+	if (!mce_find_info(&paddr))
+		mce_panic("Lost address", NULL, NULL);
+	pfn = paddr >> PAGE_SHIFT;
+
+	clear_thread_flag(TIF_MCE_NOTIFY);
+
+	pr_err("Uncorrected hardware memory error in user-access at %llx",
+		 paddr);
+	if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED) < 0) {
+		pr_err("Memory error not recovered");
+		force_sig(SIGBUS, current);
+	} else {
+		pr_err("Memory error recovered");
+		mce_clear_info();
+	}
 }
 
 static void mce_process_work(struct work_struct *dummy)
 {
-	mce_notify_process();
+	unsigned long pfn;
+
+	while (mce_ring_get(&pfn))
+		memory_failure(pfn, MCE_VECTOR, 0);
 }
 
 #ifdef CONFIG_X86_MCE_INTEL
@@ -1232,8 +1246,6 @@ int mce_notify_irq(void)
 	/* Not more than two messages every minute */
 	static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2);
 
-	clear_thread_flag(TIF_MCE_NOTIFY);
-
 	if (test_and_clear_bit(0, &mce_need_notify)) {
 		/* wake processes polling /dev/mcelog */
 		wake_up_interruptible(&mce_chrdev_wait);
Signature · 1 line
1.7.3.1
#15 lore raw

Re: [PATCH 5/6] x86, mce: handle "action required" errors

Quoted 53 lines · Tony Luck

All non-urgent actions (reporting low severity errors and handling "action-optional" errors) are now handled by a work queue. This means that TIF_MCE_NOTIFY can be used to block execution for a thread experiencing an "action-required" fault until we get all cpus out of the machine check handler (and the thread that hit the fault into mce_notify_process().

We use the new mce_{save,find,clear}_info() API to get information from do_machine_check() to mce_notify_process(), and then use the newly improved memory_failure(..., MF_ACTION_REQUIRED) to handle the error (possibly signalling the process).

---
  arch/x86/kernel/cpu/mcheck/mce.c |   64 ++++++++++++++++++++++---------------
  1 files changed, 38 insertions(+), 26 deletions(-)
arch/x86/kernel/cpu/mcheck/mce.c +3 -7
index 9b83b7d..66e3bfb 100644
@@ -1044,12 +1044,6 @@ void do_machine_check(struct pt_regs *regs, long error_code)
  			continue;
  		}
 
-		/*
-		 * Kill on action required.
-		 */
-		if (severity == MCE_AR_SEVERITY)
-			kill_it = 1;
-
  		mce_read_aux(&m, i);
 
  		/*
@@ -1070,6 +1064,8 @@ void do_machine_check(struct pt_regs *regs, long error_code)
  		}
  	}
 
+	m = *final;
+
  	if (!no_way_out)
  		mce_clear_state(toclear);
 
@@ -1088,7 +1084,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
  	 * support MCE broadcasting or it has been disabled.
  	 */
  	if (no_way_out&&  tolerant<  3)
-		mce_panic("Fatal machine check on current CPU", final, msg);
+		mce_panic("Fatal machine check on current CPU",&m, msg);
 
  	/*
  	 * If the error seems to be unrecoverable, something should be

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

Quoted 6 lines
arch/x86/kernel/cpu/mcheck/mce.c +1 -1
@@ -1097,11 +1093,13 @@ void do_machine_check(struct pt_regs *regs, long error_code)
  	 * high, don't try to do anything at all.
  	 */
 
-	if (kill_it&&  tolerant<  3)
+	if (worst != MCE_AR_SEVERITY&&  kill_it&&  tolerant<  3)
  		force_sig(SIGBUS, current);

I think here it should add more comments to clarify why not killing *AR* case. Such as: "for SRAR errors, such as DCU/IFU error, on affected logical processors, it is reasonable that RIPV is 0."

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

Quoted 4 lines
arch/x86/kernel/cpu/mcheck/mce.c +1 -2
-	/* notify userspace ASAP */
-	set_thread_flag(TIF_MCE_NOTIFY);
+	if (worst == MCE_AR_SEVERITY) {

how about adding one more condition check: mce_usable_address(&m) here?

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

Quoted 2 lines
arch/x86/kernel/cpu/mcheck/mce.c +2 -0
+		mce_save_info(m.addr);
+		set_thread_flag(TIF_MCE_NOTIFY);

Here only SRAR error are flagged with TIF_MCE_NOTIFY, which means only SRAR error is handled in the function do_notify_resume. If so, SRAO error will only be handled in work_queue mce_work. If so, I think some related function names should be updated too. Otherwise, it will confuse people not touching these codes before.

Quoted 27 lines
arch/x86/kernel/cpu/mcheck/mce.c +5 -9
+	}
 
  	if (worst>  0)
  		mce_report_event(regs);
@@ -1115,34 +1113,50 @@ EXPORT_SYMBOL_GPL(do_machine_check);
  #ifndef CONFIG_MEMORY_FAILURE
  int memory_failure(unsigned long pfn, int vector, int flags)
  {
-	printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn);
+	if (flags&  MF_ACTION_REQUIRED)
+		return -ENXIO; /* panic? */
+	else
+		printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn);
 
  	return 0;
  }
  #endif
 
  /*
- * Called after mce notification in process context. This code
- * is allowed to sleep. Call the high level VM handler to process
- * any corrupted pages.
- * Assume that the work queue code only calls this one at a time
- * per CPU.
- * Note we don't disable preemption, so this code might run on the wrong
- * CPU. In this case the event is picked up by the scheduled work queue.
- * This is merely a fast path to expedite processing in some common

arch/x86/kernel/cpu/mcheck/mce.c EXPORT_SYMBOL_GPL(do_machine_check); · line 1134

Quoted 10 lines
arch/x86/kernel/cpu/mcheck/mce.c +6 -1
- * cases.
+ * Called in process context that interrupted by MCE and marked with
+ * TIF_MCE_NOTFY, just before returning to errorneous userland.
+ * This code is allowed to sleep.
+ * Attempt possible recovery such as calling the high level VM handler to
+ * process any corrupted pages, and kill/signal current process if required.
   */
  void mce_notify_process(void)
  {
+	__u64	paddr = paddr;

you mean "__u64 paddr = 0;"?

Quoted 11 lines
arch/x86/kernel/cpu/mcheck/mce.c +7 -3
  	unsigned long pfn;
-	mce_notify_irq();
-	while (mce_ring_get(&pfn))
-		memory_failure(pfn, MCE_VECTOR, 0);
+
+	if (!mce_find_info(&paddr))
+		mce_panic("Lost address", NULL, NULL);
+	pfn = paddr>>  PAGE_SHIFT;
+
+	clear_thread_flag(TIF_MCE_NOTIFY);
+

arch/x86/kernel/cpu/mcheck/mce.c EXPORT_SYMBOL_GPL(do_machine_check); · line 1152

Quoted 10 lines
arch/x86/kernel/cpu/mcheck/mce.c +9 -0
+	pr_err("Uncorrected hardware memory error in user-access at %llx",
+		 paddr);
+	if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED)<  0) {
+		pr_err("Memory error not recovered");
+		force_sig(SIGBUS, current);
+	} else {
+		pr_err("Memory error recovered");
+		mce_clear_info();
+	}
  }

Does there exist some possibility that in the same process there are more than one error triggered? If so, maybe mce_find_info/mce_clear_info should be changed to loop-style, because here TIF_MCE_NOTIFY is cleared in the handler.

Or it is impossible because overwritten will be covered by following condition:

MCESEV(
PANIC, "Action required with lost events", SER, BITSET(MCI_STATUS_OVER|MCI_UC_SAR) ),

Quoted 20 lines
arch/x86/kernel/cpu/mcheck/mce.c +4 -3
  static void mce_process_work(struct work_struct *dummy)
  {
-	mce_notify_process();
+	unsigned long pfn;
+
+	while (mce_ring_get(&pfn))
+		memory_failure(pfn, MCE_VECTOR, 0);
  }
 
  #ifdef CONFIG_X86_MCE_INTEL
@@ -1232,8 +1246,6 @@ int mce_notify_irq(void)
  	/* Not more than two messages every minute */
  	static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2);
 
-	clear_thread_flag(TIF_MCE_NOTIFY);
-
  	if (test_and_clear_bit(0,&mce_need_notify)) {
  		/* wake processes polling /dev/mcelog */
  		wake_up_interruptible(&mce_chrdev_wait);
author
#16 lore raw

Re: [PATCH 5/6] x86, mce: handle "action required" errors

Quoted 10 lines · Chen Gong
Quoted 4 lines

-       if (kill_it&&  tolerant<  3)

+       if (worst != MCE_AR_SEVERITY&&  kill_it&&  tolerant<  3) force_sig(SIGBUS, current);

I think here it should add more comments to clarify why not killing *AR* case.
Such as: "for SRAR errors, such as DCU/IFU error, on affected logical processors, it is reasonable that RIPV is 0."

I'll look at this - the reason to not kill for AR is that we want to try to recover
first (e.g. page could be re-read from disk into a different physical page). In some cases we can recover transparently to the application.

Quoted 6 lines
Quoted 3 lines

-       /* notify userspace ASAP */
-       set_thread_flag(TIF_MCE_NOTIFY);
+       if (worst == MCE_AR_SEVERITY) {

how about adding one more condition check: mce_usable_address(&m) here?

I don't think it is needed - the table lookup in mce_severity() will only set MCE_AR_SEVERITY if the ADDRV and MISCV bits are set in MCi_STATUS.

Quoted 9 lines
Quoted 2 lines

+               mce_save_info(m.addr);
+               set_thread_flag(TIF_MCE_NOTIFY);

Here only SRAR error are flagged with TIF_MCE_NOTIFY, which means only SRAR error is handled in the function do_notify_resume. If so, SRAO error will only be handled in work_queue mce_work. If so, I think some related function names should be updated too. Otherwise, it will confuse people not touching these codes before.

Agreed - the names of the functions and the actions they perform haven't been kept up to date.

Quoted 6 lines
Quoted 3 lines

 void mce_notify_process(void)
 {
+       __u64   paddr = paddr;

you mean "__u64 paddr = 0;"?

No. The "paddr = paddr" is a gcc'ism to silence a spurious "may be used before set" warning. But the point will be moot in the next version because changes inspired by Boris' comments mean that this line goes away.

Quoted 8 lines

Does there exist some possibility that in the same process there are more than
one error triggered? If so, maybe mce_find_info/mce_clear_info should be changed
to loop-style, because here TIF_MCE_NOTIFY is cleared in the handler.

Or it is impossible because overwritten will be covered by following condition:

I think that in current cpus it isn't possible to have more than one error reported at the same time per process.

-Tony

#17 lore raw

Re: [PATCH 5/6] x86, mce: handle "action required" errors

Quoted 12 lines · Tony Luck
Quoted 10 lines · Chen Gong

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

Quoted 4 lines
arch/x86/kernel/cpu/mcheck/mce.c +1 -1
-       if (kill_it&&    tolerant<    3)
 
+       if (worst != MCE_AR_SEVERITY&&    kill_it&&    tolerant<    3)
                force_sig(SIGBUS, current);

I think here it should add more comments to clarify why not killing *AR* case.
Such as: "for SRAR errors, such as DCU/IFU error, on affected logical processors, it is reasonable that RIPV is 0."

Quoted 4 lines

I'll look at this - the reason to not kill for AR is that we want to try to recover
first (e.g. page could be re-read from disk into a different physical page). In some cases we can recover transparently to the application.

Oh, yes, these reasons are very important why not killing *AR* events. But my point is in a *AR* supported environment, "kill_it" should not be true like below:
if (!(m.mcgstatus & MCG_STATUS_RIPV))
kill_it = 1;

the reason is what I said before. But at that time the worst severity hasn't been determined so we have to wati until it is out.

anyway, it is an interesting coincidence, isn't it? :-)

#18 lore raw

Re: [PATCH 5/6] x86, mce: handle "action required" errors

In reply to Tony Luck

On Mon, Dec 12, 2011 at 01:47:45PM -0800, Tony Luck wrote:
[..]

Quoted 17 lines

- * Called after mce notification in process context. This code
- * is allowed to sleep. Call the high level VM handler to process
- * any corrupted pages.
- * Assume that the work queue code only calls this one at a time
- * per CPU.
- * Note we don't disable preemption, so this code might run on the wrong
- * CPU. In this case the event is picked up by the scheduled work queue.
- * This is merely a fast path to expedite processing in some common
- * cases.
+ * Called in process context that interrupted by MCE and marked with
+ * TIF_MCE_NOTFY, just before returning to errorneous userland.
+ * This code is allowed to sleep.
+ * Attempt possible recovery such as calling the high level VM handler to
+ * process any corrupted pages, and kill/signal current process if required. */
void mce_notify_process(void)
{

arch/x86/kernel/cpu/mcheck/mce.c EXPORT_SYMBOL_GPL(do_machine_check); · line 1138

Quoted 8 lines
arch/x86/kernel/cpu/mcheck/mce.c +4 -3
+	__u64	paddr = paddr;
 	unsigned long pfn;
-	mce_notify_irq();
-	while (mce_ring_get(&pfn))
-		memory_failure(pfn, MCE_VECTOR, 0);
+
+	if (!mce_find_info(&paddr))
+		mce_panic("Lost address", NULL, NULL);

Wouldn't it be good to return struct mce_info *mi here in addition to &paddr...

arch/x86/kernel/cpu/mcheck/mce.c EXPORT_SYMBOL_GPL(do_machine_check); · line 1150

Quoted 12 lines
arch/x86/kernel/cpu/mcheck/mce.c +12 -0
+	pfn = paddr >> PAGE_SHIFT;
+
+	clear_thread_flag(TIF_MCE_NOTIFY);
+
+	pr_err("Uncorrected hardware memory error in user-access at %llx",
+		 paddr);
+	if (memory_failure(pfn, MCE_VECTOR, MF_ACTION_REQUIRED) < 0) {
+		pr_err("Memory error not recovered");
+		force_sig(SIGBUS, current);
+	} else {
+		pr_err("Memory error recovered");
+		mce_clear_info();

so that you don't need to iterate again over the mce_info array but do:

	mce_clear_info(mi);

?

This assumes, of course, that you have only one AR MCE per task, per return to userspace. I guess this is fine for now.

Quoted 25 lines
arch/x86/kernel/cpu/mcheck/mce.c +5 -3
+	}
 }
 
 static void mce_process_work(struct work_struct *dummy)
 {
-	mce_notify_process();
+	unsigned long pfn;
+
+	while (mce_ring_get(&pfn))
+		memory_failure(pfn, MCE_VECTOR, 0);
 }
 
 #ifdef CONFIG_X86_MCE_INTEL
@@ -1232,8 +1246,6 @@ int mce_notify_irq(void)
 	/* Not more than two messages every minute */
 	static DEFINE_RATELIMIT_STATE(ratelimit, 60*HZ, 2);
 
-	clear_thread_flag(TIF_MCE_NOTIFY);
-
 	if (test_and_clear_bit(0, &mce_need_notify)) {
 		/* wake processes polling /dev/mcelog */
 		wake_up_interruptible(&mce_chrdev_wait);
Signature · 1 line
1.7.3.1

Thanks.

Signature · 8 lines
Regards/Gruss,
Boris.

Advanced Micro Devices GmbH
Einsteinring 24, 85609 Dornach
GM: Alberto Bozzo
Reg: Dornach, Landkreis Muenchen
HRB Nr. 43632 WEEE Registernr: 129 19551
author
#19 lore raw

RE: [PATCH 5/6] x86, mce: handle "action required" errors

Quoted 5 lines

arch/x86/kernel/cpu/mcheck/mce.c EXPORT_SYMBOL_GPL(do_machine_check); · line 1138

Quoted 2 lines
arch/x86/kernel/cpu/mcheck/mce.c +2 -0
+	if (!mce_find_info(&paddr))
+		mce_panic("Lost address", NULL, NULL);

Wouldn't it be good to return struct mce_info *mi here in addition to &paddr...

Great idea (actually "instead of" works better than "in addition too").

Quoted 3 lines

so that you don't need to iterate again over the mce_info array but do:

	mce_clear_info(mi);

Just coded it - looks much better. Will send new version soon with this change, and Ingo's suggestions incorporated.

Quoted 2 lines

This assumes, of course, that you have only one AR MCE per task, per return to userspace. I guess this is fine for now.

While we might have multiple memory references in flight at once, we'd have to be really unlucky to hit multiple 2-bit errors at the same time (unless there was some system level failure in the memory controller, in which case we not likely to be able to recover).

In current processor implementations, the recoverable errors are all reported in just one machine check bank - so we can't actually process more than one at a time.

-Tony

author
#20 lore raw

PATCH 6/6 x86, mce: Recognise machine check bank signature for data path error

In reply to Tony Luck

Action required data path signature is defined in table 15-19 of SDM:

+-----------------------------------------------------------------------------+
| SRAR Error | Valid | OVER | UC | EN | MISCV | ADDRV | PCC | S | AR | MCACOD |
| Data Load  |     1 |    0 |  1 |  1 |     1 |     1 |   0 | 1 |  1 |  0x134 |
+-----------------------------------------------------------------------------+

Recognise this, and pass MCE_AR_SEVERITY code back to do_machine_check()

---
 arch/x86/kernel/cpu/mcheck/mce-severity.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)
arch/x86/kernel/cpu/mcheck/mce-severity.c +13 -1
index 7395d5f..c4d8b24 100644
@@ -54,6 +54,7 @@ static struct severity {
 #define  MASK(x, y)	.mask = x, .result = y
 #define MCI_UC_S (MCI_STATUS_UC|MCI_STATUS_S)
 #define MCI_UC_SAR (MCI_STATUS_UC|MCI_STATUS_S|MCI_STATUS_AR)
+#define	MCI_ADDR (MCI_STATUS_ADDRV|MCI_STATUS_MISCV)
 #define MCACOD 0xffff
 
 	MCESEV(
@@ -102,11 +103,22 @@ static struct severity {
 		SER, BITCLR(MCI_STATUS_S)
 		),
 
-	/* AR add known MCACODs here */
 	MCESEV(
 		PANIC, "Action required with lost events",
 		SER, BITSET(MCI_STATUS_OVER|MCI_UC_SAR)
 		),
+
+	/* known AR MCACODs: */
+	MCESEV(
+		KEEP, "HT thread notices Action required: data load error",
+		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|0x0134),
+		MCGMASK(MCG_STATUS_EIPV, 0)
+		),
+	MCESEV(
+		AR, "Action required: data load error",
+		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|0x0134),
+		USER
+		),
 	MCESEV(
 		PANIC, "Action required: unknown MCACOD",
 		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR, MCI_UC_SAR)
Signature · 1 line
1.7.3.1
#21 lore raw

Re: [PATCH 6/6] x86, mce: Recognise machine check bank signature for data path error

Quoted 31 lines · Tony Luck

Action required data path signature is defined in table 15-19 of SDM:

+-----------------------------------------------------------------------------+
| SRAR Error | Valid | OVER | UC | EN | MISCV | ADDRV | PCC | S | AR | MCACOD |
| Data Load  |     1 |    0 |  1 |  1 |     1 |     1 |   0 | 1 |  1 |  0x134 |
+-----------------------------------------------------------------------------+

Recognise this, and pass MCE_AR_SEVERITY code back to do_machine_check()

---
 arch/x86/kernel/cpu/mcheck/mce-severity.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)
arch/x86/kernel/cpu/mcheck/mce-severity.c +1 -1
index 7395d5f..c4d8b24 100644
@@ -54,6 +54,7 @@ static struct severity {
 #define  MASK(x, y)	.mask = x, .result = y
 #define MCI_UC_S (MCI_STATUS_UC|MCI_STATUS_S)
 #define MCI_UC_SAR (MCI_STATUS_UC|MCI_STATUS_S|MCI_STATUS_AR)
+#define	MCI_ADDR (MCI_STATUS_ADDRV|MCI_STATUS_MISCV)
 #define MCACOD 0xffff
 
 	MCESEV(
@@ -102,11 +103,22 @@ static struct severity {
 		SER, BITCLR(MCI_STATUS_S)
 		),
 
-	/* AR add known MCACODs here */

arch/x86/kernel/cpu/mcheck/mce-severity.c static struct severity { · line 115

Quoted 10 lines
arch/x86/kernel/cpu/mcheck/mce-severity.c +6 -0
 	MCESEV(
 		PANIC, "Action required with lost events",
 		SER, BITSET(MCI_STATUS_OVER|MCI_UC_SAR)
 		),
+
+	/* known AR MCACODs: */
+	MCESEV(
+		KEEP, "HT thread notices Action required: data load error",
+		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|0x0134),
+		MCGMASK(MCG_STATUS_EIPV, 0)

Oh this is the core "observed" the error case, ok.

This is marked as MCE_KEEP_SEVERITY, which means that we're panicking in case we lose the AR error on the affected CPU. Which should be conservative enough...

ACK.

Quoted 13 lines
arch/x86/kernel/cpu/mcheck/mce-severity.c +6 -0
+		),
+	MCESEV(
+		AR, "Action required: data load error",
+		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR|MCI_ADDR|MCACOD, MCI_UC_SAR|MCI_ADDR|0x0134),
+		USER
+		),
 	MCESEV(
 		PANIC, "Action required: unknown MCACOD",
 		SER, MASK(MCI_STATUS_OVER|MCI_UC_SAR, MCI_UC_SAR)
Signature · 1 line
1.7.3.1
Signature · 8 lines
Regards/Gruss,
Boris.

Advanced Micro Devices GmbH
Einsteinring 24, 85609 Dornach
GM: Alberto Bozzo
Reg: Dornach, Landkreis Muenchen
HRB Nr. 43632 WEEE Registernr: 129 19551