| From e3cbf2c754b39cb7d150a0b6a8caa251c211436e Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 14 Jul 2025 19:42:11 +0800 |
| Subject: ACPI: APEI: send SIGBUS to current task if synchronous memory error |
| not recovered |
| |
| From: Shuai Xue <xueshuai@linux.alibaba.com> |
| |
| [ Upstream commit 79a5ae3c4c5eb7e38e0ebe4d6bf602d296080060 ] |
| |
| If a synchronous error is detected as a result of user-space process |
| triggering a 2-bit uncorrected error, the CPU will take a synchronous |
| error exception such as Synchronous External Abort (SEA) on Arm64. The |
| kernel will queue a memory_failure() work which poisons the related |
| page, unmaps the page, and then sends a SIGBUS to the process, so that |
| a system wide panic can be avoided. |
| |
| However, no memory_failure() work will be queued when abnormal |
| synchronous errors occur. These errors can include situations like |
| invalid PA, unexpected severity, no memory failure config support, |
| invalid GUID section, etc. In such a case, the user-space process will |
| trigger SEA again. This loop can potentially exceed the platform |
| firmware threshold or even trigger a kernel hard lockup, leading to a |
| system reboot. |
| |
| Fix it by performing a force kill if no memory_failure() work is queued |
| for synchronous errors. |
| |
| Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com> |
| Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> |
| Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> |
| Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com> |
| Reviewed-by: Jane Chu <jane.chu@oracle.com> |
| Reviewed-by: Hanjun Guo <guohanjun@huawei.com> |
| Link: https://patch.msgid.link/20250714114212.31660-2-xueshuai@linux.alibaba.com |
| [ rjw: Changelog edits ] |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/acpi/apei/ghes.c | 11 +++++++++++ |
| 1 file changed, 11 insertions(+) |
| |
| diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c |
| index f0584ccad451..281a0a2f6730 100644 |
| --- a/drivers/acpi/apei/ghes.c |
| +++ b/drivers/acpi/apei/ghes.c |
| @@ -902,6 +902,17 @@ static bool ghes_do_proc(struct ghes *ghes, |
| } |
| } |
| |
| + /* |
| + * If no memory failure work is queued for abnormal synchronous |
| + * errors, do a force kill. |
| + */ |
| + if (sync && !queued) { |
| + dev_err(ghes->dev, |
| + HW_ERR GHES_PFX "%s:%d: synchronous unrecoverable error (SIGBUS)\n", |
| + current->comm, task_pid_nr(current)); |
| + force_sig(SIGBUS); |
| + } |
| + |
| return queued; |
| } |
| |
| -- |
| 2.39.5 |
| |