* Increase total system call count in KPCR for performance counter.
* Increase per-systemcall call count in the KiServiceTable if it was
specified, for performance counters.
* Add sanity checks to system call handler to detect:
- User-mode system calls at > PASSIVE
- User-mode system call return at > PASSIVE
- Return to user-mode with Kernel APCs disabled.
* These features are on DBG only.
Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S
--- trunk/reactos/ntoskrnl/ke/i386/syscall.S 2006-01-16 21:14:32 UTC
(rev 20921)
+++ trunk/reactos/ntoskrnl/ke/i386/syscall.S 2006-01-16 21:41:19 UTC
(rev 20922)
@@ -7,6 +7,8 @@
#include <asm.h>
#include <internal/i386/asmmacro.S>
+#define APC_INDEX_MISMATCH 1
+#define IRQL_GT_ZERO_AT_SYSTEM_SERVICE 0x4A
.globl _KiServiceExit
.globl _KiServiceExit2
@@ -322,7 +324,18 @@
#endif
NotWin32K:
+ /* Increase total syscall count */
+ inc dword ptr fs:[KPCR_SYSTEM_CALLS]
+
+#ifdef DBG
+ /* Increase per-syscall count */
+ mov ecx, [edi+4]
+ jecxz NoCountTable
+ inc dword ptr [ecx+eax*4]
+#endif
+
/* Users's current stack frame pointer is source */
+NoCountTable:
mov esi, edx
/* Allocate room for argument list from kernel stack */
@@ -346,6 +359,14 @@
rep movsd
#ifdef DBG
+
+ /* Make sure this isn't a user-mode call at elevated IRQL */
+ test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
+ jz SkipCheck
+ call _KeGetCurrentIrql@0
+ or al, al
+ jnz InvalidIrql
+
/*
* The following lines are for the benefit of GDB. It will see the
return
* address of the "call ebx" below, find the last label before it
and
@@ -355,6 +376,7 @@
* stack backtrace. Since we do want to backtrace into usermode,
let's
* make GDB happy and create a standard prolog.
*/
+SkipCheck:
KiSystemService:
push ebp
mov ebp,esp
@@ -364,6 +386,30 @@
/* Do the System Call */
call ebx
+#ifdef DBG
+ /* Make sure the user-mode call didn't return at elevated IRQL */
+ test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
+ jz SkipCheck2
+ mov esi, eax /* We need to save the syscall's return
val */
+ call _KeGetCurrentIrql@0
+ or al, al
+ jnz InvalidIrql
+ mov eax, esi /* Restore it */
+
+ /* Get our temporary current thread pointer for sanity check */
+ mov ecx, fs:[KPCR_CURRENT_THREAD]
+
+ /* Make sure that we are not attached and that APCs are not
disabled */
+ mov dl, [ecx+KTHREAD_APC_STATE_INDEX]
+ or dl, dl
+ jnz InvalidIndex
+ mov edx, [ecx+KTHREAD_COMBINED_APC_DISABLE]
+ or edx, edx
+ jnz InvalidIndex
+#endif
+
+SkipCheck2:
+
/* Deallocate the kernel stack frame */
mov esp, ebp
@@ -540,6 +586,39 @@
sti
sysexit
+#ifdef DBG
+InvalidIrql:
+ /* Save current IRQL */
+ push fs:[KPCR_IRQL]
+
+ /* Set us at passive */
+ mov dword ptr fs:[KPCR_IRQL], 0
+ cli
+
+ /* Bugcheck */
+ push 0
+ push 0
+ push eax
+ push ebx
+ push IRQL_GT_ZERO_AT_SYSTEM_SERVICE
+ call _KeBugCheckEx@20
+
+InvalidIndex:
+
+ /* Get the index and APC state */
+ movzx eax, byte ptr [ecx+KTHREAD_APC_STATE_INDEX]
+ mov edx, [ecx+KTHREAD_COMBINED_APC_DISABLE]
+
+ /* Bugcheck */
+ push 0
+ push edx
+ push eax
+ push ebx
+ push APC_INDEX_MISMATCH
+ call _KeBugCheckEx@20
+ ret
+#endif
+
V86_Exit:
/* Move to EDX position */
add esp, KTRAP_FRAME_EDX
Do set ESP0, but after we save the old value for the V86 hack.
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
--- trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S 2006-01-16 17:05:50 UTC
(rev 20914)
+++ trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S 2006-01-16 17:07:45 UTC
(rev 20915)
@@ -170,12 +170,12 @@
NoAdjust:
- /* Set new ESP0 */
- //mov [ebp+KTSS_ESP0], eax
-
/* Save it */
push [ebp+KTSS_ESP0]
+ /* Set new ESP0 */
+ mov [ebp+KTSS_ESP0], eax
+
/* Set TEB pointer */
mov eax, [esi+KTHREAD_TEB]
mov [ebx+KPCR_TEB], eax
Disable correct usage of ESP0 since it seems the V86 code is still not
ready to handle that. This should fix the V86 exceptions some people
have been having.
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
Modified: trunk/reactos/ntoskrnl/ke/i386/thread.c
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S
--- trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S 2006-01-16 16:45:27 UTC
(rev 20913)
+++ trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S 2006-01-16 17:05:50 UTC
(rev 20914)
@@ -171,8 +171,11 @@
NoAdjust:
/* Set new ESP0 */
- mov [ebp+KTSS_ESP0], eax
+ //mov [ebp+KTSS_ESP0], eax
+ /* Save it */
+ push [ebp+KTSS_ESP0]
+
/* Set TEB pointer */
mov eax, [esi+KTHREAD_TEB]
mov [ebx+KPCR_TEB], eax
@@ -257,6 +260,9 @@
mov cr0, eax
4:
+ /* Restore ESP0 */
+ pop [ebp+KTSS_ESP0]
+
/* Restore exception list */
pop [ebx+KPCR_EXCEPTION_LIST]
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/thread.c
--- trunk/reactos/ntoskrnl/ke/i386/thread.c 2006-01-16 16:45:27 UTC
(rev 20913)
+++ trunk/reactos/ntoskrnl/ke/i386/thread.c 2006-01-16 17:05:50 UTC
(rev 20914)
@@ -14,6 +14,7 @@
typedef struct _KSHARED_CTXSWITCH_FRAME
{
+ ULONG Esp0;
PVOID ExceptionList;
PVOID RetEip;
} KSHARED_CTXSWITCH_FRAME, *PKSHARED_CTXSWITCH_FRAME;
@@ -231,6 +232,9 @@
/* And set up the Context Switch Frame */
CtxSwitchFrame->RetEip = KiThreadStartup;
+ CtxSwitchFrame->Esp0 = (ULONG_PTR)Thread->InitialStack -
+ sizeof(FX_SAVE_AREA) -
+ 0x10;
CtxSwitchFrame->ExceptionList = (PVOID)0xFFFFFFFF;
/* Save back the new value of the kernel stack. */