net: qcom/emac: disable interrupts before calling phy_disconnect
Subsystems (3)
PATCH 1/1 net: qcom/emac: disable interrupts before calling phy_disconnect
There is a race condition that can occur if EMAC interrupts are enabled when phy_disconnect() is called. phy_disconnect() sets adjust_link to NULL. When an interrupt occurs, the ISR might call phy_mac_interrupt(), which wakes up the workqueue function phy_state_machine(). This function might reference adjust_link, thereby causing a null pointer exception.
--- drivers/net/ethernet/qualcomm/emac/emac-mac.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/ethernet/qualcomm/emac/emac-mac.c +6 -2
@@ -1021,14 +1021,18 @@ void emac_mac_down(struct emac_adapter *adpt)napi_disable (&adpt->rx_q.napi);phy_stop (adpt->phydev); -phy_disconnect (adpt->phydev); -/* disable mac irq */ +/* Interrupts must be disabled before the PHY is disconnected, to +* avoid a race condition where adjust_link is null when we get +* an interrupt. +*/ writel (DIS_INT , adpt->base +EMAC_INT_STATUS );writel (0 , adpt->base +EMAC_INT_MASK );synchronize_irq (adpt->irq.irq);free_irq (adpt->irq.irq, &adpt->irq); +phy_disconnect (adpt->phydev); +emac_mac_reset (adpt);emac_tx_q_descs_free (adpt);
Signature · 3 lines
Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project.
From: Timur Tabi <[email protected]>
Date: Fri, 14 Oct 2016 14:14:35 -0500
Quoted 8 lines
There is a race condition that can occur if EMAC interrupts are enabled when
phy_disconnect()is called.phy_disconnect()setsadjust_linkto NULL. When an interrupt occurs, the ISR might callphy_mac_interrupt(), which wakes up the workqueue functionphy_state_machine(). This function might referenceadjust_link, thereby causing a null pointer exception.Signed-off-by Timur Tabi <[email protected]>
Applied.