AMD SEV and SEV-SNP
Secure Encrypted Virtualization (SEV) is AMD’s family of hardware features that encrypt a guest virtual machine’s memory — and, in later generations, its CPU register state and the integrity of its page mappings — with a key that the hypervisor never sees, so that even a fully compromised or malicious host cannot read or silently tamper with the guest. It comes in three escalating generations: plain SEV (memory encryption, since 2017’s EPYC “Naples”), SEV-ES (“Encrypted State”, adding register-state encryption), and SEV-SNP (“Secure Nested Paging”, adding integrity so the host cannot remap, replay, or alias guest pages). Each guest is keyed by a unique encryption key derived and managed inside the AMD Secure Processor (AMD-SP, historically “PSP”, the Platform Security Processor), a separate ARM core on the die that the host CPU cannot inspect. The defining design goal is to remove the host operator and the hypervisor from the guest’s Trusted Computing Base (TCB) — the radical inversion of the classic virtualization trust model where the hypervisor is omnipotent. This note traces all three generations and pins their Linux/KVM support dates; the broader rationale lives in Confidential Computing and the Trust Boundary and the proof-of-isolation in Attestation for Confidential VMs.
This note pins to the 6.12 LTS kernel (2024-11-17) and dates every support claim. The headline facts, all verified below against primary sources: SEV host support landed in Linux 4.16 (2018); SEV-ES host support in 5.11 (2021); and crucially SEV-SNP host (hypervisor) support in 6.11 (2024) — fully present in 6.12 — while SEV-SNP guest support (running Linux as an SNP guest) landed earlier, in 5.19 (2022).
Mental Model — Three Concentric Threats, Three Generations
The clean way to think about the SEV generations is as three escalating answers to three escalating threats from a malicious hypervisor. Generation one assumes the host might read your RAM, and encrypts it. Generation two assumes the host might read your registers when your VM exits, and encrypts those too. Generation three assumes the host might lie about which physical page backs which guest page — remapping, replaying old contents, or aliasing two guest pages onto one — and adds a cryptographically-enforced integrity structure to make that impossible.
flowchart TB subgraph T1["SEV (4.16): confidentiality of RAM"] A["Guest RAM encrypted with per-VM key<br/>(AES via memory controller, keyed by ASID)<br/>C-bit in guest page table selects encrypted"] end subgraph T2["SEV-ES (5.11 host): + confidentiality of CPU state"] B["Register state encrypted into the VMSA on VM exit<br/>#VC exception + GHCB mediate host communication"] end subgraph T3["SEV-SNP (6.11 host): + integrity of mappings"] C["Reverse Map Table (RMP): one entry per 4K page<br/>records the single legal owner+GPA of each page<br/>RMPCHECK on every guest access stops remap/replay/alias"] end T1 --> T2 --> T3 PSP["AMD Secure Processor (AMD-SP / PSP)<br/>owns keys, runs launch/attestation firmware<br/>host CPU cannot read it"] PSP -.->|derives & holds keys| T1 PSP -.->|signs attestation report| T3
The three SEV generations as escalating defenses. What it shows: each generation strictly adds protection — SEV encrypts memory, SEV-ES additionally encrypts the register state that leaks on every VM exit, and SEV-SNP additionally guarantees that the host cannot violate the integrity of the guest’s memory map. The AMD Secure Processor underpins all three by holding keys the host cannot read. The insight to take: encryption alone (SEV/SEV-ES) stops the host from reading the guest, but a malicious host can still corrupt a guest by swapping pages behind its back — only SEV-SNP’s Reverse Map Table closes that integrity gap, which is why SNP is the generation cloud providers actually attest as “confidential.”
SEV — Per-VM Memory Encryption (host support: Linux 4.16)
The foundation is straightforward in concept. AMD EPYC processors contain an AES engine in the memory controller that transparently encrypts and decrypts data as it moves between the cache hierarchy and DRAM. SEV builds on the older Secure Memory Encryption (SME) feature (merged in Linux 4.14) but gives each VM its own key instead of one platform-wide key (Phoronix, Linux 4.16). The key is tied to an Address Space Identifier (ASID) — the same hardware tag the TLB uses to keep one VM’s translations from matching another’s. SEV support was queued in KVM for Linux 4.16 (early 2018) after nine rounds of patch review (Phoronix, Linux 4.16).
Which physical pages get encrypted is selected by a single bit in the guest’s own page-table entries: the C-bit (“encrypted” bit), a high physical-address bit (its exact position is reported by CPUID 0x8000001F). When the guest maps a page with the C-bit set, accesses to that page are encrypted with the VM’s key; with the C-bit clear, the page is shared cleartext that the host can read — used for things like the virtio rings and DMA bounce buffers. In the KVM source the C-bit appears as sev_me_mask, initialised from CPUID during hardware setup (sev_me_mask = 1UL << (ebx & 0x3f)) and OR’d into guest physical addresses during privileged operations such as migration (data.guest_address |= sev_me_mask;) (v6.12 arch/x86/kvm/svm/sev.c).
The key never touches the host CPU. The AMD Secure Processor (AMD-SP) — an on-die ARM Cortex co-processor, historically the “Platform Secure Processor” or PSP — runs the SEV firmware that generates the key, binds it to the ASID, and later signs attestation reports. The host kernel talks to it only through a narrow command interface (the /dev/sev CCP driver), never seeing key material. This is what makes “the host cannot read the guest” a hardware guarantee rather than a software promise.
KVM exposes SEV to userspace through one umbrella ioctl, KVM_MEMORY_ENCRYPT_OP, carrying a struct kvm_sev_cmd that selects a sub-command. The classic SEV launch is a measured boot sequence (kernel docs): KVM_SEV_LAUNCH_START creates the encryption context; KVM_SEV_LAUNCH_UPDATE_DATA encrypts each region of the initial guest image in place and folds it into a running cryptographic measurement; KVM_SEV_LAUNCH_MEASURE returns that measurement (so the guest owner can verify what was loaded before trusting the VM); KVM_SEV_LAUNCH_FINISH transitions the guest to runnable; and KVM_SEV_LAUNCH_SECRET lets the owner inject secrets after validating the measurement. Modern kernels prefer KVM_SEV_INIT2, which “replaces the deprecated KVM_SEV_INIT and KVM_SEV_ES_INIT commands” and requires the VM to have been created with machine type KVM_X86_SEV_VM or KVM_X86_SEV_ES_VM (v6.12 docs).
SEV’s gap is what it does not protect. The guest’s register state is still saved into ordinary host-readable memory on a VM exit, so a host that triggers an exit can read (and forge) the guest’s registers. And the host can freely swap, remap, or replay the guest’s encrypted pages — it cannot read them, but the ciphertext is just bytes the host owns, so it can move them around, replay an old encrypted value, or point two guest addresses at the same ciphertext. SEV-ES and SEV-SNP close those two holes respectively.
SEV-ES — Encrypted State, the VMSA, VC, and the GHCB (host support: Linux 5.11)
SEV-ES (“Encrypted State”) adds protection of the guest CPU register state. The mechanism is the VMSA (VM Save Area) — the per-vCPU region into which the CPU saves the full register file on a VM exit. Under SEV-ES the VMSA is itself encrypted with the guest’s key, so when the vCPU exits to the host, the host sees only ciphertext where the registers used to be. SEV-ES guest support — i.e. running Linux itself as an SEV-ES guest — landed in Linux 5.10 (kernelnewbies 5.10; Phoronix), and the corresponding host/hypervisor support — KVM gaining the ability to run SEV-ES guests — landed one release later in Linux 5.11, whose changelog states verbatim: “Add support for running SEV-ES guests under KVM” (kernelnewbies 5.11).
Encrypting the register state breaks the normal trap-and-emulate contract, because the host can no longer read the guest’s registers to figure out why it exited or to emulate an instruction. The fix is two coupled mechanisms. First, the VC exception (VMM Communication exception, vector 29): when an SEV-ES guest executes an instruction that would normally cause a VM exit the host must service (CPUID, certain MSR accesses, MMIO, port I/O), the CPU instead delivers a VC inside the guest. The guest’s VC handler decides what information the host legitimately needs and writes only that into a shared, unencrypted page. Second, that shared page is the GHCB (Guest-Hypervisor Communication Block): an area of cleartext memory, declared by the guest via the GHCB MSR, through which the guest hands the host exactly the register values required for the requested service and no more (LWN, “Linux as SEV-ES Guest Support”; LWN, “SEV-ES hypervisor support”). The host services the request via the VMGEXIT instruction/exit code and writes results back into the GHCB. The kernel docs note ghcb_version must be 0 for SEV virtual machines, as they do not issue GHCB requests — only SEV-ES and SNP guests use the GHCB (kernel docs).
The conceptual shift SEV-ES forces is that the guest becomes a cooperative participant in its own virtualization: instead of the host transparently emulating behind the guest’s back, the guest’s VC handler chooses what to expose. This “paravisor”/cooperative model is inherited and deepened by SEV-SNP and is the direct analogue of Intel TDX’s VE exception and TDVMCALL (see Intel TDX (Trust Domain Extensions)).
SEV-SNP — Integrity via the Reverse Map Table (host support: Linux 6.11)
SEV and SEV-ES guarantee confidentiality but not integrity. A malicious host still controls the second-level (nested) page tables — the NPT that maps guest-physical to host-physical addresses — and therefore can mount three classic attacks: remapping (point a guest page at different physical memory), replay (restore a stale encrypted value the guest already overwrote), and aliasing (map two guest-physical pages to the same physical page so a write to one corrupts the other). SEV-SNP (“Secure Nested Paging”) closes all three with a single new hardware structure.
That structure is the Reverse Map Table (RMP): a single system-wide table with one entry per 4 KiB physical page of DRAM. Each RMP entry records the one legitimate owner of that page — which guest (ASID) owns it, the guest-physical address (GPA) it is allowed to be mapped at, its page size, and a validated bit. The “reverse” in the name is the key idea: ordinary page tables map GPA → HPA (forward); the RMP records, for each HPA, the single GPA and owner it may serve (reverse). On every access by a guest to a private page, the hardware performs an RMPCHECK: it walks the normal NPT to get the host-physical page, then consults the RMP entry for that page and verifies that the owner, the GPA, and the page size all match what the guest expected. If the host has remapped, replayed, or aliased the page, the RMP entry will not match and the access faults — turning a silent corruption into a detectable PF / RMP violation. This is why only SNP, not plain SEV, is what clouds actually attest as confidential.
Two new instructions let the guest control RMP state. PVALIDATE is executed by the guest to mark a page “validated” — the guest, not the host, decides a page is legitimately part of its address space, and a page can be validated for only one GPA at a time (this single-validation rule is precisely what defeats aliasing and double-mapping). RMPUPDATE / RMPADJUST let privileged software adjust RMP entries and page permissions. Page-size splits (a 2 MiB RMP entry into 4 KiB) use PSMASH.
On the host side, KVM’s SNP support — present and complete in v6.12 — implements the full launch and runtime machinery. The launch flow is the SNP analogue of the SEV one, documented in v6.12: KVM_SEV_SNP_LAUNCH_START initialises the SNP guest context, KVM_SEV_SNP_LAUNCH_UPDATE loads/measures/encrypts GPA ranges, and KVM_SEV_SNP_LAUNCH_FINISH completes the launch (optionally with an ID block and authentication) (v6.12 docs). In the source, arch/x86/kvm/svm/sev.c carries the host functions: snp_context_create() (allocates the firmware context via SNP_GCTX_CREATE), snp_launch_start(), snp_launch_update(), snp_launch_update_vmsa() (encrypts each vCPU’s VMSA), snp_launch_finish(), snp_bind_asid() (binds the ASID via SNP_ACTIVATE), and snp_decommission_context(). RMP and page-state operations appear as kvm_rmp_make_shared() (transition a page to hypervisor-owned), snp_page_reclaim() (SNP_PAGE_RECLAIM), and snp_rmptable_psmash(). A new SNP-specific VM type, KVM_X86_SNP_VM, gates this: the code sets sev->vmsa_features |= SVM_SEV_FEAT_SNP_ACTIVE when vm_type == KVM_X86_SNP_VM (v6.12 sev.c).
A second runtime mechanism is the Page State Change (PSC): because a page can be either private (RMP-tracked, encrypted) or shared (cleartext, host-visible), the guest must coordinate with the host to flip a page between the two states — for example to set up a shared DMA buffer. KVM handles PSC requests via snp_begin_psc() / snp_begin_psc_msr() and completes them with snp_complete_psc() / __snp_complete_one_psc() (v6.12 sev.c).
Uncertain
Verify: the exact RMP entry field layout (owner ASID, assigned GPA, validated bit, page size, immutable bit) as stated here. Reason: this note’s RMP-field description is synthesized from the kernel source function names plus the AMD SNP architecture, not quoted field-by-field from the AMD “SEV Secure Nested Paging Firmware ABI Specification” / APM Vol. 2 §15.36, which was not fetched in this task. To resolve: cross-check against the AMD64 Architecture Programmer’s Manual Volume 2, “Secure Nested Paging” section, and the AMD SNP ABI spec. The kernel-version claims below (host = 6.11) are independently verified and are not affected by this flag. uncertain
Version pinning — the resolved timeline
The whole point of dating these is that secondary sources routinely conflate “guest” support (running Linux inside an SNP VM) with “host” support (KVM able to run SNP VMs), and these landed in different releases:
| Feature | First mainline kernel | Date | Primary evidence |
|---|---|---|---|
| SEV host (KVM runs SEV guests) | 4.16 | 2018 | Phoronix Linux 4.16 (SEV queued in KVM for 4.16) |
| SEV-ES guest (Linux as SEV-ES guest) | 5.10 | 2020 | kernelnewbies 5.10 |
| SEV-ES host (KVM runs SEV-ES guests) | 5.11 | 2021 | kernelnewbies 5.11: “Add support for running SEV-ES guests under KVM” |
| SEV-SNP guest (Linux as SNP guest) | 5.19 | 2022 | kernelnewbies 5.19 |
| SEV-SNP host (KVM runs SNP guests) | 6.11 | 2024 | kernelnewbies 6.11: “Add AMD Secure Nested Paging (SEV-SNP) Hypervisor Support”; code present in v6.12 sev.c |
This resolves the standing uncertainty flag in the Linux Virtualization MOC header: SEV-SNP host support = Linux 6.11 (verified verbatim against the kernelnewbies 6.11 changelog and confirmed by the presence of snp_launch_* and RMP functions in v6.12 sev.c); SEV-SNP guest support = Linux 5.19. The task brief’s hints (~6.11 host, ~5.19 guest) are both correct.
Configuration — Launching an SEV-SNP Guest with QEMU
A confidential VM is configured at the VMM, not in the guest. The QEMU object below is illustrative of the SNP launch interface; flag names track QEMU’s sev-snp-guest object.
qemu-system-x86_64 \
-machine q35,confidential-guest-support=sev0 \ # bind the machine to an SEV object
-object sev-snp-guest,id=sev0,\ # SEV-SNP (not plain "sev-guest" = SEV/SEV-ES)
cbitpos=51,\ # C-bit position (reported by CPUID 0x8000001F)
reduced-phys-bits=1,\ # phys-addr bits consumed by the C-bit
policy=0x30000 \ # SNP guest policy (min ABI, SMT, debug bits...)
-cpu EPYC-Milan-v2 \ # an SNP-capable AMD vCPU model
-bios OVMF.fd \ # measured firmware folded into the launch digest
...Line-by-line: confidential-guest-support=sev0 is what flips the VM into a confidential machine type (KVM creates it as KVM_X86_SNP_VM); cbitpos/reduced-phys-bits tell QEMU where the encryption C-bit sits so it can build correct page tables and not treat the C-bit as a real address bit; policy is the SNP guest policy bitmask the AMD-SP enforces (e.g. whether debug is allowed, whether SMT is permitted, the minimum firmware ABI) and is itself part of the attested measurement; the -bios OVMF.fd is the open-source UEFI firmware whose bytes are measured by KVM_SEV_SNP_LAUNCH_UPDATE so the guest owner can verify, via attestation, exactly which firmware booted. See libvirt’s SEV launch-security guide for the libvirt-domain equivalents.
Uncertain
Verify: the exact QEMU object name (
sev-snp-guest) and property names (cbitpos,reduced-phys-bits,policy) and a representativepolicyvalue for the QEMU version paired with a 6.12 host. Reason: the QEMU SNP object interface is illustrative here and was not re-fetched from QEMU’sdocs/system/i386/amd-memory-encryption.rstduring this task; QEMU property names have shifted across versions. To resolve: check the QEMU docs for the exact release used. uncertain
Failure Modes and Common Misunderstandings
“SEV encrypts everything, so the host can’t attack the guest.” False for SEV and SEV-ES. They guarantee confidentiality, not integrity: the host cannot read the guest, but it can still remap/replay/alias the encrypted pages and corrupt the guest in controlled ways. Only SEV-SNP’s RMP closes the integrity gap. Treating SEV/SEV-ES as equivalent to SNP is the single most common and most dangerous misconception.
The “guest vs host support” version trap. Saying “SEV-SNP has been in Linux since 5.19” is ambiguous and usually wrong in context: 5.19 added the ability to run Linux as an SNP guest, but a cloud operator’s host could not run SNP VMs with mainline KVM until 6.11. Always specify which side.
Unaccepted-memory crashes. Under SNP a guest must PVALIDATE a page before using it as private memory; touching a not-yet-validated page faults. Early SNP guest kernels and bootloaders that did not understand “unaccepted memory” would crash on boot — the reason the UEFI unaccepted-memory memory-type and kernel support were added alongside SNP.
Migration is hard. Because guest RAM is encrypted with a key the host never sees, you cannot just copy pages to migrate. SEV provides KVM_SEV_SEND_START / SEND_UPDATE_DATA / RECEIVE_* to re-encrypt pages for transport between two attested hosts (kernel docs) — but this reshapes the whole live-migration story and is far more constrained than ordinary migration.
Debug is deliberately limited. KVM_SEV_DBG_DECRYPT / KVM_SEV_DBG_ENCRYPT exist but only work if the guest’s policy permits debug; an attested production guest disallows them, so you cannot attach a host debugger to peek at guest memory — by design.
Alternatives — SEV-SNP vs Intel TDX
The direct competitor is Intel TDX (see Intel TDX (Trust Domain Extensions)). They reach the same goal — remove the host from the guest TCB — by structurally different means, and the honest contrast is worth internalizing:
- Integrity mechanism. AMD uses the Reverse Map Table (RMP), a flat per-physical-page ownership table checked by the CPU on every access. Intel uses Secure-EPT: a second, hardware-managed extended page table for private memory that only the TDX module can edit, so the host literally cannot author private mappings. RMP overlays integrity on top of the host-controlled NPT; Secure-EPT takes the private page tables away from the host entirely.
- Trusted intermediary. AMD’s root of trust is the AMD Secure Processor (AMD-SP/PSP), a separate on-die ARM core running signed firmware. Intel’s is the TDX module, an attested software module running in a special CPU mode (SEAM) — software, but measured and isolated from both host and guest. AMD trusts a co-processor; Intel trusts a measured module.
- Guest cooperation. Both push work into the guest. AMD uses the VC exception + GHCB; Intel uses the VE exception + TDVMCALL/GHCI. The patterns are near-mirror-images.
- Maturity in mainline. SEV-SNP host support is the older of the two in Linux — 6.11 vs TDX-host’s 6.16 — so on equal-vintage kernels AMD’s confidential-VM story has been runnable longer.
Neither is strictly “better”; they are the two hardware ecosystems, and a workload’s choice is dictated by the CPU it runs on more than by a feature comparison. The shared concepts (private/shared memory, attestation, cooperative guests) are covered once in Confidential Computing and the Trust Boundary.
Production Notes
Every major cloud’s “confidential VM” offering on AMD silicon is SEV-SNP, not bare SEV — Google Cloud Confidential VMs, Azure Confidential VMs, and AWS (on EPYC) all attest the SNP measurement and policy before releasing secrets to the guest. The guest-side attestation flow uses the SEV-guest driver and the SNP_GET_REPORT interface documented in the SEV guest API docs; the report is signed by a key rooted in the AMD-SP and chains to AMD’s signing keys, which a relying party verifies. A practical operational gotcha is that SNP requires a coordinated stack — a recent-enough host kernel (≥ 6.11 mainline, or a vendor backport such as the one Fedora/RHEL ships), SNP-aware firmware on the AMD-SP, an SNP-capable OVMF, and a guest kernel that understands unaccepted memory and PVALIDATE. Version-skew between these layers is the most common reason an SNP VM fails to launch in practice; the AMD AMDSEV repository and the Fedora “Confidential Virtualization Host with AMD SEV-SNP” change exist precisely to pin a known-good combination.
Uncertain
Verify: that all three named clouds (Google, Azure, AWS) attest specifically the SNP measurement (vs SEV-ES) as of 2026, and the exact
SNP_GET_REPORTioctl name in the 6.12 guest driver. Reason: cloud-provider feature claims are point-in-time and were not re-confirmed against each provider’s 2026 docs in this task; the guest-driver ioctl name is from the kernel coco docs but not line-verified against the v6.12 driver source. To resolve: check each provider’s confidential-computing docs anddrivers/virt/coco/sev-guest/in v6.12. uncertain
See Also
- Intel TDX (Trust Domain Extensions) — the Intel counterpart; RMP vs Secure-EPT, AMD-SP vs TDX-module, GHCB vs TDVMCALL
- Confidential Computing and the Trust Boundary — the shared rationale: moving the host out of the guest TCB
- Attestation for Confidential VMs — how a remote party verifies an SNP measurement before trusting the VM
- Guest Physical Memory and Memory Slots — the GPA→HPA mapping that the RMP overlays integrity onto
- Two-Dimensional Paging (EPT and NPT) — the NPT that the host controls and SNP must therefore police
- Dirty Page Tracking and Live Migration — why encrypted guest RAM reshapes migration
- Nested Virtualization — sibling §9 frontier topic
- Linux Virtualization MOC — parent map (§9 Nested Virtualization and Confidential Computing)