diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 5d4508bcfbe9..06c5a8c8cc2a 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -1826,9 +1826,13 @@ static void phy_detach_internal(struct phy_device *phydev, bool notify_bus) struct hwtstamp_provider *hwprov; /* hwprov may technically be protected by ops lock but - * not for devices with a phydev, see phy_link_topo_add_phy() + * not for devices with a phydev, see phy_link_topo_add_phy(). + * Drivers may detach without RTNL while dev is unregistered, + * but then nothing else can reach hwprov. */ - hwprov = rtnl_dereference(dev->hwprov); + hwprov = rcu_dereference_protected(dev->hwprov, + lockdep_rtnl_is_held() || + dev->reg_state != NETREG_REGISTERED); /* Disable timestamp if it is the one selected */ if (hwprov && hwprov->phydev == phydev) { rcu_assign_pointer(dev->hwprov, NULL);