From a397076302a850b499d0ef3e8c30239128ce8561 Mon Sep 17 00:00:00 2001 From: Sushil Singh Date: Tue, 7 Feb 2023 16:03:21 +0530 Subject: [PATCH] nvethernet: Add NULL check for phydev in eee init Issue: During eth0 down case, the link change gets called twice, 1. due to ndo close 2. due to interrupt generated by phy. The ether_adjust_link callback also configures the EEE settings and calls phy_init_eee (a phy framework API) for the same. Here a race condition occur, when ether_close sets phydev to NULL before the phy_init_eee gets called (from ether_conf_eee) which tries to deference the phydev causing kernel panic. [35779.541305] Call trace: [35779.544018] phy_init_eee+0x24/0x290 [35779.547455] ether_conf_eee+0x110/0x1310 [nvethernet] [35779.552525] ether_conf_eee+0x4e0/0x1310 [nvethernet] [35779.557840] phy_link_change+0x40/0x90 [35779.561603] phy_state_machine+0x190/0x240 [35779.565643] process_one_work+0x1c4/0x4d0 [35779.569396] worker_thread+0x54/0x430 [35779.573072] kthread+0x148/0x180 [35779.576586] ret_from_fork+0x10/0x34 [35779.580069] Code: a90153f3 d5384113 a9025bf5 12001c36 (f941b801) [35779.586195] ---[ end trace 2ea5b6492f36b0cb ]--- [35779.590737] Kernel panic - not syncing: Oops: Fatal exception Fix: Add a NULL check and return -ENODEVICE in EEE configuration Bug 3877272 Bug 3920560 Bug 3865666 Bug 4088361 Change-Id: I2b26c6eeabb7a109b9d14b3bd2a035f5c3b3c6fa Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2854404 (cherry picked from commit 40606dc247eacf2a8987687777874575d9037058) Signed-off-by: Sushil Kumar Singh Signed-off-by: Revanth Kumar Uppala Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2855237 Tested-by: mobile promotions Reviewed-by: mobile promotions --- drivers/net/ethernet/nvidia/nvethernet/ether_linux.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c b/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c index 799988c0..19ee8c8a 100644 --- a/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c +++ b/drivers/net/ethernet/nvidia/nvethernet/ether_linux.c @@ -751,6 +751,11 @@ int ether_conf_eee(struct ether_priv_data *pdata, unsigned int tx_lpi_enable) unsigned int enable = tx_lpi_enable; struct osi_ioctl ioctl_data = {}; + if (!phydev) { + dev_err(pdata->dev, "%s() phydev is NULL\n", __func__); + return -ENODEV; + } + if (tx_lpi_enable) { /* phy_init_eee() returns 0 if EEE is supported by the PHY */ if (phy_init_eee(phydev,