[ros-diffs] [sir_richard] 45052: Patch that fixes VMWare boot (and should fix QEMu/KVM boot on the testbot): [NTOS]: A trap can get us into a state where DS/ES are invalid, making any pointer dereference (on DS/ES segmented memory, not SS, the stack) crash (and probably double-fault). Therefore, we have to be careful to switch to a good DS/ES before touching the TrapFrame pointer, which we don't have in ESP like the ASM code, but in a DS/ES-segmented register. For V8086 traps we can switch to the good DS/ES immediately, but for other kinds of traps, we actually need to save the current (bad) segments first. So we save them on the stack now, then switch to the good ones, then store the stack values into the trap frame. This is what happens on a non-optimized (-O0) build. On an optimized build, the segments will end up in registers instead, which is fine too (they'll be direct values). The order of instructions is guaranteed since the segment macros are volatile. [NTOS]: The GPF and Invalid Opcode handlers are performance critical when talking about V8086 traps, because they control the main flow of execution during that mode (GPFs will be issued for any privileged instruction we need to emulate, and invalid opcode might be generated for BOPs). Because of this, we employ a fast entry/exit macro into V8086 mode since we can make certain assumptions. We detect, and use, such scenarios when the V8086 flag is enabled in EFLAGS. However, because we can land in a GPF handler with an invalid DS/ES, as some V8086 code could trample this during BIOS calls for example, we must make sure that we are on a valid DS/ES before dereferencing any pointer. We fixup DS/ES either in KiEnterTrap (for normal entry/exit) or, for V86, in KiEnterV86Trap. Notice the problem: we need to detect which of these to use early on but we can't touch the EFLAGS in the frame because DS/ES could be invalid. Thankfully SS is always guaranteed valid, so stack dereferences are game! We therefore read the EFLAGS here, in assembly, where we can touch ESP as we please. We save this in EDX, which will be used as the second argument for the FASTCALL C trap entry. When we make the fast V86 check, we use the parameter instead of the trap frame, leading us to using the correct trap entry function, which fixes up DS/ES and lets us go on our merry way... [NTOS]: Make appropriate changes to GENERATE_TRAP_HANDLERS macro. [NTOS]: Switch to using well-known NT trap handler names (hex-based, double-zeroed) instead of decimal-based trap handler names which are confusing. [NTOS]: Clean up some debug spew.

sir_richard at svn.reactos.org sir_richard at svn.reactos.org
Tue Jan 12 06:50:45 CET 2010


Author: sir_richard
Date: Tue Jan 12 06:50:45 2010
New Revision: 45052

URL: http://svn.reactos.org/svn/reactos?rev=45052&view=rev
Log:
Patch that fixes VMWare boot (and should fix QEMu/KVM boot on the testbot):
[NTOS]: A trap can get us into a state where DS/ES are invalid, making any pointer dereference (on DS/ES segmented memory, not SS, the stack) crash (and probably double-fault). Therefore, we have to be careful to switch to a good DS/ES before touching the TrapFrame pointer, which we don't have in ESP like the ASM code, but in a DS/ES-segmented register. For V8086 traps we can switch to the good DS/ES immediately, but for other kinds of traps, we actually need to save the current (bad) segments first. So we save them on the stack now, then switch to the good ones, then store the stack values into the trap frame. This is what happens on a non-optimized (-O0) build. On an optimized build, the segments will end up in registers instead, which is fine too (they'll be direct values). The order of instructions is guaranteed since the segment macros are volatile.
[NTOS]: The GPF and Invalid Opcode handlers are performance critical when talking about V8086 traps, because they control the main flow of execution during that mode (GPFs will be issued for any privileged instruction we need to emulate, and invalid opcode might be generated for BOPs). Because of this, we employ a fast entry/exit macro into V8086 mode since we can make certain assumptions. We detect, and use, such scenarios when the V8086 flag is enabled in EFLAGS. However, because we can land in a GPF handler with an invalid DS/ES, as some V8086 code could trample this during BIOS calls for example, we must make sure that we are on a valid DS/ES before dereferencing any pointer. We fixup DS/ES either in KiEnterTrap (for normal entry/exit) or, for V86, in KiEnterV86Trap. Notice the problem: we need to detect which of these to use early on but we can't touch the EFLAGS in the frame because DS/ES could be invalid. Thankfully SS is always guaranteed valid, so stack dereferences are game! We therefore read the EFLAGS here, in assembly, where we can touch ESP as we please. We save this in EDX, which will be used as the second argument for the FASTCALL C trap entry. When we make the fast V86 check, we use the parameter instead of the trap frame, leading us to using the correct trap entry function, which fixes up DS/ES and lets us go on our merry way...
[NTOS]: Make appropriate changes to GENERATE_TRAP_HANDLERS macro.
[NTOS]: Switch to using well-known NT trap handler names (hex-based, double-zeroed) instead of decimal-based trap handler names which are confusing.
[NTOS]: Clean up some debug spew.

