Re: Worth adding another graphics option to bhyve?

From: Mario Marietto <marietto2008_at_gmail.com>
Date: Tue, 28 Jul 2026 12:01:43 UTC
---> Worth adding another graphics option to bhyve?


This is a well-framed proposal, and the answer is yes — but the version
described has one process too many, and the actual cost center isn't the
GPU part at all. A few things I'd push on before it goes to the list.

*The hard part is vhost-user, not virtio-gpu.*

The proposal treats vhost-user as a given and spends its argument on the
GPU. That's backwards. bhyve has no vhost-user infrastructure today, and
the GPU is just the first consumer. The real work is:

   - *Memory sharing model.* vhost-user's SET_MEM_TABLE assumes the VMM can
   hand the backend an fd per memory region that the backend mmaps at a given
   offset. bhyve's guest memory lives behind /dev/vmm/<name> and is set up
   by vm_setup_memory() in libvmmapi. You either pass the vmm device fd and
   teach the backend a FreeBSD-specific mapping path (breaking protocol
   compatibility, which defeats the point of using vhost-user), or you
   restructure guest memory allocation so it's backed by shm objects that can
   be shared conventionally. That second option is a non-trivial change to
   something quite load-bearing.
   - *Capsicum.* bhyve enters capability mode after device init. Connecting
   a unix socket by pathname won't work post-cap_enter, so the socket has
   to be pre-opened or inherited, and SCM_RIGHTS handling has to be sane in
   cap mode. Solvable, but it constrains the CLI design (you'll want an
   fd-passing or pre-connect scheme, not just -s
   N,virtio-gpu,sock=/var/run/foo.sock opened lazily).
   - *Eventfd/irqfd equivalents.* vhost-user's kick/call fds are eventfds.
   FreeBSD has eventfd(2) now, but the backend's expectations around
   semantics and the POLLIN behaviour need verifying rather than assuming.

*Lead with the fact that this infrastructure isn't GPU-specific.* That's
the argument that actually gets it merged. Once bhyve speaks vhost-user,
you get virtio-fs (virtiofsd — which FreeBSD badly wants and which is a
much easier sell than graphics), vhost-user-blk, vhost-user-net, and a
general escape hatch for "we want this feature but not its dependencies in
base." Pitching it as "graphics" makes it a niche desktop feature. Pitching
it as "a generic out-of-process device backend mechanism, with GPU as the
demonstrator" makes it infrastructure. Same code, very different reception
on freebsd-virtualization@.

*Drop bhyve from the scanout path entirely.*

The proposal has the renderer send the framebuffer *back* to bhyve, and
bhyve then dispatches it out again over D-Bus to a display program. That
round trip exists in QEMU only because QEMU owns the UI — the window, the
input, the multi-head config. If bhyve deliberately owns no UI (and it
shouldn't), then bhyve has no business touching pixels. vhost-device-gpu
already has a D-Bus backend; let it talk to the compositor proxy directly.
bhyve keeps only the vhost-user control plane.

That collapses your design from "vhost-user support + a new display backend
+ an out-of-tree D-Bus proxy" to "vhost-user support." No D-Bus in base, no
awkward out-of-tree shim to justify, no second copy of the scanout, and the
whole licensing conversation about the display backend evaporates. It's a
strictly stronger proposal and it's the one I'd write.

The one thing that genuinely does have to come back to bhyve is *input* —
the external window owns the keyboard/mouse events and the guest's
xhci,tablet/virtio-input lives in bhyve. But that's a thin, well-understood
channel, not a reason to route the framebuffer through bhyve. Say so
explicitly in the proposal, because someone will ask.

*Tighten the security claim.*

"Secure" as stated will get pushback, and rightly. A vhost-user backend
mmaps *all* of guest memory and holds host GPU contexts — it's fully inside
the guest's TCB and has a large privileged surface. That's not more secure
than passthrough in the abstract. The honest and still very strong framing
is: *virglrenderer, Mesa, libepoxy and the entire GL stack stay out of the
base system binary and out of bhyve's address space.* The isolation benefit
is bhyve-side, not guest-side. State it that way and it's defensible.

*Scope limits worth stating up front, because they'll be discovered anyway:*

   - *Windows guests get nothing from this.* virtio-win ships a
   display-only virtio-gpu driver; there is no production 3D virtio-gpu guest
   driver for Windows. Anyone hoping this replaces passthrough for a Windows
   gaming or CUDA VM will be disappointed. Say so, or the thread will spend
   forty messages on it.
   - *FreeBSD guests get nothing initially either.* virtio_gpu(4) in the
   guest is a simple 2D/scanout driver with no virgl support. Day one, the
   only guest that benefits is Linux. That is a slightly awkward thing to say
   on a FreeBSD list, so get ahead of it: the guest-side work is a separate,
   later, and independently useful project.
   - *virglrenderer's GL passthrough is the legacy path.* The direction of
   travel is Venus (Vulkan) and gfxstream via rutabaga. Since
   vhost-device-gpu is built on rutabaga anyway, you inherit that — but
   note that rutabaga/vhost-device-gpu is Linux-shaped (memfd, eventfd,
   /dev/dri assumptions, vmm-sys-util coverage) and budget real time for
   the FreeBSD port of the *backend*, separately from the bhyve work. That
   port may well be larger than the bhyve side.

*On udmabuf's role:* be precise about where it actually buys you something.
It's the right primitive for blob resources with guest-memory backing (
VIRTGPU_BLOB_MEM_GUEST) — turning guest pages into something the host GPU
can texture from without a copy. It is *not* the mechanism for the 3D path,
where resources are already GPU-side. And on FreeBSD there's the extra
question of whether the fd your GSoC work produces is accepted by Mesa's
EGL_EXT_image_dma_buf_import through LinuxKPI's dma-buf, or only importable
by drm-kmod internals. If that end-to-end import isn't demonstrated yet,
demonstrating it is the single highest-value next step — it's the
load-bearing assumption under the whole proposal.

