diff options
author | Bob Moore <robert.moore@intel.com> | 2008-04-10 11:06:36 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-04-22 14:29:20 -0400 |
commit | 773069d48030e670cf2032a13ddf16a2e0034df3 (patch) | |
tree | 2f45fd7e90600d26c08c641c75059eb0b15d6dcd /drivers/acpi/dispatcher/dsutils.c | |
parent | 4b119e21d0c66c22e8ca03df05d9de623d0eb50f (diff) |
ACPICA: Several fixes for internal method result stack
fixes STACK_OVERFLOW exception on nested method calls. internal
bugzilla 262 and 275.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/dispatcher/dsutils.c')
-rw-r--r-- | drivers/acpi/dispatcher/dsutils.c | 52 |
1 files changed, 38 insertions, 14 deletions
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 71503c036f7c..d2a8cfdaec22 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c | |||
@@ -630,9 +630,7 @@ acpi_ds_create_operand(struct acpi_walk_state *walk_state, | |||
630 | * Use value that was already previously returned | 630 | * Use value that was already previously returned |
631 | * by the evaluation of this argument | 631 | * by the evaluation of this argument |
632 | */ | 632 | */ |
633 | status = | 633 | status = acpi_ds_result_pop(&obj_desc, walk_state); |
634 | acpi_ds_result_pop_from_bottom(&obj_desc, | ||
635 | walk_state); | ||
636 | if (ACPI_FAILURE(status)) { | 634 | if (ACPI_FAILURE(status)) { |
637 | /* | 635 | /* |
638 | * Only error is underflow, and this indicates | 636 | * Only error is underflow, and this indicates |
@@ -698,27 +696,54 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, | |||
698 | { | 696 | { |
699 | acpi_status status = AE_OK; | 697 | acpi_status status = AE_OK; |
700 | union acpi_parse_object *arg; | 698 | union acpi_parse_object *arg; |
701 | u32 arg_count = 0; | 699 | union acpi_parse_object *arguments[ACPI_OBJ_NUM_OPERANDS]; |
700 | u8 arg_count = 0; | ||
701 | u8 count = 0; | ||
702 | u8 index = walk_state->num_operands; | ||
703 | u8 i; | ||
702 | 704 | ||
703 | ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); | 705 | ACPI_FUNCTION_TRACE_PTR(ds_create_operands, first_arg); |
704 | 706 | ||
705 | /* For all arguments in the list... */ | 707 | /* Get all arguments in the list */ |
706 | 708 | ||
707 | arg = first_arg; | 709 | arg = first_arg; |
708 | while (arg) { | 710 | while (arg) { |
709 | status = acpi_ds_create_operand(walk_state, arg, arg_count); | 711 | if (index >= ACPI_OBJ_NUM_OPERANDS) { |
710 | if (ACPI_FAILURE(status)) { | 712 | return_ACPI_STATUS(AE_BAD_DATA); |
711 | goto cleanup; | ||
712 | } | 713 | } |
713 | 714 | ||
714 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | 715 | arguments[index] = arg; |
715 | "Arg #%d (%p) done, Arg1=%p\n", arg_count, | 716 | walk_state->operands[index] = NULL; |
716 | arg, first_arg)); | ||
717 | 717 | ||
718 | /* Move on to next argument, if any */ | 718 | /* Move on to next argument, if any */ |
719 | 719 | ||
720 | arg = arg->common.next; | 720 | arg = arg->common.next; |
721 | arg_count++; | 721 | arg_count++; |
722 | index++; | ||
723 | } | ||
724 | |||
725 | index--; | ||
726 | |||
727 | /* It is the appropriate order to get objects from the Result stack */ | ||
728 | |||
729 | for (i = 0; i < arg_count; i++) { | ||
730 | arg = arguments[index]; | ||
731 | |||
732 | /* Force the filling of the operand stack in inverse order */ | ||
733 | |||
734 | walk_state->operand_index = index; | ||
735 | |||
736 | status = acpi_ds_create_operand(walk_state, arg, index); | ||
737 | if (ACPI_FAILURE(status)) { | ||
738 | goto cleanup; | ||
739 | } | ||
740 | |||
741 | count++; | ||
742 | index--; | ||
743 | |||
744 | ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, | ||
745 | "Arg #%d (%p) done, Arg1=%p\n", index, arg, | ||
746 | first_arg)); | ||
722 | } | 747 | } |
723 | 748 | ||
724 | return_ACPI_STATUS(status); | 749 | return_ACPI_STATUS(status); |
@@ -729,9 +754,8 @@ acpi_ds_create_operands(struct acpi_walk_state *walk_state, | |||
729 | * pop everything off of the operand stack and delete those | 754 | * pop everything off of the operand stack and delete those |
730 | * objects | 755 | * objects |
731 | */ | 756 | */ |
732 | (void)acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); | 757 | acpi_ds_obj_stack_pop_and_delete(arg_count, walk_state); |
733 | 758 | ||
734 | ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", | 759 | ACPI_EXCEPTION((AE_INFO, status, "While creating Arg %d", index)); |
735 | (arg_count + 1))); | ||
736 | return_ACPI_STATUS(status); | 760 | return_ACPI_STATUS(status); |
737 | } | 761 | } |