
From: Mathias Nyman <mathias.nyman@linux.intel.com> stable inclusion from stable-v5.10.164 commit aaaa7cc4aba18dfe46415f4f2c738e861052f99b bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9DNQ5 CVE: CVE-2024-26659 -------------------------------- [ Upstream commit d4dff8043ea5b93a30cb9b19d4407bd506a6877a ] isochronous endpoints do not support streams, meaning that there is only one ring per endpoint. Avoid double-fetching the transfer event DMA to get the ring. Also makes passing the event to skip_isoc_td() uncecessary. Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20210129130044.206855-3-mathias.nyman@linux.intel.... Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Stable-dep-of: a1575120972e ("xhci: Prevent infinite loop in transaction errors recovery for streams") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Li Huafei <lihuafei1@huawei.com> --- drivers/usb/host/xhci-ring.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 0730fb4c7c83..ae45175a3f2f 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2154,7 +2154,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, union xhci_trb *ep_trb, struct xhci_transfer_event *event, struct xhci_virt_ep *ep, int *status) { - struct xhci_ring *ep_ring; struct urb_priv *urb_priv; int idx; struct usb_iso_packet_descriptor *frame; @@ -2163,7 +2162,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, u32 remaining, requested, ep_trb_len; int short_framestatus; - ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer)); trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len)); urb_priv = td->urb->hcpriv; idx = urb_priv->num_tds_done; @@ -2224,7 +2222,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, } if (sum_trbs_for_length) - frame->actual_length = sum_trb_lengths(xhci, ep_ring, ep_trb) + + frame->actual_length = sum_trb_lengths(xhci, ep->ring, ep_trb) + ep_trb_len - remaining; else frame->actual_length = requested; @@ -2235,15 +2233,12 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, } static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, - struct xhci_transfer_event *event, struct xhci_virt_ep *ep, int *status) { - struct xhci_ring *ep_ring; struct urb_priv *urb_priv; struct usb_iso_packet_descriptor *frame; int idx; - ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer)); urb_priv = td->urb->hcpriv; idx = urb_priv->num_tds_done; frame = &td->urb->iso_frame_desc[idx]; @@ -2255,11 +2250,11 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, frame->actual_length = 0; /* Update ring dequeue pointer */ - while (ep_ring->dequeue != td->last_trb) - inc_deq(xhci, ep_ring); - inc_deq(xhci, ep_ring); + while (ep->ring->dequeue != td->last_trb) + inc_deq(xhci, ep->ring); + inc_deq(xhci, ep->ring); - return xhci_td_cleanup(xhci, td, ep_ring, status); + return xhci_td_cleanup(xhci, td, ep->ring, status); } /* @@ -2634,7 +2629,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, return -ESHUTDOWN; } - skip_isoc_td(xhci, td, event, ep, &status); + skip_isoc_td(xhci, td, ep, &status); goto cleanup; } if (trb_comp_code == COMP_SHORT_PACKET) -- 2.25.1