All of lore.kernel.org
 help / color / mirror / Atom feed
From: Xie XiuQi <xiexiuqi@huawei.com>
To: <catalin.marinas@arm.com>, <will@kernel.org>,
	<james.morse@arm.com>, <bp@alien8.de>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-acpi@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Cc: <tanxiaofei@huawei.com>, <lvying6@huawei.com>
Subject: [PATCH] arm64: fix error unhandling in synchronous External Data Abort
Date: Mon, 14 Nov 2022 23:19:15 +0800	[thread overview]
Message-ID: <20221114151915.167414-1-xiexiuqi@huawei.com> (raw)

According to the RAS documentation, if we cannot determine the impact
of the error based on the details of the error when an SEA occurs, the
process cannot safely continue to run. Therefore, for unhandled error,
we should signal the system and terminate the process immediately.

2.2 Generating error exceptions:
  "An error exception is generated when a detected error is signaled
  to the PE as an in-band error response to an architecturally-executed
  memory access or cache maintenance operation. This includes any explicit
  data access, instruction fetch, translation table walk, or hardware
  update to the translation tables made by an architecturally-executed
  instruction." [1]

2.3 Taking error exceptions:
  Software is only able to successfully recover execution and make progress
  from a restart address for the exception by executing an Exception Return
  instruction to branch to the instruction at this restart address if all
  of the following are true: [2]
    - The error has not been silently propagated by the PE.
    - At the point when the Exception Return instruction is executed, the
      PE state and memory system state are consistent with the PE having
      executed all of the instructions up to but not including the
      instruction at the restart address, and none afterwards. That is,
      at least one of the following restart conditions is true:
        - The error has been not architecturally consumed by the PE
          andinfected the PE state.
        - Executing the instruction at the restart address will not consume
          the error and will correct any corrupt state by overwriting it
          with the correct value or values

After commit 8fcc4ae6faf8 ("arm64: acpi: Make apei_claim_sea() synchronise
with APEI's irq work"), we deferred de SEA process to irq_work.
For example, an memory reading error without valid pa, the process isn't
been terminated. It is not safe.

In this patch, a SIGBUS is force signaled to fix this case.

Note:
RAS documentation: https://developer.arm.com/documentation/ddi0587/latest

Fixes: 8fcc4ae6faf8 ("arm64: acpi: Make apei_claim_sea() synchronise with APEI's irq work")
Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
---
 arch/arm64/kernel/acpi.c      |  6 ++++++
 drivers/acpi/apei/apei-base.c |  4 ++++
 drivers/acpi/apei/ghes.c      | 14 +++++++++++---
 include/acpi/apei.h           |  1 +
 4 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index a5a256e3f9fe..a8cb02ddaf33 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -32,6 +32,7 @@
 #include <asm/cpu_ops.h>
 #include <asm/daifflags.h>
 #include <asm/smp_plat.h>
+#include <asm/traps.h>
 
 int acpi_noirq = 1;		/* skip ACPI IRQ initialization */
 int acpi_disabled = 1;
@@ -407,6 +408,11 @@ int apei_claim_sea(struct pt_regs *regs)
 	return err;
 }
 
+void arch_apei_do_unhandled_sea(void)
+{
+	arm64_force_sig_mceerr(BUS_MCEERR_AR, 0, 0, "Unhandled processor error");
+}
+
 void arch_reserve_mem_area(acpi_physical_address addr, size_t size)
 {
 	memblock_mark_nomap(addr, size);
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index 9b52482b4ed5..f372cf872125 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -773,6 +773,10 @@ void __weak arch_apei_report_mem_error(int sev,
 }
 EXPORT_SYMBOL_GPL(arch_apei_report_mem_error);
 
+void __weak arch_apei_do_unhandled_sea(void)
+{
+}
+
 int apei_osc_setup(void)
 {
 	static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c";
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 9952f3a792ba..7da39da4577a 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -48,6 +48,7 @@
 #include <asm/fixmap.h>
 #include <asm/tlbflush.h>
 #include <ras/ras_event.h>
+#include <asm/traps.h>
 
 #include "apei-internal.h"
 
@@ -483,11 +484,12 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
 	return false;
 }
 
-static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int sev)
+static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata,
+				     int sev, int type)
 {
 	struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
 	bool queued = false;
-	int sec_sev, i;
+	int sec_sev, i, unhandled_err_count = 0;
 	char *p;
 
 	log_arm_hw_error(err);
@@ -521,9 +523,14 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int s
 		pr_warn_ratelimited(FW_WARN GHES_PFX
 				    "Unhandled processor error type: %s\n",
 				    error_type);
+		unhandled_err_count++;
+
 		p += err_info->length;
 	}
 
