[NTOS]: Add MiRemoveZeroPageSafe helper function, when a zero page is required, but the inline zeroing of MiRemoveZeroPage is not. This function will only try grabbing a zero page if one exists, otherwise a free page will be grabbed and zeroed with custom code of the caller's choosing.

[NTOS]: Add concept of process color and system color. Compute correct color to use whenever requesting a page.
[NTOS]: Uncondtionally enable the color code when inserting/removing pages.
For now, when requesting a page, colors are still ignored, and the global PFN lists are scanned instead. If there are no regressions, we are one patch away from that.

svn path=/trunk/; revision=48927
This commit is contained in:
Sir Richard 2010-09-29 01:10:28 +00:00
parent 71e8fc824b
commit 14f8621042
7 changed files with 133 additions and 65 deletions

View file

@ -218,6 +218,13 @@ extern const ULONG MmProtectToPteMask[32];
// //
#define MM_NOIRQL (KIRQL)0xFFFFFFFF #define MM_NOIRQL (KIRQL)0xFFFFFFFF
//
// Returns the color of a page
//
#define MI_GET_PAGE_COLOR(x) ((x) & MmSecondaryColorMask)
#define MI_GET_NEXT_COLOR(x) (MI_GET_PAGE_COLOR(++MmSystemPageColor))
#define MI_GET_NEXT_PROCESS_COLOR(x) (MI_GET_PAGE_COLOR(++(x)->NextPageColor))
// //
// FIXFIX: These should go in ex.h after the pool merge // FIXFIX: These should go in ex.h after the pool merge
// //
@ -455,9 +462,8 @@ extern PMMPTE MmSharedUserDataPte;
extern LIST_ENTRY MmProcessList; extern LIST_ENTRY MmProcessList;
extern BOOLEAN MmZeroingPageThreadActive; extern BOOLEAN MmZeroingPageThreadActive;
extern KEVENT MmZeroingPageEvent; extern KEVENT MmZeroingPageEvent;
extern ULONG MmSystemPageColor;
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x]) extern ULONG MmProcessColorSeed;
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
// //
// Figures out the hardware bits for a PTE // Figures out the hardware bits for a PTE
@ -1093,4 +1099,19 @@ MiGetNextNode(
IN PMMADDRESS_NODE Node IN PMMADDRESS_NODE Node
); );
//
// MiRemoveZeroPage will use inline code to zero out the page manually if only
// free pages are available. In some scenarios, we don't/can't run that piece of
// code and would rather only have a real zero page. If we can't have a zero page,
// then we'd like to have our own code to grab a free page and zero it out, by
// using MiRemoveAnyPage. This macro implements this.
//
PFN_NUMBER
FORCEINLINE
MiRemoveZeroPageSafe(IN ULONG Color)
{
if (MmFreePagesByColor[ZeroedPageList][Color].Flink != LIST_HEAD) return MiRemoveZeroPage(Color);
return 0;
}
/* EOF */ /* EOF */

View file

