Author: ion
Date: Thu Jan 25 08:14:55 2007
New Revision: 25626
URL:
http://svn.reactos.org/svn/reactos?rev=25626&view=rev
Log:
- Implement KeUpdateSystemTime properly, it now saves and returns the old time, supports
HAL time, as well as loops the timer list to fixup relative timers and expired timers
after the time has changed.
- Replace mm failure detection code by dprint + while loop to avoid bugchecks which might
make the error worse to see.
- Remove some deprecated code/functions and cleanup clock.c entirely.
Modified:
trunk/reactos/ntoskrnl/ex/init.c
trunk/reactos/ntoskrnl/ex/time.c
trunk/reactos/ntoskrnl/include/internal/ke.h
trunk/reactos/ntoskrnl/ke/clock.c
trunk/reactos/ntoskrnl/ke/dpc.c
trunk/reactos/ntoskrnl/mm/pagefile.c
trunk/reactos/ntoskrnl/mm/pageop.c
trunk/reactos/ntoskrnl/mm/rmap.c
Modified: trunk/reactos/ntoskrnl/ex/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/init.c?rev=256…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/init.c (original)
+++ trunk/reactos/ntoskrnl/ex/init.c Thu Jan 25 08:14:55 2007
@@ -14,9 +14,6 @@
#include <internal/debug.h>
/* DATA **********************************************************************/
-
-/* HACK */
-extern BOOLEAN KiClockSetupComplete;
#define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor &
0xFF))
@@ -1127,9 +1124,6 @@
KeBootTimeBias = 0;
}
- /* The clock is ready now (FIXME: HACK FOR OLD HAL) */
- KiClockSetupComplete = TRUE;
-
/* Initialize all processors */
if (!HalAllProcessorsStarted()) KeBugCheck(HAL1_INITIALIZATION_FAILED);
Modified: trunk/reactos/ntoskrnl/ex/time.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/time.c?rev=256…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/time.c (original)
+++ trunk/reactos/ntoskrnl/ex/time.c Thu Jan 25 08:14:55 2007
@@ -82,7 +82,7 @@
NTSTATUS
ExpSetTimeZoneInformation(PTIME_ZONE_INFORMATION TimeZoneInformation)
{
- LARGE_INTEGER LocalTime, SystemTime;
+ LARGE_INTEGER LocalTime, SystemTime, OldTime;
TIME_FIELDS TimeFields;
DPRINT("ExpSetTimeZoneInformation() called\n");
@@ -123,7 +123,7 @@
ExLocalTimeToSystemTime(&LocalTime, &SystemTime);
/* Set the new system time */
- KeSetSystemTime(&SystemTime, NULL, FALSE, NULL);
+ KeSetSystemTime(&SystemTime, &OldTime, FALSE, NULL);
/* Return success */
DPRINT("ExpSetTimeZoneInformation() done\n");
@@ -184,16 +184,13 @@
return STATUS_PRIVILEGE_NOT_HELD;
}
- /* Check if caller wants the old time */
- if(PreviousTime) KeQuerySystemTime(&OldSystemTime);
-
/* Convert the time and set it in HAL */
ExSystemTimeToLocalTime(&NewSystemTime, &LocalTime);
RtlTimeToTimeFields(&LocalTime, &TimeFields);
HalSetRealTimeClock(&TimeFields);
/* Now set system time */
- KeSetSystemTime(&NewSystemTime, NULL, FALSE, NULL);
+ KeSetSystemTime(&NewSystemTime, &OldSystemTime, FALSE, NULL);
/* Check if caller wanted previous time */
if(PreviousTime)
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h Thu Jan 25 08:14:55 2007
@@ -85,7 +85,8 @@
extern PVOID KeUserExceptionDispatcher;
extern PVOID KeRaiseUserExceptionDispatcher;
extern LARGE_INTEGER KeBootTime;
-extern ULONG KeBootTimeBias;
+extern ULONGLONG KeBootTimeBias;
+extern BOOLEAN ExCmosClockIsSane;
extern ULONG KeI386NpxPresent;
extern ULONG KeI386XMMIPresent;
extern ULONG KeI386FxsrPresent;
Modified: trunk/reactos/ntoskrnl/ke/clock.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/clock.c?rev=25…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/clock.c (original)
+++ trunk/reactos/ntoskrnl/ke/clock.c Thu Jan 25 08:14:55 2007
@@ -1,118 +1,182 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/ke/clock.c
- * PURPOSE: Handle System Clock
- *
- * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net) - Created
- * David Welch & Phillip Susi - Implementation (?)
- */
-
- /* NOTES ******************************************************************/
-/*
- * System time units are 100-nanosecond intervals
- */
-
-/* INCLUDES ***************************************************************/
+ * PURPOSE: System Clock Support
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
-
#define NDEBUG
-#include <internal/debug.h>
-
-#if defined (ALLOC_PRAGMA)
-#pragma alloc_text(INIT, KiInitializeSystemClock)
-#endif
-
-/* GLOBALS ****************************************************************/
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
LARGE_INTEGER KeBootTime;
-ULONG KeBootTimeBias;
-KDPC KiTimerExpireDpc;
-BOOLEAN KiClockSetupComplete = FALSE;
-ULONG KiTimeLimitIsrMicroseconds;
-
-/*
- * Number of timer interrupts since initialisation
- */
+ULONGLONG KeBootTimeBias;
volatile KSYSTEM_TIME KeTickCount = {0};
volatile ULONG KiRawTicks = 0;
+ULONG KeMaximumIncrement;
+ULONG KeMinimumIncrement;
+ULONG KeTimeAdjustment;
+ULONG KeTimeIncrement;
LONG KiTickOffset = 0;
-/*
- * The increment in the system clock every timer tick (in system time units)
- *
- * = (1/18.2)*10^9
- *
- * RJJ was 54945055
- */
-#define CLOCK_INCREMENT (100000)
-
-ULONG KeMaximumIncrement = 100000;
-ULONG KeMinimumIncrement = 100000;
-ULONG KeTimeAdjustment = 100000;
-
-#define MICROSECONDS_PER_TICK (10000)
-#define TICKS_TO_CALIBRATE (1)
-#define CALIBRATE_PERIOD (MICROSECONDS_PER_TICK * TICKS_TO_CALIBRATE)
-
-/* FUNCTIONS **************************************************************/
-
-VOID
-NTAPI
-KeSetSystemTime(IN PLARGE_INTEGER NewSystemTime,
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+NTAPI
+KeSetSystemTime(IN PLARGE_INTEGER NewTime,
OUT PLARGE_INTEGER OldTime,
IN BOOLEAN FixInterruptTime,
- IN PLARGE_INTEGER HalTime)
-{
- LARGE_INTEGER OldSystemTime;
- LARGE_INTEGER DeltaTime;
- KIRQL OldIrql;
-
- ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
-
- OldIrql = KiAcquireDispatcherLock();
-
- do
- {
- OldSystemTime.u.HighPart = SharedUserData->SystemTime.High1Time;
- OldSystemTime.u.LowPart = SharedUserData->SystemTime.LowPart;
- }
- while (OldSystemTime.u.HighPart != SharedUserData->SystemTime.High2Time);
-
- /* Set the new system time */
- SharedUserData->SystemTime.LowPart = NewSystemTime->u.LowPart;
- SharedUserData->SystemTime.High1Time = NewSystemTime->u.HighPart;
- SharedUserData->SystemTime.High2Time = NewSystemTime->u.HighPart;
-
- /* Calculate the difference between the new and the old time */
- DeltaTime.QuadPart = NewSystemTime->QuadPart - OldSystemTime.QuadPart;
-
- /* Update system boot time */
- KeBootTime.QuadPart += DeltaTime.QuadPart;
-
- /* Update absolute timers */
- DPRINT1("FIXME: TIMER UPDATE NOT DONE!!!\n");
-
- KiReleaseDispatcherLock(OldIrql);
-
- /*
- * NOTE: Expired timers will be processed at the next clock tick!
- */
-}
+ IN PLARGE_INTEGER HalTime OPTIONAL)
+{
+ TIME_FIELDS TimeFields;
+ KIRQL OldIrql, OldIrql2;
+ LARGE_INTEGER DeltaTime;
+ PLIST_ENTRY ListHead, NextEntry;
+ PKTIMER Timer;
+ PKSPIN_LOCK_QUEUE LockQueue;
+ LIST_ENTRY TempList, TempList2;
+ ULONG Hand, i;
+ PKTIMER_TABLE_ENTRY TimerEntry;
+
+ /* Sanity checks */
+ ASSERT((NewTime->HighPart & 0xF0000000) == 0);
+ ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
+
+ /* Check if this is for the HAL */
+ if (HalTime) RtlTimeToTimeFields(HalTime, &TimeFields);
+
+ /* Set affinity to this CPU, lock the dispatcher, and raise IRQL */
+ KeSetSystemAffinityThread(1);
+ OldIrql = KiAcquireDispatcherLock();
+ KeRaiseIrql(HIGH_LEVEL, &OldIrql2);
+
+ /* Query the system time now */
+ KeQuerySystemTime(OldTime);
+
+ /* Set the new system time */
+ SharedUserData->SystemTime.LowPart = NewTime->LowPart;
+ SharedUserData->SystemTime.High1Time = NewTime->HighPart;
+ SharedUserData->SystemTime.High2Time = NewTime->HighPart;
+
+ /* Check if this was for the HAL and set the RTC time */
+ if (HalTime) ExCmosClockIsSane = HalSetRealTimeClock(&TimeFields);
+
+ /* Calculate the difference between the new and the old time */
+ DeltaTime.QuadPart = NewTime->QuadPart - OldTime->QuadPart;
+
+ /* Update system boot time */
+ KeBootTime.QuadPart += DeltaTime.QuadPart;
+ KeBootTimeBias = KeBootTimeBias + DeltaTime.QuadPart;
+
+ /* Lower IRQL back */
+ KeLowerIrql(OldIrql2);
+
+ /* Check if we need to adjust interrupt time */
+ if (FixInterruptTime) KEBUGCHECK(0);
+
+ /* Setup a temporary list of absolute timers */
+ InitializeListHead(&TempList);
+
+ /* Loop current timers */
+ for (i = 0; i < TIMER_TABLE_SIZE; i++)
+ {
+ /* Loop the entries in this table and lock the timers */
+ ListHead = &KiTimerTableListHead[i].Entry;
+ LockQueue = KiAcquireTimerLock(i);
+ NextEntry = ListHead->Flink;
+ while (NextEntry != ListHead)
+ {
+ /* Get the timer */
+ Timer = CONTAINING_RECORD(NextEntry, KTIMER, TimerListEntry);
+ NextEntry = NextEntry->Flink;
+
+ /* Is is absolute? */
+ if (Timer->Header.Absolute)
+ {
+ /* Remove it from the timer list */
+ if (RemoveEntryList(&Timer->TimerListEntry))
+ {
+ /* Get the entry and check if it's empty */
+ TimerEntry = &KiTimerTableListHead[Timer->Header.Hand];
+ if (IsListEmpty(&TimerEntry->Entry))
+ {
+ /* Clear the time then */
+ TimerEntry->Time.HighPart = 0xFFFFFFFF;
+ }
+ }
+
+ /* Insert it into our temporary list */
+ DPRINT1("Adding a timer!\n");
+ InsertTailList(&TempList, &Timer->TimerListEntry);
+ }
+ }
+
+ /* Release the lock */
+ KiReleaseTimerLock(LockQueue);
+ }
+
+ /* Setup a temporary list of expired timers */
+ InitializeListHead(&TempList2);
+
+ /* Loop absolute timers */
+ while (TempList.Flink != &TempList)
+ {
+ /* Get the timer */
+ Timer = CONTAINING_RECORD(TempList.Flink, KTIMER, TimerListEntry);
+ RemoveEntryList(&Timer->TimerListEntry);
+
+ /* Update the due time and handle */
+ Timer->DueTime.QuadPart -= DeltaTime.QuadPart;
+ Hand = KiComputeTimerTableIndex(Timer->DueTime.QuadPart);
+ Timer->Header.Hand = (UCHAR)Hand;
+
+ /* Lock the timer and re-insert it */
+ LockQueue = KiAcquireTimerLock(Hand);
+ if (KiInsertTimerTable(Timer, Hand))
+ {
+ /* Remove it from the timer list */
+ if (RemoveEntryList(&Timer->TimerListEntry))
+ {
+ /* Get the entry and check if it's empty */
+ TimerEntry = &KiTimerTableListHead[Timer->Header.Hand];
+ if (IsListEmpty(&TimerEntry->Entry))
+ {
+ /* Clear the time then */
+ TimerEntry->Time.HighPart = 0xFFFFFFFF;
+ }
+ }
+
+ /* Insert it into our temporary list */
+ DPRINT1("Adding a timer 2!\n");
+ InsertTailList(&TempList2, &Timer->TimerListEntry);
+ }
+
+ /* Release the lock */
+ KiReleaseTimerLock(LockQueue);
+ }
+
+ /* FIXME: Process expired timers! */
+ KiReleaseDispatcherLock(OldIrql);
+
+ /* Revert affinity */
+ KeRevertToUserAffinityThread();
+}
+
+/* PUBLIC FUNCTIONS **********************************************************/
/*
* @implemented
*/
ULONG
-STDCALL
+NTAPI
KeQueryTimeIncrement(VOID)
-/*
- * FUNCTION: Gets the increment (in 100-nanosecond units) that is added to
- * the system clock every time the clock interrupts
- * RETURNS: The increment
- */
-{
+{
+ /* Return the increment */
return KeMaximumIncrement;
}
@@ -121,47 +185,60 @@
*/
#undef KeQueryTickCount
VOID
-STDCALL
-KeQueryTickCount(PLARGE_INTEGER TickCount)
-/*
- * FUNCTION: Returns the number of ticks since the system was booted
- * ARGUMENTS:
- * TickCount (OUT) = Points to storage for the number of ticks
- */
-{
- TickCount->QuadPart = *(PULONGLONG)&KeTickCount;
-}
-
-/*
- * FUNCTION: Gets the current system time
- * ARGUMENTS:
- * CurrentTime (OUT) = The routine stores the current time here
- * NOTE: The time is the number of 100-nanosecond intervals since the
- * 1st of January, 1601.
- *
- * @implemented
- */
-VOID
-STDCALL
-KeQuerySystemTime(PLARGE_INTEGER CurrentTime)
-{
- do {
- CurrentTime->u.HighPart = SharedUserData->SystemTime.High1Time;
- CurrentTime->u.LowPart = SharedUserData->SystemTime.LowPart;
- } while (CurrentTime->u.HighPart != SharedUserData->SystemTime.High2Time);
-}
-
+NTAPI
+KeQueryTickCount(IN PLARGE_INTEGER TickCount)
+{
+ /* Loop until we get a perfect match */
+ for (;;)
+ {
+ /* Read the tick count value */
+ TickCount->HighPart = KeTickCount.High1Time;
+ TickCount->LowPart = KeTickCount.LowPart;
+ if (TickCount->HighPart == KeTickCount.High2Time) break;
+ YieldProcessor();
+ }
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+KeQuerySystemTime(OUT PLARGE_INTEGER CurrentTime)
+{
+ /* Loop until we get a perfect match */
+ for (;;)
+ {
+ /* Read the time value */
+ CurrentTime->HighPart = SharedUserData->SystemTime.High1Time;
+ CurrentTime->LowPart = SharedUserData->SystemTime.LowPart;
+ if (CurrentTime->HighPart ==
+ SharedUserData->SystemTime.High2Time) break;
+ YieldProcessor();
+ }
+}
+
+/*
+ * @implemented
+ */
ULONGLONG
-STDCALL
+NTAPI
KeQueryInterruptTime(VOID)
{
LARGE_INTEGER CurrentTime;
- do {
- CurrentTime.u.HighPart = SharedUserData->InterruptTime.High1Time;
- CurrentTime.u.LowPart = SharedUserData->InterruptTime.LowPart;
- } while (CurrentTime.u.HighPart != SharedUserData->InterruptTime.High2Time);
-
+ /* Loop until we get a perfect match */
+ for (;;)
+ {
+ /* Read the time value */
+ CurrentTime.HighPart = SharedUserData->InterruptTime.High1Time;
+ CurrentTime.LowPart = SharedUserData->InterruptTime.LowPart;
+ if (CurrentTime.HighPart ==
+ SharedUserData->InterruptTime.High2Time) break;
+ YieldProcessor();
+ }
+
+ /* Return the time value */
return CurrentTime.QuadPart;
}
@@ -169,32 +246,20 @@
* @implemented
*/
VOID
-STDCALL
-KeSetTimeIncrement(
- IN ULONG MaxIncrement,
- IN ULONG MinIncrement)
+NTAPI
+KeSetTimeIncrement(IN ULONG MaxIncrement,
+ IN ULONG MinIncrement)
{
/* Set some Internal Variables */
- /* FIXME: We use a harcoded CLOCK_INCREMENT. That *must* be changed */
KeMaximumIncrement = MaxIncrement;
- KeMinimumIncrement = MinIncrement;
-}
-
-/*
- * @implemented
- */
-ULONG
-STDCALL
-NtGetTickCount(VOID)
-{
- LARGE_INTEGER TickCount;
-
- KeQueryTickCount(&TickCount);
- return TickCount.u.LowPart;
+ KeMinimumIncrement = max(MinIncrement, 10000);
+ KeTimeAdjustment = MaxIncrement;
+ KeTimeIncrement = MaxIncrement;
+ KiTickOffset = MaxIncrement;
}
NTSTATUS
-STDCALL
+NTAPI
NtQueryTimerResolution(OUT PULONG MinimumResolution,
OUT PULONG MaximumResolution,
OUT PULONG ActualResolution)
@@ -204,7 +269,7 @@
}
NTSTATUS
-STDCALL
+NTAPI
NtSetTimerResolution(IN ULONG DesiredResolution,
IN BOOLEAN SetResolution,
OUT PULONG CurrentResolution)
Modified: trunk/reactos/ntoskrnl/ke/dpc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/dpc.c?rev=2562…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/dpc.c (original)
+++ trunk/reactos/ntoskrnl/ke/dpc.c Thu Jan 25 08:14:55 2007
@@ -22,6 +22,8 @@
ULONG KiIdealDpcRate = 20;
BOOLEAN KeThreadDpcEnable;
FAST_MUTEX KiGenericCallDpcMutex;
+KDPC KiTimerExpireDpc;
+ULONG KiTimeLimitIsrMicroseconds;
/* PRIVATE FUNCTIONS *********************************************************/
Modified: trunk/reactos/ntoskrnl/mm/pagefile.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/pagefile.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/pagefile.c (original)
+++ trunk/reactos/ntoskrnl/mm/pagefile.c Thu Jan 25 08:14:55 2007
@@ -363,7 +363,11 @@
KIRQL oldIrql;
ULONG MiAvailSwapPages;
- if (!PagingReady) KEBUGCHECK(0);
+ if (!PagingReady)
+ {
+ DPRINT1("PAGING USED TOO SOON!!!\n");
+ while (TRUE);
+ }
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
MiAvailSwapPages =
(MiFreeSwapPages * MM_PAGEFILE_COMMIT_RATIO) + MM_PAGEFILE_COMMIT_GRACE;
@@ -383,7 +387,11 @@
{
KIRQL oldIrql;
- if (!PagingReady) KEBUGCHECK(0);
+ if (!PagingReady)
+ {
+ DPRINT1("PAGING USED TOO SOON!!!\n");
+ while (TRUE);
+ }
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
MiReservedSwapPages = MiReservedSwapPages - Nr;
KeReleaseSpinLock(&PagingFileListLock, oldIrql);
@@ -395,7 +403,11 @@
KIRQL oldIrql;
ULONG i, j;
- if (!PagingReady) KEBUGCHECK(0);
+ if (!PagingReady)
+ {
+ DPRINT1("PAGING USED TOO SOON!!!\n");
+ while (TRUE);
+ }
KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql);
for (i = 0; i < PagingFile->AllocMapSize; i++)
@@ -425,7 +437,11 @@
ULONG off;
KIRQL oldIrql;
- if (!PagingReady) KEBUGCHECK(0);
+ if (!PagingReady)
+ {
+ DPRINT1("PAGING USED TOO SOON!!!\n");
+ while (TRUE);
+ }
i = FILE_FROM_ENTRY(Entry);
off = OFFSET_FROM_ENTRY(Entry);
@@ -470,7 +486,11 @@
ULONG off;
SWAPENTRY entry;
- if (!PagingReady) KEBUGCHECK(0);
+ if (!PagingReady)
+ {
+ DPRINT1("PAGING USED TOO SOON!!!\n");
+ while (TRUE);
+ }
KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
if (MiFreeSwapPages == 0)
Modified: trunk/reactos/ntoskrnl/mm/pageop.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/pageop.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/pageop.c (original)
+++ trunk/reactos/ntoskrnl/mm/pageop.c Thu Jan 25 08:14:55 2007
@@ -149,7 +149,11 @@
KIRQL oldIrql;
PMM_PAGEOP PageOp;
- if (!PageOpReady) KEBUGCHECK(0);
+ if (!PageOpReady)
+ {
+ DPRINT1("PAGEOPS USED TOO SOON!!!\n");
+ while (TRUE);
+ }
/*
* Calcuate the hash value for pageop structure
@@ -269,3 +273,4 @@
+
Modified: trunk/reactos/ntoskrnl/mm/rmap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/rmap.c?rev=256…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/rmap.c (original)
+++ trunk/reactos/ntoskrnl/mm/rmap.c Thu Jan 25 08:14:55 2007
@@ -390,7 +390,11 @@
PMM_RMAP_ENTRY new_entry;
ULONG PrevSize;
- if (!RmapReady) KEBUGCHECK(0);
+ if (!RmapReady)
+ {
+ DPRINT1("RMAPS USED TOO SOON!!!\n");
+ while (TRUE);
+ }
Address = (PVOID)PAGE_ROUND_DOWN(Address);
@@ -459,6 +463,12 @@
PMM_RMAP_ENTRY previous_entry;
PEPROCESS Process;
+ if (!RmapReady)
+ {
+ DPRINT1("RMAPS USED TOO SOON!!!\n");
+ while (TRUE);
+ }
+
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL)
@@ -496,6 +506,12 @@
PVOID Address)
{
PMM_RMAP_ENTRY current_entry, previous_entry;
+
+ if (!RmapReady)
+ {
+ DPRINT1("RMAPS USED TOO SOON!!!\n");
+ while (TRUE);
+ }
ExAcquireFastMutex(&RmapListLock);
previous_entry = NULL;