From 91587a432bc95c4e3a99369f7b61eb159590f72f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Thu, 20 May 2021 11:48:02 +0200 Subject: [PATCH] [NTOS:MM] Fix another instance of reentrant spinlock acquisition --- ntoskrnl/cache/newcc.h | 13 +++++++++++++ ntoskrnl/cache/section/data.c | 2 +- ntoskrnl/cache/section/swapout.c | 6 +++--- ntoskrnl/mm/freelist.c | 5 ++--- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/ntoskrnl/cache/newcc.h b/ntoskrnl/cache/newcc.h index d71779f42ff..e903c66977e 100644 --- a/ntoskrnl/cache/newcc.h +++ b/ntoskrnl/cache/newcc.h @@ -160,3 +160,16 @@ CcpPinMappedData(IN PNOCC_CACHE_MAP Map, IN ULONG Length, IN ULONG Flags, IN OUT PVOID *Bcb); + +ULONG +MmGetReferenceCountPageWithoutLock(PFN_NUMBER Page) +{ + ULONG Ret; + KIRQL OldIrql = MiAcquirePfnLock(); + + Ret = MmGetReferenceCountPage(Page); + + MiReleasePfnLock(OldIrql); + + return Ret; +} diff --git a/ntoskrnl/cache/section/data.c b/ntoskrnl/cache/section/data.c index fa83080eddb..3b4aafac89f 100644 --- a/ntoskrnl/cache/section/data.c +++ b/ntoskrnl/cache/section/data.c @@ -643,7 +643,7 @@ MiFreeSegmentPage(PMM_SECTION_SEGMENT Segment, OldPage, FileOffset->QuadPart, Segment, - MmGetReferenceCountPage(OldPage), + MmGetReferenceCountPageWithoutLock(OldPage), Entry, IS_DIRTY_SSE(Entry) ? "true" : "false"); diff --git a/ntoskrnl/cache/section/swapout.c b/ntoskrnl/cache/section/swapout.c index 4c6f100f5d8..e2bf8972cbe 100644 --- a/ntoskrnl/cache/section/swapout.c +++ b/ntoskrnl/cache/section/swapout.c @@ -172,11 +172,11 @@ MmFinalizeSectionPageOut(PMM_SECTION_SEGMENT Segment, SWAPENTRY Swap = MmGetSavedSwapEntryPage(Page); /* Bail early if the reference count isn't where we need it */ - if (MmGetReferenceCountPage(Page) != 1) + if (MmGetReferenceCountPageWithoutLock(Page) != 1) { DPRINT1("Cannot page out locked page %x with ref count %lu\n", Page, - MmGetReferenceCountPage(Page)); + MmGetReferenceCountPageWithoutLock(Page)); return STATUS_UNSUCCESSFUL; } @@ -357,7 +357,7 @@ MmpPageOutPhysicalAddress(PFN_NUMBER Page) NTSTATUS Status = STATUS_SUCCESS; MM_REQUIRED_RESOURCES Resources = { 0 }; - DPRINTC("Page out %x (ref ct %x)\n", Page, MmGetReferenceCountPage(Page)); + DPRINTC("Page out %x (ref ct %x)\n", Page, MmGetReferenceCountPageWithoutLock(Page)); ExAcquireFastMutex(&MiGlobalPageOperation); if ((Segment = MmGetSectionAssociation(Page, &FileOffset))) diff --git a/ntoskrnl/mm/freelist.c b/ntoskrnl/mm/freelist.c index fdd5d4b64da..e3b2f30f9fa 100644 --- a/ntoskrnl/mm/freelist.c +++ b/ntoskrnl/mm/freelist.c @@ -537,20 +537,19 @@ ULONG NTAPI MmGetReferenceCountPage(PFN_NUMBER Pfn) { - KIRQL oldIrql; ULONG RCount; PMMPFN Pfn1; + MI_ASSERT_PFN_LOCK_HELD(); + DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); - oldIrql = MiAcquirePfnLock(); Pfn1 = MiGetPfnEntry(Pfn); ASSERT(Pfn1); ASSERT_IS_ROS_PFN(Pfn1); RCount = Pfn1->u3.e2.ReferenceCount; - MiReleasePfnLock(oldIrql); return(RCount); }