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?r... ============================================================================== --- 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.c... ============================================================================== --- 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); }