Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1727988 > unrolled thread

[PATCH v3 0/3] arm64/ras: support sea error recovery

Started byXie XiuQi <xiexiuqi@huawei.com>
First post2017-09-07 09:50 +0200
Last post2017-09-07 10:00 +0200
Articles 5 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v3 0/3] arm64/ras: support sea error recovery Xie XiuQi <xiexiuqi@huawei.com> - 2017-09-07 09:50 +0200
    [PATCH v3 1/3] arm64/ras: support sea error recovery Xie XiuQi <xiexiuqi@huawei.com> - 2017-09-07 09:50 +0200
      Re: [PATCH v3 1/3] arm64/ras: support sea error recovery Borislav Petkov <bp@suse.de> - 2017-09-08 14:50 +0200
      Re: [PATCH v3 1/3] arm64/ras: support sea error recovery James Morse <james.morse@arm.com> - 2017-09-08 20:20 +0200
    [PATCH v3 3/3] arm64/ras: save error address from memory section for recovery Xie XiuQi <xiexiuqi@huawei.com> - 2017-09-07 10:00 +0200

#1727988 — [PATCH v3 0/3] arm64/ras: support sea error recovery

FromXie XiuQi <xiexiuqi@huawei.com>
Date2017-09-07 09:50 +0200
Subject[PATCH v3 0/3] arm64/ras: support sea error recovery
Message-ID<umZJx-5lZ-23@gated-at.bofh.it>
With ARM v8.2 RAS Extension, SEA are usually triggered when memory errors
are consumed. In some cases, if the error address is in a clean page or a
read-only page, there is a chance to recover. Such as error occurs in a
instruction page, we can reread this page from disk instead of killing
process.

Because memory_failure() may sleep, we can not call it directly in SEA
exception context. So we saved faulting physical address associated with
a process in the ghes handler and set __TIF_SEA_NOTIFY. When we return
from SEA exception context and get into do_notify_resume() before the
process running, we could check it and call memory_failure() to do
recovery. It's safe, because we are in process context.

In some platform, when SEA triggerred, physical address could be reported
by memory section or by processor section, so we save address at this two
place.

---
v3 - v2:
  - fix patch style issue

v2 - v1:
  - wrap arm_proc_error_check and log_arm_hw_error in a single arm_process_error()
  - fix sea_save_info return value issue
  - fix link error if this CONFIG_ARM64_ERR_RECOV is not selected
  - use a notify chain instead of call arch_apei_report_mem_error directly

  https://lkml.org/lkml/2017/9/1/189

Xie XiuQi (3):
  arm64/ras: support sea error recovery
  GHES: add a notify chain for process memory section
  arm64/ras: save error address from memory section for recovery

 arch/arm64/Kconfig                   |  11 +++
 arch/arm64/include/asm/ras.h         |  36 ++++++++
 arch/arm64/include/asm/thread_info.h |   4 +-
 arch/arm64/kernel/Makefile           |   1 +
 arch/arm64/kernel/ras.c              | 172 +++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/signal.c           |   8 ++
 arch/arm64/mm/fault.c                |  27 ++++--
 drivers/acpi/apei/ghes.c             |  14 ++-
 include/acpi/ghes.h                  |   8 ++
 9 files changed, 270 insertions(+), 11 deletions(-)
 create mode 100644 arch/arm64/include/asm/ras.h
 create mode 100644 arch/arm64/kernel/ras.c

-- 
1.8.3.1

[toc] | [next] | [standalone]


#1727990 — [PATCH v3 1/3] arm64/ras: support sea error recovery

FromXie XiuQi <xiexiuqi@huawei.com>
Date2017-09-07 09:50 +0200
Subject[PATCH v3 1/3] arm64/ras: support sea error recovery
Message-ID<umZJx-5lZ-27@gated-at.bofh.it>
In reply to#1727988
With ARM v8.2 RAS Extension, SEA are usually triggered when memory errors
are consumed. In some cases, if the error address is in a clean page or a
read-only page, there is a chance to recover. Such as error occurs in a
instruction page, we can reread this page from disk instead of killing
process.

