| From dae68d7fd4930315389117e9da35b763f12238f9 Mon Sep 17 00:00:00 2001 |
| From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> |
| Date: Fri, 26 Jun 2020 19:42:34 +0200 |
| Subject: [PATCH] PCI: hotplug: ACPI: Fix context refcounting in |
| acpiphp_grab_context() |
| |
| commit dae68d7fd4930315389117e9da35b763f12238f9 upstream. |
| |
| If context is not NULL in acpiphp_grab_context(), but the |
| is_going_away flag is set for the device's parent, the reference |
| counter of the context needs to be decremented before returning |
| NULL or the context will never be freed, so make that happen. |
| |
| Fixes: edf5bf34d408 ("ACPI / dock: Use callback pointers from devices' ACPI hotplug contexts") |
| Reported-by: Vasily Averin <vvs@virtuozzo.com> |
| Cc: 3.15+ <stable@vger.kernel.org> # 3.15+ |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| |
| diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c |
| index b4c92cee13f8..3365c93abf0e 100644 |
| --- a/drivers/pci/hotplug/acpiphp_glue.c |
| +++ b/drivers/pci/hotplug/acpiphp_glue.c |
| @@ -122,13 +122,21 @@ static struct acpiphp_context *acpiphp_grab_context(struct acpi_device *adev) |
| struct acpiphp_context *context; |
| |
| acpi_lock_hp_context(); |
| + |
| context = acpiphp_get_context(adev); |
| - if (!context || context->func.parent->is_going_away) { |
| - acpi_unlock_hp_context(); |
| - return NULL; |
| + if (!context) |
| + goto unlock; |
| + |
| + if (context->func.parent->is_going_away) { |
| + acpiphp_put_context(context); |
| + context = NULL; |
| + goto unlock; |
| } |
| + |
| get_bridge(context->func.parent); |
| acpiphp_put_context(context); |
| + |
| +unlock: |
| acpi_unlock_hp_context(); |
| return context; |
| } |
| -- |
| 2.27.0 |
| |