Modified:
    trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
    trunk/reactos/ntoskrnl/include/internal/i386/ke.h
    trunk/reactos/ntoskrnl/ke/i386/cpu.c
    trunk/reactos/ntoskrnl/ke/i386/trap.s
    trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
    trunk/reactos/ntoskrnl/ke/i386/v86vdm.c

Modified: trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S?rev=45052&r1=45051&r2=45052&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S [iso-8859-1] Tue Jan 12 06:50:45 2010
@@ -229,16 +229,61 @@
 //
 // @remark None.
 //
-.macro GENERATE_TRAP_HANDLER Name, ErrorCode
+.macro GENERATE_TRAP_HANDLER Name, ErrorCode=1, FastV86=0
 .func Name
 _&Name:
+    /* Some traps generate an error code, some don't (thanks, Intel!) */
     .if \ErrorCode
         push 0
     .endif
+    
+    /* Save all register state before we touch it */
     pushad
+    
+    /*
+     * The GPF and Invalid Opcode handlers are performance critical when talking
+     * about V8086 traps, because they control the main flow of execution during
+     * that mode (GPFs will be issued for any privileged instruction we need to
+     * emulate, and invalid opcode might be generated for BOPs).
+     *
+     * Because of this, we employ a fast entry/exit macro into V8086 mode since
+     * we can make certain assumptions. We detect, and use, such scenarios when
+     * the V8086 flag is enabled in EFLAGS.
+     *
+     * However, because we can land in a GPF handler with an invalid DS/ES, as
+     * some V8086 code could trample this during BIOS calls for example, we must
+     * make sure that we are on a valid DS/ES before dereferencing any pointer.
+     *
+     * We fixup DS/ES either in KiEnterTrap (for normal entry/exit) or, for V86,
+     * in KiEnterV86Trap. Notice the problem: we need to detect which of these
+     * to use early on but we can't touch the EFLAGS in the frame because DS/ES
+     * could be invalid.
+     *
+     * Thankfully SS is always guaranteed valid, so stack dereferences are game!
+     *
+     * We therefore read the EFLAGS here, in assembly, where we can touch ESP as
+     * we please. We save this in EDX, which will be used as the second argument
+     * for the FASTCALL C trap entry.
+     *
+     * When we make the fast V86 check, we use the parameter instead of the trap
+     * frame, leading us to using the correct trap entry function, which fixes
+     * up DS/ES and lets us go on our merry way...
+     */
+    .if \FastV86
+        /* ESP+12 is EFLAGS on interrupt frame, add 8*4 for the PUSHAD frame */
+        mov edx, [esp+12+8*4]
+    .endif
+    
+    /* Now make space for the trap frame and store the pointer as first arg */
     sub esp, KTRAP_FRAME_LENGTH - KTRAP_FRAME_PREVIOUS_MODE
     mov ecx, esp
-    jmp @&Name&Handler at 4
+    
+    /* Normally we just have one parameter, but fast V86 handlers need two */
+    .if \FastV86
+        jmp @&Name&Handler at 8
+    .else
+        jmp @&Name&Handler at 4
+    .endif
 .endfunc
 .endm
 

Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i386/ke.h?rev=45052&r1=45051&r2=45052&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] Tue Jan 12 06:50:45 2010
@@ -440,9 +440,9 @@
 extern ULONG KeI386CpuStep;
 extern UCHAR KiDebugRegisterTrapOffsets[9];
 extern UCHAR KiDebugRegisterContextOffsets[9];
