← Back · sub-plan of the NextBSD graphics plan, which covers the shipped amd64 stack (bochs, vboxvideo, Intel/AMD/Radeon, NVIDIA)

NextBSD arm64 KMS: six routes to /dev/dri/card0 in an ARM virtual machine

The amd64 graphics stack is done — BochsGraphics and VBoxGraphics ship, Intel and AMD bind on real hardware. arm64 has nothing, and neither does anyone else: two independent research sweeps of the FreeBSD mailing lists, Bugzilla, Phabricator, forums and GitHub found zero reports of /dev/dri in any arm64 FreeBSD VM, ever. This page lays out every route to changing that, with honest costs, so the choice can be made from evidence rather than from my summary of it.

2026-08-16. Written after a 3-agent research sweep (upstream drm-kmod virtio enablement; the ravynsoft fork; arm64 KMS state of the art). Citations to Linux v6.12/v6.16 drivers/gpu/drm, freebsd/drm-kmod 6.12-lts, freebsd/freebsd-src main and releng/15.1, FreeBSD Phabricator, Bugzilla, and QEMU/UTM/EDK2 sources. Two claims made earlier in this project are corrected below.

Settled 2026-08-16 The DRM stack builds on aarch64. nextbsd-kernel-modules#33 compiles drm.ko, ttm.ko, dmabuf.ko, radeonkms.ko and our drm_extra_helpers.ko for arm64 and verifies every resulting kext resolves against the arm64 kernel. That was an open question; it no longer is. What is missing is not the DRM core — it is a driver that binds something an ARM VM actually presents.

Decided 2026-08-16 This page is now the decision record — it shows how the route was chosen, not what is open. The outcome:

Two findings since have made Option E materially smaller than costed below: the LinuxKPI virtio shim needs no FreeBSD base change, and the entire Mesa/virgl userland already ships in ports. Both are in the execution plan.

Contents

  1. What is already measured
  2. The decisions to make
  3. Where the work belongs: three layers
  4. The licensing line — GPL-2.0-only vs or-later
  5. The six options
  6. Side-by-side comparison
  7. Prior art, assessed
  8. Corrections to earlier claims
  9. Other hypervisors: Hyper-V and Xen
  10. Driver candidate survey — what the helper work unlocks
  11. Unconfirmed — check before committing effort
  12. Proposed per-arch target set

1. What is already measured

Facts, not plans. Each was verified directly rather than inferred.

FactEvidence
drm-kmod's core builds on aarch64: drm, ttm, dmabuf, amdgpu, radeonkms, plus our helper modulePR #33 CI, 2026-08-16. drm-kmod (arm64) built: drm amdgpu radeonkms
i915 is correctly absent on arm64drm-kmod Makefile adds i915 to DEFAULT_KMODS for amd64/i386 only
Upstream's amdgpu.ko cannot load on aarch64kconfig.mk gates DRM_AMD_DC_FP behind .if ${MACHINE_CPUARCH} == "amd64", dropping the Display Core FP sources while references stay compiled. Five undefined symbols (dal_hw_factory_dcn401_init, dal_hw_translate_dcn401_init, three dscl*_spl_calc_lb_num_partitions) → kldload ENOEXEC. Caught by tools/check-kext-symbols.py
There is no aarch64-capable drm port at allgraphics/drm-510-kmod, the last with aarch64 in ONLY_FOR_ARCHS, was deleted 2026-05-05
FreeBSD base has no LinuxKPI virtio shim249 headers in sys/compat/linuxkpi/common/include/linux/ on main; zero occurrences of the string “virtio” anywhere under sys/compat/linuxkpi. Same on releng/15.1
drm-kmod 6.12-lts ships no tiny/, sysfb/, virtio/ or vmwgfx/, and no drm_gem_shmem_helper.cFull file-tree listing of 6.12-lts and master
FreeBSD's native virtio_gpu(4) is a vt(4) console framebuffer only — no DRM, no /dev/dri, no 3DVT_DRIVER_DECLARE(vt_vtgpu, ...); added 2023-08-17 by andrew@, sponsored by Arm Ltd (D40094). Restated on freebsd-virtualization 2026-07: “a simple 2D/scanout driver with no virgl support”
Nobody has ever reported /dev/dri in an arm64 FreeBSD VMTwo independent exhaustive sweeps: freebsd-arm, -x11, -virtualization, -drivers, -current, -hackers, -ports, Bugzilla, forums, Phabricator, GitHub

