On Fri, Aug 17, 2012 at 10:46:47AM -0700, Greg KH wrote:
> On Fri, Aug 17, 2012 at 01:38:22PM -0400, Gregs git-bot wrote:
> > commit: 50d0206fcaea3e736f912fd5b00ec6233fb4ce44
> > From: Sarah Sharp <[email protected]>
> > Date: Thu, 26 Jul 2012 12:03:59 -0700
> > Subject: xhci: Fix bug after deq ptr set to link TRB.
> > 
> > This patch fixes a particularly nasty bug that was revealed by the ring
> > expansion patches.  The bug has been present since the very beginning of
> > the xHCI driver history, and could have caused general protection faults
> > from bad memory accesses.
> > 
> > The first thing to note is that a Set TR Dequeue Pointer command can
> > move the dequeue pointer to a link TRB, if the canceled or stalled
> > transfer TD ended just before a link TRB.  The function to increment the
> > dequeue pointer, inc_deq, was written before cancellation and stall
> > support was added.  It assumed that the dequeue pointer could never
> > point to a link TRB.  It would unconditionally increment the dequeue
> > pointer at the start of the function, check if the pointer was now on a
> > link TRB, and move it to the top of the next segment if so.
> > 
> > This means that if a Set TR Dequeue Point command moved the dequeue
> > pointer to a link TRB, a subsequent call to inc_deq() would move the
> > pointer off the segment and into la-la-land.  It would then read from
> > that memory to determine if it was a link TRB.  Other functions would
> > often call inc_deq() until the dequeue pointer matched some other
> > pointer, which means this function would quite happily read all of
> > system memory before wrapping around to the right pointer value.
> > 
> > Often, there would be another endpoint segment from a different ring
> > allocated from the same DMA pool, which would be contiguous to the
> > segment inc_deq just stepped off of.  inc_deq would eventually find the
> > link TRB in that segment, and blindly move the dequeue pointer back to
> > the top of the correct ring segment.
> > 
> > The only reason the original code worked at all is because there was
> > only one ring segment.  With the ring expansion patches, the dequeue
> > pointer would eventually wrap into place, but the dequeue segment would
> > be out-of-sync.  On the second TD after the dequeue pointer was moved to
> > a link TRB, trb_in_td() would fail (because the dequeue pointer and
> > dequeue segment were out-of-sync), and this message would appear:
> > 
> > ERROR Transfer event TRB DMA ptr not part of current TD
> > 
> > This fixes bugzilla entry 4333 (option-based modem unhappy on USB 3.0
> > port: "Transfer event TRB DMA ptr not part of current TD", "rejecting
> > I/O to offline device"),
> > 
> >     https://bugzilla.kernel.org/show_bug.cgi?id=43333
> > 
> > and possibly other general protection fault bugs as well.
> > 
> > This patch should be backported to kernels as old as 2.6.31.  A separate
> > patch will be created for kernels older than 3.4, since inc_deq was
> > modified in 3.4 and this patch will not apply.
> 
> Care to provide that patch now?

Ping?

--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to