[NTOSKRNL]

- Introduce a new and faster way to return to kernel mode from traps by using a ret 8 instruction instead of an iret.
- Make use of KiUserTrap where appropriate
- Remove some pointless toplevel volatile

svn path=/trunk/; revision=60701
This commit is contained in:
Timo Kreuzer 2013-10-19 11:33:34 +00:00
parent 76e1afdbda
commit 6697ef7a17
10 changed files with 64 additions and 40 deletions

View file

@ -241,6 +241,7 @@ ENDM
#define KI_EXIT_RET HEX(080)
#define KI_EXIT_IRET HEX(100)
#define KI_EDITED_FRAME HEX(200)
#define KI_EXIT_RET8 HEX(400)
#define KI_RESTORE_VOLATILES (KI_RESTORE_EAX OR KI_RESTORE_ECX_EDX)
MACRO(KiTrapExitStub, Name, Flags)
@ -248,16 +249,16 @@ MACRO(KiTrapExitStub, Name, Flags)
PUBLIC @&Name&@4
@&Name&@4:
if (Flags AND KI_RESTORE_EFLAGS)
/* We will pop EFlags off the stack */
OffsetEsp = KTRAP_FRAME_EFLAGS
elseif (Flags AND KI_EXIT_IRET)
if (Flags AND KI_EXIT_RET8) OR (Flags AND KI_EXIT_IRET)
/* This is the IRET frame */
OffsetEsp = KTRAP_FRAME_EIP
elseif (Flags AND KI_RESTORE_EFLAGS)
/* We will pop EFlags off the stack */
OffsetEsp = KTRAP_FRAME_EFLAGS
else
OffsetEsp = 0
@ -335,6 +336,13 @@ PUBLIC @&Name&@4
if (Flags AND KI_RESTORE_EFLAGS)
if (Flags AND KI_EXIT_RET8)
/* We are at the IRET frame, so push EFLAGS first */
push dword ptr [esp + 8]
endif
/* Restore EFLAGS */
popfd
@ -357,6 +365,11 @@ PUBLIC @&Name&@4
/* Return to kernel mode with a jmp */
jmp edx
elseif (Flags AND KI_EXIT_RET8)
/* Return to kernel mode with a ret 8 */
ret 8
elseif (Flags AND KI_EXIT_RET)
/* Return to kernel mode with a ret */

View file