-extern VOID __cdecl KiTrap2(VOID);
-extern VOID __cdecl KiTrap8(VOID);
-extern VOID __cdecl KiTrap19(VOID);
+extern VOID __cdecl KiTrap02(VOID);
+extern VOID __cdecl KiTrap08(VOID);
+extern VOID __cdecl KiTrap13(VOID);
 extern VOID __cdecl KiFastCallEntry(VOID);
 extern VOID NTAPI ExpInterlockedPopEntrySListFault(VOID);
 extern VOID __cdecl CopyParams(VOID);

Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev=45052&r1=45051&r2=45052&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/cpu.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/cpu.c [iso-8859-1] Tue Jan 12 06:50:45 2010
@@ -651,7 +651,7 @@
     Tss->CR3 = __readcr3();
     Tss->Esp0 = PtrToUlong(KiDoubleFaultStack);
     Tss->Esp = PtrToUlong(KiDoubleFaultStack);
-    Tss->Eip = PtrToUlong(KiTrap8);
+    Tss->Eip = PtrToUlong(KiTrap08);
     Tss->Cs = KGDT_R0_CODE;
     Tss->Fs = KGDT_R0_PCR;
     Tss->Ss = Ke386GetSs();
@@ -681,7 +681,7 @@
     Tss->CR3 = __readcr3();
     Tss->Esp0 = PtrToUlong(KiDoubleFaultStack);
     Tss->Esp = PtrToUlong(KiDoubleFaultStack);
-    Tss->Eip = PtrToUlong(KiTrap2);
+    Tss->Eip = PtrToUlong(KiTrap02);
     Tss->Cs = KGDT_R0_CODE;
     Tss->Fs = KGDT_R0_PCR;
     Tss->Ss = Ke386GetSs();
@@ -837,13 +837,13 @@
 {
     PKIDTENTRY IdtEntry;
 
-    /* Get the IDT Entry for Interrupt 19 */
-    IdtEntry = &((PKIPCR)KeGetPcr())->IDT[19];
+    /* Get the IDT Entry for Interrupt 0x13 */
+    IdtEntry = &((PKIPCR)KeGetPcr())->IDT[0x13];
 
     /* Set it up */
     IdtEntry->Selector = KGDT_R0_CODE;
-    IdtEntry->Offset = ((ULONG_PTR)KiTrap19 & 0xFFFF);
-    IdtEntry->ExtendedOffset = ((ULONG_PTR)KiTrap19 >> 16) & 0xFFFF;
+    IdtEntry->Offset = ((ULONG_PTR)KiTrap13 & 0xFFFF);
+    IdtEntry->ExtendedOffset = ((ULONG_PTR)KiTrap13 >> 16) & 0xFFFF;
     ((PKIDT_ACCESS)&IdtEntry->Access)->Dpl = 0;
     ((PKIDT_ACCESS)&IdtEntry->Access)->Present = 1;
     ((PKIDT_ACCESS)&IdtEntry->Access)->SegmentType = I386_INTERRUPT_GATE;

Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?rev=45052&r1=45051&r2=45052&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] Tue Jan 12 06:50:45 2010
@@ -22,24 +22,24 @@
 .globl _KiIdt
 _KiIdt:
 /* This is the Software Interrupt Table that we handle in this file:        */