2. The decisions to make

Everything below this section is evidence. These are the calls that evidence does not make for you — each one changes what gets built next. Marked blocking where work cannot start until it is answered.

D1 — Is software-rendered, fixed-resolution KMS acceptable on arm64? blocking

This single answer picks the whole near-term route.

These are not mutually exclusive in the long run — B is a stepping stone that E does not invalidate — but they compete for the next block of effort.

D2 — Is GPL-2.0-only code acceptable inside NextBSD? blocking for C and E

Everything vendored so far is GPL-2.0-or-later, and graphics/README.md states that as an invariant. drm_gem_shmem_helper.c, simpledrm.c and the whole sysfb/ family are GPL-2.0-only.

Worth deciding deliberately rather than by accident: the stated long-term direction for this code is migration toward FreeBSD base, and that is exactly the conflict evadot raised on PR #119. A decision here should also either amend or reaffirm the README invariant.

D3 — Take the free interim unblock? independent, recommended

Option D costs nothing and is orthogonal to everything else: hint.virtio_pci.1.disabled="1" keeps efifb (which has vd_fb_mmap) instead of letting vtgpu displace it, giving working X11-on-llvmpipe in UTM today. The only argument against is that it may mask the problem a real driver should solve.

D4 — Which GEM backing for Option B? only if D1 = yes

Decide before writing, because it is hard to change later and one choice silently breaks Wayland:

D5 — Does arm64 ship RadeonGraphics? low stakes

It builds and resolves cleanly on aarch64, but only matters for a discrete AMD card in a physical PCIe slot — never in a VM. Ship it (costs build time, serves ARM server hardware) or drop it (keeps the arm64 package to what VMs use). Currently shipped in PR #33.

D6 — What to do about the upstream amdgpu/aarch64 defect? outward-facing

drm-kmod's DRM_AMD_DC_FP gating produces an amdgpu.ko that builds clean and cannot load on aarch64, and nothing upstream checks for it. Options: report it upstream, fix it locally and carry a patch, or leave it and keep the guard in PR #33. Reporting is a project-representation decision, so it is being left alone pending a call.

D7 — Confirm the two blocking unknowns first? cheap, high information

Both are hours of work and could invalidate weeks of it.

3. Where the work belongs: three layers

drm-kmod is FreeBSD's out-of-tree port of Linux's DRM subsystem. Driver source is copied from Linux and patched as little as possible; branches track Linux LTS releases (5.4-lts6.12-lts); FreeBSD Makefiles replace Kbuild. The Linux kernel API those files call is not in drm-kmod — it comes from LinuxKPI, which lives in FreeBSD base at sys/compat/linuxkpi. The project's stated preference is to add to LinuxKPI rather than patch drivers, so a fix is not applied twice.

So any missing piece can live in one of three places, and choosing wrongly means either carrying a patch forever or waiting on someone else:

LayerRepositoryWhat belongs thereOur leverage
LinuxKPIFreeBSD baselinux/virtio.h, devres wrappers, gen_poolNone directly — needs a base commit
drm-kmodfreebsd/drm-kmodvendored Linux DRM + FreeBSD gluePRs only; the virtio PR has sat 5 years
oursnextbsd-kernel-moduleswhatever the two above omitTotal — this is the only layer we control

Everything shipped so far is layer 3. graphics/drm_extra_helpers now carries four files that drm-kmod either does not ship or ships and never compiles:

