[RTL/x64] Fix RtlCaptureContext/RtlpRestoreContextInternal in kernel mode

According to tests, legacy fp state is not saved in kernel mode.
Also add an int 2c to the path that changes cs, as it should not be used and probably never will be.
This commit is contained in:
Timo Kreuzer 2024-09-27 15:20:15 +03:00
parent 467efcb423
commit 4e3c0529cf

View file

@ -94,12 +94,20 @@ PUBLIC RtlCaptureContext
movaps [rcx + CxXmm14], xmm14 movaps [rcx + CxXmm14], xmm14
movaps [rcx + CxXmm15], xmm15 movaps [rcx + CxXmm15], xmm15
/* Store legacy floating point registers */ /* Store eflags */
fxsave [rcx + CxFltSave] mov [rcx + CxEFlags], eax
/* Store mxcsr */
stmxcsr [rcx + CxMxCsr] stmxcsr [rcx + CxMxCsr]
/* Store rflags */ /* Check if we are in user mode */
mov [rcx + CxEFlags], eax test byte ptr [rcx + CxSegCs], 3
jz RtlCaptureContextExit
/* Store legacy floating point registers */
fxsave [rcx + CxFltSave]
RtlCaptureContextExit:
/* Cleanup stack and return */ /* Cleanup stack and return */
add rsp, 8 add rsp, 8
@ -119,10 +127,6 @@ PUBLIC RtlpRestoreContextInternal
.ALLOCSTACK 8 .ALLOCSTACK 8
.ENDPROLOG .ENDPROLOG
/* Restore legacy floating point registers (It is slow, so do it first) */
ldmxcsr [rcx + CxMxCsr]
fxrstor [rcx + CxFltSave]
/* Load the target stack pointer into rdx */ /* Load the target stack pointer into rdx */
mov rdx, [rcx + CxRsp] mov rdx, [rcx + CxRsp]
@ -185,6 +189,18 @@ PUBLIC RtlpRestoreContextInternal
mov r8, [rcx + CxR8] mov r8, [rcx + CxR8]
mov r9, [rcx + CxR9] mov r9, [rcx + CxR9]
/* Restore MXCSR */
ldmxcsr [rcx + CxMxCsr]
/* Check if we go to user mode */
test byte ptr [rcx + CxSegCs], 3
jz Exit
/* Restore legacy floating point registers */
fxrstor [rcx + CxFltSave]
Exit:
/* Check if we go to a different cs */ /* Check if we go to a different cs */
mov ax, cs mov ax, cs
cmp [rcx + CxSegCs], ax cmp [rcx + CxSegCs], ax
@ -208,6 +224,9 @@ PUBLIC RtlpRestoreContextInternal
ReturnFar: ReturnFar:
// We should never need this path
int HEX(2c)
/* Put cs on the stack for the far return */ /* Put cs on the stack for the far return */
mov ax, [rcx + CxSegCs] mov ax, [rcx + CxSegCs]
mov [rdx - 1 * 8], ax mov [rdx - 1 * 8], ax