Extensions
Forms
1 (1 Legacy)
Data
Intel XED v2026.08.23

ERETS returns from an event that FRED delivered while the processor was already at CPL 0: an exception, interrupt or NMI in the kernel. It is FRED’s replacement for IRET in that case, and ERETU is the one for events from user mode. RSP must point at the frame that event delivery pushed, six quadwords up from RSP: the error code, which ERETS skips, then RIP, CS, RFLAGS, RSP and SS. It loads RIP, RFLAGS and RSP from the frame and stays at CPL 0.

What it checks

CS and SS are not loaded: their 16-bit selectors in the frame must be the ones in use, or ERETS raises #GP(0). So do a non-canonical RIP, RFLAGS with VM or a reserved bit set or bit 1 clear, and undefined bits in the CS or SS image. With supervisor shadow stacks it also pops SSP, RIP and CS from the shadow stack and compares them, raising #CP when they differ. ERETS raises #UD while FRED is off and at CPL above 0, and therefore outside 64-bit mode. Intel’s manual adds that nothing after it executes, even speculatively, before everything ahead has completed.

The event state in the frame

The upper bits of the CS and SS images carry state that IRET did not have. Bits 17:16 of CS give the stack level to return to, which ERETS can lower but never raise; bit 18 restores CET’s indirect-branch tracker waiting for ENDBRANCH. In SS, bit 16 restores the blocking that follows STI, bit 17 a pending single-step #DB, and bit 18 unblocks NMIs, so a handler that returns with that bit clear keeps them blocked.

In Linux

Linux 7.3’s arch/x86/entry/entry_64_fred.S ends its kernel entry point with ERETS. Its fred.c loads SS with the kernel’s data selector when it enables FRED: a frame pushed while SS was still null would otherwise fail ERETS’s SS check after a task switch. KVM on Intel, after a VM exit for an NMI or interrupt, runs the host’s handler through a frame of its own and returns with ERETS, which can unblock NMIs.

Not run here

The Zen 5 guest that ran the probe does not report FRED, so ERETS was not run. GNU as 2.44 and Clang 23 assemble erets as F2 0F 01 CA; Linux writes the bytes, and neither compiler has an intrinsic.

Forms

Every encoding of ERETS that Intel XED knows, one row per XED instruction form (iform). How to read the notation.
InstructionEncodingRequires
ERETS 64-bit mode only ERETSF2 0F 01 CAFRED

Operation

What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.

if not cr4 >> 32 & 1 or CPL > 0:
    fault(UD)                    # FRED off, or CPL 3: #UD, not #GP
t = load(rsp + 8, 64)            # RIP; the error code is skipped
c = load(rsp + 16, 64)           # CS, bits 18:16 event state
f = load(rsp + 24, 64)           # RFLAGS
p = load(rsp + 32, 64)           # RSP
s = load(rsp + 40, 64)           # SS, bits 18:16 event state
if not canonical(t):
    fault(GP, 0)
if c & ~0x70000 != cs:
    fault(GP, 0)                 # the same CS, no other bits
if f & 0xFFFFFFFFFFC2802A != 2:
    fault(GP, 0)                 # bit 1 set; VM, reserved bits clear
if s & 0xFFF8FFFF != ss:
    fault(GP, 0)                 # the same SS; bits 63:32 ignored
g = msr[0x1D4]                   # IA32_FRED_CONFIG
lvl = min(g & 3, c >> 16 & 3)    # the stack level, never raised
msr[0x1D4] = g & ~3 | lvl
rip = t
rsp = p
cf = f & 1
pf = f >> 2 & 1
af = f >> 4 & 1
zf = f >> 6 & 1
sf = f >> 7 & 1
tf = f >> 8 & 1
if_ = f >> 9 & 1
df = f >> 10 & 1
of = f >> 11 & 1
iopl = f >> 12 & 3
nt = f >> 14 & 1
rf = f >> 16 & 1                 # RF may come back set
vm = f >> 17 & 1                 # 0, as checked
ac = f >> 18 & 1
vif = f >> 19 & 1
vip = f >> 20 & 1
id = f >> 21 & 1
# SS bit 16: STI's blocking again, if IF is set; bit 17: a pending
# single-step #DB, if TF is set; bit 18: NMIs unblocked; CS bit 18:
# an indirect branch tracker of CET waiting for ENDBRANCH

Not run on a processor: the Zen 5 guest that ran the probe does not report FRED in CPUID.

Operands

What each form reads and writes, as Intel XED records it: the operands of its syntax, in order, and the implicit ones that the syntax does not name. How to read.
OperandKindAction
ERETS 64-bit mode only
stackimplicitread
rSPimplicitread, write
RIPimplicitwrite
RSPimplicitwrite
RFLAGSimplicitwrite

Flags

P loaded from the stack; blank: not affected. How to read.
OFSFZFAFPFCFDFIFTFACIOPLNTRFVMVIFVIPID
All forms
PPPPPPPPPPPPPPPPP

Attributes

What else XED records about the forms. How to read.

All forms
privileged: CPL 0 only; may abort a TSX transaction

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.

CPUID requirements and processors of the XED ISA sets above. Alternatives are separated by “or”; processors follow XED’s chip model, whose AMD processors end with Zen 2, and the CPU data of this site for Zen 3 to Zen 6.
ISA setCPUIDProcessors
FRED

FRED
CPUID.(EAX=07H,ECX=1):EAX[17] FRED

Panther Lake, Nova Lake, Diamond Rapids, Zen 6

More FRED instructions

Sources

  1. Intel XED v2026.08.23 (commit 0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model.
  2. The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s -march feature sets and AMD’s Processor Programming References, which the page of each processor cites.
  3. Flexible Return and Event Delivery (FRED) Specification (346446-009)
  4. Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2A, page 3-298 (ERETS)
  5. Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3 (325384-093, September 2026)
  6. Linux 7.3: arch/x86/entry/entry_32.S, entry_64.S and entry_64_fred.S, arch/x86/include/asm/gsseg.h, arch/x86/kernel/fred.c (SYSEXIT, LKGS and ERETS in the kernel's entry code)

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.