Author: ion
Date: Mon Sep 3 16:29:31 2012
New Revision: 57229
URL:
http://svn.reactos.org/svn/reactos?rev=57229&view=rev
Log:
[NTOSKRNL]: Fix a stupid bug in MiProtectVirtualMemory which was causing empty PTEs whose
protection was being set to remain zero PTEs, instead of demand-zero PTEs, but still
acquire a page table reference. When they were later touched in the page fault code, and
made into demand-zero PTEs, they'd get referenced again, thus Aleksey hacked away all
the referencing code to work around this (causing PDEs to disappear...)
[NTOSKRNL]: Restore the page table reference counting mechanism, and put it in a macro to
be cleaner. Also use macros for testing PD boundaries, instead of math-by-hand.
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
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] Mon Sep 3 16:29:31 2012
@@ -1619,6 +1619,41 @@
}
}
+FORCEINLINE
+VOID
+MiIncrementPageTableReferences(IN PVOID Address)
+{
+ PUSHORT RefCount;
+
+ RefCount = &MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)];
+
+ *RefCount += 1;
+ ASSERT(*RefCount <= PTE_PER_PAGE);
+}
+
+FORCEINLINE
+VOID
+MiDecrementPageTableReferences(IN PVOID Address)
+{
+ PUSHORT RefCount;
+
+ RefCount = &MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)];
+
+ *RefCount -= 1;
+ ASSERT(*RefCount < PTE_PER_PAGE);
+}
+
+FORCEINLINE
+USHORT
+MiQueryPageTableReferences(IN PVOID Address)
+{
+ PUSHORT RefCount;
+
+ RefCount = &MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)];
+
+ return *RefCount;
+}
+
BOOLEAN
NTAPI
MmArmInitSystem(
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] Mon Sep 3 16:29:31 2012
@@ -1684,8 +1684,7 @@
if (Address <= MM_HIGHEST_USER_ADDRESS)
{
/* Add an additional page table reference */
- MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
- ASSERT(MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]
<= PTE_COUNT);
+ MiIncrementPageTableReferences(Address);
}
/* Did we get a prototype PTE back? */
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] Mon Sep 3 16:29:31 2012
@@ -1821,7 +1821,6 @@
PMMPDE PointerPde;
PMMPFN Pfn1;
ULONG ProtectionMask, QuotaCharge = 0;
- PUSHORT UsedPageTableEntries;
PETHREAD Thread = PsGetCurrentThread();
PAGED_CODE();
@@ -1914,9 +1913,7 @@
// This used to be a zero PTE and it no longer is, so we must add a
// reference to the pagetable.
//
- UsedPageTableEntries =
&MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(MiPteToAddress(PointerPte))];
- (*UsedPageTableEntries)++;
- ASSERT((*UsedPageTableEntries) <= PTE_COUNT);
+ MiIncrementPageTableReferences(MiPteToAddress(PointerPte));
//
// Create the demand-zero prototype PTE
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] Mon Sep 3 16:29:31 2012
@@ -589,10 +589,8 @@
TempPte = *PointerPte;
if (TempPte.u.Long)
{
- DPRINT("Decrement used PTEs by address: %lx\n", Va);
- (*UsedPageTableEntries)--;
+ *UsedPageTableEntries -= 1;
ASSERT((*UsedPageTableEntries) < PTE_COUNT);
- DPRINT("Refs: %lx\n", (*UsedPageTableEntries));
/* Check if the PTE is actually mapped in */
if (TempPte.u.Long & 0xFFFFFC01)
@@ -653,14 +651,10 @@
/* The PDE should still be valid at this point */
ASSERT(PointerPde->u.Hard.Valid == 1);
- DPRINT("Should check if handles for: %p are zero (PDE: %lx)\n", Va,
PointerPde->u.Hard.PageFrameNumber);
- if (!(*UsedPageTableEntries))
- {
- DPRINT("They are!\n");
+ if (*UsedPageTableEntries == 0)
+ {
if (PointerPde->u.Long != 0)
{
- DPRINT("PDE active: %lx in %16s\n",
PointerPde->u.Hard.PageFrameNumber, CurrentProcess->ImageFileName);
-
/* Delete the PTE proper */
MiDeletePte(PointerPde,
MiPteToAddress(PointerPde),
@@ -1880,7 +1874,6 @@
ULONG_PTR StartingAddress, EndingAddress;
PMMPTE PointerPde, PointerPte, LastPte;
MMPTE PteContents;
- //PUSHORT UsedPageTableEntries;
PMMPFN Pfn1;
ULONG ProtectionMask, OldProtect;
BOOLEAN Committed;
@@ -2050,24 +2043,23 @@
while (PointerPte <= LastPte)
{
/* Check if we've crossed a PDE boundary and make the new PDE valid too
*/
- if ((((ULONG_PTR)PointerPte) & (SYSTEM_PD_SIZE - 1)) == 0)
+ if (MiIsPteOnPdeBoundary(PointerPte))
{
PointerPde = MiAddressToPte(PointerPte);
MiMakePdeExistAndMakeValid(PointerPde, Process, MM_NOIRQL);
}
- /* Capture the PTE and see what we're dealing with */
+ /* Capture the PTE and check if it was empty */
PteContents = *PointerPte;
if (PteContents.u.Long == 0)
{
/* This used to be a zero PTE and it no longer is, so we must add a
reference to the pagetable. */
- //UsedPageTableEntries =
&MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(MiPteToAddress(PointerPte))];
- //(*UsedPageTableEntries)++;
- //ASSERT((*UsedPageTableEntries) <= PTE_COUNT);
- DPRINT1("HACK: Not increasing UsedPageTableEntries count!\n");
- }
- else if (PteContents.u.Hard.Valid == 1)
+ MiIncrementPageTableReferences(MiPteToAddress(PointerPte));
+ }
+
+ /* Check what kind of PTE we are dealing with */
+ if (PteContents.u.Hard.Valid == 1)
{
/* Get the PFN entry */
Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(&PteContents));
@@ -2080,8 +2072,11 @@
(NewAccessProtection & PAGE_GUARD))
{
/* The page should be in the WS and we should make it transition now
*/
- UNIMPLEMENTED;
- //continue;
+ DPRINT1("Making valid page invalid is not yet
supported!\n");
+ Status = STATUS_NOT_IMPLEMENTED;
+ /* Unlock the working set */
+ MiUnlockProcessWorkingSetUnsafe(Process, Thread);
+ goto FailPath;
}
/* Write the protection mask and write it with a TLB flush */
@@ -2270,7 +2265,6 @@
ULONG PteCount = 0;
PMMPFN Pfn1;
MMPTE PteContents;
- PUSHORT UsedPageTableEntries;
PETHREAD CurrentThread = PsGetCurrentThread();
//
@@ -2292,7 +2286,7 @@
//
// Check if we've crossed a PDE boundary
//
- if ((((ULONG_PTR)PointerPte) & (SYSTEM_PD_SIZE - 1)) == 0)
+ if (MiIsPteOnPdeBoundary(PointerPte))
{
//
// Get the new PDE and flush the valid PTEs we had built up until
@@ -2383,9 +2377,7 @@
// This used to be a zero PTE and it no longer is, so we must add a
// reference to the pagetable.
//
- UsedPageTableEntries =
&MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(StartingAddress)];
- (*UsedPageTableEntries)++;
- ASSERT((*UsedPageTableEntries) <= PTE_COUNT);
+ MiIncrementPageTableReferences(StartingAddress);
//
// Next, we account for decommitted PTEs and make the PTE as such
@@ -3648,7 +3640,6 @@
PMEMORY_AREA MemoryArea;
PFN_NUMBER PageCount;
PMMVAD Vad, FoundVad;
- PUSHORT UsedPageTableEntries;
NTSTATUS Status;
PMMSUPPORT AddressSpace;
PVOID PBaseAddress;
@@ -4268,7 +4259,7 @@
//
// Have we crossed into a new page table?
//
- if (!(((ULONG_PTR)PointerPte) & (SYSTEM_PD_SIZE - 1)))
+ if (MiIsPteOnPdeBoundary(PointerPte))
{
//
// Get the PDE and now make it valid too
@@ -4286,9 +4277,7 @@
// First increment the count of pages in the page table for this
// process
//
- UsedPageTableEntries =
&MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(MiPteToAddress(PointerPte))];
- (*UsedPageTableEntries)++;
- ASSERT((*UsedPageTableEntries) <= PTE_COUNT);
+ MiIncrementPageTableReferences(MiPteToAddress(PointerPte));
//
// And now write the invalid demand-zero PTE as requested