Skip to content

rutabaga_gfx/cross_domain: handle CMD_WRITE on Eventfd items#664

Open
aford173 wants to merge 1 commit intocontainers:mainfrom
aford173:fix/cross-domain-eventfd-cmd-write
Open

rutabaga_gfx/cross_domain: handle CMD_WRITE on Eventfd items#664
aford173 wants to merge 1 commit intocontainers:mainfrom
aford173:fix/cross-domain-eventfd-cmd-write

Conversation

@aford173
Copy link
Copy Markdown

@aford173 aford173 commented May 5, 2026

The cross_domain write handler only matched
CrossDomainItem::WaylandWritePipe, falling into the catch-all for every other item type after the unconditional remove() at the top of the function had already dropped the entry from the table. PipeWire (and other clients that share host-created eventfds via SCM_RIGHTS for per-period wakeups) sends CMD_WRITE on those eventfd identifiers — the first such write returns InvalidCrossDomainItemType after removing the item, and every subsequent write on the same identifier returns InvalidCrossDomainItemId, masquerading on the guest as the opaque VIRTIO_GPU_RESP_ERR_UNSPEC (0x1200).

Reproduced inside a libkrun guest on x86_64 by routing PipeWire's ALSA-shim audio through a host PipeWire daemon. With a paired BT speaker as the sink, speaker-test -D pipewire -c2 -t wav -l 1 produces, per stream, ~10 entries of:

[    0.682819] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
[    0.723762] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
[    0.767615] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
[    0.807779] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
[    0.852469] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
[    0.896552] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
[    0.936504] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
[    0.980567] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
[    1.024476] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
[    1.064636] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)

with audio still playing — PipeWire has socket-based fallback timing that doesn't depend on eventfd ack, so the failures are cosmetic for playback. They are not cosmetic for clients that strictly require the eventfd handshake (PipeWire's ALSA shim under heavier loads, and the buffer-pool wakeup path used by V4L2 capture streams).

Add an Eventfd arm that mirrors the WaylandWritePipe semantics: write_volatile performs the 8-byte counter increment, and the item is re-inserted into the table unless the guest signaled hang_up.

Verified post-fix: zero CMD_WRITE failures, zero 0x1200 entries in guest dmesg, audio playback unchanged. Camera capture (gst-launch pipewiresrc → MJPEG) also exercises this path for buffer-pool wakeups and runs cleanly with valid 98%-non-zero JPEG frames.

@slp
Copy link
Copy Markdown
Collaborator

slp commented May 5, 2026

Nice one, thanks. Please address the formatting issue so we can merge it.

The cross_domain `write` handler only matched
`CrossDomainItem::WaylandWritePipe`, falling into the catch-all for
every other item type after the unconditional `remove()` at the top of
the function had already dropped the entry from the table. PipeWire
(and other clients that share host-created eventfds via SCM_RIGHTS for
per-period wakeups) sends CMD_WRITE on those eventfd identifiers — the
first such write returns InvalidCrossDomainItemType *after* removing
the item, and every subsequent write on the same identifier returns
InvalidCrossDomainItemId, masquerading on the guest as the opaque
VIRTIO_GPU_RESP_ERR_UNSPEC (0x1200).

Reproduced inside a libkrun guest on x86_64 by routing PipeWire's
ALSA-shim audio through a host PipeWire daemon. With a paired BT
speaker as the sink, `speaker-test -D pipewire -c2 -t wav -l 1`
produces, per stream, ~10 entries of:

    [    0.682819] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
    [    0.723762] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
    [    0.767615] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
    [    0.807779] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
    [    0.852469] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
    [    0.896552] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
    [    0.936504] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
    [    0.980567] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
    [    1.024476] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)
    [    1.064636] [drm:virtio_gpu_dequeue_ctrl_func] *ERROR* response 0x1200 (command 0x207)

with audio still playing — PipeWire has socket-based fallback timing
that doesn't depend on eventfd ack, so the failures are cosmetic for
playback. They are not cosmetic for clients that strictly require the
eventfd handshake (PipeWire's ALSA shim under heavier loads, and the
buffer-pool wakeup path used by V4L2 capture streams).

Add an Eventfd arm that mirrors the WaylandWritePipe semantics:
`write_volatile` performs the 8-byte counter increment, and the item
is re-inserted into the table unless the guest signaled `hang_up`.

Verified post-fix: zero CMD_WRITE failures, zero `0x1200` entries in
guest dmesg, audio playback unchanged. Camera capture (gst-launch
pipewiresrc → MJPEG) also exercises this path for buffer-pool wakeups
and runs cleanly with valid 98%-non-zero JPEG frames.

Signed-off-by: Adam Ford <adam.ford@anodize.com>
@aford173 aford173 force-pushed the fix/cross-domain-eventfd-cmd-write branch from e0c75f9 to 8c6eac5 Compare May 5, 2026 17:06
@aford173
Copy link
Copy Markdown
Author

aford173 commented May 5, 2026

@slp - The formatting has changed. Let me know if you want any other changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants