Page MenuHomeFreeBSD

bhyve: Keep the xhci event ring's fill count right when it is nearly full
Needs ReviewPublic

Authored by wanpengqian_gmail.com on Thu, Oct 15, 5:01 AM.
Tags
None
Referenced Files
F176063665: D60739.diff
Thu, Oct 15, 6:44 PM
F176061493: D60739.id.diff
Thu, Oct 15, 6:08 PM
F176058836: D60739.diff
Thu, Oct 15, 5:33 PM
F176058797: D60739.diff
Thu, Oct 15, 5:32 PM
F176046035: D60739.diff
Thu, Oct 15, 2:56 PM
F176045893: D60739.id189952.diff
Thu, Oct 15, 2:55 PM
F176034823: D60739.id189952.diff
Thu, Oct 15, 12:17 PM
F176033546: D60739.diff
Thu, Oct 15, 12:01 PM
Subscribers

Details

Reviewers
markj
Group Reviewers
bhyve
Summary

With er_events_cnt == er_size - 1, pci_xhci_insert_event() decided
whether the ring is full from the cycle bit of the TRB at the enqueue
slot. That TRB is from the previous lap (or zero on the first one), so
its cycle bit never matches the producer's and the event went into the
last free slot without being counted: the count then said one less than
the ring held, and the next event overwrote a TRB the guest had not
consumed yet. When the Event Ring Full Error was written at the end of
the segment, the producer cycle state was not toggled either.

Follow xHCI 4.9.4: keep one slot for the Event Ring Full Error, post it
there when the ring is otherwise full, and toggle the cycle state on a
wrap as for any other event.

Together with the unlocked hci_intr path (D60432) this showed up as
Windows 10 stopping the tablet's endpoint and resetting the controller
under fast mouse input over VNC/RDP.

Signed-off-by: Wanpeng Qian <wanpengqian@gmail.com>
Sponsored by: keelos.dev

Test Plan

Built with and without WITH_BHYVE_SNAPSHOT (no new warnings).

The same change has been in keelOS's bhyve since 2026-10-07, together with the hci_intr locking of D60432, where Windows 10/11, macOS and Linux guests drive the tablet and keyboard through this model over VNC/RDP: the endpoint-stop/HCRST loop Windows 10 went into under fast mouse input (tablet reports arriving faster than the guest drains the 256-entry event ring) does not recur there. With the controller's trace in that build, when the ring does fill the guest sees one Event Ring Full Error TRB, consumes it, and the ring carries on with the right cycle state after the wrap.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 78235
Build 75118: arc lint + arc unit