mirror of
https://github.com/reactos/reactos.git
synced 2024-06-25 23:41:35 +00:00
[NTOS:KE:X64] Move KiInitializeUserApc to usercall.c
This commit is contained in:
parent
fbdff437fd
commit
aaa86d078e
|
@ -243,108 +243,6 @@ KiIdleLoop(VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \name KiInitializeUserApc
|
|
||||||
*
|
|
||||||
* \brief
|
|
||||||
* Prepares the current trap frame (which must have come from user mode)
|
|
||||||
* with the ntdll.KiUserApcDispatcher entrypoint, copying a CONTEXT
|
|
||||||
* record with the context from the old trap frame to the threads user
|
|
||||||
* mode stack.
|
|
||||||
*
|
|
||||||
* \param ExceptionFrame
|
|
||||||
* \param TrapFrame
|
|
||||||
* \param NormalRoutine
|
|
||||||
* \param NormalContext
|
|
||||||
* \param SystemArgument1
|
|
||||||
* \param SystemArgument2
|
|
||||||
*
|
|
||||||
* \remarks
|
|
||||||
* This function is called from KiDeliverApc, when the trap frame came
|
|
||||||
* from user mode. This happens before a systemcall or interrupt exits back
|
|
||||||
* to usermode or when a thread is started from PspUserThreadstartup.
|
|
||||||
* The trap exit code will then leave to KiUserApcDispatcher which in turn
|
|
||||||
* calls the NormalRoutine, passing NormalContext, SystemArgument1 and
|
|
||||||
* SystemArgument2 as parameters. When that function returns, it calls
|
|
||||||
* NtContinue to return back to the kernel, where the old context that was
|
|
||||||
* saved on the usermode stack is restored and execution is transferred
|
|
||||||
* back to usermode, where the original trap originated from.
|
|
||||||
*
|
|
||||||
*--*/
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame,
|
|
||||||
IN PKTRAP_FRAME TrapFrame,
|
|
||||||
IN PKNORMAL_ROUTINE NormalRoutine,
|
|
||||||
IN PVOID NormalContext,
|
|
||||||
IN PVOID SystemArgument1,
|
|
||||||
IN PVOID SystemArgument2)
|
|
||||||
{
|
|
||||||
CONTEXT Context = { 0 };
|
|
||||||
ULONG64 AlignedRsp, Stack;
|
|
||||||
EXCEPTION_RECORD SehExceptRecord;
|
|
||||||
|
|
||||||
/* Sanity check, that the trap frame is from user mode */
|
|
||||||
ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode);
|
|
||||||
|
|
||||||
/* Convert the current trap frame to a context */
|
|
||||||
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
|
||||||
KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
|
|
||||||
|
|
||||||
/* We jump to KiUserApcDispatcher in ntdll */
|
|
||||||
TrapFrame->Rip = (ULONG64)KeUserApcDispatcher;
|
|
||||||
|
|
||||||
/* Setup Ring 3 segments */
|
|
||||||
TrapFrame->SegCs = KGDT64_R3_CODE | RPL_MASK;
|
|
||||||
TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
|
|
||||||
TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK;
|
|
||||||
TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
|
|
||||||
TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
|
|
||||||
TrapFrame->SegSs = KGDT64_R3_DATA | RPL_MASK;
|
|
||||||
|
|
||||||
/* Sanitize EFLAGS, enable interrupts */
|
|
||||||
TrapFrame->EFlags = (Context.EFlags & EFLAGS_USER_SANITIZE);
|
|
||||||
TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK;
|
|
||||||
|
|
||||||
/* Set parameters for KiUserApcDispatcher */
|
|
||||||
Context.P1Home = (ULONG64)NormalContext;
|
|
||||||
Context.P2Home = (ULONG64)SystemArgument1;
|
|
||||||
Context.P3Home = (ULONG64)SystemArgument2;
|
|
||||||
Context.P4Home = (ULONG64)NormalRoutine;
|
|
||||||
|
|
||||||
/* Check if thread has IOPL and force it enabled if so */
|
|
||||||
//if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= EFLAGS_IOPL;
|
|
||||||
|
|
||||||
/* Align Stack to 16 bytes and allocate space */
|
|
||||||
AlignedRsp = Context.Rsp & ~15;
|
|
||||||
Stack = AlignedRsp - sizeof(CONTEXT);
|
|
||||||
TrapFrame->Rsp = Stack;
|
|
||||||
|
|
||||||
/* The stack must be 16 byte aligned for KiUserApcDispatcher */
|
|
||||||
ASSERT((Stack & 15) == 0);
|
|
||||||
|
|
||||||
/* Protect with SEH */
|
|
||||||
_SEH2_TRY
|
|
||||||
{
|
|
||||||
/* Probe the stack */
|
|
||||||
ProbeForWrite((PCONTEXT)Stack, sizeof(CONTEXT), 8);
|
|
||||||
|
|
||||||
/* Copy the context */
|
|
||||||
RtlCopyMemory((PCONTEXT)Stack, &Context, sizeof(CONTEXT));
|
|
||||||
}
|
|
||||||
_SEH2_EXCEPT((RtlCopyMemory(&SehExceptRecord, _SEH2_GetExceptionInformation()->ExceptionRecord, sizeof(EXCEPTION_RECORD)), EXCEPTION_EXECUTE_HANDLER))
|
|
||||||
{
|
|
||||||
/* Dispatch the exception */
|
|
||||||
SehExceptRecord.ExceptionAddress = (PVOID)TrapFrame->Rip;
|
|
||||||
KiDispatchException(&SehExceptRecord,
|
|
||||||
ExceptionFrame,
|
|
||||||
TrapFrame,
|
|
||||||
UserMode,
|
|
||||||
TRUE);
|
|
||||||
}
|
|
||||||
_SEH2_END;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
KiSwapProcess(IN PKPROCESS NewProcess,
|
KiSwapProcess(IN PKPROCESS NewProcess,
|
||||||
|
|
114
ntoskrnl/ke/amd64/usercall.c
Normal file
114
ntoskrnl/ke/amd64/usercall.c
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: GPL - 2.0 + (https ://spdx.org/licenses/GPL-2.0+)
|
||||||
|
* PURPOSE: AMD64 User-mode Callout Mechanisms (APC and Win32K Callbacks)
|
||||||
|
* COPYRIGHT: Timo Kreuzer(timo.kreuzer@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
/*! \name KiInitializeUserApc
|
||||||
|
*
|
||||||
|
* \brief
|
||||||
|
* Prepares the current trap frame (which must have come from user mode)
|
||||||
|
* with the ntdll.KiUserApcDispatcher entrypoint, copying a CONTEXT
|
||||||
|
* record with the context from the old trap frame to the threads user
|
||||||
|
* mode stack.
|
||||||
|
*
|
||||||
|
* \param ExceptionFrame
|
||||||
|
* \param TrapFrame
|
||||||
|
* \param NormalRoutine
|
||||||
|
* \param NormalContext
|
||||||
|
* \param SystemArgument1
|
||||||
|
* \param SystemArgument2
|
||||||
|
*
|
||||||
|
* \remarks
|
||||||
|
* This function is called from KiDeliverApc, when the trap frame came
|
||||||
|
* from user mode. This happens before a systemcall or interrupt exits back
|
||||||
|
* to usermode or when a thread is started from PspUserThreadstartup.
|
||||||
|
* The trap exit code will then leave to KiUserApcDispatcher which in turn
|
||||||
|
* calls the NormalRoutine, passing NormalContext, SystemArgument1 and
|
||||||
|
* SystemArgument2 as parameters. When that function returns, it calls
|
||||||
|
* NtContinue to return back to the kernel, where the old context that was
|
||||||
|
* saved on the usermode stack is restored and execution is transferred
|
||||||
|
* back to usermode, where the original trap originated from.
|
||||||
|
*
|
||||||
|
*--*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
KiInitializeUserApc(
|
||||||
|
_In_ PKEXCEPTION_FRAME ExceptionFrame,
|
||||||
|
_Inout_ PKTRAP_FRAME TrapFrame,
|
||||||
|
_In_ PKNORMAL_ROUTINE NormalRoutine,
|
||||||
|
_In_ PVOID NormalContext,
|
||||||
|
_In_ PVOID SystemArgument1,
|
||||||
|
_In_ PVOID SystemArgument2)
|
||||||
|
{
|
||||||
|
CONTEXT Context;
|
||||||
|
ULONG64 AlignedRsp, Stack;
|
||||||
|
EXCEPTION_RECORD SehExceptRecord;
|
||||||
|
|
||||||
|
/* Sanity check, that the trap frame is from user mode */
|
||||||
|
ASSERT((TrapFrame->SegCs & MODE_MASK) != KernelMode);
|
||||||
|
|
||||||
|
/* Convert the current trap frame to a context */
|
||||||
|
Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
|
||||||
|
KeTrapFrameToContext(TrapFrame, ExceptionFrame, &Context);
|
||||||
|
|
||||||
|
/* We jump to KiUserApcDispatcher in ntdll */
|
||||||
|
TrapFrame->Rip = (ULONG64)KeUserApcDispatcher;
|
||||||
|
|
||||||
|
/* Setup Ring 3 segments */
|
||||||
|
TrapFrame->SegCs = KGDT64_R3_CODE | RPL_MASK;
|
||||||
|
TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
|
||||||
|
TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK;
|
||||||
|
TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
|
||||||
|
TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
|
||||||
|
TrapFrame->SegSs = KGDT64_R3_DATA | RPL_MASK;
|
||||||
|
|
||||||
|
/* Sanitize EFLAGS, enable interrupts */
|
||||||
|
TrapFrame->EFlags = (Context.EFlags & EFLAGS_USER_SANITIZE);
|
||||||
|
TrapFrame->EFlags |= EFLAGS_INTERRUPT_MASK;
|
||||||
|
|
||||||
|
/* Set parameters for KiUserApcDispatcher */
|
||||||
|
Context.P1Home = (ULONG64)NormalContext;
|
||||||
|
Context.P2Home = (ULONG64)SystemArgument1;
|
||||||
|
Context.P3Home = (ULONG64)SystemArgument2;
|
||||||
|
Context.P4Home = (ULONG64)NormalRoutine;
|
||||||
|
|
||||||
|
/* Check if thread has IOPL and force it enabled if so */
|
||||||
|
//if (KeGetCurrentThread()->Iopl) TrapFrame->EFlags |= EFLAGS_IOPL;
|
||||||
|
|
||||||
|
/* Align Stack to 16 bytes and allocate space */
|
||||||
|
AlignedRsp = Context.Rsp & ~15;
|
||||||
|
Stack = AlignedRsp - sizeof(CONTEXT);
|
||||||
|
TrapFrame->Rsp = Stack;
|
||||||
|
|
||||||
|
/* The stack must be 16 byte aligned for KiUserApcDispatcher */
|
||||||
|
ASSERT((Stack & 15) == 0);
|
||||||
|
|
||||||
|
/* Protect with SEH */
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
/* Probe the stack */
|
||||||
|
ProbeForWrite((PCONTEXT)Stack, sizeof(CONTEXT), 8);
|
||||||
|
|
||||||
|
/* Copy the context */
|
||||||
|
RtlCopyMemory((PCONTEXT)Stack, &Context, sizeof(CONTEXT));
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT((RtlCopyMemory(&SehExceptRecord, _SEH2_GetExceptionInformation()->ExceptionRecord, sizeof(EXCEPTION_RECORD)), EXCEPTION_EXECUTE_HANDLER))
|
||||||
|
{
|
||||||
|
/* Dispatch the exception */
|
||||||
|
SehExceptRecord.ExceptionAddress = (PVOID)TrapFrame->Rip;
|
||||||
|
KiDispatchException(&SehExceptRecord,
|
||||||
|
ExceptionFrame,
|
||||||
|
TrapFrame,
|
||||||
|
UserMode,
|
||||||
|
TRUE);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
|
@ -325,11 +325,12 @@ elseif(ARCH STREQUAL "amd64")
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/kiinit.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/kiinit.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/krnlinit.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/krnlinit.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/spinlock.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/spinlock.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/stubs.c
|
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/thrdini.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/thrdini.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/init.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/init.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/page.c
|
${REACTOS_SOURCE_DIR}/ntoskrnl/mm/amd64/page.c
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/amd64/psctx.c)
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ps/amd64/psctx.c
|
||||||
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/stubs.c
|
||||||
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ke/amd64/usercall.c)
|
||||||
elseif(ARCH STREQUAL "arm")
|
elseif(ARCH STREQUAL "arm")
|
||||||
list(APPEND ASM_SOURCE
|
list(APPEND ASM_SOURCE
|
||||||
${REACTOS_SOURCE_DIR}/ntoskrnl/ex/arm/ioport.s
|
${REACTOS_SOURCE_DIR}/ntoskrnl/ex/arm/ioport.s
|
||||||
|
|
Loading…
Reference in a new issue