[PATCH 0/4] usb: gadget: dummy_hcd: fixes found while testing virtio-usb

Igor Skalkin posted 4 patches 1 month, 3 weeks ago
There is a newer version of this series
drivers/usb/gadget/udc/dummy_hcd.c | 72 +++++++++++++-----------------
1 file changed, 30 insertions(+), 42 deletions(-)
[PATCH 0/4] usb: gadget: dummy_hcd: fixes found while testing virtio-usb
Posted by Igor Skalkin 1 month, 3 weeks ago
This series fixes several bugs in dummy_hcd found while testing a
virtio-usb transport under a type-1 hypervisor, using two Linux VMs:

         host VM                            guest VM
    +----------------+                  +----------------+
    |    testusb     |                  |     g_zero     |
    +-------|--------+                  +--------^-------+
            v                                     |
    +----------------+                  +----------------+
    |   dummy_hcd    |                  |   dummy_hcd    |
    |  (host port)   |<---- virtio ---->| (virtual UDC)  |
    +----------------+                  +----------------+

Most of the failures we hit were in our own virtio-usb code, but
after switching the testing from HighSpeed to SuperSpeed a few
issues traced back to dummy_hcd itself:

 - patch 1 fixes an incorrect SuperSpeed ep0 maxpacket value
 - patch 2 fixes a false -EOVERFLOW reported for legitimate bounded
   IN completions
 - patch 3 fixes broken SG transfer handling when a URB is serviced
   across multiple chunks
 - patch 4 sets no_sg_constraint, since dummy_hcd has no hardware DMA
   alignment requirement and should not reject SG URBs based on
   maxpacket alignment

Igor Skalkin (4):
  usb: gadget: dummy_hcd: fix SuperSpeed ep0 maxpacket
  usb: gadget: dummy_hcd: fix false overflow on bounded IN
  usb: gadget: dummy_hcd: fix SG transfer handling across chunks
  usb: gadget: dummy_hcd: set no_sg_constraint on the host controller

 drivers/usb/gadget/udc/dummy_hcd.c | 72 +++++++++++++-----------------
 1 file changed, 30 insertions(+), 42 deletions(-)

-- 
2.49.0
[PATCH v2 0/2] usb: gadget: dummy_hcd: fixes found while testing virtio-usb
Posted by Igor Skalkin 1 month, 2 weeks ago
This is v2 of the dummy_hcd fixes found while testing our upcoming
virtio-usb transport driver (patches for that will follow separately).

Changes since v1:

 - Patch 1 (ep0 maxpacket) is unchanged; carrying forward Alan
   Stern's Acked-by.

 - Patch 2 (false overflow on bounded IN) is dropped.  Alan Stern
   pointed out the fix was wrong: an IN short packet where the
   device has more data queued than the host's buffer can hold is a
   genuine overflow, not a normal bounded completion.  Agreed, and
   there's no replacement fix queued for this report.

 - Patch 3 (SG transfer handling across chunks) is dropped from this
   version.  Alan Stern confirmed the underlying issue and suggested
   a simpler fix (resync the sg_miter with sg_miter_skip() after each
   consumed chunk instead of restarting and re-walking from
   urb->actual_length on every call).  The original failure was
   reliably reproducible against an earlier, debug-instrumented
   version of our (not yet posted) virtio-usb transport driver, but
   is not currently reproducing against the current version of that
   driver, which makes it hard to verify a replacement fix with any
   confidence.  I'd rather confirm a fix against a real reproduction
   before resending than resend an unverified change, so this patch
   is held back for now and will follow separately once reproduced
   again.

 - Patch 4 (no_sg_constraint) is reworked per Alan Stern's review:
   instead of unconditionally relaxing the SG alignment constraint,
   it is now only relaxed on the SuperSpeed bus, preserving the
   EHCI-style alignment emulation on the HighSpeed bus.

Igor Skalkin (2):
  usb: gadget: dummy_hcd: fix SuperSpeed ep0 maxpacket
  usb: gadget: dummy_hcd: set no_sg_constraint only on the SuperSpeed
    bus

 drivers/usb/gadget/udc/dummy_hcd.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

-- 
2.49.0
[PATCH v2 1/2] usb: gadget: dummy_hcd: fix SuperSpeed ep0 maxpacket
Posted by Igor Skalkin 1 month, 2 weeks ago
For USB_SPEED_SUPER, dummy_hcd sets ep0 maxpacket to 9.
That is incorrect for SuperSpeed ep0 and breaks short packet handling
in control transfer tests.

Set ep0 maxpacket to 512 for SuperSpeed.

Fixes: 1cd8fd2887e1 ("usb: gadget: dummy_hcd: add SuperSpeed support")
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Igor Skalkin <igor.skalkin@oss.qualcomm.com>
---
 drivers/usb/gadget/udc/dummy_hcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index f47903461ed5..29f671c7b319 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -896,7 +896,7 @@ static int dummy_set_selfpowered(struct usb_gadget *_gadget, int value)
 static void dummy_udc_update_ep0(struct dummy *dum)
 {
 	if (dum->gadget.speed == USB_SPEED_SUPER)
-		dum->ep[0].ep.maxpacket = 9;
+		dum->ep[0].ep.maxpacket = 512;
 	else
 		dum->ep[0].ep.maxpacket = 64;
 }
