SYSENTER support, INT2E Optimization, new Syscall Table/Stub generator and svn:ignore fixes. Please read associated Mailing List Post. Modified: trunk/reactos/Makefile Modified: trunk/reactos/config Deleted: trunk/reactos/iface/ Modified: trunk/reactos/include/napi/shared_data.h Modified: trunk/reactos/ntoskrnl/Makefile Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h Modified: trunk/reactos/ntoskrnl/include/internal/i386/ps.h Modified: trunk/reactos/ntoskrnl/ke/i386/bthread.S Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c Modified: trunk/reactos/ntoskrnl/ke/i386/gdt.c Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c Modified: trunk/reactos/ntoskrnl/ke/i386/stkswitch.S Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S Modified: trunk/reactos/ntoskrnl/ke/i386/usercall.c Modified: trunk/reactos/ntoskrnl/ke/kthread.c Modified: trunk/reactos/ntoskrnl/ke/process.c Modified: trunk/reactos/ntoskrnl/ps/i386/continue.c Modified: trunk/reactos/subsys/system/vmwinst/vmwinst.c Added: trunk/reactos/tools/nci/ Added: trunk/reactos/tools/nci/makefile Added: trunk/reactos/tools/nci/ncitool.c Added: trunk/reactos/tools/nci/sysfuncs.lst Added: trunk/reactos/tools/nci/w32ksvc.db _____
Modified: trunk/reactos/Makefile --- trunk/reactos/Makefile 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/Makefile 2005-01-17 07:10:34 UTC (rev 13090) @@ -130,7 +130,7 @@
all: bootstrap $(BOOT_LOADERS) $(COMPONENTS) $(REGTESTS) $(HALS) $(BUS) $(LIB_FSLIB) \ $(DLLS) $(SUBSYS) $(KERNEL_DRIVERS) $(SYS_APPS) $(SYS_SVC) $(APPS) $(EXT_MODULES)
-bootstrap: dk implib iface_native iface_additional +bootstrap: dk implib iface_native
depends: $(LIB_STATIC:%=%_depends) $(LIB_FSLIB:%=%_depends) msvcrt_depends $(DLLS:%=%_depends) \ $(SUBSYS:%=%_depends) $(SYS_SVC:%=%_depends) \ @@ -147,7 +147,7 @@ $(KERNEL_DRIVERS:%=%_test) $(SUBSYS:%=%_test) \ $(SYS_SVC:%=%_test) $(EXT_MODULES:%=%_test)
-clean: tools dk_clean iface_native_clean iface_additional_clean hallib_clean \ +clean: tools dk_clean iface_native_clean hallib_clean \ $(BOOT_LOADERS:%=%_clean) $(HALS:%=%_clean) $(COMPONENTS:%=%_clean) \ $(BUS:%=%_clean) $(LIB_STATIC:%=%_clean) $(LIB_FSLIB:%=%_clean) \ msvcrt_clean $(DLLS:%=%_clean) $(KERNEL_DRIVERS:%=%_clean) \ @@ -462,37 +462,21 @@ # Interfaces # iface_native: - $(MAKE) --silent -C iface/native + $(MAKE) --silent -C tools/nci
iface_native_implib: iface_native_test: iface_native_clean: - $(MAKE) --silent -C iface/native clean + $(MAKE) --silent -C tools/nci clean
iface_native_install:
iface_native_bootcd:
-iface_additional: - $(MAKE) --silent -C iface/addsys - -iface_additional_implib: - -iface_additional_test: - -iface_additional_clean: - $(MAKE) --silent -C iface/addsys clean - -iface_additional_install: - -iface_additional_bootcd: - .PHONY: iface_native iface_native_implib iface_native_test iface_native_clean \ - iface_native_install iface_native_bootcd iface_additional \ - iface_additional_implib iface_additional_test iface_additional_clean \ - iface_additional_install iface_additional_bootcd + iface_native_install iface_native_bootcd
# _____
Modified: trunk/reactos/config --- trunk/reactos/config 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/config 2005-01-17 07:10:34 UTC (rev 13090) @@ -25,7 +25,7 @@
# # Whether to compile for debugging # -DBG := 0 +DBG := 0
# # Whether to compile with optimizations _____
Modified: trunk/reactos/include/napi/shared_data.h --- trunk/reactos/include/napi/shared_data.h 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/include/napi/shared_data.h 2005-01-17 07:10:34 UTC (rev 13090) @@ -13,6 +13,8 @@
#define PF_PAE_ENABLED 9 #define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10
+#ifndef __ASM__ + typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE { StandardDesign, @@ -62,13 +64,15 @@ BOOLEAN SafeBootMode; ULONG TraceLogging; ULONGLONG Fill0; - ULONGLONG SystemCall[4]; + UCHAR SystemCall[16]; union { volatile KSYSTEM_TIME TickCount; volatile ULONG64 TickCountQuad; }; } KUSER_SHARED_DATA, *PKUSER_SHARED_DATA;
+#endif + /* Values for DosDeviceDriveType */ #define DOSDEVICE_DRIVE_UNKNOWN 0 #define DOSDEVICE_DRIVE_CALCULATE 1 @@ -102,5 +106,7 @@ #define SharedUserData ((KUSER_SHARED_DATA * const)USER_SHARED_DATA) #endif
+#define KUSER_SHARED_SYSCALL 0x7FFE0300 +#define KUSER_SHARED_SYSCALL_RET 0x7FFE0304
#endif /* __INCLUDE_NAPI_SHARED_DATA_H */ Property changes on: trunk/reactos/lib/gdi32/misc ___________________________________________________________________ Name: svn:ignore - win32k.c *.o .*.d + win32k.S *.o .*.d Property changes on: trunk/reactos/lib/kbdes ___________________________________________________________________ Name: svn:ignore + *.sys *.exe *.dll *.cpl *.a *.o *.d *.coff *.dsp *.dsw *.aps *.ncb *.opt *.sym *.plg *.bak *.map Property changes on: trunk/reactos/lib/ntdll ___________________________________________________________________ Name: svn:ignore - temp.exp napi.asm napi.c *.tmp *.lib *.sym *.coff *.dll *.o *.a *.map doxy-doc + temp.exp napi.asm napi.S *.tmp *.lib *.sym *.coff *.dll *.o *.a *.map doxy-doc Property changes on: trunk/reactos/lib/user32/misc ___________________________________________________________________ Name: svn:ignore - win32k.c *.d *.a *.o *.sym + win32k.S *.d *.a *.o *.sym _____
Modified: trunk/reactos/ntoskrnl/Makefile --- trunk/reactos/ntoskrnl/Makefile 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/ntoskrnl/Makefile 2005-01-17 07:10:34 UTC (rev 13090) @@ -550,7 +550,7 @@
$(PATH_TO_TOP)/include/reactos/bugcodes.h \ $(DEP_OBJECTS) $(DEP_FILES) MSG00409.bin bugcodes.rc
-ex/napi.o: ex/napi.c $(PATH_TO_TOP)/include/ntdll/napi.h +ex/napi.o: ex/zw.S $(PATH_TO_TOP)/include/ntdll/napi.h
ke/main.o: ke/main.c $(PATH_TO_TOP)/include/reactos/buildno.h
Property changes on: trunk/reactos/ntoskrnl/ex ___________________________________________________________________ Name: svn:ignore - *.d *.o *.sym + *.d *.o *.sym zw.S _____
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h --- trunk/reactos/ntoskrnl/include/internal/i386/ke.h 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h 2005-01-17 07:10:34 UTC (rev 13090) @@ -88,6 +88,7 @@
#define X86_FEATURE_TSC 0x00000010 /* time stamp counters are present */ #define X86_FEATURE_PAE 0x00000040 /* physical address extension is present */ #define X86_FEATURE_CX8 0x00000100 /* CMPXCHG8B instruction present */ +#define X86_FEATURE_SYSCALL 0x00000800 /* SYSCALL/SYSRET support present */ #define X86_FEATURE_PGE 0x00002000 /* Page Global Enable */ #define X86_FEATURE_MMX 0x00800000 /* MMX extension present */ #define X86_FEATURE_FXSR 0x01000000 /* FXSAVE/FXRSTOR instructions present */ _____
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ps.h --- trunk/reactos/ntoskrnl/include/internal/i386/ps.h 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/ntoskrnl/include/internal/i386/ps.h 2005-01-17 07:10:34 UTC (rev 13090) @@ -27,6 +27,7 @@
#define KTHREAD_TEB 0x20 #define KTHREAD_KERNEL_STACK 0x28 #define KTHREAD_NPX_STATE 0x31 +#define KTHREAD_PENDING_USER_APC 0x34 + 0x16 #define KTHREAD_APCSTATE_PROCESS 0x44 #define KTHREAD_SERVICE_TABLE 0xDC #define KTHREAD_PREVIOUS_MODE 0x137 _____
Modified: trunk/reactos/ntoskrnl/ke/i386/bthread.S --- trunk/reactos/ntoskrnl/ke/i386/bthread.S 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/ntoskrnl/ke/i386/bthread.S 2005-01-17 07:10:34 UTC (rev 13090) @@ -143,4 +143,4 @@
/* Load the rest of the thread's user mode context. */ movl $0, %eax - jmp KeReturnFromSystemCallWithHook + jmp _KiServiceExit _____
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c --- trunk/reactos/ntoskrnl/ke/i386/exp.c 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/ntoskrnl/ke/i386/exp.c 2005-01-17 07:10:34 UTC (rev 13090) @@ -45,7 +45,7 @@
# define ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0])) #endif
-extern void interrupt_handler2e(void); +extern void KiSystemService(void); extern void interrupt_handler2d(void);
extern VOID KiTrap0(VOID); @@ -850,7 +850,7 @@ }
set_system_call_gate(0x2d,(int)interrupt_handler2d); - set_system_call_gate(0x2e,(int)interrupt_handler2e); + set_system_call_gate(0x2e,(int)KiSystemService); }
/* @@ -873,30 +873,32 @@ return((NTSTATUS)OldEip); }
-VOID -FASTCALL -KeRosTrapReturn ( PKTRAP_FRAME TrapFrame, PKTRAP_FRAME PrevTrapFrame ); - /* * @implemented */ -NTSTATUS STDCALL +NTSTATUS +STDCALL NtRaiseException ( - IN PEXCEPTION_RECORD ExceptionRecord, - IN PCONTEXT Context, - IN BOOLEAN SearchFrames) + IN PEXCEPTION_RECORD ExceptionRecord, + IN PCONTEXT Context, + IN BOOLEAN SearchFrames) { - PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame; - PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx; + PKTHREAD Thread = KeGetCurrentThread(); + PKTRAP_FRAME TrapFrame = Thread->TrapFrame; + PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
- KeGetCurrentKPCR()->Tib.ExceptionList = TrapFrame->ExceptionList; + KeGetCurrentKPCR()->Tib.ExceptionList = TrapFrame->ExceptionList;
- KiDispatchException(ExceptionRecord, - Context, - PsGetCurrentThread()->Tcb.TrapFrame, - (KPROCESSOR_MODE)ExGetPreviousMode(), - SearchFrames); + KiDispatchException(ExceptionRecord, + Context, + TrapFrame, + KeGetPreviousMode(), + SearchFrames);
- KeRosTrapReturn ( TrapFrame, PrevTrapFrame ); - return(STATUS_SUCCESS); + /* Restore the user context */ + Thread->TrapFrame = PrevTrapFrame; + __asm__("mov %%ebx, %%esp;\n" "jmp _KiServiceExit": : "b" (TrapFrame)); + + /* We never get here */ + return(STATUS_SUCCESS); } _____
Modified: trunk/reactos/ntoskrnl/ke/i386/gdt.c --- trunk/reactos/ntoskrnl/ke/i386/gdt.c 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/ntoskrnl/ke/i386/gdt.c 2005-01-17 07:10:34 UTC (rev 13090) @@ -40,10 +40,10 @@
0x0, 0x0, 0x0, 0x0, /* Null */ 0xffff, 0x0, 0x9a00, 0xcf, /* Kernel CS */ 0xffff, 0x0, 0x9200, 0xcf, /* Kernel DS */ - 0x0, 0x0, 0xfa00, 0xcc, /* User CS */ - 0x0, 0x0, 0xf200, 0xcc, /* User DS */ + 0x0, 0x0, 0xfa00, 0xcf, /* User CS */ + 0x0, 0x0, 0xf200, 0xcf, /* User DS */ 0x0, 0x0, 0x0, 0x0, /* TSS */ - 0x1000, 0x0000, 0x9200, 0xff00, /* PCR */ + 0x1000, 0x0000, 0x9200, 0xffc0, /* PCR */ 0x1000, 0x0, 0xf200, 0x0, /* TEB */ 0x0, 0x0, 0x0, 0x0, /* Reserved */ 0x0, 0x0, 0x0, 0x0, /* LDT */ _____
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c --- trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-01-17 07:10:34 UTC (rev 13090) @@ -43,6 +43,7 @@
BOOLEAN Ke386Pae = FALSE; BOOLEAN Ke386PaeEnabled = FALSE; BOOLEAN Ke386GlobalPagesEnabled = FALSE; +ULONG KiFastSystemCallDisable = 0;
/* FUNCTIONS *****************************************************************/
@@ -323,6 +324,18 @@ MiEnablePAE((PVOID*)LastKernelAddress); Ke386PaeEnabled = TRUE; } + + if (KPCR->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) + { + extern void KiFastCallEntry(void); + + /* CS Selector of the target segment. */ + Ke386Wrmsr(0x174, KERNEL_CS, 0); + /* Target ESP. */ + Ke386Wrmsr(0x175, 0, 0); + /* Target EIP. */ + Ke386Wrmsr(0x176, (ULONG_PTR)KiFastCallEntry, 0); + } }
VOID INIT_FUNCTION @@ -391,23 +404,89 @@ VOID INIT_FUNCTION Ki386SetProcessorFeatures(VOID) { - PKPCR Pcr = KeGetCurrentKPCR(); + PKPCR Pcr = KeGetCurrentKPCR(); + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING KeyName; + UNICODE_STRING ValueName; + HANDLE KeyHandle; + ULONG ResultLength; + KEY_VALUE_PARTIAL_INFORMATION ValueData; + NTSTATUS Status;
- SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE; - SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE; - SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = - (Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8); - SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = - (Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX); - SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE; - SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE; - SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = - (Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE); - SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = - (Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW); - SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = - (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC); - SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled; - SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = - (Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2); + SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE; + SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE; + SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = + (Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8); + SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = + (Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX); + SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE; + SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE; + SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = + (Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE); + SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = + (Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW); + SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = + (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC); + SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled; + SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = + (Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2); + + /* Does the CPU Support Fast System Call? */ + if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) { + + /* FIXME: Check for Family == 6, Model < 3 and Stepping < 3 and disable */ + + /* Make sure it's not disabled in registry */ + RtlRosInitUnicodeStringFromLiteral(&KeyName, + L"\Registry\Machine\System\CurrentControlSet\Control\Session Manager\Kernel"); + RtlRosInitUnicodeStringFromLiteral(&ValueName, + L"FastSystemCallDisable"); + InitializeObjectAttributes(&ObjectAttributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes); + + if (NT_SUCCESS(Status)) { + + /* Read the Value then Close the Key */ + Status = NtQueryValueKey(KeyHandle, + &ValueName, + KeyValuePartialInformation, + &ValueData, + sizeof(ValueData), + &ResultLength); + RtlMoveMemory(&KiFastSystemCallDisable, ValueData.Data, sizeof(ULONG)); + + NtClose(KeyHandle); + } + + } else { + + /* Disable SYSENTER/SYSEXIT, because the CPU doesn't support it */ + KiFastSystemCallDisable = 1; + + } + + if (!KiFastSystemCallDisable) { + + /* Use SYSENTER */ + SharedUserData->SystemCall[0] = 0x8B; + SharedUserData->SystemCall[1] = 0xD4; + SharedUserData->SystemCall[2] = 0x0F; + SharedUserData->SystemCall[3] = 0x34; + SharedUserData->SystemCall[4] = 0xC3; + + } else { + + /* Use INT2E */ + SharedUserData->SystemCall[0] = 0x8D; + SharedUserData->SystemCall[1] = 0x54; + SharedUserData->SystemCall[2] = 0x24; + SharedUserData->SystemCall[3] = 0x08; + SharedUserData->SystemCall[4] = 0xCD; + SharedUserData->SystemCall[5] = 0x2E; + SharedUserData->SystemCall[6] = 0xC3; + } } _____
Modified: trunk/reactos/ntoskrnl/ke/i386/stkswitch.S --- trunk/reactos/ntoskrnl/ke/i386/stkswitch.S 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/ntoskrnl/ke/i386/stkswitch.S 2005-01-17 07:10:34 UTC (rev 13090) @@ -78,5 +78,5 @@
push $0 call _KeLowerIrql@4
- jmp KeReturnFromSystemCall + jmp _KiServiceExit
_____
Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S --- trunk/reactos/ntoskrnl/ke/i386/syscall.S 2005-01-17 01:30:26 UTC (rev 13089) +++ trunk/reactos/ntoskrnl/ke/i386/syscall.S 2005-01-17 07:10:34 UTC (rev 13090) @@ -1,324 +1,317 @@
-/* - * ReactOS kernel - * Copyright (C) 2000 David Welch welch@cwcom.net - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ /* $Id$ * * FILE: ntoskrnl/ke/i386/syscall.S - * PURPOSE: 2E trap handler - * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk) + * COPYRIGHT: See COPYING in the top level directory + * PURPOSE: System Call Handler + * PROGRAMMER: Alex Ionescu (alex@relsoft.net) * UPDATE HISTORY: - * ??? + * ??-??-??: Original Version - David Welch(?) + * 13-01-05: Complete rewrite, added support for SYSENTER, direct kmode syscalls + * and re-wrote most of handler code. - Alex Ionescu */
#include <ddk/status.h> #include <internal/i386/segment.h> #include <internal/ps.h> #include <internal/i386/ke.h> +#include <ntos/tss.h> +#include <napi/shared_data.h> #include <roscfg.h>
-#define KernelMode (0) -#define UserMode (1) +#define UserMode (1)
-/* - * - */ -.globl KeReturnFromSystemCall .globl KeReturnFromSystemCallWithHook -.globl _interrupt_handler2e -_interrupt_handler2e: +.globl _KiServiceExit +.globl _KiFastCallEntry +.globl _KiSystemService
- /* Construct a trap frame on the stack */ +_KiFastCallEntry:
- /* Error code */ - pushl $0 - pushl %ebp - pushl %ebx - pushl %esi - pushl %edi - pushl %fs - /* Load PCR selector into fs */ - movl $PCR_SELECTOR, %ebx - movl %ebx, %fs + /* Set FS to PCR */ + movl $PCR_SELECTOR, %ecx + movw %cx, %fs + + /* Set the current stack to Kernel Stack */ + movl %fs:KPCR_TSS, %ecx + movl KTSS_ESP0(%ecx), %ecx + movl %ecx, %esp + + /* Set up a fake INT Stack. */ + pushl $USER_DS + pushl %edx /* Ring 3 SS:ESP */ + pushfl + orl $200, (%esp) /* Re-enable IRQs in EFLAGS, to fake INT */ + pushl $USER_CS + pushl $KUSER_SHARED_SYSCALL_RET + + /* User Parameter List */ + add $8, %edx + +_KiSystemService:
- /* Save the old exception list */ - movl %fs:KPCR_EXCEPTION_LIST, %ebx - pushl %ebx - /* Set the exception handler chain terminator */ - movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST - /* Get a pointer to the current thread */ - movl %fs:KPCR_CURRENT_THREAD, %esi - /* Save the old previous mode */ - movl $0, %ebx - movb %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl - pushl %ebx - /* Set the new previous mode based on the saved CS selector */ - movl 0x24(%esp), %ebx - andl $0x0000FFFF, %ebx - cmpl $KERNEL_CS, %ebx - jne L1 - movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi) - jmp L3 -L1: - movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi) -L3: + /* + * Construct a trap frame on the stack. + * The following are already on the stack. + */ + // SS + 0x0 + // ESP + 0x4 + // EFLAGS + 0x8 + // CS + 0xC + // EIP + 0x10 + pushl $0 // + 0x14 + pushl %ebp // + 0x18 + pushl %ebx // + 0x1C + pushl %esi // + 0x20 + pushl %edi // + 0x24 + pushl %fs // + 0x28 + + /* Load PCR Selector into fs */ + movw $PCR_SELECTOR, %bx + movw %bx, %fs + + /* Save the previous exception list */ + pushl %fs:KPCR_EXCEPTION_LIST // + 0x2C
- /* Save other registers */ - pushl %eax - pushl %ecx - pushl %edx - pushl %ds - pushl %es - pushl %gs - pushl $0 /* DR7 */ - pushl $0 /* DR6 */ - pushl $0 /* DR3 */ - pushl $0 /* DR2 */ - pushl $0 /* DR1 */ - pushl $0 /* DR0 */ - pushl $0 /* XXX: TempESP */ - pushl $0 /* XXX: TempCS */ - pushl $0 /* XXX: DebugPointer */ - pushl $0 /* XXX: DebugArgMark */ + /* Set the exception handler chain terminator */ + movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
-#ifdef DBG - /* Trick gdb 6 into backtracing over the system call */ - movl 4(%ebp), %ebx - pushl %ebx /* DebugEIP */ - movl (%ebp), %ebx - pushl %ebx /* DebugEBP */ -#else - movl 0x60(%esp), %ebx - pushl %ebx /* DebugEIP */ - pushl %ebp /* DebugEBP */ -#endif + /* Get a pointer to the current thread */ + movl %fs:KPCR_CURRENT_THREAD, %esi
- /* Load the segment registers */ - movl $KERNEL_DS, %ebx - movl %ebx, %ds - movl %ebx, %es - movl %ebx, %gs + /* Save the old previous mode */ + pushl %ss:KTHREAD_PREVIOUS_MODE(%esi) // + 0x30 + + /* Set the new previous mode based on the saved CS selector */ + movl 0x24(%esp), %ebx + and $1, %ebx + movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
- /* - * Save the old trap frame pointer over where we would save the EDX - * register. - */ - movl KTHREAD_TRAP_FRAME(%esi), %ebx - movl %ebx, KTRAP_FRAME_EDX(%esp) + /* Save other registers */ + pushl %eax // + 0x34 + pushl %ecx // + 0x38 + pushl %edx // + 0x3C + pushl %ds // + 0x40 + pushl %es // + 0x44 + pushl %gs // + 0x48 + sub $0x28, %esp // + 0x70
- /* Allocate new Kernel stack frame */ - movl %esp,%ebp - - /* Save a pointer to the trap frame in the TCB */ - movl %ebp, KTHREAD_TRAP_FRAME(%esi) - - /* Set ES to kernel segment */ - movw $KERNEL_DS,%bx - movw %bx,%es - - /* Users's current stack frame pointer is source */ - movl %edx,%esi - - /* Determine system service table to use */ - cmpl $0x0fff, %eax - ja new_useShadowTable - - /* Check to see if EAX is valid/inrange */ - cmpl %es:_KeServiceDescriptorTable + 8, %eax - jbe new_serviceInRange - movl $STATUS_INVALID_SYSTEM_SERVICE, %eax - movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */ - jmp KeReturnFromSystemCall - -new_serviceInRange: - #ifdef DBG - /* GDB thinks the function starts here and - wants a standard prolog, so let's give it */ - pushl %ebp - movl %esp,%ebp - popl %ebp + /* Trick gdb 6 into backtracing over the system call */ + pushl 4(%ebp) /* DebugEIP */ // + 0x74 + pushl (%ebp) /* DebugEBP */ // + 0x78 +#else + pushl 0x60(%esp) /* DebugEIP */ // + 0x74 + pushl %ebp /* DebugEBP */ // + 0x78 #endif
- /* Allocate room for argument list from kernel stack */ - movl %es:_KeServiceDescriptorTable + 12, %ecx - movb %es:(%ecx, %eax), %cl - movzx %cl, %ecx - subl %ecx, %esp + /* Load the segment registers */ + movw $KERNEL_DS, %bx + movw %bx, %ds + movw %bx, %es + movw %bx, %gs
- /* Copy the arguments from the user stack to the kernel stack */ - movl %esp,%edi - cld - rep movsb + /* Save the old trap frame pointer where EDX would be saved */ + movl KTHREAD_TRAP_FRAME(%esi), %ebx + movl %ebx, KTRAP_FRAME_EDX(%esp)
- /* DS is now also kernel segment */ - movw %bx, %ds + /* Allocate new Kernel stack frame */ + movl %esp,%ebp
- /* Call system call hook */ - pushl %eax - call _KiSystemCallHook - popl %eax + /* Save a pointer to the trap frame in the TCB */ + movl %ebp, KTHREAD_TRAP_FRAME(%esi)
- /* Make the system service call */ - movl %es:_KeServiceDescriptorTable, %ecx - movl %es:(%ecx, %eax, 4), %eax - call *%eax - movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */ +CheckValidCall:
-#if CHECKED - /* Bump Service Counter */ -#endif - - jmp KeDeallocateStackAndReturnFromSystemCallWithHook - -new_useShadowTable: - - subl $0x1000, %eax - - /* Check to see if EAX is valid/inrange */ - cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax - jbe new_shadowServiceInRange - movl $STATUS_INVALID_SYSTEM_SERVICE, %eax - movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */ - jmp KeReturnFromSystemCall - -new_shadowServiceInRange: - + /* + * Find out which table offset to use. Converts 0x1124 into 0x10. + * The offset is related to the Table Index as such: Offset = TableIndex x 10 + */ + movl %eax, %edi + shrl $8, %edi + andl $0x10, %edi + movl %edi, %ecx + + /* Now add the thread's base system table to the offset */ + addl KTHREAD_SERVICE_TABLE(%esi), %edi + + /* Get the true syscall ID and check it */ + movl %eax, %ebx + andl $0x0FFF, %eax + cmpl 8(%edi), %eax + + /* Invalid ID, try to load Win32K Table */ + jnb KiBBTUnexpectedRange + #ifdef DBG - /* - * GDB thinks the function starts here and - * wants a standard prolog, so let's give it - */ - pushl %ebp - movl %esp,%ebp - popl %ebp + /* + * GDB thinks the function starts here and + * wants a standard prolog, so let's give it + */ + pushl %ebp + movl %esp,%ebp + popl %ebp #endif
- /* Allocate room for argument list from kernel stack */ - movl %es:_KeServiceDescriptorTableShadow + 28, %ecx - movb %es:(%ecx, %eax), %cl - movzx %cl, %ecx - subl %ecx, %esp + /* Users's current stack frame pointer is source */ + movl %edx, %esi + + /* Allocate room for argument list from kernel stack */ + movl 12(%edi), %ecx + movb (%ecx, %eax), %cl + movzx %cl, %ecx + + /* Allocate space on our stack */ + subl %ecx, %esp + + /* Get pointer to function */ + movl (%edi), %edi + movl (%edi, %eax, 4), %eax
- /* Copy the arguments from the user stack to the kernel stack */ - movl %esp,%edi - cld - rep movsb + /* Copy the arguments from the user stack to our stack */ + shr $2, %ecx + movl %esp, %edi + cld + rep movsd
- /* DS is now also kernel segment */ - movw %bx,%ds + /* Do the System Call */ + call *%eax + movl %eax, KTRAP_FRAME_EAX(%ebp)
- /* Call system call hook */ -// pushl %eax -// call _KiSystemCallHook -// popl %eax + /* Deallocate the kernel stack frame */ + movl %ebp, %esp
- /* Call service check routine */ - pushl %eax - call _KiServiceCheck - popl %eax - - /* Make the system service call */ - movl %es:_KeServiceDescriptorTableShadow + 16, %ecx - movl %es:(%ecx, %eax, 4), %eax - call *%eax - movl %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */ - -#if CHECKED - /* Bump Service Counter */ -#endif - -KeDeallocateStackAndReturnFromSystemCallWithHook: - /* Deallocate the kernel stack frame */ - movl %ebp,%esp - -KeReturnFromSystemCallWithHook: - /* Call the post system call hook and deliver any pending APCs */ - pushl %esp - call _KiAfterSystemCallHook - addl $4,%esp - KeReturnFromSystemCall:
- /* Restore the user context */ - /* Get a pointer to the current thread */ - movl %fs:0x124, %esi + /* Get the Current Thread */ + movl %fs:KPCR_CURRENT_THREAD, %esi
- /* Restore the old trap frame pointer */ - movl KTRAP_FRAME_EDX(%esp), %ebx - movl %ebx, KTHREAD_TRAP_FRAME(%esi) + /* Restore the old trap frame pointer */ + movl KTRAP_FRAME_EDX(%esp), %ebx + movl %ebx, KTHREAD_TRAP_FRAME(%esi)
+_KiServiceExit: + + /* Get the Current Thread */ + movl %fs:KPCR_CURRENT_THREAD, %esi + + /* Deliver APCs only if we were called from user mode */ + testb $1, KTRAP_FRAME_CS(%esp) + je KiRosTrapReturn + + /* And only if any are actually pending */ + cmpb $0, KTHREAD_PENDING_USER_APC(%esi) + je KiRosTrapReturn + + /* Save pointer to Trap Frame */ + movl %esp, %ebx + + /* Raise IRQL to HIGH_LEVEL */ + movl $1, %ecx + call @KfRaiseIrql@4 + + /* Save old IRQL */ + pushl %eax + + /* Deliver APCs */ + pushl %ebx + pushl $0 + pushl $UserMode + call _KiDeliverApc@12 + + /* Return to old IRQL */ + popl %ecx + call @KfLowerIrql@4 + KiRosTrapReturn: + + /* Skip debug information and unsaved registers */ + addl $0x30, %esp // + 0x48 + popl %gs // + 0x44 + popl %es // + 0x40 + popl %ds // + 0x3C + popl %edx // + 0x38 + popl %ecx // + 0x34 + popl %eax // + 0x30
-#if 0 - mov KTRAP_FRAME_RESERVED1(%ebp), %ax - cmp %ax, SSIDX_NTCONTINUE - jnz KeNoEpilogPrint - movl KTRAP_FRAME_ESP(%ebp), %ecx - movl KTRAP_FRAME_EBP(%ebp), %edx - call @KeRosPrintEspEbp@8 -KeNoEpilogPrint: -#endif + /* Restore the old previous mode */ + popl %ebx // + 0x2C + movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
- /* Skip debug information and unsaved registers */ - addl $0x30, %esp - popl %gs - popl %es - popl %ds - popl %edx - popl %ecx - popl %eax + /* Restore the old exception handler list */ + popl %fs:KPCR_EXCEPTION_LIST // + 0x28
- /* Restore the old previous mode */ - popl %ebx - movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi) + /* Restore final registers from trap frame */ + popl %fs // + 0x24 + popl %edi // + 0x20 + popl %esi // + 0x1C + popl %ebx // + 0x18 + popl %ebp // + 0x14 + add $4, %esp // + 0x10
- /* Restore the old exception handler list */ - popl %ebx - movl %ebx, %fs:KPCR_EXCEPTION_LIST + /* Check if previous CS is from user-mode */ + testl $1, 4(%esp) + + /* It is, so use Fast Exit */ + jnz FastRet + + /* + * Restore what the stub pushed, and return back to it. + * Note that we were CALLed, so the first thing on our stack is the ret EIP! + */ + pop %edx // + 0x0C + pop %ecx // + 0x08 + popf // + 0x04 + jmp *%edx + +IntRet: + + iret [truncated at 1000 lines; 1911 more skipped]