+	if (unhandled_err_count && type == ACPI_HEST_NOTIFY_SEA)
+		arch_apei_do_unhandled_sea();
+
 	return queued;
 }
 
@@ -631,6 +638,7 @@ static bool ghes_do_proc(struct ghes *ghes,
 	const guid_t *fru_id = &guid_null;
 	char *fru_text = "";
 	bool queued = false;
+	int type = ghes->generic->notify.type;
 
 	sev = ghes_severity(estatus->error_severity);
 	apei_estatus_for_each_section(estatus, gdata) {
@@ -654,7 +662,7 @@ static bool ghes_do_proc(struct ghes *ghes,
 			ghes_handle_aer(gdata);
 		}
 		else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
-			queued = ghes_handle_arm_hw_error(gdata, sev);
+			queued = ghes_handle_arm_hw_error(gdata, sev, type);
 		} else {
 			void *err = acpi_hest_get_payload(gdata);
 
diff --git a/include/acpi/apei.h b/include/acpi/apei.h
index dc60f7db5524..663db1f9556f 100644
--- a/include/acpi/apei.h
+++ b/include/acpi/apei.h
@@ -52,6 +52,7 @@ int erst_clear(u64 record_id);
 
 int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data);
 void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
+void arch_apei_do_unhandled_sea(void);
 
 #endif
 #endif
-- 
2.20.1


WARNING: multiple messages have this Message-ID (diff)
From: Xie XiuQi <xiexiuqi@huawei.com>
To: <catalin.marinas@arm.com>, <will@kernel.org>,
	<james.morse@arm.com>, <bp@alien8.de>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-acpi@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Cc: <tanxiaofei@huawei.com>, <lvying6@huawei.com>
Subject: [PATCH] arm64: fix error unhandling in synchronous External Data Abort
Date: Mon, 14 Nov 2022 23:19:15 +0800	[thread overview]
Message-ID: <20221114151915.167414-1-xiexiuqi@huawei.com> (raw)

According to the RAS documentation, if we cannot determine the impact
of the error based on the details of the error when an SEA occurs, the
process cannot safely continue to run. Therefore, for unhandled error,
we should signal the system and terminate the process immediately.

2.2 Generating error exceptions:
  "An error exception is generated when a detected error is signaled
  to the PE as an in-band error response to an architecturally-executed
  memory access or cache maintenance operation. This includes any explicit
  data access, instruction fetch, translation table walk, or hardware
  update to the translation tables made by an architecturally-executed
  instruction." [1]

2.3 Taking error exceptions:
  Software is only able to successfully recover execution and make progress
  from a restart address for the exception by executing an Exception Return
  instruction to branch to the instruction at this restart address if all
  of the following are true: [2]
    - The error has not been silently propagated by the PE.
    - At the point when the Exception Return instruction is executed, the
      PE state and memory system state are consistent with the PE having
      executed all of the instructions up to but not including the
      instruction at the restart address, and none afterwards. That is,
      at least one of the following restart conditions is true:
        - The error has been not architecturally consumed by the PE
          andinfected the PE state.
        - Executing the instruction at the restart address will not consume
          the error and will correct any corrupt state by overwriting it
          with the correct value or values

After commit 8fcc4ae6faf8 ("arm64: acpi: Make apei_claim_sea() synchronise
with APEI's irq work"), we deferred de SEA process to irq_work.
For example, an memory reading error without valid pa, the process isn't
been terminated. It is not safe.

In this patch, a SIGBUS is force signaled to fix this case.

Note:
RAS documentation: https://developer.arm.com/documentation/ddi0587/latest

Fixes: 8fcc4ae6faf8 ("arm64: acpi: Make apei_claim_sea() synchronise with APEI's irq work")
Signed-off-by: Xie XiuQi <xiexiuqi@huawei.com>
---
 arch/arm64/kernel/acpi.c      |  6 ++++++
 drivers/acpi/apei/apei-base.c |  4 ++++
 drivers/acpi/apei/ghes.c      | 14 +++++++++++---
 include/acpi/apei.h           |  1 +
 4 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c
index a5a256e3f9fe..a8cb02ddaf33 100644
--- a/arch/arm64/kernel/acpi.c
+++ b/arch/arm64/kernel/acpi.c
@@ -32,6 +32,7 @@
 #include <asm/cpu_ops.h>
 #include <asm/daifflags.h>
 #include <asm/smp_plat.h>
+#include <asm/traps.h>
 
 int acpi_noirq = 1;		/* skip ACPI IRQ initialization */
 int acpi_disabled = 1;
@@ -407,6 +408,11 @@ int apei_claim_sea(struct pt_regs *regs)
 	return err;
 }
 
+void arch_apei_do_unhandled_sea(void)
+{
+	arm64_force_sig_mceerr(BUS_MCEERR_AR, 0, 0, "Unhandled processor error");
+}
+
 void arch_reserve_mem_area(acpi_physical_address addr, size_t size)
 {
 	memblock_mark_nomap(addr, size);
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index 9b52482b4ed5..f372cf872125 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -773,6 +773,10 @@ void __weak arch_apei_report_mem_error(int sev,
 }
 EXPORT_SYMBOL_GPL(arch_apei_report_mem_error);
 
+void __weak arch_apei_do_unhandled_sea(void)
+{
+}
+
 int apei_osc_setup(void)
 {
 	static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c";
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 9952f3a792ba..7da39da4577a 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -48,6 +48,7 @@
 #include <asm/fixmap.h>
 #include <asm/tlbflush.h>
 #include <ras/ras_event.h>
+#include <asm/traps.h>
 
 #include "apei-internal.h"
 
@@ -483,11 +484,12 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata,
 	return false;
 }
 
-static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int sev)
+static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata,
+				     int sev, int type)
 {
 	struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata);
 	bool queued = false;