drm_simple_kms_helper.c      not shipped by drm-kmod
drm_gem_vram_helper.c        not shipped by drm-kmod
drm_gem_atomic_helper.c      header is a 15-line stub; zero shadow-plane code
drm_format_helper.c          IN drm-kmod's tree, EXPORT_SYMBOLs intact,
                             named by no Makefile anywhere — dead code upstream

That last one is worth remembering when estimating any option below: a file being present in drm-kmod does not mean it is built, and a driver building does not mean it loads. Both traps have already cost this project a CI cycle each.

4. The licensing line — GPL-2.0-only vs or-later

This is a genuine decision input, and it is not the one stated earlier in this project. There is no maintainer edict against any specific file. What exists is a licence boundary that our own repo already promises to respect — graphics/README.md states “Sources are GPL-2.0-or-later, as is the rest of the vendored Linux DRM code.”

FileSPDXStatus here
drm_gem_vram_helper.cGPL-2.0-or-latervendored, shipping
drm_simple_kms_helper.cGPL-2.0-or-latervendored, shipping
tiny/bochs.cGPL-2.0-or-latervendored, shipping
drm_gem_shmem_helper.cGPL-2.0-onlywould be new
tiny/simpledrm.cGPL-2.0-onlywould be new
sysfb/efidrm.c, drm_sysfb*.cGPL-2.0-onlywould be new

Note Dropping the shmem helper does not rescue simpledrm — simpledrm.c is itself GPL-2.0-only. Any option that imports Linux's framebuffer-DRM code crosses this line twice. The only way to get that functionality while keeping the or-later invariant is to write the driver rather than import it (Option B).

Whether GPL-2.0-only is actually disqualifying for NextBSD is a project decision, not a technical one. It matters more than usual here because the stated long-term direction for this code is migration toward base.

5. The six options

Option A — run our existing bochs.ko on arm64

Ruled out Cost: days. Rejected on direct observation.

The idea. bochs-display is instantiable on qemu-system-aarch64 -M virt and is listed in UTM's own generated aarch64 device table (QEMUConstantGenerated.swift:6537). It is PCI 1234:1111 with BAR0 framebuffer and BAR2 MMIO and no legacy VGA I/O ports, which is exactly why it survives on ARM. hw/arm/sbsa-ref.c instantiates it unconditionally. Gerd Hoffmann's widely-cited 2019 claim that PCI-memory-BAR displays fail on ARM was corrected by QEMU's ARM maintainer: the failure needs KVM-on-Arm and a host lacking FEAT_S2FWB, and Apple M1+ are Armv8.5-A, so it does not apply. We already build every helper bochs needs.

Why it is out. Tested directly in UTM: no display at all, before any driver handoff. ArmVirtPkg/ArmVirtQemu.dsc ships only QemuRamfbDxe under “Video support” — there is no QemuVideoDxe, so the firmware never drives the device. Even if bochs.ko bound after kldload, the machine is black from power-on through loader, kernel boot and single-user. That is not shippable for a desktop OS, and pairing it with -device ramfb to cover the gap means running two display devices to get one working screen.

Recorded here because the analysis is sound and the conclusion is not obvious — if a future ARM firmware ships QemuVideoDxe (as SbsaQemu.dsc already does), this becomes viable at near-zero cost.

Option B — write a native FreeBSD “efidrm” on helpers we already own

Recommended near-term Cost: 1–3 weeks. ~400–600 lines.

The idea. Bind the framebuffer the firmware has already lit, rather than any device. FreeBSD's loader.efi records the UEFI GOP in MODINFOMD_EFI_FB, and sys/dev/vt/hw/efifb/efifb.c — all 5,442 bytes of it — reads the framebuffer address, stride, dimensions and colour masks straight out of it:

efifb = (struct efi_fb *)preload_search_info(preload_kmdp,
    MODINFO_METADATA | MODINFOMD_EFI_FB);
info->fb_stride = efifb->fb_stride * (info->fb_bpp / NBBY);
info->fb_pbase  = efifb->fb_addr;

