4.9-stable review patch.  If anyone has any objections, please let me know.


From: Jon Mason <jon.ma...@broadcom.com>

[ Upstream commit b60161668199ac62011c024adc9e66713b9554e7 ]

There is a potential unnecessary refcount decrement on error path of
put_device(&pb->mii_bus->dev), as it is possible to avoid the
of_mdio_find_bus() call if mux_bus is specified by the calling function.

The same put_device() is not called in the error path if the
devm_kzalloc of pb fails.  This caused the variable used in the
put_device() to be changed, as the pb pointer was obviously not set up.

There is an unnecessary of_node_get() on child_bus_node if the
of_mdiobus_register() is successful, as the
for_each_available_child_of_node() automatically increments this.
Thus the refcount on this node will always be +1 more than it should be.

There is no of_node_put() on child_bus_node if the of_mdiobus_register()
call fails.

Finally, it is lacking devm_kfree() of pb in the error path.  While this
might not be technically necessary, it was present in other parts of the
function.  So, I am adding it where necessary to make it uniform.

Signed-off-by: Jon Mason <jon.ma...@broadcom.com>
Fixes: f20e6657a875 ("mdio: mux: Enhanced MDIO mux framework for integrated 
Fixes: 0ca2997d1452 ("netdev/of/phy: Add MDIO bus multiplexer support.")
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Sasha Levin <alexander.le...@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
 drivers/net/phy/mdio-mux.c |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

--- a/drivers/net/phy/mdio-mux.c
+++ b/drivers/net/phy/mdio-mux.c
@@ -122,10 +122,9 @@ int mdio_mux_init(struct device *dev,
        pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL);
        if (pb == NULL) {
                ret_val = -ENOMEM;
-               goto err_parent_bus;
+               goto err_pb_kz;
        pb->switch_data = data;
        pb->switch_fn = switch_fn;
        pb->current_child = -1;
@@ -154,6 +153,7 @@ int mdio_mux_init(struct device *dev,
                cb->mii_bus = mdiobus_alloc();
                if (!cb->mii_bus) {
                        ret_val = -ENOMEM;
+                       devm_kfree(dev, cb);
@@ -169,8 +169,8 @@ int mdio_mux_init(struct device *dev,
                if (r) {
                        devm_kfree(dev, cb);
+                       of_node_put(child_bus_node);
                } else {
-                       of_node_get(child_bus_node);
                        cb->next = pb->children;
                        pb->children = cb;
@@ -181,9 +181,11 @@ int mdio_mux_init(struct device *dev,
                return 0;
+       devm_kfree(dev, pb);
        /* balance the reference of_mdio_find_bus() took */
-       put_device(&pb->mii_bus->dev);
+       if (!mux_bus)
+               put_device(&parent_bus->dev);
        return ret_val;

Reply via email to