Author: sir_richard
Date: Fri Jan  8 19:21:47 2010
New Revision: 45005

URL: http://svn.reactos.org/svn/reactos?rev=45005&view=rev
Log:
Trap Handlers in C Patch 3 of X (Patch by Sir_Richard <[email protected]>):
    [NTOS]: Fix a bug in the assertion handler.
    [NTOS]: Implement page fault trap (14) in C instead of ASM.
    [NTOS]: Implement V8086 trap entry/exit, we were hitting these during page 
faults in Ke386CallBios for video reset during GUI boot.

Modified:
    trunk/reactos/ntoskrnl/include/internal/trap_x.h
    trunk/reactos/ntoskrnl/ke/i386/trap.s
    trunk/reactos/ntoskrnl/ke/i386/traphdlr.c

Modified: trunk/reactos/ntoskrnl/include/internal/trap_x.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/trap_x.h?rev=45005&r1=45004&r2=45005&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] Fri Jan  8 
19:21:47 2010
@@ -9,7 +9,6 @@
 //
 // Debug Macros
 //
-#if YDEBUG
 VOID
 NTAPI
 KiDumpTrapFrame(IN PKTRAP_FRAME TrapFrame)
@@ -52,6 +51,7 @@
     DPRINT1("V86Gs: %x\n", TrapFrame->V86Gs);
 }
 
+#if YDEBUG
 FORCEINLINE
 VOID
 KiFillTrapFrameDebug(IN PKTRAP_FRAME TrapFrame)
@@ -220,6 +220,18 @@
     KiDispatchExceptionFromTrapFrame(Code, Address, 0, 0, 0, 0, TrapFrame);
 }
 
+VOID
+FORCEINLINE
+KiDispatchException2Args(IN NTSTATUS Code,
+                         IN ULONG_PTR Address,
+                         IN ULONG P1,
+                         IN ULONG P2,
+                         IN PKTRAP_FRAME TrapFrame)
+{
+    /* Helper for exceptions with no arguments */
+    KiDispatchExceptionFromTrapFrame(Code, Address, 2, P1, P2, 0, TrapFrame);
+}
+
 FORCEINLINE
 VOID
 KiTrapReturn(IN PKTRAP_FRAME TrapFrame)

Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?rev=45005&r1=45004&r2=45005&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] Fri Jan  8 19:21:47 2010
@@ -58,6 +58,10 @@
 .globl _KiTrap8
 .globl _KiTrap19
 
+/* System call code referenced from C code                                  */
+.globl _CopyParams
+.globl _ReadBatch
+
 /* System call entrypoints:                                                 */
 .globl _KiFastCallEntry
 .globl _KiSystemService
@@ -193,7 +197,7 @@
 
     /* Check if we should flush the User Batch */
     xor ebx, ebx
-ReadBatch:
+_ReadBatch:
     or ebx, [ecx+TEB_GDI_BATCH_COUNT]
     jz NotWin32K
 
@@ -239,7 +243,7 @@
     cmp esi, _MmUserProbeAddress
     jnb AccessViolation
 
-CopyParams:
+_CopyParams:
     /* Copy the parameters */
     rep movsd
 
@@ -359,7 +363,7 @@
     test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
 
     /* It's fine, go ahead with it */
-    jz CopyParams
+    jz _CopyParams
 
     /* Caller sent invalid parameters, fail here */
     mov eax, STATUS_ACCESS_VIOLATION
@@ -1219,9 +1223,9 @@
     test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
     jnz UserModeGpf
 
-    /* Check if we have a VDM alert */
-    cmp dword ptr PCR[KPCR_VDM_ALERT], 0
-    jnz VdmAlertGpf
+    ///* Check if we have a VDM alert */
+    //cmp dword ptr PCR[KPCR_VDM_ALERT], 0 // BUGBUG: Add this back later
+    //jnz VdmAlertGpf
 
     /* Check for GPF during GPF */
     mov eax, [ebp+KTRAP_FRAME_EIP]
@@ -1607,203 +1611,7 @@
     UNHANDLED_V86_PATH
 .endfunc
 
