[NTOSKRNL]

Handle _MI_PAGING_LEVELS >= 3 in MiBuildPagedPool and MmArmAccessFault

svn path=/trunk/; revision=55433
This commit is contained in:
Timo Kreuzer 2012-02-05 17:19:58 +00:00
parent 66ef59c637
commit 53b6f45505
2 changed files with 64 additions and 40 deletions

View file

@ -1605,7 +1605,10 @@ MiBuildPagedPool(VOID)
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;
//
@ -1681,18 +1684,33 @@ MiBuildPagedPool(VOID)
MmPagedPoolEnd = (PVOID)(((ULONG_PTR)MmPagedPoolStart +
MmSizeOfPagedPoolInBytes) - 1);
//
// Lock the PFN database
//
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
#if (_MI_PAGING_LEVELS >= 3)
/* 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 */
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);
#if (_MI_PAGING_LEVELS >= 3)
/* On these systems, there's no double-mapping, so instead, the PPE and PXEs
* are setup to span the entire paged pool area, so there's no need for the
* system PD */
ASSERT(FALSE);
#endif
RtlZeroMemory(PointerPde,
(1 + MiAddressToPde(MmPagedPoolEnd) - PointerPde) * sizeof(MMPDE));
@ -1703,11 +1721,6 @@ MiBuildPagedPool(VOID)
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);
MI_SET_PROCESS2("Kernel");
@ -1717,7 +1730,11 @@ MiBuildPagedPool(VOID)
#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]

View file

@ -637,8 +637,15 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
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 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
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
DPRINT("ARM3 FAULT AT: %p\n", Address);
//
// Check for dispatch-level snafu
@ -675,7 +673,7 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
}
//
// Check for kernel fault
// Check for kernel fault address
//
while (Address >= MmSystemRangeStart)
{
@ -685,8 +683,18 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
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,18 +879,21 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
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);
if (PointerPde->u.Hard.Valid == 0)
@ -916,10 +927,6 @@ MmArmAccessFault(IN BOOLEAN StoreInstruction,
#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);
}