[PATCH 3/5] usb: xhci: reset_ep: fix misaligned pointer in Set TR Dequeue Pointer

Stephano Cetola <[email protected]>
Newsgroups org.infradead.lists.barebox
Message-ID <[email protected]>
reset_ep() computed the Set TR Dequeue Pointer command's address by
ORing the ring's cycle bit into ring->enqueue before passing it to
xhci_trb_virt_to_dma(). That function does pointer arithmetic that
requires a properly aligned TRB pointer. Tainting the low bit first
breaks that arithmetic whenever cycle_state==1, which happens
naturally as the ring wraps, producing a garbage segment offset and
tripping the BUG_ON in xhci_trb_virt_to_dma().

Signed-off-by: Stephano Cetola <[email protected]>
---
 drivers/usb/host/xhci-ring.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 0b11da88a2..522ac7c45f 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -525,8 +525,8 @@ static void reset_ep(struct usb_device *udev, int ep_index)
 	BUG_ON(TRB_TO_SLOT_ID(field) != udev->slot_id);
 	xhci_acknowledge_event(ctrl);
 
-	addr = xhci_trb_virt_to_dma(ring->enq_seg,
-		(void *)((uintptr_t)ring->enqueue | ring->cycle_state));
+	addr = xhci_trb_virt_to_dma(ring->enq_seg, ring->enqueue);
+	addr |= ring->cycle_state;
 	xhci_queue_command(ctrl, addr, udev->slot_id, ep_index, TRB_SET_DEQ);
 	event = xhci_wait_for_event(ctrl, TRB_COMPLETION, XHCI_TIMEOUT_DEFAULT);
 	if (!event)

-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.