| From 2441191a19039002b2c454a261fb45986df15184 Mon Sep 17 00:00:00 2001 |
| From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> |
| Date: Thu, 7 Nov 2013 01:41:27 +0100 |
| Subject: ACPI / hotplug: Fix handle_root_bridge_removal() |
| |
| From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> |
| |
| commit 2441191a19039002b2c454a261fb45986df15184 upstream. |
| |
| It is required to do get_device() on the struct acpi_device in |
| question before passing it to acpi_bus_hot_remove_device() through |
| acpi_os_hotplug_execute(), because acpi_bus_hot_remove_device() |
| calls acpi_scan_hot_remove() that does put_device() on that |
| object. |
| |
| The ACPI PCI root removal routine, handle_root_bridge_removal(), |
| doesn't do that, which may lead to premature freeing of the |
| device object or to executing put_device() on an object that |
| has been freed already. |
| |
| Fix this problem by making handle_root_bridge_removal() use |
| get_device() as appropriate. |
| |
| Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> |
| Acked-by: Toshi Kani <toshi.kani@hp.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/acpi/pci_root.c | 5 ++++- |
| 1 file changed, 4 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/acpi/pci_root.c |
| +++ b/drivers/acpi/pci_root.c |
| @@ -614,9 +614,12 @@ static void handle_root_bridge_removal(s |
| ej_event->device = device; |
| ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; |
| |
| + get_device(&device->dev); |
| status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); |
| - if (ACPI_FAILURE(status)) |
| + if (ACPI_FAILURE(status)) { |
| + put_device(&device->dev); |
| kfree(ej_event); |
| + } |
| } |
| |
| static void _handle_hotplug_event_root(struct work_struct *work) |