lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20260126104409.1070403-1-wei.fang@nxp.com>
Date: Mon, 26 Jan 2026 18:44:09 +0800
From: Wei Fang <wei.fang@....com>
To: andrew@...n.ch,
	hkallweit1@...il.com,
	linux@...linux.org.uk,
	davem@...emloft.net,
	edumazet@...gle.com,
	kuba@...nel.org,
	pabeni@...hat.com,
	florian.fainelli@...adcom.com,
	xiaolei.wang@...driver.com,
	maxime.chevallier@...tlin.com,
	quic_abchauha@...cinc.com,
	quic_sarohasa@...cinc.com
Cc: imx@...ts.linux.dev,
	netdev@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: [PATCH net] net: phy: add device link between MAC device and MDIO device

For the shared MDIO bus use case, multiple MACs will share the same MDIO
bus. Therefore, these MACs all depend on this MDIO bus, however, current
PHY driver does not create this dependency relationship between the MACs
and the shared MDIO devices. If this shared MDIO bus is removed, it could
potentially cause a crash. For example, the i.MX6ULL platform has two FEC
ports (fec1 and fec2) and uses phylib interfaces to manage the external
PHY. And fec1 uses the MDIO bus shared by fec2. When the fec2 driver is
removed, users can see the following warning log.

$ echo 20b4000.ethernet > /sys/bus/platform/drivers/fec/unbind
WARNING: drivers/net/phy/phy.c:1352 at _phy_state_machine+0xe8/0x38c, CPU#0: kworker/0:6/35
phy_check_link_status+0x0/0xf8: returned: -13
Call trace:
 unwind_backtrace from show_stack+0x10/0x14
 show_stack from dump_stack_lvl+0x54/0x68
 dump_stack_lvl from __warn+0x84/0xf4
 __warn from warn_slowpath_fmt+0x1a8/0x1bc
 warn_slowpath_fmt from _phy_state_machine+0xe8/0x38c
 _phy_state_machine from phy_state_machine+0x20/0x50
 phy_state_machine from process_one_work+0x168/0x2f4

Another example is the i.MX95-15x15 platform which has two ENETC ports
and uses the phylink interfaces to manage the exteranl PHY. All the
external PHYs can be accessed the EMDIO, it is a different device from
ENETC. When the EMDIO driver is removed, users can see the below crash
log and the console is hanged.

$ echo 0002:01:00.0 > /sys/bus/pci/drivers/fsl_enetc_mdio/unbind
$ ifconfig eth0 down
Unable to handle kernel NULL pointer dereference at virtual address 00000000000001b8
pc : _phy_state_machine+0x230/0x36c
lr : _phy_state_machine+0x2b4/0x36c
Call trace:
 _phy_state_machine+0x230/0x36c (P)
 phy_stop+0x74/0x190
 phylink_stop+0x28/0xb8
 enetc_close+0x28/0x8c
 netif_change_flags+0x24/0x6c
 dev_change_flags+0x48/0x7c
 devinet_ioctl+0x328/0x604
 inet_ioctl+0x204/0x220

The commit bc66fa87d4fd ("net: phy: Add link between phy dev and mac
dev") has created a device link between the MAC and the PHY if the MAC
uses a shared MDIO bus (The MDIO and the MAC are two separate devices).
Sarosh Hasan tried to change the DL_FLAG_STATELESS flag to
DL_FLAG_AUTOREMOVE_SUPPLIER to fix the issue [1]. However, the solution
does not take into account the hot-swappable PHY devices (such as SFP).
so when the PHY device is unplugged, the MAC driver will automatically
be removed, which is not the expected behavior.

Therefore, to solve this issue of the shared MDIO bus, we create the
device link between the MAC device and the MDIO device, rather than
between the MAC device and the PHY device. And when the shared MDIO bus
is removed, all MAC drivers that depend on it will also be removed.

Reported-by: Abhishek Chauhan (ABC) <quic_abchauha@...cinc.com>
Closes: https://lore.kernel.org/all/d696a426-40bb-4c1a-b42d-990fb690de5e@quicinc.com/
Link: https://lore.kernel.org/imx/20250703090041.23137-1-quic_sarohasa@quicinc.com/ # [1]
Fixes: bc66fa87d4fd ("net: phy: Add link between phy dev and mac dev")
Signed-off-by: Wei Fang <wei.fang@....com>
---
 drivers/net/phy/phy_device.c | 24 ++++++++++++++----------
 include/linux/phy.h          |  4 ----
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 81984d4ebb7c..d5ac7506fe39 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1768,12 +1768,21 @@ int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
 
 	/**
 	 * If the external phy used by current mac interface is managed by
-	 * another mac interface, so we should create a device link between
-	 * phy dev and mac dev.
+	 * another MDIO controller, which means that the MAC and MDIO are
+	 * separated devices, then we should create a device link between
+	 * the MAC device and the MDIO device.
 	 */
-	if (dev && phydev->mdio.bus->parent && dev->dev.parent != phydev->mdio.bus->parent)
-		phydev->devlink = device_link_add(dev->dev.parent, &phydev->mdio.dev,
-						  DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
+	if (dev && phydev->mdio.bus->parent &&
+	    dev->dev.parent != phydev->mdio.bus->parent) {
+		if (!device_link_add(dev->dev.parent, phydev->mdio.bus->parent,
+				     DL_FLAG_PM_RUNTIME |
+				     DL_FLAG_AUTOREMOVE_SUPPLIER)) {
+			phydev_err(phydev,
+				   "Failed to add devlink between MAC and MDIO\n");
+			err = -EINVAL;
+			goto error;
+		}
+	}
 
 	return err;
 
@@ -1845,11 +1854,6 @@ void phy_detach(struct phy_device *phydev)
 	struct module *ndev_owner = NULL;
 	struct mii_bus *bus;
 
-	if (phydev->devlink) {
-		device_link_del(phydev->devlink);
-		phydev->devlink = NULL;
-	}
-
 	if (phydev->sysfs_links) {
 		if (dev)
 			sysfs_remove_link(&dev->dev.kobj, "phydev");
diff --git a/include/linux/phy.h b/include/linux/phy.h
index fbbe028cc4b7..d6f2039a63d3 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -559,8 +559,6 @@ struct phy_oatc14_sqi_capability {
  *
  * @mdio: MDIO bus this PHY is on
  * @drv: Pointer to the driver for this PHY instance
- * @devlink: Create a link between phy dev and mac dev, if the external phy
- *           used by current mac interface is managed by another mac interface.
  * @phyindex: Unique id across the phy's parent tree of phys to address the PHY
  *	      from userspace, similar to ifindex. A zero index means the PHY
  *	      wasn't assigned an id yet.
@@ -666,8 +664,6 @@ struct phy_device {
 	/* And management functions */
 	const struct phy_driver *drv;
 
-	struct device_link *devlink;
-
 	u32 phyindex;
 	u32 phy_id;
 
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