A DRM driver consumes the identical structure. Take bochs.c as the template, replace PCI BAR discovery with that preload_search_info() call, and delete the mode-setting — one fixed mode, one CRTC/encoder/connector on drm_simple_kms_helper.

Why it fits. There is no black-screen gap by construction: firmware paints, efifb paints, then the DRM driver takes over the same buffer and publishes card0. That is the efifb → drmfb handover already proven on amd64, sourced from firmware metadata instead of a BAR. It works on every arm64 VM that boots UEFI — UTM, Parallels, Fusion, Apple Virtualization.framework, Hetzner — because it binds firmware output rather than a device. UTM defaults to virtio-ramfb, so the framebuffer is already there and already working.

What it costs in licence terms: nothing. No shmem, no virtio shim, no GPL-2.0-only imports. drm_simple_kms_helper, drm_gem_atomic_helper and drm_format_helper are already built and exported in IOGraphicsExtras.kext.

One design decision to make up front

The scanout target is fixed iomem; a GEM allocator is needed only for client-side buffers, which are then blitted in. Three choices:

Inherent limits — not fixable within this approach

Upside beyond us: this closes drm-kmod #269 (open since 2023-12-01, “currently there is no way to use Wayland e.g. in VMs”) and #389, both with standing demand and no implementation. No other BSD has one either — OpenBSD and NetBSD use wsfb/genfb.

Option C — port Linux's simpledrm / efidrm verbatim

Possible, but dominated by B Cost: 2–4 weeks + a GPL-2.0-only decision.

Linux moved simpledrm out of tiny/ in April 2025 into drivers/gpu/drm/sysfb/ and added efidrm, an EFI-specific variant closer to what we want, landing in 6.16.

FileLinesNote
sysfb/efidrm.c434closest fit
sysfb/simpledrm.c906
sysfb/drm_sysfb_modeset.c608shared
v6.12 tiny/simpledrm.c1,076pre-split, self-contained

ofdrm is irrelevant (depends on ... (PPC || COMPILE_TEST), reads an Open Firmware device tree, exists for PowerPC Macs) and vesadrm is x86-only. simpledrm and efidrm are the only arch-neutral members.

Why B dominates it. Both select DRM_GEM_SHMEM_HELPER, so this inherits the shmem port and GPL-2.0-only code twice over. LinuxKPI is also missing linux/sysfb.h and linux/screen_info.h, which are precisely how efidrm.c finds the framebuffer — and on FreeBSD that whole layer collapses into the four-line preload_search_info() call above. You would be deleting the parts that differ and keeping the parts we can already write.

If the shmem helper is wanted anyway: it is 782 lines, and its dependencies are in better shape than expected — drm_gem_get_pages/put_pages are present and exported in drm-kmod's drm_gem.c, and LinuxKPI already has shmem_fs.h, dma_map_sgtable() and set_pages_array_wc(). Note the familiar trap: drm_fbdev_shmem.c sits in drm-kmod's tree and appears in no Makefile.

Option D — D55012, or simply disabling vtgpu

Interim unblock, not KMS Cost: days, or zero.

The problem it solves. sys/dev/virtio/gpu/virtio_gpu.c:121 declares .vd_fb_mmap = NULL, /* No mmap as we need to signal the host */, while vt_efifb sets .vd_fb_mmap = vt_fb_mmap. vtgpu's priority is VD_PRIORITY_GENERIC+10 against efifb's +1, so on any VM presenting a virtio-gpu it displaces efifb and removes the mmap xf86-video-scfb needs — giving scfb_mmap: Invalid argument.

D55012 (Tiago Gasiba, tiga@FreeBSD.org, created 2026-01-31, “Needs Review”, not committed) implements the vt(4) framebuffer mmap plus a ~30 fps host-flush task issuing TRANSFER_TO_HOST_2D + RESOURCE_FLUSH, with hw.virtio_gpu.* tunables. Confirmed working by a third party on bug 283646. andrew@ objected to the polling design, which is likely why it has sat six months.

