2010-07-24 01:12:13 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2023-12-06 08:49:06 +00:00
|
|
|
* PURPOSE: x64 trap handlers
|
2010-07-24 01:12:13 +00:00
|
|
|
* PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
VOID
|
|
|
|
KiRetireDpcListInDpcStack(
|
|
|
|
PKPRCB Prcb,
|
|
|
|
PVOID DpcStack);
|
|
|
|
|
2018-02-04 22:44:43 +00:00
|
|
|
NTSTATUS
|
|
|
|
KiConvertToGuiThread(
|
|
|
|
VOID);
|
|
|
|
|
2021-06-07 08:23:01 +00:00
|
|
|
_Requires_lock_not_held_(Prcb->PrcbLock)
|
2011-09-16 18:39:55 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
KiDpcInterruptHandler(VOID)
|
2011-09-16 18:39:55 +00:00
|
|
|
{
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
PKPRCB Prcb = KeGetCurrentPrcb();
|
|
|
|
PKTHREAD NewThread, OldThread;
|
|
|
|
KIRQL OldIrql;
|
|
|
|
|
|
|
|
/* Raise to DISPATCH_LEVEL */
|
|
|
|
OldIrql = KfRaiseIrql(DISPATCH_LEVEL);
|
|
|
|
|
|
|
|
/* Send an EOI */
|
|
|
|
KiSendEOI();
|
|
|
|
|
|
|
|
/* Check for pending timers, pending DPCs, or pending ready threads */
|
|
|
|
if ((Prcb->DpcData[0].DpcQueueDepth) ||
|
|
|
|
(Prcb->TimerRequest) ||
|
|
|
|
(Prcb->DeferredReadyListHead.Next))
|
|
|
|
{
|
|
|
|
/* Retire DPCs while under the DPC stack */
|
|
|
|
KiRetireDpcListInDpcStack(Prcb, Prcb->DpcStack);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Enable interrupts */
|
|
|
|
_enable();
|
|
|
|
|
|
|
|
/* Check for quantum end */
|
|
|
|
if (Prcb->QuantumEnd)
|
|
|
|
{
|
|
|
|
/* Handle quantum end */
|
|
|
|
Prcb->QuantumEnd = FALSE;
|
|
|
|
KiQuantumEnd();
|
|
|
|
}
|
|
|
|
else if (Prcb->NextThread)
|
|
|
|
{
|
2021-06-07 08:23:01 +00:00
|
|
|
/* Acquire the PRCB lock */
|
|
|
|
KiAcquirePrcbLock(Prcb);
|
|
|
|
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
/* Capture current thread data */
|
|
|
|
OldThread = Prcb->CurrentThread;
|
|
|
|
NewThread = Prcb->NextThread;
|
|
|
|
|
|
|
|
/* Set new thread data */
|
|
|
|
Prcb->NextThread = NULL;
|
|
|
|
Prcb->CurrentThread = NewThread;
|
|
|
|
|
|
|
|
/* The thread is now running */
|
|
|
|
NewThread->State = Running;
|
|
|
|
OldThread->WaitReason = WrDispatchInt;
|
|
|
|
|
|
|
|
/* Make the old thread ready */
|
|
|
|
KxQueueReadyThread(OldThread, Prcb);
|
|
|
|
|
|
|
|
/* Swap to the new thread */
|
|
|
|
KiSwapContext(APC_LEVEL, OldThread);
|
|
|
|
}
|
|
|
|
|
2018-03-09 20:07:10 +00:00
|
|
|
/* Disable interrupts and go back to old irql */
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
_disable();
|
2018-03-09 20:07:10 +00:00
|
|
|
KeLowerIrql(OldIrql);
|
2011-09-16 18:39:55 +00:00
|
|
|
}
|
|
|
|
|
2023-12-06 17:51:07 +00:00
|
|
|
VOID
|
|
|
|
KiNmiInterruptHandler(
|
|
|
|
_In_ PKTRAP_FRAME TrapFrame,
|
|
|
|
_In_ PKEXCEPTION_FRAME ExceptionFrame)
|
|
|
|
{
|
2024-04-01 18:22:29 +00:00
|
|
|
BOOLEAN ManualSwapGs = FALSE;
|
|
|
|
|
|
|
|
/* Check if the NMI came from kernel mode */
|
|
|
|
if ((TrapFrame->SegCs & MODE_MASK) == 0)
|
|
|
|
{
|
|
|
|
/* Check if GS base is already kernel mode. This is needed, because
|
|
|
|
we might be interrupted during an interrupt/exception from user-mode
|
|
|
|
before the swapgs instruction. */
|
|
|
|
if ((LONG64)__readmsr(MSR_GS_BASE) >= 0)
|
|
|
|
{
|
|
|
|
/* Swap GS to kernel */
|
|
|
|
__swapgs();
|
|
|
|
ManualSwapGs = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-29 18:01:31 +00:00
|
|
|
/* Check if this is a freeze */
|
|
|
|
if (KiProcessorFreezeHandler(TrapFrame, ExceptionFrame))
|
|
|
|
{
|
|
|
|
/* NMI was handled */
|
2024-04-01 18:22:29 +00:00
|
|
|
goto Exit;
|
2023-11-29 18:01:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Handle the NMI */
|
2023-12-06 17:51:07 +00:00
|
|
|
KiHandleNmi();
|
2024-04-01 18:22:29 +00:00
|
|
|
|
|
|
|
Exit:
|
|
|
|
/* Check if we need to swap GS back */
|
|
|
|
if (ManualSwapGs)
|
|
|
|
{
|
|
|
|
/* Swap GS back to user */
|
|
|
|
__swapgs();
|
|
|
|
}
|
2023-12-06 17:51:07 +00:00
|
|
|
}
|
|
|
|
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
#define MAX_SYSCALL_PARAMS 16
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NtSyscallFailure(void)
|
|
|
|
{
|
|
|
|
/* This is the failure function */
|
[NTOS:KE:X64] Improve kernel stack switching on GUI system calls
To be 100% correct and not rely on assumptions, stack switching can only be done when all previous code - starting with the syscall entry point - is pure asm code, since we can't rely on the C compiler to not use stack addresses in a way that is not transparent. Therefore the new code uses the same mechanism as for normal system calls, returning the address of the asm function KiConvertToGuiThread, which is then called like an Nt* function would be called normally. KiConvertToGuiThread then allocated a new stack, switches to it (which is now fine, since all the code is asm), frees the old stack, calls PsConvertToGuiThread (which now will not try to allocate another stack, since we already have one) and then jumps into the middle of KiSystemCallEntry64, where the system call is handled again.
Also simplify KiSystemCallEntry64 a bit by copying the first parameters into the trap frame, avoiding to allocate additional stack space for the call to KiSystemCallHandler, which now overlaps with the space that is allocated for the Nt* function.
Finally fix the locations where r10 and r11 are stored, which is TrapFrame->Rcx and TrapFrame->EFlags, based on the situation in user mode.
2018-02-06 19:52:16 +00:00
|
|
|
return (NTSTATUS)KeGetCurrentThread()->TrapFrame->Rax;
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
PVOID
|
|
|
|
KiSystemCallHandler(
|
2018-03-08 11:23:45 +00:00
|
|
|
VOID)
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
{
|
[NTOS:KE:X64] Improve kernel stack switching on GUI system calls
To be 100% correct and not rely on assumptions, stack switching can only be done when all previous code - starting with the syscall entry point - is pure asm code, since we can't rely on the C compiler to not use stack addresses in a way that is not transparent. Therefore the new code uses the same mechanism as for normal system calls, returning the address of the asm function KiConvertToGuiThread, which is then called like an Nt* function would be called normally. KiConvertToGuiThread then allocated a new stack, switches to it (which is now fine, since all the code is asm), frees the old stack, calls PsConvertToGuiThread (which now will not try to allocate another stack, since we already have one) and then jumps into the middle of KiSystemCallEntry64, where the system call is handled again.
Also simplify KiSystemCallEntry64 a bit by copying the first parameters into the trap frame, avoiding to allocate additional stack space for the call to KiSystemCallHandler, which now overlaps with the space that is allocated for the Nt* function.
Finally fix the locations where r10 and r11 are stored, which is TrapFrame->Rcx and TrapFrame->EFlags, based on the situation in user mode.
2018-02-06 19:52:16 +00:00
|
|
|
PKTRAP_FRAME TrapFrame;
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
PKSERVICE_TABLE_DESCRIPTOR DescriptorTable;
|
|
|
|
PKTHREAD Thread;
|
|
|
|
PULONG64 KernelParams, UserParams;
|
2024-03-25 20:37:50 +00:00
|
|
|
ULONG ServiceNumber, TableIndex, Count;
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
ULONG64 UserRsp;
|
[NTOS:KE:X64] Improve kernel stack switching on GUI system calls
To be 100% correct and not rely on assumptions, stack switching can only be done when all previous code - starting with the syscall entry point - is pure asm code, since we can't rely on the C compiler to not use stack addresses in a way that is not transparent. Therefore the new code uses the same mechanism as for normal system calls, returning the address of the asm function KiConvertToGuiThread, which is then called like an Nt* function would be called normally. KiConvertToGuiThread then allocated a new stack, switches to it (which is now fine, since all the code is asm), frees the old stack, calls PsConvertToGuiThread (which now will not try to allocate another stack, since we already have one) and then jumps into the middle of KiSystemCallEntry64, where the system call is handled again.
Also simplify KiSystemCallEntry64 a bit by copying the first parameters into the trap frame, avoiding to allocate additional stack space for the call to KiSystemCallHandler, which now overlaps with the space that is allocated for the Nt* function.
Finally fix the locations where r10 and r11 are stored, which is TrapFrame->Rcx and TrapFrame->EFlags, based on the situation in user mode.
2018-02-06 19:52:16 +00:00
|
|
|
|
|
|
|
/* Get a pointer to the trap frame */
|
|
|
|
TrapFrame = (PKTRAP_FRAME)((PULONG64)_AddressOfReturnAddress() + 1 + MAX_SYSCALL_PARAMS);
|
|
|
|
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
/* Increase system call count */
|
|
|
|
__addgsdword(FIELD_OFFSET(KIPCR, Prcb.KeSystemCalls), 1);
|
|
|
|
|
|
|
|
/* Get the current thread */
|
|
|
|
Thread = KeGetCurrentThread();
|
|
|
|
|
|
|
|
/* Set previous mode */
|
|
|
|
Thread->PreviousMode = TrapFrame->PreviousMode = UserMode;
|
|
|
|
|
2018-05-15 10:43:37 +00:00
|
|
|
/* We don't have an exception frame yet */
|
|
|
|
TrapFrame->ExceptionFrame = 0;
|
|
|
|
|
2024-12-12 12:44:05 +00:00
|
|
|
/* Get the user Stack pointer */
|
|
|
|
UserRsp = TrapFrame->Rsp;
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
|
|
|
|
/* Enable interrupts */
|
|
|
|
_enable();
|
|
|
|
|
|
|
|
/* If the usermode rsp was not a usermode address, prepare an exception */
|
|
|
|
if (UserRsp > MmUserProbeAddress) UserRsp = MmUserProbeAddress;
|
|
|
|
|
|
|
|
/* Get the address of the usermode and kernelmode parameters */
|
|
|
|
UserParams = (PULONG64)UserRsp + 1;
|
|
|
|
KernelParams = (PULONG64)TrapFrame - MAX_SYSCALL_PARAMS;
|
|
|
|
|
|
|
|
/* Get the system call number from the trap frame and decode it */
|
|
|
|
ServiceNumber = (ULONG)TrapFrame->Rax;
|
2024-03-25 20:37:50 +00:00
|
|
|
TableIndex = (ServiceNumber >> TABLE_OFFSET_BITS) & ((1 << TABLE_NUMBER_BITS) - 1);
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
ServiceNumber &= SERVICE_NUMBER_MASK;
|
|
|
|
|
2019-05-28 09:06:56 +00:00
|
|
|
/* Check for win32k system calls */
|
2024-03-25 20:37:50 +00:00
|
|
|
if (TableIndex == WIN32K_SERVICE_INDEX)
|
2019-05-28 09:06:56 +00:00
|
|
|
{
|
|
|
|
ULONG GdiBatchCount;
|
|
|
|
|
|
|
|
/* Read the GDI batch count from the TEB */
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
GdiBatchCount = NtCurrentTeb()->GdiBatchCount;
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
GdiBatchCount = 0;
|
|
|
|
}
|
2021-01-05 18:22:21 +00:00
|
|
|
_SEH2_END;
|
2019-05-28 09:06:56 +00:00
|
|
|
|
|
|
|
/* Flush batch, if there are entries */
|
|
|
|
if (GdiBatchCount != 0)
|
|
|
|
{
|
|
|
|
KeGdiFlushUserBatch();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
/* Get descriptor table */
|
2024-03-25 20:37:50 +00:00
|
|
|
DescriptorTable = &((PKSERVICE_TABLE_DESCRIPTOR)Thread->ServiceTable)[TableIndex];
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
|
2018-02-04 22:44:43 +00:00
|
|
|
/* Validate the system call number */
|
|
|
|
if (ServiceNumber >= DescriptorTable->Limit)
|
|
|
|
{
|
2024-03-25 20:37:50 +00:00
|
|
|
/* Check if this is a GUI call and this is not a GUI thread yet */
|
|
|
|
if ((TableIndex == WIN32K_SERVICE_INDEX) &&
|
|
|
|
(Thread->ServiceTable == KeServiceDescriptorTable))
|
2018-02-04 22:44:43 +00:00
|
|
|
{
|
2024-03-25 20:37:50 +00:00
|
|
|
/* Convert this thread to a GUI thread.
|
|
|
|
It is invalid to change the stack in the middle of a C function,
|
|
|
|
therefore we return KiConvertToGuiThread to the system call entry
|
|
|
|
point, which then calls the asm function KiConvertToGuiThread,
|
|
|
|
which allocates a new stack, switches to it, calls
|
|
|
|
PsConvertToGuiThread and resumes in the middle of
|
|
|
|
KiSystemCallEntry64 to restart the system call handling.
|
|
|
|
If converting fails, the system call returns a failure code. */
|
|
|
|
return (PVOID)KiConvertToGuiThread;
|
2018-02-04 22:44:43 +00:00
|
|
|
}
|
|
|
|
|
2024-03-25 20:37:50 +00:00
|
|
|
/* Fail the call */
|
|
|
|
TrapFrame->Rax = STATUS_INVALID_SYSTEM_SERVICE;
|
|
|
|
return (PVOID)NtSyscallFailure;
|
2018-02-04 22:44:43 +00:00
|
|
|
}
|
|
|
|
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
/* Get stack bytes and calculate argument count */
|
|
|
|
Count = DescriptorTable->Number[ServiceNumber] / 8;
|
|
|
|
|
2021-01-05 18:22:21 +00:00
|
|
|
_SEH2_TRY
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
{
|
|
|
|
switch (Count)
|
|
|
|
{
|
|
|
|
case 16: KernelParams[15] = UserParams[15];
|
|
|
|
case 15: KernelParams[14] = UserParams[14];
|
|
|
|
case 14: KernelParams[13] = UserParams[13];
|
|
|
|
case 13: KernelParams[12] = UserParams[12];
|
|
|
|
case 12: KernelParams[11] = UserParams[11];
|
|
|
|
case 11: KernelParams[10] = UserParams[10];
|
|
|
|
case 10: KernelParams[9] = UserParams[9];
|
|
|
|
case 9: KernelParams[8] = UserParams[8];
|
|
|
|
case 8: KernelParams[7] = UserParams[7];
|
|
|
|
case 7: KernelParams[6] = UserParams[6];
|
|
|
|
case 6: KernelParams[5] = UserParams[5];
|
|
|
|
case 5: KernelParams[4] = UserParams[4];
|
[NTOS:KE:X64] Improve kernel stack switching on GUI system calls
To be 100% correct and not rely on assumptions, stack switching can only be done when all previous code - starting with the syscall entry point - is pure asm code, since we can't rely on the C compiler to not use stack addresses in a way that is not transparent. Therefore the new code uses the same mechanism as for normal system calls, returning the address of the asm function KiConvertToGuiThread, which is then called like an Nt* function would be called normally. KiConvertToGuiThread then allocated a new stack, switches to it (which is now fine, since all the code is asm), frees the old stack, calls PsConvertToGuiThread (which now will not try to allocate another stack, since we already have one) and then jumps into the middle of KiSystemCallEntry64, where the system call is handled again.
Also simplify KiSystemCallEntry64 a bit by copying the first parameters into the trap frame, avoiding to allocate additional stack space for the call to KiSystemCallHandler, which now overlaps with the space that is allocated for the Nt* function.
Finally fix the locations where r10 and r11 are stored, which is TrapFrame->Rcx and TrapFrame->EFlags, based on the situation in user mode.
2018-02-06 19:52:16 +00:00
|
|
|
case 4:
|
|
|
|
case 3:
|
|
|
|
case 2:
|
|
|
|
case 1:
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2018-03-08 11:23:45 +00:00
|
|
|
ASSERT(FALSE);
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2018-03-08 11:23:45 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
{
|
|
|
|
TrapFrame->Rax = _SEH2_GetExceptionCode();
|
|
|
|
return (PVOID)NtSyscallFailure;
|
|
|
|
}
|
2021-01-05 18:22:21 +00:00
|
|
|
_SEH2_END;
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
|
|
|
|
return (PVOID)DescriptorTable->Base[ServiceNumber];
|
2010-07-24 01:12:13 +00:00
|
|
|
}
|
|
|
|
|
[NTOSKRNL/KE/AMD64]
- Fix stack alignment in KiSwitchToBootStack
- Handle ExceptionFrame == NULL in KeContextToTrapFrame and KeTrapFrameToContext
- Implement KiSwapContextInternal
- Fix KiSwapContext and KiThreadStartup
- Implement dispatching of user mode exceptions including in-paging of module data used by the kernel-debugger
- Implement KeInitializeInterrupt, KeConnectInterrupt, KeSynchronizeExecution
- Don't zero more than the actual PCR size in KiInitializePcr
- Add asm function KiInitializeSegments to initialize the segment selectors to proper values
- Initialize system call entrypoints in KiInitializeCpu
- Implement KiDpcInterruptHandler, KiIdleLoop, KiInitializeUserApc, KiSwapProcess, KiSystemCallHandler, KiInitializeContextThread, KiSwapContextResume
- Implement asm functions KiRetireDpcList, KiInterruptDispatch, KiSystemCallEntry64, KiZwSystemService
svn path=/trunk/; revision=55405
2012-02-04 11:32:13 +00:00
|
|
|
|
|
|
|
// FIXME: we need to
|
2010-07-24 01:12:13 +00:00
|
|
|
VOID
|
|
|
|
KiSystemService(IN PKTHREAD Thread,
|
|
|
|
IN PKTRAP_FRAME TrapFrame,
|
|
|
|
IN ULONG Instruction)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
2011-09-16 18:39:55 +00:00
|
|
|
__debugbreak();
|
2010-07-24 01:12:13 +00:00
|
|
|
}
|
|
|
|
|