-.func KiTrap14
-TRAP_FIXUPS kite_a, kite_t, DoFixupV86, DoNotFixupAbios
-_KiTrap14:
-
-    /* Enter trap */
-    TRAP_PROLOG kite_a, kite_t
-
-    /* Check if we have a VDM alert */
-    cmp dword ptr PCR[KPCR_VDM_ALERT], 0
-    jnz VdmAlertGpf
-
-    /* Get the current thread */
-    mov edi, PCR[KPCR_CURRENT_THREAD]
-
-    /* Get the stack address of the frame */
-    lea eax, [esp+KTRAP_FRAME_LENGTH+NPX_FRAME_LENGTH]
-    sub eax, [edi+KTHREAD_INITIAL_STACK]
-    jz NoFixUp
-
-    /* This isn't the base frame, check if it's the second */
-    cmp eax, -KTRAP_FRAME_EFLAGS
-    jb NoFixUp
-
-    /* Check if we have a TEB */
-    mov eax, PCR[KPCR_TEB]
-    or eax, eax
-    jle NoFixUp
-
-    /* Fixup the frame */
-    call _KiFixupFrame
-
-    /* Save CR2 */
-NoFixUp:
-    mov edi, cr2
-
-    /* Check if this processor has the cmpxchg8b lock errata */
-    cmp byte ptr _KiI386PentiumLockErrataPresent, 0
-    jnz HandleLockErrata
-
-NotLockErrata:
-    /* HACK: Handle page faults with interrupts disabled */
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
-    je HandlePf
-
-    /* Enable interrupts and check if we got here with interrupts disabled */
-    sti
-#ifdef HACK_ABOVE_FIXED
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_INTERRUPT_MASK
-    jz IllegalState
-#endif
-
-HandlePf:
-    /* Send trap frame and check if this is kernel-mode or usermode */
-    push ebp
-    mov eax, [ebp+KTRAP_FRAME_CS]
-    and eax, MODE_MASK
-    push eax
-
-    /* Send faulting address and check if this is read or write */
-    push edi
-    mov eax, [ebp+KTRAP_FRAME_ERROR_CODE]
-    and eax, 1
-    push eax
-
-    /* Call the access fault handler */
-    call _mmaccessfa...@16
-    test eax, eax
-    jl AccessFail
-
-    /* Access fault handled, return to caller */
-    jmp _kei386eoihel...@0
-
-AccessFail:
-    /* First check if this is a fault in the S-LIST functions */
-    mov ecx, offset _expinterlockedpopentryslistfa...@0
-    cmp [ebp+KTRAP_FRAME_EIP], ecx
-    jz SlistFault
-
-    /* Check if this is a fault in the syscall handler */
-    mov ecx, offset CopyParams
-    cmp [ebp+KTRAP_FRAME_EIP], ecx
-    jz SysCallCopyFault
-    mov ecx, offset ReadBatch
-    cmp [ebp+KTRAP_FRAME_EIP], ecx
-    jnz CheckVdmPf
-
-    /* FIXME: TODO */
-    UNHANDLED_PATH "SYSENTER Fault"
-    jmp _kei386eoihel...@0
-
-SysCallCopyFault:
-    /* FIXME: TODO */
-    UNHANDLED_PATH "SYSENTER Fault"
-    jmp _kei386eoihel...@0
-
-    /* Check if the fault occured in a V86 mode */
-CheckVdmPf:
-    mov ecx, [ebp+KTRAP_FRAME_ERROR_CODE]
-    shr ecx, 1
-    and ecx, 1
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
-    jnz VdmPF
-
-    /* Check if the fault occured in a VDM */
-    mov esi, PCR[KPCR_CURRENT_THREAD]
-    mov esi, [esi+KTHREAD_APCSTATE_PROCESS]
-    cmp dword ptr [esi+EPROCESS_VDM_OBJECTS], 0
-    jz CheckStatus
-
-    /* Check if we this was in kernel-mode */
-    test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
-    jz CheckStatus
-    cmp word ptr [ebp+KTRAP_FRAME_CS], KGDT_R3_CODE + RPL_MASK
-    jz CheckStatus
-
-VdmPF:
-    /* FIXME: TODO */
-    UNHANDLED_V86_PATH
-
-    /* Save EIP and check what kind of status failure we got */
-CheckStatus:
-    mov esi, [ebp+KTRAP_FRAME_EIP]
-    cmp eax, STATUS_ACCESS_VIOLATION
-    je AccessViol
-    cmp eax, STATUS_GUARD_PAGE_VIOLATION
-    je SpecialCode
-    cmp eax, STATUS_STACK_OVERFLOW
-    je SpecialCode
-
-    /* Setup an in-page exception to dispatch */
-    mov edx, ecx
-    mov ebx, esi
-    mov esi, edi
-    mov ecx, 3
-    mov edi, eax
-    mov eax, STATUS_IN_PAGE_ERROR
-    call _CommonDispatchException
-
-AccessViol:
-    /* Use more proper status code */
-    mov eax, KI_EXCEPTION_ACCESS_VIOLATION
-
-SpecialCode:
-    /* Setup a normal page fault exception */
-    mov ebx, esi
-    mov edx, ecx
-    mov esi, edi
-    jmp _DispatchTwoParam
-
-SlistFault:
-    /* FIXME: TODO */
-    UNHANDLED_PATH "SLIST Fault"
-
-IllegalState:
-
-    /* This is completely illegal, bugcheck the system */
-    push ebp
-    push esi
-    push ecx
-    push eax
-    push edi
-    push IRQL_NOT_LESS_OR_EQUAL
-    call _kebugcheckwit...@24
-
-VdmAlertGpf:
-
-    /* FIXME: NOT SUPPORTED */
-    UNHANDLED_V86_PATH
-
-HandleLockErrata:
-
-    /* Fail if this isn't a write fault */
-    test word ptr [ebp+KTRAP_FRAME_ERROR_CODE], 0x4
-    jnz NotLockErrata
-
-    /* Also make sure the page fault is for IDT entry 6 */
-    mov eax, PCR[KPCR_IDT]
-    add eax, 0x30
-    cmp eax, edi
-    jne NotLockErrata
-
-    /*
-     * This is a write fault to the Invalid Opcode handler entry.
-     * We assume this is the lock errata and not a real write fault.
-     */
-
-    /* Clear the error code */
-    and dword ptr [ebp+KTRAP_FRAME_ERROR_CODE], 0
-
-    /* Check if this happened in V86 mode */
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
-    jnz VdmOpCodeFault
-
-    /* Dispatch this to the invalid opcode handler */
-    jmp DispatchLockErrata
-.endfunc
-
+GENERATE_TRAP_HANDLER KiTrap14, 0
 GENERATE_TRAP_HANDLER KiTrap0F, 1
 
 .func KiTrap16

Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.c?rev=45005&r1=45004&r2=45005&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Fri Jan  8 19:21:47 
2010
@@ -43,13 +43,8 @@
     }
     
     /* Check if this was a V8086 trap */
