Author: sir_richard
Date: Fri Jun 4 19:49:36 2010
New Revision: 47571
URL: http://svn.reactos.org/svn/reactos?rev=47571&view=rev
Log:
Testers: Please test this build.
[NTOS]: Implement a MI_MAKE_HARDWARE_PTE macro for the generation of valid kernel PTEs instead of always taking the ValidKernelPte and changing its flags. This macro will take into account the protection mask (up until now ignored) and use the array previously implemented to determine the correct hardware PTE settings. Assertions are also added to validate correct usage of the macro, and later revisions will fill out NT-specific fields to help deal with transition PTEs, page faults, etc.
[NTOS]: Make the stack code the first user of this macro, for the stack PTEs. Good testing base as we create kernel stacks very often.
[NTOS]: The NT MM ABI specifies that in between the allocation of a new PTE and its initialization as a valid PFN, the PTE entry should be an invalid PTE, and should only be marked valid after the PFN has been initialized. For stack PTEs, do this -- first allocating the page, making it invalid, then initializing the PFN, and then writing the valid page.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?r…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Fri Jun 4 19:49:36 2010
@@ -446,6 +446,29 @@
#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?
//
Modified: trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/procsup.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] Fri Jun 4 19:49:36 2010
@@ -107,7 +107,7 @@
PFN_NUMBER StackPtes, StackPages;
PMMPTE PointerPte, StackPte;
PVOID BaseAddress;
- MMPTE TempPte;
+ MMPTE TempPte, InvalidPte;
KIRQL OldIrql;
PFN_NUMBER PageFrameIndex;
ULONG i;
@@ -151,13 +151,12 @@
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
@@ -174,8 +173,10 @@
//
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);
@@ -210,7 +211,7 @@
PMMPTE LimitPte, NewLimitPte, LastPte;
PFN_NUMBER StackPages;
KIRQL OldIrql;
- MMPTE TempPte;
+ MMPTE TempPte, InvalidPte;
PFN_NUMBER PageFrameIndex;
//
@@ -251,13 +252,8 @@
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
@@ -269,14 +265,18 @@
//
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;