So why implement this code path if we have nothing that hits it?

Best regards,
Alex Ionescu

On Fri, Apr 14, 2017 at 4:18 AM, <tfaber@svn.reactos.org> wrote:
Author: tfaber
Date: Fri Apr 14 11:18:22 2017
New Revision: 74305

URL: http://svn.reactos.org/svn/reactos?rev=74305&view=rev
Log:
[NTOS:KE]
- Gracefully handle page faults during V86 code execution. This is a bit of a hack because with our limited use of V86 code it is unclear how a page fault can even occur.
CORE-12993 #resolve

Modified:
    trunk/reactos/ntoskrnl/include/internal/i386/ke.h
    trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
    trunk/reactos/ntoskrnl/vdm/vdmexec.c

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=74305&r1=74304&r2=74305&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] Fri Apr 14 11:18:22 2017
@@ -478,6 +478,12 @@
 NTAPI
 VdmDispatchBop(
     IN PKTRAP_FRAME TrapFrame
+);
+
+BOOLEAN
+NTAPI
+VdmDispatchPageFault(
+    _In_ PKTRAP_FRAME TrapFrame
 );

 BOOLEAN

Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.c?rev=74305&r1=74304&r2=74305&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c   [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c   [iso-8859-1] Fri Apr 14 11:18:22 2017
@@ -1304,8 +1304,20 @@
         UNIMPLEMENTED_FATAL();
     }
 #endif
+
     /* Check for VDM trap */
-    ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
+    if (KiVdmTrap(TrapFrame))
+    {
+        DPRINT1("VDM PAGE FAULT at %lx:%lx for address %lx\n",
+                TrapFrame->SegCs, TrapFrame->Eip, Cr2);
+        if (VdmDispatchPageFault(TrapFrame))
+        {
+            /* Return and end VDM execution */
+            DPRINT1("VDM page fault with status 0x%lx resolved\n", Status);
+            KiEoiHelper(TrapFrame);
+        }
+        DPRINT1("VDM page fault with status 0x%lx NOT resolved\n", Status);
+    }

     /* Either kernel or user trap (non VDM) so dispatch exception */
     if (Status == STATUS_ACCESS_VIOLATION)

Modified: trunk/reactos/ntoskrnl/vdm/vdmexec.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/vdm/vdmexec.c?rev=74305&r1=74304&r2=74305&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/vdm/vdmexec.c        [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/vdm/vdmexec.c        [iso-8859-1] Fri Apr 14 11:18:22 2017
@@ -239,7 +239,7 @@
         KeLowerIrql(OldIrql);
         return STATUS_INVALID_SYSTEM_SERVICE;
     }
-
+
     /* Now do the VDM Swap */
     VdmSwapContext(VdmFrame, &VdmTib->MonitorContext, &VdmContext);

@@ -269,7 +269,7 @@

     /* Make a copy of the monitor context */
     Context = VdmTib->MonitorContext;
-
+
     /* Check if V86 mode was enabled or the trap was edited */
     if ((Context.EFlags & EFLAGS_V86_MASK) || (Context.SegCs & FRAME_EDITED))
     {
@@ -291,7 +291,7 @@
                 /* Remove real IF flag */
                 VdmTib->VdmContext.EFlags &= ~EFLAGS_INTERRUPT_MASK;
             }
-
+
             /* Turn off VIP and VIF */
             TrapFrame->EFlags &= ~(EFLAGS_VIP | EFLAGS_VIF);
             VdmTib->VdmContext.EFlags &= ~(EFLAGS_VIP | EFLAGS_VIF);
@@ -362,4 +362,45 @@
     return TRUE;
 }

-
+BOOLEAN
+NTAPI
+VdmDispatchPageFault(
+    _In_ PKTRAP_FRAME TrapFrame)
+{
+    NTSTATUS Status;
+    PVDM_TIB VdmTib;
+
+    PAGED_CODE();
+
+    /* Get the VDM TIB so we can terminate V86 execution */
+    Status = VdmpGetVdmTib(&VdmTib);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Not a proper VDM fault, keep looking */
+        DPRINT1("VdmDispatchPageFault: no VDM TIB, Vdm=%p\n", NtCurrentTeb()->Vdm);
+        return FALSE;
+    }
+
+    /* Must be coming from V86 code */
+    ASSERT(TrapFrame->EFlags & EFLAGS_V86_MASK);
+
+    _SEH2_TRY
+    {
+        /* Fill out a VDM Event */
+        VdmTib->EventInfo.Event = VdmMemAccess;
+        VdmTib->EventInfo.InstructionSize = 0;
+
+        /* End VDM Execution */
+        VdmEndExecution(TrapFrame, VdmTib);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = _SEH2_GetExceptionCode();
+    }
+    _SEH2_END;
+
+    /* Consider the exception handled if we succeeded */
+    DPRINT1("VdmDispatchPageFault EFlags %lx exit with 0x%lx\n", TrapFrame->EFlags, Status);
+    return NT_SUCCESS(Status);
+}
+