diff --git a/reactos/dll/ntdll/def/ntdll.def b/reactos/dll/ntdll/def/ntdll.def index b06e82606ab..bbb4dbd703c 100644 --- a/reactos/dll/ntdll/def/ntdll.def +++ b/reactos/dll/ntdll/def/ntdll.def @@ -37,6 +37,9 @@ KiRaiseUserExceptionDispatcher@0 KiUserApcDispatcher@16 KiUserCallbackDispatcher@12 KiUserExceptionDispatcher@8 +KiIntSystemCall@0 +KeFastSystemCallRet@0 ; big hack since LdrGetProcedureAddress is broken +KiFastSystemCall@0 LdrAccessResource@16 LdrAddRefDll@8 LdrDisableThreadCalloutsForDll@4 diff --git a/reactos/dll/ntdll/main/i386/dispatch.S b/reactos/dll/ntdll/main/i386/dispatch.S index 33237242df1..552ee7d0a4b 100644 --- a/reactos/dll/ntdll/main/i386/dispatch.S +++ b/reactos/dll/ntdll/main/i386/dispatch.S @@ -236,6 +236,35 @@ Exit: ret 8 .endfunc +.func KiIntSystemCall@0 +.globl _KiIntSystemCall@0 +_KiIntSystemCall@0: + + /* Set stack in EDX and do the interrupt */ + lea edx, [esp+8] + int 0x2E + + /* Return to caller */ + ret +.endfunc + +.func KiFastSystemCall@0 +.globl _KiFastSystemCall@0 +_KiFastSystemCall@0: + + /* Put ESP in EDX and do the SYSENTER */ + mov edx, esp + sysenter +.endfunc + +.func KeFastSystemCallRet@0 +.globl _KeFastSystemCallRet@0 +_KeFastSystemCallRet@0: + + /* Just return to caller */ + ret +.endfunc + .func RtlpGetStackLimits@8 .globl _RtlpGetStackLimits@8 _RtlpGetStackLimits@8: diff --git a/reactos/ntoskrnl/KrnlFun.c b/reactos/ntoskrnl/KrnlFun.c index b0e9f4546a1..932c2d090ad 100644 --- a/reactos/ntoskrnl/KrnlFun.c +++ b/reactos/ntoskrnl/KrnlFun.c @@ -27,8 +27,10 @@ // Ke: // // - FIXES: -// * Get rid of KiRosPrintAddress and use KiDumpParameterImages instead. +// * Stop using CachedModules. +// * Try to make MmInit1 NTLDR compatible. // * Sanitize some context fields during conversions. +// * Figure out why the DPC stack doesn't really work. // * Add DR macro/save and VM macro/save. // - FEATURES: // * New optimized table-based tick-hashed timer implementation. diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index beb7392b542..07b4d779be9 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -67,18 +67,9 @@ InitSystemSharedUserPage (IN PLOADER_PARAMETER_BLOCK LoaderBlock) ULONG i; BOOLEAN BootDriveFound = FALSE; - /* - * NOTE: - * The shared user page has been zeroed-out right after creation. - * There is NO need to do this again. - */ - Ki386SetProcessorFeatures(); - - /* Set the Version Data */ + /* Set the Product Type */ SharedUserData->NtProductType = NtProductWinNt; SharedUserData->ProductTypeIsValid = TRUE; - SharedUserData->NtMajorVersion = 5; - SharedUserData->NtMinorVersion = 0; /* * Retrieve the current dos system path diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index 23366d4f632..8996231d1ae 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -649,97 +649,6 @@ Ki386InitializeTss(IN PKTSS Tss, TssEntry->LimitLow = KTSS_IO_MAPS; } -VOID -INIT_FUNCTION -Ki386SetProcessorFeatures(VOID) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING KeyName = - RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Kernel"); - UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"FastSystemCallDisable"); - HANDLE KeyHandle; - ULONG ResultLength; - struct - { - KEY_VALUE_PARTIAL_INFORMATION Info; - UCHAR Buffer[20]; - } ValueData; - NTSTATUS Status; - ULONG FastSystemCallDisable = 0; - - SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE; - SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE; - SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = - (KeFeatureBits & KF_CMPXCHG8B) ? TRUE : FALSE; - SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = - (KeFeatureBits & KF_MMX) ? TRUE : FALSE; - SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE; - SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE; - SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = - (KeFeatureBits & KF_XMMI) ? TRUE : FALSE; - SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = - (KeFeatureBits & KF_RDTSC) ? TRUE : FALSE; - - /* Does the CPU Support Fast System Call? */ - if (KeFeatureBits & KF_FAST_SYSCALL) { - - /* FIXME: Check for Family == 6, Model < 3 and Stepping < 3 and disable */ - - /* Make sure it's not disabled in registry */ - InitializeObjectAttributes(&ObjectAttributes, - &KeyName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - Status = ZwOpenKey(&KeyHandle, - KEY_QUERY_VALUE, - &ObjectAttributes); - - if (NT_SUCCESS(Status)) { - - /* Read the Value then Close the Key */ - Status = ZwQueryValueKey(KeyHandle, - &ValueName, - KeyValuePartialInformation, - &ValueData, - sizeof(ValueData), - &ResultLength); - if (NT_SUCCESS(Status)) - { - if (ResultLength == sizeof(ValueData) && - ValueData.Info.Type == REG_DWORD) - { - FastSystemCallDisable = *(PULONG)ValueData.Info.Data != 0; - } - - ZwClose(KeyHandle); - } - } - - } else { - - /* Disable SYSENTER/SYSEXIT, because the CPU doesn't support it */ - FastSystemCallDisable = 1; - - } - - if (FastSystemCallDisable) { - /* Use INT2E */ - const unsigned char Entry[7] = {0x8D, 0x54, 0x24, 0x08, /* lea 0x8(%esp),%edx */ - 0xCD, 0x2E, /* int 0x2e */ - 0xC3}; /* ret */ - memcpy(&SharedUserData->SystemCall, Entry, sizeof(Entry)); - } else { - /* Use SYSENTER */ - const unsigned char Entry[5] = {0x8B, 0xD4, /* movl %esp,%edx */ - 0x0F, 0x34, /* sysenter */ - 0xC3}; /* ret */ - memcpy(&SharedUserData->SystemCall, Entry, sizeof(Entry)); - /* Enable SYSENTER/SYSEXIT */ - KiFastSystemCallDisable = 0; - } -} - VOID NTAPI KeFlushCurrentTb(VOID) diff --git a/reactos/ntoskrnl/ke/i386/kiinit.c b/reactos/ntoskrnl/ke/i386/kiinit.c index 9630bf5666d..74d21b6500d 100644 --- a/reactos/ntoskrnl/ke/i386/kiinit.c +++ b/reactos/ntoskrnl/ke/i386/kiinit.c @@ -421,6 +421,20 @@ KiInitializeKernel(IN PKPROCESS InitProcess, /* Set the NX Support policy */ SharedUserData->NXSupportPolicy = NXSupportPolicy; + /* Set basic CPU Features that user mode can read */ + SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_MMX); + SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] = + (KeFeatureBits & KF_CMPXCHG8B); + SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = + ((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI)); + SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = + ((KeFeatureBits & KF_FXSR) && (KeFeatureBits & KF_XMMI64)); + SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] = + (KeFeatureBits & KF_3DNOW); + SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] = + (KeFeatureBits & KF_RDTSC); + /* Setup the Idle Thread */ KeInitializeThread(InitProcess, InitThread, diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 85bfd88817d..501b7074bb7 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -134,7 +134,7 @@ _KiFastCallEntry: popf /* Set our EFLAGS */ or dword ptr [esp], EFLAGS_INTERRUPT_MASK /* Re-enable IRQs in EFLAGS, to fake INT */ push KGDT_R3_CODE + RPL_MASK - push KUSER_SHARED_SYSCALL_RET + push dword ptr ds:KUSER_SHARED_SYSCALL_RET /* Setup the Trap Frame stack */ push 0 diff --git a/reactos/ntoskrnl/ldr/rtl.c b/reactos/ntoskrnl/ldr/rtl.c index 02e9e5a4369..0212889ff8c 100644 --- a/reactos/ntoskrnl/ldr/rtl.c +++ b/reactos/ntoskrnl/ldr/rtl.c @@ -55,6 +55,12 @@ LdrGetProcedureAddress (IN PVOID BaseAddress, * -- Filip Navara, August 1st, 2005 */ + /* + * I don't know who wrote this code but it's not working. + * Test case: KiFastSystemCall and KiFastSystemCallRet in ntdll. + * Former can't be found even though it's exported. + */ + OrdinalPtr = (PUSHORT)RVA(BaseAddress, ExportDir->AddressOfNameOrdinals); NamePtr = (PULONG)RVA(BaseAddress, ExportDir->AddressOfNames); diff --git a/reactos/ntoskrnl/ps/psmgr.c b/reactos/ntoskrnl/ps/psmgr.c index a02e4398ad4..7ec0e4f5a6f 100644 --- a/reactos/ntoskrnl/ps/psmgr.c +++ b/reactos/ntoskrnl/ps/psmgr.c @@ -41,6 +41,9 @@ ANSI_STRING ApcName = RTL_CONSTANT_STRING("KiUserApcDispatcher"); ANSI_STRING ExceptName = RTL_CONSTANT_STRING("KiUserExceptionDispatcher"); ANSI_STRING CallbackName = RTL_CONSTANT_STRING("KiUserCallbackDispatcher"); ANSI_STRING RaiseName = RTL_CONSTANT_STRING("KiRaiseUserExceptionDispatcher"); +ANSI_STRING FastName = RTL_CONSTANT_STRING("KiFastSystemCall"); +ANSI_STRING FastReturnName = RTL_CONSTANT_STRING("KeFastSystemCallRet"); +ANSI_STRING InterruptName = RTL_CONSTANT_STRING("KiIntSystemCall"); PHANDLE_TABLE PspCidTable; @@ -97,6 +100,34 @@ PspLookupKernelUserEntryPoints(VOID) /* Get user-mode exception raise trampoline */ Status = PspLookupSystemDllEntryPoint(&RaiseName, &KeRaiseUserExceptionDispatcher); + if (!NT_SUCCESS(Status)) return Status; + + /* Check if this is a machine that supports SYSENTER */ + if (KeFeatureBits & KF_FAST_SYSCALL) + { + /* Get user-mode sysenter stub */ + Status = PspLookupSystemDllEntryPoint(&FastName, + (PVOID)&SharedUserData-> + SystemCall); + if (!NT_SUCCESS(Status)) return Status; + + /* Get user-mode sysenter return stub */ + Status = PspLookupSystemDllEntryPoint(&FastReturnName, + (PVOID)&SharedUserData-> + SystemCallReturn); + } + else + { + /* Get the user-mode interrupt stub */ + Status = PspLookupSystemDllEntryPoint(&InterruptName, + (PVOID)&SharedUserData-> + SystemCall); + } + + /* Set the test instruction */ + if (!NT_SUCCESS(Status)) SharedUserData->TestRetInstruction = 0xC3; + + /* Return the status */ return Status; } diff --git a/reactos/tools/nci/ncitool.c b/reactos/tools/nci/ncitool.c index bdfdab8f362..6083b90b410 100644 --- a/reactos/tools/nci/ncitool.c +++ b/reactos/tools/nci/ncitool.c @@ -51,7 +51,7 @@ #if defined(__GNUC__) #define UserModeStub_x86 " movl $0x%x, %%eax\n" \ " movl $KUSER_SHARED_SYSCALL, %%ecx\n" \ - " call *%%ecx\n" \ + " call *(%%ecx)\n" \ " ret $0x%x\n\n" #elif defined(_MSC_VER) #define UserModeStub_x86 " asm { \n" \