@ -383,13 +383,13 @@ KeI386VdmInitialize(
ULONG_PTR
NTAPI
Ki386EnableGlobalPage(
IN volatile ULONG_PTR Context
IN ULONG_PTR Context
);
ULONG_PTR
NTAPI
Ki386EnableTargetLargePage(
IN volatile ULONG_PTR Context
IN ULONG_PTR Context
);
BOOLEAN

View file

@ -163,7 +163,7 @@ KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame,
}
/* Check DR values */
if (TrapFrame->SegCs & MODE_MASK)
if (KiUserTrap(TrapFrame)
{
/* Check for active debugging */
if (KeGetCurrentThread()->Header.DebugActive)
@ -244,6 +244,7 @@ DECLSPEC_NORETURN VOID FASTCALL KiSystemCallTrapReturn(IN PKTRAP_FRAME TrapFrame
DECLSPEC_NORETURN VOID FASTCALL KiEditedTrapReturn(IN PKTRAP_FRAME TrapFrame);
DECLSPEC_NORETURN VOID FASTCALL KiTrapReturn(IN PKTRAP_FRAME TrapFrame);
DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegments(IN PKTRAP_FRAME TrapFrame);
DECLSPEC_NORETURN VOID FASTCALL KiTrapReturnNoSegmentsRet8(IN PKTRAP_FRAME TrapFrame);
typedef
ATTRIB_NORETURN
@ -382,7 +383,7 @@ KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
TrapFrame->Dr7 = 0;
/* Check if the frame was from user mode or v86 mode */
if ((TrapFrame->SegCs & MODE_MASK) ||
if (KiUserTrap(TrapFrame) ||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
{
/* Check for active debugging */
@ -411,7 +412,7 @@ KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
TrapFrame->Dr7 = 0;
/* Check if the frame was from user mode or v86 mode */
if ((TrapFrame->SegCs & MODE_MASK) ||
if (KiUserTrap(TrapFrame) ||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
{
/* Check for active debugging */

View file

@ -1535,7 +1535,7 @@ KeFlushEntireTb(IN BOOLEAN Invalid,
if (TargetAffinity)
{
/* Sanity check */
ASSERT(Prcb == (volatile PKPRCB)KeGetCurrentPrcb());
ASSERT(Prcb == KeGetCurrentPrcb());
/* FIXME: TODO */
ASSERTMSG("Not yet implemented\n", FALSE);

View file

@ -137,7 +137,7 @@ NTAPI
KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
{
/* Check if this is user-mode or V86 */
if ((TrapFrame->SegCs & MODE_MASK) ||
if (KiUserTrap(TrapFrame) ||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
{
/* Return it directly */
@ -175,7 +175,7 @@ KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
Previous = KiEspFromTrapFrame(TrapFrame);
/* Check if this is user-mode or V86 */
if ((TrapFrame->SegCs & MODE_MASK) ||
if (KiUserTrap(TrapFrame) ||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
{
/* Write it directly */
@ -225,7 +225,7 @@ KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
/* Just return it */
return TrapFrame->HardwareSegSs;
}
else if (TrapFrame->SegCs & MODE_MASK)
else if (KiUserTrap(TrapFrame))
{
/* User mode, return the User SS */
return TrapFrame->HardwareSegSs | RPL_MASK;
@ -251,7 +251,7 @@ KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame,
/* Just write it */
TrapFrame->HardwareSegSs = Ss;
}
else if (TrapFrame->SegCs & MODE_MASK)
else if (KiUserTrap(TrapFrame))
{
/* Usermode, save the User SS */
TrapFrame->HardwareSegSs = Ss | RPL_MASK;
@ -398,7 +398,7 @@ KeContextToTrapFrame(IN PCONTEXT Context,
TrapFrame->V86Fs = Context->SegFs;
TrapFrame->V86Gs = Context->SegGs;
}
else if (!(TrapFrame->SegCs & MODE_MASK))
else if (!KiUserTrap(TrapFrame))
{
/* For kernel mode, write the standard values */
TrapFrame->SegDs = KGDT_R3_DATA | RPL_MASK;
@ -429,7 +429,7 @@ KeContextToTrapFrame(IN PCONTEXT Context,
/* Handle the extended registers */
if (((ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
CONTEXT_EXTENDED_REGISTERS) && (TrapFrame->SegCs & MODE_MASK))
CONTEXT_EXTENDED_REGISTERS) && KiUserTrap(TrapFrame))
{
/* Get the FX Area */
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
@ -463,7 +463,7 @@ KeContextToTrapFrame(IN PCONTEXT Context,
/* Handle the floating point state */
if (((ContextFlags & CONTEXT_FLOATING_POINT) ==
CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK))
CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame))
{
/* Get the FX Area */
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
@ -692,7 +692,7 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
/* Handle extended registers */
if (((Context->ContextFlags & CONTEXT_EXTENDED_REGISTERS) ==
CONTEXT_EXTENDED_REGISTERS) && (TrapFrame->SegCs & MODE_MASK))
CONTEXT_EXTENDED_REGISTERS) && KiUserTrap(TrapFrame))
{
/* Get the FX Save Area */
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
@ -712,7 +712,7 @@ KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
/* Handle Floating Point */
if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK))
CONTEXT_FLOATING_POINT) && KiUserTrap(TrapFrame))
{
/* Get the FX Save Area */
FxSaveArea = (PFX_SAVE_AREA)(TrapFrame + 1);
@ -1045,6 +1045,13 @@ DispatchToUser:
}
}
_SEH2_END;
DPRINT("First chance exception in %.16s, ExceptionCode: %lx, ExceptionAddress: %p, P0: %lx, P1: %lx\n",
PsGetCurrentProcess()->ImageFileName,
ExceptionRecord->ExceptionCode,
ExceptionRecord->ExceptionAddress,
ExceptionRecord->ExceptionInformation[0],
ExceptionRecord->ExceptionInformation[1]);
}
/* Try second chance */
@ -1060,11 +1067,13 @@ DispatchToUser:
}
/* 3rd strike, kill the process */
DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %p, BaseAddress: %p\n",
DPRINT1("Kill %.16s, ExceptionCode: %lx, ExceptionAddress: %p, BaseAddress: %p, P0: %lx, P1: %lx\n",
PsGetCurrentProcess()->ImageFileName,
ExceptionRecord->ExceptionCode,
ExceptionRecord->ExceptionAddress,
PsGetCurrentProcess()->SectionBaseAddress);
PsGetCurrentProcess()->SectionBaseAddress,
ExceptionRecord->ExceptionInformation[0],
ExceptionRecord->ExceptionInformation[1]);
ZwTerminateProcess(NtCurrentProcess(), ExceptionRecord->ExceptionCode);
KeBugCheckEx(KMODE_EXCEPTION_NOT_HANDLED,

View file

@ -20,9 +20,9 @@
ULONG_PTR
NTAPI
INIT_FUNCTION
Ki386EnableGlobalPage(IN volatile ULONG_PTR Context)
Ki386EnableGlobalPage(IN ULONG_PTR Context)
{
volatile PLONG Count = (PLONG)Context;
PLONG Count = (PLONG)Context;
ULONG Cr4, Cr3;
/* Disable interrupts */
@ -144,7 +144,7 @@ Ki386IdentityMapMakeValid(PLARGE_IDENTITY_MAP IdentityMap,
if (PageTable)
*PageTable = (PHARDWARE_PTE)(Pde->PageFrameNumber << PAGE_SHIFT);
}
return TRUE;
}
@ -172,7 +172,7 @@ Ki386MapAddress(PLARGE_IDENTITY_MAP IdentityMap,
/* Get PTE of VirtualPtr, make it valid, and map PhysicalPtr there */
Pte = &PageTable[(VirtualPtr >> 12) & ((1 << PTE_BITS) - 1)];
Pte->Valid = 1;
Pte->PageFrameNumber = PhysicalPtr.QuadPart >> PAGE_SHIFT;
Pte->PageFrameNumber = (PFN_NUMBER)(PhysicalPtr.QuadPart >> PAGE_SHIFT);
return TRUE;
}
@ -189,7 +189,7 @@ Ki386ConvertPte(PHARDWARE_PTE Pte)
PhysicalPtr = MmGetPhysicalAddress(VirtualPtr);
/* Map its physical address in the page table provided by the caller */
Pte->PageFrameNumber = PhysicalPtr.QuadPart >> PAGE_SHIFT;
Pte->PageFrameNumber = (PFN_NUMBER)(PhysicalPtr.QuadPart >> PAGE_SHIFT);
}
BOOLEAN

View file

@ -166,6 +166,7 @@ KiTrapExitStub KiSystemCallTrapReturn, (KI_RESTORE_EAX OR KI_RESTORE_FS OR KI
KiTrapExitStub KiEditedTrapReturn, (KI_RESTORE_VOLATILES OR KI_RESTORE_EFLAGS OR KI_EDITED_FRAME OR KI_EXIT_RET)
KiTrapExitStub KiTrapReturn, (KI_RESTORE_VOLATILES OR KI_RESTORE_SEGMENTS OR KI_EXIT_IRET)
KiTrapExitStub KiTrapReturnNoSegments, (KI_RESTORE_VOLATILES OR KI_EXIT_IRET)
KiTrapExitStub KiTrapReturnNoSegmentsRet8,(KI_RESTORE_VOLATILES OR KI_RESTORE_EFLAGS OR KI_EXIT_RET8)
#ifdef _MSC_VER
EXTERN _PsConvertToGuiThread@0:PROC

View file

@ -100,7 +100,7 @@ KiCommonExit(IN PKTRAP_FRAME TrapFrame, BOOLEAN SkipPreviousMode)
if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
{
/* Check if the frame was from user mode or v86 mode */
if ((TrapFrame->SegCs & MODE_MASK) ||
if (KiUserTrap(TrapFrame) ||
(TrapFrame->EFlags & EFLAGS_V86_MASK))
{
/* Handle debug registers */
@ -124,13 +124,13 @@ KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame);
/* Check for user mode exit */
if (TrapFrame->SegCs & MODE_MASK) KiTrapReturn(TrapFrame);
if (KiUserTrap(TrapFrame)) KiTrapReturn(TrapFrame);
/* Check for edited frame */
if (KiIsFrameEdited(TrapFrame)) KiEditedTrapReturn(TrapFrame);
/* Exit the trap to kernel mode */
KiTrapReturnNoSegments(TrapFrame);
KiTrapReturnNoSegmentsRet8(TrapFrame);
}
DECLSPEC_NORETURN
@ -152,7 +152,7 @@ KiServiceExit(IN PKTRAP_FRAME TrapFrame,
KeGetCurrentThread()->PreviousMode = (CCHAR)TrapFrame->PreviousPreviousMode;
/* Check for user mode exit */
if (TrapFrame->SegCs & MODE_MASK)
if (KiUserTrap(TrapFrame))
{
/* Check if we were single stepping */
if (TrapFrame->EFlags & EFLAGS_TF)
@ -186,13 +186,13 @@ KiServiceExit2(IN PKTRAP_FRAME TrapFrame)
if (TrapFrame->EFlags & EFLAGS_V86_MASK) KiTrapReturnNoSegments(TrapFrame);
/* Check for user mode exit */
if (TrapFrame->SegCs & MODE_MASK) KiTrapReturn(TrapFrame);
if (KiUserTrap(TrapFrame)) KiTrapReturn(TrapFrame);
/* Check for edited frame */
if (KiIsFrameEdited(TrapFrame)) KiEditedTrapReturn(TrapFrame);
/* Exit the trap to kernel mode */
KiTrapReturnNoSegments(TrapFrame);
KiTrapReturnNoSegmentsRet8(TrapFrame);
}
@ -1250,10 +1250,10 @@ KiTrap0EHandler(IN PKTRAP_FRAME TrapFrame)
/* Call the access fault handler */
Status = MmAccessFault(TrapFrame->ErrCode & 1,
(PVOID)Cr2,
TrapFrame->SegCs & MODE_MASK,
KiUserTrap(TrapFrame),
TrapFrame);
if (NT_SUCCESS(Status)) KiEoiHelper(TrapFrame);
/* Check for syscall fault */
#if 0
if ((TrapFrame->Eip == (ULONG_PTR)CopyParams) ||
@ -1541,7 +1541,7 @@ KiSystemCall(IN PKTRAP_FRAME TrapFrame,
TrapFrame->Dr7 = 0;
/* Check if the frame was from user mode */
if (TrapFrame->SegCs & MODE_MASK)
if (KiUserTrap(TrapFrame))
{
/* Check for active debugging */
if (KeGetCurrentThread()->Header.DebugActive & 0xFF)

View file

@ -67,7 +67,7 @@ KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame,
_SEH2_TRY
{
/* Sanity check */
ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode);
ASSERT(KiUserTrap(TrapFrame));
/* Get the aligned size */
AlignedEsp = Context.Esp & ~3;
@ -210,7 +210,7 @@ KeUserModeCallback(IN ULONG RoutineIndex,
}
/*
/*
* Stack layout for KiUserModeCallout:
* ----------------------------------
* KCALLOUT_FRAME.ResultLength <= 2nd Parameter to KiCallUserMode

View file

@ -153,7 +153,7 @@ KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
/* Check if we came from user mode */
#ifndef _M_ARM
if ((TrapFrame->SegCs & MODE_MASK) || (TrapFrame->EFlags & EFLAGS_V86_MASK))
if (KiUserTrap(TrapFrame) || (TrapFrame->EFlags & EFLAGS_V86_MASK))
#else
if (TrapFrame->PreviousMode == UserMode)
#endif