[NTOS]: Implement MiDeleteSystemPageableVm.

[NTOS]: The paged pool free code was behaving incorrectly, assuming that paged pool was "locked down" and never paged out/reused (a valid NT operation mode), while the allocation code was assuming paged pool was a volatile, reusable, pageable resource (normal NT operation mode). The free code now assumes normal operation mode, and actually frees the freed paged pool pages, by using MiDeleteSystemPageableVm.
I have a feeling this will make ARM3 paged pool work.

svn path=/trunk/; revision=47582
This commit is contained in:
Sir Richard 2010-06-05 04:16:46 +00:00
parent 9ef0181983
commit f4f8ee78d1
3 changed files with 111 additions and 0 deletions

View file

@ -733,6 +733,15 @@ MiInsertPageInFreeList(
IN PFN_NUMBER PageFrameIndex
);
PFN_NUMBER
NTAPI
MiDeleteSystemPageableVm(
IN PMMPTE PointerPte,
IN PFN_NUMBER PageCount,
IN ULONG Flags,
OUT PPFN_NUMBER ValidPages
);
PLDR_DATA_TABLE_ENTRY
NTAPI
MiLookupDataTableEntry(

View file

@ -264,6 +264,7 @@ MiAllocatePoolPages(IN POOL_TYPE PoolType,
// Get the page bit count
//
i = ((SizeInPages - 1) / 1024) + 1;
DPRINT1("Paged pool expansion: %d %x\n", i, SizeInPages);
//
// Check if there is enougn paged pool expansion space left
@ -666,6 +667,11 @@ MiFreePoolPages(IN PVOID StartingVa)
//
NumberOfPages = End - i + 1;
/* Delete the actual pages */
PointerPte = MmPagedPoolInfo.FirstPteForPagedPool + i;
FreePages = MiDeleteSystemPageableVm(PointerPte, NumberOfPages, 0, NULL);
ASSERT(FreePages == NumberOfPages);
//
// Acquire the paged pool lock
//

View file

@ -29,6 +29,102 @@ MiProtectVirtualMemory(IN PEPROCESS Process,
/* PRIVATE FUNCTIONS **********************************************************/
PFN_NUMBER
NTAPI
MiDeleteSystemPageableVm(IN PMMPTE PointerPte,
IN PFN_NUMBER PageCount,
IN ULONG Flags,
OUT PPFN_NUMBER ValidPages)
{
PFN_NUMBER ActualPages = 0;
PETHREAD CurrentThread;
PMMPFN Pfn1, Pfn2;
PFN_NUMBER PageFrameIndex, PageTableIndex;
KIRQL OldIrql, LockIrql;
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
/*
* Now we must raise to APC_LEVEL and mark the thread as owner
* We don't actually implement a working set pushlock, so this is only
* for internal consistency (and blocking APCs)
*/
KeRaiseIrql(APC_LEVEL, &LockIrql);
CurrentThread = PsGetCurrentThread();
KeEnterGuardedRegion();
ASSERT((CurrentThread->OwnsSystemWorkingSetExclusive == 0) &&
(CurrentThread->OwnsSystemWorkingSetShared == 0));
CurrentThread->OwnsSystemWorkingSetExclusive = 1;
/* Loop all pages */
while (PageCount)
{
/* Make sure there's some data about the page */
if (PointerPte->u.Long)
{
/* As always, only handle current ARM3 scenarios */
ASSERT(PointerPte->u.Soft.Prototype == 0);
ASSERT(PointerPte->u.Soft.Transition == 0);
ASSERT(PointerPte->u.Hard.Valid == 1);
/* Normally this is one possibility -- freeing a valid page */
if (PointerPte->u.Hard.Valid)
{
/* Get the page PFN */
PageFrameIndex = PFN_FROM_PTE(PointerPte);
Pfn1 = MiGetPfnEntry(PageFrameIndex);
/* Should not have any working set data yet */
ASSERT(Pfn1->u1.WsIndex == 0);
/* Actual valid, legitimate, pages */
if (ValidPages) *ValidPages++;
/* Get the page table entry */
PageTableIndex = Pfn1->u4.PteFrame;
DPRINT1("Page table: %lx\n", PageTableIndex);
Pfn2 = MiGetPfnEntry(PageTableIndex);
/* Lock the PFN database */
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
/* Delete it the page */
MI_SET_PFN_DELETED(Pfn1);
MiDecrementShareCount(Pfn1, PageFrameIndex);
/* Decrement the page table too */
#if 0 // ARM3: Dont't trust this yet
MiDecrementShareCount(Pfn2, PageTableIndex);
#endif
/* Release the PFN database */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
/* Destroy the PTE */
PointerPte->u.Long = 0;
}
/* Actual legitimate pages */
ActualPages++;
}
/* Keep going */
PointerPte++;
PageCount--;
}
/* Re-enable APCs */
ASSERT(KeAreAllApcsDisabled() == TRUE);
CurrentThread->OwnsSystemWorkingSetExclusive = 0;
KeLeaveGuardedRegion();
KeLowerIrql(LockIrql);
/* Flush the entire TLB */
KeFlushEntireTb(TRUE, TRUE);
/* Done */
return ActualPages;
}
LONG
MiGetExceptionInfo(IN PEXCEPTION_POINTERS ExceptionInfo,
OUT PBOOLEAN HaveBadAddress,