* [PATCH] ACPICA: Fix parse tree memory leak on AML execution error unwind
@ 2026-10-15 1:28 Iurii Trukhin
2026-10-15 15:58 ` Markus Elfring
2026-10-15 16:04 ` Rafael J. Wysocki (Intel)
0 siblings, 2 replies; 3+ messages in thread
From: Iurii Trukhin @ 2026-10-15 1:28 UTC (permalink / raw)
To: Rafael J. Wysocki, Len Brown
Cc: Robert Moore, Erik Kaneda, Maciej Wieczor-Retman,
Pawel Chmielewski, linux-acpi, acpica-devel, linux-kernel,
Iurii Trukhin
acpi_ps_complete_this_op() decides whether to defer deletion of an
AML_CLASS_ARGUMENT parse object to its enclosing parent by checking
walk_state->op_info->class instead of the opcode class of the op being
completed.
When acpi_ps_complete_op() or acpi_ps_complete_final_op() unwinds open
parser scopes on AE_CTRL_TERMINATE or an execution error (such as
AE_NOT_FOUND when resolving a missing symbol inside a control method),
it pops each enclosing parent op and passes it to
acpi_ps_complete_this_op() while walk_state->op_info still points to the
last child op that failed. If that failing child op was of class
AML_CLASS_ARGUMENT (for example, AML_INT_NAMEPATH_OP when
acpi_ps_get_arguments() fails to resolve a method call or predicate
operand), acpi_ps_complete_this_op() sees AML_CLASS_ARGUMENT for every
popped parent op and returns AE_OK early without deleting any of the
enclosing parent subtrees.
For nested control methods invoked via acpi_ds_call_control_method(),
the walk state is initialized with root_op = NULL, so top-level ops in
the called method (such as AML_IF_OP) have op->common.parent == NULL
and are never attached to a root scope op. Skipping
acpi_ps_delete_parse_tree() during error unwind leaks the entire parse
subtree (both Acpi-ParseExt and Acpi-Parse objects, the latter merged
by SLUB into the 80-byte Acpi-State kmem_cache on 64-bit kernels) on
every failed GPE or method evaluation.
Look up the opcode info of op->common.aml_opcode directly in
acpi_ps_complete_this_op() and only defer deletion of
AML_CLASS_ARGUMENT ops when op->common.parent is non-NULL, without
mutating walk_state->opcode during error unwind (which acpi_ps_parse_loop()
still inspects when skipping failed module-level scopes). Remove the
now-redundant acpi_ps_delete_parse_tree(*op) inside the AML_REGION_OP /
AML_DATA_REGION_OP error block in acpi_ps_complete_op(), which previously
worked around this bug only for region ops and caused a double-free when
region creation failed on a non-argument child op. Also use
acpi_ut_delete_generic_state() instead of ACPI_FREE() when draining
walk_state->control_state in acpi_ps_parse_loop().
Fixes: 5088814a6e93 ("ACPICA: AML parser: attempt to continue loading
table after error")
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221241
Signed-off-by: Iurii Trukhin <yuri@trukhin.com>
---
drivers/acpi/acpica/psloop.c | 5 +++--
drivers/acpi/acpica/psobject.c | 1 -
drivers/acpi/acpica/psparse.c | 7 +++++--
3 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
index 24a57f971c96..0b672a531907 100644
--- a/drivers/acpi/acpica/psloop.c
+++ b/drivers/acpi/acpica/psloop.c
@@ -464,8 +464,9 @@ acpi_status acpi_ps_parse_loop(struct
acpi_walk_state *walk_state)
walk_state->aml =
parser_state->aml;
}
- ACPI_FREE(acpi_ut_pop_generic_state
- (&walk_state->control_state));
+ acpi_ut_delete_generic_state
+ (acpi_ut_pop_generic_state
+ (&walk_state->control_state));
}
op = NULL;
continue;
diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c
index 629cafab1930..f1425b98087b 100644
--- a/drivers/acpi/acpica/psobject.c
+++ b/drivers/acpi/acpica/psobject.c
@@ -559,7 +559,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
node);
acpi_ns_remove_node((*op)->common.node);
(*op)->common.node = NULL;
- acpi_ps_delete_parse_tree(*op);
}
status2 =
diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c
index 42ec8abef626..b5110d43ab7a 100644
--- a/drivers/acpi/acpica/psparse.c
+++ b/drivers/acpi/acpica/psparse.c
@@ -108,6 +108,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state *walk_state,
{
union acpi_parse_object *prev;
union acpi_parse_object *next;
+ const struct acpi_opcode_info *op_info;
const struct acpi_opcode_info *parent_info;
union acpi_parse_object *replacement_op = NULL;
acpi_status status = AE_OK;
@@ -124,9 +125,11 @@ acpi_ps_complete_this_op(struct acpi_walk_state
*walk_state,
/* Delete this op and the subtree below it if asked to */
+ op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) !=
- ACPI_PARSE_DELETE_TREE)
- || (walk_state->op_info->class == AML_CLASS_ARGUMENT)) {
+ ACPI_PARSE_DELETE_TREE) ||
+ ((op_info->class == AML_CLASS_ARGUMENT) &&
+ op->common.parent)) {
return_ACPI_STATUS(AE_OK);
}
--
2.56.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] ACPICA: Fix parse tree memory leak on AML execution error unwind
2026-10-15 1:28 [PATCH] ACPICA: Fix parse tree memory leak on AML execution error unwind Iurii Trukhin
@ 2026-10-15 15:58 ` Markus Elfring
2026-10-15 16:04 ` Rafael J. Wysocki (Intel)
1 sibling, 0 replies; 3+ messages in thread
From: Markus Elfring @ 2026-10-15 15:58 UTC (permalink / raw)
To: Iurii Trukhin, acpica-devel, linux-acpi, Len Brown, Rafael J. Wysocki
Cc: LKML, Erik Kaneda, Maciej Wieczor-Retman, Pawel Chmielewski,
Robert Moore
…
> Fixes: 5088814a6e93 ("ACPICA: AML parser: attempt to continue loading
> table after error")
…
See also once more:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?h=v7.3-rc7#n145
Regards,
Markus
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] ACPICA: Fix parse tree memory leak on AML execution error unwind
2026-10-15 1:28 [PATCH] ACPICA: Fix parse tree memory leak on AML execution error unwind Iurii Trukhin
2026-10-15 15:58 ` Markus Elfring
@ 2026-10-15 16:04 ` Rafael J. Wysocki (Intel)
1 sibling, 0 replies; 3+ messages in thread
From: Rafael J. Wysocki (Intel) @ 2026-10-15 16:04 UTC (permalink / raw)
To: Iurii Trukhin
Cc: Rafael J. Wysocki, Len Brown, Robert Moore, Erik Kaneda,
Maciej Wieczor-Retman, Pawel Chmielewski, linux-acpi,
acpica-devel, linux-kernel
On Thu, Oct 15, 2026 at 3:28 AM Iurii Trukhin <yuri@trukhin.com> wrote:
>
> acpi_ps_complete_this_op() decides whether to defer deletion of an
> AML_CLASS_ARGUMENT parse object to its enclosing parent by checking
> walk_state->op_info->class instead of the opcode class of the op being
> completed.
>
> When acpi_ps_complete_op() or acpi_ps_complete_final_op() unwinds open
> parser scopes on AE_CTRL_TERMINATE or an execution error (such as
> AE_NOT_FOUND when resolving a missing symbol inside a control method),
> it pops each enclosing parent op and passes it to
> acpi_ps_complete_this_op() while walk_state->op_info still points to the
> last child op that failed. If that failing child op was of class
> AML_CLASS_ARGUMENT (for example, AML_INT_NAMEPATH_OP when
> acpi_ps_get_arguments() fails to resolve a method call or predicate
> operand), acpi_ps_complete_this_op() sees AML_CLASS_ARGUMENT for every
> popped parent op and returns AE_OK early without deleting any of the
> enclosing parent subtrees.
>
> For nested control methods invoked via acpi_ds_call_control_method(),
> the walk state is initialized with root_op = NULL, so top-level ops in
> the called method (such as AML_IF_OP) have op->common.parent == NULL
> and are never attached to a root scope op. Skipping
> acpi_ps_delete_parse_tree() during error unwind leaks the entire parse
> subtree (both Acpi-ParseExt and Acpi-Parse objects, the latter merged
> by SLUB into the 80-byte Acpi-State kmem_cache on 64-bit kernels) on
> every failed GPE or method evaluation.
>
> Look up the opcode info of op->common.aml_opcode directly in
> acpi_ps_complete_this_op() and only defer deletion of
> AML_CLASS_ARGUMENT ops when op->common.parent is non-NULL, without
> mutating walk_state->opcode during error unwind (which acpi_ps_parse_loop()
> still inspects when skipping failed module-level scopes). Remove the
> now-redundant acpi_ps_delete_parse_tree(*op) inside the AML_REGION_OP /
> AML_DATA_REGION_OP error block in acpi_ps_complete_op(), which previously
> worked around this bug only for region ops and caused a double-free when
> region creation failed on a non-argument child op. Also use
> acpi_ut_delete_generic_state() instead of ACPI_FREE() when draining
> walk_state->control_state in acpi_ps_parse_loop().
>
> Fixes: 5088814a6e93 ("ACPICA: AML parser: attempt to continue loading
> table after error")
> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221241
> Signed-off-by: Iurii Trukhin <yuri@trukhin.com>
Please submit this change as a pull request to the upstream ACPICA
project on GitHub. The kernel will pick it up from there as per
Documentation/driver-api/acpi/linuxized-acpica.rst
> ---
> drivers/acpi/acpica/psloop.c | 5 +++--
> drivers/acpi/acpica/psobject.c | 1 -
> drivers/acpi/acpica/psparse.c | 7 +++++--
> 3 files changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c
> index 24a57f971c96..0b672a531907 100644
> --- a/drivers/acpi/acpica/psloop.c
> +++ b/drivers/acpi/acpica/psloop.c
> @@ -464,8 +464,9 @@ acpi_status acpi_ps_parse_loop(struct
> acpi_walk_state *walk_state)
> walk_state->aml =
> parser_state->aml;
> }
> - ACPI_FREE(acpi_ut_pop_generic_state
> - (&walk_state->control_state));
> + acpi_ut_delete_generic_state
> + (acpi_ut_pop_generic_state
> + (&walk_state->control_state));
> }
> op = NULL;
> continue;
> diff --git a/drivers/acpi/acpica/psobject.c b/drivers/acpi/acpica/psobject.c
> index 629cafab1930..f1425b98087b 100644
> --- a/drivers/acpi/acpica/psobject.c
> +++ b/drivers/acpi/acpica/psobject.c
> @@ -559,7 +559,6 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
> node);
> acpi_ns_remove_node((*op)->common.node);
> (*op)->common.node = NULL;
> - acpi_ps_delete_parse_tree(*op);
> }
>
> status2 =
> diff --git a/drivers/acpi/acpica/psparse.c b/drivers/acpi/acpica/psparse.c
> index 42ec8abef626..b5110d43ab7a 100644
> --- a/drivers/acpi/acpica/psparse.c
> +++ b/drivers/acpi/acpica/psparse.c
> @@ -108,6 +108,7 @@ acpi_ps_complete_this_op(struct acpi_walk_state *walk_state,
> {
> union acpi_parse_object *prev;
> union acpi_parse_object *next;
> + const struct acpi_opcode_info *op_info;
> const struct acpi_opcode_info *parent_info;
> union acpi_parse_object *replacement_op = NULL;
> acpi_status status = AE_OK;
> @@ -124,9 +125,11 @@ acpi_ps_complete_this_op(struct acpi_walk_state
> *walk_state,
>
> /* Delete this op and the subtree below it if asked to */
>
> + op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
> if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) !=
> - ACPI_PARSE_DELETE_TREE)
> - || (walk_state->op_info->class == AML_CLASS_ARGUMENT)) {
> + ACPI_PARSE_DELETE_TREE) ||
> + ((op_info->class == AML_CLASS_ARGUMENT) &&
> + op->common.parent)) {
> return_ACPI_STATUS(AE_OK);
> }
>
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-15 16:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-15 1:28 [PATCH] ACPICA: Fix parse tree memory leak on AML execution error unwind Iurii Trukhin
2026-10-15 15:58 ` Markus Elfring
2026-10-15 16:04 ` Rafael J. Wysocki (Intel)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®