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(a)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(a)seh.ox.ac.uk)
+ * COPYRIGHT: See COPYING in the top level directory
+ * PURPOSE: System Call Handler
+ * PROGRAMMER: Alex Ionescu (alex(a)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]