Conversation
USB 3.2 Gen 2 (10 Gbps) devices were reported by libusb at a speed the usb-redir protocol cannot express, so QEMU attached them at full speed while forwarding their SuperSpeed descriptors. Guests rejected them with "Invalid ep0 maxpacket: 9" and "unable to enumerate USB device". - present LIBUSB_SPEED_SUPER_PLUS as SuperSpeed to the guest - apply QEMU's bMaxPacketSize0 fix-up whenever the device is presented at a non-SuperSpeed link - unmount the host volumes of a mass storage device before redirecting it - reconnect a saved device when it appears while the virtual machine runs Resolves utmapp#7530 Assisted-by: OpenCode:deepseek-v4.1-flash
Contributor
|
If you don't have the entitlement you can still test with sudo (QEMU command line only) or with SIP off (get entitlement without needing a profile). Either way we do not accept untested PR as per CONTRIBUTING.md. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
QEMU USB passthrough fails for USB 3.2 Gen 2 (10 Gbps) devices — the external SSDs and NVMe enclosures that most users hit in #7530 — with the guest rejecting the device as
Invalid ep0 maxpacket: 9. This change fixes the speed negotiation that causes it, unmounts the host volumes of a mass storage device before it is redirected so macOS never loses a mounted disk, and reconnects a saved device automatically when it appears again (for example after a firmware update restarts it).Resolves #7530, #2728, #3975, #3995, #5154, #6291, #6721 and #6764.
Root cause
UTM's QEMU passthrough does not hand the device to QEMU directly: it uses SPICE usb-redir with libusb running in the app process (CocoaSpice/usbredirhost). The entitlements are already in place (
com.apple.security.device.usb,com.apple.vm.device-access), so macOS can release the device from its kernel drivers; the failure is in the speed negotiation:LIBUSB_SPEED_SUPER_PLUS(kUSBDeviceSpeedSuperPlus).usbredirhost_send_device_connect(), so it sendsusb_redir_speed_unknown.hw/usb/redirect.c) while still forwarding the device's SuperSpeed descriptor, whosebMaxPacketSize0is 9 (the SuperSpeed encoding, 512 bytes).Invalid ep0 maxpacket: 9, thenunable to enumerate USB device.This matches the reports: USB 2.0 and USB 3.0 (5 Gbps) devices keep working, 10 Gbps SSDs and NVMe enclosures fail, and a USB 2.0 hub "fixes" it by forcing the host device to enumerate at high speed. The usb-redir protocol has no speed above SuperSpeed, so these devices are presented at 5 Gbps instead of 10 Gbps.
Changes
patches/usbredir-0.14.0.patch(new): presentLIBUSB_SPEED_SUPER_PLUSdevices as SuperSpeed, so the guest gets a link and descriptors that match.patches/qemu-10.0.12-utm.patch: the existingbMaxPacketSize0fix-up only ran when QEMU had marked the device as SuperSpeed. Run it whenever the device is presented at a non-SuperSpeed link, which also covers speeds libusb cannot report (for example 20 GbpskUSBDeviceSpeedSuperPlusBy2devices are reported as unknown speed).Services/UTMUSBDeviceUnmount.swift(new, macOS): before redirecting a device, unmount its mounted volumes with DiskArbitration so the capture does not tear the storage driver away from macOS with volumes still in use. If a volume is busy the connection is refused with a clear message instead of risking data loss. The helper also maps the "device still in use" errors from libusb to a message that tells the user what to do.VMDisplayQemuDisplayController): a device in the saved auto-connect list is connected again without prompting when it is attached while the virtual machine is running. This covers devices that reset themselves, for example during a firmware update, and come back a few seconds later.Related issues
These issues are less specific or describe a different problem and are only possibly related: #3322, #3375, #4167, #5664, #7288.
Testing
I confirmed the report with a synthetic test: without access to the
com.apple.vm.device-accessentitlement a local build cannot capture the physical device (on macOS 27 the device is markedNeedsDeviceAccessEntitlement = Yes, so even root cannot), which makes a hardware test impossible. The tests were run on macOS 27.0, MacBook Air M4 (Apple Silicon).The reporter's ASM2362 enclosure (
174c:2362) was used to confirm the reported values:speed=5 (LIBUSB_SPEED_SUPER_PLUS),bcdUSB=0x0320,bMaxPacketSize0=9USBSpeed=5,UsbLinkSpeed=10000000000SUPER_PLUSfalls through to "unknown"); the patched one handles speeds below 6 and mapsSUPER_PLUStosuper.End-to-end in QEMU, with a synthetic usb-redir device that mirrors the SSD descriptors (
bcdUSB 0x0320,bMaxPacketSize0 = 9, mass storage interface) and an Alpine Linux guest on the serial console:unknownspeed)new high-speed USB device,Invalid ep0 maxpacket: 9,unable to enumerate USB devicesuperspeed)new SuperSpeed USB device number 2,New USB device found, idVendor=174c, idProduct=2362unknownspeed)new high-speed USB device, descriptor accepted (the fix-up rewritesbMaxPacketSize0to 64)The physical device itself could not be captured on this machine (see above), and the automatic reconnection path also needs a device that resets while a virtual machine is running, which was not exercised here.
Testing: Tested by the author on macOS 27.0, MacBook Air M4 (Apple Silicon), assisted by the AI agent (DeepSeek V4.1 Flash via OpenCode) which set up and ran the diagnostics and the QEMU tests under the author's supervision. The author acknowledges that this change has been tested and/or reviewed by a human in accordance with UTM's AI contribution guidelines.