aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-06-15 04:51:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-06-15 04:51:19 -0400
commit35e60a6b7577218ac7eb7777c8849822a080e127 (patch)
treea1578093e1e88e17a53ac7b99b0638bd110e04ee
parent92091c438bad93ba2591e8c4ba86126227327be2 (diff)
parent9522933454f4c4bd5bedf3d71c538708b7c5de5b (diff)
Merge tag 'acpi-4.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI fixes from Rafael Wysocki: "These revert an ACPICA commit from the 4.11 cycle that causes problems to happen on some systems and add a protection against possible kernel crashes due to table reference counter imbalance. Specifics: - Revert a 4.11 ACPICA change that made assumptions which are not satisfied on some systems and caused the enumeration of resources to fail on them (Rafael Wysocki). - Add a mechanism to prevent tables from being unmapped prematurely due to reference counter overflows (Lv Zheng)" * tag 'acpi-4.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: ACPICA: Tables: Mechanism to handle late stage acpi_get_table() imbalance Revert "ACPICA: Disassembler: Enhance resource descriptor detection"
-rw-r--r--drivers/acpi/acpica/tbutils.c34
-rw-r--r--drivers/acpi/acpica/utresrc.c9
-rw-r--r--include/acpi/actbl.h14
3 files changed, 39 insertions, 18 deletions
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 7abe66505739..0d2e98920069 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -416,9 +416,18 @@ acpi_tb_get_table(struct acpi_table_desc *table_desc,
416 } 416 }
417 } 417 }
418 418
419 table_desc->validation_count++; 419 if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) {
420 if (table_desc->validation_count == 0) { 420 table_desc->validation_count++;
421 table_desc->validation_count--; 421
422 /*
423 * Detect validation_count overflows to ensure that the warning
424 * message will only be printed once.
425 */
426 if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) {
427 ACPI_WARNING((AE_INFO,
428 "Table %p, Validation count overflows\n",
429 table_desc));
430 }
422 } 431 }
423 432
424 *out_table = table_desc->pointer; 433 *out_table = table_desc->pointer;
@@ -445,13 +454,20 @@ void acpi_tb_put_table(struct acpi_table_desc *table_desc)
445 454
446 ACPI_FUNCTION_TRACE(acpi_tb_put_table); 455 ACPI_FUNCTION_TRACE(acpi_tb_put_table);
447 456
448 if (table_desc->validation_count == 0) { 457 if (table_desc->validation_count < ACPI_MAX_TABLE_VALIDATIONS) {
449 ACPI_WARNING((AE_INFO, 458 table_desc->validation_count--;
450 "Table %p, Validation count is zero before decrement\n", 459
451 table_desc)); 460 /*
452 return_VOID; 461 * Detect validation_count underflows to ensure that the warning
462 * message will only be printed once.
463 */
464 if (table_desc->validation_count >= ACPI_MAX_TABLE_VALIDATIONS) {
465 ACPI_WARNING((AE_INFO,
466 "Table %p, Validation count underflows\n",
467 table_desc));
468 return_VOID;
469 }
453 } 470 }
454 table_desc->validation_count--;
455 471
456 if (table_desc->validation_count == 0) { 472 if (table_desc->validation_count == 0) {
457 473
diff --git a/drivers/acpi/acpica/utresrc.c b/drivers/acpi/acpica/utresrc.c
index e0587c85bafd..ff096d9755b9 100644
--- a/drivers/acpi/acpica/utresrc.c
+++ b/drivers/acpi/acpica/utresrc.c
@@ -474,15 +474,6 @@ acpi_ut_walk_aml_resources(struct acpi_walk_state *walk_state,
474 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG); 474 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
475 } 475 }
476 476
477 /*
478 * The end_tag opcode must be followed by a zero byte.
479 * Although this byte is technically defined to be a checksum,
480 * in practice, all ASL compilers set this byte to zero.
481 */
482 if (*(aml + 1) != 0) {
483 return_ACPI_STATUS(AE_AML_NO_RESOURCE_END_TAG);
484 }
485
486 /* Return the pointer to the end_tag if requested */ 477 /* Return the pointer to the end_tag if requested */
487 478
488 if (!user_function) { 479 if (!user_function) {
diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h
index d92543f3bbfd..bdc55c0da19c 100644
--- a/include/acpi/actbl.h
+++ b/include/acpi/actbl.h
@@ -374,6 +374,20 @@ struct acpi_table_desc {
374 u16 validation_count; 374 u16 validation_count;
375}; 375};
376 376
377/*
378 * Maximum value of the validation_count field in struct acpi_table_desc.
379 * When reached, validation_count cannot be changed any more and the table will
380 * be permanently regarded as validated.
381 *
382 * This is to prevent situations in which unbalanced table get/put operations
383 * may cause premature table unmapping in the OS to happen.
384 *
385 * The maximum validation count can be defined to any value, but should be
386 * greater than the maximum number of OS early stage mapping slots to avoid
387 * leaking early stage table mappings to the late stage.
388 */
389#define ACPI_MAX_TABLE_VALIDATIONS ACPI_UINT16_MAX
390
377/* Masks for Flags field above */ 391/* Masks for Flags field above */
378 392
379#define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL (0) /* Virtual address, external maintained */ 393#define ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL (0) /* Virtual address, external maintained */