This episode guides you through running Windows in Cloud Hypervisor: booting Windows 10/Server via UEFI (CLOUDHV.fd), installing virtio drivers, the differences between upstream edk2 and the CLOUDHV fork especially on AArch64, and best practices for stable Windows on virtio devices.

So far all our guests have been Linux-based. In episode 15 we challenge that assumption and run Windows — Windows 10 or Windows Server — on Cloud Hypervisor. This might sound odd for a "cloud-native" VMM, but Cloud Hypervisor is actually designed to support full Windows guests, and many modern PaaS platforms run Windows workloads with VM isolation.
The main challenges are clear: Windows needs the right UEFI, drivers for virtio devices, and Windows' uncompromising habits (licensing, activation, timers). We cover all of it step by step.
Linux can be booted directly with PVH (episode 4) without firmware. Windows cannot. Windows requires UEFI firmware (or BIOS, which is even more complicated in Cloud Hypervisor) to find its boot loader on the ESP (EFI System Partition). That's why Windows in Cloud Hypervisor always uses CLOUDHV.fd:
cloud-hypervisor \
--firmware CLOUDHV.fd \
--disk path=windows.raw \
--cpus boot=4 \
--memory size=8G \
--serial tty \
--console offThere's no --kernel here: CLOUDHV.fd (UEFI based on edk2) reads the ESP, runs the Windows Boot Manager, then loads the Windows kernel. --console off --serial tty redirects the console so Windows boot output is visible in the terminal.
Windows is pickier about "hardware". At minimum, prepare:
Download a Windows ISO (an evaluation version is available from Microsoft), then present it as a virtio CD-ROM:
qemu-img create -f raw windows.raw 40G
cloud-hypervisor \
--firmware CLOUDHV.fd \
--disk path=windows.raw \
--disk path=Win10_22H2.iso,readonly=on \
--cpus boot=4 \
--memory size=8G \
--serial ttyThe biggest problem during installation: Windows doesn't know virtio-blk/virtio-net. During setup, Windows won't see the virtio disk because there's no driver. The solution is to provide the drivers on another medium:
cloud-hypervisor \
--firmware CLOUDHV.fd \
--disk path=windows.raw \
--disk path=Win10_22H2.iso,readonly=on \
--disk path=virtio-win.iso,readonly=on \
--cpus boot=4 \
--memory size=8G \
--serial ttyWhen setup refuses to find a disk, choose "Load driver" and point it at the virtio-win CD-ROM — select the viostor (storage) and NetKVM (network) drivers. The official virtio drivers for Windows are provided in the virtio-win repository (community-maintained, including drivers for Cloud Hypervisor).
Important
Windows virtio drivers are the key to everything: without viostor, Windows can't boot from the virtio disk; without NetKVM, there's no NIC. The correct order: boot the installer → load the storage driver → install to the virtio disk → after Windows is in, install the other drivers (net, fs, balloon).
Windows licensing isn't a VMM technical problem, but it's still relevant: make sure you use a valid license for the VM. Modern Windows Server can be installed without activation and used in evaluation mode, with activation done through standard Microsoft methods (KMS or digital license) — Cloud Hypervisor doesn't provide any special mechanism here.
CLOUDHV.fd is an edk2 build forked specifically for Cloud Hypervisor. Why not use upstream edk2 directly? Because Cloud Hypervisor provides a specific firmware interface (e.g., an MMIO device layout consistent with its VMM), and this fork ensures the firmware is optimized for that context — smaller size, faster boot, and relevant device support.
The most striking differences are on AArch64. On this architecture, upstream edk2 doesn't provide console output and device setup that match Cloud Hypervisor conventions without adjustments. The CLOUDHV fork adds the needed support (e.g., correct serial UART, device tree, and virtio support for booting Arm guests like Windows on Arm or Linux). This is why the official docs recommend CLOUDHV_EFI.fd on aarch64:
cloud-hypervisor \
--firmware CLOUDHV_EFI.fd \
--disk path=windows-arm.raw \
--cpus boot=4 \
--memory size=8G \
--serial ttyIf you try upstream edk2 on AArch64 and get no output, this is most likely the reason — use the Cloud Hypervisor-maintained fork.
hotplug_size for growth.viostor driver from virtio-win.CLOUDHV.fd boots from the first disk by default.NetKVM; verify in Device Manager.CLOUDHV_EFI.fd), not upstream edk2.Tip
For a lab, run Windows with a JSON config (episode 5) that stores all options — ISO, driver disk, memory. Copying this config makes the setup reproducible, and it's easy to adapt when you move to production templates.
Key takeaways:
--firmware CLOUDHV.fd, no direct PVH boot.CLOUDHV.fd is an edk2 fork specific to Cloud Hypervisor; on AArch64 use CLOUDHV_EFI.fd.In the next episode, episode 16, we'll cover testing & CI — cargo test, integration tests (integration.rs), CI running against kernel 5.15, plus benchmarks for boot time, memory overhead, and throughput compared to QEMU. How this project keeps quality, and how you can test it yourself.