[NTOS] Allocate the trap frame on the stack by decreasing esp before modifying any...
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Mon, 15 Feb 2010 20:16:15 +0000 (20:16 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Mon, 15 Feb 2010 20:16:15 +0000 (20:16 +0000)
While doing it after is a tiny optimization (no need to wait for esp to be ready) and would work with all real traps (which clear cli), it doesn't work with Zw calls that directly call KiSystemService with interrupts enabled. This caused random trap frame corruption when an interrupt fired after members of the trap frame have been set but before esp was adjusted. Should hopefully fix most random failures on real hardware and qemu.

svn path=/trunk/; revision=45598

reactos/ntoskrnl/include/internal/i386/asmmacro.S

index 7e0596e..d8ca99d 100644 (file)
@@ -115,38 +115,41 @@ MACRO(KiEnterTrap, Flags)
 
     endif
 
+    /* Make space for this frame */
+    sub esp, FrameSize
+
     /* Save nonvolatile registers */
-    mov [esp - FrameSize + KTRAP_FRAME_EBP], ebp
-    mov [esp - FrameSize + KTRAP_FRAME_EBX], ebx
-    mov [esp - FrameSize + KTRAP_FRAME_ESI], esi
-    mov [esp - FrameSize + KTRAP_FRAME_EDI], edi
+    mov [esp + KTRAP_FRAME_EBP], ebp
+    mov [esp + KTRAP_FRAME_EBX], ebx
+    mov [esp + KTRAP_FRAME_ESI], esi
+    mov [esp + KTRAP_FRAME_EDI], edi
 
     /* Save eax for system calls, for use by the C handler */
-    mov [esp - FrameSize + KTRAP_FRAME_EAX], eax
+    mov [esp + KTRAP_FRAME_EAX], eax
 
     /* Does the caller want nonvolatiles only? */
     if ((Flags AND KI_NONVOLATILES_ONLY) == 0)
         /* Otherwise, save the volatiles as well */
-        mov [esp - FrameSize + KTRAP_FRAME_ECX], ecx
-        mov [esp - FrameSize + KTRAP_FRAME_EDX], edx
+        mov [esp + KTRAP_FRAME_ECX], ecx
+        mov [esp + KTRAP_FRAME_EDX], edx
     endif
 
     /* Save segment registers? */
     if ((Flags AND KI_DONT_SAVE_SEGS) == 0)
 
         /* Check for V86 mode */
-        test byte ptr [esp - FrameSize + KTRAP_FRAME_EFLAGS + 2], (EFLAGS_V86_MASK >> 16)
+        test byte ptr [esp + KTRAP_FRAME_EFLAGS + 2], (EFLAGS_V86_MASK >> 16)
         jz not_v86_trap
 
             /* Restore V8086 segments into Protected Mode segments */
-            mov eax, [esp - FrameSize + KTRAP_FRAME_V86_DS]
-            mov ecx, [esp - FrameSize + KTRAP_FRAME_V86_ES]
-            mov [esp - FrameSize + KTRAP_FRAME_DS], eax
-            mov [esp - FrameSize + KTRAP_FRAME_ES], ecx
-            mov eax, [esp - FrameSize + KTRAP_FRAME_V86_FS]
-            mov ecx, [esp - FrameSize + KTRAP_FRAME_V86_GS]
-            mov [esp - FrameSize + KTRAP_FRAME_FS], eax
-            mov [esp - FrameSize + KTRAP_FRAME_GS], ecx
+            mov eax, [esp + KTRAP_FRAME_V86_DS]
+            mov ecx, [esp + KTRAP_FRAME_V86_ES]
+            mov [esp + KTRAP_FRAME_DS], eax
+            mov [esp + KTRAP_FRAME_ES], ecx
+            mov eax, [esp + KTRAP_FRAME_V86_FS]
+            mov ecx, [esp + KTRAP_FRAME_V86_GS]
+            mov [esp + KTRAP_FRAME_FS], eax
+            mov [esp + KTRAP_FRAME_GS], ecx
             jmp set_sane_segs
 
         not_v86_trap:
@@ -154,12 +157,12 @@ MACRO(KiEnterTrap, Flags)
             /* Save segment selectors */
             mov eax, ds
             mov ecx, es
-            mov [esp - FrameSize + KTRAP_FRAME_DS], eax
-            mov [esp - FrameSize + KTRAP_FRAME_ES], ecx
+            mov [esp + KTRAP_FRAME_DS], eax
+            mov [esp + KTRAP_FRAME_ES], ecx
             mov eax, fs
             mov ecx, gs
-            mov [esp - FrameSize + KTRAP_FRAME_FS], eax
-            mov [esp - FrameSize + KTRAP_FRAME_GS], ecx
+            mov [esp + KTRAP_FRAME_FS], eax
+            mov [esp + KTRAP_FRAME_GS], ecx
 
     endif
 
@@ -176,15 +179,12 @@ set_sane_segs:
         mov fs, ax
     endif
 
-    /* Make space for this frame */
-    sub esp, FrameSize
+    /* Set parameter 1 (ECX) to point to the frame */
+    mov ecx, esp
 
     /* Clear direction flag */
     cld
 
-    /* Set parameter 1 (ECX) to point to the frame */
-    mov ecx, esp
-
 ENDM
 
 MACRO(TRAP_ENTRY, Trap, Flags)