Skip to content

Commit

Permalink
ACPI: property: Release subnode properties with data nodes
Browse files Browse the repository at this point in the history
commit 3bd561e upstream.

struct acpi_device_properties describes one source of properties present
on either struct acpi_device or struct acpi_data_node. When properties are
parsed, both are populated but when released, only those properties that
are associated with the device node are freed.

Fix this by also releasing memory of the data node properties.

Fixes: 5f5e489 ("ACPI / property: Allow multiple property compatible _DSD entries")
Cc: 4.20+ <stable@vger.kernel.org> # 4.20+
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Sakari Ailus authored and gregkh committed Jun 9, 2022
1 parent d5a16a6 commit 2e7cfcc
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions drivers/acpi/property.c
Expand Up @@ -433,6 +433,16 @@ void acpi_init_properties(struct acpi_device *adev)
acpi_extract_apple_properties(adev);
}

static void acpi_free_device_properties(struct list_head *list)
{
struct acpi_device_properties *props, *tmp;

list_for_each_entry_safe(props, tmp, list, list) {
list_del(&props->list);
kfree(props);
}
}

static void acpi_destroy_nondev_subnodes(struct list_head *list)
{
struct acpi_data_node *dn, *next;
Expand All @@ -445,22 +455,18 @@ static void acpi_destroy_nondev_subnodes(struct list_head *list)
wait_for_completion(&dn->kobj_done);
list_del(&dn->sibling);
ACPI_FREE((void *)dn->data.pointer);
acpi_free_device_properties(&dn->data.properties);
kfree(dn);
}
}

void acpi_free_properties(struct acpi_device *adev)
{
struct acpi_device_properties *props, *tmp;

acpi_destroy_nondev_subnodes(&adev->data.subnodes);
ACPI_FREE((void *)adev->data.pointer);
adev->data.of_compatible = NULL;
adev->data.pointer = NULL;
list_for_each_entry_safe(props, tmp, &adev->data.properties, list) {
list_del(&props->list);
kfree(props);
}
acpi_free_device_properties(&adev->data.properties);
}

/**
Expand Down

0 comments on commit 2e7cfcc

Please sign in to comment.