Message ID | 1476472475-12104-1-git-send-email-timur@codeaurora.org |
---|---|
State | Accepted, archived |
Delegated to: | David Miller |
Headers | show |
From: Timur Tabi <timur@codeaurora.org> Date: Fri, 14 Oct 2016 14:14:35 -0500 > 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. > > Signed-off-by: Timur Tabi <timur@codeaurora.org> Applied.
diff --git a/drivers/net/ethernet/qualcomm/emac/emac-mac.c b/drivers/net/ethernet/qualcomm/emac/emac-mac.c index e97968e..6fb3bee 100644 --- a/drivers/net/ethernet/qualcomm/emac/emac-mac.c +++ b/drivers/net/ethernet/qualcomm/emac/emac-mac.c @@ -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);
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. Signed-off-by: Timur Tabi <timur@codeaurora.org> --- drivers/net/ethernet/qualcomm/emac/emac-mac.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)