Notably, Gasiba's own test platform is “FreeBSD 15 (arm64) running on MacOS 26.2 and UTM” — our exact target.

It does not produce /dev/dri. Framebuffer/scfb only: X11 on llvmpipe, no DRM device, no render node, no modesetting, no Wayland.

Zero-cost equivalent available today: keep efifb (which already has vd_fb_mmap) by stopping vtgpu attaching — hint.virtio_pci.1.disabled="1" in /boot/device.hints, or nodevice virtio_gpu. newbus honours this generically via resource_disabled().

Option E — port Linux's virtio-gpu DRM driver

The real prize, and the real cost Cost: months. Four separable sub-projects.

Why it is wanted. It is the only display device Apple's Virtualization.framework and Parallels offer, Parallels ships VirGL 3D, and it is the only option here that gives dynamic resolution — resize the window, the guest follows.

What it needs, none of which exists in shippable form:

  1. A LinuxKPI virtio shim in base (~500–700 lines; 6 headers + linux_virtio.c). D32372 is a usable design sketch but has sat in “Needs Review” since 2021, was never committed, depends on another uncommitted review (D32371), calls a virtio_alloc_virtqueues() signature removed in 2023, and its virtio_reset/virtio_del_vqs are panic() stubs. A rewrite informed by it, not a rebase.
  2. drm_gem_shmem_helper (782 lines, GPL-2.0-only) — virtio-gpu genuinely needs it (drm_gem_shmem_create, _get_pages_sgt, _object_{mmap,pin,vmap}), unlike Option B where it is incidental.
  3. The driver re-ported from 6.12 (~4,000 lines), not the 5.5 snapshot in PR #119 — virtgpu_drv.c there calls drm_fbdev_generic_setup(), which no longer exists.
  4. Making it attach. The 2021 work never got past drm_dev_alloc().

Licence: mostly MIT, except the vram bits, which are GPLv2 (Linux 16845c5d5409).

Option F — port vmwgfx

Prerequisite vmwgfx is blocked by nextbsd-kernel#71 before any of the porting cost below is even reached. vmwgfx is heavily TTM-based with VRAM-resident scanout buffers, so it takes the identical is_iomem fault path that currently blocks indefinitely for bochs: once a buffer is pinned for scanout it moves into device memory, and the fault handler feeds a device-BAR pfn to a function that assumes managed shmem pages. Porting vmwgfx without fixing that path first yields a driver that binds, creates card0, and then hangs on first access — precisely the bochs outcome.

Genuinely supports ARM64 — but largest, and one hypervisor Cost: months. 1.12 MB across 57 files.

Contrary to an assumption made earlier in this project, vmwgfx is not x86-only. Linux's Kconfig reads depends on (X86 && HYPERVISOR_GUEST) || ARM64, added by VMware's Zack Rusin in 523375c943e5 (2021-05-05, “drm/vmwgfx: Port vmwgfx to arm64… ARM support is provided in svga version 3”), which split the hypervisor backdoor into vmwgfx_msg_x86.h and vmwgfx_msg_arm64.h.

Broadcom's own KB 315602 confirms vmwgfx is the display driver for Arm guests on Apple Silicon, with accelerated 3D on kernel 5.19+ and Mesa 22.1.1+. The device is SVGA3 (VMWGFX_PCI_ID_SVGA3 0x0406), not SVGA2 (0x0405).

