diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index efcc0537ebc..67eeb4238cf 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -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( diff --git a/reactos/ntoskrnl/mm/ARM3/pool.c b/reactos/ntoskrnl/mm/ARM3/pool.c index c4a73746d6b..e3af2a6d6b5 100644 --- a/reactos/ntoskrnl/mm/ARM3/pool.c +++ b/reactos/ntoskrnl/mm/ARM3/pool.c @@ -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 // diff --git a/reactos/ntoskrnl/mm/ARM3/virtual.c b/reactos/ntoskrnl/mm/ARM3/virtual.c index 88ff54f5dcc..a517cba0892 100644 --- a/reactos/ntoskrnl/mm/ARM3/virtual.c +++ b/reactos/ntoskrnl/mm/ARM3/virtual.c @@ -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,