-    if (TrapFrame->EFlags & EFLAGS_V86_MASK)
-    {
-        /* Not handled yet */
-        UNIMPLEMENTED;
-        while (TRUE);
-    }
-    
+    if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturn(TrapFrame);
+
     /* Check if the trap frame was edited */
     if (!(TrapFrame->SegCs & FRAME_EDITED))
     {
@@ -155,8 +150,11 @@
     /* Check for V86 mode */
     if (TrapFrame->EFlags & EFLAGS_V86_MASK)
     {
-        UNIMPLEMENTED;
-        while (TRUE);
+        /* Restore V8086 segments into Protected Mode segments */
+        TrapFrame->SegFs = TrapFrame->V86Fs;
+        TrapFrame->SegGs = TrapFrame->V86Gs;
+        TrapFrame->SegDs = TrapFrame->V86Ds;
+        TrapFrame->SegEs = TrapFrame->V86Es;
     }
 
     /* Clear direction flag */
@@ -404,6 +402,130 @@
 
 VOID
 FASTCALL
+KiTrap14Handler(IN PKTRAP_FRAME TrapFrame)
+{
+    PKTHREAD Thread;
+    ULONG_PTR Cr2;
+    NTSTATUS Status;
+    extern VOID NTAPI ExpInterlockedPopEntrySListFault(VOID);
+    extern VOID CopyParams(VOID);
+    extern VOID ReadBatch(VOID);
+
+    /* Save trap frame */
+    KiEnterTrap(TrapFrame);
+
+    /* Check for custom VDM trap handler */
+    if (KeGetPcr()->VdmAlert)
+    {
+        /* Not implemented */
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+
+    /* Check if this is the base frame */
+    Thread = KeGetCurrentThread();
+    if (KeGetTrapFrame(Thread) != TrapFrame)
+    {
+        /* It isn't, check if this is a second nested frame */
+        if (((ULONG_PTR)KeGetTrapFrame(Thread) - (ULONG_PTR)TrapFrame) <=
+            FIELD_OFFSET(KTRAP_FRAME, EFlags))
+        {
+            /* The stack is somewhere in between frames, we need to fix it */
+            UNIMPLEMENTED;
+            while (TRUE);
+        }
+    }
+    
+    /* Save CR2 */
+    Cr2 = __readcr2();
+    
+    /* Check for Pentium LOCK errata */
+    if (KiI386PentiumLockErrataPresent)
+    {
+        /* Not yet implemented */
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+    
+    /* HACK: Check if interrupts are disabled and enable them */
+    if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
+    {
+        /* Enable interupts */
+        _enable();
+#ifdef HACK_ABOVE_FIXED
+        if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
+        {
+            /* This is illegal */
+            KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
+                             Cr2,
+                             -1,
+                             TrapFrame->ErrCode & 1,
+                             TrapFrame->Eip,
+                             TrapFrame);
+        }
+#endif
+    }
+
+    /* Call the access fault handler */
+    Status = MmAccessFault(TrapFrame->ErrCode & 1,
+                           (PVOID)Cr2,
+                           TrapFrame->SegCs & MODE_MASK,
+                           TrapFrame);
+    if (Status == STATUS_SUCCESS) KiEoiHelper(TrapFrame);
+    
+    /* Check for S-LIST fault */
+    if (TrapFrame->Eip == (ULONG_PTR)ExpInterlockedPopEntrySListFault)
+    {
+        /* Not yet implemented */
+        UNIMPLEMENTED;
+        while (TRUE);   
+    }
+    
+    /* Check for syscall fault */
+    if ((TrapFrame->Eip == (ULONG_PTR)CopyParams) ||
+        (TrapFrame->Eip == (ULONG_PTR)ReadBatch))
+    {
+        /* Not yet implemented */
+        UNIMPLEMENTED;
+        while (TRUE);
+    }
+
+    /* Check for VDM trap */
+    ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
+    
+    /* Either kernel or user trap (non VDM) so dispatch exception */
+    if (Status == STATUS_ACCESS_VIOLATION)
+    {
+        /* This status code is repurposed so we can recognize it later */
+        KiDispatchException2Args(KI_EXCEPTION_ACCESS_VIOLATION,
+                                 TrapFrame->Eip,
+                                 TrapFrame->ErrCode & 1,
+                                 Cr2,
+                                 TrapFrame);
+    }
+    else if ((Status == STATUS_GUARD_PAGE_VIOLATION) ||
+             (Status == STATUS_STACK_OVERFLOW))
+    {
+        /* These faults only have two parameters */
+        KiDispatchException2Args(Status,
+                                 TrapFrame->Eip,
+                                 TrapFrame->ErrCode & 1,
+                                 Cr2,
+                                 TrapFrame);
+    }
+    
+    /* Only other choice is an in-page error, with 3 parameters */
+    KiDispatchExceptionFromTrapFrame(STATUS_IN_PAGE_ERROR,
+                                     TrapFrame->Eip,
+                                     3,
+                                     TrapFrame->ErrCode & 1,
+                                     Cr2,
+                                     Status,
+                                     TrapFrame);
+}
+
+VOID
+FASTCALL
 KiTrap0FHandler(IN PKTRAP_FRAME TrapFrame)
 {
     /* Save trap frame */
@@ -433,8 +555,8 @@
     /* Save trap frame */
     KiEnterTrap(TrapFrame);
 
-    /* Increment EIP to skip the INT2C instruction (2 bytes, not 1 like INT3) 
*/
-    TrapFrame->Eip += 2;
+    /* Decrement EIP to point to the INT2C instruction (2 bytes, not 1 like 
INT3) */
+    TrapFrame->Eip -= 2;
 
     /* Dispatch the exception */
     KiDispatchException0Args(STATUS_ASSERTION_FAILURE,


Reply via email to