Instruction
RMPUPDATE
Writes a new reverse map (RMP) entry for a page, which the hypervisor uses to assign it to a guest; SEV-SNP.
An AMD extension: Intel processors do not have this instruction.
- Extensions
- Forms
- 1 (1 Legacy)
- Data
- Intel XED v2026.08.23
Forms
| Instruction | Encoding | Requires |
|---|---|---|
RMPUPDATE RAX, RCX 64-bit mode only
RMPUPDATE_RAX_RCX | F2 0F 01 FE | SNP |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
if not msr[SYSCFG] >> 24 & 1:
fault(UD) # SEV-SNP off (SYSCFG.SNPEn)
if CPL > 0:
fault(GP, 0)
spa = addr.read() & ~0xFFF # RAX: a system physical address
n = 0
if asid == 0:
n = load(src.read(), 128) # [RCX], as RMPREAD stores one
on = n >> 64 & 1 # Assigned
big = n >> 72 & 1 # Page_Size: 2 MB
fix = n >> 80 & 1 # Immutable
owner = n >> 96 # the ASID
r2m = spa & ~0x1FFFFF # the 2-MB page around spa
code = 0
if asid != 0:
code = 2 # FAIL_PERMISSION: the hypervisor
# alone, at ASID 0
elif big and spa != r2m:
code = 1 # FAIL_INPUT: off a 2-MB boundary
elif not on and (fix or owner):
code = 1 # FAIL_INPUT: a free page has
# neither
elif not in_rmp(spa):
code = 1 # FAIL_INPUT: no RMP entry
elif rmp(spa) >> 80 & 1:
code = 2 # FAIL_PERMISSION: immutable
elif not big and spa == r2m:
if rmp(spa) >> 72 & 1:
code = 4 # FAIL_OVERLAP: a 2-MB page here
elif not big:
e = rmp(r2m)
if e >> 64 & e >> 72 & 1:
code = 4 # FAIL_OVERLAP: a 2-MB page here
else:
for i in range(1, 512): # the 511 pages after, as RMPREAD
e = rmp(r2m + 4096 * i) # counts them
if e >> 64 & 1:
code = 4 # FAIL_OVERLAP: 4-KB pages here
if code == 0:
if big: # the 511 pages after: free, or
for i in range(1, 512): # assigned to none
a = r2m + 4096 * i
set_rmp(a, on << 64)
old = rmp(spa)
gpa = low(n, 64) if owner else 0
new = owner << 96 | fix << 80
new = new | big << 72 | on << 64 | gpa
moved = low(old ^ new, 128) & ~(1 << 80)
r = old >> 128 << 128 | new # Validated, VMSA and the masks
if moved: # stay, unless owner, address, size
r = new | 0x1F << 136 # or Assigned changed: then every
# permission (bits 4:0) for VMPL 0
# alone
if not on:
r = 0 # a free page: all clear
set_rmp(spa, r)
eax = code # 0: SUCCESS
of = zf = af = pf = sf = UNDEFINEDRun on AMD Zen 5 (EPYC 9645): 2 cases. Its cases ran where CPUID reported no SEV-SNP, and every one raised an exception.
Operands
| Operand | Kind | Action |
|---|---|---|
RMPUPDATE RAX, RCX 64-bit mode only | ||
RAX | explicit | read, write |
RCX | explicit | read |
RFLAGS | implicit | write |
Flags
| OF | SF | ZF | AF | PF |
|---|---|---|---|---|
| All forms | ||||
| M | M | M | M | M |
Attributes
What else XED records about the forms. How to read.
- All forms
- privileged: CPL 0 only
CPUID and processors
Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.
More SEV-SNP instructions
Sources
- Intel XED v2026.08.23 (commit
0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model. - The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s
-marchfeature sets and AMD’s Processor Programming References, which the page of each processor cites. - AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.36, March 2024), Wayback Machine copy of AMD's PDF
- AMD64 Architecture Programmer's Manual, Volume 2: System Programming (24593, rev. 3.42, March 2024), Wayback Machine copy of AMD's PDF
The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The text is our own.