summaryrefslogtreecommitdiff
path: root/drivers/pci/hotplug
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2020-06-26 20:42:34 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-08-21 14:14:46 +0300
commit815260de064b1a6210a171ff2e9366d79a7b7434 (patch)
tree48f78e36586ea6577f148dc539cfbb06d8db757d /drivers/pci/hotplug
parent64947da67a3a39990deb5f342112010b3286c609 (diff)
downloadlinux-815260de064b1a6210a171ff2e9366d79a7b7434.tar.xz
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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c14
1 files changed, 11 insertions, 3 deletions
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;
}