[NTOS:MM] Implement resolving PXE/PPE page table demand zero faults

This commit is contained in:
Timo Kreuzer 2017-12-27 17:18:00 +01:00
parent 2eff510074
commit d4765fe366

View file

@ -2025,43 +2025,67 @@ UserFault:
/* Lock the working set */ /* Lock the working set */
MiLockProcessWorkingSet(CurrentProcess, CurrentThread); MiLockProcessWorkingSet(CurrentProcess, CurrentThread);
ProtectionCode = MM_INVALID_PROTECTION;
#if (_MI_PAGING_LEVELS == 4) #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 */ /* Check if the PXE is valid */
if (PointerPxe->u.Hard.Valid == 0) if (PointerPxe->u.Hard.Valid == 0)
{ {
/* Right now, we only handle scenarios where the PXE is totally empty */ /* Right now, we only handle scenarios where the PXE is totally empty */
ASSERT(PointerPxe->u.Long == 0); 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 */ /* Resolve a demand zero fault */
Status = MiResolveDemandZeroFault(PointerPpe, MiResolveDemandZeroFault(PointerPpe,
PointerPxe, PointerPxe,
MM_READWRITE, MM_READWRITE,
CurrentProcess, CurrentProcess,
MM_NOIRQL); MM_NOIRQL);
#endif
/* We should come back with a valid PXE */ /* We should come back with a valid PXE */
ASSERT(PointerPxe->u.Hard.Valid == 1); ASSERT(PointerPxe->u.Hard.Valid == 1);
} }
#endif #endif
#if (_MI_PAGING_LEVELS >= 3) #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 */ /* Check if the PPE is valid */
if (PointerPpe->u.Hard.Valid == 0) if (PointerPpe->u.Hard.Valid == 0)
{ {
/* Right now, we only handle scenarios where the PPE is totally empty */ /* Right now, we only handle scenarios where the PPE is totally empty */
ASSERT(PointerPpe->u.Long == 0); 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 */ /* Resolve a demand zero fault */
Status = MiResolveDemandZeroFault(PointerPde, MiResolveDemandZeroFault(PointerPde,
PointerPpe, PointerPpe,
MM_READWRITE, MM_READWRITE,
CurrentProcess, CurrentProcess,
MM_NOIRQL); MM_NOIRQL);
#endif
/* We should come back with a valid PPE */ /* We should come back with a valid PPE */
ASSERT(PointerPpe->u.Hard.Valid == 1); ASSERT(PointerPpe->u.Hard.Valid == 1);
} }
@ -2077,7 +2101,12 @@ UserFault:
#if MI_TRACE_PFNS #if MI_TRACE_PFNS
UserPdeFault = TRUE; UserPdeFault = TRUE;
#endif #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 (ProtectionCode == MM_NOACCESS)
{ {
#if (_MI_PAGING_LEVELS == 2) #if (_MI_PAGING_LEVELS == 2)