https://git.reactos.org/?p=reactos.git;a=commitdiff;h=d4765fe3666e32cbf2536…
commit d4765fe3666e32cbf25363520e010421bd2ef307
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Wed Dec 27 17:18:00 2017 +0100
[NTOS:MM] Implement resolving PXE/PPE page table demand zero faults
---
ntoskrnl/mm/ARM3/pagfault.c | 67 ++++++++++++++++++++++++++++++++-------------
1 file changed, 48 insertions(+), 19 deletions(-)
diff --git a/ntoskrnl/mm/ARM3/pagfault.c b/ntoskrnl/mm/ARM3/pagfault.c
index f37fa458d2..69d70cc80b 100644
--- a/ntoskrnl/mm/ARM3/pagfault.c
+++ b/ntoskrnl/mm/ARM3/pagfault.c
@@ -2025,43 +2025,67 @@ UserFault:
/* Lock the working set */
MiLockProcessWorkingSet(CurrentProcess, CurrentThread);
+ ProtectionCode = MM_INVALID_PROTECTION;
+
#if (_MI_PAGING_LEVELS == 4)
-// Note to Timo: You should call MiCheckVirtualAddress and also check if it's zero pte
-// also this is missing the page count increment
/* Check if the PXE is valid */
if (PointerPxe->u.Hard.Valid == 0)
{
/* Right now, we only handle scenarios where the PXE is totally empty */
ASSERT(PointerPxe->u.Long == 0);
-#if 0
+
+ /* This is only possible for user mode addresses! */
+ ASSERT(PointerPte <= MiHighestUserPte);
+
+ /* Check if we have a VAD */
+ MiCheckVirtualAddress(Address, &ProtectionCode, &Vad);
+ if (ProtectionCode == MM_NOACCESS)
+ {
+ MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread);
+ return STATUS_ACCESS_VIOLATION;
+ }
+
/* Resolve a demand zero fault */
- Status = MiResolveDemandZeroFault(PointerPpe,
- PointerPxe,
- MM_READWRITE,
- CurrentProcess,
- MM_NOIRQL);
-#endif
+ MiResolveDemandZeroFault(PointerPpe,
+ PointerPxe,
+ MM_READWRITE,
+ CurrentProcess,
+ MM_NOIRQL);
+
/* We should come back with a valid PXE */
ASSERT(PointerPxe->u.Hard.Valid == 1);
}
#endif
#if (_MI_PAGING_LEVELS >= 3)
-// Note to Timo: You should call MiCheckVirtualAddress and also check if it's zero pte
-// also this is missing the page count increment
/* Check if the PPE is valid */
if (PointerPpe->u.Hard.Valid == 0)
{
/* Right now, we only handle scenarios where the PPE is totally empty */
ASSERT(PointerPpe->u.Long == 0);
-#if 0
+
+ /* This is only possible for user mode addresses! */
+ ASSERT(PointerPte <= MiHighestUserPte);
+
+ /* Check if we have a VAD, unless we did this already */
+ if (ProtectionCode == MM_INVALID_PROTECTION)
+ {
+ MiCheckVirtualAddress(Address, &ProtectionCode, &Vad);
+ }
+
+ if (ProtectionCode == MM_NOACCESS)
+ {
+ MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread);
+ return STATUS_ACCESS_VIOLATION;
+ }
+
/* Resolve a demand zero fault */
- Status = MiResolveDemandZeroFault(PointerPde,
- PointerPpe,
- MM_READWRITE,
- CurrentProcess,
- MM_NOIRQL);
-#endif
+ MiResolveDemandZeroFault(PointerPde,
+ PointerPpe,
+ MM_READWRITE,
+ CurrentProcess,
+ MM_NOIRQL);
+
/* We should come back with a valid PPE */
ASSERT(PointerPpe->u.Hard.Valid == 1);
}
@@ -2077,7 +2101,12 @@ UserFault:
#if MI_TRACE_PFNS
UserPdeFault = TRUE;
#endif
- MiCheckVirtualAddress(Address, &ProtectionCode, &Vad);
+ /* Check if we have a VAD, unless we did this already */
+ if (ProtectionCode == MM_INVALID_PROTECTION)
+ {
+ MiCheckVirtualAddress(Address, &ProtectionCode, &Vad);
+ }
+
if (ProtectionCode == MM_NOACCESS)
{
#if (_MI_PAGING_LEVELS == 2)
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2eff510074aec9c843e19…
commit 2eff510074aec9c843e196364f0f9b4bd7ce3d61
Author: Timo Kreuzer <timo.kreuzer(a)reactos.org>
AuthorDate: Wed Dec 27 15:09:39 2017 +0100
[NTOS:MM] Increment Prcb->MmDemandZeroCount while holding the Pfn lock
---
ntoskrnl/mm/ARM3/pagfault.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/ntoskrnl/mm/ARM3/pagfault.c b/ntoskrnl/mm/ARM3/pagfault.c
index b2dd08cdda..f37fa458d2 100644
--- a/ntoskrnl/mm/ARM3/pagfault.c
+++ b/ntoskrnl/mm/ARM3/pagfault.c
@@ -669,6 +669,9 @@ MiResolveDemandZeroFault(IN PVOID Address,
/* Initialize it */
MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
+ /* Increment demand zero faults */
+ KeGetCurrentPrcb()->MmDemandZeroCount++;
+
/* Do we have the lock? */
if (HaveLock)
{
@@ -679,9 +682,6 @@ MiResolveDemandZeroFault(IN PVOID Address,
if (Process > HYDRA_PROCESS) Process->NumberOfPrivatePages++;
}
- /* Increment demand zero faults */
- InterlockedIncrement(&KeGetCurrentPrcb()->MmDemandZeroCount);
-
/* Zero the page if need be */
if (NeedZero) MiZeroPfn(PageFrameNumber);
@@ -2297,14 +2297,14 @@ UserFault:
/* Initialize the PFN entry now */
MiInitializePfn(PageFrameIndex, PointerPte, 1);
- /* And we're done with the lock */
- MiReleasePfnLock(OldIrql);
-
/* Increment the count of pages in the process */
CurrentProcess->NumberOfPrivatePages++;
/* One more demand-zero fault */
- InterlockedIncrement(&KeGetCurrentPrcb()->MmDemandZeroCount);
+ KeGetCurrentPrcb()->MmDemandZeroCount++;
+
+ /* And we're done with the lock */
+ MiReleasePfnLock(OldIrql);
/* Fault on user PDE, or fault on user PTE? */
if (PointerPte <= MiHighestUserPte)