mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Len Brown <lenb@kernel.org>
To: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: Dennis Noordsij <dennis.noordsij@helsinki.fi>,
	Bob Moore <robert.moore@intel.com>,
	Lin Ming <ming.m.lin@intel.com>, Andi Kleen <ak@linux.intel.com>,
	Len Brown <len.brown@intel.com>
Subject: [PATCH 08/85] ACPICA: Copy dynamically loaded tables to local buffer
Date: Sat, 11 Oct 2008 02:35:28 -0400	[thread overview]
Message-ID: <a4377db47f9b0586f32ed7beddb53c86d5ef422d.1223706853.git.len.brown@intel.com> (raw)
In-Reply-To: <1223707005-26864-1-git-send-email-lenb@kernel.org>
In-Reply-To: <1d80ebdb81444701024ad9b9f026516561496a43.1223706853.git.len.brown@intel.com>

From: Dennis Noordsij <dennis.noordsij@helsinki.fi>

Previously, dynamically loaded tables were simply mapped, but on some machines
this memory is corrupted after suspend. Now copy the table to a local buffer.
For OpRegion case, added checksum verify. Use the table length from the table header,
not the region length. For Buffer case, use the table length also.

http://bugzilla.kernel.org/show_bug.cgi?id=10734

Signed-off-by: Dennis Noordsij <dennis.noordsij@helsinki.fi>
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Lin Ming <ming.m.lin@intel.com>
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/executer/exconfig.c |  113 +++++++++++++++++++++++++++----------
 1 files changed, 82 insertions(+), 31 deletions(-)

diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 8892b98..331a114 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -280,6 +280,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 		struct acpi_walk_state *walk_state)
 {
 	union acpi_operand_object *ddb_handle;
+	struct acpi_table_header *table;
 	struct acpi_table_desc table_desc;
 	u32 table_index;
 	acpi_status status;
@@ -294,9 +295,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 	switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
 	case ACPI_TYPE_REGION:
 
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n",
-				  obj_desc,
-				  acpi_ut_get_object_type_name(obj_desc)));
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "Load table from Region %p\n", obj_desc));
 
 		/* Region must be system_memory (from ACPI spec) */
 
@@ -316,61 +316,112 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 		}
 
 		/*
-		 * We will simply map the memory region for the table. However, the
-		 * memory region is technically not guaranteed to remain stable and
-		 * we may eventually have to copy the table to a local buffer.
+		 * Map the table header and get the actual table length. The region
+		 * length is not guaranteed to be the same as the table length.
+		 */
+		table = acpi_os_map_memory(obj_desc->region.address,
+					   sizeof(struct acpi_table_header));
+		if (!table) {
+			return_ACPI_STATUS(AE_NO_MEMORY);
+		}
+
+		length = table->length;
+		acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+
+		/* Must have at least an ACPI table header */
+
+		if (length < sizeof(struct acpi_table_header)) {
+			return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
+		}
+
+		/*
+		 * The memory region is not guaranteed to remain stable and we must
+		 * copy the table to a local buffer. For example, the memory region
+		 * is corrupted after suspend on some machines. Dynamically loaded
+		 * tables are usually small, so this overhead is minimal.
 		 */
+
+		/* Allocate a buffer for the table */
+
+		table_desc.pointer = ACPI_ALLOCATE(length);
+		if (!table_desc.pointer) {
+			return_ACPI_STATUS(AE_NO_MEMORY);
+		}
+
+		/* Map the entire table and copy it */
+
+		table = acpi_os_map_memory(obj_desc->region.address, length);
+		if (!table) {
+			ACPI_FREE(table_desc.pointer);
+			return_ACPI_STATUS(AE_NO_MEMORY);
+		}
+
+		ACPI_MEMCPY(table_desc.pointer, table, length);
+		acpi_os_unmap_memory(table, length);
+
 		table_desc.address = obj_desc->region.address;
-		table_desc.length = obj_desc->region.length;
-		table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
 		break;
 
 	case ACPI_TYPE_BUFFER:	/* Buffer or resolved region_field */
 
 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "Load from Buffer or Field %p %s\n", obj_desc,
