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/i... ============================================================================== --- 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... ============================================================================== --- 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=... ============================================================================== --- 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); +} +