1.1 · How the stack works

What a Hypervisor Is, and Where KVM Fits (Type-1 vs Type-2)

KVM · Linux · Virtualization · ARM64

This series builds the KVM/QEMU/libvirt stack from the silicon up, on ARM64. Every command is aarch64-native, and the terminal output throughout is real — captured from a Raspberry Pi 5 (8 GB) running Raspberry Pi OS Bookworm, kernel 6.12 aarch64. The concepts apply anywhere Linux runs; the specifics are ARM64, because almost every KVM tutorial in existence assumes x86 and quietly leaves ARM readers to translate.

We start with the question that every virtualization introduction opens with and then answers badly: what is a hypervisor, and which kind is KVM?

The lie that makes virtualization work

A normal computer runs one operating system, and that OS believes it owns the hardware — all the RAM, every CPU core, the disks, the network interface. This belief isn’t a simplification for beginners. It’s baked into how kernels are written. A kernel executes privileged instructions, sets up memory maps, talks directly to devices, and assumes nothing sits above it.

A hypervisor is the thing that lets several of those “I own everything” operating systems run on one machine, each still believing the lie. The hypervisor’s job is to keep the lie convincing while quietly sharing the real hardware underneath.

Everything else in this series — VM exits, VirtIO, virtqueues, passthrough — is a technique for maintaining that lie either more convincingly or more cheaply.

The classic split

The textbook taxonomy divides hypervisors in two:

   TYPE 1 (bare metal)              TYPE 2 (hosted)
   ┌───────┬───────┬───────┐        ┌───────┬───────┐
   │ Guest │ Guest │ Guest │        │ Guest │ Guest │
   ├───────┴───────┴───────┤        ├───────┴───────┤
   │      Hypervisor       │        │  Hypervisor   │  ← an app
   ├───────────────────────┤        ├───────────────┤
   │       Hardware        │        │   Host OS     │
   └───────────────────────┘        ├───────────────┤
                                    │   Hardware    │
   e.g. ESXi, Xen                   e.g. VirtualBox

Type 1 sits directly on hardware. There is no general-purpose OS underneath it — the hypervisor is the thing the machine boots into. ESXi and Xen are the standard examples. The pitch is performance and isolation: nothing stands between a guest and the silicon except the hypervisor itself.

Type 2 runs as an application on top of a normal operating system. You boot Linux or macOS or Windows, and then you launch VirtualBox the way you’d launch a browser. The pitch is convenience: your normal desktop keeps working, and VMs are just another program.

The trade-off is usually stated as speed versus convenience, and for those two examples it holds up.

Where KVM fits, and why the question is harder than it looks

KVM is a kernel module. When it’s loaded, the Linux kernel itself becomes the hypervisor. There’s no separate hypervisor layer above or below — the kernel you’re already running gains the ability to execute guests directly on the hardware.

   KVM — the kernel IS the hypervisor
   ┌───────┬───────┬───────────────┐
   │ Guest │ Guest │ normal apps   │   ← guests are just
   │  VM   │  VM   │ (browser,etc) │     processes here too
   ├───────┴───────┴───────────────┤
   │     Linux kernel + KVM        │   ← hypervisor lives
   ├───────────────────────────────┤      inside the kernel
   │          Hardware             │
   └───────────────────────────────┘

Now try to place that on the Type-1/Type-2 chart.

It has Type-1’s defining property: the hypervisor talks straight to the silicon, with no intermediary OS between it and the hardware. Guest code runs on real cores at native speed. There’s no translation layer, no host kernel being asked to relay requests on the guest’s behalf. By the performance argument that motivates the Type-1 category in the first place, KVM is Type 1.

But it lives inside a general-purpose operating system that is simultaneously running your SSH session, your browser, and a few dozen daemons. Your VMs appear in ps output. They’re scheduled by the ordinary Linux scheduler, killable with kill, and constrained by cgroups like any other process. By the structural argument, that’s unmistakably Type 2.

This is why the classification argument never resolves. KVM is usually called “Type-1-ish”, and the hedge is honest rather than evasive: the taxonomy was built before a design like KVM existed, and KVM satisfies each category’s definition on a different axis.

Why this matters beyond trivia

It would be easy to file this under terminology and move on. Don’t — the reason KVM doesn’t fit the chart is the reason the rest of the stack looks the way it does.

Because the hypervisor lives inside a full Linux kernel, it inherits everything that kernel already knows how to do. It doesn’t need its own scheduler; Linux has one, and vCPUs become ordinary threads on it. It doesn’t need its own memory manager, driver model, filesystem layer, or network stack — Linux brought all of them. A dedicated Type-1 hypervisor has to build or port every one of those.

That inheritance shapes the whole series. When we pin vCPU threads to physical cores, we’ll be using the ordinary Linux scheduler affinity mechanism, because a vCPU genuinely is just a thread. When guest disks turn out to be files in a directory, that’s the host filesystem doing its normal job. When we bridge guest networking, we’ll use the same Linux bridge that would connect any two interfaces.

The corollary is the important half: KVM is deliberately small. It handles CPU and memory. That’s the entire scope. It has no idea how to be a disk, a network card, a display, or a USB port — because inside a Linux kernel, something else already handles all of those, and above it in userspace, QEMU handles the rest.

Which raises the obvious question of what the division of labour actually looks like. That’s article 3 in this series — but there’s a prerequisite first, because “the kernel becomes the hypervisor” glosses over something significant. A kernel can’t just decide to run guest operating systems at full speed. It needs the CPU’s cooperation, in the form of a hardware feature that sits dormant in the silicon until software switches it on.

On ARM64 that feature is EL2, and it’s where the next article starts.

Summary

  • A hypervisor lets multiple operating systems each believe they own the hardware, and shares the real hardware underneath.
  • Type 1 runs directly on hardware (ESXi, Xen). Type 2 runs as an application on a host OS (VirtualBox).
  • KVM is a kernel module that turns the running Linux kernel into a hypervisor. Guest code executes directly on real cores, but guests are also ordinary Linux processes.
  • It’s Type-1 by the performance argument and Type-2 by the structural one, hence “Type-1-ish”. The taxonomy predates the design.
  • Because the hypervisor lives inside Linux, it reuses Linux’s scheduler, memory manager, and drivers — which is why KVM itself only handles CPU and memory.

Comments

get new posts

About one email a week, and only when there is something new.

Subscribe →