Author: tkreuzer
Date: Wed Nov 27 00:04:26 2013
New Revision: 61110
URL:
http://svn.reactos.org/svn/reactos?rev=61110&view=rev
Log:
[NTOSKRNL]
- Get rid of MmZeroPte and instead implement MI_ERASE_PTE. Use this and only this to make
a PTE zero. The other functions will not allow to do this.
- Add MI_UPDATE_VALID_PTE to update a valid PTE with another valid PTE
- Add 2 additional protection mask constants: MM_PROTECT_ACCESS for the lower 3 bits and
MM_PROTECT_SPECIAL for the higher 2 bits. Make use of the latter when dealing with guard
pages and caching.
- Deduplicate some code in MmArmAccessFault
- Move code in MiDeleteSystemPageableVm to where it belongs (it was in the wrong else
case!)
- Wse MiQueryPageTableReferences instead of manipulating
MmWorkingSetList->UsedPageTableEntries
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/miarm.h
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
trunk/reactos/ntoskrnl/mm/ARM3/section.c
trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
trunk/reactos/ntoskrnl/mm/balance.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] Wed Nov 27 00:04:26 2013
@@ -107,6 +107,7 @@
#define MM_WRITECOPY 5
#define MM_EXECUTE_READWRITE 6
#define MM_EXECUTE_WRITECOPY 7
+#define MM_PROTECT_ACCESS 7
//
// These are flags on top of the actual protection mask
@@ -114,6 +115,7 @@
#define MM_NOCACHE 0x08
#define MM_GUARDPAGE 0x10
#define MM_WRITECOMBINE 0x18
+#define MM_PROTECT_SPECIAL 0x18
//
// These are special cases
@@ -588,7 +590,6 @@
LONG ImageLoadingCount;
} MM_SESSION_SPACE, *PMM_SESSION_SPACE;
-static const MMPTE MmZeroPte = {{0}};
extern PMM_SESSION_SPACE MmSessionSpace;
extern MMPTE HyperTemplatePte;
extern MMPDE ValidKernelPde;
@@ -1003,6 +1004,21 @@
}
//
+// Updates a valid PTE
+//
+VOID
+FORCEINLINE
+MI_UPDATE_VALID_PTE(IN PMMPTE PointerPte,
+ IN MMPTE TempPte)
+{
+ /* Write the valid PTE */
+ ASSERT(PointerPte->u.Hard.Valid == 1);
+ ASSERT(TempPte.u.Hard.Valid == 1);
+ ASSERT(PointerPte->u.Hard.PageFrameNumber == TempPte.u.Hard.PageFrameNumber);
+ *PointerPte = TempPte;
+}
+
+//
// Writes an invalid PTE
//
FORCEINLINE
@@ -1012,7 +1028,20 @@
{
/* Write the invalid PTE */
ASSERT(InvalidPte.u.Hard.Valid == 0);
+ ASSERT(InvalidPte.u.Long != 0);
*PointerPte = InvalidPte;
+}
+
+//
+// Erase the PTE completely
+//
+VOID
+FORCEINLINE
+MI_ERASE_PTE(IN PMMPTE PointerPte)
+{
+ /* Zero out the PTE */
+ ASSERT(PointerPte->u.Long != 0);
+ PointerPte->u.Long = 0;
}
//
@@ -1039,6 +1068,7 @@
{
/* Write the invalid PDE */
ASSERT(InvalidPde.u.Hard.Valid == 0);
+ ASSERT(InvalidPde.u.Long != 0);
*PointerPde = InvalidPde;
}
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Wed Nov 27 00:04:26 2013
@@ -122,7 +122,7 @@
#define _BYTE_MASK(Bit0, Bit1, Bit2, Bit3, Bit4, Bit5, Bit6, Bit7) \
(Bit0) | ((Bit1) << 1) | ((Bit2) << 2) | ((Bit3) << 3) | \
((Bit4) << 4) | ((Bit5) << 5) | ((Bit6) << 6) | ((Bit7)
<< 7)
- static const UCHAR MiAccessAllowedMask[2][2] =
+ static const UCHAR AccessAllowedMask[2][2] =
{
{ // Protect 0 1 2 3 4 5 6 7
_BYTE_MASK(0, 1, 1, 1, 1, 1, 1, 1), // READ
@@ -134,11 +134,11 @@
}
};
- /* We want only the low 3 bits */
- ProtectionMask &= 7;
+ /* We want only the lower access bits */
+ ProtectionMask &= MM_PROTECT_ACCESS;
/* Look it up in the table */
- return (MiAccessAllowedMask[Write != 0][Execute != 0] >> ProtectionMask) &
1;
+ return (AccessAllowedMask[Write != 0][Execute != 0] >> ProtectionMask) &
1;
}
NTSTATUS
@@ -187,7 +187,7 @@
}
/* Check if this is a guard page */
- if (ProtectionMask & MM_GUARDPAGE)
+ if ((ProtectionMask & MM_PROTECT_SPECIAL) == MM_GUARDPAGE)
{
NT_ASSERT(ProtectionMask != MM_DECOMMIT);
@@ -765,8 +765,8 @@
/* Release the PFN lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
- /* Remove caching bits */
- Protection &= ~(MM_NOCACHE | MM_NOACCESS);
+ /* Remove special/caching bits */
+ Protection &= ~MM_PROTECT_SPECIAL;
/* Setup caching */
if (Pfn1->u3.e1.CacheAttribute == MiWriteCombined)
@@ -820,7 +820,8 @@
PMMPFN Pfn1;
MMPTE TempPte;
PMMPTE PointerToPteForProtoPage;
- DPRINT1("Transition fault on 0x%p with PTE 0x%p in process %s\n",
FaultingAddress, PointerPte, CurrentProcess->ImageFileName);
+ DPRINT1("Transition fault on 0x%p with PTE 0x%p in process %s\n",
+ FaultingAddress, PointerPte, CurrentProcess->ImageFileName);
/* Windowss does this check */
ASSERT(*InPageBlock == NULL);
@@ -1453,37 +1454,25 @@
/* Bail out, if the fault came from user mode */
if (Mode == UserMode) return STATUS_ACCESS_VIOLATION;
-#if (_MI_PAGING_LEVELS == 4)
- /* AMD64 system, check if PXE is invalid */
- if (PointerPxe->u.Hard.Valid == 0)
- {
- KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA,
- (ULONG_PTR)Address,
- StoreInstruction,
- (ULONG_PTR)TrapInformation,
- 7);
- }
-#endif
-#if (_MI_PAGING_LEVELS == 4)
- /* PAE/AMD64 system, check if PPE is invalid */
- if (PointerPpe->u.Hard.Valid == 0)
- {
- KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA,
- (ULONG_PTR)Address,
- StoreInstruction,
- (ULONG_PTR)TrapInformation,
- 5);
- }
-#endif
#if (_MI_PAGING_LEVELS == 2)
if (MI_IS_SYSTEM_PAGE_TABLE_ADDRESS(Address))
MiSynchronizeSystemPde((PMMPDE)PointerPte);
MiCheckPdeForPagedPool(Address);
#endif
- /* Check if the PDE is invalid */
- if (PointerPde->u.Hard.Valid == 0)
- {
- /* PDE (still) not valid, kill the system */
+ /* Check if the higher page table entries are invalid */
+ if (
+#if (_MI_PAGING_LEVELS == 4)
+ /* AMD64 system, check if PXE is invalid */
+ (PointerPxe->u.Hard.Valid == 0) ||
+#endif
+#if (_MI_PAGING_LEVELS >= 3)
+ /* PAE/AMD64 system, check if PPE is invalid */
+ (PointerPpe->u.Hard.Valid == 0) ||
+#endif
+ /* Always check if the PDE is valid */
+ (PointerPde->u.Hard.Valid == 0))
+ {
+ /* PXE/PPE/PDE (still) not valid, kill the system */
KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA,
(ULONG_PTR)Address,
StoreInstruction,
@@ -1894,7 +1883,7 @@
}
/* Is this a guard page? */
- if (ProtectionCode & MM_GUARDPAGE)
+ if ((ProtectionCode & MM_PROTECT_SPECIAL) == MM_GUARDPAGE)
{
/* The VAD protection cannot be MM_DECOMMIT! */
NT_ASSERT(ProtectionCode != MM_DECOMMIT);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/section.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/section.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] Wed Nov 27 00:04:26 2013
@@ -198,7 +198,7 @@
}
/* This actually turns on guard page in this scenario! */
- ProtectMask |= MM_GUARDPAGE;
+ ProtectMask |= MM_DECOMMIT;
}
/* Check for nocache option */
@@ -1914,10 +1914,7 @@
//
// Write the new PTE, making sure we are only changing the bits
//
- ASSERT(PointerPte->u.Hard.Valid == 1);
- ASSERT(TempPte.u.Hard.Valid == 1);
- ASSERT(PointerPte->u.Hard.PageFrameNumber == TempPte.u.Hard.PageFrameNumber);
- *PointerPte = TempPte;
+ MI_UPDATE_VALID_PTE(PointerPte, TempPte);
//
// Flush the TLB
Modified: trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/virtual.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] Wed Nov 27 00:04:26 2013
@@ -350,25 +350,25 @@
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
/* Destroy the PTE */
- MI_WRITE_INVALID_PTE(PointerPte, MmZeroPte);
+ MI_ERASE_PTE(PointerPte);
+ }
+ else
+ {
+ /*
+ * The only other ARM3 possibility is a demand zero page, which would
+ * mean freeing some of the paged pool pages that haven't even been
+ * touched yet, as part of a larger allocation.
+ *
+ * Right now, we shouldn't expect any page file information in the
PTE
+ */
+ ASSERT(PointerPte->u.Soft.PageFileHigh == 0);
+
+ /* Destroy the PTE */
+ MI_ERASE_PTE(PointerPte);
}
/* Actual legitimate pages */
ActualPages++;
- }
- else
- {
- /*
- * The only other ARM3 possibility is a demand zero page, which would
- * mean freeing some of the paged pool pages that haven't even been
- * touched yet, as part of a larger allocation.
- *
- * Right now, we shouldn't expect any page file information in the PTE
- */
- ASSERT(PointerPte->u.Soft.PageFileHigh == 0);
-
- /* Destroy the PTE */
- MI_WRITE_INVALID_PTE(PointerPte, MmZeroPte);
}
/* Keep going */
@@ -486,7 +486,7 @@
}
/* Destroy the PTE and flush the TLB */
- MI_WRITE_INVALID_PTE(PointerPte, MmZeroPte);
+ MI_ERASE_PTE(PointerPte);
KeFlushCurrentTb();
}
@@ -618,7 +618,7 @@
(TempPte.u.Soft.Prototype == 1))
{
/* Just nuke it */
- MI_WRITE_INVALID_PTE(PointerPte, MmZeroPte);
+ MI_ERASE_PTE(PointerPte);
}
else
{
@@ -632,7 +632,7 @@
else
{
/* The PTE was never mapped, just nuke it here */
- MI_WRITE_INVALID_PTE(PointerPte, MmZeroPte);
+ MI_ERASE_PTE(PointerPte);
}
}
Modified: trunk/reactos/ntoskrnl/mm/balance.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/balance.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/balance.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/balance.c [iso-8859-1] Wed Nov 27 00:04:26 2013
@@ -394,7 +394,7 @@
Address < (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS;
Address += (PAGE_SIZE * PTE_COUNT))
{
- if (MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] ==
0)
+ if (MiQueryPageTableReferences((PVOID)Address) == 0)
{
pointerPde = MiAddressToPde(Address);
if (pointerPde->u.Hard.Valid)