Skip to content

Commit 673b427

Browse files
joukewitteveenrafaeljw
authored andcommitted
ACPI / battery: Safe unregistering of hooks
A hooking API was implemented for 4.17 in fa93854 followed by hooks for Thinkpad laptops in 2801b96. The Thinkpad drivers did not support the Thinkpad 13 and the hooking API crashes on unsupported batteries by altering a list of hooks during unsafe iteration. Thus, Thinkpad 13 laptops could no longer boot. Additionally, a lock was kept in place and debugging information was printed out of order. Fixes: fa93854 (battery: Add the battery hooking API) Cc: 4.17+ <[email protected]> # 4.17+ Signed-off-by: Jouke Witteveen <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 021c917 commit 673b427

File tree

1 file changed

+5
-4
lines changed

1 file changed

+5
-4
lines changed

drivers/acpi/battery.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -717,10 +717,11 @@ void battery_hook_register(struct acpi_battery_hook *hook)
717717
*/
718718
pr_err("extension failed to load: %s", hook->name);
719719
__battery_hook_unregister(hook, 0);
720-
return;
720+
goto end;
721721
}
722722
}
723723
pr_info("new extension: %s\n", hook->name);
724+
end:
724725
mutex_unlock(&hook_mutex);
725726
}
726727
EXPORT_SYMBOL_GPL(battery_hook_register);
@@ -732,7 +733,7 @@ EXPORT_SYMBOL_GPL(battery_hook_register);
732733
*/
733734
static void battery_hook_add_battery(struct acpi_battery *battery)
734735
{
735-
struct acpi_battery_hook *hook_node;
736+
struct acpi_battery_hook *hook_node, *tmp;
736737

737738
mutex_lock(&hook_mutex);
738739
INIT_LIST_HEAD(&battery->list);
@@ -744,15 +745,15 @@ static void battery_hook_add_battery(struct acpi_battery *battery)
744745
* when a battery gets hotplugged or initialized
745746
* during the battery module initialization.
746747
*/
747-
list_for_each_entry(hook_node, &battery_hook_list, list) {
748+
list_for_each_entry_safe(hook_node, tmp, &battery_hook_list, list) {
748749
if (hook_node->add_battery(battery->bat)) {
749750
/*
750751
* The notification of the extensions has failed, to
751752
* prevent further errors we will unload the extension.
752753
*/
753-
__battery_hook_unregister(hook_node, 0);
754754
pr_err("error in extension, unloading: %s",
755755
hook_node->name);
756+
__battery_hook_unregister(hook_node, 0);
756757
}
757758
}
758759
mutex_unlock(&hook_mutex);

0 commit comments

Comments
 (0)