• Sarah Sharp's avatar
    USB: xHCI: Fix bug in link TRB activation change. · 6cc30d85
    Sarah Sharp authored
    Commit 6c12db90 introduced a bug for
    control transfers.  The patch was supposed to change when the link TRBs at
    the end of each ring segment were given to the hardware.  If a transfer
    descriptor (TD) ended just before the link TRB, the code wouldn't give
    back the link TRB to the hardware; instead it would be given back in
    prepare_ring() just before the next TD was enqueued at the top of the
    ring.
    
    Unfortunately, the code relied on checking the chain bit of the TRB to
    determine whether the TD ended just before the link TRB.  It assumed that
    the ring enqueuing code would call prepare_ring() before enqueuing the
    next TD.  However, control transfers are made of multiple TDs, and
    prepare_ring() is only called once before enqueuing two or three TDs.
    
    If the first or second TD of the control transfer ended just before the
    link TRB, then the code in inc_enq() would not move the enqueue pointer
    past the link TRB, and the link TRB would get overwritten.  This would
    cause the xHCI driver to start writing to memory past the ring segment,
    and eventually the system would crash or hang.
    
    The fix is to add a flag to inc_enq() that says whether the caller will
    enqueue more TDs before calling prepare_ring().  If the chain bit is
    cleared (meaning this is the last TRB in a TD), and the caller will not
    enqueue more TDs, then we defer giving back the link TRB.
    Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
    Cc: stable <stable@kernel.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
    6cc30d85
xhci-ring.c 80 KB