From 3538fd95561fee71276e65c1bc9dbcaffb165a36 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 17 May 2015 00:34:59 +0000 Subject: [PATCH] [NTOSKRNL] Implement MiRosCleanupMemoryArea to cleanup memory areas from MmCleanProcessAddressSpace, since later when we remove the old-style memory area links, we will not be able to retrieve those. svn path=/trunk/; revision=67794 --- reactos/ntoskrnl/include/internal/mm.h | 6 ++ reactos/ntoskrnl/mm/ARM3/procsup.c | 10 +++- reactos/ntoskrnl/mm/marea.c | 77 +++++++++++++++++--------- 3 files changed, 67 insertions(+), 26 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 6ba3a3b468f..6a77a0cdb70 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -507,6 +507,12 @@ MmFreeMemoryArea( PVOID FreePageContext ); +VOID +NTAPI +MiRosCleanupMemoryArea( + PEPROCESS Process, + PMMVAD Vad); + NTSTATUS NTAPI MmFreeMemoryAreaByPtr( diff --git a/reactos/ntoskrnl/mm/ARM3/procsup.c b/reactos/ntoskrnl/mm/ARM3/procsup.c index 3b42ede15e7..a2a55849d78 100644 --- a/reactos/ntoskrnl/mm/ARM3/procsup.c +++ b/reactos/ntoskrnl/mm/ARM3/procsup.c @@ -1279,6 +1279,14 @@ MmCleanProcessAddressSpace(IN PEPROCESS Process) /* Grab the current VAD */ Vad = (PMMVAD)VadTree->BalancedRoot.RightChild; + /* Check for old-style memory areas */ + if (Vad->u.VadFlags.Spare == 1) + { + /* Let RosMm handle this */ + MiRosCleanupMemoryArea(Process, Vad); + continue; + } + /* Lock the working set */ MiLockProcessWorkingSetUnsafe(Process, Thread); @@ -1306,7 +1314,7 @@ MmCleanProcessAddressSpace(IN PEPROCESS Process) MiUnlockProcessWorkingSetUnsafe(Process, Thread); } - /* Skip ARM3 fake VADs, they'll be freed by MmDeleteProcessAddresSpace */ + /* Skip ARM3 fake VADs, they'll be freed by MmDeleteProcessAddresSpace */ if (Vad->u.VadFlags.Spare == 1) { /* Set a flag so MmDeleteMemoryArea knows to free, but not to remove */ diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index 44d1ba80b32..b0e35486469 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -1103,6 +1103,50 @@ MmCreateMemoryArea(PMMSUPPORT AddressSpace, return STATUS_SUCCESS; } +VOID +NTAPI +MiRosCleanupMemoryArea( + PEPROCESS Process, + PMMVAD Vad) +{ + PMEMORY_AREA MemoryArea; + PVOID BaseAddress; + NTSTATUS Status; + + /* We must be called from MmCleanupAddressSpace and nowhere else! + Make sure things are as expected... */ + ASSERT(Process == PsGetCurrentProcess()); + ASSERT(Process->VmDeleted == TRUE); + ASSERT(((PsGetCurrentThread()->ThreadsProcess == Process) && + (Process->ActiveThreads == 1)) || + (Process->ActiveThreads == 0)); + + /* We are in cleanup, we don't need to synchronize */ + MmUnlockAddressSpace(&Process->Vm); + + MemoryArea = (PMEMORY_AREA)Vad; + BaseAddress = (PVOID)MA_GetStartingAddress(MemoryArea); + + if (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW) + { + Status = MiRosUnmapViewOfSection(Process, BaseAddress, 0); + } + else if (MemoryArea->Type == MEMORY_AREA_CACHE) + { + Status = MmUnmapViewOfCacheSegment(&Process->Vm, BaseAddress); + } + else + { + /* There shouldn't be anything else! */ + ASSERT(FALSE); + } + + /* Make sure this worked! */ + ASSERT(NT_SUCCESS(Status)); + + /* Lock the address space again */ + MmLockAddressSpace(&Process->Vm); +} VOID NTAPI @@ -1125,32 +1169,13 @@ MmDeleteProcessAddressSpace(PEPROCESS Process) while ((MemoryArea = (PMEMORY_AREA)Process->Vm.WorkingSetExpansionLinks.Flink) != NULL) { - switch (MemoryArea->Type) - { - case MEMORY_AREA_SECTION_VIEW: - Address = (PVOID)MA_GetStartingAddress(MemoryArea); - MmUnlockAddressSpace(&Process->Vm); - MmUnmapViewOfSection(Process, Address); - MmLockAddressSpace(&Process->Vm); - break; + /* There should be nothing else left */ + ASSERT(MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3); - case MEMORY_AREA_CACHE: - Address = (PVOID)MA_GetStartingAddress(MemoryArea); - MmUnlockAddressSpace(&Process->Vm); - MmUnmapViewOfCacheSegment(&Process->Vm, Address); - MmLockAddressSpace(&Process->Vm); - break; - - case MEMORY_AREA_OWNED_BY_ARM3: - MmFreeMemoryArea(&Process->Vm, - MemoryArea, - NULL, - NULL); - break; - - default: - KeBugCheck(MEMORY_MANAGEMENT); - } + MmFreeMemoryArea(&Process->Vm, + MemoryArea, + NULL, + NULL); } #if (_MI_PAGING_LEVELS == 2) @@ -1176,6 +1201,7 @@ MmDeleteProcessAddressSpace(PEPROCESS Process) MiQueryPageTableReferences(Address)); ASSERT(MiQueryPageTableReferences(Address) == 0); } + pointerPde = MiAddressToPde(Address); /* Unlike in ARM3, we don't necesarrily free the PDE page as soon as reference reaches 0, * so we must clean up a bit when process closes */ @@ -1183,6 +1209,7 @@ MmDeleteProcessAddressSpace(PEPROCESS Process) MiDeletePte(pointerPde, MiPdeToPte(pointerPde), Process, NULL); ASSERT(pointerPde->u.Hard.Valid == 0); } + /* Release lock */ KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);