[NTOS:MM] Make MiCalculatePageCommitment 64-bits aware

This commit is contained in:
Jérôme Gardou 2021-05-25 16:08:25 +02:00 committed by Jérôme Gardou
parent b48e27ada1
commit a80ae8f2ea

View file

@ -46,157 +46,135 @@ MiCalculatePageCommitment(IN ULONG_PTR StartingAddress,
{ {
PMMPTE PointerPte, LastPte; PMMPTE PointerPte, LastPte;
PMMPDE PointerPde; PMMPDE PointerPde;
ULONG CommittedPages; BOOLEAN OnPdeBoundary = TRUE;
#if _MI_PAGING_LEVELS >= 3
PMMPPE PointerPpe;
BOOLEAN OnPpeBoundary = TRUE;
#if _MI_PAGING_LEVELS == 4
PMMPXE PointerPxe;
BOOLEAN OnPxeBoundary = TRUE;
#endif
#endif
/* Compute starting and ending PTE and PDE addresses */ /* Make sure this all makes sense */
PointerPde = MiAddressToPde(StartingAddress); ASSERT(PsGetCurrentThread()->OwnsProcessWorkingSetExclusive || PsGetCurrentThread()->OwnsProcessWorkingSetShared);
ASSERT(EndingAddress >= StartingAddress);
PointerPte = MiAddressToPte(StartingAddress); PointerPte = MiAddressToPte(StartingAddress);
LastPte = MiAddressToPte(EndingAddress); LastPte = MiAddressToPte(EndingAddress);
/* Handle commited pages first */ /*
if (Vad->u.VadFlags.MemCommit == 1) * In case this is a committed VAD, assume the whole range is committed
{ * and count the individually decommitted pages.
/* This is a committed VAD, so Assume the whole range is committed */ * In case it is not, assume the range is not committed and count the individually committed pages.
CommittedPages = (ULONG)BYTES_TO_PAGES(EndingAddress - StartingAddress); */
ULONG_PTR CommittedPages = Vad->u.VadFlags.MemCommit ? BYTES_TO_PAGES(EndingAddress - StartingAddress) : 0;
/* Is the PDE demand-zero? */
PointerPde = MiPteToPde(PointerPte);
if (PointerPde->u.Long != 0)
{
/* It is not. Is it valid? */
if (PointerPde->u.Hard.Valid == 0)
{
/* Fault it in */
PointerPte = MiPteToAddress(PointerPde);
MiMakeSystemAddressValid(PointerPte, Process);
}
}
else
{
/* It is, skip it and move to the next PDE, unless we're done */
PointerPde++;
PointerPte = MiPteToAddress(PointerPde);
if (PointerPte > LastPte) return CommittedPages;
}
/* Now loop all the PTEs in the range */
while (PointerPte <= LastPte)
{
/* Have we crossed a PDE boundary? */
if (MiIsPteOnPdeBoundary(PointerPte))
{
/* Is this PDE demand zero? */
PointerPde = MiPteToPde(PointerPte);
if (PointerPde->u.Long != 0)
{
/* It isn't -- is it valid? */
if (PointerPde->u.Hard.Valid == 0)
{
/* Nope, fault it in */
PointerPte = MiPteToAddress(PointerPde);
MiMakeSystemAddressValid(PointerPte, Process);
}
}
else
{
/* It is, skip it and move to the next PDE */
PointerPde++;
PointerPte = MiPteToAddress(PointerPde);
continue;
}
}
/* Is this PTE demand zero? */
if (PointerPte->u.Long != 0)
{
/* It isn't -- is it a decommited, invalid, or faulted PTE? */
if ((PointerPte->u.Soft.Protection == MM_DECOMMIT) &&
(PointerPte->u.Hard.Valid == 0) &&
((PointerPte->u.Soft.Prototype == 0) ||
(PointerPte->u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED)))
{
/* It is, so remove it from the count of commited pages */
CommittedPages--;
}
}
/* Move to the next PTE */
PointerPte++;
}
/* Return how many committed pages there still are */
return CommittedPages;
}
/* This is a non-commited VAD, so assume none of it is committed */
CommittedPages = 0;
/* Is the PDE demand-zero? */
PointerPde = MiPteToPde(PointerPte);
if (PointerPde->u.Long != 0)
{
/* It isn't -- is it invalid? */
if (PointerPde->u.Hard.Valid == 0)
{
/* It is, so page it in */
PointerPte = MiPteToAddress(PointerPde);
MiMakeSystemAddressValid(PointerPte, Process);
}
}
else
{
/* It is, so skip it and move to the next PDE */
PointerPde++;
PointerPte = MiPteToAddress(PointerPde);
if (PointerPte > LastPte) return CommittedPages;
}
/* Loop all the PTEs in this PDE */
while (PointerPte <= LastPte) while (PointerPte <= LastPte)
{ {
/* Have we crossed a PDE boundary? */ #if _MI_PAGING_LEVELS == 4
if (MiIsPteOnPdeBoundary(PointerPte)) /* Check if PXE was ever paged in. */
if (OnPxeBoundary)
{ {
/* Is this new PDE demand-zero? */ PointerPxe = MiPteToPxe(PointerPte);
PointerPde = MiPteToPde(PointerPte);
if (PointerPde->u.Long != 0) /* Check that this loop is sane */
ASSERT(OnPpeBoundary);
ASSERT(OnPdeBoundary);
if (PointerPxe->u.Long == 0)
{ {
/* It isn't. Is it valid? */ PointerPxe++;
if (PointerPde->u.Hard.Valid == 0) PointerPte = MiPxeToPte(PointerPde);
{
/* It isn't, so make it valid */
PointerPte = MiPteToAddress(PointerPde);
MiMakeSystemAddressValid(PointerPte, Process);
}
}
else
{
/* It is, so skip it and move to the next one */
PointerPde++;
PointerPte = MiPteToAddress(PointerPde);
continue; continue;
} }
}
/* Is this PTE demand-zero? */ if (PointerPxe->u.Hard.Valid == 0)
MiMakeSystemAddressValid(MiPteToPpe(PointerPte), Process);
}
ASSERT(PointerPxe->u.Hard.Valid == 1);
#endif
#if _MI_PAGING_LEVELS >= 3
/* Now PPE */
if (OnPpeBoundary)
{
PointerPpe = MiPteToPpe(PointerPte);
/* Sanity again */
ASSERT(OnPdeBoundary);
if (PointerPpe->u.Long == 0)
{
PointerPpe++;
PointerPte = MiPpeToPte(PointerPpe);
#if _MI_PAGING_LEVELS == 4
OnPxeBoundary = MiIsPteOnPxeBoundary(PointerPte);
#endif
continue;
}
if (PointerPpe->u.Hard.Valid == 0)
MiMakeSystemAddressValid(MiPteToPde(PointerPte), Process);
}
ASSERT(PointerPpe->u.Hard.Valid == 1);
#endif
/* Last level is the PDE */
if (OnPdeBoundary)
{
PointerPde = MiPteToPde(PointerPte);
if (PointerPde->u.Long == 0)
{
PointerPde++;
PointerPte = MiPdeToPte(PointerPde);
#if _MI_PAGING_LEVELS >= 3
OnPpeBoundary = MiIsPteOnPpeBoundary(PointerPte);
#if _MI_PAGING_LEVELS == 4
OnPxeBoundary = MiIsPteOnPxeBoundary(PointerPte);
#endif
#endif
continue;
}
if (PointerPde->u.Hard.Valid == 0)
MiMakeSystemAddressValid(PointerPte, Process);
}
ASSERT(PointerPde->u.Hard.Valid == 1);
/* Is this PTE demand zero? */
if (PointerPte->u.Long != 0) if (PointerPte->u.Long != 0)
{ {
/* Nope. Is it a valid, non-decommited, non-paged out PTE? */ /* It isn't -- is it a decommited, invalid, or faulted PTE? */
if ((PointerPte->u.Soft.Protection != MM_DECOMMIT) || if ((PointerPte->u.Hard.Valid == 0) &&
(PointerPte->u.Hard.Valid == 1) || (PointerPte->u.Soft.Protection == MM_DECOMMIT) &&
((PointerPte->u.Soft.Prototype == 1) && ((PointerPte->u.Soft.Prototype == 0) ||
(PointerPte->u.Soft.PageFileHigh != MI_PTE_LOOKUP_NEEDED))) (PointerPte->u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED)))
{ {
/* It is! So we'll treat this as a committed page */ /* It is, so remove it from the count of committed pages if we have to */
if (Vad->u.VadFlags.MemCommit)
CommittedPages--;
}
else if (!Vad->u.VadFlags.MemCommit)
{
/* It is a valid, non-decommited, non-paged out PTE. Count it in. */
CommittedPages++; CommittedPages++;
} }
} }
/* Move to the next PTE */ /* Move to the next PTE */
PointerPte++; PointerPte++;
/* Manage page tables */
OnPdeBoundary = MiIsPteOnPdeBoundary(PointerPte);
#if _MI_PAGING_LEVELS >= 3
OnPpeBoundary = MiIsPteOnPpeBoundary(PointerPte);
#if _MI_PAGING_LEVELS == 4
OnPxeBoundary = MiIsPteOnPxeBoundary(PointerPte);
#endif
#endif
} }
/* Return how many committed pages we found in this VAD */ /* Make sure we didn't mess this up */
ASSERT(CommittedPages <= BYTES_TO_PAGES(EndingAddress - StartingAddress));
return CommittedPages; return CommittedPages;
} }