56 lines
2.2 KiB
Diff
56 lines
2.2 KiB
Diff
From ed08be11433715381e5a67569d2eadd9264523e0 Mon Sep 17 00:00:00 2001
|
|
From: Xu Yang <xu.yang_2@nxp.com>
|
|
Date: Wed, 6 Aug 2025 16:39:55 +0800
|
|
Subject: usb: core: hcd: fix accessing unmapped memory in
|
|
SINGLE_STEP_SET_FEATURE test
|
|
|
|
The USB core will unmap urb->transfer_dma after SETUP stage completes.
|
|
Then the USB controller will access unmapped memory when it received
|
|
device descriptor. If iommu is equipped, the entire test can't be
|
|
completed due to the memory accessing is blocked.
|
|
|
|
Fix it by calling map_urb_for_dma() again for IN stage. To reduce
|
|
redundant map for urb->transfer_buffer, this will also set
|
|
URB_NO_TRANSFER_DMA_MAP flag before first map_urb_for_dma() to skip
|
|
dma map for urb->transfer_buffer and clear URB_NO_TRANSFER_DMA_MAP
|
|
flag before second map_urb_for_dma().
|
|
|
|
Fixes: 216e0e563d81 ("usb: core: hcd: use map_urb_for_dma for single step set feature urb")
|
|
Cc: stable <stable@kernel.org>
|
|
Reviewed-by: Jun Li <jun.li@nxp.com>
|
|
Signed-off-by: Xu Yang <xu.yang_2@nxp.com>
|
|
Acked-by: Alan Stern <stern@rowland.harvard.edu>
|
|
Link: https://lore.kernel.org/r/20250806083955.3325299-1-xu.yang_2@nxp.com
|
|
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
---
|
|
drivers/usb/core/hcd.c | 8 +++++++-
|
|
1 file changed, 7 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/usb/core/hcd.c
|
|
+++ b/drivers/usb/core/hcd.c
|
|
@@ -2153,7 +2153,7 @@ static struct urb *request_single_step_s
|
|
urb->complete = usb_ehset_completion;
|
|
urb->status = -EINPROGRESS;
|
|
urb->actual_length = 0;
|
|
- urb->transfer_flags = URB_DIR_IN;
|
|
+ urb->transfer_flags = URB_DIR_IN | URB_NO_TRANSFER_DMA_MAP;
|
|
usb_get_urb(urb);
|
|
atomic_inc(&urb->use_count);
|
|
atomic_inc(&urb->dev->urbnum);
|
|
@@ -2217,9 +2217,15 @@ int ehset_single_step_set_feature(struct
|
|
|
|
/* Complete remaining DATA and STATUS stages using the same URB */
|
|
urb->status = -EINPROGRESS;
|
|
+ urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP;
|
|
usb_get_urb(urb);
|
|
atomic_inc(&urb->use_count);
|
|
atomic_inc(&urb->dev->urbnum);
|
|
+ if (map_urb_for_dma(hcd, urb, GFP_KERNEL)) {
|
|
+ usb_put_urb(urb);
|
|
+ goto out1;
|
|
+ }
|
|
+
|
|
retval = hcd->driver->submit_single_step_set_feature(hcd, urb, 0);
|
|
if (!retval && !wait_for_completion_timeout(&done,
|
|
msecs_to_jiffies(2000))) {
|