Commit 4712f71b authored by Bob Moore's avatar Bob Moore Committed by Rafael J. Wysocki
Browse files

ACPICA: Correctly cleanup after a ACPI table load failure

ACPICA commit ed7769e832de6c7ba90615480d916c85fd100422

If a table load fails, delete all namespace objects created by the
table, otherwise these objects will be uninitialized, causing
problems later. This appears to be a very rare problem.
Also handle the unitialized node problem to prevent possible
faults. ACPICA BZ 1185.

Link: https://github.com/acpica/acpica/commit/ed7769e8


Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 40913fe6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
	if (!source_desc) {
		ACPI_ERROR((AE_INFO, "No object attached to node [%4.4s] %p",
			    node->name.ascii, node));
		return_ACPI_STATUS(AE_AML_NO_OPERAND);
		return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE);
	}

	/*
+11 −5
Original line number Diff line number Diff line
@@ -337,8 +337,9 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
			 acpi_object_type * return_type,
			 union acpi_operand_object **return_desc)
{
	union acpi_operand_object *obj_desc = (void *)operand;
	struct acpi_namespace_node *node;
	union acpi_operand_object *obj_desc = ACPI_CAST_PTR(void, operand);
	struct acpi_namespace_node *node =
	    ACPI_CAST_PTR(struct acpi_namespace_node, operand);
	acpi_object_type type;
	acpi_status status;

@@ -355,9 +356,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
	case ACPI_DESC_TYPE_NAMED:

		type = ((struct acpi_namespace_node *)obj_desc)->type;
		obj_desc =
		    acpi_ns_get_attached_object((struct acpi_namespace_node *)
						obj_desc);
		obj_desc = acpi_ns_get_attached_object(node);

		/* If we had an Alias node, use the attached object for type info */

@@ -368,6 +367,13 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
							 acpi_namespace_node *)
							obj_desc);
		}

		if (!obj_desc) {
			ACPI_ERROR((AE_INFO,
				    "[%4.4s] Node is unresolved or uninitialized",
				    acpi_ut_get_node_name(node)));
			return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE);
		}
		break;

	default:
+1 −0
Original line number Diff line number Diff line
@@ -274,6 +274,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
		acpi_ex_exit_interpreter();

		if (ACPI_FAILURE(status)) {
			info->return_object = NULL;
			goto cleanup;
		}

+15 −1
Original line number Diff line number Diff line
@@ -111,7 +111,21 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
	if (ACPI_SUCCESS(status)) {
		acpi_tb_set_table_loaded_flag(table_index, TRUE);
	} else {
		(void)acpi_tb_release_owner_id(table_index);
		/*
		 * On error, delete any namespace objects created by this table.
		 * We cannot initialize these objects, so delete them. There are
		 * a couple of expecially bad cases:
		 * AE_ALREADY_EXISTS - namespace collision.
		 * AE_NOT_FOUND - the target of a Scope operator does not
		 * exist. This target of Scope must already exist in the
		 * namespace, as per the ACPI specification.
		 */
		(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
		acpi_ns_delete_namespace_by_owner(acpi_gbl_root_table_list.
						  tables[table_index].owner_id);
		acpi_tb_release_owner_id(table_index);

		return_ACPI_STATUS(status);
	}

unlock:
+26 −3
Original line number Diff line number Diff line
@@ -102,6 +102,8 @@ static acpi_status acpi_tb_load_namespace(void)
	acpi_status status;
	u32 i;
	struct acpi_table_header *new_dsdt;
	u32 tables_loaded = 0;
	u32 tables_failed = 0;

	ACPI_FUNCTION_TRACE(tb_load_namespace);

@@ -159,7 +161,10 @@ static acpi_status acpi_tb_load_namespace(void)

	status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
	if (ACPI_FAILURE(status)) {
		return_ACPI_STATUS(status);
		ACPI_EXCEPTION((AE_INFO, status, "[DSDT] table load failed"));
		tables_failed++;
	} else {
		tables_loaded++;
	}

	/* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
@@ -187,11 +192,29 @@ static acpi_status acpi_tb_load_namespace(void)
		/* Ignore errors while loading tables, get as many as possible */

		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
		(void)acpi_ns_load_table(i, acpi_gbl_root_node);
		status = acpi_ns_load_table(i, acpi_gbl_root_node);
		if (ACPI_FAILURE(status)) {
			ACPI_EXCEPTION((AE_INFO, status,
					"[%4.4s] table load failed",
					&acpi_gbl_root_table_list.tables[i].
					signature.ascii[0]));
			tables_failed++;
		} else {
			tables_loaded++;
		}

		(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
	}

	ACPI_INFO((AE_INFO, "All ACPI Tables successfully acquired"));
	if (!tables_failed) {
		ACPI_INFO((AE_INFO,
			   "All (%u) ACPI AML tables successfully loaded",
			   tables_loaded));
	} else {
		ACPI_ERROR((AE_INFO,
			    "%u ACPI AML tables loaded, %u failed",
			    tables_loaded, tables_failed));
	}

unlock_and_exit:
	(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
Loading