I bought my current PC in mid-2022, when GPU prices finally came back down after the mining boom had just collapsed and cards were affordable again for the first time in years, so I built it back then and have barely touched it since – a couple of storage upgrades (when storage was actually affordable) along the way, and a new GPU recently. But the CPU and board are still the same ones I started with.
The CPU I decided to go with is an i7 12700K, which back then was a better offer for productivity compared to AMD, and let’s be honest, Ryzen’s AM4 PGA sockets were a nightmare back then, so I went team blue. I had also considered the 12700KF – the same chip without the integrated graphics – but the K happened to be 20€ cheaper, so I ended up with an iGPU almost by accident.
Most people, including myself, with a discrete graphics card will never use the iGPU, it just sits there, idle silicon usually paid extra for.
Nearly four years later that iGPU had done nothing but idle. So I decided to give it an actual job – hand it to a Windows VM I could stream to, without dual-booting or keeping a second machine around. The reason is simple: even though I genuinely dislike Microsoft Windows, it’s useful to have access to it
for the things that only run there. On paper it’s a solved problem. In practice, Alder Lake’s iGPU fought me at almost every step.
Getting the host to let go
The first wall has nothing to do with the VM: Linux claims the iGPU on boot and won’t share it. You have to tell it to leave the card alone by binding the device to vfio-pci early, blacklist i915 and xe, and disable the EFI framebuffer
so nothing draws on it during boot (intel_iommu=on, video=efifb:off, vfio-pci.ids=...). On Artix with OpenRC that means rebuilding the initramfs and rebooting, then checking that lspci reports Kernel driver in use: vfio-pci on 00:02.0. Until it does, there’s nothing to pass through.
The ROM rabbit hole
This is the part that ate literally days. An Intel iGPU needs its option ROM to initialize inside the guest, and Q35 is strict about which one. Every ROM I found linked around gave me Code 43 – Windows seeing the card and refusing to use it.
The one that finally worked was built specifically for 12th-to-14th gen chips, not the older dumps most guides point to. With that in place, plus two QEMU options (x-igd-opregion=on and x-igd-gms) and enough SMBIOS detail that the guest believes it’s running on a real board, the driver finally loaded clean.
None of this lives in one place. It’s a thread here, a GitHub release and some random Proxmox forum posts there, and a comment from years ago that turns out to be the whole answer.
Looking Glass, and knowing when to quit
My plan was Looking Glass: it copies the guest’s frames into shared memory so you can see them on the host with almost no latency. It never came together. The IVSHMEM device and VFIO kept hitting DMA mapping errors I couldn’t resolve, and after a couple of evenings I gave up on it for this setup.
What actually worked was simpler – Sunshine
running in the VM and Moonlight
on my host. No monitor, no dummy HDMI plug: a virtual display driver and a stream that’s good enough that I forget it’s a stream. Not the clever solution, just the one that runs.
What I’d tell past me
- The host fighting you for the card is the real first problem, not a footnote.
- Most “Code 43” errors are the wrong ROM, not the XML.
- Looking Glass is great when it works and a pain when it doesn’t.
- Taking notes on the way is a must. A lot of this was hard to find once and would be just as hard to find again; my notes are the only reason I could repeat it.
So that’s basically it: I now have a fully hardware-accelerated Windows VM for the
rare cases I actually need it. Full write-up soon.