-idt _KiTrap0,          INT_32_DPL0  /* INT 00: Divide Error (#DE)           */
-idt _KiTrap1,          INT_32_DPL0  /* INT 01: Debug Exception (#DB)        */
-idt _KiTrap2,          INT_32_DPL0  /* INT 02: NMI Interrupt                */
-idt _KiTrap3,          INT_32_DPL3  /* INT 03: Breakpoint Exception (#BP)   */
-idt _KiTrap4,          INT_32_DPL3  /* INT 04: Overflow Exception (#OF)     */
-idt _KiTrap5,          INT_32_DPL0  /* INT 05: BOUND Range Exceeded (#BR)   */
-idt _KiTrap6,          INT_32_DPL0  /* INT 06: Invalid Opcode Code (#UD)    */
-idt _KiTrap7,          INT_32_DPL0  /* INT 07: Device Not Available (#NM)   */
-idt _KiTrap8,          INT_32_DPL0  /* INT 08: Double Fault Exception (#DF) */
-idt _KiTrap9,          INT_32_DPL0  /* INT 09: RESERVED                     */
-idt _KiTrap10,         INT_32_DPL0  /* INT 0A: Invalid TSS Exception (#TS)  */
-idt _KiTrap11,         INT_32_DPL0  /* INT 0B: Segment Not Present (#NP)    */
-idt _KiTrap12,         INT_32_DPL0  /* INT 0C: Stack Fault Exception (#SS)  */
-idt _KiTrap13,         INT_32_DPL0  /* INT 0D: General Protection (#GP)     */
-idt _KiTrap14,         INT_32_DPL0  /* INT 0E: Page-Fault Exception (#PF)   */
+idt _KiTrap00,         INT_32_DPL0  /* INT 00: Divide Error (#DE)           */
+idt _KiTrap01,         INT_32_DPL0  /* INT 01: Debug Exception (#DB)        */
+idt _KiTrap02,         INT_32_DPL0  /* INT 02: NMI Interrupt                */
+idt _KiTrap03,         INT_32_DPL3  /* INT 03: Breakpoint Exception (#BP)   */
+idt _KiTrap04,         INT_32_DPL3  /* INT 04: Overflow Exception (#OF)     */
+idt _KiTrap05,         INT_32_DPL0  /* INT 05: BOUND Range Exceeded (#BR)   */
+idt _KiTrap06,         INT_32_DPL0  /* INT 06: Invalid Opcode Code (#UD)    */
+idt _KiTrap07,         INT_32_DPL0  /* INT 07: Device Not Available (#NM)   */
+idt _KiTrap08,         INT_32_DPL0  /* INT 08: Double Fault Exception (#DF) */
+idt _KiTrap09,         INT_32_DPL0  /* INT 09: RESERVED                     */
+idt _KiTrap0A,         INT_32_DPL0  /* INT 0A: Invalid TSS Exception (#TS)  */
+idt _KiTrap0B,         INT_32_DPL0  /* INT 0B: Segment Not Present (#NP)    */
+idt _KiTrap0C,         INT_32_DPL0  /* INT 0C: Stack Fault Exception (#SS)  */
+idt _KiTrap0D,         INT_32_DPL0  /* INT 0D: General Protection (#GP)     */
+idt _KiTrap0E,         INT_32_DPL0  /* INT 0E: Page-Fault Exception (#PF)   */
 idt _KiTrap0F,         INT_32_DPL0  /* INT 0F: RESERVED                     */
-idt _KiTrap16,         INT_32_DPL0  /* INT 10: x87 FPU Error (#MF)          */
-idt _KiTrap17,         INT_32_DPL0  /* INT 11: Align Check Exception (#AC)  */
+idt _KiTrap10,         INT_32_DPL0  /* INT 10: x87 FPU Error (#MF)          */
+idt _KiTrap11,         INT_32_DPL0  /* INT 11: Align Check Exception (#AC)  */
 idt _KiTrap0F,         INT_32_DPL0  /* INT 12: Machine Check Exception (#MC)*/
 idt _KiTrap0F,         INT_32_DPL0  /* INT 13: SIMD FPU Exception (#XF)     */
 .rept 22
@@ -54,8 +54,8 @@
 GENERATE_IDT_STUBS                  /* INT 30-FF: UNEXPECTED INTERRUPTS     */
 
 /* Trap handlers referenced from C code                                     */
-.globl _KiTrap8
-.globl _KiTrap19
+.globl _KiTrap08
+.globl _KiTrap13
 
 /* System call code referenced from C code                                  */
 .globl _CopyParams
@@ -383,7 +383,7 @@
     push 0x20202
     push KGDT_R3_CODE + RPL_MASK
     push 0
-    jmp _KiTrap6
+    jmp _KiTrap06
 
 #if DBG
 InvalidIrql:
@@ -573,127 +573,24 @@
 
 /* HARDWARE TRAP HANDLERS ****************************************************/
 
