linux-stable/drivers/net/dsa
Vladimir Oltean 74b6d7d133 net: dsa: realtek: register the MDIO bus under devres
The Linux device model permits both the ->shutdown and ->remove driver
methods to get called during a shutdown procedure. Example: a DSA switch
which sits on an SPI bus, and the SPI bus driver calls this on its
->shutdown method:

spi_unregister_controller
-> device_for_each_child(&ctlr->dev, NULL, __unregister);
   -> spi_unregister_device(to_spi_device(dev));
      -> device_del(&spi->dev);

So this is a simple pattern which can theoretically appear on any bus,
although the only other buses on which I've been able to find it are
I2C:

i2c_del_adapter
-> device_for_each_child(&adap->dev, NULL, __unregister_client);
   -> i2c_unregister_device(client);
      -> device_unregister(&client->dev);

The implication of this pattern is that devices on these buses can be
unregistered after having been shut down. The drivers for these devices
might choose to return early either from ->remove or ->shutdown if the
other callback has already run once, and they might choose that the
->shutdown method should only perform a subset of the teardown done by
->remove (to avoid unnecessary delays when rebooting).

So in other words, the device driver may choose on ->remove to not
do anything (therefore to not unregister an MDIO bus it has registered
on ->probe), because this ->remove is actually triggered by the
device_shutdown path, and its ->shutdown method has already run and done
the minimally required cleanup.

This used to be fine until the blamed commit, but now, the following
BUG_ON triggers:

void mdiobus_free(struct mii_bus *bus)
{
	/* For compatibility with error handling in drivers. */
	if (bus->state == MDIOBUS_ALLOCATED) {
		kfree(bus);
		return;
	}

	BUG_ON(bus->state != MDIOBUS_UNREGISTERED);
	bus->state = MDIOBUS_RELEASED;

	put_device(&bus->dev);
}

In other words, there is an attempt to free an MDIO bus which was not
unregistered. The attempt to free it comes from the devres release
callbacks of the SPI device, which are executed after the device is
unregistered.

I'm not saying that the fact that MDIO buses allocated using devres
would automatically get unregistered wasn't strange. I'm just saying
that the commit didn't care about auditing existing call paths in the
kernel, and now, the following code sequences are potentially buggy:

(a) devm_mdiobus_alloc followed by plain mdiobus_register, for a device
    located on a bus that unregisters its children on shutdown. After
    the blamed patch, either both the alloc and the register should use
    devres, or none should.

(b) devm_mdiobus_alloc followed by plain mdiobus_register, and then no
    mdiobus_unregister at all in the remove path. After the blamed
    patch, nobody unregisters the MDIO bus anymore, so this is even more
    buggy than the previous case which needs a specific bus
    configuration to be seen, this one is an unconditional bug.

In this case, the Realtek drivers fall under category (b). To solve it,
we can register the MDIO bus under devres too, which restores the
previous behavior.

Fixes: ac3a68d566 ("net: phy: don't abuse devres in devm_mdiobus_register()")
Reported-by: Lino Sanfilippo <LinoSanfilippo@gmx.de>
Reported-by: Alvin Šipraga <alsi@bang-olufsen.dk>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
2021-09-21 13:52:16 +01:00
..
b53 net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
hirschmann net: dsa: hellcreek: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
microchip net: dsa: microchip: ksz8863: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
mv88e6xxx net: dsa: tear down devlink port regions when tearing down the devlink port on error 2021-09-19 13:05:44 +01:00
ocelot net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
qca net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
sja1105 net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
xrs700x net: dsa: xrs700x: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
bcm_sf2.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
bcm_sf2.h net: dsa: bcm_sf2: setup BCM4908 internal crossbar 2021-03-12 17:06:37 -08:00
bcm_sf2_cfp.c net: dsa: propagate extack to .port_vlan_add 2021-02-14 17:38:11 -08:00
bcm_sf2_regs.h net: dsa: bcm_sf2: fix BCM4908 RGMII reg(s) 2021-03-18 14:44:05 -07:00
dsa_loop.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
dsa_loop.h
dsa_loop_bdinfo.c
Kconfig dsa: simplify Kconfig symbols and dependencies 2021-03-22 12:15:37 -07:00
lan9303-core.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
lan9303.h net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
lan9303_i2c.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
lan9303_mdio.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
lantiq_gswip.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
lantiq_pce.h net: dsa: Use the correct style for SPDX License Identifier 2019-09-22 15:25:08 -07:00
Makefile net: dsa: add Arrow SpeedChips XRS700x driver 2021-01-15 15:37:37 -08:00
mt7530.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
mt7530.h net: dsa: mt7530: manually set up VLAN ID 0 2021-08-25 11:09:31 +01:00
mv88e6060.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
mv88e6060.h
qca8k.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
qca8k.h net: dsa: qca8k: add support for internal phy and internal mdio 2021-05-14 15:30:22 -07:00
realtek-smi-core.c net: dsa: realtek: register the MDIO bus under devres 2021-09-21 13:52:16 +01:00
realtek-smi-core.h net: dsa: propagate extack to .port_vlan_filtering 2021-02-14 17:38:12 -08:00
rtl8366.c net: dsa: propagate extack to .port_vlan_filtering 2021-02-14 17:38:12 -08:00
rtl8366rb.c net: dsa: rtl8366rb: standardize init jam tables 2021-01-27 20:21:20 -08:00
vitesse-vsc73xx-core.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
vitesse-vsc73xx-platform.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
vitesse-vsc73xx-spi.c net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00
vitesse-vsc73xx.h net: dsa: be compatible with masters which unregister on shutdown 2021-09-19 12:08:37 +01:00