43 lines
3.0 KiB
Markdown
Executable File
43 lines
3.0 KiB
Markdown
Executable File
# SYSRET — Return from Fast System Call
|
|
|
|
## Description
|
|
|
|
SYSRET is a companion instruction to the SYSCALL instruction. It returns from an OS system-call handler to user code at privilege level 3. It
|
|
does so by loading RIP from RCX and loading RFLAGS from R11.1 With a 64-bit operand size, SYSRET remains in 64-bit mode; otherwise, it enters
|
|
compatibility mode and only the low 32 bits of the regis- ters are loaded.
|
|
|
|
## Instruction
|
|
|
|
| Opcode | Assembly | Op/En | Modern Mode | Legacy Mode | Description |
|
|
|---------------|----------|-------|-------------|-------------|-------------------------------------------------------------------------------|
|
|
| 0F 07 | SYSRET | NP | Valid | Invalid | Return to compatibility mode from fast system call. |
|
|
| REX.W + 0F 07 | SYSRET | NP | Valid | Invalid | Return to 64-bit mode from fast system call. |
|
|
|
|
## Information
|
|
|
|
SYSRET loads the CS and SS selectors with values derived from bits 63:48 of the IA32_STAR MSR. However, the CS and SS descriptor caches are not
|
|
loaded from the descriptors (in GDT or LDT) referenced by those selectors. Instead, the descriptor caches are loaded with fixed values. See the
|
|
Operation section for details. It is the respon- sibility of OS software to ensure that the descriptors (in GDT or LDT) referenced by those
|
|
selector values corre- spond to the fixed values loaded into the descriptor caches; the SYSRET instruction does not ensure this correspondence.
|
|
|
|
The SYSRET instruction does not modify the stack pointer (ESP or RSP). For that reason, it is necessary for software to switch to the user
|
|
stack. The OS may load the user stack pointer (if it was saved after SYSCALL) before executing SYSRET; alternatively, user code may load the
|
|
stack pointer (if it was saved before SYSCALL) after receiving control from SYSRET.
|
|
|
|
If the OS loads the stack pointer before executing SYSRET, it must ensure that the handler of any interrupt or exception delivered between
|
|
restoring the stack pointer and successful execution of SYSRET is not invoked with the user stack. It can do so using approaches such as the
|
|
following:
|
|
|
|
- External interrupts. The OS can prevent an external interrupt from being delivered by clearing EFLAGS.IF before loading the user stack
|
|
pointer.
|
|
|
|
- Nonmaskable interrupts (NMIs). The OS can ensure that the NMI handler is invoked with the correct stack by using the interrupt stack table
|
|
(IST) mechanism for gate 2 (NMI) in the IDT .
|
|
|
|
- General-protection exceptions (#GP). The SYSRET instruction generates #GP(0) if the value of RCX is not canonical. The OS can address this
|
|
possibility using one or more of the following approaches:
|
|
|
|
1) Confirming that the value of RCX is canonical before executing SYSRET.
|
|
2) Using paging to ensure that the SYSCALL instruction will never save a non-canonical value into RCX.
|
|
3) Using the IST mechanism for gate 13 (#GP) in the IDT.
|