Commit 9febcdc0 authored by Lv Zheng's avatar Lv Zheng Committed by Rafael J. Wysocki

ACPICA: Tables: Fix "UNLOAD" code path lock issues

ACPICA commit 39227380f5b99c51b897a3ffedd88508aa26789b

The previous lock fixes didn't cover "Unload" opcode and table unload APIs,
this patch fixes lock issues in the "Unload" code path. BZ 1325, Lv Zheng.

Link: https://github.com/acpica/acpica/commit/39227380
Link: https://bugs.acpica.org/show_bug.cgi?id=1325Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 86ec64bc
...@@ -532,10 +532,17 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) ...@@ -532,10 +532,17 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
table_index = table_desc->reference.value; table_index = table_desc->reference.value;
/*
* Release the interpreter lock so that the table lock won't have
* strict order requirement against it.
*/
acpi_ex_exit_interpreter();
/* Ensure the table is still loaded */ /* Ensure the table is still loaded */
if (!acpi_tb_is_table_loaded(table_index)) { if (!acpi_tb_is_table_loaded(table_index)) {
return_ACPI_STATUS(AE_NOT_EXIST); status = AE_NOT_EXIST;
goto lock_and_exit;
} }
/* Invoke table handler if present */ /* Invoke table handler if present */
...@@ -553,16 +560,24 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle) ...@@ -553,16 +560,24 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
status = acpi_tb_delete_namespace_by_owner(table_index); status = acpi_tb_delete_namespace_by_owner(table_index);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); goto lock_and_exit;
} }
(void)acpi_tb_release_owner_id(table_index); (void)acpi_tb_release_owner_id(table_index);
acpi_tb_set_table_loaded_flag(table_index, FALSE); acpi_tb_set_table_loaded_flag(table_index, FALSE);
lock_and_exit:
/* Re-acquire the interpreter lock */
acpi_ex_enter_interpreter();
/* /*
* Invalidate the handle. We do this because the handle may be stored * Invalidate the handle. We do this because the handle may be stored
* in a named object and may not be actually deleted until much later. * in a named object and may not be actually deleted until much later.
*/ */
ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID; if (ACPI_SUCCESS(status)) {
return_ACPI_STATUS(AE_OK); ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID;
}
return_ACPI_STATUS(status);
} }
...@@ -614,17 +614,12 @@ acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) ...@@ -614,17 +614,12 @@ acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
* lock may block, and also since the execution of a namespace walk * lock may block, and also since the execution of a namespace walk
* must be allowed to use the interpreter. * must be allowed to use the interpreter.
*/ */
(void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
acpi_ns_delete_namespace_by_owner(owner_id);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
acpi_ns_delete_namespace_by_owner(owner_id);
acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
......
...@@ -378,9 +378,9 @@ acpi_status acpi_unload_parent_table(acpi_handle object) ...@@ -378,9 +378,9 @@ acpi_status acpi_unload_parent_table(acpi_handle object)
return_ACPI_STATUS(AE_TYPE); return_ACPI_STATUS(AE_TYPE);
} }
/* Must acquire the interpreter lock during this operation */ /* Must acquire the table lock during this operation */
status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -407,8 +407,10 @@ acpi_status acpi_unload_parent_table(acpi_handle object) ...@@ -407,8 +407,10 @@ acpi_status acpi_unload_parent_table(acpi_handle object)
/* Ensure the table is actually loaded */ /* Ensure the table is actually loaded */
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
if (!acpi_tb_is_table_loaded(i)) { if (!acpi_tb_is_table_loaded(i)) {
status = AE_NOT_EXIST; status = AE_NOT_EXIST;
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
break; break;
} }
...@@ -434,10 +436,11 @@ acpi_status acpi_unload_parent_table(acpi_handle object) ...@@ -434,10 +436,11 @@ acpi_status acpi_unload_parent_table(acpi_handle object)
status = acpi_tb_release_owner_id(i); status = acpi_tb_release_owner_id(i);
acpi_tb_set_table_loaded_flag(i, FALSE); acpi_tb_set_table_loaded_flag(i, FALSE);
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
break; break;
} }
(void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
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