aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorErik Schmauss <erik.schmauss@intel.com>2018-06-01 15:06:43 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2018-06-06 02:53:43 -0400
commit5088814a6e931350e5bd29f5d59fa40c6dbbdf10 (patch)
treeb8ac50dc8f6e826eae179409c4cf9a3aa6f5f06a
parent3877b2ccb71356492d8f514a76d764c3ecc1147e (diff)
ACPICA: AML parser: attempt to continue loading table after error
This change alters the parser so that the table load does not abort upon an error. Notable changes: If there is an error while parsing an element of the termlist, we will skip parsing the current termlist element and continue parsing to the next opcode in the termlist. If we get an error while parsing the conditional of If/Else/While or the device name of Scope, we will skip the body of the statement all together and pop the parser_state. If we get an error while parsing the base offset and length of an operation region declaration, we will remove the operation region from the namespace. Signed-off-by: Erik Schmauss <erik.schmauss@intel.com> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/acpi/acpica/psloop.c51
-rw-r--r--drivers/acpi/acpica/psobject.c30
-rw-r--r--drivers/acpi/acpica/uterror.c10
3 files changed, 85 insertions, 6 deletions
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
index 68422afc365f..bc5f05906bd1 100644
--- a/drivers/acpi/acpica/psloop.c
+++ b/drivers/acpi/acpica/psloop.c
@@ -515,6 +515,22 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
515 if (ACPI_FAILURE(status)) { 515 if (ACPI_FAILURE(status)) {
516 return_ACPI_STATUS(status); 516 return_ACPI_STATUS(status);
517 } 517 }
518 if (walk_state->opcode == AML_SCOPE_OP) {
519 /*
520 * If the scope op fails to parse, skip the body of the
521 * scope op because the parse failure indicates that the
522 * device may not exist.
523 */
524 walk_state->parser_state.aml =
525 walk_state->aml + 1;
526 walk_state->parser_state.aml =
527 acpi_ps_get_next_package_end
528 (&walk_state->parser_state);
529 walk_state->aml =
530 walk_state->parser_state.aml;
531 ACPI_ERROR((AE_INFO,
532 "Skipping Scope block"));
533 }
518 534
519 continue; 535 continue;
520 } 536 }
@@ -557,7 +573,40 @@ acpi_status acpi_ps_parse_loop(struct acpi_walk_state *walk_state)
557 if (ACPI_FAILURE(status)) { 573 if (ACPI_FAILURE(status)) {
558 return_ACPI_STATUS(status); 574 return_ACPI_STATUS(status);
559 } 575 }
560 576 if ((walk_state->control_state) &&
577 ((walk_state->control_state->control.
578 opcode == AML_IF_OP)
579 || (walk_state->control_state->control.
580 opcode == AML_WHILE_OP))) {
581 /*
582 * If the if/while op fails to parse, we will skip parsing
583 * the body of the op.
584 */
585 parser_state->aml =
586 walk_state->control_state->control.
587 aml_predicate_start + 1;
588 parser_state->aml =
589 acpi_ps_get_next_package_end
590 (parser_state);
591 walk_state->aml = parser_state->aml;
592
593 ACPI_ERROR((AE_INFO,
594 "Skipping While/If block"));
595 if (*walk_state->aml == AML_ELSE_OP) {
596 ACPI_ERROR((AE_INFO,
597 "Skipping Else block"));
598 walk_state->parser_state.aml =
599 walk_state->aml + 1;
600 walk_state->parser_state.aml =
601 acpi_ps_get_next_package_end
602 (parser_state);
603 walk_state->aml =
604 parser_state->aml;
605 }
606 ACPI_FREE(acpi_ut_pop_generic_state
607 (&walk_state->control_state));
608 }
609 op = NULL;
561 continue; 610 continue;
562 } 611 }
563 } 612 }
diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c
index 7d9d0151ee54..3138e7a00da8 100644
--- a/drivers/acpi/acpica/psobject.c
+++ b/drivers/acpi/acpica/psobject.c
@@ -12,6 +12,7 @@
12#include "acparser.h" 12#include "acparser.h"
13#include "amlcode.h" 13#include "amlcode.h"
14#include "acconvert.h" 14#include "acconvert.h"
15#include "acnamesp.h"
15 16
16#define _COMPONENT ACPI_PARSER 17#define _COMPONENT ACPI_PARSER
17ACPI_MODULE_NAME("psobject") 18ACPI_MODULE_NAME("psobject")
@@ -549,6 +550,21 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
549 550
550 do { 551 do {
551 if (*op) { 552 if (*op) {
553 /*
554 * These Opcodes need to be removed from the namespace because they
555 * get created even if these opcodes cannot be created due to
556 * errors.
557 */
558 if (((*op)->common.aml_opcode == AML_REGION_OP)
559 || ((*op)->common.aml_opcode ==
560 AML_DATA_REGION_OP)) {
561 acpi_ns_delete_children((*op)->common.
562 node);
563 acpi_ns_remove_node((*op)->common.node);
564 (*op)->common.node = NULL;
565 acpi_ps_delete_parse_tree(*op);
566 }
567
552 status2 = 568 status2 =
553 acpi_ps_complete_this_op(walk_state, *op); 569 acpi_ps_complete_this_op(walk_state, *op);
554 if (ACPI_FAILURE(status2)) { 570 if (ACPI_FAILURE(status2)) {
@@ -574,6 +590,20 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
574#endif 590#endif
575 walk_state->prev_op = NULL; 591 walk_state->prev_op = NULL;
576 walk_state->prev_arg_types = walk_state->arg_types; 592 walk_state->prev_arg_types = walk_state->arg_types;
593
594 if (walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL) {
595 /*
596 * There was something that went wrong while executing code at the
597 * module-level. We need to skip parsing whatever caused the
598 * error and keep going. One runtime error during the table load
599 * should not cause the entire table to not be loaded. This is
600 * because there could be correct AML beyond the parts that caused
601 * the runtime error.
602 */
603 ACPI_ERROR((AE_INFO,
604 "Ignore error and continue table load"));
605 return_ACPI_STATUS(AE_OK);
606 }
577 return_ACPI_STATUS(status); 607 return_ACPI_STATUS(status);
578 } 608 }
579 609
diff --git a/drivers/acpi/acpica/uterror.c b/drivers/acpi/acpica/uterror.c
index 12d4a0f6b8d2..5a64ddaed8a3 100644
--- a/drivers/acpi/acpica/uterror.c
+++ b/drivers/acpi/acpica/uterror.c
@@ -182,20 +182,20 @@ acpi_ut_prefixed_namespace_error(const char *module_name,
182 switch (lookup_status) { 182 switch (lookup_status) {
183 case AE_ALREADY_EXISTS: 183 case AE_ALREADY_EXISTS:
184 184
185 acpi_os_printf(ACPI_MSG_BIOS_ERROR); 185 acpi_os_printf("\n" ACPI_MSG_BIOS_ERROR);
186 message = "Failure creating"; 186 message = "Failure creating";
187 break; 187 break;
188 188
189 case AE_NOT_FOUND: 189 case AE_NOT_FOUND:
190 190
191 acpi_os_printf(ACPI_MSG_BIOS_ERROR); 191 acpi_os_printf("\n" ACPI_MSG_BIOS_ERROR);
192 message = "Failure looking up"; 192 message = "Could not resolve";
193 break; 193 break;
194 194
195 default: 195 default:
196 196
197 acpi_os_printf(ACPI_MSG_ERROR); 197 acpi_os_printf("\n" ACPI_MSG_ERROR);
198 message = "Failure looking up"; 198 message = "Failure resolving";
199 break; 199 break;
200 } 200 }
201 201