diff --git a/ntoskrnl/mm/ARM3/miarm.h b/ntoskrnl/mm/ARM3/miarm.h index 7de6227f5a1..84357d1e7ea 100644 --- a/ntoskrnl/mm/ARM3/miarm.h +++ b/ntoskrnl/mm/ARM3/miarm.h @@ -1398,6 +1398,46 @@ MiUnlockWorkingSetShared( KeLeaveGuardedRegion(); } +FORCEINLINE +BOOLEAN +MiConvertSharedWorkingSetLockToExclusive( + _In_ PETHREAD Thread, + _In_ PMMSUPPORT Vm) +{ + /* Sanity check: No exclusive lock. */ + ASSERT(!Thread->OwnsProcessWorkingSetExclusive); + ASSERT(!Thread->OwnsSessionWorkingSetExclusive); + ASSERT(!Thread->OwnsSystemWorkingSetExclusive); + + /* And it should have one and only one shared lock */ + ASSERT((Thread->OwnsProcessWorkingSetShared + Thread->OwnsSessionWorkingSetShared + Thread->OwnsSystemWorkingSetShared) == 1); + + /* Try. */ + if (!ExConvertPushLockSharedToExclusive(&Vm->WorkingSetMutex)) + return FALSE; + + if (Vm == &MmSystemCacheWs) + { + ASSERT(Thread->OwnsSystemWorkingSetShared); + Thread->OwnsSystemWorkingSetShared = FALSE; + Thread->OwnsSystemWorkingSetExclusive = TRUE; + } + else if (Vm->Flags.SessionSpace) + { + ASSERT(Thread->OwnsSessionWorkingSetShared); + Thread->OwnsSessionWorkingSetShared = FALSE; + Thread->OwnsSessionWorkingSetExclusive = TRUE; + } + else + { + ASSERT(Thread->OwnsProcessWorkingSetShared); + Thread->OwnsProcessWorkingSetShared = FALSE; + Thread->OwnsProcessWorkingSetExclusive = TRUE; + } + + return TRUE; +} + FORCEINLINE VOID MiUnlockProcessWorkingSetForFault(IN PEPROCESS Process,