• Sarah Sharp's avatar
    xhci: Remove TDs from TD lists when URBs are canceled. · 585df1d9
    Sarah Sharp authored
    When a driver tries to cancel an URB, and the host controller is dying,
    xhci_urb_dequeue will giveback the URB without removing the xhci_tds
    that comprise that URB from the td_list or the cancelled_td_list.  This
    can cause a race condition between the driver calling URB dequeue and
    the stop endpoint command watchdog timer.
    
    If the timer fires on a dying host, and a driver attempts to resubmit
    while the watchdog timer has dropped the xhci->lock to giveback a
    cancelled URB, URBs may be given back by the xhci_urb_dequeue() function.
    At that point, the URB's priv pointer will be freed and set to NULL, but
    the TDs will remain on the td_list.  This will cause an oops in
    xhci_giveback_urb_in_irq() when the watchdog timer attempts to loop
    through the endpoints' td_lists, giving back killed URBs.
    
    Make sure that xhci_urb_dequeue() removes TDs from the TD lists and
    canceled TD lists before it gives back the URB.
    
    This patch should be backported to kernels as old as 2.6.36.
    Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
    Cc: Andiry Xu <andiry.xu@amd.com>
    Cc: stable@kernel.org
    585df1d9
xhci.c 94.5 KB