#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
+//
+// Creates a valid kernel PTE with the given protection
+//
+FORCEINLINE
+VOID
+MI_MAKE_HARDWARE_PTE(IN PMMPTE NewPte,
+ IN PMMPTE MappingPte,
+ IN ULONG ProtectionMask,
+ IN PFN_NUMBER PageFrameNumber)
+{
+ /* Only valid for kernel, non-session PTEs */
+ ASSERT(MappingPte > MiHighestUserPte);
+ ASSERT(!MI_IS_SESSION_PTE(MappingPte));
+ ASSERT((MappingPte < (PMMPTE)PDE_BASE) || (MappingPte > (PMMPTE)PDE_TOP));
+
+ /* Start fresh */
+ *NewPte = ValidKernelPte;
+
+ /* Set the protection and page */
+ NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
+ NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
+}
+
//
// Returns if the page is physically resident (ie: a large page)
// FIXFIX: CISC/x86 only?
PFN_NUMBER StackPtes, StackPages;
PMMPTE PointerPte, StackPte;
PVOID BaseAddress;
- MMPTE TempPte;
+ MMPTE TempPte, InvalidPte;
KIRQL OldIrql;
PFN_NUMBER PageFrameIndex;
ULONG i;
if (GuiStack) PointerPte += BYTES_TO_PAGES(KERNEL_LARGE_STACK_SIZE -
KERNEL_LARGE_STACK_COMMIT);
- //
- // Setup the template stack PTE
- //
- TempPte = ValidKernelPte;
- MI_MAKE_LOCAL_PAGE(&TempPte);
- MI_MAKE_DIRTY_PAGE(&TempPte);
- TempPte.u.Hard.PageFrameNumber = 0;
+
+ /* Setup the temporary invalid PTE */
+ MI_MAKE_SOFTWARE_PTE(&InvalidPte, MM_NOACCESS);
+
+ /* Setup the template stack PTE */
+ MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte + 1, MM_READWRITE, 0);
//
// Acquire the PFN DB lock
//
PointerPte++;
- /* Get a page */
+ /* Get a page and write the current invalid PTE */
PageFrameIndex = MiRemoveAnyPage(0);
+ ASSERT(InvalidPte.u.Hard.Valid == 0);
+ *PointerPte = InvalidPte;
/* Initialize the PFN entry for this page */
MiInitializePfn(PageFrameIndex, PointerPte, 1);
PMMPTE LimitPte, NewLimitPte, LastPte;
PFN_NUMBER StackPages;
KIRQL OldIrql;
- MMPTE TempPte;
+ MMPTE TempPte, InvalidPte;
PFN_NUMBER PageFrameIndex;
//
LimitPte--;
StackPages = (LimitPte - NewLimitPte + 1);
- //
- // Setup the template stack PTE
- //
- TempPte = ValidKernelPte;
- MI_MAKE_LOCAL_PAGE(&TempPte);
- MI_MAKE_DIRTY_PAGE(&TempPte);
- TempPte.u.Hard.PageFrameNumber = 0;
+ /* Setup the temporary invalid PTE */
+ MI_MAKE_SOFTWARE_PTE(&InvalidPte, MM_NOACCESS);
//
// Acquire the PFN DB lock
//
while (LimitPte >= NewLimitPte)
{
- /* Get a page */
+ /* Get a page and write the current invalid PTE */
PageFrameIndex = MiRemoveAnyPage(0);
+ ASSERT(InvalidPte.u.Hard.Valid == 0);
+ *LimitPte = InvalidPte;
/* Initialize the PFN entry for this page */
MiInitializePfn(PageFrameIndex, LimitPte, 1);
+ /* Setup the template stack PTE */
+ MI_MAKE_HARDWARE_PTE(&TempPte, LimitPte, MM_READWRITE, PageFrameIndex);
+
/* Write the valid PTE */
- TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
ASSERT(LimitPte->u.Hard.Valid == 0);
ASSERT(TempPte.u.Hard.Valid == 1);
*LimitPte-- = TempPte;