-				  acpi_ut_get_object_type_name(obj_desc)));
-
-		length = obj_desc->buffer.length;
+				  "Load table from Buffer or Field %p\n",
+				  obj_desc));
 
 		/* Must have at least an ACPI table header */
 
-		if (length < sizeof(struct acpi_table_header)) {
+		if (obj_desc->buffer.length < sizeof(struct acpi_table_header)) {
 			return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
 		}
 
-		/* Validate checksum here. It won't get validated in tb_add_table */
+		/* Get the actual table length from the table header */
 
-		status =
-		    acpi_tb_verify_checksum(ACPI_CAST_PTR
-					    (struct acpi_table_header,
-					     obj_desc->buffer.pointer), length);
-		if (ACPI_FAILURE(status)) {
-			return_ACPI_STATUS(status);
+		table =
+		    ACPI_CAST_PTR(struct acpi_table_header,
+				  obj_desc->buffer.pointer);
+		length = table->length;
+
+		/* Table cannot extend beyond the buffer */
+
+		if (length > obj_desc->buffer.length) {
+			return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
+		}
+		if (length < sizeof(struct acpi_table_header)) {
+			return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
 		}
 
 		/*
-		 * We need to copy the buffer since the original buffer could be
-		 * changed or deleted in the future
+		 * Copy the table from the buffer because the buffer could be modified
+		 * or even deleted in the future
 		 */
 		table_desc.pointer = ACPI_ALLOCATE(length);
 		if (!table_desc.pointer) {
 			return_ACPI_STATUS(AE_NO_MEMORY);
 		}
 
-		ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer,
-			    length);
-		table_desc.length = length;
-		table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
+		ACPI_MEMCPY(table_desc.pointer, table, length);
+		table_desc.address = ACPI_TO_INTEGER(table_desc.pointer);
 		break;
 
 	default:
 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 	}
 
