The guest's lie: who really owns physical memory?
Guide 2 in this rung handled CPU virtualization: the hypervisor runs the guest's instructions directly on the real CPU and only steps in — via a VM exit — when the guest does something privileged. That works for instructions. But there is one resource a guest OS reaches for constantly and assumes it owns completely: physical memory. The guest's kernel built its own page tables, it thinks address 0x0 is the first byte of RAM, and it freely maps any physical frame it likes. The problem is obvious once you say it out loud: there are several guests, plus the host, and they cannot all own physical frame 0. Somebody has to be lying to the guest, and doing it fast enough that the guest never notices.
So virtualization adds a second layer of translation. You already know one layer from the virtual-memory rung: the guest's MMU turns a guest virtual address into what the guest believes is a physical address. Call that guest-physical. But guest-physical is itself a fiction — it is just a number the guest made up. The hypervisor must translate guest-physical into the real machine address, the actual byte in the actual DRAM chip. So one memory access now needs two translations stacked on top of each other, and the whole art of memory virtualization is making that second translation nearly free.
Three address spaces, two translations: guest virtual addr --[ guest page tables ]--> guest physical addr guest physical addr --[ hypervisor mapping ]--> host physical addr Native (no VM): GVA --------------------------> HPA (one walk) Virtualized: GVA --> GPA --> HPA (two walks)
Why you cannot just let the guest's page table run
Here is the tempting shortcut, and why it fails. The CPU has exactly one register that points at the active page-table root — on x86 it is cr3 — and the hardware MMU walks whatever that register points to. So you might hope to just load the guest's own page table into cr3 and let the real MMU do the work. But the guest's page table maps guest-virtual to guest-physical, and guest-physical is the made-up number. If the guest maps a virtual page to guest-physical frame 0x5000 and you let the MMU use that table directly, the hardware will read real machine frame 0x5000 — which probably belongs to the host or to a different guest. That is not a performance bug; it is a total breach of isolation, the one thing a hypervisor exists to provide.
So the hypervisor faces a hard requirement: the hardware MMU must end up walking a table that maps guest-virtual straight to the correct host-physical frame, yet the guest must still be free to edit its own page tables whenever it likes, believing it controls memory. The guest cannot be told the truth — that would break the illusion and the guest's own kernel code. Two designs solve this. The older, purely-software one is the shadow page table. The newer, hardware-assisted one is nested paging, sold by Intel as EPT and by AMD as NPT. The rest of this guide is those two ideas.
Shadow page tables: the hypervisor keeps a secret copy
The shadow page table is a clever trick built on the VM exit machinery from guide 2. The idea: the guest builds its own page tables in its own memory, exactly as it would on bare metal, mapping guest-virtual to guest-physical. The hypervisor never lets the hardware use those tables directly. Instead, for each guest page table, the hypervisor maintains a shadow — a second, hidden table that the guest cannot see — which collapses both translations into one. Where the guest maps virtual page V to guest-physical frame G, the shadow maps V straight to host-physical frame H, the real machine frame the hypervisor chose to back G. Then the hypervisor loads the shadow into cr3. The real MMU walks the shadow, gets the correct host-physical address in a single walk, and the guest is never the wiser.
But there is a catch that decides everything: how does the shadow stay in sync? The guest edits its own tables freely — it adds a mapping, removes one, marks a page read-only — and the hypervisor must mirror every such change into the shadow, or the shadow goes stale and the guest sees the wrong memory. The trick is to make the guest's edits trap. The hypervisor marks the guest's real page tables as read-only in the shadow. When the guest writes to its own page table, that write hits a read-only page and triggers a VM exit; the hypervisor catches it, decodes what the guest was trying to write, applies the equivalent change to the shadow, and resumes the guest. The guest believes it freely edited memory; in truth every page-table write was intercepted and shadowed.
EPT / nested paging: let the hardware walk both tables
The fix Intel and AMD shipped is hardware-assisted nested paging — Intel's Extended Page Tables (EPT), AMD's Nested Page Tables (NPT). The insight is direct: instead of forcing the hypervisor to flatten two translations into one shadow table by hand, give the MMU a second set of page tables and teach it to walk both. The guest keeps and freely edits its own page tables (guest-virtual to guest-physical), loaded in cr3 just as on bare metal. The hypervisor separately builds the EPT, which maps guest-physical to host-physical, and points a new control register at it. Now the hardware does the two-level walk itself — guest table to get guest-physical, then EPT to get host-physical — with no hypervisor involvement per access.
This erases the shadow design's worst pain. When the guest now edits its own page tables, nothing traps — those edits only change the guest-virtual to guest-physical mapping, which the guest is genuinely allowed to control, so the hardware applies them with no VM exit at all. The hypervisor only gets involved when the EPT itself needs changing: the guest touches a guest-physical page the hypervisor has not backed with real memory yet, the MMU cannot complete the second-level walk, and that causes an EPT violation exit so the hypervisor can map in a frame. Routine guest memory activity — the fork-and-mmap storms that crushed shadow paging — now runs at near-native speed.
What the second layer buys you
Step back and notice the prize the extra translation layer hands the hypervisor: total, transparent control over what guest-physical memory really is. Because the hypervisor owns the guest-physical to host-physical map, it can play every trick the OS already plays on processes — but on whole guests. It can leave a guest-physical page unbacked until the guest first touches it (demand paging a VM into existence lazily), and it can swap a guest's idle pages out to disk without the guest knowing. It can even hand the same host-physical frame to two guests' identical pages and mark it copy-on-write, so two VMs running the same OS share one copy of read-only code until one writes — a memory saving that only the second translation layer makes possible.
One caveat keeps this honest and ties back to the whole rung. The two designs are not different goals — they are the same goal reached two ways, and which one runs depends on the hardware: a modern CPU with EPT/NPT uses nested paging, while an old chip without it falls back to software shadow paging. The guest cannot tell the difference, which is the point; it just edits its page tables and reads memory. And memory is only one of the three resources a hypervisor must virtualize. CPU you saw in guide 2; memory is here; next, guide 4 turns to I/O, where the guest talks to virtual devices — and where hardware-assisted tricks give way to the cooperative approach of paravirtualization and virtio.