From: Tiezhu Yang yangtiezhu@loongson.cn
[ Upstream commit 6896c2449a1858acb643014894d01b3a1223d4e5 ]
stmmac_hw_setup() may return 0 on success and an appropriate negative integer as defined in errno.h file on failure, just check it and then return early if failed in stmmac_resume().
Signed-off-by: Tiezhu Yang yangtiezhu@loongson.cn Reviewed-by: Maxime Chevallier maxime.chevallier@bootlin.com Reviewed-by: Huacai Chen chenhuacai@loongson.cn Link: https://patch.msgid.link/20250811073506.27513-2-yangtiezhu@loongson.cn Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES
- What it fixes - The resume path ignores the return value of stmmac_hw_setup(), which is documented to return 0 on success or -errno on failure. See the function signature and comment in drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3396. Inside that function, critical steps like stmmac_init_dma_engine() can fail and return -errno (e.g., invalid DMA configuration, failed reset), see drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3410. - In the current resume path, the return from stmmac_hw_setup() is not checked: drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8033. The code then proceeds to run initialization and enablement sequences (e.g., stmmac_init_coalesce(), stmmac_set_rx_mode(), stmmac_enable_all_queues(), stmmac_enable_all_dma_irq()), which operate on hardware that may not be properly initialized after a failure, risking hangs or crashes. These calls are at drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8034, drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8035, drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8039, and drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:8040, respectively. - The open path already does the right thing by checking the return value and bailing on failure with an error message (drivers/net/ethernet/stmicro/stmmac/stmmac_main.c:3977). The resume path should be consistent with this.
- What the patch changes - It assigns the return value of stmmac_hw_setup() to ret and checks for errors. On error it logs and returns early after correctly releasing the held locks (mutex_unlock and rtnl_unlock). This prevents further use of uninitialized DMA/MAC state and keeps error handling consistent with the open path.
- Scope and risk - Minimal and contained: only the stmmac driver, no API/ABI changes, no feature additions. The change is a straightforward error-path fix and mirrors existing patterns in __stmmac_open(). - Locking is handled correctly: the new early-return path explicitly releases both the private mutex and rtnl lock before returning, avoiding deadlocks. - User impact: prevents resume-time failures from cascading into deeper faults by stopping early and reporting a clear error.
- Context and applicability - Many stmmac glue drivers call stmmac_resume() directly, so this affects a broad set of platforms (e.g., drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c:1183, drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c:2066). - The fix does not depend on newer phylink changes (e.g., phylink_prepare_resume()). While newer mainline code refines phylink sequencing, this error check is orthogonal and safe to apply to stable branches that don’t have those changes. - The stmmac_resume() in current stable series has the same problematic pattern (call stmmac_hw_setup() without checking its return), so the patch is directly relevant.
- Stable rules assessment - Fixes a real bug that can lead to faults after resume. - Small, localized change with minimal regression risk. - No architectural or user-visible feature changes. - Affects only the stmmac driver; well-scoped for backporting.
Conclusion: This is a clear, low-risk bug fix that prevents unsafe continuation after hardware initialization failures during resume. It should be backported to stable kernels.
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 7b16d1207b80c..b9f55e4e360fb 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -7977,7 +7977,14 @@ int stmmac_resume(struct device *dev) stmmac_free_tx_skbufs(priv); stmmac_clear_descriptors(priv, &priv->dma_conf);
- stmmac_hw_setup(ndev, false); + ret = stmmac_hw_setup(ndev, false); + if (ret < 0) { + netdev_err(priv->dev, "%s: Hw setup failed\n", __func__); + mutex_unlock(&priv->lock); + rtnl_unlock(); + return ret; + } + stmmac_init_coalesce(priv); phylink_rx_clk_stop_block(priv->phylink); stmmac_set_rx_mode(ndev);