Commit 591230c6 authored by Armin Wolf's avatar Armin Wolf Committed by Rafael J. Wysocki
Browse files

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: default avatarArmin 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: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 6de23f81
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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
+18 −1
Original line number Diff line number Diff line
@@ -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:
		/*