-- 
2.49.0
[PATCH v2 2/2] usb: gadget: dummy_hcd: set no_sg_constraint only on the SuperSpeed bus
Posted by Igor Skalkin 1 month, 2 weeks ago
dummy_hcd registers two separate root hubs/buses: a HighSpeed one
emulating an EHCI-class controller, and a SuperSpeed one emulating an
xHCI-class controller.  usb_submit_urb() rejects SG URBs whose
non-final segments are not a multiple of the endpoint maxpacket size,
unless the bus has no_sg_constraint set.

For SuperSpeed bulk endpoints maxpacket is 1024 bytes; usbtest
generates SG lists with varying segment sizes (e.g. 512 bytes) that
are valid transfers but not maxpacket-aligned, causing usb_submit_urb
to return -EINVAL before the URB reaches the host controller.

xHCI-class controllers have no such DMA alignment requirement, so set
no_sg_constraint on the SS bus to match.  Leave the HS bus unchanged:
EHCI-class controllers do have this requirement in hardware, and
dummy_hcd's HS roothub is meant to emulate that behaviour, so the
constraint should stay enforced there.

Suggested-by: Alan Stern <stern@rowland.harvard.edu>
Assisted-by: OpenCode:claude-sonnet-5
Signed-off-by: Igor Skalkin <igor.skalkin@oss.qualcomm.com>
---
 drivers/usb/gadget/udc/dummy_hcd.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index 29f671c7b319..0ae600159478 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -2578,6 +2578,15 @@ static int dummy_setup(struct usb_hcd *hcd)
 		dum->ss_hcd->dum = dum;
 		hcd->speed = HCD_USB3;
 		hcd->self.root_hub->speed = USB_SPEED_SUPER;
+
+		/*
+		 * xHCI-class SuperSpeed controllers have no maxpacket
+		 * alignment requirement for non-final SG segments.  Only
+		 * relax the constraint on the SS bus; the HS bus keeps
+		 * emulating the alignment requirement of EHCI-class
+		 * controllers.
+		 */
+		hcd->self.no_sg_constraint = 1;
 	}
 	return 0;
 }
-- 
2.49.0
Re: [PATCH v2 2/2] usb: gadget: dummy_hcd: set no_sg_constraint only on the SuperSpeed bus
Posted by Alan Stern 1 month, 2 weeks ago
On Wed, Aug 12, 2026 at 10:19:10AM +0200, Igor Skalkin wrote:
> dummy_hcd registers two separate root hubs/buses: a HighSpeed one
> emulating an EHCI-class controller, and a SuperSpeed one emulating an
> xHCI-class controller.  usb_submit_urb() rejects SG URBs whose
> non-final segments are not a multiple of the endpoint maxpacket size,
> unless the bus has no_sg_constraint set.
> 
> For SuperSpeed bulk endpoints maxpacket is 1024 bytes; usbtest
> generates SG lists with varying segment sizes (e.g. 512 bytes) that
> are valid transfers but not maxpacket-aligned, causing usb_submit_urb
> to return -EINVAL before the URB reaches the host controller.
> 
> xHCI-class controllers have no such DMA alignment requirement, so set
> no_sg_constraint on the SS bus to match.  Leave the HS bus unchanged:
> EHCI-class controllers do have this requirement in hardware, and
> dummy_hcd's HS roothub is meant to emulate that behaviour, so the
> constraint should stay enforced there.
> 
> Suggested-by: Alan Stern <stern@rowland.harvard.edu>
> Assisted-by: OpenCode:claude-sonnet-5
> Signed-off-by: Igor Skalkin <igor.skalkin@oss.qualcomm.com>
> ---

Acked-by: Alan Stern <stern@rowland.harvard.edu>

>  drivers/usb/gadget/udc/dummy_hcd.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
> index 29f671c7b319..0ae600159478 100644
> --- a/drivers/usb/gadget/udc/dummy_hcd.c
> +++ b/drivers/usb/gadget/udc/dummy_hcd.c
> @@ -2578,6 +2578,15 @@ static int dummy_setup(struct usb_hcd *hcd)
>  		dum->ss_hcd->dum = dum;
>  		hcd->speed = HCD_USB3;
>  		hcd->self.root_hub->speed = USB_SPEED_SUPER;
> +
> +		/*
> +		 * xHCI-class SuperSpeed controllers have no maxpacket
> +		 * alignment requirement for non-final SG segments.  Only
> +		 * relax the constraint on the SS bus; the HS bus keeps
> +		 * emulating the alignment requirement of EHCI-class
> +		 * controllers.
> +		 */
> +		hcd->self.no_sg_constraint = 1;
>  	}
>  	return 0;
>  }
> -- 
> 2.49.0
>