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
