ACPI: OSL: Poweroff when encountering a fatal ACPI error

The ACPI spec states that the operating system should respond
to a fatal ACPI error by "performing a controlled OS shutdown in
a timely fashion". Comply with the ACPI specification by powering
off the system when ACPICA signals a fatal ACPI error. Users can
still disable this behavior by using the acpi.poweroff_on_fatal
kernel option to work around firmware bugs.

Link: https://uefi.org/specs/ACPI/6.6/19_ASL_Reference.html#fatal-fatal-error-check
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
[ rjw: Dropped the new Kconfig option, adjusted header file inclusions ]
Link: https://patch.msgid.link/20260204212931.3860-1-W_Armin@gmx.de
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Armin Wolf 2026-02-04 22:29:31 +01:00 committed by Rafael J. Wysocki
parent 6de23f81a5
commit 591230c6f2
2 changed files with 26 additions and 1 deletions

View File

@ -189,6 +189,14 @@ Kernel parameters
unusable. The "log_buf_len" parameter may be useful
if you need to capture more output.
acpi.poweroff_on_fatal= [ACPI]
{0 | 1}
Causes the system to poweroff when the ACPI bytecode signals
a fatal error. The default value of this setting is 1.
Overriding this value should only be done for diagnosing
ACPI firmware problems, as the system might behave erratically
after having encountered a fatal ACPI error.
acpi_enforce_resources= [ACPI]
{ strict | lax | no }
Check for resource conflicts between native drivers

View File

@ -13,6 +13,8 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/panic.h>
#include <linux/reboot.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/highmem.h>
@ -70,6 +72,10 @@ static bool acpi_os_initialized;
unsigned int acpi_sci_irq = INVALID_ACPI_IRQ;
bool acpi_permanent_mmap = false;
static bool poweroff_on_fatal = true;
module_param(poweroff_on_fatal, bool, 0);
MODULE_PARM_DESC(poweroff_on_fatal, "Poweroff when encountering a fatal ACPI error");
/*
* This list of permanent mappings is for memory that may be accessed from
* interrupt context, where we can't do the ioremap().
@ -1381,9 +1387,20 @@ acpi_status acpi_os_notify_command_complete(void)
acpi_status acpi_os_signal(u32 function, void *info)
{
struct acpi_signal_fatal_info *fatal_info;
switch (function) {
case ACPI_SIGNAL_FATAL:
pr_err("Fatal opcode executed\n");
fatal_info = info;
pr_emerg("Fatal error while evaluating ACPI control method\n");
pr_emerg("Type 0x%X Code 0x%X Argument 0x%X\n",
fatal_info->type, fatal_info->code, fatal_info->argument);
if (poweroff_on_fatal)
orderly_poweroff(true);
else
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
break;
case ACPI_SIGNAL_BREAKPOINT:
/*