From bd074499cbe752fadaab762e6bff63e08febe65d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Mon, 25 Aug 2014 12:33:49 +0000 Subject: [PATCH] [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 --- reactos/ntoskrnl/mm/ARM3/pagfault.c | 5 +---- reactos/ntoskrnl/mm/ARM3/virtual.c | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index df4dbebe248..f78a445343c 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -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) diff --git a/reactos/ntoskrnl/mm/ARM3/virtual.c b/reactos/ntoskrnl/mm/ARM3/virtual.c index 932e1d04ac2..ce616018d6d 100644 --- a/reactos/ntoskrnl/mm/ARM3/virtual.c +++ b/reactos/ntoskrnl/mm/ARM3/virtual.c @@ -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);