-	/*
-	 * Install the new table into the local data structures
-	 */
+	/* Validate table checksum (will not get validated in tb_add_table) */
+
+	status = acpi_tb_verify_checksum(table_desc.pointer, length);
+	if (ACPI_FAILURE(status)) {
+		ACPI_FREE(table_desc.pointer);
+		return_ACPI_STATUS(status);
+	}
+
+	/* Complete the table descriptor */
+
+	table_desc.length = length;
+	table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
+
+	/* Install the new table into the local data structures */
+
 	status = acpi_tb_add_table(&table_desc, &table_index);
 	if (ACPI_FAILURE(status)) {
 		goto cleanup;
@@ -379,7 +430,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 	/*
 	 * Add the table to the namespace.
 	 *
-	 * Note: We load the table objects relative to the root of the namespace.
+	 * Note: Load the table objects relative to the root of the namespace.
 	 * This appears to go against the ACPI specification, but we do it for
 	 * compatibility with other ACPI implementations.
 	 */
@@ -415,7 +466,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
       cleanup:
 	if (ACPI_FAILURE(status)) {
 
-		/* Delete allocated buffer or mapping */
+		/* Delete allocated table buffer */
 
 		acpi_tb_delete_table(&table_desc);
 	}
-- 
1.5.5.1


  parent reply	other threads:[~2008-10-11  6:55 UTC|newest]

Thread overview: 111+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-11  6:35 ACPI patch queue for 2.6.28 Len Brown
2008-10-11  6:35 ` [PATCH 01/85] ACPI: Add missing acpi.debug_layer Documentation hunk from Thomas Renninger Len Brown
2008-10-11  6:35   ` [PATCH 02/85] acpi: replace AE_BAD_ADDRESS exception code with AE_ERROR Len Brown
2008-10-11  6:35   ` [PATCH 03/85] ACPI: Get the device power state in the course of scanning device Len Brown
2008-10-11  6:35   ` [PATCH 04/85] ACPI: Attach the ACPI device to the ACPI handle as early as possible Len Brown
2008-10-11  6:35   ` [PATCH 05/85] ACPI: Add "acpi.power_nocheck=1" to disable power state check in power transition Len Brown
2008-10-11  6:35   ` [PATCH 06/85] ACPI: Add DMI check " Len Brown
2008-10-11  6:35   ` [PATCH 07/85] ACPI : Load device driver according to the status of acpi device Len Brown
2008-10-11  6:35   ` Len Brown [this message]
2008-10-11  6:35   ` [PATCH 09/85] ACPICA: Add check for invalid handle in acpi_get_object_info Len Brown
2008-10-11  6:35   ` [PATCH 10/85] ACPICA: Allow same ACPI table to be loaded/unloaded more than once Len Brown
2008-10-11  6:35   ` [PATCH 11/85] ACPICA: Fix wrong resource descriptor length for 64-bit build Len Brown
2008-10-11  6:35   ` [PATCH 12/85] ACPICA: Fix table compare code, length then data Len Brown
2008-10-11  6:35   ` [PATCH 13/85] ACPICA: Return status from global init function Len Brown
2008-10-11  6:35   ` [PATCH 14/85] ACPICA: Add function to dereference returned reference objects Len Brown
2008-10-11  6:35   ` [PATCH 15/85] ACPICA: Fix warning for 64-bit build Len Brown
2008-10-11  6:35   ` [PATCH 16/85] ACPICA: Cleanup macro definition file Len Brown
2008-10-11  6:35   ` [PATCH 17/85] ACPICA: Return method arg count from acpi_get_object_info Len Brown
2008-10-11  6:35   ` [PATCH 18/85] ACPICA: Update version to 20080701 Len Brown
2008-10-11  6:35   ` [PATCH 19/85] ACPICA: Add function to decode reference obj types to strings Len Brown
2008-10-11  6:35   ` [PATCH 20/85] ACPICA: Improve object conversion error messages Len Brown
2008-10-11  6:35   ` [PATCH 21/85] ACPICA: x2APIC support: changes for MADT and SRAT ACPI tables Len Brown
2008-10-11  6:35   ` [PATCH 22/85] ACPICA: Update version to 20080729 Len Brown
2008-10-11  6:35   ` [PATCH 23/85] ACPI: Clear WAK_STS on resume Len Brown
2008-10-13  9:01     ` Christian Borntraeger
2008-10-11  6:35   ` [PATCH 24/85] ACPI : Add the support for _TTS object Len Brown
2008-10-11  6:35   ` [PATCH 25/85] Introduce FW_BUG, FW_WARN and FW_INFO to consistenly tell users about BIOS bugs Len Brown
2008-10-11  6:35   ` [PATCH 26/85] ACPI: cpufreq, processor: Detect old BIOS, not supporting CPU freq on a recent CPU Len Brown
2008-10-11  6:35   ` [PATCH 27/85] CPUFREQ: powernow-k8: Try to detect old BIOS, not supporting CPU freq on a recent AMD CPUs Len Brown
2008-10-11  6:35   ` [PATCH 28/85] ACPI: dock: avoid check _STA method Len Brown
2008-10-11  6:35   ` [PATCH 29/85] dock: fix eject request process (2.6.27-rc1 regression) Len Brown
2008-10-11  6:35   ` [PATCH 30/85] dock: add _LCK support Len Brown
2008-10-11  6:35   ` [PATCH 31/85] dock: add bay and battery hotplug support Len Brown
2008-10-11  6:35   ` [PATCH 32/85] ACPI: introduce notifier change to avoid duplicates Len Brown
2008-10-11  6:35   ` [PATCH 33/85] ACPI: fix hotplug race Len Brown
2008-10-11  6:35   ` [PATCH 34/85] libata: remove functions now handed by ACPI dock driver Len Brown
2008-10-11  6:35   ` [PATCH 35/85] dock: introduce .uevent for devices in dock, eg libata Len Brown
2008-10-11  6:35   ` [PATCH 36/85] bay: remove driver, all functions now handled by dock driver Len Brown
2008-10-11  6:35   ` [PATCH 37/85] dock: fix for ATA bay in a dock station Len Brown
2008-10-11  6:35   ` [PATCH 38/85] dock: add 'type' sysfs file Len Brown
2008-10-11  6:35   ` [PATCH 39/85] dock: Shaohua Li is new maintainer Len Brown
2008-10-11  6:36   ` [PATCH 40/85] ACPI suspend: Always use the 32-bit waking vector Len Brown
2008-10-11  6:36   ` [PATCH 41/85] panasonic-laptop: add Panasonic Let's Note laptop extras driver v0.94 Len Brown
2008-10-11  6:36   ` [PATCH 42/85] ACPI: EC: do transaction from interrupt context Len Brown
2008-10-11  6:36   ` [PATCH 43/85] ACPI: EC: Rename some variables Len Brown
2008-10-11  6:36   ` [PATCH 44/85] ACPICA: add preemption point after each opcode parse Len Brown
2008-10-11  6:36   ` [PATCH 45/85] ACPI Suspend: Enable ACPI during resume if SCI_EN is not set Len Brown
2008-10-11  6:36   ` [PATCH 46/85] ACPI: don't enable control method power button as wakeup device when Fixed Power button is used Len Brown
2008-10-11  6:36   ` [PATCH 47/85] acer-wmi: Add rfkill support for wireless and bluetooth Len Brown
2008-10-11  6:36   ` [PATCH 48/85] acer-wmi: Remove wireless and bluetooth sysfs entries Len Brown
2008-10-11  6:36   ` [PATCH 49/85] ACPI: WMI: Enable event methods when registering notifiers Len Brown
2008-10-11  6:36   ` [PATCH 50/85] ACPI: Change acpi_evaluate_integer to support 64-bit on 32-bit kernels Len Brown
2008-10-11  6:36   ` [PATCH 51/85] ACPI: fix FADT parsing Len Brown
2008-10-11  6:36   ` [PATCH 52/85] fujitsu-laptop: better handling of P8010 hotkey Len Brown
2008-10-11  6:36   ` [PATCH 53/85] i7300_idle driver v1.55 Len Brown
2008-10-11  8:33     ` Ingo Molnar
2008-10-15 22:32       ` Len Brown
2008-10-16 22:05       ` [PATCH 1/2] x86: allow module driver to register idle notifier Len Brown
2008-10-21  1:57         ` Len Brown
2008-10-21 11:49           ` Ingo Molnar
2008-10-16 22:08       ` [PATCH 2/2] i7300_idle driver v1.55 Len Brown
2008-10-20 17:32         ` Randy Dunlap
2008-10-21 22:09           ` Pallipadi, Venkatesh
2008-10-21 22:15             ` Randy Dunlap
2008-10-21 23:02               ` Pallipadi, Venkatesh
2008-10-21 16:47         ` Andi Kleen
2008-10-21 22:34           ` Pallipadi, Venkatesh
2008-10-22  7:19             ` Andi Kleen
2008-10-22 23:34               ` [PATCH] Disable ioat channel only on platforms where ile driver can load Venki Pallipadi
2008-10-22 23:51                 ` [PATCH] Cleanup of i7300_idle based on review comments Venki Pallipadi
2008-10-24 17:03                   ` Len Brown
2008-10-24 17:02                 ` [PATCH] Disable ioat channel only on platforms where ile driver can load Len Brown
     [not found]                 ` <f12847240810270941v68a1cf7aqfa7db14fceb61fe5@mail.gmail.com>
2008-10-28 16:30                   ` Sosnowski, Maciej
2008-10-22 23:40               ` [PATCH 2/2] i7300_idle driver v1.55 Venki Pallipadi
2008-10-23  1:11                 ` Andi Kleen
2008-10-23  4:59                   ` Pallipadi, Venkatesh
2008-10-23 12:26                     ` Andi Kleen
2008-10-23 15:00                     ` Paul E. McKenney
2008-10-23 16:26                       ` Andi Kleen
2008-10-11  6:36   ` [PATCH 54/85] eeepc-laptop: Use standard interfaces Len Brown
2008-10-11  6:36   ` [PATCH 55/85] x86: remove magic number from ACPI sleep stack buffer Len Brown
2008-10-11  6:36   ` [PATCH 56/85] x86: trim " Len Brown
2008-10-11  6:36   ` [PATCH 57/85] ACPI: acpi_driver_data could only be applied to acpi_device Len Brown
2008-10-11  6:36   ` [PATCH 58/85] ACPI: toshiba_acpi.c fix sparse signedness mismatch warnings Len Brown
2008-10-11  6:36   ` [PATCH 59/85] ACPI: catch calls of acpi_driver_data on pointer of wrong type Len Brown
2008-10-11  6:36   ` [PATCH 60/85] toshiba_acpi: depends on INPUT Len Brown
2008-10-11  6:36   ` [PATCH 61/85] PNP: fix debug formatting (cosmetic) Len Brown
2008-10-11  6:36   ` [PATCH 62/85] PNPACPI: use dev_printk when possible Len Brown
2008-10-11  6:36   ` [PATCH 63/85] PNP: convert the last few pnp_info() uses to printk() Len Brown
2008-10-11  6:36   ` [PATCH 64/85] PNP: use new vsprintf symbolic function pointer format Len Brown
2008-10-11  6:36   ` [PATCH 65/85] PNP: remove some uses of DEBUG ifdef Len Brown
2008-10-11  6:36   ` [PATCH 66/85] PNP: add CONFIG_PNP_DEBUG_MESSAGES and pnp_dbg() Len Brown
2008-10-11  6:36   ` [PATCH 67/85] PNP: convert to using pnp_dbg() Len Brown
2008-10-11  6:36   ` [PATCH 68/85] PNP: remove old CONFIG_PNP_DEBUG option Len Brown
2008-10-11  6:36   ` [PATCH 69/85] ACPI: don't load acpi_cpufreq if acpi=off Len Brown
2008-10-11  6:36   ` [PATCH 70/85] ACPI: remove unused have_arch_parse_srat Len Brown
2008-10-11  6:36   ` [PATCH 71/85] acer-wmi: Remove private workqueue Len Brown
2008-10-11  6:36   ` [PATCH 72/85] Subject: ACPI dock: Use ACPI_EXCEPTION instead of printk(KERN_ERR Len Brown
2008-10-11  6:36   ` [PATCH 73/85] ACPI cm_sbs: Debug interface used for error message cleanup Len Brown
2008-10-11  6:36   ` [PATCH 74/85] ACPI memhotplug: " Len Brown
2008-10-11  6:36   ` [PATCH 75/85] ACPI processor: " Len Brown
2008-10-11  6:36   ` [PATCH 76/85] ACPI video: " Len Brown
2008-10-11  6:36   ` [PATCH 77/85] ACPI scan: " Len Brown
2008-10-11  6:36   ` [PATCH 78/85] ACPI fan: " Len Brown
2008-10-11  6:36   ` [PATCH 79/85] ACPI osl: " Len Brown
2008-10-11  6:36   ` [PATCH 80/85] ACPI thermal: " Len Brown
2008-10-11  6:36   ` [PATCH 81/85] ACPI system: " Len Brown
2008-10-11  6:36   ` [PATCH 82/85] ACPI: remove unused acpi_is_child_device() Len Brown
2008-10-11  6:36   ` [PATCH 83/85] ACPI: Enable EC device immediately after ACPI full initialization Len Brown
2008-10-11  6:36   ` [PATCH 84/85] delete drivers/acpi/bay.c Len Brown
2008-10-11  6:36   ` [PATCH 85/85] panasonic-laptop: fix build Len Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a4377db47f9b0586f32ed7beddb53c86d5ef422d.1223706853.git.len.brown@intel.com \
    --to=lenb@kernel.org \
    --cc=ak@linux.intel.com \
    --cc=dennis.noordsij@helsinki.fi \
    --cc=len.brown@intel.com \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ming.m.lin@intel.com \
    --cc=robert.moore@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®