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(a)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);
+}
+