Repository navigation
Replace VZ with HV as default macOS backend #250
Description
Current decision
The strategic target is now All-in-HV runtime by default.
For linux/amd64 on Apple Silicon, the next decision gate is #292: evaluate FEX64 inside the HV guest as the default runtime translator. If FEX64 is good enough, VZ/Rosetta should be retained only as an optional docker build --platform linux/amd64 backend or compatibility escape hatch, not as a second always-on runtime VM. If FEX64 is not good enough, #290 remains the fallback dual HV+VZ runtime routing plan.
Summary
The HV (Hypervisor.framework) backend is already the de facto default for non-Rosetta workloads: resolve_backend() returns HV for VmBackend::Auto when Rosetta is not requested. The remaining strategic question is no longer “keep VZ as the default until HV is ready”, but “can HV also cover amd64 runtime workloads via FEX64?”
Blockers / decision gates
- [Correctness] Pause / resume / snapshot dispatch is VZ-only — HV-backed VMs must not call Virtualization.framework lifecycle code.
- [Test coverage] At least one E2E suite must boot a Linux guest through HV and reach network + filesystem smoke tests.
- [Verification] DAX end-to-end path must be verified:
guest mmap → FUSE_SETUPMAPPING → hv_vm_map → page fault. - [Feature] Balloon device is missing from
initialize_darwin_hv(). - [Performance] Interrupt coalescing / EVENT_IDX batching must land on the hottest device paths.
- [amd64 strategy] Evaluate FEX64 as default linux/amd64 runtime inside HV #292 must validate whether FEX64 can be the default
linux/amd64runtime inside HV.
Evidence for HV readiness
- Core container runtime devices — block, net, vsock, fs, rng — are registered in
initialize_darwin_hv()and functional. - Phases 1-6 of the VirtIO improvements plan have landed: MRG_RXBUF, TAP TSO offload, RX scratch reuse, DAX plumbing, DISCARD/WRITE_ZEROES, vmnet bridge cleanup.
- ABX-287, ABX-286, ABX-285, ABX-288 — core HV crate, device model, Linux boot, and dual-backend switching are Done.
- fix(hv): join net RX worker on shutdown + Release fence on avail_event #245, HV backend net RX polling starvation — vCPU can't keep up with datapath frame injection #238, fix(vmm): DAX window mmap not munmap'd on shutdown or error #231, fix(vmm): stop_darwin_hv doesn't join blk I/O workers before dropping guest memory #230 — hardening work completed.
Exit criteria
- Existing HV correctness/test/performance blockers are resolved or explicitly accepted.
- Evaluate FEX64 as default linux/amd64 runtime inside HV #292 produces a clear decision on FEX64 viability for Docker runtime, Compose, BuildKit, compatibility, and performance.
- If Evaluate FEX64 as default linux/amd64 runtime inside HV #292 passes: default runtime architecture is single HV; VZ/Rosetta is build-only/optional/compatibility path.
- If Evaluate FEX64 as default linux/amd64 runtime inside HV #292 fails: resume Fallback: run HV and VZ Rosetta utility VMs side-by-side with Docker/OCI routing #290 as the fallback dual-runtime plan.
-
resolve_backend()comments and config semantics reflect the final policy. - Refactor Vmm into trait-based backend dispatch (VmBackend) + split HV/VZ into their own crates #248 or equivalent backend isolation is complete enough that VZ can be moved behind a clean optional boundary and eventually removed if no longer needed.
Activity
linear commentedon Apr 17, 2026
ABX-359