Commit 2f38b1b1 authored by Lv Zheng's avatar Lv Zheng Committed by Rafael J. Wysocki

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: 2785ce8d
  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: 2785ce8d (ACPICA: Add per-table execution of module-level code)
Reported-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Tested-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Cc: 4.5+ <stable@vger.kernel.org> # 4.5+
[ rjw : Subject ]
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent da4e7925
...@@ -108,7 +108,9 @@ acpi_ex_add_table(u32 table_index, ...@@ -108,7 +108,9 @@ acpi_ex_add_table(u32 table_index,
/* Add the table to the namespace */ /* Add the table to the namespace */
acpi_ex_exit_interpreter();
status = acpi_ns_load_table(table_index, parent_node); status = acpi_ns_load_table(table_index, parent_node);
acpi_ex_enter_interpreter();
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
acpi_ut_remove_reference(obj_desc); acpi_ut_remove_reference(obj_desc);
*ddb_handle = NULL; *ddb_handle = NULL;
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "acparser.h" #include "acparser.h"
#include "acdispat.h" #include "acdispat.h"
#include "actables.h" #include "actables.h"
#include "acinterp.h"
#define _COMPONENT ACPI_NAMESPACE #define _COMPONENT ACPI_NAMESPACE
ACPI_MODULE_NAME("nsparse") ACPI_MODULE_NAME("nsparse")
...@@ -170,6 +171,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) ...@@ -170,6 +171,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
ACPI_FUNCTION_TRACE(ns_parse_table); ACPI_FUNCTION_TRACE(ns_parse_table);
acpi_ex_enter_interpreter();
/* /*
* AML Parse, pass 1 * AML Parse, pass 1
* *
...@@ -185,7 +188,7 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node) ...@@ -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, status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
table_index, start_node); table_index, start_node);
if (ACPI_FAILURE(status)) { 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) ...@@ -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, status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
table_index, start_node); table_index, start_node);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); goto error_exit;
} }
error_exit:
acpi_ex_exit_interpreter();
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment