Author: tkreuzer
Date: Sun Feb 5 17:19:58 2012
New Revision: 55433
URL:
http://svn.reactos.org/svn/reactos?rev=55433&view=rev
Log:
[NTOSKRNL]
Handle _MI_PAGING_LEVELS >= 3 in MiBuildPagedPool and MmArmAccessFault
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/mminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/mminit.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/mminit.c [iso-8859-1] Sun Feb 5 17:19:58 2012
@@ -1605,7 +1605,10 @@
KIRQL OldIrql;
SIZE_T Size;
ULONG BitMapSize;
-#if (_MI_PAGING_LEVELS == 2)
+#if (_MI_PAGING_LEVELS >= 3)
+ MMPPE TempPpe = ValidKernelPpe;
+ PMMPPE PointerPpe;
+#elif (_MI_PAGING_LEVELS == 2)
MMPTE TempPte = ValidKernelPte;
//
@@ -1682,17 +1685,32 @@
MmSizeOfPagedPoolInBytes) - 1);
//
- // So now get the PDE for paged pool and zero it out
- //
- PointerPde = MiAddressToPde(MmPagedPoolStart);
+ // Lock the PFN database
+ //
+ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
#if (_MI_PAGING_LEVELS >= 3)
- /* On these systems, there's no double-mapping, so instead, the PPE and PXEs
+ /* On these systems, there's no double-mapping, so instead, the PPEs
* are setup to span the entire paged pool area, so there's no need for the
* system PD */
- ASSERT(FALSE);
+ for (PointerPpe = MiAddressToPpe(MmPagedPoolStart);
+ PointerPpe <= MiAddressToPpe(MmPagedPoolEnd);
+ PointerPpe++)
+ {
+ /* Check if the PPE is already valid */
+ if (!PointerPpe->u.Hard.Valid)
+ {
+ /* It is not, so map a fresh zeroed page */
+ TempPpe.u.Hard.PageFrameNumber = MiRemoveZeroPage(0);
+ MI_WRITE_VALID_PPE(PointerPpe, TempPpe);
+ }
+ }
#endif
+ //
+ // So now get the PDE for paged pool and zero it out
+ //
+ PointerPde = MiAddressToPde(MmPagedPoolStart);
RtlZeroMemory(PointerPde,
(1 + MiAddressToPde(MmPagedPoolEnd) - PointerPde) * sizeof(MMPDE));
@@ -1702,11 +1720,6 @@
PointerPte = MiAddressToPte(MmPagedPoolStart);
MmPagedPoolInfo.FirstPteForPagedPool = PointerPte;
MmPagedPoolInfo.LastPteForPagedPool = MiAddressToPte(MmPagedPoolEnd);
-
- //
- // Lock the PFN database
- //
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Allocate a page and map the first paged pool PDE */
MI_SET_USAGE(MI_USAGE_PAGED_POOL);
@@ -1717,7 +1730,11 @@
#if (_MI_PAGING_LEVELS >= 3)
/* Use the PPE of MmPagedPoolStart that was setup above */
// Bla = PFN_FROM_PTE(PpeAddress(MmPagedPool...));
- ASSERT(FALSE);
+
+ /* Initialize the PFN entry for it */
+ MiInitializePfnForOtherProcess(PageFrameIndex,
+ (PMMPTE)PointerPde,
+ PFN_FROM_PTE(MiAddressToPpe(MmPagedPoolStart)));
#else
/* Do it this way */
// Bla = MmSystemPageDirectory[(PointerPde - (PMMPTE)PDE_BASE) / PDE_COUNT]
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] Sun Feb 5 17:19:58 2012
@@ -637,8 +637,15 @@
IN PVOID TrapInformation)
{
KIRQL OldIrql = KeGetCurrentIrql(), LockIrql;
- PMMPTE PointerPte, ProtoPte = NULL;
- PMMPDE PointerPde;
+ PMMPTE ProtoPte = NULL;
+ PMMPTE PointerPte = MiAddressToPte(Address);
+ PMMPDE PointerPde = MiAddressToPde(Address);
+#if (_MI_PAGING_LEVELS >= 3)
+ PMMPDE PointerPpe = MiAddressToPpe(Address);
+#if (_MI_PAGING_LEVELS == 4)
+ PMMPDE PointerPxe = MiAddressToPxe(Address);
+#endif
+#endif
MMPTE TempPte;
PETHREAD CurrentThread;
PEPROCESS CurrentProcess;
@@ -648,17 +655,8 @@
PMMVAD Vad;
PFN_NUMBER PageFrameIndex;
ULONG Color;
+
DPRINT("ARM3 FAULT AT: %p\n", Address);
-
- //
- // Get the PTE and PDE
- //
- PointerPte = MiAddressToPte(Address);
- PointerPde = MiAddressToPde(Address);
-#if (_MI_PAGING_LEVELS >= 3)
- /* We need the PPE and PXE addresses */
- ASSERT(FALSE);
-#endif
//
// Check for dispatch-level snafu
@@ -675,7 +673,7 @@
}
//
- // Check for kernel fault
+ // Check for kernel fault address
//
while (Address >= MmSystemRangeStart)
{
@@ -685,8 +683,18 @@
if (Mode == UserMode) return STATUS_ACCESS_VIOLATION;
#if (_MI_PAGING_LEVELS >= 3)
- /* Need to check PXE and PDE validity */
- ASSERT(FALSE);
+ if (
+#if (_MI_PAGING_LEVELS == 4)
+ (PointerPxe->u.Hard.Valid == 0) ||
+#endif
+ (PointerPpe->u.Hard.Valid == 0))
+ {
+ KeBugCheckEx(PAGE_FAULT_IN_NONPAGED_AREA,
+ (ULONG_PTR)Address,
+ StoreInstruction,
+ (ULONG_PTR)TrapInformation,
+ 2);
+ }
#endif
//
@@ -871,17 +879,20 @@
return Status;
}
- /* This is a user fault */
+#if (_MI_PAGING_LEVELS == 4)
+ /* On these systems we have PXEs and PPEs ready for everything we need */
+ if (PointerPxe->u.Hard.Valid == 0) return STATUS_ACCESS_VIOLATION;
+#endif
+#if (_MI_PAGING_LEVELS >= 3)
+ if (PointerPpe->u.Hard.Valid == 0) return STATUS_ACCESS_VIOLATION;
+#endif
+
+ /* This is a user fault (<- And this is a lie!) */
CurrentThread = PsGetCurrentThread();
CurrentProcess = PsGetCurrentProcess();
/* Lock the working set */
MiLockProcessWorkingSet(CurrentProcess, CurrentThread);
-
-#if (_MI_PAGING_LEVELS >= 3)
- /* Need to check/handle PPE and PXE validity too */
- ASSERT(FALSE);
-#endif
/* First things first, is the PDE valid? */
ASSERT(PointerPde->u.Hard.LargePage == 0);
@@ -916,10 +927,6 @@
#endif
/* We should come back with APCs enabled, and with a valid PDE */
ASSERT(KeAreAllApcsDisabled() == TRUE);
-#if (_MI_PAGING_LEVELS >= 3)
- /* Need to check/handle PPE and PXE validity too */
- ASSERT(FALSE);
-#endif
ASSERT(PointerPde->u.Hard.Valid == 1);
}