|
@@ -118,6 +118,8 @@ acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
|
|
|
control_state->control.package_end =
|
|
|
walk_state->parser_state.pkg_end;
|
|
|
control_state->control.opcode = op->common.aml_opcode;
|
|
|
+ control_state->control.loop_timeout = acpi_os_get_timer() +
|
|
|
+ (u64)(acpi_gbl_max_loop_iterations * ACPI_100NSEC_PER_SEC);
|
|
|
|
|
|
/* Push the control state on this walk's control stack */
|
|
|
|
|
@@ -206,14 +208,14 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state *walk_state,
|
|
|
/* 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.
|
|
|
+ * This infinite loop detection 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.
|
|
|
*/
|
|
|
- control_state->control.loop_count++;
|
|
|
- if (control_state->control.loop_count >
|
|
|
- acpi_gbl_max_loop_iterations) {
|
|
|
+ if (ACPI_TIME_AFTER(acpi_os_get_timer(),
|
|
|
+ control_state->control.
|
|
|
+ loop_timeout)) {
|
|
|
status = AE_AML_INFINITE_LOOP;
|
|
|
break;
|
|
|
}
|