a shadow page table
Before CPUs could translate guest-physical to host-physical addresses in hardware (nested paging), hypervisors faced a puzzle: the guest manages its own page tables mapping guest-virtual to guest-physical, but the real memory unit can only do one translation, and it must land on a real host-physical address. The shadow page table is the clever software answer. The hypervisor secretly builds and maintains its OWN page table - the 'shadow' - that maps guest-virtual addresses directly to host-physical addresses, collapsing the two layers into the single table the real hardware actually uses.
Here is the catch that makes it hard. The guest keeps editing its own page tables, blissfully unaware the shadow exists, so the shadow must be kept in sync. The trick is to mark the guest's real page tables as read-only to the hardware. When the guest tries to modify them, the write traps (a VM-exit); the hypervisor wakes up, sees which mapping the guest changed, recomputes the corresponding host-physical entry by composing the guest's intended guest-physical with its own guest-physical-to-host-physical map, updates the shadow, and resumes. The hardware then translates using the up-to-date shadow, fast - until the next guest page-table edit traps again.
Why it matters and why it died back: shadow paging worked and was the ONLY way to virtualize memory on hardware without EPT/NPT, but it was painful. Every guest context switch could require a fresh or rebuilt shadow, and page-table-heavy workloads (forking processes, booting) generated storms of trap-emulate-resync exits that dominated the cost. That pain is precisely what motivated Intel EPT and AMD NPT - hardware nested paging that lets the guest edit its own tables freely with no traps. Today shadow paging survives mainly as a fallback on older or constrained hardware, and as the clearest way to understand WHY nested paging was such a relief.
The guest maps guest-virtual 0x4000 to guest-physical 0x9000. The hypervisor knows guest-physical 0x9000 really lives at host-physical 0x3A2000, so its shadow table maps 0x4000 straight to 0x3A2000. When the guest later remaps 0x4000, the write to its page table traps, and the hypervisor patches the shadow to match.
The shadow collapses guest-virtual-to-host-physical into one table; guest edits trap to keep it in sync.
Shadow paging is the software predecessor to hardware nested paging (EPT/NPT), not a complement to it - you typically use one or the other. Its trap-on-every-page-table-write cost is exactly what nested paging eliminated.