[NTDLL]: Apply the special begin/fault/resume lablels to the user-mode SList functions. Access faults can happen there due to a bug in the Windows algorithm, and Mm will need to handle that.
[NTOS]: Lookup the special labels from above when initializing the System DLL. Only lookup INT2E vs SYSENTER on x86, other architectures don't need a stub.
[NTOS]: Bitmap resources start at index 1, not 0. Also make sure we don't go past the maximum IDB_ resource index for no reason, and check the size of the resource instead of assuming it's going to be one page.
[NMIDEBUG]: Fix and cleanup some code, and enable NMI support on the boot/install CD as well.
svn path=/trunk/; revision=48860
[SourceDisksFiles]
acpi.sys=,,,,,,,,,,,,4
+nmidebug.sys=,,,,,,x,,,,,,4
uniata.sys=,,,,,,x,,,,,,4
buslogic.sys=,,,,,,x,,,,,,4
blue.sys=,,,,,,x,,,,,,4
@ stdcall -arch=i386 KiFastSystemCall()
@ stdcall -arch=i386 KiFastSystemCallRet()
@ stdcall -arch=i386 KiIntSystemCall()
+@ stdcall -arch=i386 ExpInterlockedPopEntrySListEnd()
+@ stdcall -arch=i386 ExpInterlockedPopEntrySListFault()
+@ stdcall -arch=i386 ExpInterlockedPopEntrySListResume()
@ stdcall KiRaiseUserExceptionDispatcher()
@ stdcall KiUserApcDispatcher(ptr ptr ptr ptr)
@ stdcall KiUserCallbackDispatcher(ptr ptr long) // CHECKME
/* FUNCTIONS ******************************************************************/
-PCHAR NmiBegin = "NMI2NMI1";
+PCHAR NmiBegin = "NMI4NMI@";
+
+VOID
+FORCEINLINE
+NmiClearFlag(VOID)
+{
+ ((PCHAR)&KiBugCheckData[4])[0] -= (NmiBegin[3] | NmiBegin[7]);
+ ((PCHAR)&KiBugCheckData[4])[3] |= 1;
+ __asm__("rcrl %b[shift], %k[retval]" : [retval] "=rm" (KiBugCheckData[4]) : "[retval]" (KiBugCheckData[4]), [shift] "Nc" (8));
+}
BOOLEAN
NTAPI
IN BOOLEAN Handled)
{
/* Clear the NMI flag */
- ((PCHAR)&KiBugCheckData[4])[3] -= NmiBegin[3];
+ NmiClearFlag();
/* Get NMI status signature */
__indwordstring(0x80, (PULONG)NmiBegin, 1);
((void(*)())&KiBugCheckData[4])();
/* Handle the NMI safely */
- KiEnableTimerWatchdog = strcmp(NmiBegin, NmiBegin + 4);
+ KiEnableTimerWatchdog = (RtlCompareMemory(NmiBegin, NmiBegin + 4, 4) != 4);
return TRUE;
}
-
+
NTSTATUS
NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
<module name="nmidebug" type="kernelmodedriver" installbase="system32/drivers" installname="nmidebug.sys">
+ <bootstrap installbase="$(CDOUTPUT)" />
<include base="null">.</include>
<library>ntoskrnl</library>
<library>hal</library>
* RtlInterlockedPopEntrySList(
* IN PSLIST_HEADER ListHead);
*/
+.global _ExpInterlockedPopEntrySListResume@0
+.global _ExpInterlockedPopEntrySListEnd@0
+.global _ExpInterlockedPopEntrySListFault@0
.global _RtlInterlockedPopEntrySList@4
_RtlInterlockedPopEntrySList@4:
/* Load ListHead into ebp */
mov ebp, [esp + 12]
-
+_ExpInterlockedPopEntrySListResume@0:
/* Load ListHead->Next into eax */
mov eax, [ebp]
/* Copy Depth and Sequence number and adjust Depth */
lea ecx, [edx - 1]
+_ExpInterlockedPopEntrySListFault@0:
/* Get next pointer */
mov ebx, [eax]
-
+_ExpInterlockedPopEntrySListEnd@0:
/* If [ebp] equals edx:eax, exchange it with ecx:ebx */
- lock cmpxchg8b [ebp]
+ LOCK cmpxchg8b qword ptr [ebp]
/* If not equal, retry with edx:eax, being the content of [ebp] now */
- jnz 1b
+ jnz _ExpInterlockedPopEntrySListResume@0
/* Restore registers and return */
2:
lea ecx, [edx + 0x10001]
/* If [ebp] equals edx:eax, exchange it with ecx:ebx */
- lock cmpxchg8b [ebp]
+ LOCK cmpxchg8b qword ptr [ebp]
/* If not equal, retry with edx:eax, being the content of [ebp] now */
jnz 1b
xor cx, cx
/* If [ebp] equals edx:eax, exchange it with ecx:ebx */
- lock cmpxchg8b [ebp]
+ LOCK cmpxchg8b qword ptr [ebp]
/* If not equal, retry with edx:eax, being the content of [ebp] now */
jnz 1b
if (NT_SUCCESS(Status))
{
/* Access the resource */
+ ULONG Size = 0;
Status = LdrAccessResource(LdrEntry->DllBase,
ResourceDataEntry,
&Data,
- NULL);
- if (Data) KiBugCheckData[4] ^= RtlComputeCrc32(0, Data, PAGE_SIZE);
+ &Size);
+ if ((Data) && (ResourceId < 3))
+ {
+ KiBugCheckData[4] ^= RtlComputeCrc32(0, Data, Size);
+ }
if (!NT_SUCCESS(Status)) Data = NULL;
}
}
VidResetDisplay(CustomLogo);
/* Find bitmap resources in the kernel */
- ResourceCount = Count;
- for (i = 0; i < Count; i++)
+ ResourceCount = min(IDB_CLUSTER_SERVER, Count);
+ for (i = 1; i <= Count; i++)
{
/* Do the lookup */
ResourceList[i] = FindBitmapResource(LoaderBlock, i);
extern ULONG ExpInitializationPhase;
extern BOOLEAN SysThreadCreated;
+PVOID KeUserPopEntrySListEnd;
+PVOID KeUserPopEntrySListFault;
+PVOID KeUserPopEntrySListResume;
+
GENERIC_MAPPING PspProcessMapping =
{
STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
&KeRaiseUserExceptionDispatcher);
if (!NT_SUCCESS(Status)) return Status;
+ /* Get user-mode SLIST exception functions for page fault rollback race hack */
+ Status = PspLookupSystemDllEntryPoint("ExpInterlockedPopEntrySListEnd",
+ &KeUserPopEntrySListEnd);
+ if (!NT_SUCCESS(Status)) { DPRINT1("this not found\n"); return Status; }
+ Status = PspLookupSystemDllEntryPoint("ExpInterlockedPopEntrySListFault",
+ &KeUserPopEntrySListFault);
+ if (!NT_SUCCESS(Status)) { DPRINT1("this not found\n"); return Status; }
+ Status = PspLookupSystemDllEntryPoint("ExpInterlockedPopEntrySListResume",
+ &KeUserPopEntrySListResume);
+ if (!NT_SUCCESS(Status)) { DPRINT1("this not found\n"); return Status; }
+
+ /* On x86, there are multiple ways to do a system call, find the right stubs */
+#if defined(_X86_)
/* Check if this is a machine that supports SYSENTER */
if (KeFeatureBits & KF_FAST_SYSCALL)
{
/* Get user-mode sysenter stub */
+ SharedUserdata->SystemCall = (PsNtosImageBase >> (PAGE_SHIFT + 1));
Status = PspLookupSystemDllEntryPoint("KiFastSystemCall",
(PVOID)&SharedUserData->
SystemCall);
/* Set the test instruction */
SharedUserData->TestRetInstruction = 0xC3;
+#endif
/* Return the status */
return Status;