Against it: vmwgfx_execbuf.c alone is 140 KB, versus 19 KB for all of bochs.c. It buys exactly one hypervisor. Prior FreeBSD art is dead — vmwgfx and vboxvideo were removed from drm-kmod in 787a917018a3 (2021-10-08, “haven't been compiled or working for more than a year”). ravynsoft's vmware branch reached “vmwgfx now compiles” (2023-12-28) but never “works”, with vmwgfx_page_dirty.c gutted to five empty // FIXME bodies and a documented memory leak in the validation path.

6. Side-by-side comparison

OptionCostcard0Render node / 3DDynamic resDisplay from power-onNew GPL-2.0-onlyWorks on
A bochs on arm64daysprobablenoyes*no — black until kldloadnoqemu/UTM only
B native efidrm1–3 wkyesno (llvmpipe)noyesnoevery UEFI arm64 VM
C port simpledrm2–4 wkyesno (llvmpipe)noyesyes, twiceevery UEFI arm64 VM
D D55012 / hint0–daysnononoyesnoUTM, Parallels
E virtio-gpumonthsyesyes (virgl)yesyesvram bits onlyUTM, Parallels, AVF
F vmwgfxmonthsyesyesyesyesnoVMware Fusion only

* Option A's mode-setting works, but is moot given the boot-time blackout.

The decision in one sentence. If software-rendered Wayland at a fixed resolution is acceptable on arm64, Option B is weeks and carries no licence cost; if dynamic resolution or 3D is required, Option E is unavoidable and is a months-long project with three prerequisites before the driver is even reached. Option D is worth doing regardless as a same-day unblock, because it is free.

7. Prior art, assessed

EffortStateVerdict
drm-kmod PR #119
Alex Richardson, 2021-10-08
Open/draft. Linux 5.5. Compiles; panics on attach — page fault at 0x30 in drm_sysfs_minor_alloc(). virtgpu_bsdmodule.c passes an uninitialised struct linux_virtio_device into virtio_gpu_probe(). Author, 2024-02: “I stopped working on this a long time ago.” Design reference. ~5 years and 12 kernel releases stale. Its VIRTIO_DRIVER_MODULE-on-native-virtio-bus attach pattern (~120 lines, BSD-2-Clause) is the salvageable part.
D32372 LinuxKPI virtio
Richardson, 2021-10-08
“Needs Review” — never accepted, never committed. Depends on D32371, also never committed. Already API-broken. Usable sketch; needs rewriting.
ravynsoft/drm-kmod virtio Does not compile — literal syntax error in linux_virtio.c (stray paren, missing semicolon), introduced 2022-07-16 and never fixed. Would not link even so: calls vq_ring_must_notify_host()/vq_ring_notify_host(), both static in FreeBSD. drm_gem_shmem_helper.c implementation absent entirely. Unrelated git history to that fork's main. Dead end. Last commit 2022-07-17. ravynOS itself uses the stock graphics/drm-kmod port.
ravynsoft vmware Linux 5.17 vmwgfx on a 6.1 core; “vmwgfx now compiles” 2023-12-28. Nobody ever claimed it runs. vmwgfx_page_dirty.c has five empty // FIXME: what is needed here? FreeBSD branches; documented memory leak in vmwgfx_validation.c. Porting knowledge is valuable (backdoor hypercall, Makefile, LinuxKPI tweaks); the 47.5k-line diff is not — 6.12's vmwgfx is a different driver.
bsd-sbc-drm/drm-subtree
Jesper Schmitz Mouridsen (jsm@)
Active — last push 2026-08-10. Ships drm_kmod.ko, rk_vop.ko, rk_drm.ko etc. as loadable DRM modules on arm64, rebased onto drm-kmod, on 15-/16-CURRENT. Read this first. The only working demonstration that DRM drivers link and load on FreeBSD/arm64 against modern drm-kmod. Build methodology directly reusable; the Rockchip SoC driver content is not.
D55012
Tiago Gasiba (tiga@)
“Needs Review”. Third-party confirmed working. Tested on FreeBSD 15 arm64 under UTM on macOS. Complementary, not competing — scfb/X11, not DRM.

8. Corrections to earlier claims

Corrected Two claims made earlier in this project were wrong and are retracted here so they do not propagate.

1. scripts/diffignore is not a licensing blacklist. It was cited as evidence that drm-kmod “refuses” drm_gem_shmem_helper.c. It is in fact the ignore-list for drm-kmod's own diff tooling (drmdiff, drmcheck) — the set of upstream paths to skip when diffing against Linux, i.e. “files drm-kmod does not carry”. Its first three entries are Kconfig, Kconfig.*, Makefile, and it also lists drm_gem_vram_helper.c, drm_gem_atomic_helper.c and drm_gem_framebuffer_helper.c — three files we have already vendored and ship. Presence there carries no policy verdict.

2. The GPL objection was overstated. What is sourceable is evadot objecting on PR #119 to GPL-2.0 files specifically because they conflict with moving code into the FreeBSD base system — which does not obviously bind an out-of-tree kld. No blanket refusal of the shmem helper exists. The real constraint is the narrower or-later vs only line, which our own README asserts.

Also corrected: vmwgfx was assumed x86-only; it supports ARM64 upstream and is the display driver for Arm guests on Apple Silicon. And bochs was described as invalid on arm64 for lack of a VGA device; the device is in fact instantiable and listed in UTM's own device table — it is firmware, not the device, that makes Option A unusable.

9. Other hypervisors: Hyper-V and Xen

Both have real DRM drivers upstream; neither is in drm-kmod, and neither was in this plan's original six options. Verified against Linux v6.12.

Hyper-V — drivers/gpu/drm/hyperv/ cheapest follow-on

Five files, in Linux since 5.14. A proper KMS driver for Hyper-V synthetic video, and critically it is shmem-backed, not VRAM:

#include <drm/drm_gem_shmem_helper.h>
DRM_GEM_SHMEM_DRIVER_OPS,
drm_fbdev_shmem_setup(dev, 0);

That places it on the same side of the line as virtio-gpu: it would not hit the device-memory defect (nextbsd-kernel#71) that stops every VRAM-backed driver, and it needs the same prerequisite — drm_gem_shmem_helper, the 782-line GPL-2.0-only file drm-kmod omits.

Why it is the cheapest follow-on: it shares virtio-gpu's single largest cost, so once that helper exists Hyper-V is mostly the driver itself. And unlike virtio, the transport is not starting from zero — FreeBSD ships Hyper-V support in base (hv_vmbus and friends), where LinuxKPI has no virtio bus at all.

Xen / Citrix — drivers/gpu/drm/xen/ not recommended

Fourteen files: a paravirtual DRM frontend over Xen's display protocol, with its own event channels (xen_drm_front_evtchnl.c), config layer, and a bespoke GEM implementation (xen_drm_front_gem.c).

The graphics driver is the small part of this job. It sits on Xen guest infrastructure — grant tables, xenbus — which is an entire KPI surface that does not exist, and which nothing else we want would reuse. Citrix Hypervisor guests can in any case use the standard emulated devices, so this buys little that is not already covered.

DriverBackingNeedsRelative cost
virtio-gpushmemshmem helper + a LinuxKPI virtio bus shim (none exists)months
hyperv_drmshmemshmem helper + vmbus glue (base already has hv_vmbus)less than virtio-gpu
vmwgfxVRAMnothing new, but 1.12 MB across 57 filesmonths
xen-drm-frontbespoke GEMXen grant tables + xenbus KPI, none of which existsmost

10. Driver candidate survey — what the helper work unlocks

Recorded for later consideration, not proposed now. The question this answers: having built the VRAM/KMS helper layer for bochs and vboxvideo, which other upstream drivers become cheap?

The deflating answer Almost every small driver migrated to shmem years ago. bochs and vboxvideo were effectively the last drm_gem_vram_helper holdouts, so the VRAM work unlocked exactly the two drivers it was written for — there is no queue of easy VRAM drivers behind it.

DriverBackingBlocked onWhy it might matter
ast (ASPEED BMC)shmemshmem helperarm64 and amd64 servers. Kconfig is depends on DRM && PCI && MMU with no arch constraint; ASPEED BMCs are what Ampere/Marvell-class arm64 server boards actually ship. The strongest hardware case on this list
mgag200 (Matrox BMC)shmemshmem helperServer BMCs, mostly x86 (Dell iDRAC / HPE iLO lineage)
cirrusshmemshmem helperLegacy qemu; largely superseded by bochs
hypervshmemshmem helperHyper-V guests. Transport already in FreeBSD base (hv_vmbus) — see §9
simpledrm / sysfbshmemshmem helperAny UEFI machine, any arch. See the fallback plan, which proposes writing this natively instead
qxlTTM + drm_gem_ttm_helpernothing newThe cheapest driver on the board. 168 KB, and drm-kmod already ships and compiles both helpers it needs. A qemu/SPICE device, so unlike vboxvideo CI could actually exercise it

What this changes about the shmem helper

It is not virtio-gpu's private cost. One prerequisite gates six drivers — virtio-gpu, hyperv, ast, mgag200, cirrus and simpledrm — including the BMC driver that matters on real arm64 server hardware. That is a materially stronger argument for paying it than “virtio-gpu needs it”.

qxl: cheap, with one caution

qxl needs no new helper layer at all. The caution: drm-kmod issue #62 records someone's qxl attempt panicking inside ttm_bo_vm_fault. Now that the device-memory defect is understood (nextbsd-kernel#71), that reads like the same bug — qxl has VRAM and would need the same vm_phys_fictitious_reg_range() registration. Suggestive, not proven.

Not in this category: SoC display controllers

Raspberry Pi (vc4), Rockchip, Allwinner and friends are a different problem, and none of the helper work applies. vc4's Kconfig alone:

depends on ARCH_BCM2835
depends on RASPBERRYPI_FIRMWARE      # VideoCore firmware mailbox
depends on SND && SND_SOC            # ALSA, for HDMI audio
depends on COMMON_CLK                # Linux clock framework
select DRM_GEM_DMA_HELPER            # CMA -- a third backing type
select DRM_DISPLAY_HDMI_STATE_HELPER

659 KB, needing a CMA GEM helper, the common clock framework, device-tree attachment, an ALSA/SoC binding and a firmware mailbox — none of which exists here. The only working precedent for DRM on FreeBSD/arm64 is bsd-sbc-drm (jsm@), whose Rockchip drivers are exactly this shape. If SBCs ever become a target, that is a separate track with its own prerequisites and should be scoped as one.

11. Unconfirmed — check before committing effort

Source to distrust freebsdsoftware.org, “State of Wayland on FreeBSD in 2026” (2026-04-09) claims virtio-gpu works with Wayland compositors on FreeBSD and that nouveau has limited drm-kmod support. Both are false — drm-kmod ships neither driver. Likely generated content; do not cite it.

12. Proposed per-arch target set

Reflecting the stated preference that arm64 carry only what an ARM VM can actually use, rather than everything that happens to compile.

Driveramd64arm64Why
IOGraphics / TTM / DMABuf / IOGraphicsExtrasshipshipCore + helpers. Prerequisite for every option; already builds and resolves
IntelGraphicsshipdrm-kmod gates i915 to amd64/i386; no Intel iGPU on aarch64
AMDGraphicsshipcannotUpstream DRM_AMD_DC_FP gating makes amdgpu.ko unloadable on aarch64
RadeonGraphicsshipoptionalBuilds and resolves; only relevant for a discrete card in a PCIe slot, not a VM
BochsGraphicsshipOption A: black screen until kldload on ARM firmware
VBoxGraphicsshipVirtualBox guests are x86
NVIDIAshipNo aarch64 legacy blob
EFIGraphics (Option B)optionaltargetWould also give amd64 VMs a firmware-framebuffer KMS fallback
VirtIOGraphics (Option E)eventualeventualThe only path to dynamic resolution and 3D

Sub-plan of the NextBSD graphics plan. Written 2026-08-16 from a three-agent research sweep; every factual claim above was checked against a primary source (repository file, commit, review, mailing-list post or CI log) rather than inferred, and the items that could not be confirmed are listed in §8 rather than smoothed over. Where this page contradicts something said earlier in the project, §7 says so explicitly.