- Implement XPSP2+ syscall stub that uses indirect pointer instead of executable code inside KUSER_SHARED_DATA.

- Someone (FILIP!) please fix LdrGetProcedureAddress. It's broken and I had to rename an ntdll export to make it work (see comments).
- Make sure you REBUILD CLEAN. This commit changes NCITool!!!
- Setup some NPX-related CPU features in SharedUserData during KiInitializeKernel.
- Remove some now-deprecated initialization functions.

svn path=/trunk/; revision=24395
This commit is contained in:
Alex Ionescu 2006-10-04 16:00:36 +00:00
parent 48236aa642
commit d0cb64ce3d
10 changed files with 89 additions and 104 deletions

View file

@ -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

View file

@ -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:

View file

@ -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.

View file

@ -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

View file

@ -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)

View file

@ -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,

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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" \