]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ACPI: APEI: send SIGBUS to current task if synchronous memory error not recovered
authorShuai Xue <xueshuai@linux.alibaba.com>
Mon, 14 Jul 2025 11:42:11 +0000 (19:42 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 28 Aug 2025 14:28:16 +0000 (16:28 +0200)
[ 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

index 2abf20736702c0dfe6c5ef9d90ddeb15cdc5bf79..22db720b128b2bdcd2273dbcb2634790a85c2c5a 100644 (file)
@@ -715,6 +715,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;
 }