Skip to content

Commit e2ffcda

Browse files
committed
ACPI: OSL: Allow Notify () handlers to run on all CPUs
Notify () handlers, like GPE handlers, are only allowed to run on CPU0 now out of the concern that they might trigger an SMM trap leading to memory corruption. Namely, in some cases, SMM code might corrupt memory if not run on CPU0. However, Notify () handlers are registered by kernel code and they are not likely to evaluate AML that would trigger an SMM trap. In fact, many of them don't even evaluate any AML at all and even if they do, that AML may as well be evaluated in other code paths. In other words, they are not special from the AML evaluation perspective, so there is no real reason to treat them in any special way. Accordingly, allow Notify () handlers, unlike GPE handlers, to be executed by all CPUs in the system. Also adjust the allocation of the "notify" workqueue to allow multiple handlers to be executed at the same time, because they need not be serialized. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
1 parent 3f3a259 commit e2ffcda

File tree

1 file changed

+10
-13
lines changed

1 file changed

+10
-13
lines changed

drivers/acpi/osl.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,7 +1061,6 @@ acpi_status acpi_os_execute(acpi_execute_type type,
10611061
acpi_osd_exec_callback function, void *context)
10621062
{
10631063
struct acpi_os_dpc *dpc;
1064-
struct workqueue_struct *queue;
10651064
int ret;
10661065

10671066
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -1101,24 +1100,22 @@ acpi_status acpi_os_execute(acpi_execute_type type,
11011100
*/
11021101
switch (type) {
11031102
case OSL_NOTIFY_HANDLER:
1104-
queue = kacpi_notify_wq;
1103+
ret = queue_work(kacpi_notify_wq, &dpc->work);
11051104
break;
11061105
case OSL_GPE_HANDLER:
1107-
queue = kacpid_wq;
1106+
/*
1107+
* On some machines, a software-initiated SMI causes corruption
1108+
* unless the SMI runs on CPU 0. An SMI can be initiated by
1109+
* any AML, but typically it's done in GPE-related methods that
1110+
* are run via workqueues, so we can avoid the known corruption
1111+
* cases by always queueing on CPU 0.
1112+
*/
1113+
ret = queue_work_on(0, kacpid_wq, &dpc->work);
11081114
break;
11091115
default:
11101116
pr_err("Unsupported os_execute type %d.\n", type);
11111117
goto err;
11121118
}
1113-
1114-
/*
1115-
* On some machines, a software-initiated SMI causes corruption unless
1116-
* the SMI runs on CPU 0. An SMI can be initiated by any AML, but
1117-
* typically it's done in GPE-related methods that are run via
1118-
* workqueues, so we can avoid the known corruption cases by always
1119-
* queueing on CPU 0.
1120-
*/
1121-
ret = queue_work_on(0, queue, &dpc->work);
11221119
if (!ret) {
11231120
pr_err("Unable to queue work\n");
11241121
goto err;
@@ -1668,7 +1665,7 @@ acpi_status __init acpi_os_initialize(void)
16681665
acpi_status __init acpi_os_initialize1(void)
16691666
{
16701667
kacpid_wq = alloc_workqueue("kacpid", 0, 1);
1671-
kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 1);
1668+
kacpi_notify_wq = alloc_workqueue("kacpi_notify", 0, 0);
16721669
kacpi_hotplug_wq = alloc_ordered_workqueue("kacpi_hotplug", 0);
16731670
BUG_ON(!kacpid_wq);
16741671
BUG_ON(!kacpi_notify_wq);

0 commit comments

Comments
 (0)