@ -179,9 +179,10 @@ MiResolveDemandZeroFault(IN PVOID Address,
IN PEPROCESS Process, IN PEPROCESS Process,
IN KIRQL OldIrql) IN KIRQL OldIrql)
{ {
PFN_NUMBER PageFrameNumber; PFN_NUMBER PageFrameNumber = 0;
MMPTE TempPte; MMPTE TempPte;
BOOLEAN NeedZero = FALSE; BOOLEAN NeedZero = FALSE;
ULONG Color;
DPRINT("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n", DPRINT("ARM3 Demand Zero Page Fault Handler for address: %p in process: %p\n",
Address, Address,
Process); Process);
@ -196,9 +197,17 @@ MiResolveDemandZeroFault(IN PVOID Address,
/* No forking yet */ /* No forking yet */
ASSERT(Process->ForkInProgress == NULL); ASSERT(Process->ForkInProgress == NULL);
/* Get process color */
Color = MI_GET_NEXT_PROCESS_COLOR(Process);
/* We'll need a zero page */ /* We'll need a zero page */
NeedZero = TRUE; NeedZero = TRUE;
} }
else
{
/* Get the next system page color */
Color = MI_GET_NEXT_COLOR();
}
// //
// Lock the PFN database // Lock the PFN database
@ -206,9 +215,21 @@ MiResolveDemandZeroFault(IN PVOID Address,
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
ASSERT(PointerPte->u.Hard.Valid == 0); ASSERT(PointerPte->u.Hard.Valid == 0);
/* Get a page */ /* Do we need a zero page? */
PageFrameNumber = MiRemoveAnyPage(0); if (NeedZero)
{
/* Try to get one, if we couldn't grab a free page and zero it */
PageFrameNumber = MiRemoveZeroPageSafe(Color);
if (PageFrameNumber) NeedZero = FALSE;
}
/* Did we get a page? */
if (!PageFrameNumber)
{
/* We either failed to find a zero page, or this is a system request */
PageFrameNumber = MiRemoveAnyPage(Color);
DPRINT("New pool page: %lx\n", PageFrameNumber); DPRINT("New pool page: %lx\n", PageFrameNumber);
}
/* Initialize it */ /* Initialize it */
MiInitializePfn(PageFrameNumber, PointerPte, TRUE); MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
@ -463,6 +484,7 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
ULONG ProtectionCode; ULONG ProtectionCode;
PMMVAD Vad; PMMVAD Vad;
PFN_NUMBER PageFrameIndex; PFN_NUMBER PageFrameIndex;
ULONG Color;
DPRINT("ARM3 FAULT AT: %p\n", Address); DPRINT("ARM3 FAULT AT: %p\n", Address);
// //
@ -757,8 +779,13 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
/* Lock the PFN database since we're going to grab a page */ /* Lock the PFN database since we're going to grab a page */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Try to get a zero page */
Color = MI_GET_NEXT_PROCESS_COLOR(CurrentProcess);
PageFrameIndex = MiRemoveZeroPageSafe(Color);
if (!PageFrameIndex)
{
/* Grab a page out of there. Later we should grab a colored zero page */ /* Grab a page out of there. Later we should grab a colored zero page */
PageFrameIndex = MiRemoveAnyPage(0); PageFrameIndex = MiRemoveAnyPage(Color);
ASSERT(PageFrameIndex); ASSERT(PageFrameIndex);
/* Release the lock since we need to do some zeroing */ /* Release the lock since we need to do some zeroing */
@ -769,6 +796,7 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
/* Grab the lock again so we can initialize the PFN entry */ /* Grab the lock again so we can initialize the PFN entry */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
}
/* Initialize the PFN entry now */ /* Initialize the PFN entry now */
MiInitializePfn(PageFrameIndex, PointerPte, 1); MiInitializePfn(PageFrameIndex, PointerPte, 1);

View file

@ -30,12 +30,11 @@ do { \
#define ASSERT_LIST_INVARIANT(x) #define ASSERT_LIST_INVARIANT(x)
#endif #endif
#define ARM3_COLORS 1
/* GLOBALS ********************************************************************/ /* GLOBALS ********************************************************************/
BOOLEAN MmDynamicPfn; BOOLEAN MmDynamicPfn;
BOOLEAN MmMirroring; BOOLEAN MmMirroring;
ULONG MmSystemPageColor;
MMPFNLIST MmZeroedPageListHead = {0, ZeroedPageList, LIST_HEAD, LIST_HEAD}; MMPFNLIST MmZeroedPageListHead = {0, ZeroedPageList, LIST_HEAD, LIST_HEAD};
MMPFNLIST MmFreePageListHead = {0, FreePageList, LIST_HEAD, LIST_HEAD}; MMPFNLIST MmFreePageListHead = {0, FreePageList, LIST_HEAD, LIST_HEAD};
@ -80,11 +79,9 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
PFN_NUMBER OldFlink, OldBlink; PFN_NUMBER OldFlink, OldBlink;
PMMPFNLIST ListHead; PMMPFNLIST ListHead;
MMLISTS ListName; MMLISTS ListName;
#ifdef ARM3_COLORS
ULONG Color; ULONG Color;
PMMCOLOR_TABLES ColorTable; PMMCOLOR_TABLES ColorTable;
PMMPFN Pfn1; PMMPFN Pfn1;
#endif
/* Make sure the PFN lock is held */ /* Make sure the PFN lock is held */
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
@ -131,7 +128,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
/* Set the list head's backlink instead */ /* Set the list head's backlink instead */
ListHead->Flink = OldFlink; ListHead->Flink = OldFlink;
} }
#ifdef ARM3_COLORS
/* Get the page color */ /* Get the page color */
OldBlink = MiGetPfnEntryIndex(Entry); OldBlink = MiGetPfnEntryIndex(Entry);
Color = OldBlink & MmSecondaryColorMask; Color = OldBlink & MmSecondaryColorMask;
@ -185,7 +182,7 @@ MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
/* ReactOS Hack */ /* ReactOS Hack */
Entry->OriginalPte.u.Long = 0; Entry->OriginalPte.u.Long = 0;
#endif
/* We are not on a list anymore */ /* We are not on a list anymore */
Entry->u1.Flink = Entry->u2.Blink = 0; Entry->u1.Flink = Entry->u2.Blink = 0;
ASSERT_LIST_INVARIANT(ListHead); ASSERT_LIST_INVARIANT(ListHead);
@ -219,9 +216,8 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
MMLISTS ListName; MMLISTS ListName;
PFN_NUMBER OldFlink, OldBlink; PFN_NUMBER OldFlink, OldBlink;
ULONG OldColor, OldCache; ULONG OldColor, OldCache;
#ifdef ARM3_COLORS
PMMCOLOR_TABLES ColorTable; PMMCOLOR_TABLES ColorTable;
#endif
/* Make sure PFN lock is held */ /* Make sure PFN lock is held */
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(Color < MmSecondaryColors); ASSERT(Color < MmSecondaryColors);
@ -280,7 +276,7 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
Pfn1->u3.e2.ShortFlags = 0; Pfn1->u3.e2.ShortFlags = 0;
Pfn1->u3.e1.PageColor = OldColor; Pfn1->u3.e1.PageColor = OldColor;
Pfn1->u3.e1.CacheAttribute = OldCache; Pfn1->u3.e1.CacheAttribute = OldCache;
#ifdef ARM3_COLORS
/* Get the first page on the color list */ /* Get the first page on the color list */
ASSERT(Color < MmSecondaryColors); ASSERT(Color < MmSecondaryColors);
ColorTable = &MmFreePagesByColor[ListName][Color]; ColorTable = &MmFreePagesByColor[ListName][Color];
@ -306,7 +302,7 @@ MiRemovePageByColor(IN PFN_NUMBER PageIndex,
/* ReactOS Hack */ /* ReactOS Hack */
Pfn1->OriginalPte.u.Long = 0; Pfn1->OriginalPte.u.Long = 0;
#endif
/* See if we hit any thresholds */ /* See if we hit any thresholds */
if (MmAvailablePages == MmHighMemoryThreshold) if (MmAvailablePages == MmHighMemoryThreshold)
{ {
@ -340,9 +336,8 @@ MiRemoveAnyPage(IN ULONG Color)
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(MmAvailablePages != 0); ASSERT(MmAvailablePages != 0);
ASSERT(Color < MmSecondaryColors); ASSERT(Color < MmSecondaryColors);
#if 0
/* Check the colored free list */ /* Check the colored free list */
#if 0 // Enable when using ARM3 database */
PageIndex = MmFreePagesByColor[FreePageList][Color].Flink; PageIndex = MmFreePagesByColor[FreePageList][Color].Flink;
if (PageIndex == LIST_HEAD) if (PageIndex == LIST_HEAD)
{ {
@ -368,11 +363,10 @@ MiRemoveAnyPage(IN ULONG Color)
ASSERT(MmZeroedPageListHead.Total == 0); ASSERT(MmZeroedPageListHead.Total == 0);
} }
} }
#if 0 // Enable when using ARM3 database */ #if 0
} }
} }
#endif #endif
/* Remove the page from its list */ /* Remove the page from its list */
PageIndex = MiRemovePageByColor(PageIndex, Color); PageIndex = MiRemovePageByColor(PageIndex, Color);
@ -403,7 +397,7 @@ MiRemoveZeroPage(IN ULONG Color)
ASSERT(Color < MmSecondaryColors); ASSERT(Color < MmSecondaryColors);
/* Check the colored zero list */ /* Check the colored zero list */
#if 0 // Enable when using ARM3 database */ #if 0
PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink; PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink;
if (PageIndex == LIST_HEAD) if (PageIndex == LIST_HEAD)
{ {
@ -414,9 +408,10 @@ MiRemoveZeroPage(IN ULONG Color)
Color = PageIndex & MmSecondaryColorMask; Color = PageIndex & MmSecondaryColorMask;
if (PageIndex == LIST_HEAD) if (PageIndex == LIST_HEAD)
{ {
/* This means there's no zero pages, we have to look for free ones */
ASSERT(MmZeroedPageListHead.Total == 0); ASSERT(MmZeroedPageListHead.Total == 0);
Zero = TRUE; Zero = TRUE;
#if 0 // Enable when using ARM3 database */ #if 0
/* Check the colored free list */ /* Check the colored free list */
PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink; PageIndex = MmFreePagesByColor[ZeroedPageList][Color].Flink;
if (PageIndex == LIST_HEAD) if (PageIndex == LIST_HEAD)
@ -432,13 +427,14 @@ MiRemoveZeroPage(IN ULONG Color)
/* FIXME: Should check the standby list */ /* FIXME: Should check the standby list */
ASSERT(MmZeroedPageListHead.Total == 0); ASSERT(MmZeroedPageListHead.Total == 0);
} }
#if 0 // Enable when using ARM3 database */ #if 0
} }
#endif #endif
} }
#if 0 // Enable when using ARM3 database */ #if 0
} }
#endif #endif
/* Sanity checks */ /* Sanity checks */
Pfn1 = MiGetPfnEntry(PageIndex); Pfn1 = MiGetPfnEntry(PageIndex);
ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) || ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) ||
@ -468,11 +464,10 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
PMMPFNLIST ListHead; PMMPFNLIST ListHead;
PFN_NUMBER LastPage; PFN_NUMBER LastPage;
PMMPFN Pfn1; PMMPFN Pfn1;
#ifdef ARM3_COLORS
ULONG Color; ULONG Color;
PMMPFN Blink; PMMPFN Blink;
PMMCOLOR_TABLES ColorTable; PMMCOLOR_TABLES ColorTable;
#endif
/* Make sure the page index is valid */ /* Make sure the page index is valid */
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
ASSERT((PageFrameIndex != 0) && ASSERT((PageFrameIndex != 0) &&
@ -537,7 +532,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
/* Otherwise check if we reached the high threshold and signal the event */ /* Otherwise check if we reached the high threshold and signal the event */
KeSetEvent(MiHighMemoryEvent, 0, FALSE); KeSetEvent(MiHighMemoryEvent, 0, FALSE);
} }
#ifdef ARM3_COLORS
/* Get the page color */ /* Get the page color */
Color = PageFrameIndex & MmSecondaryColorMask; Color = PageFrameIndex & MmSecondaryColorMask;
@ -571,7 +566,7 @@ MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
/* And increase the count in the colored list */ /* And increase the count in the colored list */
ColorTable->Count++; ColorTable->Count++;
#endif
/* Notify zero page thread if enough pages are on the free list now */ /* Notify zero page thread if enough pages are on the free list now */
if ((ListHead->Total >= 8) && !(MmZeroingPageThreadActive)) if ((ListHead->Total >= 8) && !(MmZeroingPageThreadActive))
{ {
@ -590,10 +585,9 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
PFN_NUMBER Flink; PFN_NUMBER Flink;
PMMPFN Pfn1, Pfn2; PMMPFN Pfn1, Pfn2;
MMLISTS ListName; MMLISTS ListName;
#ifdef ARM3_COLORS
PMMCOLOR_TABLES ColorHead; PMMCOLOR_TABLES ColorHead;
ULONG Color; ULONG Color;
#endif
/* For free pages, use MiInsertPageInFreeList */ /* For free pages, use MiInsertPageInFreeList */
ASSERT(ListHead != &MmFreePageListHead); ASSERT(ListHead != &MmFreePageListHead);
@ -657,7 +651,7 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
KeSetEvent(MiHighMemoryEvent, 0, FALSE); KeSetEvent(MiHighMemoryEvent, 0, FALSE);
} }
#ifdef ARM3_COLORS /* Sanity checks */
ASSERT(ListName == ZeroedPageList); ASSERT(ListName == ZeroedPageList);
ASSERT(Pfn1->u4.InPageError == 0); ASSERT(Pfn1->u4.InPageError == 0);
@ -695,7 +689,6 @@ MiInsertPageInList(IN PMMPFNLIST ListHead,
/* One more paged on the colored list */ /* One more paged on the colored list */
ColorHead->Count++; ColorHead->Count++;
#endif
} }
VOID VOID
@ -783,7 +776,7 @@ MiAllocatePfn(IN PMMPTE PointerPte,
/* Grab a page */ /* Grab a page */
ASSERT_LIST_INVARIANT(&MmFreePageListHead); ASSERT_LIST_INVARIANT(&MmFreePageListHead);
ASSERT_LIST_INVARIANT(&MmZeroedPageListHead); ASSERT_LIST_INVARIANT(&MmZeroedPageListHead);
PageFrameIndex = MiRemoveAnyPage(0); PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
/* Write the software PTE */ /* Write the software PTE */
MI_WRITE_INVALID_PTE(PointerPte, TempPte); MI_WRITE_INVALID_PTE(PointerPte, TempPte);

View file

@ -473,7 +473,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
ASSERT(PointerPte->u.Hard.Valid == 0); ASSERT(PointerPte->u.Hard.Valid == 0);
/* Request a page */ /* Request a page */
PageFrameNumber = MiRemoveAnyPage(0); PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
TempPte.u.Hard.PageFrameNumber = PageFrameNumber; TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
#if (_MI_PAGING_LEVELS >= 3) #if (_MI_PAGING_LEVELS >= 3)
@ -768,7 +768,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
do do
{ {
/* Allocate a page */ /* Allocate a page */
PageFrameNumber = MiRemoveAnyPage(0); PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
/* Get the PFN entry for it and fill it out */ /* Get the PFN entry for it and fill it out */
Pfn1 = MiGetPfnEntry(PageFrameNumber); Pfn1 = MiGetPfnEntry(PageFrameNumber);

View file

@ -16,7 +16,9 @@
#define MODULE_INVOLVED_IN_ARM3 #define MODULE_INVOLVED_IN_ARM3
#include "../ARM3/miarm.h" #include "../ARM3/miarm.h"
extern MM_SYSTEMSIZE MmSystemSize; /* GLOBALS ********************************************************************/
ULONG MmProcessColorSeed = 0x12345678;
/* PRIVATE FUNCTIONS **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
@ -357,7 +359,7 @@ MmCreateKernelStack(IN BOOLEAN GuiStack,
PointerPte++; PointerPte++;
/* Get a page and write the current invalid PTE */ /* Get a page and write the current invalid PTE */
PageFrameIndex = MiRemoveAnyPage(0); PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
MI_WRITE_INVALID_PTE(PointerPte, InvalidPte); MI_WRITE_INVALID_PTE(PointerPte, InvalidPte);
/* Initialize the PFN entry for this page */ /* Initialize the PFN entry for this page */
@ -444,7 +446,7 @@ MmGrowKernelStackEx(IN PVOID StackPointer,
while (LimitPte >= NewLimitPte) while (LimitPte >= NewLimitPte)
{ {
/* Get a page and write the current invalid PTE */ /* Get a page and write the current invalid PTE */
PageFrameIndex = MiRemoveAnyPage(0); PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
MI_WRITE_INVALID_PTE(LimitPte, InvalidPte); MI_WRITE_INVALID_PTE(LimitPte, InvalidPte);
/* Initialize the PFN entry for this page */ /* Initialize the PFN entry for this page */
@ -1058,9 +1060,10 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
MMPTE TempPte, PdePte; MMPTE TempPte, PdePte;
ULONG PdeOffset; ULONG PdeOffset;
PMMPTE SystemTable; PMMPTE SystemTable;
ULONG Color;
/* No page colors yet */ /* Choose a process color */
Process->NextPageColor = 0; Process->NextPageColor = RtlRandom(&MmProcessColorSeed);
/* Setup the hyperspace lock */ /* Setup the hyperspace lock */
KeInitializeSpinLock(&Process->HyperSpaceLock); KeInitializeSpinLock(&Process->HyperSpaceLock);
@ -1068,16 +1071,37 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
/* Lock PFN database */ /* Lock PFN database */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Get a page for the PDE */ /* Get a zero page for the PDE, if possible */
PdeIndex = MiRemoveAnyPage(0); Color = MI_GET_NEXT_PROCESS_COLOR(Process);
PdeIndex = MiRemoveZeroPageSafe(Color);
if (!PdeIndex)
{
/* No zero pages, grab a free one */
PdeIndex = MiRemoveAnyPage(Color);
/* Zero it outside the PFN lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
MiZeroPhysicalPage(PdeIndex); MiZeroPhysicalPage(PdeIndex);
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
}
/* Get a page for hyperspace */ /* Get a zero page for hyperspace, if possible */
HyperIndex = MiRemoveAnyPage(0); Color = MI_GET_NEXT_PROCESS_COLOR(Process);
HyperIndex = MiRemoveZeroPageSafe(Color);
if (!HyperIndex)
{
/* No zero pages, grab a free one */
HyperIndex = MiRemoveAnyPage(Color);
/* Zero it outside the PFN lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql); KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
MiZeroPhysicalPage(HyperIndex); MiZeroPhysicalPage(HyperIndex);
}
else
{
/* Release the PFN lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
}
/* Switch to phase 1 initialization */ /* Switch to phase 1 initialization */
ASSERT(Process->AddressSpaceInitialized == 0); ASSERT(Process->AddressSpaceInitialized == 0);
@ -1112,7 +1136,6 @@ MmCreateProcessAddressSpace(IN ULONG MinWs,
/* Copy all the kernel mappings */ /* Copy all the kernel mappings */
PdeOffset = MiGetPdeOffset(MmSystemRangeStart); PdeOffset = MiGetPdeOffset(MmSystemRangeStart);
RtlCopyMemory(&SystemTable[PdeOffset], RtlCopyMemory(&SystemTable[PdeOffset],
MiAddressToPde(MmSystemRangeStart), MiAddressToPde(MmSystemRangeStart),
PAGE_SIZE - PdeOffset * sizeof(MMPTE)); PAGE_SIZE - PdeOffset * sizeof(MMPTE));

View file

@ -69,8 +69,11 @@ MmZeroPageThread(VOID)
} }
PageIndex = MmFreePageListHead.Flink; PageIndex = MmFreePageListHead.Flink;
ASSERT(PageIndex != LIST_HEAD);
Pfn1 = MiGetPfnEntry(PageIndex); Pfn1 = MiGetPfnEntry(PageIndex);
FreePage = MiRemoveAnyPage(0); // FIXME: Use real color FreePage = MiRemoveAnyPage(MI_GET_PAGE_COLOR(PageIndex));
/* The first global free page should also be the first on its own list */
if (FreePage != PageIndex) if (FreePage != PageIndex)
{ {
KeBugCheckEx(PFN_LIST_CORRUPT, KeBugCheckEx(PFN_LIST_CORRUPT,

View file

@ -604,11 +604,11 @@ MmAllocPage(ULONG Type)
if (Type != MC_SYSTEM) if (Type != MC_SYSTEM)
{ {
PfnOffset = MiRemoveZeroPage(0); PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
} }
else else
{ {
PfnOffset = MiRemoveAnyPage(0); PfnOffset = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
} }
if (!PfnOffset) if (!PfnOffset)