Skip to content

Commit a619cba

Browse files
lkpdnBartosz Golaszewski
authored andcommitted
gpio: virtuser: fix missing lookup table cleanups
When a virtuser device is created via configfs and the probe fails due to an incorrect lookup table, the table is not removed. This prevents subsequent probe attempts from succeeding, even if the issue is corrected, unless the device is released. Additionally, cleanup is also needed in the less likely case of platform_device_register_full() failure. Besides, a consistent memory leak in lookup_table->dev_id was spotted using kmemleak by toggling the live state between 0 and 1 with a correct lookup table. Introduce gpio_virtuser_remove_lookup_table() as the counterpart to the existing gpio_virtuser_make_lookup_table() and call it from all necessary points to ensure proper cleanup. Fixes: 91581c4 ("gpio: virtuser: new virtual testing driver for the GPIO API") Signed-off-by: Koichiro Den <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent fc033cf commit a619cba

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

drivers/gpio/gpio-virtuser.c

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,6 +1439,15 @@ gpio_virtuser_make_lookup_table(struct gpio_virtuser_device *dev)
14391439
return 0;
14401440
}
14411441

1442+
static void
1443+
gpio_virtuser_remove_lookup_table(struct gpio_virtuser_device *dev)
1444+
{
1445+
gpiod_remove_lookup_table(dev->lookup_table);
1446+
kfree(dev->lookup_table->dev_id);
1447+
kfree(dev->lookup_table);
1448+
dev->lookup_table = NULL;
1449+
}
1450+
14421451
static struct fwnode_handle *
14431452
gpio_virtuser_make_device_swnode(struct gpio_virtuser_device *dev)
14441453
{
@@ -1487,34 +1496,40 @@ gpio_virtuser_device_activate(struct gpio_virtuser_device *dev)
14871496
pdevinfo.fwnode = swnode;
14881497

14891498
ret = gpio_virtuser_make_lookup_table(dev);
1490-
if (ret) {
1491-
fwnode_remove_software_node(swnode);
1492-
return ret;
1493-
}
1499+
if (ret)
1500+
goto err_remove_swnode;
14941501

14951502
reinit_completion(&dev->probe_completion);
14961503
dev->driver_bound = false;
14971504
bus_register_notifier(&platform_bus_type, &dev->bus_notifier);
14981505

14991506
pdev = platform_device_register_full(&pdevinfo);
15001507
if (IS_ERR(pdev)) {
1508+
ret = PTR_ERR(pdev);
15011509
bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier);
1502-
fwnode_remove_software_node(swnode);
1503-
return PTR_ERR(pdev);
1510+
goto err_remove_lookup_table;
15041511
}
15051512

15061513
wait_for_completion(&dev->probe_completion);
15071514
bus_unregister_notifier(&platform_bus_type, &dev->bus_notifier);
15081515

15091516
if (!dev->driver_bound) {
1510-
platform_device_unregister(pdev);
1511-
fwnode_remove_software_node(swnode);
1512-
return -ENXIO;
1517+
ret = -ENXIO;
1518+
goto err_unregister_pdev;
15131519
}
15141520

15151521
dev->pdev = pdev;
15161522

15171523
return 0;
1524+
1525+
err_unregister_pdev:
1526+
platform_device_unregister(pdev);
1527+
err_remove_lookup_table:
1528+
gpio_virtuser_remove_lookup_table(dev);
1529+
err_remove_swnode:
1530+
fwnode_remove_software_node(swnode);
1531+
1532+
return ret;
15181533
}
15191534

15201535
static void
@@ -1526,10 +1541,9 @@ gpio_virtuser_device_deactivate(struct gpio_virtuser_device *dev)
15261541

15271542
swnode = dev_fwnode(&dev->pdev->dev);
15281543
platform_device_unregister(dev->pdev);
1544+
gpio_virtuser_remove_lookup_table(dev);
15291545
fwnode_remove_software_node(swnode);
15301546
dev->pdev = NULL;
1531-
gpiod_remove_lookup_table(dev->lookup_table);
1532-
kfree(dev->lookup_table);
15331547
}
15341548

15351549
static ssize_t

0 commit comments

Comments
 (0)