1.1 · How the stack works
What a Hypervisor Is, and Where KVM Fits (Type-1 vs Type-2)
This series builds the KVM, QEMU and libvirt stack from the processor upwards, on ARM64. The commands were run on a Raspberry Pi 5 (8 GB), running Raspberry Pi OS Bookworm with Linux kernel 6.12, 64-bit, and the terminal output shown is real. The ideas, though, apply anywhere Linux runs. I chose ARM64 deliberately, because almost every KVM tutorial is written for x86.
The first question is: what is a hypervisor, and which kind is KVM?
Virtualization works on an illusion
A normal computer runs one operating system, and that operating system believes it owns the hardware: all of the memory, every processor core, the disks and the network card. That belief is not a simplification for beginners. It is built into how kernels are written. A kernel runs privileged instructions, sets up memory maps, talks directly to devices, and assumes nothing exists above it.
A hypervisor is what lets several of those operating systems run on one machine, each still believing it owns everything. Its job is to keep that illusion convincing, while quietly sharing the real hardware underneath.
Everything else in this series, such as VM exits, virtio, virtqueues and device passthrough, is a technique for keeping that illusion either more convincing or cheaper.
The two types of hypervisor
The usual classification divides hypervisors into two types:
Type 1 hypervisors run directly on the hardware. There is no general-purpose operating system underneath, so the hypervisor is what the machine starts. ESXi and Xen are the standard examples. What you get is performance and isolation: the hypervisor is the only layer between a guest and the hardware.
Type 2 hypervisors run as programs on an ordinary operating system. You start Linux, macOS or Windows as usual, then start a program such as VirtualBox, the same way you would start a web browser. What you get is convenience: your usual desktop carries on as before, and a virtual machine is one more program running alongside everything else.
The difference is usually summarised as speed against convenience.
Where KVM fits
KVM, the Kernel-based Virtual Machine, is part of the Linux kernel. Depending on how the kernel was built, it is either built in, as on the Raspberry Pi, or loaded as a module. Either way, once it is active, the Linux kernel itself becomes the hypervisor. There is no separate hypervisor layer above or below it. That is meant literally, not as an analogy: there is one kernel, and it runs ordinary programs and virtual machines alike.
Now try to place that in one of the two types.
KVM has Type 1’s most important property: there is no other operating system between the hypervisor and the hardware. Guest code runs on real processor cores, at the processor’s full speed, with no translation and no host operating system relaying requests for it. By that measure, KVM belongs with Type 1.
But it lives inside a general-purpose operating system that is, at the same time, running SSH sessions,
a web browser and dozens of services. Your VMs appear in ps. They are scheduled by the ordinary Linux
scheduler, can be stopped with kill, and are limited by cgroups, like any other process. By that
measure, it is unmistakably Type 2.
That is why the argument never ends. KVM is often called “Type 1, more or less”, and that hedge is fair: the two types were defined in the 1970s, decades before anything like KVM existed.
Why it matters which type KVM is
Because the hypervisor is part of a complete Linux kernel, it inherits everything that kernel can already do. It needs no scheduler of its own, because Linux has one, and virtual processors are ordinary threads on it. It needs no memory manager, drivers, file systems or network stack of its own either, because Linux has all of them. A dedicated Type 1 hypervisor has to build or adapt every one.
That inheritance shapes this whole series. Tying a VM’s virtual processors to particular physical cores uses the ordinary Linux way of doing that for any thread, because a virtual processor is a thread. A guest’s disk turns out to be a file in a folder, because the host’s file system is doing its normal job. And connecting guests to a network uses the same Linux bridge that connects any two network interfaces.
The other side matters just as much: KVM is deliberately small. It handles the processor and memory, and nothing else. It does not know how to be a disk, a network card, a screen or a USB port, and it was never meant to. It does not need to: the Linux kernel already has mature code for storage, networking and devices, and above the kernel, QEMU handles whatever remains.
That raises the question of how the work is divided between these pieces, which post 1.3 answers. Before that, one thing needs clearing up, because “the kernel becomes the hypervisor” skips over something important. A kernel cannot simply decide to run guest operating systems at the processor’s full speed. It needs the processor’s cooperation, which comes from a feature built into the chip, inactive until software switches it on.
On ARM64, that feature is called EL2, and it is where the next post starts.
Summary
- A hypervisor lets several operating systems each believe they own the hardware, while sharing the real hardware underneath.
- Type 1 runs directly on the hardware, such as ESXi and Xen. Type 2 runs as a program on an ordinary operating system, such as VirtualBox.
- KVM is part of the Linux kernel, built in or as a module, and turns the running kernel into a hypervisor. Guest code runs directly on real processor cores, but guests are also ordinary Linux processes.
- It is Type 1 by the absence of any operating system in between, and Type 2 by being part of one. The two types were defined long before KVM.
- Because the hypervisor is part of Linux, it reuses Linux’s scheduler, memory management and drivers, which is why KVM itself only handles the processor and memory.
Comments