RSTORSSP - Restore Saved Shadow Stack Pointer

Opcode/ Instruction

Op/ En

64/32 bit Mode Support

CPUID Feature Flag

Description

F3 0F 01 /5 (mod!=11, /5, memory only) RSTORSSP m64

M

V/V

CET_SS

Restore SSP.

Instruction Operand Encoding

Op/En

Operand 1

Operand 2

Operand 3

Operand 4

M

ModRM:r/m (r, w)

N/A

N/A

N/A

Description

Restores SSP from the shadow-stack-restore token pointed to by m64. If the SSP restore was successful then the instruction replaces the shadow-stack-restore token with a previous-ssp token. The instruction sets the CF flag to indicate whether the SSP address recorded in the shadow-stack-restore token that was processed was 4 byte aligned, i.e., whether an alignment hole was created when the restore-shadow-stack token was pushed on this shadow stack.

Following RSTORSSP if a restore-shadow-stack token needs to be saved on the previous shadow stack, use the SAVEPREVSSP instruction.

If pushing a restore-shadow-stack token on the previous shadow stack is not required, the previous-ssp token can be popped using the INCSSPQ instruction. If the CF flag was set to indicate presence of an alignment hole, an addi- tional INCSSPD instruction is needed to advance the SSP past the alignment hole.

Operation

IF CPL = 3
   IF (CR4.CET & IA32_U_CET.SH_STK_EN) = 0
       THEN #UD; FI;
ELSE
   IF (CR4.CET & IA32_S_CET.SH_STK_EN) = 0
       THEN #UD; FI;
FI;
SSP_LA = Linear_Address(mem operand)
IF SSP_LA not aligned to 8 bytes
   THEN #GP(0); FI;
previous_ssp_token = SSP | (IA32_EFER.LMA AND CS.L) | 0x02
Start Atomic Execution
restore_ssp_token = Locked shadow_stack_load 8 bytes from SSP_LA
fault = 0
IF ((restore_ssp_token & 0x03) != (IA32_EFER.LMA & CS.L))
   THEN fault = 1; FI;      (* If L flag in token does not match IA32_EFER.LMA & CS.L or bit 1 is not 0 *)
IF ((IA32_EFER.LMA AND CS.L) = 0 AND restore_ssp_token[63:32] != 0)
   THEN fault = 1; FI;      (* If compatibility/legacy mode and SSP to be restored not below 4G *)
TMP = restore_ssp_token & ~0x01
TMP = (TMP - 8)
TMP = TMP & ~0x07
IF TMP != SSP_LA
   THEN fault = 1; FI;      (* If address in token does not match the requested top of stack *)
TMP = (fault == 0) ? previous_ssp_token : restore_ssp_token
shadow_stack_store 8 bytes of TMP to SSP_LA and release lock
End Atomic Execution
IF fault == 1
    THEN #CP(RSTORSSP); FI;
SSP = SSP_LA
// Set the CF if the SSP in the restore token was 4 byte aligned, i.e., there is an alignment hole
RFLAGS.CF = (restore_ssp_token & 0x04) ? 1 : 0;
RFLAGS.ZF,PF,AF,OF,SF := 0;

Flags Affected

CF is set to indicate if the shadow stack pointer in the restore token was 4 byte aligned, else it is cleared. ZF, PF, AF, OF, and SF are cleared.

C/C++ Compiler Intrinsic Equivalent

RSTORSSP void _rstorssp(void *);

Protected Mode Exceptions

#UD

If the LOCK prefix is used. If CR4.CET = 0. IF CPL = 3 and IA32_U_CET.SH_STK_EN = 0. IF CPL < 3 and IA32_S_CET.SH_STK_EN = 0.

#GP(0)

If linear address of memory operand not 8 byte aligned. If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit. If destination is located in a non-writeable segment. If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment selector.

#SS(0)

If a memory operand effective address is outside the SS segment limit.

#CP(rstorssp)

If L bit in token does not match (IA32_EFER.LMA & CS.L). If address in token does not match linear address of memory operand. If in 32-bit or compatibility mode and the address in token is not below 4G.

#PF(fault-code)

If a page fault occurs.

Real-Address Mode Exceptions

#UD

The RSTORSSP instruction is not recognized in real-address mode.

Virtual-8086 Mode Exceptions

#UD

The RSTORSSP instruction is not recognized in virtual-8086 mode.

Compatibility Mode Exceptions

Same as protected mode exceptions.

64-Bit Mode Exceptions

#UD

If the LOCK prefix is used. If CR4.CET = 0. If CPL = 3 and IA32_U_CET.SH_STK_EN = 0. If CPL < 3 and IA32_S_CET.SH_STK_EN = 0.

#GP(0)

If linear address of memory operand not 8 byte aligned. If a memory address is in a non-canonical form.

#SS(0)

If a memory address referencing the SS segment is in a non-canonical form.

#CP(rstorssp)

If L bit in token does not match (IA32_EFER.LMA & CS.L). If address in token does not match linear address of memory operand.

#PF(fault-code)

If a page fault occurs.