Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ACPI / hotplug: Fix concurrency issues and memory leaks

This changeset is aimed at fixing a few different but related
problems in the ACPI hotplug infrastructure.

First of all, since notify handlers may be run in parallel with
acpi_bus_scan(), acpi_bus_trim() and acpi_bus_hot_remove_device()
and some of them are installed for ACPI handles that have no struct
acpi_device objects attached (i.e. before those objects are created),
those notify handlers have to take acpi_scan_lock to prevent races
from taking place (e.g. a struct acpi_device is found to be present
for the given ACPI handle, but right after that it is removed by
acpi_bus_trim() running in parallel to the given notify handler).
Moreover, since some of them call acpi_bus_scan() and
acpi_bus_trim(), this leads to the conclusion that acpi_scan_lock
should be acquired by the callers of these two funtions rather by
these functions themselves.

For these reasons, make all notify handlers that can handle device
addition and eject events take acpi_scan_lock and remove the
acpi_scan_lock locking from acpi_bus_scan() and acpi_bus_trim().
Accordingly, update all of their users to make sure that they
are always called under acpi_scan_lock.

Furthermore, since eject operations are carried out asynchronously
with respect to the notify events that trigger them, with the help
of acpi_bus_hot_remove_device(), even if notify handlers take the
ACPI scan lock, it still is possible that, for example,
acpi_bus_trim() will run between acpi_bus_hot_remove_device() and
the notify handler that scheduled its execution and that
acpi_bus_trim() will remove the device node passed to
acpi_bus_hot_remove_device() for ejection. In that case, the struct
acpi_device object obtained by acpi_bus_hot_remove_device() will be
invalid and not-so-funny things will ensue. To protect agaist that,
make the users of acpi_bus_hot_remove_device() run get_device() on
ACPI device node objects that are about to be passed to it and make
acpi_bus_hot_remove_device() run put_device() on them and check if
their ACPI handles are not NULL (make acpi_device_unregister() clear
the device nodes' ACPI handles for that check to work).

Finally, observe that acpi_os_hotplug_execute() actually can fail,
in which case its caller ought to free memory allocated for the
context object to prevent leaks from happening. It also needs to
run put_device() on the device node that it ran get_device() on
previously in that case. Modify the code accordingly.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>

+139 -55
+37 -19
drivers/acpi/acpi_memhotplug.c
··· 153 153 return 0; 154 154 } 155 155 156 - static int 157 - acpi_memory_get_device(acpi_handle handle, 158 - struct acpi_memory_device **mem_device) 156 + static int acpi_memory_get_device(acpi_handle handle, 157 + struct acpi_memory_device **mem_device) 159 158 { 160 159 struct acpi_device *device = NULL; 161 - int result; 160 + int result = 0; 162 161 163 - if (!acpi_bus_get_device(handle, &device) && device) 162 + acpi_scan_lock_acquire(); 163 + 164 + acpi_bus_get_device(handle, &device); 165 + if (device) 164 166 goto end; 165 167 166 168 /* ··· 171 169 */ 172 170 result = acpi_bus_scan(handle); 173 171 if (result) { 174 - acpi_handle_warn(handle, "Cannot add acpi bus\n"); 175 - return -EINVAL; 172 + acpi_handle_warn(handle, "ACPI namespace scan failed\n"); 173 + result = -EINVAL; 174 + goto out; 176 175 } 177 176 result = acpi_bus_get_device(handle, &device); 178 177 if (result) { 179 178 acpi_handle_warn(handle, "Missing device object\n"); 180 - return -EINVAL; 179 + result = -EINVAL; 180 + goto out; 181 181 } 182 182 183 - end: 183 + end: 184 184 *mem_device = acpi_driver_data(device); 185 185 if (!(*mem_device)) { 186 186 dev_err(&device->dev, "driver data not found\n"); 187 - return -ENODEV; 187 + result = -ENODEV; 188 + goto out; 188 189 } 189 190 190 - return 0; 191 + out: 192 + acpi_scan_lock_release(); 193 + return result; 191 194 } 192 195 193 196 static int acpi_memory_check_device(struct acpi_memory_device *mem_device) ··· 312 305 struct acpi_device *device; 313 306 struct acpi_eject_event *ej_event = NULL; 314 307 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ 308 + acpi_status status; 315 309 316 310 switch (event) { 317 311 case ACPI_NOTIFY_BUS_CHECK: ··· 335 327 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 336 328 "\nReceived EJECT REQUEST notification for device\n")); 337 329 330 + status = AE_ERROR; 331 + acpi_scan_lock_acquire(); 332 + 338 333 if (acpi_bus_get_device(handle, &device)) { 339 334 acpi_handle_err(handle, "Device doesn't exist\n"); 340 - break; 335 + goto unlock; 341 336 } 342 337 mem_device = acpi_driver_data(device); 343 338 if (!mem_device) { 344 339 acpi_handle_err(handle, "Driver Data is NULL\n"); 345 - break; 340 + goto unlock; 346 341 } 347 342 348 343 ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); 349 344 if (!ej_event) { 350 345 pr_err(PREFIX "No memory, dropping EJECT\n"); 351 - break; 346 + goto unlock; 352 347 } 353 348 349 + get_device(&device->dev); 354 350 ej_event->device = device; 355 351 ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; 356 - acpi_os_hotplug_execute(acpi_bus_hot_remove_device, 357 - (void *)ej_event); 352 + /* The eject is carried out asynchronously. */ 353 + status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, 354 + ej_event); 355 + if (ACPI_FAILURE(status)) { 356 + put_device(&device->dev); 357 + kfree(ej_event); 358 + } 358 359 359 - /* eject is performed asynchronously */ 360 - return; 360 + unlock: 361 + acpi_scan_lock_release(); 362 + if (ACPI_SUCCESS(status)) 363 + return; 361 364 default: 362 365 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 363 366 "Unsupported event [0x%x]\n", event)); ··· 379 360 380 361 /* Inform firmware that the hotplug operation has completed */ 381 362 (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); 382 - return; 383 363 } 384 364 385 365 static void acpi_memory_device_free(struct acpi_memory_device *mem_device)
+8 -4
drivers/acpi/container.c
··· 88 88 acpi_status status; 89 89 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ 90 90 91 + acpi_scan_lock_acquire(); 92 + 91 93 switch (type) { 92 94 case ACPI_NOTIFY_BUS_CHECK: 93 95 /* Fall through */ ··· 105 103 /* device exist and this is a remove request */ 106 104 device->flags.eject_pending = 1; 107 105 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); 108 - return; 106 + goto out; 109 107 } 110 108 break; 111 109 } ··· 132 130 if (!acpi_bus_get_device(handle, &device) && device) { 133 131 device->flags.eject_pending = 1; 134 132 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); 135 - return; 133 + goto out; 136 134 } 137 135 break; 138 136 139 137 default: 140 138 /* non-hotplug event; possibly handled by other handler */ 141 - return; 139 + goto out; 142 140 } 143 141 144 142 /* Inform firmware that the hotplug operation has completed */ 145 143 (void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); 146 - return; 144 + 145 + out: 146 + acpi_scan_lock_release(); 147 147 } 148 148 149 149 static bool is_container(acpi_handle handle)
+16 -3
drivers/acpi/dock.c
··· 744 744 { 745 745 struct dock_data *data = context; 746 746 747 + acpi_scan_lock_acquire(); 747 748 dock_notify(data->handle, data->event, data->ds); 749 + acpi_scan_lock_release(); 748 750 kfree(data); 749 751 } 750 752 ··· 759 757 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK 760 758 && event != ACPI_NOTIFY_EJECT_REQUEST) 761 759 return 0; 760 + 761 + acpi_scan_lock_acquire(); 762 + 762 763 list_for_each_entry(dock_station, &dock_stations, sibling) { 763 764 if (dock_station->handle == handle) { 764 765 struct dock_data *dd; 766 + acpi_status status; 765 767 766 768 dd = kmalloc(sizeof(*dd), GFP_KERNEL); 767 769 if (!dd) 768 - return 0; 770 + break; 771 + 769 772 dd->handle = handle; 770 773 dd->event = event; 771 774 dd->ds = dock_station; 772 - acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd); 773 - return 0 ; 775 + status = acpi_os_hotplug_execute(acpi_dock_deferred_cb, 776 + dd); 777 + if (ACPI_FAILURE(status)) 778 + kfree(dd); 779 + 780 + break; 774 781 } 775 782 } 783 + 784 + acpi_scan_lock_release(); 776 785 return 0; 777 786 } 778 787
+17 -7
drivers/acpi/processor_driver.c
··· 683 683 struct acpi_device *device = NULL; 684 684 struct acpi_eject_event *ej_event = NULL; 685 685 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ 686 + acpi_status status; 686 687 int result; 688 + 689 + acpi_scan_lock_acquire(); 687 690 688 691 switch (event) { 689 692 case ACPI_NOTIFY_BUS_CHECK: ··· 736 733 break; 737 734 } 738 735 736 + get_device(&device->dev); 739 737 ej_event->device = device; 740 738 ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; 741 - acpi_os_hotplug_execute(acpi_bus_hot_remove_device, 742 - (void *)ej_event); 743 - 744 - /* eject is performed asynchronously */ 745 - return; 739 + /* The eject is carried out asynchronously. */ 740 + status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, 741 + ej_event); 742 + if (ACPI_FAILURE(status)) { 743 + put_device(&device->dev); 744 + kfree(ej_event); 745 + break; 746 + } 747 + goto out; 746 748 747 749 default: 748 750 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 749 751 "Unsupported event [0x%x]\n", event)); 750 752 751 753 /* non-hotplug event; possibly handled by other handler */ 752 - return; 754 + goto out; 753 755 } 754 756 755 757 /* Inform firmware that the hotplug operation has completed */ 756 758 (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); 757 - return; 759 + 760 + out: 761 + acpi_scan_lock_release(); 758 762 } 759 763 760 764 static acpi_status is_processor_device(acpi_handle handle)
+48 -21
drivers/acpi/scan.c
··· 42 42 struct list_head node; 43 43 }; 44 44 45 + void acpi_scan_lock_acquire(void) 46 + { 47 + mutex_lock(&acpi_scan_lock); 48 + } 49 + EXPORT_SYMBOL_GPL(acpi_scan_lock_acquire); 50 + 51 + void acpi_scan_lock_release(void) 52 + { 53 + mutex_unlock(&acpi_scan_lock); 54 + } 55 + EXPORT_SYMBOL_GPL(acpi_scan_lock_release); 56 + 45 57 int acpi_scan_add_handler(struct acpi_scan_handler *handler) 46 58 { 47 59 if (!handler || !handler->attach) ··· 107 95 } 108 96 static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); 109 97 110 - static void __acpi_bus_trim(struct acpi_device *start); 111 - 112 98 /** 113 99 * acpi_bus_hot_remove_device: hot-remove a device and its children 114 100 * @context: struct acpi_eject_event pointer (freed in this func) ··· 117 107 */ 118 108 void acpi_bus_hot_remove_device(void *context) 119 109 { 120 - struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context; 110 + struct acpi_eject_event *ej_event = context; 121 111 struct acpi_device *device = ej_event->device; 122 112 acpi_handle handle = device->handle; 123 113 acpi_handle temp; ··· 128 118 129 119 mutex_lock(&acpi_scan_lock); 130 120 121 + /* If there is no handle, the device node has been unregistered. */ 122 + if (!device->handle) { 123 + dev_dbg(&device->dev, "ACPI handle missing\n"); 124 + put_device(&device->dev); 125 + goto out; 126 + } 127 + 131 128 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 132 129 "Hot-removing device %s...\n", dev_name(&device->dev))); 133 130 134 - __acpi_bus_trim(device); 135 - /* Device node has been released. */ 131 + acpi_bus_trim(device); 132 + /* Device node has been unregistered. */ 133 + put_device(&device->dev); 136 134 device = NULL; 137 135 138 136 if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) { ··· 169 151 ost_code, NULL); 170 152 } 171 153 154 + out: 172 155 mutex_unlock(&acpi_scan_lock); 173 156 kfree(context); 174 157 return; ··· 231 212 goto err; 232 213 } 233 214 215 + get_device(&acpi_device->dev); 234 216 ej_event->device = acpi_device; 235 217 if (acpi_device->flags.eject_pending) { 236 218 /* event originated from ACPI eject notification */ ··· 244 224 ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); 245 225 } 246 226 247 - acpi_os_hotplug_execute(acpi_bus_hot_remove_device, (void *)ej_event); 227 + status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event); 228 + if (ACPI_FAILURE(status)) { 229 + put_device(&acpi_device->dev); 230 + kfree(ej_event); 231 + } 248 232 err: 249 233 return ret; 250 234 } ··· 803 779 * no more references. 804 780 */ 805 781 acpi_device_set_power(device, ACPI_STATE_D3_COLD); 782 + device->handle = NULL; 806 783 put_device(&device->dev); 807 784 } 808 785 ··· 1648 1623 * there has been a real error. There just have been no suitable ACPI objects 1649 1624 * in the table trunk from which the kernel could create a device and add an 1650 1625 * appropriate driver. 1626 + * 1627 + * Must be called under acpi_scan_lock. 1651 1628 */ 1652 1629 int acpi_bus_scan(acpi_handle handle) 1653 1630 { 1654 1631 void *device = NULL; 1655 1632 int error = 0; 1656 - 1657 - mutex_lock(&acpi_scan_lock); 1658 1633 1659 1634 if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) 1660 1635 acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, ··· 1666 1641 acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, 1667 1642 acpi_bus_device_attach, NULL, NULL, NULL); 1668 1643 1669 - mutex_unlock(&acpi_scan_lock); 1670 1644 return error; 1671 1645 } 1672 1646 EXPORT_SYMBOL(acpi_bus_scan); ··· 1702 1678 return AE_OK; 1703 1679 } 1704 1680 1705 - static void __acpi_bus_trim(struct acpi_device *start) 1681 + /** 1682 + * acpi_bus_trim - Remove ACPI device node and all of its descendants 1683 + * @start: Root of the ACPI device nodes subtree to remove. 1684 + * 1685 + * Must be called under acpi_scan_lock. 1686 + */ 1687 + void acpi_bus_trim(struct acpi_device *start) 1706 1688 { 1707 1689 /* 1708 1690 * Execute acpi_bus_device_detach() as a post-order callback to detach ··· 1724 1694 acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL, 1725 1695 acpi_bus_remove, NULL, NULL); 1726 1696 acpi_bus_remove(start->handle, 0, NULL, NULL); 1727 - } 1728 - 1729 - void acpi_bus_trim(struct acpi_device *start) 1730 - { 1731 - mutex_lock(&acpi_scan_lock); 1732 - __acpi_bus_trim(start); 1733 - mutex_unlock(&acpi_scan_lock); 1734 1697 } 1735 1698 EXPORT_SYMBOL_GPL(acpi_bus_trim); 1736 1699 ··· 1781 1758 acpi_csrt_init(); 1782 1759 acpi_container_init(); 1783 1760 1761 + mutex_lock(&acpi_scan_lock); 1784 1762 /* 1785 1763 * Enumerate devices in the ACPI namespace. 1786 1764 */ 1787 1765 result = acpi_bus_scan(ACPI_ROOT_OBJECT); 1788 1766 if (result) 1789 - return result; 1767 + goto out; 1790 1768 1791 1769 result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root); 1792 1770 if (result) 1793 - return result; 1771 + goto out; 1794 1772 1795 1773 result = acpi_bus_scan_fixed(); 1796 1774 if (result) { 1797 1775 acpi_device_unregister(acpi_root); 1798 - return result; 1776 + goto out; 1799 1777 } 1800 1778 1801 1779 acpi_update_all_gpes(); 1802 - return 0; 1780 + 1781 + out: 1782 + mutex_unlock(&acpi_scan_lock); 1783 + return result; 1803 1784 }
+6
drivers/pci/hotplug/acpiphp_glue.c
··· 1218 1218 handle = hp_work->handle; 1219 1219 type = hp_work->type; 1220 1220 1221 + acpi_scan_lock_acquire(); 1222 + 1221 1223 if (acpi_bus_get_device(handle, &device)) { 1222 1224 /* This bridge must have just been physically inserted */ 1223 1225 handle_bridge_insertion(handle, type); ··· 1297 1295 } 1298 1296 1299 1297 out: 1298 + acpi_scan_lock_release(); 1300 1299 kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ 1301 1300 } 1302 1301 ··· 1344 1341 1345 1342 func = (struct acpiphp_func *)context; 1346 1343 1344 + acpi_scan_lock_acquire(); 1345 + 1347 1346 switch (type) { 1348 1347 case ACPI_NOTIFY_BUS_CHECK: 1349 1348 /* bus re-enumerate */ ··· 1376 1371 break; 1377 1372 } 1378 1373 1374 + acpi_scan_lock_release(); 1379 1375 kfree(hp_work); /* allocated in handle_hotplug_event_func */ 1380 1376 } 1381 1377
+4 -1
drivers/pci/hotplug/sgi_hotplug.c
··· 425 425 pdevice = NULL; 426 426 } 427 427 428 + acpi_scan_lock_acquire(); 428 429 /* 429 430 * Walk the rootbus node's immediate children looking for 430 431 * the slot's device node(s). There can be more than ··· 459 458 } 460 459 } 461 460 } 461 + acpi_scan_lock_release(); 462 462 } 463 463 464 464 /* Call the driver for the new device */ ··· 510 508 /* Get the rootbus node pointer */ 511 509 phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; 512 510 511 + acpi_scan_lock_acquire(); 513 512 /* 514 513 * Walk the rootbus node's immediate children looking for 515 514 * the slot's device node(s). There can be more than ··· 541 538 acpi_bus_trim(device); 542 539 } 543 540 } 544 - 541 + acpi_scan_lock_release(); 545 542 } 546 543 547 544 /* Free the SN resources assigned to the Linux device.*/
+3
include/acpi/acpi_bus.h
··· 395 395 static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) 396 396 { return 0; } 397 397 #endif 398 + 399 + void acpi_scan_lock_acquire(void); 400 + void acpi_scan_lock_release(void); 398 401 int acpi_scan_add_handler(struct acpi_scan_handler *handler); 399 402 int acpi_bus_register_driver(struct acpi_driver *driver); 400 403 void acpi_bus_unregister_driver(struct acpi_driver *driver);