public inbox for linux-usb@vger.kernel.org
 help / color / mirror / Atom feed
From: Michal Pecio <michal.pecio@gmail.com>
To: Mathias Nyman <mathias.nyman@intel.com>,
	Greg Kroah-Hartman  <gregkh@linuxfoundation.org>
Cc: Niklas Neronin <niklas.neronin@linux.intel.com>,
	linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 3/5] usb: xhci: Fix isochronous Ring Underrun/Overrun event handling
Date: Mon, 10 Feb 2025 08:40:39 +0100	[thread overview]
Message-ID: <20250210084039.734666bd@foxbook> (raw)
In-Reply-To: <20250210083718.2dd337c3@foxbook>

The TRB pointer of these events points at enqueue at the time of error
occurrence on xHCI 1.1+ HCs or it's NULL on older ones. By the time we
are handling the event, a new TD may be queued at this ring position.

I can trigger this race by rising interrupt moderation to increase IRQ
handling delay. Similar delay may occur naturally due to system load.

If this ever happens after a Missed Service Error, missed TDs will be
skipped and the new TD processed as if it matched the event. It could
be given back prematurely, risking data loss or buffer UAF by the xHC.

Don't complete TDs on xrun events and don't warn if queued TDs don't
match the event's TRB pointer, which can be NULL or a link/no-op TRB.

Now that it's safe, also handle xrun events if the skip flag is clear.
This ensures completion of any TD stuck in 'error mid TD' state right
before the xrun event, which could happen if a driver submits a finite
number of URBs to a buggy HC and then an error occurs on the last TD.

Signed-off-by: Michal Pecio <michal.pecio@gmail.com>
---
 drivers/usb/host/xhci-ring.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 9b06a911a16e..11a53e310826 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2664,6 +2664,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
 	int status = -EINPROGRESS;
 	struct xhci_ep_ctx *ep_ctx;
 	u32 trb_comp_code;
+	bool ring_xrun_event = false;
 
 	slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags));
 	ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1;
@@ -2770,14 +2771,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
 		 * Underrun Event for OUT Isoch endpoint.
 		 */
 		xhci_dbg(xhci, "Underrun event on slot %u ep %u\n", slot_id, ep_index);
-		if (ep->skip)
-			break;
-		return 0;
+		ring_xrun_event = true;
+		break;
 	case COMP_RING_OVERRUN:
 		xhci_dbg(xhci, "Overrun event on slot %u ep %u\n", slot_id, ep_index);
-		if (ep->skip)
-			break;
-		return 0;
+		ring_xrun_event = true;
+		break;
 	case COMP_MISSED_SERVICE_ERROR:
 		/*
 		 * When encounter missed service error, one or more isoc tds
@@ -2894,6 +2893,9 @@ static int handle_tx_event(struct xhci_hcd *xhci,
 	 */
 	} while (ep->skip);
 
+	if (ring_xrun_event)
+		return 0;	/* don't warn or complete any TDs */
+
 	if (!ep_seg) {
 		/*
 		 * Skip the Force Stopped Event. The 'ep_trb' of FSE is not in the current
-- 
2.48.1

  parent reply	other threads:[~2025-02-10  7:40 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-10  7:37 [PATCH 0/5] xHCI: Isochronous error handling fixes and improvements Michal Pecio
2025-02-10  7:38 ` [PATCH 1/5] usb: xhci: Complete 'error mid TD' transfers when handling Missed Service Michal Pecio
2025-02-10  7:39 ` [PATCH 2/5] usb: xhci: Clean up the TD skipping loop Michal Pecio
2025-02-22 12:37   ` Neronin, Niklas
2025-02-24  0:02     ` Michał Pecio
2025-02-10  7:40 ` Michal Pecio [this message]
2025-02-10  7:41 ` [PATCH 4/5] usb: xhci: Expedite skipping missed isoch TDs on modern HCs Michal Pecio
2025-02-10  7:42 ` [PATCH 5/5] usb: xhci: Skip only one TD on Ring Underrun/Overrun Michal Pecio
2025-02-11 15:41   ` Mathias Nyman
2025-02-12  7:30     ` Michał Pecio
2025-02-21  1:17     ` Michał Pecio
2025-02-21  1:18       ` [PATCH v2 3/5] usb: xhci: Fix isochronous Ring Underrun/Overrun event handling Michal Pecio
2025-02-21  1:20       ` [PATCH v2 5/5] usb: xhci: Skip only one TD on Ring Underrun/Overrun Michal Pecio
2025-02-21 13:17       ` [PATCH " Mathias Nyman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250210084039.734666bd@foxbook \
    --to=michal.pecio@gmail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.com \
    --cc=niklas.neronin@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox