aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/executer/exconfig.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/executer/exconfig.c')
-rw-r--r--drivers/acpi/executer/exconfig.c123
1 files changed, 86 insertions, 37 deletions
diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c
index 8892b9824fae..74da6fa52ef1 100644
--- a/drivers/acpi/executer/exconfig.c
+++ b/drivers/acpi/executer/exconfig.c
@@ -43,7 +43,6 @@
43 43
44#include <acpi/acpi.h> 44#include <acpi/acpi.h>
45#include <acpi/acinterp.h> 45#include <acpi/acinterp.h>
46#include <acpi/amlcode.h>
47#include <acpi/acnamesp.h> 46#include <acpi/acnamesp.h>
48#include <acpi/actables.h> 47#include <acpi/actables.h>
49#include <acpi/acdispat.h> 48#include <acpi/acdispat.h>
@@ -91,13 +90,12 @@ acpi_ex_add_table(u32 table_index,
91 90
92 /* Init the table handle */ 91 /* Init the table handle */
93 92
94 obj_desc->reference.opcode = AML_LOAD_OP; 93 obj_desc->reference.class = ACPI_REFCLASS_TABLE;
95 *ddb_handle = obj_desc; 94 *ddb_handle = obj_desc;
96 95
97 /* Install the new table into the local data structures */ 96 /* Install the new table into the local data structures */
98 97
99 obj_desc->reference.object = ACPI_CAST_PTR(void, 98 obj_desc->reference.value = table_index;
100 (unsigned long)table_index);
101 99
102 /* Add the table to the namespace */ 100 /* Add the table to the namespace */
103 101
@@ -280,6 +278,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
280 struct acpi_walk_state *walk_state) 278 struct acpi_walk_state *walk_state)
281{ 279{
282 union acpi_operand_object *ddb_handle; 280 union acpi_operand_object *ddb_handle;
281 struct acpi_table_header *table;
283 struct acpi_table_desc table_desc; 282 struct acpi_table_desc table_desc;
284 u32 table_index; 283 u32 table_index;
285 acpi_status status; 284 acpi_status status;
@@ -294,9 +293,8 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
294 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) { 293 switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
295 case ACPI_TYPE_REGION: 294 case ACPI_TYPE_REGION:
296 295
297 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Load from Region %p %s\n", 296 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
298 obj_desc, 297 "Load table from Region %p\n", obj_desc));
299 acpi_ut_get_object_type_name(obj_desc)));
300 298
301 /* Region must be system_memory (from ACPI spec) */ 299 /* Region must be system_memory (from ACPI spec) */
302 300
@@ -316,61 +314,112 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
316 } 314 }
317 315
318 /* 316 /*
319 * We will simply map the memory region for the table. However, the 317 * Map the table header and get the actual table length. The region
320 * memory region is technically not guaranteed to remain stable and 318 * length is not guaranteed to be the same as the table length.
321 * we may eventually have to copy the table to a local buffer. 319 */
320 table = acpi_os_map_memory(obj_desc->region.address,
321 sizeof(struct acpi_table_header));
322 if (!table) {
323 return_ACPI_STATUS(AE_NO_MEMORY);
324 }
325
326 length = table->length;
327 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
328
329 /* Must have at least an ACPI table header */
330
331 if (length < sizeof(struct acpi_table_header)) {
332 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
333 }
334
335 /*
336 * The memory region is not guaranteed to remain stable and we must
337 * copy the table to a local buffer. For example, the memory region
338 * is corrupted after suspend on some machines. Dynamically loaded
339 * tables are usually small, so this overhead is minimal.
322 */ 340 */
341
342 /* Allocate a buffer for the table */
343
344 table_desc.pointer = ACPI_ALLOCATE(length);
345 if (!table_desc.pointer) {
346 return_ACPI_STATUS(AE_NO_MEMORY);
347 }
348
349 /* Map the entire table and copy it */
350
351 table = acpi_os_map_memory(obj_desc->region.address, length);
352 if (!table) {
353 ACPI_FREE(table_desc.pointer);
354 return_ACPI_STATUS(AE_NO_MEMORY);
355 }
356
357 ACPI_MEMCPY(table_desc.pointer, table, length);
358 acpi_os_unmap_memory(table, length);
359
323 table_desc.address = obj_desc->region.address; 360 table_desc.address = obj_desc->region.address;
324 table_desc.length = obj_desc->region.length;
325 table_desc.flags = ACPI_TABLE_ORIGIN_MAPPED;
326 break; 361 break;
327 362
328 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */ 363 case ACPI_TYPE_BUFFER: /* Buffer or resolved region_field */
329 364
330 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 365 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
331 "Load from Buffer or Field %p %s\n", obj_desc, 366 "Load table from Buffer or Field %p\n",
332 acpi_ut_get_object_type_name(obj_desc))); 367 obj_desc));
333
334 length = obj_desc->buffer.length;
335 368
336 /* Must have at least an ACPI table header */ 369 /* Must have at least an ACPI table header */
337 370
338 if (length < sizeof(struct acpi_table_header)) { 371 if (obj_desc->buffer.length < sizeof(struct acpi_table_header)) {
339 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH); 372 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
340 } 373 }
341 374
342 /* Validate checksum here. It won't get validated in tb_add_table */ 375 /* Get the actual table length from the table header */
343 376
344 status = 377 table =
345 acpi_tb_verify_checksum(ACPI_CAST_PTR 378 ACPI_CAST_PTR(struct acpi_table_header,
346 (struct acpi_table_header, 379 obj_desc->buffer.pointer);
347 obj_desc->buffer.pointer), length); 380 length = table->length;
348 if (ACPI_FAILURE(status)) { 381
349 return_ACPI_STATUS(status); 382 /* Table cannot extend beyond the buffer */
383
384 if (length > obj_desc->buffer.length) {
385 return_ACPI_STATUS(AE_AML_BUFFER_LIMIT);
386 }
387 if (length < sizeof(struct acpi_table_header)) {
388 return_ACPI_STATUS(AE_INVALID_TABLE_LENGTH);
350 } 389 }
351 390
352 /* 391 /*
353 * We need to copy the buffer since the original buffer could be 392 * Copy the table from the buffer because the buffer could be modified
354 * changed or deleted in the future 393 * or even deleted in the future
355 */ 394 */
356 table_desc.pointer = ACPI_ALLOCATE(length); 395 table_desc.pointer = ACPI_ALLOCATE(length);
357 if (!table_desc.pointer) { 396 if (!table_desc.pointer) {
358 return_ACPI_STATUS(AE_NO_MEMORY); 397 return_ACPI_STATUS(AE_NO_MEMORY);
359 } 398 }
360 399
361 ACPI_MEMCPY(table_desc.pointer, obj_desc->buffer.pointer, 400 ACPI_MEMCPY(table_desc.pointer, table, length);
362 length); 401 table_desc.address = ACPI_TO_INTEGER(table_desc.pointer);
363 table_desc.length = length;
364 table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
365 break; 402 break;
366 403
367 default: 404 default:
368 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 405 return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
369 } 406 }
370 407
371 /* 408 /* Validate table checksum (will not get validated in tb_add_table) */
372 * Install the new table into the local data structures 409
373 */ 410 status = acpi_tb_verify_checksum(table_desc.pointer, length);
411 if (ACPI_FAILURE(status)) {
412 ACPI_FREE(table_desc.pointer);
413 return_ACPI_STATUS(status);
414 }
415
416 /* Complete the table descriptor */
417
418 table_desc.length = length;
419 table_desc.flags = ACPI_TABLE_ORIGIN_ALLOCATED;
420
421 /* Install the new table into the local data structures */
422
374 status = acpi_tb_add_table(&table_desc, &table_index); 423 status = acpi_tb_add_table(&table_desc, &table_index);
375 if (ACPI_FAILURE(status)) { 424 if (ACPI_FAILURE(status)) {
376 goto cleanup; 425 goto cleanup;
@@ -379,7 +428,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
379 /* 428 /*
380 * Add the table to the namespace. 429 * Add the table to the namespace.
381 * 430 *
382 * Note: We load the table objects relative to the root of the namespace. 431 * Note: Load the table objects relative to the root of the namespace.
383 * This appears to go against the ACPI specification, but we do it for 432 * This appears to go against the ACPI specification, but we do it for
384 * compatibility with other ACPI implementations. 433 * compatibility with other ACPI implementations.
385 */ 434 */
@@ -415,7 +464,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
415 cleanup: 464 cleanup:
416 if (ACPI_FAILURE(status)) { 465 if (ACPI_FAILURE(status)) {
417 466
418 /* Delete allocated buffer or mapping */ 467 /* Delete allocated table buffer */
419 468
420 acpi_tb_delete_table(&table_desc); 469 acpi_tb_delete_table(&table_desc);
421 } 470 }
@@ -455,9 +504,9 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
455 return_ACPI_STATUS(AE_BAD_PARAMETER); 504 return_ACPI_STATUS(AE_BAD_PARAMETER);
456 } 505 }
457 506
458 /* Get the table index from the ddb_handle (acpi_size for 64-bit case) */ 507 /* Get the table index from the ddb_handle */
459 508
460 table_index = (u32) (acpi_size) table_desc->reference.object; 509 table_index = table_desc->reference.value;
461 510
462 /* Invoke table handler if present */ 511 /* Invoke table handler if present */
463 512