← All writing

Near-native, on my own terms: Arch, KVM, and a love for type-1 at home

People ask why I run Arch when “something stable” would do. The honest answer is control. I don’t want a distro that decides things for me – I want one I build up from nothing, where every package on the box is there because I put it there and I can tell you what it does. Arch isn’t hard so much as it’s transparent: there’s no vendor layer guessing at what I want, no defaults quietly working against me. I’d rather assemble the system myself and actually understand it than inherit one I have to reverse-engineer later.

That same instinct is why I fell for KVM.

Linux as the hypervisor

The thing people miss about KVM is that it isn’t a program you run on Linux — it turns the Linux kernel itself into the hypervisor. The scheduler, the memory manager, the drivers you already trust are doing the virtualization. QEMU just hands it the hardware to emulate around the edges.

So the old “type-1 vs type-2” debate mostly dissolves. With KVM the kernel is the bare-metal layer. There’s no host OS sitting underneath a hypervisor product — the host OS is the hypervisor. That’s the part I love: it’s not a black box bolted on top, it’s the system I already understand, doing one more job.

Chasing native

A VM only feels like a toy if you let it run like one. With a few deliberate choices, a guest gets within a rounding error of bare metal:

  • virtio everywhere — paravirtualized disk and network instead of emulated hardware. The guest stops pretending it’s talking to a real NIC and just talks to the host.
  • CPU pinning — pin vCPUs to physical cores so the scheduler stops shuffling them around and the cache stays warm.
  • Hugepages — back the guest’s RAM with 2MB pages to cut TLB pressure.
  • PCIe passthrough — hand a real GPU or NIC straight to the guest with VFIO. At that point it isn’t emulated at all; it’s the actual silicon.
qemu-system-x86_64 \
  -enable-kvm \
  -cpu host \
  -smp 8,sockets=1,cores=8 \
  -m 16G -mem-prealloc \
  -object memory-backend-file,id=mem,size=16G,mem-path=/dev/hugepages,share=on \
  -drive file=guest.qcow2,if=virtio,cache=none,aio=native \
  -netdev tap,id=n0,vhost=on -device virtio-net-pci,netdev=n0
Reply by email →