Add a mechanism to escape infinite AML While() loops.

Add a loop counter to force exit from AML While loops if the count
becomes too large. This can occur in poorly written AML when the
hardware does not respond within a while loop and the loop does not
implement a timeout. The maximum loop count is configurable. A new
exception code is returned when a loop is broken, AE_AML_INFINITE_LOOP.
Bob Moore, Alexey Starikovskiy.
This commit is contained in:
Robert Moore 2008-10-09 14:37:11 -07:00
parent d2a82ede58
commit dc3e72f35a
4 changed files with 29 additions and 4 deletions

View File

@ -1430,12 +1430,30 @@ AcpiDsExecEndControlOp (
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", Op));
if (WalkState->ControlState->Common.Value)
ControlState = WalkState->ControlState;
if (ControlState->Common.Value)
{
/* Predicate was true, go back and evaluate it again! */
/* Predicate was true, the body of the loop was just executed */
/*
* This loop counter mechanism allows the interpreter to escape
* possibly infinite loops. This can occur in poorly written AML
* when the hardware does not respond within a while loop and the
* loop does not implement a timeout.
*/
ControlState->Control.LoopCount++;
if (ControlState->Control.LoopCount > ACPI_MAX_LOOP_ITERATIONS)
{
Status = AE_AML_INFINITE_LOOP;
break;
}
/*
* Go back and evaluate the predicate and maybe execute the loop
* another time
*/
Status = AE_CTRL_PENDING;
WalkState->AmlLastWhile = WalkState->ControlState->Control.AmlPredicateStart;
WalkState->AmlLastWhile = ControlState->Control.AmlPredicateStart;
break;
}

View File

@ -193,6 +193,10 @@
#define ACPI_ROOT_TABLE_SIZE_INCREMENT 4
/* Maximum number of While() loop iterations before forced abort */
#define ACPI_MAX_LOOP_ITERATIONS 0xFFFF
/******************************************************************************
*

View File

@ -231,8 +231,9 @@
#define AE_AML_CIRCULAR_REFERENCE (ACPI_STATUS) (0x001E | AE_CODE_AML)
#define AE_AML_BAD_RESOURCE_LENGTH (ACPI_STATUS) (0x001F | AE_CODE_AML)
#define AE_AML_ILLEGAL_ADDRESS (ACPI_STATUS) (0x0020 | AE_CODE_AML)
#define AE_AML_INFINITE_LOOP (ACPI_STATUS) (0x0021 | AE_CODE_AML)
#define AE_CODE_AML_MAX 0x0020
#define AE_CODE_AML_MAX 0x0021
/*
@ -352,6 +353,7 @@ char const *AcpiGbl_ExceptionNames_Aml[] =
"AE_AML_CIRCULAR_REFERENCE",
"AE_AML_BAD_RESOURCE_LENGTH",
"AE_AML_ILLEGAL_ADDRESS",
"AE_AML_INFINITE_LOOP"
};
char const *AcpiGbl_ExceptionNames_Ctrl[] =

View File

@ -731,6 +731,7 @@ typedef struct acpi_control_state
union acpi_parse_object *PredicateOp;
UINT8 *AmlPredicateStart; /* Start of if/while predicate */
UINT8 *PackageEnd; /* End of if/while block */
UINT32 LoopCount; /* While() loop counter */
} ACPI_CONTROL_STATE;