mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 14:05:42 +00:00
[NTOS]: Simplify trap exit code.
[NTOS]: Move some stuff in appropriate headers. [NTOS]: Write V86 fast entry/exit traps, needed for later. svn path=/trunk/; revision=45028
This commit is contained in:
parent
f61b9c9113
commit
ff8920ffc1
4 changed files with 146 additions and 50 deletions
|
@ -66,6 +66,25 @@ extern ULONG Ke386CacheAlignment;
|
||||||
#define KeGetTrapFrameInterruptState(TrapFrame) \
|
#define KeGetTrapFrameInterruptState(TrapFrame) \
|
||||||
BooleanFlagOn((TrapFrame)->EFlags, EFLAGS_INTERRUPT_MASK)
|
BooleanFlagOn((TrapFrame)->EFlags, EFLAGS_INTERRUPT_MASK)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Flags for exiting a trap
|
||||||
|
//
|
||||||
|
#define KTE_SKIP_PM_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipPreviousMode = TRUE } }).Bits)
|
||||||
|
#define KTE_SKIP_SEG_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipSegments = TRUE } }).Bits)
|
||||||
|
#define KTE_SKIP_VOL_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipVolatiles = TRUE } }).Bits)
|
||||||
|
|
||||||
|
typedef union _KTRAP_EXIT_SKIP_BITS
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
UCHAR SkipPreviousMode:1;
|
||||||
|
UCHAR SkipSegments:1;
|
||||||
|
UCHAR SkipVolatiles:1;
|
||||||
|
UCHAR Reserved:5;
|
||||||
|
};
|
||||||
|
UCHAR Bits;
|
||||||
|
} KTRAP_EXIT_SKIP_BITS, *PKTRAP_EXIT_SKIP_BITS;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Registers an interrupt handler with an IDT vector
|
// Registers an interrupt handler with an IDT vector
|
||||||
//
|
//
|
||||||
|
@ -289,6 +308,25 @@ Ki386EnableXMMIExceptions(
|
||||||
IN ULONG_PTR Context
|
IN ULONG_PTR Context
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
VdmDispatchBop(
|
||||||
|
IN PKTRAP_FRAME TrapFrame
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
FASTCALL
|
||||||
|
KiVdmOpcodePrefix(
|
||||||
|
IN PKTRAP_FRAME TrapFrame,
|
||||||
|
IN ULONG Flags
|
||||||
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
FASTCALL
|
||||||
|
Ki386HandleOpcodeV86(
|
||||||
|
IN PKTRAP_FRAME TrapFrame
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Global x86 only Kernel data
|
// Global x86 only Kernel data
|
||||||
//
|
//
|
||||||
|
@ -312,6 +350,10 @@ extern VOID __cdecl KiTrap2(VOID);
|
||||||
extern VOID __cdecl KiTrap8(VOID);
|
extern VOID __cdecl KiTrap8(VOID);
|
||||||
extern VOID __cdecl KiTrap19(VOID);
|
extern VOID __cdecl KiTrap19(VOID);
|
||||||
extern VOID __cdecl KiFastCallEntry(VOID);
|
extern VOID __cdecl KiFastCallEntry(VOID);
|
||||||
|
extern VOID NTAPI ExpInterlockedPopEntrySListFault(VOID);
|
||||||
|
extern VOID __cdecl CopyParams(VOID);
|
||||||
|
extern VOID __cdecl ReadBatch(VOID);
|
||||||
|
extern VOID __cdecl FrRestore(VOID);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Sanitizes a selector
|
// Sanitizes a selector
|
||||||
|
|
|
@ -72,20 +72,6 @@ typedef struct _KNMI_HANDLER_CALLBACK
|
||||||
PVOID Handle;
|
PVOID Handle;
|
||||||
} KNMI_HANDLER_CALLBACK, *PKNMI_HANDLER_CALLBACK;
|
} KNMI_HANDLER_CALLBACK, *PKNMI_HANDLER_CALLBACK;
|
||||||
|
|
||||||
typedef union _KTRAP_STATE_BITS
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
UCHAR SystemCall:1;
|
|
||||||
UCHAR PreviousMode:1;
|
|
||||||
UCHAR Segments:1;
|
|
||||||
UCHAR Volatiles:1;
|
|
||||||
UCHAR Full:1;
|
|
||||||
UCHAR Reserved:3;
|
|
||||||
};
|
|
||||||
UCHAR Bits;
|
|
||||||
} KTRAP_STATE_BITS, *PKTRAP_STATE_BITS;
|
|
||||||
|
|
||||||
typedef PCHAR
|
typedef PCHAR
|
||||||
(NTAPI *PKE_BUGCHECK_UNICODE_TO_ANSI)(
|
(NTAPI *PKE_BUGCHECK_UNICODE_TO_ANSI)(
|
||||||
IN PUNICODE_STRING Unicode,
|
IN PUNICODE_STRING Unicode,
|
||||||
|
|
|
@ -66,7 +66,7 @@ KiFillTrapFrameDebug(IN PKTRAP_FRAME TrapFrame)
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame,
|
KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame,
|
||||||
IN KTRAP_STATE_BITS StateBits)
|
IN KTRAP_STATE_BITS SkipBits)
|
||||||
{
|
{
|
||||||
/* Make sure interrupts are disabled */
|
/* Make sure interrupts are disabled */
|
||||||
if (__readeflags() & EFLAGS_INTERRUPT_MASK)
|
if (__readeflags() & EFLAGS_INTERRUPT_MASK)
|
||||||
|
@ -105,7 +105,7 @@ KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're ignoring previous mode, make sure caller doesn't actually want it */
|
/* If we're ignoring previous mode, make sure caller doesn't actually want it */
|
||||||
if (!(StateBits.PreviousMode) && (TrapFrame->PreviousPreviousMode != -1))
|
if ((SkipBits.SkipPreviousMode) && (TrapFrame->PreviousPreviousMode != -1))
|
||||||
{
|
{
|
||||||
DPRINT1("Exiting a trap witout restoring previous mode, yet previous mode seems valid: %lx", TrapFrame->PreviousPreviousMode);
|
DPRINT1("Exiting a trap witout restoring previous mode, yet previous mode seems valid: %lx", TrapFrame->PreviousPreviousMode);
|
||||||
while (TRUE);
|
while (TRUE);
|
||||||
|
|
|
@ -18,16 +18,19 @@
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
KiExitTrap(IN PKTRAP_FRAME TrapFrame,
|
KiExitTrap(IN PKTRAP_FRAME TrapFrame,
|
||||||
IN UCHAR State)
|
IN UCHAR Skip)
|
||||||
{
|
{
|
||||||
KTRAP_STATE_BITS StateBits = { .Bits = State };
|
KTRAP_EXIT_SKIP_BITS SkipBits = { .Bits = Skip };
|
||||||
KiExitTrapDebugChecks(TrapFrame, StateBits);
|
KiExitTrapDebugChecks(TrapFrame, SkipBits);
|
||||||
|
|
||||||
|
/* If you skip volatile reload, you must skip segment reload */
|
||||||
|
ASSERT((SkipBits.SkipVolatiles == FALSE) || (SkipBits.SkipSegments == TRUE));
|
||||||
|
|
||||||
/* Restore the SEH handler chain */
|
/* Restore the SEH handler chain */
|
||||||
KeGetPcr()->Tib.ExceptionList = TrapFrame->ExceptionList;
|
KeGetPcr()->Tib.ExceptionList = TrapFrame->ExceptionList;
|
||||||
|
|
||||||
/* Check if the previous mode must be restored */
|
/* Check if the previous mode must be restored */
|
||||||
if (StateBits.PreviousMode)
|
if (!SkipBits.SkipPreviousMode)
|
||||||
{
|
{
|
||||||
/* Not handled yet */
|
/* Not handled yet */
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
@ -53,35 +56,32 @@ KiExitTrap(IN PKTRAP_FRAME TrapFrame,
|
||||||
while (TRUE);
|
while (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if all registers must be restored */
|
/* Check if segments should be restored */
|
||||||
if (StateBits.Full)
|
if (!SkipBits.SkipSegments)
|
||||||
{
|
{
|
||||||
/* Only do the restore if we made a transition from user-mode */
|
/* Restore segments */
|
||||||
if (KiUserTrap(TrapFrame))
|
Ke386SetGs(TrapFrame->SegGs);
|
||||||
{
|
Ke386SetEs(TrapFrame->SegEs);
|
||||||
/* Restore segments */
|
Ke386SetDs(TrapFrame->SegDs);
|
||||||
Ke386SetGs(TrapFrame->SegGs);
|
Ke386SetFs(TrapFrame->SegFs);
|
||||||
Ke386SetEs(TrapFrame->SegEs);
|
|
||||||
Ke386SetDs(TrapFrame->SegDs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else if (KiUserTrap(TrapFrame))
|
||||||
/* Check if we came from user-mode */
|
|
||||||
if (KiUserTrap(TrapFrame))
|
|
||||||
{
|
{
|
||||||
/* Check if the caller wants segments restored */
|
|
||||||
if (StateBits.Segments)
|
|
||||||
{
|
|
||||||
/* Restore them */
|
|
||||||
Ke386SetGs(TrapFrame->SegGs);
|
|
||||||
Ke386SetEs(TrapFrame->SegEs);
|
|
||||||
Ke386SetDs(TrapFrame->SegDs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Always restore FS since it goes from KPCR to TEB */
|
/* Always restore FS since it goes from KPCR to TEB */
|
||||||
Ke386SetFs(TrapFrame->SegFs);
|
Ke386SetFs(TrapFrame->SegFs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if the caller wants to skip volatiles */
|
||||||
|
if (SkipBits.SkipVolatiles)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* When we do the system call handler through this path, we need
|
||||||
|
* to have some sort to restore the kernel EAX instead of pushing
|
||||||
|
* back the user EAX. We'll figure it out...
|
||||||
|
*/
|
||||||
|
DPRINT1("Warning: caller doesn't want volatiles restored\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Check for ABIOS code segment */
|
/* Check for ABIOS code segment */
|
||||||
if (TrapFrame->SegCs == 0x80)
|
if (TrapFrame->SegCs == 0x80)
|
||||||
{
|
{
|
||||||
|
@ -90,8 +90,8 @@ KiExitTrap(IN PKTRAP_FRAME TrapFrame,
|
||||||
while (TRUE);
|
while (TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for system call */
|
/* Check for system call -- a system call skips volatiles! */
|
||||||
if (StateBits.SystemCall)
|
if (SkipBits.SkipVolatiles)
|
||||||
{
|
{
|
||||||
/* Not handled yet */
|
/* Not handled yet */
|
||||||
UNIMPLEMENTED;
|
UNIMPLEMENTED;
|
||||||
|
@ -104,6 +104,50 @@ KiExitTrap(IN PKTRAP_FRAME TrapFrame,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
KiExitV86Trap(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
PKTHREAD Thread;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* Get the thread */
|
||||||
|
Thread = KeGetCurrentThread();
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
/* Turn off the alerted state for kernel mode */
|
||||||
|
Thread->Alerted[KernelMode] = FALSE;
|
||||||
|
|
||||||
|
/* Are there pending user APCs? */
|
||||||
|
if (!Thread->ApcState.UserApcPending) break;
|
||||||
|
|
||||||
|
/* Raise to APC level and enable interrupts */
|
||||||
|
OldIrql = KfRaiseIrql(APC_LEVEL);
|
||||||
|
_enable();
|
||||||
|
|
||||||
|
/* Deliver APCs */
|
||||||
|
KiDeliverApc(UserMode, NULL, TrapFrame);
|
||||||
|
|
||||||
|
/* Restore IRQL and disable interrupts once again */
|
||||||
|
KfLowerIrql(OldIrql);
|
||||||
|
_disable();
|
||||||
|
|
||||||
|
/* Return if this isn't V86 mode anymore */
|
||||||
|
if (TrapFrame->EFlags & EFLAGS_V86_MASK) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we got here, we're still in a valid V8086 context, so quit it */
|
||||||
|
if (TrapFrame->Dr7 & ~DR7_RESERVED_MASK)
|
||||||
|
{
|
||||||
|
/* Not handled yet */
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
while (TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return from interrupt */
|
||||||
|
KiTrapReturn(TrapFrame);
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
|
KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
@ -115,11 +159,39 @@ KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
|
||||||
KiCheckForApcDelivery(TrapFrame);
|
KiCheckForApcDelivery(TrapFrame);
|
||||||
|
|
||||||
/* Now exit the trap for real */
|
/* Now exit the trap for real */
|
||||||
KiExitTrap(TrapFrame, KTS_SEG_BIT | KTS_VOL_BIT);
|
KiExitTrap(TrapFrame, KTE_SKIP_PM_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TRAP ENTRY CODE ************************************************************/
|
/* TRAP ENTRY CODE ************************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
KiEnterV86Trap(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
/* Save registers */
|
||||||
|
KiTrapFrameFromPushaStack(TrapFrame);
|
||||||
|
|
||||||
|
/* Load correct registers */
|
||||||
|
Ke386SetFs(KGDT_R0_PCR);
|
||||||
|
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
|
||||||
|
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
|
||||||
|
|
||||||
|
/* Save exception list and bogus previous mode */
|
||||||
|
TrapFrame->PreviousPreviousMode = -1;
|
||||||
|
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
|
||||||
|
|
||||||
|
/* Clear direction flag */
|
||||||
|
Ke386ClearDirectionFlag();
|
||||||
|
|
||||||
|
/* Save DR7 and check for debugging */
|
||||||
|
TrapFrame->Dr7 = __readdr(7);
|
||||||
|
if (TrapFrame->Dr7 & ~DR7_RESERVED_MASK)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
while (TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
|
KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
@ -258,7 +330,6 @@ KiNpxHandler(IN PKTRAP_FRAME TrapFrame,
|
||||||
IN PFX_SAVE_AREA SaveArea)
|
IN PFX_SAVE_AREA SaveArea)
|
||||||
{
|
{
|
||||||
ULONG Cr0, Mask, Error, ErrorOffset, DataOffset;
|
ULONG Cr0, Mask, Error, ErrorOffset, DataOffset;
|
||||||
extern VOID FrRestore(VOID);
|
|
||||||
|
|
||||||
/* Check for VDM trap */
|
/* Check for VDM trap */
|
||||||
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
|
ASSERT((KiVdmTrap(TrapFrame)) == FALSE);
|
||||||
|
@ -718,9 +789,6 @@ KiTrap14Handler(IN PKTRAP_FRAME TrapFrame)
|
||||||
PKTHREAD Thread;
|
PKTHREAD Thread;
|
||||||
ULONG_PTR Cr2;
|
ULONG_PTR Cr2;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
extern VOID NTAPI ExpInterlockedPopEntrySListFault(VOID);
|
|
||||||
extern VOID CopyParams(VOID);
|
|
||||||
extern VOID ReadBatch(VOID);
|
|
||||||
|
|
||||||
/* Save trap frame */
|
/* Save trap frame */
|
||||||
KiEnterTrap(TrapFrame);
|
KiEnterTrap(TrapFrame);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue