Author: tkreuzer
Date: Mon Feb 6 10:46:52 2012
New Revision: 55456
URL:
http://svn.reactos.org/svn/reactos?rev=55456&view=rev
Log:
[NTOSKRNL]
- Implement MiSynchronizeSystemPde, which does what its name suggests, synchronize a
system PDE and is an improved replacement (with a more proper name) for
MiCheckPdeForPagedPool
- Move some code to avoid an additional check
- Call MiResolveDemandZeroFault directy instead of creating a demand zero PDE and then
calling MiDispatchFault, which after a lot of checks will finally do the same
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
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 Feb 6 10:46:52 2012
@@ -100,6 +100,28 @@
}
}
+#if (_MI_PAGING_LEVELS == 2)
+BOOLEAN
+FORCEINLINE
+MiSynchronizeSystemPde(PMMPDE PointerPde)
+{
+ MMPDE SystemPde;
+ ULONG Index;
+
+ /* Get the Index from the PDE */
+ Index = ((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE);
+
+ /* Copy the PDE from the double-mapped system page directory */
+ SystemPde = MmSystemPagePtes[Index];
+ *PointerPde = SystemPde;
+
+ /* Make sure we re-read the PDE and PTE */
+ KeMemoryBarrierWithoutFence();
+
+ /* Return, if we had success */
+ return (BOOLEAN)SystemPde.u.Hard.Valid;
+}
+
NTSTATUS
FASTCALL
MiCheckPdeForPagedPool(IN PVOID Address)
@@ -159,6 +181,7 @@
//
return Status;
}
+#endif
VOID
NTAPI
@@ -699,28 +722,12 @@
/* Check if the PDE is invalid */
if (PointerPde->u.Hard.Valid == 0)
{
- //
- // Debug spew (eww!)
- //
- DPRINT("Invalid PDE\n");
#if (_MI_PAGING_LEVELS == 2)
- //
- // Handle mapping in "Special" PDE directoreis
- //
- MiCheckPdeForPagedPool(Address);
-#endif
- //
- // Now we SHOULD be good
- //
- if (PointerPde->u.Hard.Valid == 0)
+ /* Sync this PDE and check, if that made it valid */
+ if (!MiSynchronizeSystemPde(PointerPde))
+#endif
{
- //
- // FIXFIX: Do the S-LIST hack
- //
-
- //
- // Kill the system
- //
+ /* PDE (still) not valid, kill the system */
KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA,
(ULONG_PTR)Address,
StoreInstruction,
@@ -824,20 +831,20 @@
(ULONG_PTR)TrapInformation,
1);
}
- }
-
- /* Check for demand page */
- if ((StoreInstruction) && !(ProtoPte) &&
!(TempPte.u.Hard.Valid))
- {
- /* Get the protection code */
- if (!(TempPte.u.Soft.Protection & MM_READWRITE))
+
+ /* Check for demand page */
+ if ((StoreInstruction) && !(TempPte.u.Hard.Valid))
{
- /* Bad boy, bad boy, whatcha gonna do, whatcha gonna do when ARM3 comes
for you! */
- KeBugCheckEx(ATTEMPTED_WRITE_TO_READONLY_MEMORY,
- (ULONG_PTR)Address,
- TempPte.u.Long,
- (ULONG_PTR)TrapInformation,
- 14);
+ /* Get the protection code */
+ if (!(TempPte.u.Soft.Protection & MM_READWRITE))
+ {
+ /* Bugcheck the system! */
+ KeBugCheckEx(ATTEMPTED_WRITE_TO_READONLY_MEMORY,
+ (ULONG_PTR)Address,
+ TempPte.u.Long,
+ (ULONG_PTR)TrapInformation,
+ 14);
+ }
}
}
@@ -889,21 +896,15 @@
/* Right now, we expect a valid protection mask on the VAD */
ASSERT(ProtectionCode != MM_NOACCESS);
- /* Make the PDE demand-zero */
- MI_WRITE_INVALID_PDE(PointerPde, DemandZeroPde);
-
/* And go dispatch the fault on the PDE. This should handle the demand-zero */
#if MI_TRACE_PFNS
UserPdeFault = TRUE;
#endif
- Status = MiDispatchFault(TRUE,
- PointerPte,
- (PMMPTE)PointerPde,
- NULL,
- FALSE,
- PsGetCurrentProcess(),
- TrapInformation,
- NULL);
+ /* Resolve a demand zero fault */
+ Status = MiResolveDemandZeroFault(PointerPte,
+ MM_READWRITE,
+ CurrentProcess,
+ MM_NOIRQL);
#if MI_TRACE_PFNS
UserPdeFault = FALSE;
#endif
@@ -930,15 +931,14 @@
return STATUS_PAGE_FAULT_DEMAND_ZERO;
}
- /* Get protection and check if it's a prototype PTE */
- ProtectionCode = (ULONG)TempPte.u.Soft.Protection;
+ /* Make sure it's not a prototype PTE */
ASSERT(TempPte.u.Soft.Prototype == 0);
/* Check for non-demand zero PTE */
if (TempPte.u.Long != 0)
{
/* This is a page fault, check for valid protection */
- ASSERT(ProtectionCode != 0x100);
+ ASSERT(TempPte.u.Soft.Protection != 0x100);
/* FIXME: Run MiAccessCheck */