*Stage it.* Reviewers will ask "why not do the small thing first?", and you
want an answer ready:

   1. Native 2D virtio-gpu in bhyve (no vhost-user), rendering into the
   existing fbuf/VNC path, using udmabuf to avoid the copy. Small,
   self-contained, immediately useful — gets you guest-driven resize,
   multi-head, and a real EDID, all of which fbuf lacks. Also proves the
   udmabuf import path in isolation.
   2. Generic vhost-user support in bhyve, demonstrated with something
   boring and valuable (virtiofsd, or vhost-user-blk).
   3. vhost-user-gpu as a consumer of (2), with the backend ported
   separately.

Each stage is independently mergeable and independently useful. A single
3000-line "graphics rework" patch series against base has a much worse
survival rate than three of those.

*Two things to clear early, while they're cheap:* the vhost-user protocol
is documented in QEMU's docs/interop/vhost-user.rst (and the GPU
sub-protocol in vhost-user-gpu.rst) under QEMU's licensing. A clean-room
BSD implementation from a spec document is normally fine, but get a read
from core@ or the Foundation before you've written the code, not after. And
confirm what licensing constraint actually applies to a *port* in the tree
versus a *dependency* — the proposal assumes "no GPL in base" is the
binding constraint, and it is, but the D-Bus objection specifically
evaporates under the architecture change above, so don't design around a
constraint you've already engineered away.

Short version: worth doing, the idea is sound, and you're targeting a real
gap. Reframe it as generic out-of-process device backends with GPU as the
first user, take bhyve out of the pixel path, and stage it. That version
I'd expect to get a genuinely positive reception

Mario.

On Tue, Jul 28, 2026 at 1:48 PM yi zishun <zishun.yi.dev@gmail.com> wrote:

> Hi, hackers
>
> As the title suggests, briefly speaking, the proposed option is a
> combination of "vhost-user-gpu" and another display backend (for
> example, a D-Bus backend).
>
> Currently, bhyve has two main approaches for graphics rendering and
> display. One is fbuf+VNC for 2D graphics, and the other is GPU
> passthrough mainly for 3D workloads.  Both approaches have some
> obvious drawbacks. For example, fbuf is non-accelerated and VNC does
> not support zero-copy transfer, which makes fbuf+vnc have poor
> performance. GPU pci passthrough has excellent performance. But due to
> its exclusive use, the host cannot access the GPU anymore, not to
> mention supporting multiple VMs.
>
> I understand why these two designs exist: because bhyve is part of the
> base system, we cannot introduce GPL-licensed software or heavy
> graphics dependencies. So it is better, if there is an option, with a
> minimal implementation without any heavy dependence, but still can use
> modern graphics stack render and display capabilities, and can support
> multiple VM.
>
> My motivation for this proposal stems from my GSoC work on udmabuf.
> With the underlying zero-copy buffer sharing mechanism now in place, I
> wanted to explore how bhyve could natively utilize it to overcome the
> current performance bottlenecks in graphics rendering and displaying.
>
> For rendering, we can implement a device which presents itself to the
> guest kernel as a virtio-gpu device, but does not process any commands
> internally, the main virtqueue is handled by a separate userspace
> program, vhost-user-gpu. And the device communicates to vhost-user-gpu
> using vhost-user protocol. One implementation of vhost-user-gpu is
> rust-vmm's vhost-device-gpu, which processes the data and sends the
> rendered image back to QEMU/bhyve for display, and currently supports
> gtk and dbus backend as far as I know. We can then implement a new
> display backend, dbus backend, to dispatch the display to another
> program, too. But we can't introduce dbus into the base system, so
> maybe we need another out-of-tree small proxy to do the conversion.
>
> In conclusion, this approach dispatches the actual rendering and
> display tasks to two separate programs. bhyve only presents itself as
> a virtio-gpu device from the guest's point of view, and communicates
> to the two programs internally. This option is minimal, modular, and
> secure, leveraging the modern graphics stack to support multiple VMs
> without requiring dedicated hardware support, while providing the
> benefits of virtio-gpu.
>
> I would appreciate any feedback and discussion on the feasibility of
> this approach. If the idea is considered worthwhile, I am willing to
> invest the time and effort required to implement it.
>
> Best,
> Zishun Yi
>
>

-- 
Mario.