Anonymous user
SYSENTER: Difference between revisions
no edit summary
[unchecked revision] | [unchecked revision] |
m (it's -> its: Grammar fix) |
No edit summary |
||
(18 intermediate revisions by 12 users not shown) | |||
Line 1:
==Introduction==
The SYSENTER/SYSEXIT instructions (and
==INTEL: SYSENTER/SYSEXIT==
Line 10:
====MSRs====
'''These must be accessed through rdmsr and wrmsr'''<br/>
*IA32_SYSENTER_CS (0x174)
** Contains ring 0 code segment (CS).
These values cannot be changed, therefore your [[GDT]] must be structured as such.▼
** Ring 0 data = CS + 8.
** If REX.W prefix is used with SYSEXIT, ring 3 code = CS + 32 and ring 3 data = CS + 40.
** Otherwise, ring 3 code = CS + 16 and ring 3 data = CS + 24.
▲<b>These values cannot be changed, therefore your [[GDT]] must be structured as such.</b>
*IA32_SYSENTER_ESP (0x175) - The kernel's ESP for SYSENTER.
*IA32_SYSENTER_EIP (0x176) - The kernel's EIP for SYSENTER. This is the address of your SYSENTER entry point.
====CPU registers====
'''These must be set by the application, or the C library wrapper'''<br />
Line 46 ⟶ 51:
*CSTAR (0xC0000083) - The kernel's RIP for SYSCALL in compatibility mode.
*SFMASK (0xC0000084) - The low 32 bits are the SYSCALL flag mask. If a bit in this is set, the corresponding bit in rFLAGS is cleared.
===Operation===
NOTE: these instructions assume a flat segmented memory model (paging allowed). They require that "the code-segment base, limit, and attributes (except for CPL) are consistent for all application and system processes." --AMD System programming
SYSCALL loads CS from STAR 47:32. It masks EFLAGS with SFMASK. Next it stores EIP in ECX. It then loads EIP from STAR 32:0 and SS from STAR 47:32 + 8. It then executes.
Line 57 ⟶ 58:
'''Note that the Kernel does not automatically have a kernel stack loaded. This is the handler's responsibility.'''
SYSRET loads CS from STAR 63:48. It loads EIP from ECX and SS from STAR 63:48 + 8.
'''Note that the User
====64 bit mode====
The operation in 64 bit mode is the same,
'''In Long Mode, userland CS will be loaded from STAR 63:48 + 16 and userland SS from STAR 63:48 + 8 on SYSRET. You may need to modify your GDT accordingly.'''
==Compatability across Intel and AMD==▼
For a 32bit kernel, SYSENTER/SYSEXIT are the only compatible pair. For a 64bit kernel in Long mode only (not Long Compat mode), SYSCALL/SYSRET are the only compatible pair. For Intel 64bit, IA32_EFER.SCE must be set, or SYSCALL will result in a #UD exception.▼
Moreover, SYSRET will return to compatibility mode if the operand size is set to 32 bits, which is, for instance, nasm's default. To explicitly request a return into long mode, set the operand size to 64 bits (e.g. "o64 sysret" with nasm).
▲For a 32bit kernel, SYSENTER/SYSEXIT are the only compatible pair. For a 64bit kernel in Long mode only (not Long Compat mode), SYSCALL/SYSRET are the only compatible pair. For Intel 64bit, IA32_EFER.SCE must be set, or SYSCALL will result in a #UD exception. IA32_EFER is an MSR at 0xC0000080, and SCE (SYSCALL Enable) is its 0th bit.
==Security of SYSRET==
For both AMD and Intel, it is up to the kernel to switch stack back to the userspace stack before executing SYSRET. This opens a race condition where the NMIs and MCEs exception handlers will be executed on a guest controlled stack. For 64bit mode, the kernel must use Interrupt Stack Tables to safely move NMIs/MCEs onto a properly designated kernel stack. For 32bit mode AMD systems, the kernel must use Task Gates for NMIs and MCEs to switch stack.
All Intel CPUs to date (2013) have a silicon bug when executing the SYSRET instruction. If a non-canonical address is present in RCX when executing SYSRET, a General Protection Fault will be taken in CPL0 with CPL3 registers. See [http://lists.xen.org/archives/html/xen-announce/2012-06/msg00001.html
[[Category:X86 CPU]]
[[de:Syscall/sysret]]
==See also==
===External Links===
*https://cdrdv2.intel.com/v1/dl/getContent/671200 Page 1882 for SYSRET
[[Category:System Calls]]
|