mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net] net: phy: reject attach while the PHY driver is in transition
@ 2026-09-14 20:42 Aleksei Sviridkin
  2026-09-17 11:43 ` netdev-bot+sashiko
  2026-09-17 12:00 ` Maxime Chevallier
  0 siblings, 2 replies; 6+ messages in thread
From: Aleksei Sviridkin @ 2026-09-14 20:42 UTC (permalink / raw)
  To: netdev
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni,
	linux-kernel, Aleksei Sviridkin

phy_remove() clears phydev->drv as its last act; the driver core
clears d->driver only afterwards, in device_unbind_cleanup(). In that
window phy_attach_direct() skips the genphy substitution, because
d->driver is still set, and then dereferences the NULL phydev->drv in
phy_drv_supports_irq().

Refuse the attach there, before any reference on the driver is taken.
The function holds no lock over phydev->drv, and it cannot hold
device_lock across the attach: for a genphy-substituted PHY its error
path reaches device_release_driver() on the same device, which takes
that lock again. So this closes the case where the unbind is already
in flight; an unbind starting mid-attach still races.

Failing beats falling back to polling: phylink_bringup_phy()
dereferences phy->drv right after a successful attach, and a continued
attach would already hold the driver module reference that
phy_detach() drops only while d->driver is set, leaking it once the
unbind completes. -ENODEV is wrong: DSA takes it as permission to
look for the PHY on the switch's internal MDIO bus.

Fixes: 61c81872815f ("net: phy: phy_device: Prevent nullptr exceptions on ISR")
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
---

Notes:
    Found by reading the unbind path, not from a crash report: phy_remove()
    clears phydev->drv before the driver core clears d->driver, while
    phy_attach_direct() keys its genphy substitution off d->driver.
    
    Verified on an MT7981 board (mtk_eth_soc GMAC, "MediaTek MT7981 PHY" at
    mdio-bus:00), 6.18.44, with a 200 ms msleep() added at the end of
    phy_remove() to hold the window open. Two images, identical except for
    this patch.
    
    Without the patch, backgrounding
    
      echo mdio-bus:00 > "/sys/bus/mdio_bus/drivers/MediaTek MT7981 PHY/unbind"
    
    and immediately running "ip link set wan up" oopses on the first
    attempt:
    
      Unable to handle kernel access to user memory outside uaccess
      routines at virtual address 0000000000000128
      pc : phy_attach_direct+0x150/0x380
      Call trace:
       phy_attach_direct+0x150/0x380 (P)
       mtk_open+0x38/0xb70
    
    x0 is 0 and 0x128 is the offset of config_intr in struct phy_driver.
    
    With the patch the same sequence fails the attach on the first attempt
    instead, "wan: mtk_open: could not attach PHY: -16", and no oops is
    logged. Binding the driver back and bringing the interface up afterwards
    succeeds with the link up, so the early return leaves the phydev
    reusable. An ordinary bring-up is unaffected, and with the driver left
    unbound the genphy substitution still runs: "PHY [mdio-bus:00] driver
    [Generic PHY]", link up.

 drivers/net/phy/phy_device.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 94b2e85e00a3..044cefd9840b 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1781,6 +1781,10 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 			d->driver = &genphy_driver.mdiodrv.driver;
 
 		phydev->is_genphy_driven = 1;
+	} else if (!phydev->drv) {
+		/* d->driver outlives phydev->drv on unbind, precedes it on bind */
+		err = -EBUSY;
+		goto error_put_device;
 	}
 
 	if (!try_module_get(d->driver->owner)) {
-- 
2.53.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-17 21:04 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-14 20:42 [PATCH net] net: phy: reject attach while the PHY driver is in transition Aleksei Sviridkin
2026-09-17 11:43 ` netdev-bot+sashiko
2026-09-17 12:00 ` Maxime Chevallier
2026-09-17 18:33   ` Aleksei Sviridkin
2026-09-17 20:30     ` Maxime Chevallier
2026-09-17 21:04       ` Aleksei Sviridkin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®