Author: ion Date: Mon Sep 3 06:23:31 2012 New Revision: 57228
URL: http://svn.reactos.org/svn/reactos?rev=57228&view=rev Log: [NTOSKRNL]: Implement correct locking and unlocking of the working set, one of the biggest blunders in ARM3 so far. [NTOSKRNL]: Implement MiDereferenceControlArea to avoid leaking CAs in failure cases.
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h trunk/reactos/ntoskrnl/mm/ARM3/miarm.h trunk/reactos/ntoskrnl/mm/ARM3/procsup.c trunk/reactos/ntoskrnl/mm/ARM3/section.c trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/m... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/mm.h [iso-8859-1] Mon Sep 3 06:23:31 2012 @@ -1718,17 +1718,13 @@ MmLockAddressSpace(PMMSUPPORT AddressSpace) { KeAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock); - //ASSERT(Thread->OwnsProcessAddressSpaceExclusive == 0); - //Thread->OwnsProcessAddressSpaceExclusive = TRUE; }
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace) { - //ASSERT(Thread->OwnsProcessAddressSpaceExclusive == 1); KeReleaseGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock); - //Thread->OwnsProcessAddressSpaceExclusive = 0; }
FORCEINLINE
Modified: trunk/reactos/ntoskrnl/mm/ARM3/miarm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/miarm.h?re... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/miarm.h [iso-8859-1] Mon Sep 3 06:23:31 2012 @@ -1041,6 +1041,14 @@ MI_WS_OWNER(IN PEPROCESS Process) { /* Check if this process is the owner, and that the thread owns the WS */ + if (PsGetCurrentThread()->OwnsProcessWorkingSetExclusive == 0) + { + DPRINT1("Thread: %p is not an owner\n", PsGetCurrentThread()); + } + if (KeGetCurrentThread()->ApcState.Process != &Process->Pcb) + { + DPRINT1("Current thread %p is attached to another process %p\n", PsGetCurrentThread(), Process); + } return ((KeGetCurrentThread()->ApcState.Process == &Process->Pcb) && ((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) || (PsGetCurrentThread()->OwnsProcessWorkingSetShared))); @@ -1083,6 +1091,13 @@ IN PFN_NUMBER PageFrameIndex );
+FORCEINLINE +BOOLEAN +MI_IS_WS_UNSAFE(IN PEPROCESS Process) +{ + return (Process->Vm.Flags.AcquiredUnsafe == TRUE); +} + // // Locks the working set for the given process // @@ -1099,12 +1114,57 @@ KeEnterGuardedRegion(); ASSERT(!MM_ANY_WS_LOCK_HELD(Thread));
- /* FIXME: Actually lock it (we can't because Vm is used by MAREAs) */ - - /* FIXME: This also can't be checked because Vm is used by MAREAs) */ - //ASSERT(Process->Vm.Flags.AcquiredUnsafe == 0); - - /* Okay, now we can own it exclusively */ + /* Lock the working set */ + ExAcquirePushLockExclusive(&Process->Vm.WorkingSetMutex); + + /* Now claim that we own the lock */ + ASSERT(!MI_IS_WS_UNSAFE(Process)); + ASSERT(Thread->OwnsProcessWorkingSetExclusive == FALSE); + Thread->OwnsProcessWorkingSetExclusive = TRUE; +} + +FORCEINLINE +VOID +MiLockProcessWorkingSetShared(IN PEPROCESS Process, + IN PETHREAD Thread) +{ + /* Shouldn't already be owning the process working set */ + ASSERT(Thread->OwnsProcessWorkingSetShared == FALSE); + ASSERT(Thread->OwnsProcessWorkingSetExclusive == FALSE); + + /* Block APCs, make sure that still nothing is already held */ + KeEnterGuardedRegion(); + ASSERT(!MM_ANY_WS_LOCK_HELD(Thread)); + + /* Lock the working set */ + ExAcquirePushLockShared(&Process->Vm.WorkingSetMutex); + + /* Now claim that we own the lock */ + ASSERT(!MI_IS_WS_UNSAFE(Process)); + ASSERT(Thread->OwnsProcessWorkingSetShared == FALSE); + ASSERT(Thread->OwnsProcessWorkingSetExclusive == FALSE); + Thread->OwnsProcessWorkingSetShared = TRUE; +} + +FORCEINLINE +VOID +MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, + IN PETHREAD Thread) +{ + /* Shouldn't already be owning the process working set */ + ASSERT(Thread->OwnsProcessWorkingSetExclusive == FALSE); + + /* APCs must be blocked, make sure that still nothing is already held */ + ASSERT(KeAreAllApcsDisabled() == TRUE); + ASSERT(!MM_ANY_WS_LOCK_HELD(Thread)); + + /* Lock the working set */ + ExAcquirePushLockExclusive(&Process->Vm.WorkingSetMutex); + + /* Now claim that we own the lock */ + ASSERT(!MI_IS_WS_UNSAFE(Process)); + Process->Vm.Flags.AcquiredUnsafe = 1; + ASSERT(Thread->OwnsProcessWorkingSetExclusive == FALSE); Thread->OwnsProcessWorkingSetExclusive = TRUE; }
@@ -1116,19 +1176,43 @@ MiUnlockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread) { - /* Make sure this process really is owner, and it was a safe acquisition */ + /* Make sure we are the owner of a safe acquisition */ ASSERT(MI_WS_OWNER(Process)); - /* This can't be checked because Vm is used by MAREAs) */ - //ASSERT(Process->Vm.Flags.AcquiredUnsafe == 0); + ASSERT(!MI_IS_WS_UNSAFE(Process));
/* The thread doesn't own it anymore */ ASSERT(Thread->OwnsProcessWorkingSetExclusive == TRUE); Thread->OwnsProcessWorkingSetExclusive = FALSE;
- /* FIXME: Actually release it (we can't because Vm is used by MAREAs) */ - - /* Unblock APCs */ + /* Release the lock and re-enable APCs */ + ExReleasePushLockExclusive(&Process->Vm.WorkingSetMutex); KeLeaveGuardedRegion(); +} + +// +// Unlocks the working set for the given process +// +FORCEINLINE +VOID +MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, + IN PETHREAD Thread) +{ + /* Make sure we are the owner of an unsafe acquisition */ + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); + ASSERT(KeAreAllApcsDisabled() == TRUE); + ASSERT(MI_WS_OWNER(Process)); + ASSERT(MI_IS_WS_UNSAFE(Process)); + + /* No longer unsafe */ + Process->Vm.Flags.AcquiredUnsafe = 0; + + /* The thread doesn't own it anymore */ + ASSERT(Thread->OwnsProcessWorkingSetExclusive == TRUE); + Thread->OwnsProcessWorkingSetExclusive = FALSE; + + /* Release the lock but don't touch APC state */ + ExReleasePushLockExclusive(&Process->Vm.WorkingSetMutex); + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); }
// @@ -1148,7 +1232,8 @@ /* Thread shouldn't already be owning something */ ASSERT(!MM_ANY_WS_LOCK_HELD(Thread));
- /* FIXME: Actually lock it (we can't because Vm is used by MAREAs) */ + /* Lock this working set */ + ExAcquirePushLockExclusive(&WorkingSet->WorkingSetMutex);
/* Which working set is this? */ if (WorkingSet == &MmSystemCacheWs) @@ -1208,10 +1293,66 @@ Thread->OwnsProcessWorkingSetExclusive = FALSE; }
- /* FIXME: Actually release it (we can't because Vm is used by MAREAs) */ + /* Release the working set lock */ + ExReleasePushLockExclusive(&WorkingSet->WorkingSetMutex);
/* Unblock APCs */ KeLeaveGuardedRegion(); +} + +FORCEINLINE +VOID +MiUnlockProcessWorkingSetForFault(IN PEPROCESS Process, + IN PETHREAD Thread, + IN BOOLEAN Safe, + IN BOOLEAN Shared) +{ + ASSERT(MI_WS_OWNER(Process)); + + /* Check if the current owner is unsafe */ + if (MI_IS_WS_UNSAFE(Process)) + { + /* Release unsafely */ + MiUnlockProcessWorkingSetUnsafe(Process, Thread); + Safe = FALSE; + Shared = FALSE; + } + else if (Thread->OwnsProcessWorkingSetExclusive == 1) + { + /* Owner is safe and exclusive, release normally */ + MiUnlockProcessWorkingSet(Process, Thread); + Safe = TRUE; + Shared = FALSE; + } + else + { + /* Owner is shared (implies safe), release normally */ + ASSERT(FALSE); + Safe = TRUE; + Shared = TRUE; + } +} + +FORCEINLINE +VOID +MiLockProcessWorkingSetForFault(IN PEPROCESS Process, + IN PETHREAD Thread, + IN BOOLEAN Safe, + IN BOOLEAN Shared) +{ + ASSERT(Shared == FALSE); + + /* Check if this was a safe lock or not */ + if (Safe) + { + /* Reacquire safely */ + MiLockProcessWorkingSet(Process, Thread); + } + else + { + /* Reacquire unsafely */ + MiLockProcessWorkingSetUnsafe(Process, Thread); + } }
//
Modified: trunk/reactos/ntoskrnl/mm/ARM3/procsup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/procsup.c?... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] Mon Sep 3 06:23:31 2012 @@ -135,7 +135,7 @@ Status = STATUS_SUCCESS;
/* Pretend as if we own the working set */ - MiLockProcessWorkingSet(Process, Thread); + MiLockProcessWorkingSetUnsafe(Process, Thread);
/* Insert the VAD */ ASSERT(Vad->EndingVpn >= Vad->StartingVpn); @@ -147,7 +147,7 @@ MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result);
/* Release the working set */ - MiUnlockProcessWorkingSet(Process, Thread); + MiUnlockProcessWorkingSetUnsafe(Process, Thread);
/* Release the address space lock */ KeReleaseGuardedMutex(&Process->AddressCreationLock); @@ -195,7 +195,7 @@ ASSERT(Vad->u2.VadFlags2.MultipleSecured == FALSE);
/* Lock the working set */ - MiLockProcessWorkingSet(Process, Thread); + MiLockProcessWorkingSetUnsafe(Process, Thread);
/* Remove this VAD from the tree */ ASSERT(VadTree->NumberGenericTableElements >= 1); @@ -205,7 +205,7 @@ MiDeleteVirtualAddresses((ULONG_PTR)Teb, TebEnd, NULL);
/* Release the working set */ - MiUnlockProcessWorkingSet(Process, Thread); + MiUnlockProcessWorkingSetUnsafe(Process, Thread);
/* Remove the VAD */ ExFreePool(Vad); @@ -1338,9 +1338,11 @@
/* Lock the process address space from changes */ MmLockAddressSpace(&Process->Vm); + MiLockProcessWorkingSetUnsafe(Process, Thread);
/* VM is deleted now */ Process->VmDeleted = TRUE; + MiUnlockProcessWorkingSetUnsafe(Process, Thread);
/* Enumerate the VADs */ VadTree = &Process->VadRoot; @@ -1350,7 +1352,7 @@ Vad = (PMMVAD)VadTree->BalancedRoot.RightChild;
/* Lock the working set */ - MiLockProcessWorkingSet(Process, Thread); + MiLockProcessWorkingSetUnsafe(Process, Thread);
/* Remove this VAD from the tree */ ASSERT(VadTree->NumberGenericTableElements >= 1); @@ -1373,7 +1375,7 @@ Vad);
/* Release the working set */ - MiUnlockProcessWorkingSet(Process, Thread); + MiUnlockProcessWorkingSetUnsafe(Process, Thread); }
/* Skip ARM3 fake VADs, they'll be freed by MmDeleteProcessAddresSpace */ @@ -1388,8 +1390,16 @@ ExFreePool(Vad); }
+ /* Lock the working set */ + MiLockProcessWorkingSetUnsafe(Process, Thread); + ASSERT(Process->CloneRoot == NULL); + ASSERT(Process->PhysicalVadRoot == NULL); + /* Delete the shared user data section */ MiDeleteVirtualAddresses(USER_SHARED_DATA, USER_SHARED_DATA, NULL); + + /* Release the working set */ + MiUnlockProcessWorkingSetUnsafe(Process, Thread);
/* Release the address space */ MmUnlockAddressSpace(&Process->Vm);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/section.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/section.c?... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] Mon Sep 3 06:23:31 2012 @@ -84,22 +84,22 @@ ULONG MmCompatibleProtectionMask[8] = { PAGE_NOACCESS, - + PAGE_NOACCESS | PAGE_READONLY | PAGE_WRITECOPY, - + PAGE_NOACCESS | PAGE_EXECUTE, - + PAGE_NOACCESS | PAGE_READONLY | PAGE_WRITECOPY | PAGE_EXECUTE | PAGE_EXECUTE_READ, - + PAGE_NOACCESS | PAGE_READONLY | PAGE_WRITECOPY | PAGE_READWRITE, - + PAGE_NOACCESS | PAGE_READONLY | PAGE_WRITECOPY, - + PAGE_NOACCESS | PAGE_READONLY | PAGE_WRITECOPY | PAGE_READWRITE | PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY, - + PAGE_NOACCESS | PAGE_READONLY | PAGE_WRITECOPY | PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_WRITECOPY }; @@ -713,11 +713,29 @@
VOID NTAPI +MiDereferenceControlArea(IN PCONTROL_AREA ControlArea) +{ + KIRQL OldIrql; + + /* Lock the PFN database */ + OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); + + /* Drop reference counts */ + ControlArea->NumberOfMappedViews--; + ControlArea->NumberOfUserReferences--; + + /* Check if it's time to delete the CA. This releases the lock */ + MiCheckControlArea(ControlArea, OldIrql); +} + +VOID +NTAPI MiRemoveMappedView(IN PEPROCESS CurrentProcess, IN PMMVAD Vad) { KIRQL OldIrql; PCONTROL_AREA ControlArea; + PETHREAD CurrentThread = PsGetCurrentThread();
/* Get the control area */ ControlArea = Vad->ControlArea; @@ -734,7 +752,7 @@ Vad);
/* Release the working set */ - MiUnlockProcessWorkingSet(CurrentProcess, PsGetCurrentThread()); + MiUnlockProcessWorkingSetUnsafe(CurrentProcess, CurrentThread);
/* Lock the PFN database */ OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock); @@ -760,6 +778,8 @@ PVOID DbgBase = NULL; SIZE_T RegionSize; NTSTATUS Status; + PETHREAD CurrentThread = PsGetCurrentThread(); + PEPROCESS CurrentProcess = PsGetCurrentProcess(); PAGED_CODE();
/* Check for Mm Region */ @@ -771,7 +791,7 @@ }
/* Check if we should attach to the process */ - if (PsGetCurrentProcess() != Process) + if (CurrentProcess != Process) { /* The process is different, do an attach */ KeStackAttachProcess(&Process->Pcb, &ApcState); @@ -837,13 +857,13 @@ /* FIXME: Remove VAD charges */
/* Lock the working set */ - MiLockWorkingSet(PsGetCurrentThread(), &Process->Vm); + MiLockProcessWorkingSetUnsafe(Process, CurrentThread);
/* Remove the VAD */ ASSERT(Process->VadRoot.NumberGenericTableElements >= 1); MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
- /* Remove the PTEs for this view */ + /* Remove the PTEs for this view, which also releases the working set lock */ MiRemoveMappedView(Process, Vad);
/* FIXME: Remove commitment */ @@ -1205,7 +1225,8 @@ &Process->VadRoot)) { DPRINT1("Conflict with SEC_BASED or manually based section!\n"); - return STATUS_CONFLICTING_ADDRESSES; // FIXME: CA Leak + MiDereferenceControlArea(ControlArea); + return STATUS_CONFLICTING_ADDRESSES; } }
@@ -1213,7 +1234,11 @@ /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */ ASSERT((AllocationType & MEM_RESERVE) == 0); /* ARM3 does not support this */ Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV'); - if (!Vad) return STATUS_INSUFFICIENT_RESOURCES; /* FIXME: CA Leak */ + if (!Vad) + { + MiDereferenceControlArea(ControlArea); + return STATUS_INSUFFICIENT_RESOURCES; + } RtlZeroMemory(Vad, sizeof(MMVAD_LONG)); Vad->u4.Banked = (PVOID)0xDEADBABE;
@@ -1244,13 +1269,13 @@ Status = STATUS_SUCCESS;
/* Pretend as if we own the working set */ - MiLockProcessWorkingSet(Process, Thread); + MiLockProcessWorkingSetUnsafe(Process, Thread);
/* Insert the VAD */ MiInsertVad((PMMVAD)Vad, Process);
/* Release the working set */ - MiUnlockProcessWorkingSet(Process, Thread); + MiUnlockProcessWorkingSetUnsafe(Process, Thread);
/* Windows stores this for accounting purposes, do so as well */ if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress; @@ -1797,7 +1822,7 @@ PMMPFN Pfn1; ULONG ProtectionMask, QuotaCharge = 0; PUSHORT UsedPageTableEntries; - //PETHREAD Thread = PsGetCurrentThread(); + PETHREAD Thread = PsGetCurrentThread(); PAGED_CODE();
// @@ -1829,7 +1854,7 @@ // // Get the PTE and PDE for the address, as well as the final PTE // - //MiLockProcessWorkingSet(Thread, Process); + MiLockProcessWorkingSetUnsafe(Process, Thread); PointerPde = MiAddressToPde(StartingAddress); PointerPte = MiAddressToPte(StartingAddress); LastPte = MiAddressToPte(EndingAddress); @@ -1943,7 +1968,7 @@ // // Unlock the working set and update quota charges if needed, then return // - //MiUnlockProcessWorkingSet(Thread, Process); + MiUnlockProcessWorkingSetUnsafe(Process, Thread); if ((QuotaCharge > 0) && (!DontCharge)) { FoundVad->u.VadFlags.CommitCharge -= QuotaCharge;
Modified: trunk/reactos/ntoskrnl/mm/ARM3/virtual.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/virtual.c?... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] Mon Sep 3 06:23:31 2012 @@ -205,7 +205,7 @@ IN PEPROCESS CurrentProcess) { NTSTATUS Status; - BOOLEAN WsWasLocked = FALSE, LockChange = FALSE; + BOOLEAN WsShared = FALSE, WsSafe = FALSE, LockChange = FALSE; PETHREAD CurrentThread = PsGetCurrentThread();
/* Must be a non-pool page table, since those are double-mapped already */ @@ -219,13 +219,11 @@ /* Check if the page table is valid */ while (!MmIsAddressValid(PageTableVirtualAddress)) { - /* Check if the WS is locked */ - if (CurrentThread->OwnsProcessWorkingSetExclusive) - { - /* Unlock the working set and remember it was locked */ - MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread); - WsWasLocked = TRUE; - } + /* Release the working set lock */ + MiUnlockProcessWorkingSetForFault(CurrentProcess, + CurrentThread, + WsSafe, + WsShared);
/* Fault it in */ Status = MmAccessFault(FALSE, PageTableVirtualAddress, KernelMode, NULL); @@ -240,7 +238,10 @@ }
/* Lock the working set again */ - if (WsWasLocked) MiLockProcessWorkingSet(CurrentProcess, CurrentThread); + MiLockProcessWorkingSetForFault(CurrentProcess, + CurrentThread, + WsSafe, + WsShared);
/* This flag will be useful later when we do better locking */ LockChange = TRUE; @@ -1884,8 +1885,9 @@ ULONG ProtectionMask, OldProtect; BOOLEAN Committed; NTSTATUS Status = STATUS_SUCCESS; - - /* Calcualte base address for the VAD */ + PETHREAD Thread = PsGetCurrentThread(); + + /* Calculate base address for the VAD */ StartingAddress = (ULONG_PTR)PAGE_ALIGN((*BaseAddress)); EndingAddress = (((ULONG_PTR)*BaseAddress + *NumberOfBytesToProtect - 1) | (PAGE_SIZE - 1));
@@ -1896,7 +1898,7 @@ DPRINT1("Invalid protection mask\n"); return STATUS_INVALID_PAGE_PROTECTION; } - + /* Check for ROS specific memory area */ MemoryArea = MmLocateMemoryAreaByAddress(&Process->Vm, *BaseAddress); if ((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_SECTION_VIEW)) @@ -2006,7 +2008,8 @@ goto FailPath; }
- //MiLockProcessWorkingSet(Thread, Process); + /* Lock the working set */ + MiLockProcessWorkingSetUnsafe(Process, Thread);
/* Check if all pages in this range are committed */ Committed = MiIsEntireRangeCommitted(StartingAddress, @@ -2018,7 +2021,7 @@ /* Fail */ DPRINT1("The entire range is not committed\n"); Status = STATUS_NOT_COMMITTED; - //MiUnlockProcessWorkingSet(Thread, Process); + MiUnlockProcessWorkingSetUnsafe(Process, Thread); goto FailPath; }
@@ -2105,7 +2108,7 @@ }
/* Unlock the working set */ - //MiUnlockProcessWorkingSet(Thread, Process); + MiUnlockProcessWorkingSetUnsafe(Process, Thread); }
/* Unlock the address space */ @@ -2278,7 +2281,7 @@ PointerPde = MiAddressToPde(StartingAddress); PointerPte = MiAddressToPte(StartingAddress); if (Vad->u.VadFlags.MemCommit) CommitPte = MiAddressToPte(Vad->EndingVpn << PAGE_SHIFT); - MiLockWorkingSet(CurrentThread, &Process->Vm); + MiLockProcessWorkingSetUnsafe(Process, CurrentThread);
// // Make the PDE valid, and now loop through each page's worth of data @@ -2403,7 +2406,7 @@ // release the working set and return the commit reduction accounting. // if (PteCount) MiProcessValidPteList(ValidPteList, PteCount); - MiUnlockWorkingSet(CurrentThread, &Process->Vm); + MiUnlockProcessWorkingSetUnsafe(Process, CurrentThread); return CommitReduction; }
@@ -3992,10 +3995,10 @@ // // Lock the working set and insert the VAD into the process VAD tree // - MiLockProcessWorkingSet(Process, CurrentThread); + MiLockProcessWorkingSetUnsafe(Process, CurrentThread); Vad->ControlArea = NULL; // For Memory-Area hack MiInsertVad(Vad, Process); - MiUnlockProcessWorkingSet(Process, CurrentThread); + MiUnlockProcessWorkingSetUnsafe(Process, CurrentThread);
// // Update the virtual size of the process, and if this is now the highest @@ -4254,7 +4257,7 @@ // // Lock the working set while we play with user pages and page tables // - //MiLockWorkingSet(CurrentThread, AddressSpace); + MiLockProcessWorkingSetUnsafe(Process, CurrentThread);
// // Make the current page table valid, and then loop each page within it @@ -4335,7 +4338,7 @@ // the target process if it was not the current process. Also dereference the // target process if this wasn't the case. // - //MiUnlockProcessWorkingSet(Process, CurrentThread); + MiUnlockProcessWorkingSetUnsafe(Process, CurrentThread); Status = STATUS_SUCCESS; FailPath: MmUnlockAddressSpace(AddressSpace); @@ -4584,7 +4587,7 @@ // // Finally lock the working set and remove the VAD from the VAD tree // - MiLockWorkingSet(CurrentThread, AddressSpace); + MiLockProcessWorkingSetUnsafe(Process, CurrentThread); ASSERT(Process->VadRoot.NumberGenericTableElements >= 1); MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot); } @@ -4614,7 +4617,7 @@ // the code path above when the caller sets a zero region size // and the whole VAD is destroyed // - MiLockWorkingSet(CurrentThread, AddressSpace); + MiLockProcessWorkingSetUnsafe(Process, CurrentThread); ASSERT(Process->VadRoot.NumberGenericTableElements >= 1); MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot); } @@ -4653,7 +4656,7 @@ // and then change the ending address of the VAD to be a bit // smaller. // - MiLockWorkingSet(CurrentThread, AddressSpace); + MiLockProcessWorkingSetUnsafe(Process, CurrentThread); CommitReduction = MiCalculatePageCommitment(StartingAddress, EndingAddress, Vad, @@ -4695,7 +4698,7 @@ // around with process pages. // MiDeleteVirtualAddresses(StartingAddress, EndingAddress, NULL); - MiUnlockWorkingSet(CurrentThread, AddressSpace); + MiUnlockProcessWorkingSetUnsafe(Process, CurrentThread); Status = STATUS_SUCCESS;
FinalPath: