From patchwork Thu Mar 6 14:49:40 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004622 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 721931624E4 for ; Thu, 6 Mar 2025 14:49:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272568; cv=none; b=amSTEpC7ay2AYOHE2GH0HZIop2oImm6gMPPA5V1+VutXTThw9msurImM2P9QFJU4p3Q2HRRO3v0sGLTdWwRg0x7DwZLPph3McY7Wpkpg4aAGtoQ5u7GFVUQh/Atn/ieIPsSDw8B7U1CakwgMfK4H3b24NE5zj+8lHOI5WBVj16M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272568; c=relaxed/simple; bh=nTD0UkiUHT9LHNQczzrsJVllYHYdZIEvl81sro3tMrA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ooqABDAHDopPd28JYpH18vpZnOLLf3pa3qRV/LXL/EQZUbq8RJAq/9BV/gMvCu0F3TE+lc7I005ZYOQWk7rNPYIEnq4i8R4rD3OXBTu0HtncflwU7Rv7b6k2F0mMa9x/MvSITGnVhYg95aloAB++D9hjd83HII8fZWUN6sBroLw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=K8++kpHr; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="K8++kpHr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272567; x=1772808567; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=nTD0UkiUHT9LHNQczzrsJVllYHYdZIEvl81sro3tMrA=; b=K8++kpHrqhGbWLoeg8+NGSLpkO02KePFolnyMQ+FAQsvkAuZA6XAlkcO mBbVxC+Fluk7C/IZXIBRxlAXCULjmzOKvhkfpxJogSLJCrq7ciTtNOH8A SovmBMlJZZNKMhRBIBSnV9SFTwFahJZCpQLvf7r0QpSAAJCzdjZu68tAg WUepmFcMy3EuSq7fnCW1Rc/wa7CXV+pY4yfVqEJ6ExhD9yqpXwsdfQ2I1 1lBsDUhueJKOiV1cae/C2SVKGRBh3tM70+1Yue7DbFzTLO+eb8D+RsW5Y foIShXw6WYppS0tIedbjkMhDMXceZ/l6/wsY0y23X4uWlQFt6tczXHTfS Q==; X-CSE-ConnectionGUID: gRl4PpyHRGWkMD3lzd30sA== X-CSE-MsgGUID: mCaSwMJCTJKSpCrENRxy+w== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657064" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657064" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:26 -0800 X-CSE-ConnectionGUID: HCCSyVmlQIqc4c/c72PaCQ== X-CSE-MsgGUID: 0GhSinJPSEyAK2MeF0jkfw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954786" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:25 -0800 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 01/15] xhci: show correct U1 and U2 timeout values in debug messages Date: Thu, 6 Mar 2025 16:49:40 +0200 Message-ID: <20250306144954.3507700-2-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 U2 value is encoded in 256 microsecond intervals, show in microseconds. U1 value is in microseconds. debug message incorrectly showed "ms" Unwrap debug messages while we anyway modify them. Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 45653114ccd7..3f2cd546a7a2 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4755,8 +4755,8 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci, */ if (timeout_ns <= USB3_LPM_U1_MAX_TIMEOUT) return timeout_ns; - dev_dbg(&udev->dev, "Hub-initiated U1 disabled " - "due to long timeout %llu ms\n", timeout_ns); + dev_dbg(&udev->dev, "Hub-initiated U1 disabled due to long timeout %lluus\n", + timeout_ns); return xhci_get_timeout_no_hub_lpm(udev, USB3_LPM_U1); } @@ -4813,8 +4813,8 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci, */ if (timeout_ns <= USB3_LPM_U2_MAX_TIMEOUT) return timeout_ns; - dev_dbg(&udev->dev, "Hub-initiated U2 disabled " - "due to long timeout %llu ms\n", timeout_ns); + dev_dbg(&udev->dev, "Hub-initiated U2 disabled due to long timeout %lluus\n", + timeout_ns * 256); return xhci_get_timeout_no_hub_lpm(udev, USB3_LPM_U2); } From patchwork Thu Mar 6 14:49:41 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004623 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F6E716DEB3 for ; Thu, 6 Mar 2025 14:49:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272570; cv=none; b=uPXrdw6fKzyZWDHTo6gG8yM0ucOb+5uh88ishUSjrjtMn1S3DBUuWUWUmGBEjlataSUvKU7/V9aBGcvj5fOjjVOED54VQXS4g+AxVHco75fRbzRUreev2DGP/7aNlCn8BEoUgWizobx0IqMXm7G5CkbpKU2gTcrf7f0OJCkdSD0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272570; c=relaxed/simple; bh=ZhQp1SbanU9lG/QyxFdzp5uy0GZaoqivD0iflGquVMo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VcXJHcF9AGz088KD8LL12r/9tWWbSKBX3exNGggxX3Xs/c7bd5Vy8xlCsI9GYForyGVJsyoef7KG2uXU3HY71p4XKVOtNll0ViXTWOVDcYeHLFuXWx44hdi0XghUwKV5d8b6YKTSbCJDcaITs2X4buTGxSXCaoIWBW3GmsWfack= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=PoaEf+L+; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="PoaEf+L+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272569; x=1772808569; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZhQp1SbanU9lG/QyxFdzp5uy0GZaoqivD0iflGquVMo=; b=PoaEf+L+v2wzqoKpvSY6x//cEC/LC576e14aWNmYrxqVo41v/jvfsEYz i1/91ArctiaWtJ2AEWcT0UeeS8YaqgBh83/KoZr0iWJkHQGvTBEvOnCCZ pdcyx2vvJdMUogwj2xmktR8HEE/pdMs/uRFq+QKUllMrk+q9unodRcuL0 xtk2ElqwMDpzsurk8TuyqIfFKExGmvuShq6cI3bRoCJ+h9LRt9lg0HBwe O1LdRVnV1hGoXmzMgkpjh0Cx+T1hJX72i9Zmq/J6MBlMyA543+wxL1l9E jbuuWwCpUEKTjTMOCaHCJ+fKvd7i6pRf06BJVfpt9/wvA/8pcAO6/ENdl w==; X-CSE-ConnectionGUID: BuQ3aAXGTQqfTmGNklt8sg== X-CSE-MsgGUID: VEcd934qRWeOc3E0rarP+g== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657069" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657069" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:28 -0800 X-CSE-ConnectionGUID: Ry/zP7HuRVOA2UCA4WxyGA== X-CSE-MsgGUID: Rb3TI7z7QTa3LgUorfcgtA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954790" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:26 -0800 From: Mathias Nyman To: Cc: , Niklas Neronin , Mathias Nyman Subject: [PATCH 02/15] usb: xhci: remove redundant update_ring_for_set_deq_completion() function Date: Thu, 6 Mar 2025 16:49:41 +0200 Message-ID: <20250306144954.3507700-3-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Niklas Neronin The function is a remnant from a previous implementation and is now redundant. There is no longer a need to search for the dequeue pointer, as both the TRB and segment dequeue pointers are saved within 'queued_deq_seg' and 'queued_deq_ptr'. Signed-off-by: Niklas Neronin Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 41 ++---------------------------------- 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 965bffce301e..23cf20026359 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1332,43 +1332,6 @@ void xhci_hc_died(struct xhci_hcd *xhci) usb_hc_died(xhci_to_hcd(xhci)); } -static void update_ring_for_set_deq_completion(struct xhci_hcd *xhci, - struct xhci_virt_device *dev, - struct xhci_ring *ep_ring, - unsigned int ep_index) -{ - union xhci_trb *dequeue_temp; - - dequeue_temp = ep_ring->dequeue; - - /* If we get two back-to-back stalls, and the first stalled transfer - * ends just before a link TRB, the dequeue pointer will be left on - * the link TRB by the code in the while loop. So we have to update - * the dequeue pointer one segment further, or we'll jump off - * the segment into la-la-land. - */ - if (trb_is_link(ep_ring->dequeue)) { - ep_ring->deq_seg = ep_ring->deq_seg->next; - ep_ring->dequeue = ep_ring->deq_seg->trbs; - } - - while (ep_ring->dequeue != dev->eps[ep_index].queued_deq_ptr) { - /* We have more usable TRBs */ - ep_ring->dequeue++; - if (trb_is_link(ep_ring->dequeue)) { - if (ep_ring->dequeue == - dev->eps[ep_index].queued_deq_ptr) - break; - ep_ring->deq_seg = ep_ring->deq_seg->next; - ep_ring->dequeue = ep_ring->deq_seg->trbs; - } - if (ep_ring->dequeue == dequeue_temp) { - xhci_dbg(xhci, "Unable to find new dequeue pointer\n"); - break; - } - } -} - /* * When we get a completion for a Set Transfer Ring Dequeue Pointer command, * we need to clear the set deq pending flag in the endpoint ring state, so that @@ -1473,8 +1436,8 @@ static void xhci_handle_cmd_set_deq(struct xhci_hcd *xhci, int slot_id, /* Update the ring's dequeue segment and dequeue pointer * to reflect the new position. */ - update_ring_for_set_deq_completion(xhci, ep->vdev, - ep_ring, ep_index); + ep_ring->deq_seg = ep->queued_deq_seg; + ep_ring->dequeue = ep->queued_deq_ptr; } else { xhci_warn(xhci, "Mismatch between completed Set TR Deq Ptr command & xHCI internal state.\n"); xhci_warn(xhci, "ep deq seg = %p, deq ptr = %p\n", From patchwork Thu Mar 6 14:49:42 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004624 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8BB2E1624E4; Thu, 6 Mar 2025 14:49:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272572; cv=none; b=XfETX6MchFMxahy0kg3E5y+yWInC71Ik3Bbgwx5d1yjfI1KatcrFbaglJcIHM7H6QHCaB5HauKeiIOkgfCLtkyRJ588HdBeCkSk89saw2b7rrkGmqfSyiCKhlgmoW9TtiTYERzgTn1M6UFz/9Awqn/H7lcNtwJGK+pymu3sDQgA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272572; c=relaxed/simple; bh=0wx40jwKMq+iAK7skI5rEnHpc5MqM8TEkEtfZVhrA5c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nW8t7XOzcggWK08jiWq1bX5fa2sYQ+xpp78PCS+9N11XFCcVb/Q7mpDPosyQBszaUBMjONGY7lG4hGG3ufbrsDhjTbK1yNPC9U/N1R4v2E0+K5pd16maAEMbreFEjTYuP/G+ZnNJiteXvO1QPKpsv96naUPDPDB2m7/0YFCGD3w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=V8hWWQ4U; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="V8hWWQ4U" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272570; x=1772808570; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=0wx40jwKMq+iAK7skI5rEnHpc5MqM8TEkEtfZVhrA5c=; b=V8hWWQ4UoDPVHRZTOMvdS3ePGV9xEFbyP/3qfHpfFh6fb/Id9d93QibL NnVGRRXnVQ6iuKFxzz+6AFEVfsbCh1vr8GdyNQ7hkAqVmWzuuPogDwNvH HAASoyN6HT+leH+bSDBRgqALttTI5wMsxcTtMBcGjD5ulXTN/P2fmUPUw ur7tk2gscJuSydO2RoUEsXWCptChwIIsvn2j4Y3L1HTY0bHGGuKLq4dB2 ugErS7lYaw+AGrx4h9lBuAisQec3pzLTaviOOLEMY424skCO///FoRrkN RXiy+jCADK1bTVwyxQqePpSAY9au7ZAuSg0dALbmTZVoNzp5gYNCtjiUd g==; X-CSE-ConnectionGUID: KMyG8DVMQ+aTkylnlwq0ww== X-CSE-MsgGUID: lMFPJ4GaSI20nQO2CFFHAQ== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657071" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657071" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:30 -0800 X-CSE-ConnectionGUID: Nb3DCXLqQGCZVMRtDywrlg== X-CSE-MsgGUID: aYX/4QglSCirClTr6iWrHg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954795" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:28 -0800 From: Mathias Nyman To: Cc: , Michal Pecio , stable@vger.kernel.org, Mathias Nyman Subject: [PATCH 03/15] usb: xhci: Don't skip on Stopped - Length Invalid Date: Thu, 6 Mar 2025 16:49:42 +0200 Message-ID: <20250306144954.3507700-4-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Michal Pecio Up until commit d56b0b2ab142 ("usb: xhci: ensure skipped isoc TDs are returned when isoc ring is stopped") in v6.11, the driver didn't skip missed isochronous TDs when handling Stoppend and Stopped - Length Invalid events. Instead, it erroneously cleared the skip flag, which would cause the ring to get stuck, as future events won't match the missed TD which is never removed from the queue until it's cancelled. This buggy logic seems to have been in place substantially unchanged since the 3.x series over 10 years ago, which probably speaks first and foremost about relative rarity of this case in normal usage, but by the spec I see no reason why it shouldn't be possible. After d56b0b2ab142, TDs are immediately skipped when handling those Stopped events. This poses a potential problem in case of Stopped - Length Invalid, which occurs either on completed TDs (likely already given back) or Link and No-Op TRBs. Such event won't be recognized as matching any TD (unless it's the rare Link TRB inside a TD) and will result in skipping all pending TDs, giving them back possibly before they are done, risking isoc data loss and maybe UAF by HW. As a compromise, don't skip and don't clear the skip flag on this kind of event. Then the next event will skip missed TDs. A downside of not handling Stopped - Length Invalid on a Link inside a TD is that if the TD is cancelled, its actual length will not be updated to account for TRBs (silently) completed before the TD was stopped. I had no luck producing this sequence of completion events so there is no compelling demonstration of any resulting disaster. It may be a very rare, obscure condition. The sole motivation for this patch is that if such unlikely event does occur, I'd rather risk reporting a cancelled partially done isoc frame as empty than gamble with UAF. This will be fixed more properly by looking at Stopped event's TRB pointer when making skipping decisions, but such rework is unlikely to be backported to v6.12, which will stay around for a few years. Fixes: d56b0b2ab142 ("usb: xhci: ensure skipped isoc TDs are returned when isoc ring is stopped") Cc: stable@vger.kernel.org Signed-off-by: Michal Pecio Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 23cf20026359..6fb48d30ec21 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2828,6 +2828,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, if (!ep_seg) { if (ep->skip && usb_endpoint_xfer_isoc(&td->urb->ep->desc)) { + /* this event is unlikely to match any TD, don't skip them all */ + if (trb_comp_code == COMP_STOPPED_LENGTH_INVALID) + return 0; + skip_isoc_td(xhci, td, ep, status); if (!list_empty(&ep_ring->td_list)) continue; From patchwork Thu Mar 6 14:49:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004625 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3600E176ADB for ; Thu, 6 Mar 2025 14:49:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272573; cv=none; b=k4fxBauHDPUSddcCMAAY/MQ7WweSf3tnnlDHspg0habe7/z5Hvjcc2cCI0mMZY9uRyL3s8R4PHqgGEka0Dg35cLggIKTSVdC7G/wwCMXtpbFJqyc6MtYFHZytN3gP2Rpc5+KO2BD/uIh5ezsUnQPRtGyA41u0tpkvMtWbXtnNnw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272573; c=relaxed/simple; bh=oVmjP8w0JU6XCm+Dk/U7ONYI2FWa0ax1oTFED//DoSM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UmtoG58pV+n46b25lXqk8h72H/2QeDi1bgm5cqUESwSWLR6hkFnVEEN09RFI45kh/AGkoWFsEzKuuRW3TQbIh0zjs5Dw9GwzE1q1CKKBdP7AoJ+rv3qqNC0XaGj4TvAhIGmcoQhZCELn2fhhSLOWNzTVq7oyYRlSdcCXKHOD6IY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=SmGxu9gF; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="SmGxu9gF" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272572; x=1772808572; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oVmjP8w0JU6XCm+Dk/U7ONYI2FWa0ax1oTFED//DoSM=; b=SmGxu9gF3gkTBjoyEx6flcXZ4WLknFoH+U/nONhNC5wz3nLIkOWPBSNy D107XO1TtbCk4BiRnkvyDu4mpiD/JuPWmQy9M0tU0VrX/IZmeG2wBmLTn KccqjRHu9gBleRYZ+/9DbTdTKAMWywXviay7hF+ugcccZlAPlMbGsgyMN N0PW2/VCnlXeCs5sJibkjO26ltI/oh11TRi+O1LA6TW/p3Y5Y0/gx4yH3 DtIJJs07BKOQMS4j762RpcLSSSL/Gz7CAb47FXa16opnFOtbDRlJEk4n5 xBWt41c8EFhw41z8luI7UMZcz/77UZIdgT4VBhblqGtl3K8o+jTOjF5aA Q==; X-CSE-ConnectionGUID: UMiRtNrkQGmLbVPJgbtedQ== X-CSE-MsgGUID: Y7VI7IOTSWyxUIiCTScJ1A== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657074" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657074" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:32 -0800 X-CSE-ConnectionGUID: s3ox1EpIQ2y4cDFXWH1rrw== X-CSE-MsgGUID: O/eMaZ7eQ6SPA0w0mMBPgg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954798" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:30 -0800 From: Mathias Nyman To: Cc: , Michal Pecio , Mathias Nyman Subject: [PATCH 04/15] usb: xhci: Complete 'error mid TD' transfers when handling Missed Service Date: Thu, 6 Mar 2025 16:49:43 +0200 Message-ID: <20250306144954.3507700-5-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Michal Pecio Missed Service Error after an error mid TD means that the failed TD has already been passed by the xHC without acknowledgment of the final TRB, a known hardware bug. So don't wait any more and give back the TD. Reproduced on NEC uPD720200 under conditions of ludicrously bad USB link quality, confirmed to behave as expected using dynamic debug. Signed-off-by: Michal Pecio Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6fb48d30ec21..47aaaf4eb92a 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2752,7 +2752,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, xhci_dbg(xhci, "Miss service interval error for slot %u ep %u, set skip flag\n", slot_id, ep_index); - return 0; + break; case COMP_NO_PING_RESPONSE_ERROR: ep->skip = true; xhci_dbg(xhci, @@ -2800,6 +2800,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, xhci_dequeue_td(xhci, td, ep_ring, td->status); } + /* Missed TDs will be skipped on the next event */ + if (trb_comp_code == COMP_MISSED_SERVICE_ERROR) + return 0; + if (list_empty(&ep_ring->td_list)) { /* * Don't print wanings if ring is empty due to a stopped endpoint generating an From patchwork Thu Mar 6 14:49:44 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004626 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4BBA71898E9 for ; Thu, 6 Mar 2025 14:49:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272576; cv=none; b=RFSMBtRKmP6qmlhyjxIE0x3YkTQWBQ5a5GK7Q5EgG00SUGKwnRtI2RfJzCmLBbBJccjnwFY/b/xfUi7XZz8BrnlReFqIyhY05uesMf9B1/2M/GvabjbC5+NhrlZezgF+cZD1U5iNiMFlMY4L3pAAoUslgg5Pw7611nOwrPlenuc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272576; c=relaxed/simple; bh=WTo7iAd8v0TqG8xP1gXPK0X4oX25knAvutngm3Td86U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qFpm2/eaPJDCMUl7JxkeYVtDoB8thPLxbJci9as5BZeZBw1eBFPFoa3yhFml06rbFFmw5JTsrF8l3ytUvdf1rA3mVaQogpJO/FlfzOF0S5Oggf24mMbY4Cfjw7pLvBAbVElVU1mEVxDP4KT3JYF02Yf4xeqwwktIpSrYraRKY0k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=aD3+8YjC; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="aD3+8YjC" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272574; x=1772808574; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=WTo7iAd8v0TqG8xP1gXPK0X4oX25knAvutngm3Td86U=; b=aD3+8YjCLnSjsfcWpEY9RaFNykby7/ELcQMb35BR4SNiuU+wO17jAzu6 kn/rVpYPJ0Ew6CpLIpOpf668zGXT6Uh5WOKP2Ld5KmmyXMsf56v4WhbbS Cb2N7rEwVYRJB4QvSlhhVLmIBxo1mXe4ffWja3QTrBjxDwPJ3A5NoTsPX 6ETBXhq/JdKL5p0FUrgaU3rXtZvq2KCSlpGJsvQH/p41Gcd3yK7aAfv0N teDZO+ly9wFYYaj56l9ZG2Fb/I2vPVXbRooerpknwzFmMCoDYUxaDOQ/7 2ac8YNDM+XpHlH1CyoGNBH8ZJ1CMFTo957moHp8R7F5cch6J3yr1fCn5L g==; X-CSE-ConnectionGUID: 2J5sQDs7TRy9ax5e3Ef+og== X-CSE-MsgGUID: zF3kU8LYQ82yyhL+3Mtcqg== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657078" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657078" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:33 -0800 X-CSE-ConnectionGUID: 7Vp5hkr6R1GKxFThI1a8aQ== X-CSE-MsgGUID: oqcmsH5CTDKZsExylPm+pw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954803" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:32 -0800 From: Mathias Nyman To: Cc: , Michal Pecio , Mathias Nyman Subject: [PATCH 05/15] usb: xhci: Fix isochronous Ring Underrun/Overrun event handling Date: Thu, 6 Mar 2025 16:49:44 +0200 Message-ID: <20250306144954.3507700-6-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Michal Pecio 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. Don't warn if there are no queued TDs at all. 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 Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 47aaaf4eb92a..d34f46b63006 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2627,6 +2627,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; @@ -2733,14 +2734,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 @@ -2813,6 +2812,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, */ if (trb_comp_code != COMP_STOPPED && trb_comp_code != COMP_STOPPED_LENGTH_INVALID && + !ring_xrun_event && !ep_ring->last_td_was_short) { xhci_warn(xhci, "Event TRB for slot %u ep %u with no TDs queued\n", slot_id, ep_index); @@ -2847,6 +2847,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, goto check_endpoint_halted; } + /* TD was queued after xrun, maybe xrun was on a link, don't panic yet */ + if (ring_xrun_event) + return 0; + /* * Skip the Force Stopped Event. The 'ep_trb' of FSE is not in the current * TD pointed by 'ep_ring->dequeue' because that the hardware dequeue @@ -2893,6 +2897,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, */ } while (ep->skip); + /* Get out if a TD was queued at enqueue after the xrun occurred */ + if (ring_xrun_event) + return 0; + if (trb_comp_code == COMP_SHORT_PACKET) ep_ring->last_td_was_short = true; else From patchwork Thu Mar 6 14:49:45 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004627 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3EE55176ADB for ; Thu, 6 Mar 2025 14:49:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272577; cv=none; b=Z3+2nj9CI+AQq0KvQ3BQprI0KKI5iwrmzi9r7SUgqXtrfdLnd58E/q4K94a6rkpD5HN6DG/lEtY7IJvJctef9B7nIctdA1t6TZkVcrLiQYsxyg44rnukjIqbexJgfyXgVBbcxjW0WPCSKFOeP5KhTA2hKwPz/Pr7Tf/b7y8G/V0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272577; c=relaxed/simple; bh=zVRu0Dcyn4GnoVhJbWKp0to9ukP5+nTq0yFqha6kKpE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PpT4DtwJEHAj+tS6INu27H9wUz2fp/Vupx3HdEqy/WjhmhaBwkE3Ui5zGDf/vj7joZgEcpTnDn+HyHwdmSm35P6pYxhZqjGlqqCsTP7P8oB/1lyaIpyCOwOC1+R05qxjBjXOkp/30ow3C016QZkx4cLCP8O9HkQlFSpEEtHiQWg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=J2WuY0pL; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="J2WuY0pL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272576; x=1772808576; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zVRu0Dcyn4GnoVhJbWKp0to9ukP5+nTq0yFqha6kKpE=; b=J2WuY0pL03EiHHR9G2Ay7ITut3tdtNr81NjCqZQ50Bs6DF2W1yXj/hKZ j8BIzwqBrgZpHzTEyXsIJnzf65q3eK2E0yaA5oHXo9qGcONdGO0nQDPMI FIanXLDc/kePjKTEocvY5Twka5JkxIa21S0he4yTgHorhHJELtR1r8/WE T6n3XVGh4uS0e/h6u1YZR6M/vBNZvZ51eZZV9muWp8hl3Y0Nrc9GErjuS enlgnml6MSdIDqUiMAZgXNTmpjXxPZ+3LXZuboqtX7dh81TatIDvQs9O0 s+NXB69hkXJpfFMIC/ohEQvDVM4z7NOMPSaYCVJ+JRriPoiP9kaAvQQAY Q==; X-CSE-ConnectionGUID: f/KKg8RXRPGGUmWrFYTodg== X-CSE-MsgGUID: y1C31HJSS+KPRZXEv13aeQ== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657087" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657087" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:35 -0800 X-CSE-ConnectionGUID: GBIn5CQsT2CmRSnY2emjHw== X-CSE-MsgGUID: Jee0kzDeTJmAVbUv2V7N3A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954806" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:33 -0800 From: Mathias Nyman To: Cc: , Michal Pecio , Mathias Nyman Subject: [PATCH 06/15] usb: xhci: Expedite skipping missed isoch TDs on modern HCs Date: Thu, 6 Mar 2025 16:49:45 +0200 Message-ID: <20250306144954.3507700-7-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Michal Pecio xHCI spec rev. 1.0 allowed the TRB pointer of Missed Service events to be NULL. Having no idea which of the queued TDs were missed and which are waiting, we can only set a flag to skip missed TDs later. But HCs are also allowed to give us pointer to the last missed TRB, and this became mandatory in spec rev. 1.1 and later. Use this pointer, if available, to immediately skip all missed TDs. This reduces latency and risk of skipping-related bugs, because we can now leave the skip flag cleared for future events. Handle Missed Service Error events as 'error mid TD', if applicable, because rev. 1.0 spec excplicitly says so in notes to 4.10.3.2 and later revs in 4.10.3.2 and 4.11.2.5.2. Notes to 4.9.1 seem to apply. Tested on ASM1142 and ASM3142 v1.1 xHCs which provide TRB pointers. Tested on AMD, Etron, Renesas v1.0 xHCs which provide TRB pointers. Tested on NEC v0.96 and VIA v1.0 xHCs which send a NULL pointer. Change inspired by a discussion about realtime USB audio. Link: https://lore.kernel.org/linux-usb/76e1a191-020d-4a76-97f6-237f9bd0ede0@gmx.net/T/ Signed-off-by: Michal Pecio Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index d34f46b63006..e871dd61a636 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2439,6 +2439,12 @@ static void process_isoc_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, if (ep_trb != td->end_trb) td->error_mid_td = true; break; + case COMP_MISSED_SERVICE_ERROR: + frame->status = -EXDEV; + sum_trbs_for_length = true; + if (ep_trb != td->end_trb) + td->error_mid_td = true; + break; case COMP_INCOMPATIBLE_DEVICE_ERROR: case COMP_STALL_ERROR: frame->status = -EPROTO; @@ -2749,8 +2755,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, */ ep->skip = true; xhci_dbg(xhci, - "Miss service interval error for slot %u ep %u, set skip flag\n", - slot_id, ep_index); + "Miss service interval error for slot %u ep %u, set skip flag%s\n", + slot_id, ep_index, ep_trb_dma ? ", skip now" : ""); break; case COMP_NO_PING_RESPONSE_ERROR: ep->skip = true; @@ -2799,8 +2805,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, xhci_dequeue_td(xhci, td, ep_ring, td->status); } - /* Missed TDs will be skipped on the next event */ - if (trb_comp_code == COMP_MISSED_SERVICE_ERROR) + /* If the TRB pointer is NULL, missed TDs will be skipped on the next event */ + if (trb_comp_code == COMP_MISSED_SERVICE_ERROR && !ep_trb_dma) return 0; if (list_empty(&ep_ring->td_list)) { From patchwork Thu Mar 6 14:49:46 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004628 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6ACE918A6A8 for ; Thu, 6 Mar 2025 14:49:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272578; cv=none; b=dI114uRD800hoF8Jzlu3Bmt+Tjvo/mrhuvCnbU8jrAJn0ApbHScldFS7q+XFODFOVeZhVEPKAO/pRgiAaOXca+7UCvoIjjVhEF8CDBfE9hINkDOadsCxswqjGa2dJ0DKQuJROrMtkqF/kimEGGuhy76Qc0qFDiFCeGCypOSVZv8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272578; c=relaxed/simple; bh=yJRzzo5/COsmxeegx4DFYRPoycqUAjf4h3FW7G+oWYA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BEXGHBGmkka9EL+IJuWroB6x4Z2sxBE31KlqQ+oJ+nbqPxqMK70isgRHilMKOvJoDAH4xP9YCfVjmv6Fdlbl6RZx1ZBpX+HPa7h5w7XIqRp41m6U0DcnD0+YJuCX3yQwUPVecARPyBbWW5QeIH1ymHsW9nyrpbpVOcmDDu6pRf0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=BIVBXftL; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="BIVBXftL" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272577; x=1772808577; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=yJRzzo5/COsmxeegx4DFYRPoycqUAjf4h3FW7G+oWYA=; b=BIVBXftLN/g1PqGi/n0WZ9y+kk2w+rc8TtYaFobTqs4jkU82KpCO+NqX gbYsBbUUTifsECoeCXwgsKxvJKlhNi9BXI0nUY6rgua+k6PxFTu8VPjS+ F+k5/qswGQ+4Zt9HyUFWXf8mfszE7coQ1WmbsbkVTJ4YWQmo0wN+x4cR5 /JS+S/Af0zIPuEMIYMpicsWZYkOG+qb+uOcD28eYXOj1fTUbZNSrYtLBN cQu9+FdgH4Hybuii6Xbnm0zWn5s3CiltShZ+8By8GihZrgrzyEQ7D+4xx CuKstwx5kgphlqG0AY1wVKNAK+ot0UO8n+Py/ep3kQwQPUvZuwYVtd+PE g==; X-CSE-ConnectionGUID: tZyz8qRoQ8qGh0Xw5nrjTw== X-CSE-MsgGUID: F4BotkQzRg+VKyDDBvE/zA== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657092" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657092" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:37 -0800 X-CSE-ConnectionGUID: OeKUdtGARsaHTtR6qdpW9g== X-CSE-MsgGUID: PnmDb1mhSwaopPvpfn4buQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954825" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:35 -0800 From: Mathias Nyman To: Cc: , Michal Pecio , Mathias Nyman Subject: [PATCH 07/15] usb: xhci: Skip only one TD on Ring Underrun/Overrun Date: Thu, 6 Mar 2025 16:49:46 +0200 Message-ID: <20250306144954.3507700-8-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Michal Pecio If skipping is deferred to events other than Missed Service Error itsef, it means we are running on an xHCI 1.0 host and don't know how many TDs were missed until we reach some ordinary transfer completion event. And in case of ring xrun, we can't know where the xrun happened either. If we skip all pending TDs, we may prematurely give back TDs added after the xrun had occurred, risking data loss or buffer UAF by the xHC. If we skip none, a driver may become confused and stop working when all its URBs are missed and appear to be "in flight" forever. Skip exactly one TD on each xrun event - the first one that was missed, as we can now be sure that the HC has finished processing it. Provided that one more TD is queued before any subsequent doorbell ring, it will become safe to skip another TD by the time we get an xrun again. Signed-off-by: Michal Pecio Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index e871dd61a636..70b896297494 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2843,8 +2843,21 @@ static int handle_tx_event(struct xhci_hcd *xhci, return 0; skip_isoc_td(xhci, td, ep, status); - if (!list_empty(&ep_ring->td_list)) + + if (!list_empty(&ep_ring->td_list)) { + if (ring_xrun_event) { + /* + * If we are here, we are on xHCI 1.0 host with no + * idea how many TDs were missed or where the xrun + * occurred. New TDs may have been added after the + * xrun, so skip only one TD to be safe. + */ + xhci_dbg(xhci, "Skipped one TD for slot %u ep %u", + slot_id, ep_index); + return 0; + } continue; + } xhci_dbg(xhci, "All TDs skipped for slot %u ep %u. Clear skip flag.\n", slot_id, ep_index); From patchwork Thu Mar 6 14:49:47 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004629 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 80E46189520 for ; Thu, 6 Mar 2025 14:49:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272580; cv=none; b=PlVHgzJyVwuqBpOqH5XQy1W+QflQe6WI9S/dTGYaDbQC/nOmTFKoBQE2MhVRObeqLmbr6xmWcEuIt+u7I5y5riMBXkpxPmTlZvG/mUyXvrO5mytrH/X4Rs7+RYxrhZWkMRteZBtRHbwRWdHn0McLg+5ZnhQl1IijF4VSNDfUIjc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272580; c=relaxed/simple; bh=WlPYjLgbpW13RkXfUCvYmGhjGRIj2KD2O+2YVWR1p3k=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jOpw/chaUfSmI/JL8SCzb4cYAfsftD0a+0OVv3wQLSjoaLiaFxBvmAWhpVRUyXFvLDd/0BdsaS1FfHlIGLfACTbxXG1RGrI0LdQy9eOTFFCJcPU+Of8MYHkidUBcY8/ldiTpzlq3QnNm9sbeKsVwDuKbjnQT97TCRmcVhZb7JXc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=ePTjGjr+; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="ePTjGjr+" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272579; x=1772808579; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=WlPYjLgbpW13RkXfUCvYmGhjGRIj2KD2O+2YVWR1p3k=; b=ePTjGjr+etrsGL+sr28n+tpjBzqh2DAyAkjAdTrtm19tedkGN5Zhj92N +EDwY7reDbc64yD9osRhFTXFENHpsfU0dSJz4zet1L7abLKClGJ5raaiF wBpwZ8pAw+mP3idsxJVCgL91g7BMfV0uLqRdXpX7BcM/q80ufV0/NLeeo 0Bqqrdmld/FOrrqLoT9AX69PgURxb68yVHHQlcKt/TJLGJvIyCJdlXcQy gm24wjxXhlxJG/eT+hA4UOpZ6hDZVi9ANtW1+KTJ3OO64oybaEPjfueHo TWf9PPW/h5zvTOF4McjPu4T56R7MmoMwBNO6iH0WfyzWc0ktTOBj8j9Vw w==; X-CSE-ConnectionGUID: u4gMUdjvSE+sqTPTWwbxxg== X-CSE-MsgGUID: iaC7cTXPTFqxsMa/OMQi3g== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657101" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657101" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:38 -0800 X-CSE-ConnectionGUID: ymb58kyqQ2aeHZnRG4mxBQ== X-CSE-MsgGUID: 4QwmtPDQRr2kSRa4R/S3CQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954831" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:37 -0800 From: Mathias Nyman To: Cc: , Niklas Neronin , Mathias Nyman Subject: [PATCH 08/15] usb: xhci: correct debug message page size calculation Date: Thu, 6 Mar 2025 16:49:47 +0200 Message-ID: <20250306144954.3507700-9-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Niklas Neronin The ffs() function returns the index of the first set bit, starting from 1. If no bits are set, it returns zero. This behavior causes an off-by-one page size in the debug message, as the page size calculation [1] is zero-based, while ffs() is one-based. Fix this by subtracting one from the result of ffs(). Note that since variable 'val' is unsigned, subtracting one from zero will result in the maximum unsigned integer value. Consequently, the condition 'if (val < 16)' will still function correctly. [1], Page size: (2^(n+12)), where 'n' is the set page size bit. Fixes: 81720ec5320c ("usb: host: xhci: use ffs() in xhci_mem_init()") Signed-off-by: Niklas Neronin Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-mem.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 92703efda1f7..dc5bcd8db4c0 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2391,10 +2391,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) page_size = readl(&xhci->op_regs->page_size); xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Supported page size register = 0x%x", page_size); - i = ffs(page_size); - if (i < 16) + val = ffs(page_size) - 1; + if (val < 16) xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "Supported page size of %iK", (1 << (i+12)) / 1024); + "Supported page size of %iK", (1 << (val + 12)) / 1024); else xhci_warn(xhci, "WARN: no supported page size\n"); /* Use 4K pages, since that's common and the minimum the HC supports */ From patchwork Thu Mar 6 14:49:48 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004630 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0D4E51891AA for ; Thu, 6 Mar 2025 14:49:41 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272582; cv=none; b=Yktg8+FXD/LLn9VopG7IUwRP1mzlf+PT3GVWzHaonb9/7WmCQyncMUzFvDfOtUbtowiZobhSxeaZlRhIrRDRcuuZwPuH0wfYcyhR9NNSSDfw1fnLz+1dAVMQLbCqLjDARQEak3NEEGA5+JFURhtw/4JCt2Gc4eS9sgtCCF0tc7c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272582; c=relaxed/simple; bh=GxLFvvNYvF55jn3x/zainmiVwdhLBbfy7sYORdPaprY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s7Zkb+EF+GSBCy1l/4m8XhXKkYZCiCBn7Qwe5XytKBr5DpqtzcwgPbCpLM4lVxDWhV/bj8QeB9fLBfk9M2tUs0Xn7tqtvYe57oMYz7uBugVTOtzqfFTBWPcQ6MJEnW1PK5sXacmfOBqOeK6McHbbkGe3qzl+DHEoib4fTPfCxec= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=CJcITuAv; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="CJcITuAv" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272581; x=1772808581; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=GxLFvvNYvF55jn3x/zainmiVwdhLBbfy7sYORdPaprY=; b=CJcITuAv2Tx5Qmwra/UUzPq7rA2WHWttqQmagXG95kqiq7C8A4kyI4lv MM7HVI4IFhotP6jUyNY7PXH9bhAShRnjuv4CrID74d0vDj2yXxMgXSb1i 4RbgFg/zPNGOiIguR72IqFbTKfjd9mxONhjGbOKr0hqBKh3tV5amXK7Fa K++05rd0cLIa9WXRgFKZeFdDo9z7paoLJ0V0ZvT/NCYM905jUIxMLORga eBnaaVc3fY32nInek4imH0NuyQ/UxUOWWY+6r5JzHlOYFga/pQcAhFGDO 3+VG5ReXi1nBnS/G6bK4MAdH+8Yu9WubXhYflXP6O4OP9UD51kQmxjwLf A==; X-CSE-ConnectionGUID: T7fsq6OCTE2QqelJGyq3aA== X-CSE-MsgGUID: SiPSegE/QKmp1fjQkg2KCQ== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657108" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657108" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:40 -0800 X-CSE-ConnectionGUID: ND5sZ5TfTZ676eIjkki1lQ== X-CSE-MsgGUID: I7IiUjgpQiWi3A5yJZIGbg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954842" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:39 -0800 From: Mathias Nyman To: Cc: , Niklas Neronin , Mathias Nyman Subject: [PATCH 09/15] usb: xhci: set page size to the xHCI-supported size Date: Thu, 6 Mar 2025 16:49:48 +0200 Message-ID: <20250306144954.3507700-10-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Niklas Neronin The current xHCI driver does not validate whether a page size of 4096 bytes is supported. Address the issue by setting the page size to the value supported by the xHCI controller, as read from the Page Size register. In the event of an unexpected value; default to a 4K page size. Additionally, this commit removes unnecessary debug messages and instead prints the supported and used page size once. The xHCI controller supports page sizes of (2^{(n+12)}) bytes, where 'n' is the Page Size Bit. Only one page size is supported, with a maximum page size of 128 KB. Signed-off-by: Niklas Neronin Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-mem.c | 34 ++++++++++++++++++---------------- drivers/usb/host/xhci.h | 8 ++++---- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index dc5bcd8db4c0..a7fdfa00eb48 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -1953,7 +1953,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci) xhci->interrupters = NULL; xhci->page_size = 0; - xhci->page_shift = 0; xhci->usb2_rhub.bus_state.bus_suspended = 0; xhci->usb3_rhub.bus_state.bus_suspended = 0; } @@ -2372,6 +2371,22 @@ xhci_create_secondary_interrupter(struct usb_hcd *hcd, unsigned int segs, } EXPORT_SYMBOL_GPL(xhci_create_secondary_interrupter); +static void xhci_hcd_page_size(struct xhci_hcd *xhci) +{ + u32 page_size; + + page_size = readl(&xhci->op_regs->page_size) & XHCI_PAGE_SIZE_MASK; + if (!is_power_of_2(page_size)) { + xhci_warn(xhci, "Invalid page size register = 0x%x\n", page_size); + /* Fallback to 4K page size, since that's common */ + page_size = 1; + } + + xhci->page_size = page_size << 12; + xhci_dbg_trace(xhci, trace_xhci_dbg_init, "HCD page size set to %iK", + xhci->page_size >> 10); +} + int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) { struct xhci_interrupter *ir; @@ -2379,7 +2394,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) dma_addr_t dma; unsigned int val, val2; u64 val_64; - u32 page_size, temp; + u32 temp; int i; INIT_LIST_HEAD(&xhci->cmd_list); @@ -2388,20 +2403,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) INIT_DELAYED_WORK(&xhci->cmd_timer, xhci_handle_command_timeout); init_completion(&xhci->cmd_ring_stop_completion); - page_size = readl(&xhci->op_regs->page_size); - xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "Supported page size register = 0x%x", page_size); - val = ffs(page_size) - 1; - if (val < 16) - xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "Supported page size of %iK", (1 << (val + 12)) / 1024); - else - xhci_warn(xhci, "WARN: no supported page size\n"); - /* Use 4K pages, since that's common and the minimum the HC supports */ - xhci->page_shift = 12; - xhci->page_size = 1 << xhci->page_shift; - xhci_dbg_trace(xhci, trace_xhci_dbg_init, - "HCD page size set to %iK", xhci->page_size / 1024); + xhci_hcd_page_size(xhci); /* * Program the Number of Device Slots Enabled field in the CONFIG diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 8c164340a2c3..5b8751b86008 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -211,6 +211,9 @@ struct xhci_op_regs { #define CONFIG_CIE (1 << 9) /* bits 10:31 - reserved and should be preserved */ +/* bits 15:0 - HCD page shift bit */ +#define XHCI_PAGE_SIZE_MASK 0xffff + /** * struct xhci_intr_reg - Interrupt Register Set * @irq_pending: IMAN - Interrupt Management Register. Used to enable @@ -1514,10 +1517,7 @@ struct xhci_hcd { u16 max_interrupters; /* imod_interval in ns (I * 250ns) */ u32 imod_interval; - /* 4KB min, 128MB max */ - int page_size; - /* Valid values are 12 to 20, inclusive */ - int page_shift; + u32 page_size; /* MSI-X/MSI vectors */ int nvecs; /* optional clocks */ From patchwork Thu Mar 6 14:49:49 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004631 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D96FF18C92F for ; Thu, 6 Mar 2025 14:49:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272584; cv=none; b=DwRwkJu1PgiLJ+ZF+BTulF+0c1FvM1LkTEkQzNYl6rKNOHFiaTpxz6pXrFIB1eNUCO/WQUZspCjIeo1iMALj9e+LoeS5CD2TKcMs1WvdXokqURiSPz+YESsfcPaHRQV5QM2cdk4nP/vvmT3p4N4OUDWCFY7yHI/1+Qh2FeXiH+s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272584; c=relaxed/simple; bh=lHz2IuVhfAf7hNSWAwFhNo2S0ql8i7glZ/39KTaUcQo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SSTx6V7Z+DNfOKOTFRUja0Pxq3rDKIzkYZVgvNQ5FvOjIL6stwX5gvO69r56IiEloiE3Xn/xUMa/2YUDoy3DDe9b0t1bIKsu1lp3bzBPvdaGgMt4TW2et/YjuI/JrCOih4KuVzNsI6Cf0LscftGPVkbRvLJXSmg7u9BleYdqDRw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Y30SiK0D; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Y30SiK0D" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272582; x=1772808582; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=lHz2IuVhfAf7hNSWAwFhNo2S0ql8i7glZ/39KTaUcQo=; b=Y30SiK0DXZZ1OJfZbr9DWM+xLUEQ9jENmyEGrUA03q60Ywall3E7yJwc eMdo/um08QfTxav3dqIXlPWIn/6i9eogrEV8g+azOaMyA1ZvRmcVRQ3tv 9obmqpTFaX0DMumOvSIry1+F2A2WonwbRXSbaI/bUS6U6chClhQkEfjFb N9jHvKLlMqCpIvDVJ+t02mMo98p4IGHo+94tJnZparKf0MoXYa7AsNlHj yrnS5akTMYt+KAgxyf8el6YaOPqtKVbaPMQfBJGXlxLSraSGMLL/cg7QD QXnPktMjtuvguBEz6hBI+7PDdUMFh0pxxc5OAN4T7nyzb6VnE4gJXtfsa Q==; X-CSE-ConnectionGUID: p9E2MoR8QUiI3Hv/RmHaDw== X-CSE-MsgGUID: 4rnW83ATSjGMQY2uyM7IRQ== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657115" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657115" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:42 -0800 X-CSE-ConnectionGUID: vBEDqE/KSNirjcdiy4r8SQ== X-CSE-MsgGUID: q9b0RNBXQry/43qSZ6DNwg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954847" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:40 -0800 From: Mathias Nyman To: Cc: , Niklas Neronin , Mathias Nyman Subject: [PATCH 10/15] usb: xhci: refactor trb_in_td() to be static Date: Thu, 6 Mar 2025 16:49:49 +0200 Message-ID: <20250306144954.3507700-11-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Niklas Neronin Relocate trb_in_td() and marks it as static, as it's exclusively utilized in xhci-ring.c. This adjustment lays the groundwork for future rework of the function. The function's logic remains unchanged; only its access specifier is altered to static and a redundant "else" is removed on line 325 (due to checkpatch.pl complaining). Signed-off-by: Niklas Neronin Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 122 +++++++++++++++++------------------ drivers/usb/host/xhci.h | 2 - 2 files changed, 61 insertions(+), 63 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 70b896297494..8c7258afb6bf 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -277,6 +277,67 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, } } +/* + * If the suspect DMA address is a TRB in this TD, this function returns that + * TRB's segment. Otherwise it returns 0. + */ +static struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, struct xhci_td *td, + dma_addr_t suspect_dma, bool debug) +{ + dma_addr_t start_dma; + dma_addr_t end_seg_dma; + dma_addr_t end_trb_dma; + struct xhci_segment *cur_seg; + + start_dma = xhci_trb_virt_to_dma(td->start_seg, td->start_trb); + cur_seg = td->start_seg; + + do { + if (start_dma == 0) + return NULL; + /* We may get an event for a Link TRB in the middle of a TD */ + end_seg_dma = xhci_trb_virt_to_dma(cur_seg, + &cur_seg->trbs[TRBS_PER_SEGMENT - 1]); + /* If the end TRB isn't in this segment, this is set to 0 */ + end_trb_dma = xhci_trb_virt_to_dma(cur_seg, td->end_trb); + + if (debug) + xhci_warn(xhci, + "Looking for event-dma %016llx trb-start %016llx trb-end %016llx seg-start %016llx seg-end %016llx\n", + (unsigned long long)suspect_dma, + (unsigned long long)start_dma, + (unsigned long long)end_trb_dma, + (unsigned long long)cur_seg->dma, + (unsigned long long)end_seg_dma); + + if (end_trb_dma > 0) { + /* The end TRB is in this segment, so suspect should be here */ + if (start_dma <= end_trb_dma) { + if (suspect_dma >= start_dma && suspect_dma <= end_trb_dma) + return cur_seg; + } else { + /* Case for one segment with + * a TD wrapped around to the top + */ + if ((suspect_dma >= start_dma && + suspect_dma <= end_seg_dma) || + (suspect_dma >= cur_seg->dma && + suspect_dma <= end_trb_dma)) + return cur_seg; + } + return NULL; + } + /* Might still be somewhere in this segment */ + if (suspect_dma >= start_dma && suspect_dma <= end_seg_dma) + return cur_seg; + + cur_seg = cur_seg->next; + start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]); + } while (cur_seg != td->start_seg); + + return NULL; +} + /* * Return number of free normal TRBs from enqueue to dequeue pointer on ring. * Not counting an assumed link TRB at end of each TRBS_PER_SEGMENT sized segment. @@ -2079,67 +2140,6 @@ static void handle_port_status(struct xhci_hcd *xhci, union xhci_trb *event) spin_lock(&xhci->lock); } -/* - * If the suspect DMA address is a TRB in this TD, this function returns that - * TRB's segment. Otherwise it returns 0. - */ -struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, struct xhci_td *td, dma_addr_t suspect_dma, - bool debug) -{ - dma_addr_t start_dma; - dma_addr_t end_seg_dma; - dma_addr_t end_trb_dma; - struct xhci_segment *cur_seg; - - start_dma = xhci_trb_virt_to_dma(td->start_seg, td->start_trb); - cur_seg = td->start_seg; - - do { - if (start_dma == 0) - return NULL; - /* We may get an event for a Link TRB in the middle of a TD */ - end_seg_dma = xhci_trb_virt_to_dma(cur_seg, - &cur_seg->trbs[TRBS_PER_SEGMENT - 1]); - /* If the end TRB isn't in this segment, this is set to 0 */ - end_trb_dma = xhci_trb_virt_to_dma(cur_seg, td->end_trb); - - if (debug) - xhci_warn(xhci, - "Looking for event-dma %016llx trb-start %016llx trb-end %016llx seg-start %016llx seg-end %016llx\n", - (unsigned long long)suspect_dma, - (unsigned long long)start_dma, - (unsigned long long)end_trb_dma, - (unsigned long long)cur_seg->dma, - (unsigned long long)end_seg_dma); - - if (end_trb_dma > 0) { - /* The end TRB is in this segment, so suspect should be here */ - if (start_dma <= end_trb_dma) { - if (suspect_dma >= start_dma && suspect_dma <= end_trb_dma) - return cur_seg; - } else { - /* Case for one segment with - * a TD wrapped around to the top - */ - if ((suspect_dma >= start_dma && - suspect_dma <= end_seg_dma) || - (suspect_dma >= cur_seg->dma && - suspect_dma <= end_trb_dma)) - return cur_seg; - } - return NULL; - } else { - /* Might still be somewhere in this segment */ - if (suspect_dma >= start_dma && suspect_dma <= end_seg_dma) - return cur_seg; - } - cur_seg = cur_seg->next; - start_dma = xhci_trb_virt_to_dma(cur_seg, &cur_seg->trbs[0]); - } while (cur_seg != td->start_seg); - - return NULL; -} - static void xhci_clear_hub_tt_buffer(struct xhci_hcd *xhci, struct xhci_td *td, struct xhci_virt_ep *ep) { diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 5b8751b86008..cd96e0a8c593 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1884,8 +1884,6 @@ int xhci_set_interrupter_moderation(struct xhci_interrupter *ir, /* xHCI ring, segment, TRB, and TD functions */ dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb); -struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, struct xhci_td *td, - dma_addr_t suspect_dma, bool debug); int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code); void xhci_ring_cmd_db(struct xhci_hcd *xhci); int xhci_queue_slot_control(struct xhci_hcd *xhci, struct xhci_command *cmd, From patchwork Thu Mar 6 14:49:50 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004632 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3EEB817C224 for ; Thu, 6 Mar 2025 14:49:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272585; cv=none; b=F4EJP9EZQGQz7PID366k0s4ZSFeSOLo7cWs3gcJ0fNcQWxZkCSzep6b00cX5ZcVHR7zWc9CLrCaE4m9/lfX9689vWRoYi+n3uILUih3Q+4SAuXUPd9xRDXbQ0DwGDELqwB8qpVuZGZyAapCdoFmMEh4uNBfaonbqoYwkl4qMgLs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272585; c=relaxed/simple; bh=kxR/DT4MfNB17dS4SWdmQTxXcMxvQTwz25wUAJt7Wiw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EKHID+tqtgbjEKcRt9Ec+5BmGOV/S7cWNAxcBAr7+e30VbEKLtL4byZrbJLXLPxrycfNTxKbukE85y174/NNYME3ZmZXXkBq8Aoq3mJrXK/Ypy7Uq8curVF1kCJqvoChAQpDY4LC1CsviyWpV5kGtrE2gVTTWEU0d5cgoaK6jtI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=aiIwYXZe; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="aiIwYXZe" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272584; x=1772808584; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kxR/DT4MfNB17dS4SWdmQTxXcMxvQTwz25wUAJt7Wiw=; b=aiIwYXZeSBow8Zsqn/PTdSnapVWC7G5Ifk+RUHm6hvCTIvxUQRC2HssQ huAkIEdNXP3252Azw3oqZHoH/671xU+5thueKXYwuDJgeO00b8omdD/oO 9bd04g/S9oPK79zs3uI/KAeF3KQnlFgYDWn3xPdXWYsqMxOMhXAbaIRjS 2CoUoOW+xeluoOv8TYop7h8pjhzrgkfikVu2HHS+zvDqkSFv5IcYTyERk DBitTtv/JH+d+3QtvVnTZPa/vZfx7+55iRB7wEj97QeCfKDI8oqd4lzdQ l5WNBWadWMtfDY+UN+K+e3BbCmpUH/wQeqMcPZ8oJ1bvny7bssHg3jxPn Q==; X-CSE-ConnectionGUID: TxQZI1ogSJiDbBKX7V0+bQ== X-CSE-MsgGUID: xsm91THNStSnE4L/pH3jMA== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657119" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657119" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:44 -0800 X-CSE-ConnectionGUID: rG3rYfTnRsC7sz/SmMc/EQ== X-CSE-MsgGUID: l5zJpqi/SGaD0+6mv+Rz2A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954852" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:42 -0800 From: Mathias Nyman To: Cc: , Niklas Neronin , Mathias Nyman Subject: [PATCH 11/15] usb: xhci: move debug capabilities from trb_in_td() to handle_tx_event() Date: Thu, 6 Mar 2025 16:49:50 +0200 Message-ID: <20250306144954.3507700-12-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Niklas Neronin Function trb_in_td() currently includes debug capabilities that are triggered when its debug argument is set to true. The only consumer of these debug capabilities is handle_tx_event(), which calls trb_in_td() twice, once for its primary functionality and a second time solely for debugging purposes if the first call returns 'NULL'. This approach is inefficient and can lead to confusion, as trb_in_td() executes the same code with identical arguments twice, differing only in the debug output during the second execution. To enhance clarity and efficiency, move the debug capabilities out of trb_in_td() and integrates them directly into handle_tx_event(). This change reduces the argument count of trb_in_td() and ensures that debug steps are executed only when necessary, streamlining the function's operation. Signed-off-by: Niklas Neronin Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 38 ++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 8c7258afb6bf..c2e15a27338b 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -281,8 +281,7 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, * If the suspect DMA address is a TRB in this TD, this function returns that * TRB's segment. Otherwise it returns 0. */ -static struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, struct xhci_td *td, - dma_addr_t suspect_dma, bool debug) +static struct xhci_segment *trb_in_td(struct xhci_td *td, dma_addr_t suspect_dma) { dma_addr_t start_dma; dma_addr_t end_seg_dma; @@ -301,15 +300,6 @@ static struct xhci_segment *trb_in_td(struct xhci_hcd *xhci, struct xhci_td *td, /* If the end TRB isn't in this segment, this is set to 0 */ end_trb_dma = xhci_trb_virt_to_dma(cur_seg, td->end_trb); - if (debug) - xhci_warn(xhci, - "Looking for event-dma %016llx trb-start %016llx trb-end %016llx seg-start %016llx seg-end %016llx\n", - (unsigned long long)suspect_dma, - (unsigned long long)start_dma, - (unsigned long long)end_trb_dma, - (unsigned long long)cur_seg->dma, - (unsigned long long)end_seg_dma); - if (end_trb_dma > 0) { /* The end TRB is in this segment, so suspect should be here */ if (start_dma <= end_trb_dma) { @@ -1075,7 +1065,7 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep) td->urb->stream_id); hw_deq &= ~0xf; - if (td->cancel_status == TD_HALTED || trb_in_td(xhci, td, hw_deq, false)) { + if (td->cancel_status == TD_HALTED || trb_in_td(td, hw_deq)) { switch (td->cancel_status) { case TD_CLEARED: /* TD is already no-op */ case TD_CLEARING_CACHE: /* set TR deq command already queued */ @@ -1165,7 +1155,7 @@ static struct xhci_td *find_halted_td(struct xhci_virt_ep *ep) hw_deq = xhci_get_hw_deq(ep->xhci, ep->vdev, ep->ep_index, 0); hw_deq &= ~0xf; td = list_first_entry(&ep->ring->td_list, struct xhci_td, td_list); - if (trb_in_td(ep->xhci, td, hw_deq, false)) + if (trb_in_td(td, hw_deq)) return td; } return NULL; @@ -2800,7 +2790,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, */ td = list_first_entry_or_null(&ep_ring->td_list, struct xhci_td, td_list); - if (td && td->error_mid_td && !trb_in_td(xhci, td, ep_trb_dma, false)) { + if (td && td->error_mid_td && !trb_in_td(td, ep_trb_dma)) { xhci_dbg(xhci, "Missing TD completion event after mid TD error\n"); xhci_dequeue_td(xhci, td, ep_ring, td->status); } @@ -2833,7 +2823,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, td_list); /* Is this a TRB in the currently executing TD? */ - ep_seg = trb_in_td(xhci, td, ep_trb_dma, false); + ep_seg = trb_in_td(td, ep_trb_dma); if (!ep_seg) { @@ -2893,12 +2883,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, } /* HC is busted, give up! */ - xhci_err(xhci, - "ERROR Transfer event TRB DMA ptr not part of current TD ep_index %d comp_code %u\n", - ep_index, trb_comp_code); - trb_in_td(xhci, td, ep_trb_dma, true); - - return -ESHUTDOWN; + goto debug_finding_td; } if (ep->skip) { @@ -2955,6 +2940,17 @@ static int handle_tx_event(struct xhci_hcd *xhci, return 0; +debug_finding_td: + xhci_err(xhci, "Event dma %pad for ep %d status %d not part of TD at %016llx - %016llx\n", + &ep_trb_dma, ep_index, trb_comp_code, + (unsigned long long)xhci_trb_virt_to_dma(td->start_seg, td->start_trb), + (unsigned long long)xhci_trb_virt_to_dma(td->end_seg, td->end_trb)); + + xhci_for_each_ring_seg(ep_ring->first_seg, ep_seg) + xhci_warn(xhci, "Ring seg %u dma %pad\n", ep_seg->num, &ep_seg->dma); + + return -ESHUTDOWN; + err_out: xhci_err(xhci, "@%016llx %08x %08x %08x %08x\n", (unsigned long long) xhci_trb_virt_to_dma( From patchwork Thu Mar 6 14:49:51 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004633 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9828218DF81 for ; Thu, 6 Mar 2025 14:49:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272587; cv=none; b=WwFUkKMnWbMb5nWL+IJLJTrxymZ/HyxQ5ZXeBG7bJ8vD3l0gKLpbHn9hU6+dI3XIOD76n2JFemiKVZ8LPNSSRaLXSQUr5fMbQFtwR0E9rY0nvUPL3VlNuyNAOSd80BU9gz4AzDSyWpIjkMLmgeOBDqiNVUEZ2UBlH+8ElRDQ+4M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272587; c=relaxed/simple; bh=v+Mk99ZnZEQmPQ5kDPchn9OHkgy2n4/m7U5IopKQ5rY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mElxSG42TWfVtJ2XVaUWDkE616VOz4PlWJcuhCadLwZ0/e+h0rG9GyX0e1FL8ePaAeQw6CT7/22FC4o+iU9QXGPvbWmPwzadsY4oeRg5dwEj/29ueuFjHk9VxJy7dxZnCAddj7xR61+LVRjNGq2b9P2u7uxcTQQl94HndVVYRdc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=N73VWpHx; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="N73VWpHx" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272585; x=1772808585; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=v+Mk99ZnZEQmPQ5kDPchn9OHkgy2n4/m7U5IopKQ5rY=; b=N73VWpHxyJhWaZcEkiTUiboMy1yUIKd3Q5h5YVdCUKpV/j2RJd3E3mMZ WX7xkon4zq1CAzJD+K6nzgWki1SnQRlmF6tLLCfFxy77PqdE3Z4y0L+uG 9y8bqUkFs62ap7XTyhCaaTC88KWji1FoMDrEdrKXS1gzFLD3heMQgcz/h oSeWZM8VXi6e+1V+siyU3M7hC0miTxAMdVL/hQUD58Wozj7UpyW89nzE1 ID1QKpo3Xv8V/mVrdndPBCRhxDQ/CI95KMCyZ4UPfUSsin8/32O6C/8Z6 oi6CygxVrspJtWwfwa21NSAfosThIYdD4xUrsymJxtQk5guGGGcp9mG6S Q==; X-CSE-ConnectionGUID: VHaSpRpVTo+RjDHmBs6oWw== X-CSE-MsgGUID: Hd2H0mq+Qy2YhMFVrPChHQ== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657127" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657127" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:45 -0800 X-CSE-ConnectionGUID: Uq2vwelKQ2ui/AA60bK5uw== X-CSE-MsgGUID: F49EXsQpQmOr/pPeai8NKQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954861" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:44 -0800 From: Mathias Nyman To: Cc: , Mathias Nyman Subject: [PATCH 12/15] xhci: Prevent early endpoint restart when handling STALL errors. Date: Thu, 6 Mar 2025 16:49:51 +0200 Message-ID: <20250306144954.3507700-13-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Ensure that an endpoint halted due to device STALL is not restarted before a Clear_Feature(ENDPOINT_HALT) request is sent to the device. The host side of the endpoint may otherwise be started early by the 'Set TR Deq' command completion handler which is called if dequeue is moved past a cancelled or halted TD. Prevent this with a new flag set for bulk and interrupt endpoints when a Stall Error is received. Clear it in hcd->endpoint_reset() which is called after Clear_Feature(ENDPOINT_HALT) is sent. Also add a debug message if a class driver queues a new URB after the STALL. Note that class driver might not be aware of the STALL yet when it submits the URB as URBs are given back in BH. Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 7 +++++-- drivers/usb/host/xhci.c | 6 ++++++ drivers/usb/host/xhci.h | 3 ++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index c2e15a27338b..7643ab9ec3b4 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -556,8 +556,8 @@ void xhci_ring_ep_doorbell(struct xhci_hcd *xhci, * pointer command pending because the device can choose to start any * stream once the endpoint is on the HW schedule. */ - if ((ep_state & EP_STOP_CMD_PENDING) || (ep_state & SET_DEQ_PENDING) || - (ep_state & EP_HALTED) || (ep_state & EP_CLEARING_TT)) + if (ep_state & (EP_STOP_CMD_PENDING | SET_DEQ_PENDING | EP_HALTED | + EP_CLEARING_TT | EP_STALLED)) return; trace_xhci_ring_ep_doorbell(slot_id, DB_VALUE(ep_index, stream_id)); @@ -2555,6 +2555,9 @@ static void process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_virt_ep *ep, xhci_handle_halted_endpoint(xhci, ep, td, EP_SOFT_RESET); return; + case COMP_STALL_ERROR: + ep->ep_state |= EP_STALLED; + break; default: /* do nothing */ break; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 3f2cd546a7a2..0c22b78358b9 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1604,6 +1604,11 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag goto free_priv; } + /* Class driver might not be aware ep halted due to async URB giveback */ + if (*ep_state & EP_STALLED) + dev_dbg(&urb->dev->dev, "URB %p queued before clearing halt\n", + urb); + switch (usb_endpoint_type(&urb->ep->desc)) { case USB_ENDPOINT_XFER_CONTROL: @@ -3202,6 +3207,7 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd, return; ep = &vdev->eps[ep_index]; + ep->ep_state &= ~EP_STALLED; /* Bail out if toggle is already being cleared by a endpoint reset */ spin_lock_irqsave(&xhci->lock, flags); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index cd96e0a8c593..4ee14f651d36 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -664,7 +664,7 @@ struct xhci_virt_ep { unsigned int err_count; unsigned int ep_state; #define SET_DEQ_PENDING (1 << 0) -#define EP_HALTED (1 << 1) /* For stall handling */ +#define EP_HALTED (1 << 1) /* Halted host ep handling */ #define EP_STOP_CMD_PENDING (1 << 2) /* For URB cancellation */ /* Transitioning the endpoint to using streams, don't enqueue URBs */ #define EP_GETTING_STREAMS (1 << 3) @@ -675,6 +675,7 @@ struct xhci_virt_ep { #define EP_SOFT_CLEAR_TOGGLE (1 << 7) /* usb_hub_clear_tt_buffer is in progress */ #define EP_CLEARING_TT (1 << 8) +#define EP_STALLED (1 << 9) /* For stall handling */ /* ---- Related to URB cancellation ---- */ struct list_head cancelled_td_list; struct xhci_hcd *xhci; From patchwork Thu Mar 6 14:49:52 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004634 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 14E5F188736; Thu, 6 Mar 2025 14:49:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272589; cv=none; b=rgH0YdKYLEcPun692XDHWoawYTuN4MaYG9pY4ZrCx/7+XQxzueJqePbpMM+5w6dT/3dbXPfywpNtLqaTUqeqM4r2NWHdyrHkKiG1Pj2fewM9vfZ/VC+IFgAGlTYg45Rx5uI7jb487JdA+IzSBVwN+ezApfmn1O0Kbt42gsCidyI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272589; c=relaxed/simple; bh=npN7YT+FCGZDJdKq2GDB5Y0sUZvaHfkB+s20EmA/Lko=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KSqvQZK7j3OoqmWSCLNDFTB1HnBAXgc7by39gF1TJrNCzbaTew6gBC0nj85ENnb+D6BzZrNeqKhyq6MuzIiCOt0CM7VT8IJiLExhs/QlNIiCURXBGVXz9gfYxXfXDQWkyfQeOU9Ad+fiNF8p2SvSfypwHbT3vRM3lBcJ58fjVLI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=VSULzDA5; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="VSULzDA5" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272588; x=1772808588; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=npN7YT+FCGZDJdKq2GDB5Y0sUZvaHfkB+s20EmA/Lko=; b=VSULzDA5PQsTmLoxPnbH/6R5kskL3nhDgnjzo2dRlFlxAh5ZFyJZ4LyD KhaFh65KOG4ZSR6uqtJNFvTgmqRGSqjQZBTt+JI0Z4Vu76KW/Sm4OoRZM ZR5L5ciLIXMMFvECItMXUELHVyvidbl7lnaFLE8bpcnpJoKRpqHfaYuas KgjlR9Li4RsLzbg31q8BxSFklOlJGi3iICoTXbvn3uNhh6h4cIKJbGXGQ xl6KYbVh1JxpRxDL6ICJqYOomJSqHi1Av4R53fP2d3vISqLez1hrbnfNW vETeshcxK9nOlGNw8H8EuOFoaBC1zxtsRwptFV8RfSt5VfbdTovy5c1A7 g==; X-CSE-ConnectionGUID: 5HG65KBmTYmXVzQd/ya/Xg== X-CSE-MsgGUID: 25cMcOz8T/GipWR4Pxyj2A== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657135" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657135" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:47 -0800 X-CSE-ConnectionGUID: ON07u6UFRgiOG38Jq9Zv6Q== X-CSE-MsgGUID: tZ1x9r6NQdqCwf6YynPCZw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954865" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:45 -0800 From: Mathias Nyman To: Cc: , Michal Pecio , stable@vger.kernel.org, Mathias Nyman Subject: [PATCH 13/15] usb: xhci: Apply the link chain quirk on NEC isoc endpoints Date: Thu, 6 Mar 2025 16:49:52 +0200 Message-ID: <20250306144954.3507700-14-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Michal Pecio Two clearly different specimens of NEC uPD720200 (one with start/stop bug, one without) were seen to cause IOMMU faults after some Missed Service Errors. Faulting address is immediately after a transfer ring segment and patched dynamic debug messages revealed that the MSE was received when waiting for a TD near the end of that segment: [ 1.041954] xhci_hcd: Miss service interval error for slot 1 ep 2 expected TD DMA ffa08fe0 [ 1.042120] xhci_hcd: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0005 address=0xffa09000 flags=0x0000] [ 1.042146] xhci_hcd: AMD-Vi: Event logged [IO_PAGE_FAULT domain=0x0005 address=0xffa09040 flags=0x0000] It gets even funnier if the next page is a ring segment accessible to the HC. Below, it reports MSE in segment at ff1e8000, plows through a zero-filled page at ff1e9000 and starts reporting events for TRBs in page at ff1ea000 every microframe, instead of jumping to seg ff1e6000. [ 7.041671] xhci_hcd: Miss service interval error for slot 1 ep 2 expected TD DMA ff1e8fe0 [ 7.041999] xhci_hcd: Miss service interval error for slot 1 ep 2 expected TD DMA ff1e8fe0 [ 7.042011] xhci_hcd: WARN: buffer overrun event for slot 1 ep 2 on endpoint [ 7.042028] xhci_hcd: All TDs skipped for slot 1 ep 2. Clear skip flag. [ 7.042134] xhci_hcd: WARN: buffer overrun event for slot 1 ep 2 on endpoint [ 7.042138] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 31 [ 7.042144] xhci_hcd: Looking for event-dma 00000000ff1ea040 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820 [ 7.042259] xhci_hcd: WARN: buffer overrun event for slot 1 ep 2 on endpoint [ 7.042262] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 31 [ 7.042266] xhci_hcd: Looking for event-dma 00000000ff1ea050 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820 At some point completion events change from Isoch Buffer Overrun to Short Packet and the HC finally finds cycle bit mismatch in ff1ec000. [ 7.098130] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 13 [ 7.098132] xhci_hcd: Looking for event-dma 00000000ff1ecc50 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820 [ 7.098254] xhci_hcd: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 2 comp_code 13 [ 7.098256] xhci_hcd: Looking for event-dma 00000000ff1ecc60 trb-start 00000000ff1e6820 trb-end 00000000ff1e6820 [ 7.098379] xhci_hcd: Overrun event on slot 1 ep 2 It's possible that data from the isochronous device were written to random buffers of pending TDs on other endpoints (either IN or OUT), other devices or even other HCs in the same IOMMU domain. Lastly, an error from a different USB device on another HC. Was it caused by the above? I don't know, but it may have been. The disk was working without any other issues and generated PCIe traffic to starve the NEC of upstream BW and trigger those MSEs. The two HCs shared one x1 slot by means of a commercial "PCIe splitter" board. [ 7.162604] usb 10-2: reset SuperSpeed USB device number 3 using xhci_hcd [ 7.178990] sd 9:0:0:0: [sdb] tag#0 UNKNOWN(0x2003) Result: hostbyte=0x07 driverbyte=DRIVER_OK cmd_age=0s [ 7.179001] sd 9:0:0:0: [sdb] tag#0 CDB: opcode=0x28 28 00 04 02 ae 00 00 02 00 00 [ 7.179004] I/O error, dev sdb, sector 67284480 op 0x0:(READ) flags 0x80700 phys_seg 5 prio class 0 Fortunately, it appears that this ridiculous bug is avoided by setting the chain bit of Link TRBs on isochronous rings. Other ancient HCs are known which also expect the bit to be set and they ignore Link TRBs if it's not. Reportedly, 0.95 spec guaranteed that the bit is set. The bandwidth-starved NEC HC running a 32KB/uframe UVC endpoint reports tens of MSEs per second and runs into the bug within seconds. Chaining Link TRBs allows the same workload to run for many minutes, many times. No negative side effects seen in UVC recording and UAC playback with a few devices at full speed, high speed and SuperSpeed. The problem doesn't reproduce on the newer Renesas uPD720201/uPD720202 and on old Etron EJ168 and VIA VL805 (but the VL805 has other bug). [shorten line length of log snippets in commit messge -Mathias] Signed-off-by: Michal Pecio Cc: stable@vger.kernel.org Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 4ee14f651d36..d9d7cd1906f3 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1760,11 +1760,20 @@ static inline void xhci_write_64(struct xhci_hcd *xhci, } -/* Link TRB chain should always be set on 0.95 hosts, and AMD 0.96 ISOC rings */ +/* + * Reportedly, some chapters of v0.95 spec said that Link TRB always has its chain bit set. + * Other chapters and later specs say that it should only be set if the link is inside a TD + * which continues from the end of one segment to the next segment. + * + * Some 0.95 hardware was found to misbehave if any link TRB doesn't have the chain bit set. + * + * 0.96 hardware from AMD and NEC was found to ignore unchained isochronous link TRBs when + * "resynchronizing the pipe" after a Missed Service Error. + */ static inline bool xhci_link_chain_quirk(struct xhci_hcd *xhci, enum xhci_ring_type type) { return (xhci->quirks & XHCI_LINK_TRB_QUIRK) || - (type == TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST)); + (type == TYPE_ISOC && (xhci->quirks & (XHCI_AMD_0x96_HOST | XHCI_NEC_HOST))); } /* xHCI debugging */ From patchwork Thu Mar 6 14:49:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004635 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AC481188012 for ; Thu, 6 Mar 2025 14:49:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272591; cv=none; b=H9vIUhCgYo5PxJI7DnpclfVJYuA2FhuiTvDxWuC1UQ6pKfkfOG4BTboP+pk4viTz4FVWiN7GjmvwPeak3uvtGsW9us9537fsVVg5bVYu3NflngWSMVeZdw8GmXMG2L5616WKO9RAN1GNeKB5ApJIPQ6ISiXl32v+bPGNLcj+WMQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272591; c=relaxed/simple; bh=QaIqd/aAOjm82oUjsmHWxXEkA2zfHO0WeYg2sFbSqJY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ur6tTFIw7GUstblV7pfd24lBjbLWGUm0t87V/8i34uJ5mzfoGEUpy4ICfgsnbcl/OuiAUzfhJykCvk4XT7+pR59ylDWMqdQ4sH/0yje41/Pq0TY5puY+aWeXvnyQ67aEL9N6/m/JwrF4axjRAjZYkChL8jBvTp15QhBbilmuZtI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=joZp3jTy; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="joZp3jTy" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272589; x=1772808589; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=QaIqd/aAOjm82oUjsmHWxXEkA2zfHO0WeYg2sFbSqJY=; b=joZp3jTyYE31jdCiXX9pO1MvQfV3SmKe3lc1vbdKAvZwQCWyytO+mssG 4KepBBc9zYPO2V2ygWQEeGDVqStUWfY9oYVPrjP6rwhH611n2QXyBzlt/ NO0AK53T5bHl8J2CEjLjtwDc35e66QfaNWt6I6y+EjeoGcA6RfXNBrOOI O1pSnxFfOeXfJgVGHXyh0YlhBJHsTTOpobwrk0VmPIPDRKMV7T1xrmc9h ixJSvDiXP0oSAVMy0ttxQan9LP/NUNxFnHJGImQ8DtgV8NG4OtEbaWVt5 Gco5QsgHN19DrbyYynhh0di9Lc/NPsdeFo+zu7287zjrwwK3MiP52HqEl w==; X-CSE-ConnectionGUID: u2KE7CYfQYquvp453ixGPg== X-CSE-MsgGUID: YWA7IdoWRZGRTkzDJmqR2g== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657146" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657146" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:49 -0800 X-CSE-ConnectionGUID: 7pDB5363T1KAs2/nVTF5og== X-CSE-MsgGUID: zJyQvk/ERkO0kGhrDV+oeg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954867" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:47 -0800 From: Mathias Nyman To: Cc: , Michal Pecio , Mathias Nyman Subject: [PATCH 14/15] usb: xhci: Unify duplicate inc_enq() code Date: Thu, 6 Mar 2025 16:49:53 +0200 Message-ID: <20250306144954.3507700-15-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Michal Pecio Extract a block of code copied from inc_enq() into a separate function and call it from inc_enq() and the other function which used this code. Remove the pointless 'next' variable which only aliases ring->enqueue. Note: I don't know if any 0.95 xHC ever reached series production, but "AMD 0.96 host" appears to be the "Llano" family APU. Example dmesg at https://linux-hardware.org/?probe=79d5cfd4fd&log=dmesg pci 0000:00:10.0: [1022:7812] type 00 class 0x0c0330 hcc params 0x014042c3 hci version 0x96 quirks 0x0000000000000608 Signed-off-by: Michal Pecio Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 130 +++++++++++++++-------------------- 1 file changed, 55 insertions(+), 75 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7643ab9ec3b4..2df94ed3152c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -204,79 +204,84 @@ void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) } /* - * See Cycle bit rules. SW is the consumer for the event ring only. - * - * If we've just enqueued a TRB that is in the middle of a TD (meaning the - * chain bit is set), then set the chain bit in all the following link TRBs. - * If we've enqueued the last TRB in a TD, make sure the following link TRBs - * have their chain bit cleared (so that each Link TRB is a separate TD). - * - * Section 6.4.4.1 of the 0.95 spec says link TRBs cannot have the chain bit - * set, but other sections talk about dealing with the chain bit set. This was - * fixed in the 0.96 specification errata, but we have to assume that all 0.95 - * xHCI hardware can't handle the chain bit being cleared on a link TRB. - * - * @more_trbs_coming: Will you enqueue more TRBs before calling - * prepare_transfer()? + * If enqueue points at a link TRB, follow links until an ordinary TRB is reached. + * Toggle the cycle bit of passed link TRBs and optionally chain them. */ -static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, - bool more_trbs_coming) +static void inc_enq_past_link(struct xhci_hcd *xhci, struct xhci_ring *ring, u32 chain) { - u32 chain; - union xhci_trb *next; unsigned int link_trb_count = 0; - chain = le32_to_cpu(ring->enqueue->generic.field[3]) & TRB_CHAIN; - - if (last_trb_on_seg(ring->enq_seg, ring->enqueue)) { - xhci_err(xhci, "Tried to move enqueue past ring segment\n"); - return; - } - - next = ++(ring->enqueue); - - /* Update the dequeue pointer further if that was a link TRB */ - while (trb_is_link(next)) { + while (trb_is_link(ring->enqueue)) { /* - * If the caller doesn't plan on enqueueing more TDs before - * ringing the doorbell, then we don't want to give the link TRB - * to the hardware just yet. We'll give the link TRB back in - * prepare_ring() just before we enqueue the TD at the top of - * the ring. - */ - if (!chain && !more_trbs_coming) - break; - - /* If we're not dealing with 0.95 hardware or isoc rings on - * AMD 0.96 host, carry over the chain bit of the previous TRB - * (which may mean the chain bit is cleared). + * Section 6.4.4.1 of the 0.95 spec says link TRBs cannot have the chain bit + * set, but other sections talk about dealing with the chain bit set. This was + * fixed in the 0.96 specification errata, but we have to assume that all 0.95 + * xHCI hardware can't handle the chain bit being cleared on a link TRB. + * + * On 0.95 and some 0.96 HCs the chain bit is set once at segment initalization + * and never changed here. On all others, modify it as requested by the caller. */ if (!xhci_link_chain_quirk(xhci, ring->type)) { - next->link.control &= cpu_to_le32(~TRB_CHAIN); - next->link.control |= cpu_to_le32(chain); + ring->enqueue->link.control &= cpu_to_le32(~TRB_CHAIN); + ring->enqueue->link.control |= cpu_to_le32(chain); } + /* Give this link TRB to the hardware */ wmb(); - next->link.control ^= cpu_to_le32(TRB_CYCLE); + ring->enqueue->link.control ^= cpu_to_le32(TRB_CYCLE); /* Toggle the cycle bit after the last ring segment. */ - if (link_trb_toggles_cycle(next)) + if (link_trb_toggles_cycle(ring->enqueue)) ring->cycle_state ^= 1; ring->enq_seg = ring->enq_seg->next; ring->enqueue = ring->enq_seg->trbs; - next = ring->enqueue; trace_xhci_inc_enq(ring); if (link_trb_count++ > ring->num_segs) { - xhci_warn(xhci, "%s: Ring link TRB loop\n", __func__); + xhci_warn(xhci, "Link TRB loop at enqueue\n"); break; } } } +/* + * See Cycle bit rules. SW is the consumer for the event ring only. + * + * If we've just enqueued a TRB that is in the middle of a TD (meaning the + * chain bit is set), then set the chain bit in all the following link TRBs. + * If we've enqueued the last TRB in a TD, make sure the following link TRBs + * have their chain bit cleared (so that each Link TRB is a separate TD). + * + * @more_trbs_coming: Will you enqueue more TRBs before calling + * prepare_transfer()? + */ +static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, + bool more_trbs_coming) +{ + u32 chain; + + chain = le32_to_cpu(ring->enqueue->generic.field[3]) & TRB_CHAIN; + + if (last_trb_on_seg(ring->enq_seg, ring->enqueue)) { + xhci_err(xhci, "Tried to move enqueue past ring segment\n"); + return; + } + + ring->enqueue++; + + /* + * If we are in the middle of a TD or the caller plans to enqueue more + * TDs as one transfer (eg. control), traverse any link TRBs right now. + * Otherwise, enqueue can stay on a link until the next prepare_ring(). + * This avoids enqueue entering deq_seg and simplifies ring expansion. + */ + if (trb_is_link(ring->enqueue) && (chain || more_trbs_coming)) + inc_enq_past_link(xhci, ring, chain); +} + /* * If the suspect DMA address is a TRB in this TD, this function returns that * TRB's segment. Otherwise it returns 0. @@ -3213,7 +3218,6 @@ static void queue_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, u32 ep_state, unsigned int num_trbs, gfp_t mem_flags) { - unsigned int link_trb_count = 0; unsigned int new_segs = 0; /* Make sure the endpoint has been added to xHC schedule */ @@ -3261,33 +3265,9 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, } } - while (trb_is_link(ep_ring->enqueue)) { - /* If we're not dealing with 0.95 hardware or isoc rings - * on AMD 0.96 host, clear the chain bit. - */ - if (!xhci_link_chain_quirk(xhci, ep_ring->type)) - ep_ring->enqueue->link.control &= - cpu_to_le32(~TRB_CHAIN); - else - ep_ring->enqueue->link.control |= - cpu_to_le32(TRB_CHAIN); - - wmb(); - ep_ring->enqueue->link.control ^= cpu_to_le32(TRB_CYCLE); - - /* Toggle the cycle bit after the last ring segment. */ - if (link_trb_toggles_cycle(ep_ring->enqueue)) - ep_ring->cycle_state ^= 1; - - ep_ring->enq_seg = ep_ring->enq_seg->next; - ep_ring->enqueue = ep_ring->enq_seg->trbs; - - /* prevent infinite loop if all first trbs are link trbs */ - if (link_trb_count++ > ep_ring->num_segs) { - xhci_warn(xhci, "Ring is an endless link TRB loop\n"); - return -EINVAL; - } - } + /* Ensure that new TRBs won't overwrite a link */ + if (trb_is_link(ep_ring->enqueue)) + inc_enq_past_link(xhci, ep_ring, 0); if (last_trb_on_seg(ep_ring->enq_seg, ep_ring->enqueue)) { xhci_warn(xhci, "Missing link TRB at end of ring segment\n"); From patchwork Thu Mar 6 14:49:54 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathias Nyman X-Patchwork-Id: 14004636 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3DF81188713 for ; Thu, 6 Mar 2025 14:49:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.7 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272592; cv=none; b=Ugp543wXcrbYoAgWVFvOpiixBd9LVz8zMDHy7Fk5LJD6yzgv8dY/OAuMLUNwyJGsnlJvRcAad6wmQZ3SWMlLigccg7/sJGek+0YfpdWDsIHejTeitY9vmf5oZqK9Ge5UqeHjOPr2tgXt01QQrasYL7wNh3mhRbwdKBk7KL3q388= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741272592; c=relaxed/simple; bh=h0jmkNPs0kBm6EOeKCEag0WU4dJUWsRvAIz2E3r2iVI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mGKKouJmLug43E7unkk2wH/uXSrbeQy/GGiOH3YQgEX3b3MbQhm+S53lqI9s6fxOGd1X+husZw5m92Xv5/MukrLEGbpJUwRiCN7JzTInYnF2DvkSqGnwFL2D8+07XJ29ZSAP2+f5Iqgx+akqWdHzYBAL/GREWWOiOZw0U+OtG/w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=BnTEl5c6; arc=none smtp.client-ip=192.198.163.7 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="BnTEl5c6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1741272591; x=1772808591; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=h0jmkNPs0kBm6EOeKCEag0WU4dJUWsRvAIz2E3r2iVI=; b=BnTEl5c6yceW8WFBh+WsW2jLOZ8PsrKHoNRPezsM7mW61JJodes3bZHS xTnIiVYUsRTH+ONZ1cczRYo5lokSmfG/FiPwKx9aWoYonCCe/wDu4PbbY Lrky0AfVfPUsN6ciUcukATPRMgfDkQraSZNrz4H2SAuo9Mc3McDvu4s88 e2gMrbe03CmXrhS5/CTROyflYSvKGAryCk0WLgQ+/VzlID7Rrjm9yPCfX 1CH7Lgx+CMspSGAZQq1q1WBS4l1y6q5NOAXhI4+jb+e6GwKNHjA2hNmWX 4+Tv49/1EvIdPeCY4F3DbZvYCLq1B+M5MYhmPy6CtjfeCJ3k4vK3fqR1I A==; X-CSE-ConnectionGUID: 225sBlAbRwybuw82m6Tl1g== X-CSE-MsgGUID: 6T2zbr53QT6qlpbiCYBxTQ== X-IronPort-AV: E=McAfee;i="6700,10204,11365"; a="67657152" X-IronPort-AV: E=Sophos;i="6.14,226,1736841600"; d="scan'208";a="67657152" Received: from orviesa008.jf.intel.com ([10.64.159.148]) by fmvoesa101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Mar 2025 06:49:51 -0800 X-CSE-ConnectionGUID: KKsl0be6QC6MKR7JW4juQA== X-CSE-MsgGUID: LVUEjJOqSneGyGggd2z21Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,224,1728975600"; d="scan'208";a="119954873" Received: from unknown (HELO mattu-haswell.fi.intel.com) ([10.237.72.199]) by orviesa008.jf.intel.com with ESMTP; 06 Mar 2025 06:49:49 -0800 From: Mathias Nyman To: Cc: , Mathias Nyman , Kuangyi Chiang , Michal Pecio Subject: [PATCH 15/15] xhci: Handle spurious events on Etron host isoc enpoints Date: Thu, 6 Mar 2025 16:49:54 +0200 Message-ID: <20250306144954.3507700-16-mathias.nyman@linux.intel.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> References: <20250306144954.3507700-1-mathias.nyman@linux.intel.com> Precedence: bulk X-Mailing-List: linux-usb@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Unplugging a USB3.0 webcam from Etron hosts while streaming results in errors like this: [ 2.646387] xhci_hcd 0000:03:00.0: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 18 comp_code 13 [ 2.646446] xhci_hcd 0000:03:00.0: Looking for event-dma 000000002fdf8630 trb-start 000000002fdf8640 trb-end 000000002fdf8650 [ 2.646560] xhci_hcd 0000:03:00.0: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 18 comp_code 13 [ 2.646568] xhci_hcd 0000:03:00.0: Looking for event-dma 000000002fdf8660 trb-start 000000002fdf8670 trb-end 000000002fdf8670 Etron xHC generates two transfer events for the TRB if an error is detected while processing the last TRB of an isoc TD. The first event can be any sort of error (like USB Transaction or Babble Detected, etc), and the final event is Success. The xHCI driver will handle the TD after the first event and remove it from its internal list, and then print an "Transfer event TRB DMA ptr not part of current TD" error message after the final event. Commit 5372c65e1311 ("xhci: process isoc TD properly when there was a transaction error mid TD.") is designed to address isoc transaction errors, but unfortunately it doesn't account for this scenario. This issue is similar to the XHCI_SPURIOUS_SUCCESS case where a success event follows a 'short transfer' event, but the TD the event points to is already given back. Expand the spurious success 'short transfer' event handling to cover the spurious success after error on Etron hosts. Kuangyi Chiang reported this issue and submitted a different solution based on using error_mid_td. This commit message is mostly taken from that patch. Reported-by: Kuangyi Chiang Closes: https://lore.kernel.org/linux-usb/20241028025337.6372-6-ki.chiang65@gmail.com/ Tested-by: Kuangyi Chiang Tested-by: Michal Pecio Signed-off-by: Mathias Nyman --- drivers/usb/host/xhci-ring.c | 38 ++++++++++++++++++++++++------------ drivers/usb/host/xhci.h | 2 +- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 2df94ed3152c..0f8acbb9cd21 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2611,6 +2611,22 @@ static int handle_transferless_tx_event(struct xhci_hcd *xhci, struct xhci_virt_ return 0; } +static bool xhci_spurious_success_tx_event(struct xhci_hcd *xhci, + struct xhci_ring *ring) +{ + switch (ring->old_trb_comp_code) { + case COMP_SHORT_PACKET: + return xhci->quirks & XHCI_SPURIOUS_SUCCESS; + case COMP_USB_TRANSACTION_ERROR: + case COMP_BABBLE_DETECTED_ERROR: + case COMP_ISOCH_BUFFER_OVERRUN: + return xhci->quirks & XHCI_ETRON_HOST && + ring->type == TYPE_ISOC; + default: + return false; + } +} + /* * If this function returns an error condition, it means it got a Transfer * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address. @@ -2665,8 +2681,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, case COMP_SUCCESS: if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { trb_comp_code = COMP_SHORT_PACKET; - xhci_dbg(xhci, "Successful completion on short TX for slot %u ep %u with last td short %d\n", - slot_id, ep_index, ep_ring->last_td_was_short); + xhci_dbg(xhci, "Successful completion on short TX for slot %u ep %u with last td comp code %d\n", + slot_id, ep_index, ep_ring->old_trb_comp_code); } break; case COMP_SHORT_PACKET: @@ -2817,7 +2833,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, if (trb_comp_code != COMP_STOPPED && trb_comp_code != COMP_STOPPED_LENGTH_INVALID && !ring_xrun_event && - !ep_ring->last_td_was_short) { + !xhci_spurious_success_tx_event(xhci, ep_ring)) { xhci_warn(xhci, "Event TRB for slot %u ep %u with no TDs queued\n", slot_id, ep_index); } @@ -2882,11 +2898,12 @@ static int handle_tx_event(struct xhci_hcd *xhci, /* * Some hosts give a spurious success event after a short - * transfer. Ignore it. + * transfer or error on last TRB. Ignore it. */ - if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) && - ep_ring->last_td_was_short) { - ep_ring->last_td_was_short = false; + if (xhci_spurious_success_tx_event(xhci, ep_ring)) { + xhci_dbg(xhci, "Spurious event dma %pad, comp_code %u after %u\n", + &ep_trb_dma, trb_comp_code, ep_ring->old_trb_comp_code); + ep_ring->old_trb_comp_code = trb_comp_code; return 0; } @@ -2909,15 +2926,12 @@ static int handle_tx_event(struct xhci_hcd *xhci, */ } while (ep->skip); + ep_ring->old_trb_comp_code = trb_comp_code; + /* Get out if a TD was queued at enqueue after the xrun occurred */ if (ring_xrun_event) return 0; - if (trb_comp_code == COMP_SHORT_PACKET) - ep_ring->last_td_was_short = true; - else - ep_ring->last_td_was_short = false; - ep_trb = &ep_seg->trbs[(ep_trb_dma - ep_seg->dma) / sizeof(*ep_trb)]; trace_xhci_handle_transfer(ep_ring, (struct xhci_generic_trb *) ep_trb, ep_trb_dma); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index d9d7cd1906f3..6c00062a9acc 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1375,7 +1375,7 @@ struct xhci_ring { unsigned int num_trbs_free; /* used only by xhci DbC */ unsigned int bounce_buf_len; enum xhci_ring_type type; - bool last_td_was_short; + u32 old_trb_comp_code; struct radix_tree_root *trb_address_map; };