Because memory_failure() may sleep, we can not call it directly in SEA
exception context. So we saved faulting physical address associated with
a process in the ghes handler and set __TIF_SEA_NOTIFY. When we return
from SEA exception context and get into do_notify_resume() before the
process running, we could check it and call memory_failure() to do
recovery. It's safe, because we are in process context.

Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
Signed-off-by: Wang Xiongfeng <wangxiongfeng2@huawei.com>
---
 arch/arm64/Kconfig                   |  11 +++
 arch/arm64/include/asm/ras.h         |  36 +++++++++
 arch/arm64/include/asm/thread_info.h |   4 +-
 arch/arm64/kernel/Makefile           |   1 +
 arch/arm64/kernel/ras.c              | 141 +++++++++++++++++++++++++++++++++++
 arch/arm64/kernel/signal.c           |   8 ++
 arch/arm64/mm/fault.c                |  27 +++++--
 drivers/acpi/apei/ghes.c             |   4 +-
 8 files changed, 221 insertions(+), 11 deletions(-)
 create mode 100644 arch/arm64/include/asm/ras.h
 create mode 100644 arch/arm64/kernel/ras.c

diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index dfd9086..7d44589 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -640,6 +640,17 @@ config HOTPLUG_CPU
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
 	  can be controlled through /sys/devices/system/cpu.
 
+config ARM64_ERR_RECOV
+	bool "Support arm64 RAS error recovery"
+	depends on ACPI_APEI_SEA && MEMORY_FAILURE
+	help
+	  With ARM v8.2 RAS Extension, SEA are usually triggered when memory errors
+	  are consumed. In some cases, if the error address is in a clean page or a
+	  read-only page, there is a chance to recover. Such as error occurs in a
+	  instruction page, we can reread this page from disk instead of killing process.
+
+	  Say Y if unsure.
+
 # Common NUMA Features
 config NUMA
 	bool "Numa Memory Allocation and Scheduler Support"