-GENERATE_TRAP_HANDLER KiTrap0, 1
-GENERATE_TRAP_HANDLER KiTrap1, 1
-GENERATE_TRAP_HANDLER KiTrap3, 1
-GENERATE_TRAP_HANDLER KiTrap4, 1
-GENERATE_TRAP_HANDLER KiTrap5, 1
-GENERATE_TRAP_HANDLER KiTrap6, 1
-GENERATE_TRAP_HANDLER KiTrap7, 1
-GENERATE_TRAP_HANDLER KiTrap8, 0
-GENERATE_TRAP_HANDLER KiTrap9, 1
-GENERATE_TRAP_HANDLER KiTrap10, 0
-GENERATE_TRAP_HANDLER KiTrap11, 0
-GENERATE_TRAP_HANDLER KiTrap12, 0
-
-//GENERATE_TRAP_HANDLER KiTrap13, 0
-
-.func KiTrap13
-TRAP_FIXUPS kitd_a, kitd_t, DoFixupV86, DoNotFixupAbios
-_KiTrap13:
-
-    /* It this a V86 GPF? */
-    test dword ptr [esp+12], EFLAGS_V86_MASK
-    jz NotV86
-
-    /* Enter V86 Trap */
-    V86_TRAP_PROLOG kitd_a, kitd_v
-
-    /* Make sure that this is a V86 process */
-    mov ecx, PCR[KPCR_CURRENT_THREAD]
-    mov ecx, [ecx+KTHREAD_APCSTATE_PROCESS]
-    cmp dword ptr [ecx+EPROCESS_VDM_OBJECTS], 0
-    jz ShouldNotGetHere
-
-RaiseIrql:
-
-    /* Go to APC level */
-    mov ecx, APC_LEVEL
-    call @KfRaiseIrql at 4
-
-    /* Save old IRQL and enable interrupts */
-    push eax
-    sti
-
-    /* Handle the opcode */
-    mov ecx, ebp
-    call @Ki386HandleOpcodeV86 at 4
-
-    /* Check if this was VDM */
-    test al, 0xFF
-    jz ShouldNotGetHere
-
-NoReflect:
-
-    /* Lower IRQL and disable interrupts */
-    pop ecx
-    call @KfLowerIrql at 4
-    cli
-
-    /* Check if this was a V86 trap */
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
-    jz NotV86Trap
-
-    /* Exit the V86 Trap */
-    V86_TRAP_EPILOG
-
-NotV86Trap:
-
-    /* Either this wasn't V86, or it was, but an APC interrupted us */
-    jmp _Kei386EoiHelper at 0
-
-NotV86:
-    /* Enter trap */
-    TRAP_PROLOG kitd_a, kitd_t
-    
-    /* Check if this was from kernel-mode */
-    test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
-    jnz ShouldNotGetHere
-
-    /* Get the opcode and trap frame */
-KmodeGpf:
-    mov eax, [ebp+KTRAP_FRAME_EIP]
-    mov eax, [eax]
-    mov edx, [ebp+KTRAP_FRAME_EBP]
-
-    /* Was it IRETD? */
-    cmp al, 0xCF
-    jne ShouldNotGetHere
-
-    /* Get error code */
-    lea edx, [ebp+KTRAP_FRAME_ESP]
-    mov ax, [ebp+KTRAP_FRAME_ERROR_CODE]
-    and ax, ~RPL_MASK
-
-    /* Get CS */
-    mov cx, word ptr [edx+4]
-    and cx, ~RPL_MASK
-    cmp cx, ax
-    jnz ShouldNotGetHere
-
-    /* This should be a Ki386CallBios return */
-    mov eax, offset @Ki386BiosCallReturnAddress at 4
-    cmp eax, [edx]
-    jne ShouldNotGetHere
-    mov eax, [edx+4]
-    cmp ax, KGDT_R0_CODE + RPL_MASK
-    jne ShouldNotGetHere
-
-    /* Jump to return address */
-    mov ecx, ebp
-    jmp @Ki386BiosCallReturnAddress at 4
-
-_Ki16BitStackException:
-ShouldNotGetHere:
-    /* FIXME */
-    UNHANDLED_PATH "Other GPF stuff"
-.endfunc
-
-GENERATE_TRAP_HANDLER KiTrap14, 0
-GENERATE_TRAP_HANDLER KiTrap0F, 1
-GENERATE_TRAP_HANDLER KiTrap16, 1
-GENERATE_TRAP_HANDLER KiTrap17, 1
-GENERATE_TRAP_HANDLER KiTrap19, 1
+GENERATE_TRAP_HANDLER KiTrap00
+GENERATE_TRAP_HANDLER KiTrap01
+GENERATE_TRAP_HANDLER KiTrap03
+GENERATE_TRAP_HANDLER KiTrap04
+GENERATE_TRAP_HANDLER KiTrap05
+GENERATE_TRAP_HANDLER KiTrap06
+GENERATE_TRAP_HANDLER KiTrap07
+GENERATE_TRAP_HANDLER KiTrap08, 0
+GENERATE_TRAP_HANDLER KiTrap09
+GENERATE_TRAP_HANDLER KiTrap0A, 0
+GENERATE_TRAP_HANDLER KiTrap0B, 0
+GENERATE_TRAP_HANDLER KiTrap0C, 0
+GENERATE_TRAP_HANDLER KiTrap0D, 0, 1
+GENERATE_TRAP_HANDLER KiTrap0E, 0
+GENERATE_TRAP_HANDLER KiTrap0F
+GENERATE_TRAP_HANDLER KiTrap10
+GENERATE_TRAP_HANDLER KiTrap11
+GENERATE_TRAP_HANDLER KiTrap13
 
 /* UNEXPECTED INTERRUPT HANDLERS **********************************************/
 

Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.c?rev=45052&r1=45051&r2=45052&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Tue Jan 12 06:50:45 2010
@@ -203,13 +203,13 @@
 FASTCALL
 KiEnterV86Trap(IN PKTRAP_FRAME TrapFrame)
 {
-    /* Save registers */
-    KiTrapFrameFromPushaStack(TrapFrame);
-    
     /* Load correct registers */
     Ke386SetFs(KGDT_R0_PCR);
     Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
     Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
+    
+    /* Save registers */
+    KiTrapFrameFromPushaStack(TrapFrame);
     
     /* Save exception list and bogus previous mode */
     TrapFrame->PreviousPreviousMode = -1;
@@ -283,17 +283,32 @@
 FASTCALL
 KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
 {
+    ULONG Ds, Es;
+    
+    /*
+     * We really have to get a good DS/ES first before touching any data.
+     *
+     * These two reads will either go in a register (with optimizations ON) or
+     * a stack variable (which is on SS:ESP, guaranteed to be good/valid).
+     *
+     * Because the assembly is marked volatile, the order of instructions is
+     * as-is, otherwise the optimizer could simply get rid of our DS/ES.
+     *
+     */
+    Ds = Ke386GetDs();
+    Es = Ke386GetEs();
+    Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
+    Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
+    TrapFrame->SegDs = Ds;
+    TrapFrame->SegEs = Es;
+        
+    /* Now we can save the other segments and then switch to the correct FS */
+    TrapFrame->SegFs = Ke386GetFs();
+    TrapFrame->SegGs = Ke386GetGs();
+    Ke386SetFs(KGDT_R0_PCR);
+
     /* Save registers */
     KiTrapFrameFromPushaStack(TrapFrame);
-    
-    /* Save segments and then switch to correct ones */
-    TrapFrame->SegFs = Ke386GetFs();
-    TrapFrame->SegGs = Ke386GetGs();
-    TrapFrame->SegDs = Ke386GetDs();
-    TrapFrame->SegEs = Ke386GetEs();
-    Ke386SetFs(KGDT_R0_PCR);
-    Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
-    Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
     
     /* Save exception list and bogus previous mode */
     TrapFrame->PreviousPreviousMode = -1;
@@ -568,7 +583,7 @@
 
 VOID
 FASTCALL
-KiTrap0Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap00Handler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
@@ -587,7 +602,7 @@
 
 VOID
 FASTCALL
-KiTrap1Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap01Handler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
@@ -606,7 +621,7 @@
 }
 
 VOID
-KiTrap2(VOID)
+KiTrap02(VOID)
 {
     PKTSS Tss, NmiTss;
     PKTHREAD Thread;
@@ -752,7 +767,7 @@
 
 VOID
 FASTCALL
-KiTrap3Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap03Handler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
@@ -763,7 +778,7 @@
 
 VOID
 FASTCALL
-KiTrap4Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap04Handler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
@@ -782,7 +797,7 @@
 
 VOID
 FASTCALL
-KiTrap5Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap05Handler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
@@ -804,7 +819,7 @@
 
 VOID
 FASTCALL
-KiTrap6Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap06Handler(IN PKTRAP_FRAME TrapFrame)
 {
     PUCHAR Instruction;
     ULONG i;
@@ -849,7 +864,7 @@
 
 VOID
 FASTCALL
-KiTrap7Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap07Handler(IN PKTRAP_FRAME TrapFrame)
 {
     PKTHREAD Thread, NpxThread;
     PFX_SAVE_AREA SaveArea, NpxSaveArea;
@@ -958,7 +973,7 @@
 
 VOID
 FASTCALL
-KiTrap8Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap08Handler(IN PKTRAP_FRAME TrapFrame)
 {
     /* FIXME: Not handled */
     KiSystemFatalException(EXCEPTION_DOUBLE_FAULT, TrapFrame);
@@ -966,7 +981,7 @@
 
 VOID
 FASTCALL
-KiTrap9Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap09Handler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
@@ -978,7 +993,7 @@
 
 VOID
 FASTCALL
-KiTrap10Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap0AHandler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
@@ -992,7 +1007,7 @@
 
 VOID
 FASTCALL
-KiTrap11Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap0BHandler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
@@ -1004,7 +1019,7 @@
 
 VOID
 FASTCALL
-KiTrap12Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap0CHandler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
@@ -1016,7 +1031,8 @@
 
 VOID
 FASTCALL
-KiTrap13Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap0DHandler(IN PKTRAP_FRAME TrapFrame,
+                IN ULONG EFlags)
 {
     ULONG i, j, Iopl;
     BOOLEAN Privileged = FALSE;
@@ -1025,7 +1041,7 @@
     KIRQL OldIrql;
     
     /* Check for V86 GPF */
-    if (TrapFrame->EFlags & EFLAGS_V86_MASK)
+    if (EFlags & EFLAGS_V86_MASK)
     {
         /* Enter V86 trap */
         KiEnterV86Trap(TrapFrame);
@@ -1064,16 +1080,13 @@
         /* Exit trap the slow way */
         KiEoiHelper(TrapFrame);
     }
-
+    
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
 
     /* Check for user-mode GPF */
     if (KiUserTrap(TrapFrame))
-    {
-        /* Must be user-mode! */
-        if (!KiUserTrap(TrapFrame)) KiSystemFatalException(EXCEPTION_GP_FAULT, TrapFrame);
-        
+    {   
         /* Should not be VDM */
         ASSERT(KiVdmTrap(TrapFrame) == FALSE);
         
@@ -1204,8 +1217,8 @@
      * with an invalid CS, which will generate another GPF instead.
      *
      */
-    if (((PVOID)TrapFrame->Eip >= (PVOID)KiTrap13Handler) &&
-        ((PVOID)TrapFrame->Eip < (PVOID)KiTrap13Handler))
+    if (((PVOID)TrapFrame->Eip >= (PVOID)KiTrap0DHandler) &&
+        ((PVOID)TrapFrame->Eip < (PVOID)KiTrap0DHandler))
     {
         /* Not implemented */
         UNIMPLEMENTED;
@@ -1298,7 +1311,7 @@
 
 VOID
 FASTCALL
-KiTrap14Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
 {
     PKTHREAD Thread;
     ULONG_PTR Cr2;
@@ -1432,7 +1445,7 @@
 
 VOID
 FASTCALL
-KiTrap16Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap10Handler(IN PKTRAP_FRAME TrapFrame)
 {
     PKTHREAD Thread;
     PFX_SAVE_AREA SaveArea;
@@ -1459,7 +1472,7 @@
 
 VOID
 FASTCALL
-KiTrap17Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap11Handler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
@@ -1471,7 +1484,7 @@
 
 VOID
 FASTCALL
-KiTrap19Handler(IN PKTRAP_FRAME TrapFrame)
+KiTrap13Handler(IN PKTRAP_FRAME TrapFrame)
 {
     PKTHREAD Thread;
     PFX_SAVE_AREA SaveArea;

Modified: trunk/reactos/ntoskrnl/ke/i386/v86vdm.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/v86vdm.c?rev=45052&r1=45051&r2=45052&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/v86vdm.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/v86vdm.c [iso-8859-1] Tue Jan 12 06:50:45 2010
@@ -623,9 +623,7 @@
     Tss->IoMapBase = (USHORT)IOPM_OFFSET;
 
     /* Switch stacks and work the magic */
-    DPRINT1("Entering V86 mode\n");
     Ki386SetupAndExitToV86Mode(VdmTeb);
-    DPRINT1("Left V86 mode\n");
 
     /* Restore IOPM */
     RtlCopyMemory(&Tss->IoMaps[0].IoMap, Ki386IopmSaveArea, PAGE_SIZE * 2);




More information about the Ros-diffs mailing list