• Sekhar Nori's avatar
    net: ethernet: ti: cpsw: fix race condition during open() · 30c57f07
    Sekhar Nori authored
    TI's cpsw driver handles both OF and non-OF case for phy
    connect. Unfortunately of_phy_connect() returns NULL on
    error while phy_connect() returns ERR_PTR().
    
    To handle this, cpsw_slave_open() overrides the return value
    from phy_connect() to make it NULL or error.
    
    This leaves a small window, where cpsw_adjust_link() may be
    invoked for a slave while slave->phy pointer is temporarily
    set to -ENODEV (or some other error) before it is finally set
    to NULL.
    
    _cpsw_adjust_link() only handles the NULL case, and an oops
    results when ERR_PTR() is seen by it.
    
    Note that cpsw_adjust_link() checks PHY status for each
    slave whenever it is invoked. It can so happen that even
    though phy_connect() for a given slave returns error,
    _cpsw_adjust_link() is still called for that slave because
    the link status of another slave changed.
    
    Fix this by using a temporary pointer to store return value
    of {of_}phy_connect() and do a one-time write to slave->phy.
    Reviewed-by: default avatarGrygorii Strashko <grygorii.strashko@ti.com>
    Reported-by: default avatarYan Liu <yan-liu@ti.com>
    Signed-off-by: default avatarSekhar Nori <nsekhar@ti.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    30c57f07
cpsw.c 84.7 KB