From: Greg Kroah-Hartman Date: Mon, 13 Jul 2026 13:15:07 +0000 (+0200) Subject: 5.10-stable patches X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9ce1cadcdcf3936c20a22ee7cb923c67784465ee;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: usb-xhci-fix-sleep-in-atomic-context-in-xhci_free_streams.patch --- diff --git a/queue-5.10/series b/queue-5.10/series index 7621daaac5..9791717b11 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -60,3 +60,4 @@ alsa-usb-audio-update-us-16x08-eq-comp-shadow-state-after-successful-writes.patc bluetooth-btusb-add-usb-id-2c4e-0128-for-mercusys-ma60xnb.patch bluetooth-btusb-fix-use-after-free-on-registration-failure.patch binder-fix-uaf-in-binder_thread_release.patch +usb-xhci-fix-sleep-in-atomic-context-in-xhci_free_streams.patch diff --git a/queue-5.10/usb-xhci-fix-sleep-in-atomic-context-in-xhci_free_streams.patch b/queue-5.10/usb-xhci-fix-sleep-in-atomic-context-in-xhci_free_streams.patch new file mode 100644 index 0000000000..28b41b4476 --- /dev/null +++ b/queue-5.10/usb-xhci-fix-sleep-in-atomic-context-in-xhci_free_streams.patch @@ -0,0 +1,86 @@ +From 42c37c4b75d38b51d84f31a8e29427f5e06a7c2a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E8=83=A1=E8=BF=9E=E5=8B=A4?= +Date: Fri, 3 Jul 2026 17:40:33 +0300 +Subject: usb: xhci: Fix sleep in atomic context in xhci_free_streams() + +From: 胡连勤 + +commit 42c37c4b75d38b51d84f31a8e29427f5e06a7c2a upstream. + +When a USB device with active stream endpoints is disconnected, +xhci_free_streams() is called from the hub_event workqueue to +free the stream resources. It calls xhci_free_stream_info() +while holding xhci->lock with irqs disabled. + +xhci_free_stream_info() invokes xhci_free_stream_ctx(), which +calls dma_free_coherent() for large stream context arrays. + +dma_free_coherent() can sleep (e.g. via vunmap), triggering +a BUG when called from atomic context. + +Call trace: + dma_free_attrs+0x174/0x220 + xhci_free_stream_info+0xd0/0x11c + xhci_free_streams+0x278/0x37c + usb_free_streams+0x98/0xc0 + usb_unbind_interface+0x1b8/0x2f8 + device_release_driver_internal+0x1d4/0x2cc + device_release_driver+0x18/0x28 + bus_remove_device+0x160/0x1a4 + device_del+0x1ec/0x350 + usb_disable_device+0x98/0x214 + usb_disconnect+0xf0/0x35c + hub_event+0xab4/0x19ec + process_one_work+0x278/0x63c + +Fix this by saving the stream_info pointers and clearing the +ep references under the lock, then calling xhci_free_stream_info() +outside the lock where sleeping is allowed. + +Fixes: 8df75f42f8e6 ("USB: xhci: Add memory allocation for USB3 bulk streams.") +Cc: stable +Signed-off-by: Lianqin Hu +Signed-off-by: Mathias Nyman +Link: https://patch.msgid.link/20260703144033.483286-3-mathias.nyman@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/host/xhci.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -3636,6 +3636,7 @@ static int xhci_free_streams(struct usb_ + struct xhci_virt_device *vdev; + struct xhci_command *command; + struct xhci_input_control_ctx *ctrl_ctx; ++ struct xhci_stream_info *stream_info[EP_CTX_PER_DEV]; + unsigned int ep_index; + unsigned long flags; + u32 changed_ep_bitmask; +@@ -3696,10 +3697,15 @@ static int xhci_free_streams(struct usb_ + if (ret < 0) + return ret; + ++ /* ++ * dma_free_coherent() called by xhci_free_stream_info() may sleep, ++ * so save stream_info pointers and clear references under lock, ++ * then free the memory outside lock. ++ */ + spin_lock_irqsave(&xhci->lock, flags); + for (i = 0; i < num_eps; i++) { + ep_index = xhci_get_endpoint_index(&eps[i]->desc); +- xhci_free_stream_info(xhci, vdev->eps[ep_index].stream_info); ++ stream_info[i] = vdev->eps[ep_index].stream_info; + vdev->eps[ep_index].stream_info = NULL; + /* FIXME Unset maxPstreams in endpoint context and + * update deq ptr to point to normal string ring. +@@ -3709,6 +3715,9 @@ static int xhci_free_streams(struct usb_ + } + spin_unlock_irqrestore(&xhci->lock, flags); + ++ for (i = 0; i < num_eps; i++) ++ xhci_free_stream_info(xhci, stream_info[i]); ++ + return 0; + } +