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

net: mdio_bus: add refcounting for fwnodes to mdiobus

Luiz Angelo Daros de Luca reports that the MDIO bus code maintains a
reference to the DT node, but does not hold a refcount on the node.

The simple solution to this is to add the necessary refcounting into
the MDIO bus code for all users, ensuring that on registration, the
refcount is incremented, and only dropped when the MDIO bus is
released.

Do this for fwnodes, so we not only fix this for DT, but also other
types of firmware nodes as well.

Reported-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Russell King (Oracle) and committed by
David S. Miller
3b73a7b8 0f2b2147

+13
+13
drivers/net/phy/mdio_bus.c
··· 193 193 bus->state != MDIOBUS_ALLOCATED, 194 194 "%s: not in RELEASED or ALLOCATED state\n", 195 195 bus->id); 196 + 197 + if (bus->state == MDIOBUS_RELEASED) 198 + fwnode_handle_put(dev_fwnode(d)); 199 + 196 200 kfree(bus); 197 201 } 198 202 ··· 687 683 bus->dev.class = &mdio_bus_class; 688 684 bus->dev.groups = NULL; 689 685 dev_set_name(&bus->dev, "%s", bus->id); 686 + 687 + /* If the bus state is allocated, we're registering a fresh bus 688 + * that may have a fwnode associated with it. Grab a reference 689 + * to the fwnode. This will be dropped when the bus is released. 690 + * If the bus was set to unregistered, it means that the bus was 691 + * previously registered, and we've already grabbed a reference. 692 + */ 693 + if (bus->state == MDIOBUS_ALLOCATED) 694 + fwnode_handle_get(dev_fwnode(&bus->dev)); 690 695 691 696 /* We need to set state to MDIOBUS_UNREGISTERED to correctly release 692 697 * the device in mdiobus_free()