diff options
author | Lv Zheng <lv.zheng@intel.com> | 2016-06-21 12:34:15 +0800 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-06-22 01:07:35 +0200 |
commit | 2f38b1b16d9280689e5cfa47a4c50956bf437f0d (patch) | |
tree | 5ce8811934caf7d10eed25f693f9ada91d97096b | |
parent | da4e792550a856e2f66aa8183d408553f7513a86 (diff) |
ACPICA: Namespace: Fix deadlock triggered by MLC support in dynamic table loading
The new module-level code (MLC) approach invokes MLC on the per-table
basis, but the dynamic loading support of this is incorrect because
of the lock order:
acpi_ns_evaluate
acpi_ex_enter_intperter
acpi_ns_load_table (triggered by Load opcode)
acpi_ns_exec_module_code_list
acpi_ex_enter_intperter
The regression is introduced by the following commit:
Commit: 2785ce8d0da1cac9d8f78615e116cf929e9a9123
ACPICA Commit: 071eff738c59eda1792ac24b3b688b61691d7e7c
Subject: ACPICA: Add per-table execution of module-level code
This patch fixes this regression by unlocking the interpreter lock
before invoking MLC. However, the unlocking is done to the
acpi_ns_load_table(), in which the interpreter lock should be locked
by acpi_ns_parse_table() but it wasn't.
Fixes: 2785ce8d0da1 (ACPICA: Add per-table execution of module-level code)
Reported-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Lv Zheng <lv.zheng@intel.com>
Cc: 4.5+ <stable@vger.kernel.org> # 4.5+
[ rjw : Subject ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r-- | drivers/acpi/acpica/exconfig.c | 2 | ||||
-rw-r--r-- | drivers/acpi/acpica/nsparse.c | 9 |
2 files changed, 9 insertions, 2 deletions
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index a1d177d58254..21932d640a41 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -108,7 +108,9 @@ acpi_ex_add_table(u32 table_index, /* Add the table to the namespace */ + acpi_ex_exit_interpreter(); status = acpi_ns_load_table(table_index, parent_node); + acpi_ex_enter_interpreter(); if (ACPI_FAILURE(status)) { acpi_ut_remove_reference(obj_desc); *ddb_handle = NULL; diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c index f631a47724f0..1783cd7e1446 100644 --- a/drivers/acpi/acpica/nsparse.c +++ b/drivers/acpi/acpica/nsparse.c @@ -47,6 +47,7 @@ #include "acparser.h" #include "acdispat.h" #include "actables.h" +#include "acinterp.h" #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsparse") @@ -170,6 +171,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) ACPI_FUNCTION_TRACE(ns_parse_table); + acpi_ex_enter_interpreter(); + /* * AML Parse, pass 1 * @@ -185,7 +188,7 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index, start_node); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + goto error_exit; } /* @@ -201,8 +204,10 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index, start_node); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + goto error_exit; } +error_exit: + acpi_ex_exit_interpreter(); return_ACPI_STATUS(status); } |