-	int sec_sev, i;
+	int sec_sev, i, unhandled_err_count = 0;
 	char *p;
 
 	log_arm_hw_error(err);
@@ -521,9 +523,14 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, int s
 		pr_warn_ratelimited(FW_WARN GHES_PFX
 				    "Unhandled processor error type: %s\n",
 				    error_type);
+		unhandled_err_count++;
+
 		p += err_info->length;
 	}
 
+	if (unhandled_err_count && type == ACPI_HEST_NOTIFY_SEA)
+		arch_apei_do_unhandled_sea();
+
 	return queued;
 }
 
@@ -631,6 +638,7 @@ static bool ghes_do_proc(struct ghes *ghes,
 	const guid_t *fru_id = &guid_null;
 	char *fru_text = "";
 	bool queued = false;
+	int type = ghes->generic->notify.type;
 
 	sev = ghes_severity(estatus->error_severity);
 	apei_estatus_for_each_section(estatus, gdata) {
@@ -654,7 +662,7 @@ static bool ghes_do_proc(struct ghes *ghes,
 			ghes_handle_aer(gdata);
 		}
 		else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
-			queued = ghes_handle_arm_hw_error(gdata, sev);
+			queued = ghes_handle_arm_hw_error(gdata, sev, type);
 		} else {
 			void *err = acpi_hest_get_payload(gdata);
 
diff --git a/include/acpi/apei.h b/include/acpi/apei.h
index dc60f7db5524..663db1f9556f 100644
--- a/include/acpi/apei.h
+++ b/include/acpi/apei.h
@@ -52,6 +52,7 @@ int erst_clear(u64 record_id);
 
 int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data);
 void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
+void arch_apei_do_unhandled_sea(void);
 
 #endif
 #endif
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

             reply	other threads:[~2022-11-14 15:01 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-14 15:19 Xie XiuQi [this message]
2022-11-14 15:19 ` [PATCH] arm64: fix error unhandling in synchronous External Data Abort Xie XiuQi
2022-11-14 22:42 ` kernel test robot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221114151915.167414-1-xiexiuqi@huawei.com \
    --to=xiexiuqi@huawei.com \
    --cc=bp@alien8.de \
    --cc=catalin.marinas@arm.com \
    --cc=james.morse@arm.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lvying6@huawei.com \
    --cc=tanxiaofei@huawei.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.