diff --git a/arch/arm64/include/asm/ras.h b/arch/arm64/include/asm/ras.h
new file mode 100644
index 0000000..e174f95
--- /dev/null
+++ b/arch/arm64/include/asm/ras.h
@@ -0,0 +1,36 @@
+/*
+ * ARM64 SEA error recoery support
+ *
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *   Author: Xie XiuQi <xiexiuqi@huawei.com>
+ *   Author: Wang Xiongfeng <wangxiongfeng2@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _ASM_RAS_H
+#define _ASM_RAS_H
+
+#include <linux/cper.h>
+#include <linux/ras.h>
+#include <acpi/ghes.h>
+
+extern void sea_notify_process(void);
+
+#ifdef CONFIG_ARM64_ERR_RECOV
+extern void arm_process_error(struct ghes *ghes, struct cper_sec_proc_arm *err);
+#else
+static inline void arm_process_error(struct ghes *ghes, struct cper_sec_proc_arm *err)
+{
+	log_arm_hw_error(err);
+}
+#endif /* CONFIG_ARM64_ERR_RECOV */
+
+#endif /*_ASM_RAS_H*/
diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h
index 46c3b93..4b10131 100644
--- a/arch/arm64/include/asm/thread_info.h
+++ b/arch/arm64/include/asm/thread_info.h
@@ -86,6 +86,7 @@ struct thread_info {
 #define TIF_NOTIFY_RESUME	2	/* callback before returning to user */
 #define TIF_FOREIGN_FPSTATE	3	/* CPU's FP state is not current's */
 #define TIF_UPROBE		4	/* uprobe breakpoint or singlestep */
+#define TIF_SEA_NOTIFY          5       /* notify to do an error recovery */
 #define TIF_NOHZ		7
 #define TIF_SYSCALL_TRACE	8
 #define TIF_SYSCALL_AUDIT	9
@@ -102,6 +103,7 @@ struct thread_info {
 #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)
 #define _TIF_FOREIGN_FPSTATE	(1 << TIF_FOREIGN_FPSTATE)
 #define _TIF_NOHZ		(1 << TIF_NOHZ)
+#define _TIF_SEA_NOTIFY         (1 << TIF_SEA_NOTIFY)
 #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
@@ -111,7 +113,7 @@ struct thread_info {
 
 #define _TIF_WORK_MASK		(_TIF_NEED_RESCHED | _TIF_SIGPENDING | \
 				 _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \
-				 _TIF_UPROBE)
+				 _TIF_UPROBE|_TIF_SEA_NOTIFY)
 
 #define _TIF_SYSCALL_WORK	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
 				 _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index f2b4e81..ba3abf8 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -43,6 +43,7 @@ arm64-obj-$(CONFIG_EFI)			+= efi.o efi-entry.stub.o
 arm64-obj-$(CONFIG_PCI)			+= pci.o
 arm64-obj-$(CONFIG_ARMV8_DEPRECATED)	+= armv8_deprecated.o
 arm64-obj-$(CONFIG_ACPI)		+= acpi.o
+arm64-obj-$(CONFIG_ARM64_ERR_RECOV)	+= ras.o
 arm64-obj-$(CONFIG_ACPI_NUMA)		+= acpi_numa.o
 arm64-obj-$(CONFIG_ARM64_ACPI_PARKING_PROTOCOL)	+= acpi_parking_protocol.o
 arm64-obj-$(CONFIG_PARAVIRT)		+= paravirt.o
diff --git a/arch/arm64/kernel/ras.c b/arch/arm64/kernel/ras.c
new file mode 100644
index 0000000..797722d
--- /dev/null
+++ b/arch/arm64/kernel/ras.c
@@ -0,0 +1,141 @@
+/*
+ * ARM64 SEA error recoery support
+ *
+ * Copyright 2017 Huawei Technologies Co., Ltd.
+ *   Author: Xie XiuQi <xiexiuqi@huawei.com>
+ *   Author: Wang Xiongfeng <wangxiongfeng2@huawei.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/cper.h>
+#include <linux/mm.h>
+#include <linux/preempt.h>
+#include <linux/acpi.h>
+#include <linux/sched/signal.h>
+#include <linux/ras.h>
+
+#include <acpi/actbl1.h>
+#include <acpi/ghes.h>
+#include <acpi/apei.h>
+
+#include <asm/thread_info.h>
+#include <asm/atomic.h>
+#include <asm/ras.h>
+
+/*
+ * Need to save faulting physical address associated with a process
+ * in the sea ghes handler some place where we can grab it back
+ * later in sea_notify_process()
+ */
+#define SEA_INFO_MAX    16
+
+struct sea_info {
+	atomic_t                inuse;
+	struct task_struct      *t;
+	__u64                   paddr;
+} sea_info[SEA_INFO_MAX];
+
+static bool sea_save_info(__u64 addr)
+{
+	struct sea_info *si;
+
+	for (si = sea_info; si < &sea_info[SEA_INFO_MAX]; si++) {
+		if (atomic_cmpxchg(&si->inuse, 0, 1) == 0) {
+			si->t = current;
+			si->paddr = addr;
+			return true;
+		}
+	}
+
+	pr_err("Too many concurrent recoverable errors\n");
+	return false;
+}
+
+static struct sea_info *sea_find_info(void)
+{
+	struct sea_info *si;
+
+	for (si = sea_info; si < &sea_info[SEA_INFO_MAX]; si++)
+		if (atomic_read(&si->inuse) && si->t == current)
+			return si;
+	return NULL;
+}
+
+static void sea_clear_info(struct sea_info *si)
+{
+	atomic_set(&si->inuse, 0);
+}
+
+/*
+ * Called in process context that interrupted by SEA and marked with
+ * TIF_SEA_NOTIFY, just before returning to erroneous 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.
+ * Action required errors are handled here.
+ */
+void sea_notify_process(void)
+{
+	unsigned long pfn;
+	int fail = 0, flags = MF_ACTION_REQUIRED;
+	struct sea_info *si = sea_find_info();
+
+	if (!si)
+		panic("Lost physical address for consumed uncorrectable error");
+
+	clear_thread_flag(TIF_SEA_NOTIFY);
+	do {
+		pfn = si->paddr >> PAGE_SHIFT;
+
+
+		pr_err("Uncorrected hardware memory error in user-access at %llx\n",
+			si->paddr);
+		/*
+		 * We must call memory_failure() here even if the current process is
+		 * doomed. We still need to mark the page as poisoned and alert any
+		 * other users of the page.
+		 */
+		if (memory_failure(pfn, 0, flags) < 0)
+			fail++;
+
+		sea_clear_info(si);
+
+		si = sea_find_info();
+	} while (si);
+
+	if (fail) {
+		pr_err("Memory error not recovered\n");
+		force_sig(SIGBUS, current);
+	}
+}
+
+void arm_process_error(struct ghes *ghes, struct cper_sec_proc_arm *err)
+{
+	int i;
+	bool info_saved = false;
+	struct cper_arm_err_info *err_info;
+
+	log_arm_hw_error(err);
+
+	if ((ghes->generic->notify.type != ACPI_HEST_NOTIFY_SEA) ||
+	    (ghes->estatus->error_severity != CPER_SEV_RECOVERABLE))
+		return;
+
+	err_info = (struct cper_arm_err_info *)(err + 1);
+	for (i = 0; i < err->err_info_num; i++, err_info++) {
+		if (err_info->validation_bits & CPER_ARM_INFO_VALID_PHYSICAL_ADDR)
+			info_saved |= sea_save_info(err_info->physical_fault_addr);
+	}
+
+	if (info_saved)
+		set_thread_flag(TIF_SEA_NOTIFY);
+}
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 089c3747..71e314e 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -38,6 +38,7 @@
 #include <asm/fpsimd.h>
 #include <asm/signal32.h>
 #include <asm/vdso.h>
+#include <asm/ras.h>
 
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
@@ -749,6 +750,13 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
 	 * Update the trace code with the current status.
 	 */
 	trace_hardirqs_off();
+
+#ifdef CONFIG_ARM64_ERR_RECOV
+		/* notify userspace of pending SEAs */
+		if (thread_flags & _TIF_SEA_NOTIFY)
+			sea_notify_process();
+#endif /* CONFIG_ARM64_ERR_RECOV */
+
 	do {
 		if (thread_flags & _TIF_NEED_RESCHED) {
 			schedule();
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 1f22a41..b38476d 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -594,14 +594,25 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs)
 			nmi_exit();
 	}
 
-	info.si_signo = SIGBUS;
-	info.si_errno = 0;
-	info.si_code  = 0;
-	if (esr & ESR_ELx_FnV)
-		info.si_addr = NULL;
-	else
-		info.si_addr  = (void __user *)addr;
-	arm64_notify_die("", regs, &info, esr);
+	if (user_mode(regs)) {
+		if (test_thread_flag(TIF_SEA_NOTIFY))
+			return ret;
+
+		info.si_signo = SIGBUS;
+		info.si_errno = 0;
+		info.si_code  = 0;
+		if (esr & ESR_ELx_FnV)
+			info.si_addr = NULL;
+		else
+			info.si_addr  = (void __user *)addr;
+
+		current->thread.fault_address = 0;
+		current->thread.fault_code = esr;
+		force_sig_info(info.si_signo, &info, current);
+	} else {
+		die("Uncorrected hardware memory error in kernel-access\n",
+		    regs, esr);
+	}
 
 	return ret;
 }
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index d661d45..502335c 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -46,12 +46,12 @@
 #include <linux/nmi.h>
 #include <linux/sched/clock.h>
 #include <linux/uuid.h>
