mirror of
https://github.com/reactos/reactos.git
synced 2025-04-18 03:34:11 +00:00
[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 svn path=/trunk/; revision=74305
This commit is contained in:
parent
8c82e4261d
commit
389bdb30ca
3 changed files with 63 additions and 4 deletions
|
@ -480,6 +480,12 @@ VdmDispatchBop(
|
|||
IN PKTRAP_FRAME TrapFrame
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
VdmDispatchPageFault(
|
||||
_In_ PKTRAP_FRAME TrapFrame
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
FASTCALL
|
||||
KiVdmOpcodePrefix(
|
||||
|
|
|
@ -1304,8 +1304,20 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
|
|||
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)
|
||||
|
|
|
@ -239,7 +239,7 @@ VdmpStartExecution(VOID)
|
|||
KeLowerIrql(OldIrql);
|
||||
return STATUS_INVALID_SYSTEM_SERVICE;
|
||||
}
|
||||
|
||||
|
||||
/* Now do the VDM Swap */
|
||||
VdmSwapContext(VdmFrame, &VdmTib->MonitorContext, &VdmContext);
|
||||
|
||||
|
@ -269,7 +269,7 @@ VdmEndExecution(IN PKTRAP_FRAME TrapFrame,
|
|||
|
||||
/* 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 @@ VdmEndExecution(IN PKTRAP_FRAME TrapFrame,
|
|||
/* 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 @@ VdmDispatchBop(IN PKTRAP_FRAME TrapFrame)
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue