2026-09-04
When you run a virtual machine, the guest OS still manages its own page tables — mapping guest virtual addresses (GVA) to guest physical addresses (GPA). But the "physical" addresses the guest sees aren't real. The hypervisor has to translate them one more time, from GPA to host physical address (HPA). This second layer is Extended Page Tables (EPT) on Intel, or Nested Page Tables (NPT) on AMD.
Before EPT (introduced in Nehalem, 2008), hypervisors did this with shadow paging: intercept every guest CR3 write and page table modification, build a merged GVA→HPA table, and hope the guest didn't scribble on its tables too often. VM exits everywhere. Terrible.
EPT moves the second translation into hardware. The VMCS points to an EPT root pointer (EPTP), and the CPU walks both trees automatically. The guest never traps for a page table update — its writes just modify guest memory.
The cost: a TLB miss now requires walking both tables. Guest page tables are 4 levels deep on x86-64. Each level's guest-physical address must be translated through EPT, which is also 4 levels deep. That's 4 × 4 + 4 = 20 memory accesses for a single TLB miss (four EPT walks for each of the four guest walk steps, plus the final EPT walk for the resulting GPA). Native: 4 accesses.
Real-world example: a database with a working set larger than the TLB can cover shows a 5-15% slowdown just from EPT walks under virtualization. AWS's Nitro system doesn't fix this — it hides the hypervisor overhead in other places (I/O, interrupts), but nested paging cost is still there. This is exactly why every serious VM workload uses huge pages in the guest AND on the host: 2MB pages skip the bottom two levels of both walks, cutting worst-case TLB miss cost from 20 to 8 memory accesses.
EPT entries have permission bits independent of the guest's page tables. The hypervisor can revoke write access to a guest page (for live migration dirty-tracking, or copy-on-write between VMs) and get an EPT violation VM exit instead of the guest seeing a fault. This is how KSM-across-VMs, live migration, and memory ballooning all work without the guest noticing.
Rule of thumb: for latency-sensitive workloads inside VMs, always enable huge pages on both sides. The TLB reach of a modern CPU with 4KB pages is ~2MB; with 2MB pages it's ~1GB. Under EPT that difference matters twice.
