[NTOS/MM]

- Bring back PTE frame refcounting when serving a prototype PTE page fault.
 - Fix a bug in MiDeletePte where the said PTE frame was not unshared.
 - Improve transitional PTEs deletion (will be needed for future work).
Do not always trust the comments stating that "strange RosMm code broke everything"

svn path=/trunk/; revision=63947
This commit is contained in:
Jérôme Gardou 2014-08-25 12:33:49 +00:00
parent c8374ba758
commit bd074499cb
2 changed files with 15 additions and 9 deletions

View file

@ -709,12 +709,9 @@ MiCompleteProtoPteFault(IN BOOLEAN StoreInstruction,
Pfn1->u3.e1.PrototypePte = 1;
/* Increment the share count for the page table */
// FIXME: This doesn't work because we seem to bump the sharecount to two, and MiDeletePte gets annoyed and ASSERTs.
// This could be beause MiDeletePte is now being called from strange code in Rosmm
PageTablePte = MiAddressToPte(PointerPte);
Pfn2 = MiGetPfnEntry(PageTablePte->u.Hard.PageFrameNumber);
//Pfn2->u2.ShareCount++;
DBG_UNREFERENCED_LOCAL_VARIABLE(Pfn2);
Pfn2->u2.ShareCount++;
/* Check where we should be getting the protection information from */
if (PointerPte->u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED)

View file

@ -407,15 +407,17 @@ MiDeletePte(IN PMMPTE PointerPte,
/* See if the PTE is valid */
if (TempPte.u.Hard.Valid == 0)
{
/* Prototype PTEs not supported yet */
/* Prototype and paged out PTEs not supported yet */
ASSERT(TempPte.u.Soft.Prototype == 0);
ASSERT(TempPte.u.Soft.PageFileHigh == 0);
if (TempPte.u.Soft.Transition)
{
/* Get the PFN entry */
PageFrameIndex = PFN_FROM_PTE(&TempPte);
Pfn1 = MiGetPfnEntry(PageFrameIndex);
DPRINT1("Pte %p is transitional!\n", PointerPte);
DPRINT("Pte %p is transitional!\n", PointerPte);
/* Destroy the PTE */
MI_ERASE_PTE(PointerPte);
@ -433,12 +435,14 @@ MiDeletePte(IN PMMPTE PointerPte,
/* And it should be in standby or modified list */
ASSERT((Pfn1->u3.e1.PageLocation == ModifiedPageList) || (Pfn1->u3.e1.PageLocation == StandbyPageList));
/* Unlink it and put it back in free list */
/* Unlink it and temporarily mark it as active */
MiUnlinkPageFromList(Pfn1);
Pfn1->u3.e2.ReferenceCount++;
Pfn1->u3.e1.PageLocation = ActiveAndValid;
/* Bring it back into the free list */
MiInsertPageInFreeList(PageFrameIndex);
/* This will put it back in free list and clean properly up */
MI_SET_PFN_DELETED(Pfn1);
MiDecrementReferenceCount(Pfn1, PageFrameIndex);
}
return;
}
@ -470,6 +474,11 @@ MiDeletePte(IN PMMPTE PointerPte,
#if (_MI_PAGING_LEVELS == 2)
}
#endif
/* Drop the share count on the page table */
PointerPde = MiPteToPde(PointerPte);
MiDecrementShareCount(MiGetPfnEntry(PointerPde->u.Hard.PageFrameNumber),
PointerPde->u.Hard.PageFrameNumber);
/* Drop the share count */
MiDecrementShareCount(Pfn1, PageFrameIndex);