Understanding QEMU/KVM Virtualization
Disclaimer: The views expressed on this website are my own and do not necessarily reflect the views of Oracle. Nothing published here is written on behalf of, endorsed by, or reviewed by my employer. All technical content is written from public documentation and personal study, and describes general industry practice rather than any specific employer system, configuration, or product plan.
What is QEMU/KVM?
QEMU (Quick EMUlator) and KVM (Kernel-based Virtual Machine) are two complementary technologies that together form one of the most performant open-source virtualization stacks available on Linux.
KVM is a kernel module that turns the Linux kernel itself into a hypervisor. It leverages hardware virtualization extensions (Intel VT-x, AMD-V) to run guest code directly on the CPU with minimal overhead. QEMU, on the other hand, handles device emulation — providing virtual disks, network interfaces, USB controllers, and more.
When combined, KVM accelerates CPU and memory virtualization while QEMU provides the full device model and user-space tooling.
How They Communicate
QEMU spawns a process per virtual machine. It opens /dev/kvm and interacts with it via ioctl calls — creating VMs, creating vCPUs, setting up memory mappings, and running the guest.
int kvm_fd = open("/dev/kvm", O_RDWR);
int vm_fd = ioctl(kvm_fd, KVM_CREATE_VM, 0);
int vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
The guest's execution happens in a tight loop:
while (1) {
ioctl(vcpu_fd, KVM_RUN, 0);
// handle exit reason (I/O, MMIO, halt, ...)
}
Each KVM_RUN call puts the vCPU into guest mode. When the guest does something that requires hypervisor intervention (I/O access, page fault, hypercall), the CPU exits back to host mode and QEMU handles it.
Memory Virtualization
Guest physical memory is backed by a mmap-ed region in QEMU's address space. The KVM slot system maps guest physical addresses to host virtual addresses:
struct kvm_userspace_memory_region region = {
.slot = 0,
.guest_phys_addr = 0x0,
.memory_size = RAM_SIZE,
.userspace_addr = (uint64_t)guest_mem,
};
ioctl(vm_fd, KVM_SET_USER_MEMORY_REGION, ®ion);
Hardware EPT (Extended Page Tables) or NPT (Nested Page Tables) then handle the two-dimensional address translation transparently.
Why It Matters
Understanding this stack is essential for anyone working on hypervisor development, cloud infrastructure, or OS internals. The boundary between QEMU and KVM — userspace and kernel — is where most of the interesting engineering decisions live.
The views expressed on this website are my own and do not necessarily reflect the views of Oracle. Nothing published here is written on behalf of, endorsed by, or reviewed by my employer.