Skip to content

vz(usbip): serve devlist and import, attach in guest via vhci-hcd - #5786

Open
PlatyPew wants to merge 16 commits into
lima-vm:masterfrom
pwnpad:feat/usb-passthrough-pr-2
Open

PlatyPew wants to merge 16 commits into
lima-vm:masterfrom
pwnpad:feat/usb-passthrough-pr-2

Conversation

@PlatyPew

@PlatyPew PlatyPew commented Nov 10, 2026 •

Copy link
Copy Markdown

What This PR Changes

Part 2 of 6, on top of #5785. Only the last 8 commits were added. It adds the USB/IP handshake on the host and the import step in the guest.

  • Host (server.go, protocol.go): answers OP_REQ_DEVLIST and OP_REQ_IMPORT through a Provider interface, which lists and opens devices.
    • A reimport of a busid that is already held ends the old session first, because a rebooted guest's old conn never gets EOF.
    • The handshake is bounded by 30 seconds.
  • Guest (attach_linux.go, vhci.go): dials the host on vsock port 2223 and hands the socket to vhci-hcd through sysfs.
    • On EBUSY it retries on the next free port, as usbip_attach.c does.
    • It waits up to 15 s for enumeration and releases the port on timeout.
  • lima-guestagent usbip attach|probe, so the guest needs no usbip userspace tools.

Linked Issue (Required in most cases)

Refs #4766

How I Tested This

Host: macOS 27.2

  • go test -race ./pkg/usbip/ (reimport of a held busid, handshake deadline, unplug, vhci attach and enumeration)
  • GOOS=linux go vet ./pkg/usbip/... ./cmd/lima-guestagent/...
  • golangci-lint on darwin and linux: 0 issues
  • Every commit builds and passes vet.

I tested end to end on hardware on the full stack in #5770.

AI Usage

Assisted-by: Claude Code (Claude Opus 5.5)

PlatyPew and others added 16 commits November 10, 2026 21:42
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
- Device hides the host USB backend, so URB handling stays
  OS-neutral.
- Relay control, bulk and interrupt URBs. Isochronous URBs fail with
  -ESHUTDOWN, which stops snd-usb resubmitting, unlike -EOPNOTSUPP.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
- One worker per endpoint and direction, so a pending IN does not
  hold up OUT. Endpoint 0 is one bidirectional pipe.
- Unlinking a started URB waits for the device call, so RET_SUBMIT
  always comes before RET_UNLINK.
- Cap queued URBs at 64 MiB per session. Each URB also costs a fixed
  4 KiB, so header floods hit the cap too.
- After the session ends, answer every pending URB before closing:
  vhci-hcd oopses on any giveback of a scatter-gather URB other than
  RET_SUBMIT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
- A reimport of a held busid ends the old session first: a rebooted
  guest's old conn never gets EOF, and vsock is per VM. Refuse the
  import if the old session outlives 10 s.
- Bound the handshake by 30 s, longer than the supersede wait it
  contains, so a silent conn does not linger.
- Call Provider.Unplugged before closing the device: Close frees the
  device for a new import, whose state Unplugged must not touch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
- On EBUSY another attach won the port, so try the next free one, as
  usbip_attach.c does.
- Release the port when enumeration times out, so no device stays half
  attached.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
- Dial vsock port 2223 with a raw blocking socket, as vhci-hcd takes
  the fd number.
- Wait up to 15 s for enumeration: one lost control read costs 5 s
  before the hub core retries.
- Probe closes before any request, so the host session ends at once.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
The guest needs no usbip userspace tools.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: PlatyPew <23520617+PlatyPew@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants