From 4e3c0529cf2b32be0548371ce3cd2d61d5943988 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Fri, 27 Sep 2024 15:20:15 +0300 Subject: [PATCH] [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. --- sdk/lib/rtl/amd64/except_asm.S | 35 ++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/sdk/lib/rtl/amd64/except_asm.S b/sdk/lib/rtl/amd64/except_asm.S index b8384b6529b..a45c316ea94 100644 --- a/sdk/lib/rtl/amd64/except_asm.S +++ b/sdk/lib/rtl/amd64/except_asm.S @@ -94,12 +94,20 @@ PUBLIC RtlCaptureContext movaps [rcx + CxXmm14], xmm14 movaps [rcx + CxXmm15], xmm15 - /* Store legacy floating point registers */ - fxsave [rcx + CxFltSave] + /* Store eflags */ + mov [rcx + CxEFlags], eax + + /* Store mxcsr */ stmxcsr [rcx + CxMxCsr] - /* Store rflags */ - mov [rcx + CxEFlags], eax + /* Check if we are in user mode */ + test byte ptr [rcx + CxSegCs], 3 + jz RtlCaptureContextExit + + /* Store legacy floating point registers */ + fxsave [rcx + CxFltSave] + +RtlCaptureContextExit: /* Cleanup stack and return */ add rsp, 8 @@ -119,10 +127,6 @@ PUBLIC RtlpRestoreContextInternal .ALLOCSTACK 8 .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 */ mov rdx, [rcx + CxRsp] @@ -185,6 +189,18 @@ PUBLIC RtlpRestoreContextInternal mov r8, [rcx + CxR8] 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 */ mov ax, cs cmp [rcx + CxSegCs], ax @@ -208,6 +224,9 @@ PUBLIC RtlpRestoreContextInternal ReturnFar: + // We should never need this path + int HEX(2c) + /* Put cs on the stack for the far return */ mov ax, [rcx + CxSegCs] mov [rdx - 1 * 8], ax