ACPI: ACPICA 20060512

Replaced the acpi_os_queue_for_execution() with a new
interface named acpi_os_execute(). The major difference is
that the new interface does not have a Priority parameter,
this appeared to be useless and has been replaced by
a Type parameter. The Type tells the OS what type of
execution is being requested, such as global lock handler,
notify handler, GPE handler, etc. This allows the host
to queue and execute the request as appropriate for the
request type, possibly using different work queues and
different priorities for the various request types. This
enables fixes for multithreading deadlock problems such as
http://bugzilla.kernel.org/show_bug.cgi?id=5534
(Alexey Starikovskiy and Bob Moore)

Fixed a possible memory leak associated with the
support for the so-called "implicit return" ACPI
extension. Reported by FreeBSD  (Fiodor Suietov)
http://bugzilla.kernel.org/show_bug.cgi?id=6514

Fixed a problem with the Load() operator where a table
load from an operation region could overwrite an internal
table buffer by up to 7 bytes and cause alignment faults
on IPF systems. (With assistance from Luming Yu)

Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 9c46f33..9ae3cb5 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -298,6 +298,7 @@
 	struct acpi_table_header *table_ptr = NULL;
 	acpi_physical_address address;
 	struct acpi_table_header table_header;
+	acpi_integer temp;
 	u32 i;
 
 	ACPI_FUNCTION_TRACE(ex_load_op);
@@ -326,7 +327,7 @@
 
 		address = obj_desc->region.address;
 
-		/* Get the table length from the table header */
+		/* Get part of the table header to get the table length */
 
 		table_header.length = 0;
 		for (i = 0; i < 8; i++) {
@@ -334,11 +335,14 @@
 			    acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
 							   (acpi_physical_address)
 							   (i + address), 8,
-							   ((u8 *) &
-							    table_header) + i);
+							   &temp);
 			if (ACPI_FAILURE(status)) {
 				return_ACPI_STATUS(status);
 			}
+
+			/* Get the one valid byte of the returned 64-bit value */
+
+			ACPI_CAST_PTR(u8, &table_header)[i] = (u8) temp;
 		}
 
 		/* Sanity check the table length */
@@ -361,11 +365,14 @@
 			    acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
 							   (acpi_physical_address)
 							   (i + address), 8,
-							   ((u8 *) table_ptr +
-							    i));
+							   &temp);
 			if (ACPI_FAILURE(status)) {
 				goto cleanup;
 			}
+
+			/* Get the one valid byte of the returned 64-bit value */
+
+			ACPI_CAST_PTR(u8, table_ptr)[i] = (u8) temp;
 		}
 		break;