-#include <linux/ras.h>
 
 #include <acpi/actbl1.h>
 #include <acpi/ghes.h>
 #include <acpi/apei.h>
 #include <asm/tlbflush.h>
+#include <asm/ras.h>
 #include <ras/ras_event.h>
 
 #include "apei-internal.h"
@@ -520,7 +520,7 @@ static void ghes_do_proc(struct ghes *ghes,
 		else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
 			struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
 
-			log_arm_hw_error(err);
+			arm_process_error(ghes, err);
 		} else {
 			void *err = acpi_hest_get_payload(gdata);
 
-- 
1.8.3.1

[toc] | [prev] | [next] | [standalone]


#1728796 — Re: [PATCH v3 1/3] arm64/ras: support sea error recovery

FromBorislav Petkov <bp@suse.de>
Date2017-09-08 14:50 +0200
SubjectRe: [PATCH v3 1/3] arm64/ras: support sea error recovery
Message-ID<unqTo-74F-5@gated-at.bofh.it>
In reply to#1727990
On Thu, Sep 07, 2017 at 03:45:14PM +0800, Xie XiuQi wrote:
> With ARM v8.2 RAS Extension, SEA are usually triggered when memory errors
> are consumed. In some cases, if the error address is in a clean page or a
> read-only page, there is a chance to recover. Such as error occurs in a
> instruction page, we can reread this page from disk instead of killing
> process.
> 
> Because memory_failure() may sleep, we can not call it directly in SEA
> exception context. So we saved faulting physical address associated with
> a process in the ghes handler and set __TIF_SEA_NOTIFY. When we return
> from SEA exception context and get into do_notify_resume() before the
> process running, we could check it and call memory_failure() to do
> recovery. It's safe, because we are in process context.
> 
> Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
> Signed-off-by: Wang Xiongfeng <wangxiongfeng2@huawei.com>

This is not a correct SOB chain, please check:

Documentation/process/submitting-patches.rst, section 11.

> ---
>  arch/arm64/Kconfig                   |  11 +++
>  arch/arm64/include/asm/ras.h         |  36 +++++++++
>  arch/arm64/include/asm/thread_info.h |   4 +-
>  arch/arm64/kernel/Makefile           |   1 +
>  arch/arm64/kernel/ras.c              | 141 +++++++++++++++++++++++++++++++++++
>  arch/arm64/kernel/signal.c           |   8 ++
>  arch/arm64/mm/fault.c                |  27 +++++--
>  drivers/acpi/apei/ghes.c             |   4 +-
>  8 files changed, 221 insertions(+), 11 deletions(-)
>  create mode 100644 arch/arm64/include/asm/ras.h
>  create mode 100644 arch/arm64/kernel/ras.c

What tree are those patches against?

They don't apply cleanly against latest mainline:

checking file arch/arm64/Kconfig
Hunk #1 succeeded at 641 (offset 1 line).
checking file arch/arm64/include/asm/ras.h
checking file arch/arm64/include/asm/thread_info.h
Hunk #1 FAILED at 86.
Hunk #2 succeeded at 98 (offset -4 lines).
Hunk #3 FAILED at 112.
2 out of 3 hunks FAILED
checking file arch/arm64/kernel/Makefile
checking file arch/arm64/kernel/ras.c
checking file arch/arm64/kernel/signal.c
Hunk #1 succeeded at 40 with fuzz 1 (offset 2 lines).
Hunk #2 FAILED at 750.
1 out of 2 hunks FAILED
checking file arch/arm64/mm/fault.c
Hunk #1 succeeded at 631 (offset 37 lines).
checking file drivers/acpi/apei/ghes.c

-- 
Regards/Gruss,
    Boris.

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

[toc] | [prev] | [next] | [standalone]


#1729164 — Re: [PATCH v3 1/3] arm64/ras: support sea error recovery

FromJames Morse <james.morse@arm.com>
Date2017-09-08 20:20 +0200
SubjectRe: [PATCH v3 1/3] arm64/ras: support sea error recovery
Message-ID<unw2J-283-3@gated-at.bofh.it>
In reply to#1727990
Hi Xie XiuQi,

(Sorry a few versions of this went past before I caught up with it)

On 07/09/17 08:45, Xie XiuQi wrote:
> With ARM v8.2 RAS Extension, SEA are usually triggered when memory errors
> are consumed. In some cases, if the error address is in a clean page or a
> read-only page, there is a chance to recover. Such as error occurs in a
> instruction page, we can reread this page from disk instead of killing
> process.

> Because memory_failure() may sleep, we can not call it directly in SEA
> exception context.

This is why we have memory_failure_queue() instead, it ... bother. That doesn't
look nmi-safe. (I thought this ended with an llist, but clearly I was looking at
the wrong thing).

It doesn't look like this is a problem for NOTIFY_SEA as it would only interrupt
itself on the same CPU if the memory-failure code/data were corrupt. (which is
not a case we can handle). We need to fix this before any of the asynchronous
NMI-like RAS notifications for arm64 get merged.

(this is one problem, but I don't think its 'the' problem you are trying to
solve with this series).


> So we saved faulting physical address associated with
> a process in the ghes handler and set __TIF_SEA_NOTIFY.

A per-notification type TIF flag looks fishy, surely this would affect all
NMI-like RAS notification methods?


> When we return
> from SEA exception context and get into do_notify_resume() before the
> process running, we could check it and call memory_failure() to do
> recovery. It's safe, because we are in process context.

I'm afraid I don't think this is the best approach for fixing this.
Its tied to the notification type, but the notification should be irrelevant
once we call ghes_proc().
It adds code poking around in CPER and ACPI/GHES to the arm64 arch code, all of
this should be in the core common code.
Most importantly: this means arm64 behaves differently with regard to handling
memory errors to other architectures using ACPI. Two behaviours means twice the
code, review and bugs...


Delaying the handling until we re-enter user-space means faults that may affect
the kernel aren't handled until much later. Just because the fault was
synchronous and user-space was running doesn't mean only user space is affected.
Some examples I've collected so far: the zero-page may be corrupt, this is
mapped into every process and used by the kernel. Similarly corruption in the
vdso affects all user-space. The fault may affect the page tables, this affects
all users of the mm_struct.

(I'm sure we agree that an synchronous-external-abort interrupting the kernel is
fatal for the kernel, but the other way round isn't always true).

Setting a TIF flag to handle the error before re-entering user-space is a
problem as the scheduler may choose to pre-empt this task and run all the other
tasks before this eventually gets handled.


Assuming this is just a problem with memory_failure_queue(), two alternatives I
can suggest are making memory_failure_queue() nmi-safe, or abstracting
NOTIFY_NMI's estatus pool/cache to use for the arm64 NMI-like notifications too.

If there is more to this, can you explain the problem you're trying to solve?
(I suspect there may be an issue with multiple-signals being merged, or exactly
when memory_failure_queue()'s work gets run.) Can you outline the sequence of
events?


You're picking a physical address out of 'ARM Processor Error Information
Structure', these correspond with Cache, TLB, Bus or (the mysterious) 'micro
architectural error'. I don't see anything checking the error type.
Given the physical address, are you adding error-handling for cache-errors with
this series?


Thanks,

James

[toc] | [prev] | [next] | [standalone]


#1727996 — [PATCH v3 3/3] arm64/ras: save error address from memory section for recovery

FromXie XiuQi <xiexiuqi@huawei.com>
Date2017-09-07 10:00 +0200
Subject[PATCH v3 3/3] arm64/ras: save error address from memory section for recovery
Message-ID<umZTc-5qV-7@gated-at.bofh.it>
In reply to#1727988
In some platform, when SEA triggerred, physical address might be
reported by memory section, so we save it for error recovery later.

Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
---
 arch/arm64/kernel/ras.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/arch/arm64/kernel/ras.c b/arch/arm64/kernel/ras.c
index 797722d..b24b449 100644
--- a/arch/arm64/kernel/ras.c
+++ b/arch/arm64/kernel/ras.c
@@ -139,3 +139,34 @@ void arm_process_error(struct ghes *ghes, struct cper_sec_proc_arm *err)
 	if (info_saved)
 		set_thread_flag(TIF_SEA_NOTIFY);
 }
+
+int ghes_mem_err_callback(struct notifier_block *nb, unsigned long val, void *data)
+{
+	bool info_saved = false;
+	struct ghes_mem_err *ghes_mem = (struct ghes_mem_err *)data;
+	struct cper_sec_mem_err *mem_err = ghes_mem->mem_err;
+
+	if ((ghes_mem->notify_type != ACPI_HEST_NOTIFY_SEA) ||
+	    (ghes_mem->severity != CPER_SEV_RECOVERABLE))
+		return 0;
+
+	if (mem_err->validation_bits & CPER_MEM_VALID_PA)
+		info_saved = sea_save_info(mem_err->physical_addr);
+
+	if (info_saved)
+		set_thread_flag(TIF_SEA_NOTIFY);
+
+	return 0;
+}
+
+static struct notifier_block ghes_mem_err_nb = {
+	.notifier_call	= ghes_mem_err_callback,
+};
+
+static int arm64_err_recov_init(void)
+{
+	atomic_notifier_chain_register(&ghes_mem_err_chain, &ghes_mem_err_nb);
+	return 0;
+}
+
+late_initcall(arm64_err_recov_init);
-- 
1.8.3.1

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web