https://git.reactos.org/?p=reactos.git;a=commitdiff;h=4e3c0529cf2b32be0548371ce3cd2d61d5943988

commit 4e3c0529cf2b32be0548371ce3cd2d61d5943988
Author:     Timo Kreuzer <timo.kreu...@reactos.org>
AuthorDate: Fri Sep 27 15:20:15 2024 +0300
Commit:     Timo Kreuzer <timo.kreu...@reactos.org>
CommitDate: Mon Oct 21 10:17:11 2024 +0300

    [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 | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 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 eflags */
+    mov [rcx + CxEFlags], eax
+
+    /* Store mxcsr */
+    stmxcsr [rcx + CxMxCsr]
+
+    /* Check if we are in user mode */
+    test byte ptr [rcx + CxSegCs], 3
+    jz RtlCaptureContextExit
+
     /* Store legacy floating point registers */
     fxsave [rcx + CxFltSave]
-    stmxcsr [rcx + CxMxCsr]
 
-    /* Store rflags */
-    mov [rcx + CxEFlags], eax
+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

Reply via email to