Author: arty Date: Mon Jul 28 17:05:56 2008 New Revision: 34920
URL: http://svn.reactos.org/svn/reactos?rev=34920&view=rev Log: - Reverse my previous (in retrospect) hack - Make MmProbeAndLockPages smart enough to work at DISPATCH_LEVEL - At Alex' request, remove the stand alone spinlock for the page list, and use the queued spinlock in the prcb.
Modified: trunk/reactos/drivers/storage/scsiport/scsiport.c trunk/reactos/ntoskrnl/include/internal/mm.h trunk/reactos/ntoskrnl/io/iomgr/irp.c trunk/reactos/ntoskrnl/mm/freelist.c trunk/reactos/ntoskrnl/mm/mdlsup.c
Modified: trunk/reactos/drivers/storage/scsiport/scsiport.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/storage/scsiport/sc... ============================================================================== --- trunk/reactos/drivers/storage/scsiport/scsiport.c [iso-8859-1] (original) +++ trunk/reactos/drivers/storage/scsiport/scsiport.c [iso-8859-1] Mon Jul 28 17:05:56 2008 @@ -4405,8 +4405,7 @@
if (Irp->MdlAddress != NULL) { - /* We don't need to unlock this MDL because the request could - * only have come from dispatch level */ + MmUnlockPages(Irp->MdlAddress); IoFreeMdl(Irp->MdlAddress); Irp->MdlAddress = NULL; }
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 Jul 28 17:05:56 2008 @@ -1009,6 +1009,22 @@ NTAPI MmGetLockCountPage(PFN_TYPE Page);
+FORCEINLINE +VOID +NTAPI +MmAcquirePageListLock() +{ + KeAcquireQueuedSpinLock(LockQueuePfnLock); +} + +FORCEINLINE +VOID +NTAPI +MmReleasePageListLock(KIRQL oldIrql) +{ + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); +} + VOID NTAPI MmInitializePageList(
Modified: trunk/reactos/ntoskrnl/io/iomgr/irp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/io/iomgr/irp.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/io/iomgr/irp.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/io/iomgr/irp.c [iso-8859-1] Mon Jul 28 17:05:56 2008 @@ -682,31 +682,24 @@ return NULL; }
- if (KeGetCurrentIrql() >= DISPATCH_LEVEL) + /* Probe and Lock */ + _SEH_TRY { - MmBuildMdlForNonPagedPool(Irp->MdlAddress); + /* Do the probe */ + MmProbeAndLockPages(Irp->MdlAddress, + KernelMode, + MajorFunction == IRP_MJ_READ ? + IoWriteAccess : IoReadAccess); } - else + _SEH_HANDLE { - /* Probe and Lock */ - _SEH_TRY - { - /* Do the probe */ - MmProbeAndLockPages(Irp->MdlAddress, - KernelMode, - MajorFunction == IRP_MJ_READ ? - IoWriteAccess : IoReadAccess); - } - _SEH_HANDLE - { - /* Free the IRP and its MDL */ - IoFreeMdl(Irp->MdlAddress); - IoFreeIrp(Irp); - Irp = NULL; - } - _SEH_END; + /* Free the IRP and its MDL */ + IoFreeMdl(Irp->MdlAddress); + IoFreeIrp(Irp); + Irp = NULL; } - + _SEH_END; + /* This is how we know if we failed during the probe */ if (!Irp) return NULL; }
Modified: trunk/reactos/ntoskrnl/mm/freelist.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/freelist.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/freelist.c [iso-8859-1] Mon Jul 28 17:05:56 2008 @@ -30,7 +30,6 @@ PPHYSICAL_PAGE MmPageArray; ULONG MmPageArraySize;
-static KSPIN_LOCK PageListLock; /* List of pages allocated to the MC_USER Consumer */ static LIST_ENTRY UserPageListHead; /* List of pages zeroed by the ZPW (MmZeroPageThreadMain) */ @@ -52,18 +51,18 @@ { PLIST_ENTRY NextListEntry; PHYSICAL_PAGE* PageDescriptor; - KIRQL oldIrql; - - KeAcquireSpinLock(&PageListLock, &oldIrql); + KIRQL oldIrql = KeGetCurrentIrql(); + + KeAcquireQueuedSpinLock(LockQueuePfnLock); NextListEntry = UserPageListHead.Flink; if (NextListEntry == &UserPageListHead) { - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); return 0; } PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry); ASSERT_PFN(PageDescriptor); - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); return PageDescriptor - MmPageArray; }
@@ -71,15 +70,15 @@ NTAPI MmInsertLRULastUserPage(PFN_TYPE Pfn) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); PPHYSICAL_PAGE Page;
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); Page = MiGetPfnEntry(Pfn); ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED); ASSERT(Page->Flags.Consumer == MC_USER); InsertTailList(&UserPageListHead, &Page->ListEntry); - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); }
PFN_TYPE @@ -88,21 +87,21 @@ { PLIST_ENTRY NextListEntry; PHYSICAL_PAGE* PageDescriptor; - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); PPHYSICAL_PAGE Page;
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); Page = MiGetPfnEntry(PreviousPfn); ASSERT(Page->Flags.Type == MM_PHYSICAL_PAGE_USED); ASSERT(Page->Flags.Consumer == MC_USER); NextListEntry = Page->ListEntry.Flink; if (NextListEntry == &UserPageListHead) { - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); return 0; } PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry); - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); return PageDescriptor - MmPageArray; }
@@ -126,11 +125,11 @@ ULONG last; ULONG length; ULONG boundary; - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql();
NrPages = PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE;
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock);
last = min(HighestAcceptableAddress.LowPart / PAGE_SIZE, MmPageArraySize - 1); boundary = BoundaryAddressMultiple.LowPart / PAGE_SIZE; @@ -197,7 +196,7 @@ Page->MapCount = 0; Page->SavedSwapEntry = 0; } - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); for (i = start; i < (start + length); i++) { if (MiGetPfnEntry(i)->Flags.Zero == 0) @@ -212,7 +211,7 @@ return start; } } - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); return 0; }
@@ -243,7 +242,6 @@ PMEMORY_ALLOCATION_DESCRIPTOR Md;
/* Initialize the page lists */ - KeInitializeSpinLock(&PageListLock); InitializeListHead(&UserPageListHead); InitializeListHead(&FreeUnzeroedPageListHead); InitializeListHead(&FreeZeroedPageListHead); @@ -372,34 +370,34 @@ NTAPI MmSetFlagsPage(PFN_TYPE Pfn, ULONG Flags) { - KIRQL oldIrql; - - KeAcquireSpinLock(&PageListLock, &oldIrql); + KIRQL oldIrql = KeGetCurrentIrql(); + + KeAcquireQueuedSpinLock(LockQueuePfnLock); MiGetPfnEntry(Pfn)->AllFlags = Flags; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); }
VOID NTAPI MmSetRmapListHeadPage(PFN_TYPE Pfn, struct _MM_RMAP_ENTRY* ListHead) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql();
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); MiGetPfnEntry(Pfn)->RmapListHead = ListHead; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); }
struct _MM_RMAP_ENTRY* NTAPI MmGetRmapListHeadPage(PFN_TYPE Pfn) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); struct _MM_RMAP_ENTRY* ListHead;
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); ListHead = MiGetPfnEntry(Pfn)->RmapListHead; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(ListHead); } @@ -408,12 +406,12 @@ NTAPI MmMarkPageMapped(PFN_TYPE Pfn) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); PPHYSICAL_PAGE Page;
if (Pfn <= MmPageArraySize) { - KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); Page = MiGetPfnEntry(Pfn); if (Page->Flags.Type == MM_PHYSICAL_PAGE_FREE) { @@ -422,7 +420,7 @@ } Page->MapCount++; Page->ReferenceCount++; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); } }
@@ -430,12 +428,12 @@ NTAPI MmMarkPageUnmapped(PFN_TYPE Pfn) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); PPHYSICAL_PAGE Page;
if (Pfn <= MmPageArraySize) { - KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); Page = MiGetPfnEntry(Pfn); if (Page->Flags.Type == MM_PHYSICAL_PAGE_FREE) { @@ -449,7 +447,7 @@ } Page->MapCount--; Page->ReferenceCount--; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); } }
@@ -457,12 +455,12 @@ NTAPI MmGetFlagsPage(PFN_TYPE Pfn) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); ULONG Flags;
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); Flags = MiGetPfnEntry(Pfn)->AllFlags; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(Flags); } @@ -472,11 +470,11 @@ NTAPI MmSetSavedSwapEntryPage(PFN_TYPE Pfn, SWAPENTRY SavedSwapEntry) { - KIRQL oldIrql; - - KeAcquireSpinLock(&PageListLock, &oldIrql); + KIRQL oldIrql = KeGetCurrentIrql(); + + KeAcquireQueuedSpinLock(LockQueuePfnLock); MiGetPfnEntry(Pfn)->SavedSwapEntry = SavedSwapEntry; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); }
SWAPENTRY @@ -484,11 +482,11 @@ MmGetSavedSwapEntryPage(PFN_TYPE Pfn) { SWAPENTRY SavedSwapEntry; - KIRQL oldIrql; - - KeAcquireSpinLock(&PageListLock, &oldIrql); + KIRQL oldIrql = KeGetCurrentIrql(); + + KeAcquireQueuedSpinLock(LockQueuePfnLock); SavedSwapEntry = MiGetPfnEntry(Pfn)->SavedSwapEntry; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(SavedSwapEntry); } @@ -497,7 +495,7 @@ NTAPI MmReferencePageUnsafe(PFN_TYPE Pfn) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); PPHYSICAL_PAGE Page;
DPRINT("MmReferencePageUnsafe(PysicalAddress %x)\n", Pfn << PAGE_SHIFT); @@ -507,7 +505,7 @@ return; }
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MiGetPfnEntry(Pfn); if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) @@ -517,7 +515,7 @@ }
Page->ReferenceCount++; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); }
VOID @@ -533,13 +531,13 @@ NTAPI MmGetReferenceCountPage(PFN_TYPE Pfn) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); ULONG RCount; PPHYSICAL_PAGE Page;
DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); Page = MiGetPfnEntry(Pfn); if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) { @@ -549,7 +547,7 @@
RCount = Page->ReferenceCount;
- KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); return(RCount); }
@@ -567,12 +565,12 @@ NTAPI MmDereferencePage(PFN_TYPE Pfn) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); PPHYSICAL_PAGE Page;
DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MiGetPfnEntry(Pfn);
@@ -630,20 +628,20 @@ KeSetEvent(&ZeroPageThreadEvent, IO_NO_INCREMENT, FALSE); } } - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); }
ULONG NTAPI MmGetLockCountPage(PFN_TYPE Pfn) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); ULONG LockCount; PPHYSICAL_PAGE Page;
DPRINT("MmGetLockCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MiGetPfnEntry(Pfn); if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) @@ -653,7 +651,7 @@ }
LockCount = Page->LockCount; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(LockCount); } @@ -662,12 +660,12 @@ NTAPI MmLockPageUnsafe(PFN_TYPE Pfn) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); PPHYSICAL_PAGE Page;
DPRINT("MmLockPageUnsafe(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MiGetPfnEntry(Pfn); if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) @@ -677,7 +675,7 @@ }
Page->LockCount++; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); }
VOID @@ -693,12 +691,12 @@ NTAPI MmUnlockPage(PFN_TYPE Pfn) { - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); PPHYSICAL_PAGE Page;
DPRINT("MmUnlockPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MiGetPfnEntry(Pfn); if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED) @@ -708,7 +706,7 @@ }
Page->LockCount--; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); }
PFN_TYPE @@ -718,12 +716,12 @@ PFN_TYPE PfnOffset; PLIST_ENTRY ListEntry; PPHYSICAL_PAGE PageDescriptor; - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); BOOLEAN NeedClear = FALSE;
DPRINT("MmAllocPage()\n");
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); if (IsListEmpty(&FreeZeroedPageListHead)) { if (IsListEmpty(&FreeUnzeroedPageListHead)) @@ -732,14 +730,14 @@ if (MmStats.NrTotalPages == 0) { /* Allocate an early page -- we'll account for it later */ - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); PfnOffset = MmAllocEarlyPage(); MiZeroPage(PfnOffset); return PfnOffset; }
DPRINT1("MmAllocPage(): Out of memory\n"); - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); return 0; } ListEntry = RemoveTailList(&FreeUnzeroedPageListHead); @@ -781,7 +779,7 @@ MmStats.NrSystemPages++; MmStats.NrFreePages--;
- KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
PfnOffset = PageDescriptor - MmPageArray; if (NeedClear) @@ -805,7 +803,7 @@ PPFN_TYPE Pages) { PPHYSICAL_PAGE PageDescriptor; - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); PFN_TYPE LowestPage, HighestPage; PFN_TYPE pfn; ULONG NumberOfPagesFound = 0; @@ -835,7 +833,7 @@ if (HighestPage > MmPageArraySize) HighestPage = MmPageArraySize;
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); if (LowestPage == 0 && HighestPage == MmPageArraySize) { PLIST_ENTRY ListEntry; @@ -854,7 +852,7 @@ { if (NumberOfPagesFound == 0) { - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); DPRINT1("MmAllocPagesSpecifyRange(): Out of memory\n"); return -1; } @@ -925,7 +923,7 @@ break; } } - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
/* Zero unzero-ed pages */ for (i = 0; i < NumberOfPagesFound; i++) @@ -949,7 +947,7 @@ MmZeroPageThreadMain(PVOID Ignored) { NTSTATUS Status; - KIRQL oldIrql; + KIRQL oldIrql = KeGetCurrentIrql(); PLIST_ENTRY ListEntry; PPHYSICAL_PAGE PageDescriptor; PFN_TYPE Pfn; @@ -981,7 +979,7 @@ return STATUS_SUCCESS; } Count = 0; - KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); while (!IsListEmpty(&FreeUnzeroedPageListHead)) { ListEntry = RemoveTailList(&FreeUnzeroedPageListHead); @@ -989,11 +987,11 @@ PageDescriptor = CONTAINING_RECORD(ListEntry, PHYSICAL_PAGE, ListEntry); /* We set the page to used, because MmCreateVirtualMapping failed with unused pages */ PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED; - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); Pfn = PageDescriptor - MmPageArray; Status = MiZeroPage(Pfn);
- KeAcquireSpinLock(&PageListLock, &oldIrql); + KeAcquireQueuedSpinLock(LockQueuePfnLock); if (PageDescriptor->MapCount != 0) { DPRINT1("Mapped page on freelist.\n"); @@ -1015,7 +1013,7 @@ } DPRINT("Zeroed %d pages.\n", Count); KeResetEvent(&ZeroPageThreadEvent); - KeReleaseSpinLock(&PageListLock, oldIrql); + KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql); }
return STATUS_SUCCESS;
Modified: trunk/reactos/ntoskrnl/mm/mdlsup.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/mdlsup.c?rev=34... ============================================================================== --- trunk/reactos/ntoskrnl/mm/mdlsup.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/mdlsup.c [iso-8859-1] Mon Jul 28 17:05:56 2008 @@ -391,11 +391,12 @@ PVOID Base, Address; ULONG i, j; ULONG NrPages; - NTSTATUS Status; + NTSTATUS Status = STATUS_SUCCESS; PFN_TYPE Page; PEPROCESS CurrentProcess; PETHREAD Thread; PMM_AVL_TABLE AddressSpace; + KIRQL OldIrql = KeGetCurrentIrql(); DPRINT("Probing MDL: %p\n", Mdl);
/* Sanity checks */ @@ -486,7 +487,10 @@ /* * Lock the pages */ - MmLockAddressSpace(AddressSpace); + if (OldIrql < DISPATCH_LEVEL) + MmLockAddressSpace(AddressSpace); + else + MmAcquirePageListLock(&OldIrql);
for (i = 0; i < NrPages; i++) { @@ -500,8 +504,7 @@ Status = MmAccessFault(FALSE, Address, AccessMode, NULL); if (!NT_SUCCESS(Status)) { - MmUnlockAddressSpace(AddressSpace); - ExRaiseStatus(STATUS_ACCESS_VIOLATION); + goto cleanup; } } else @@ -524,8 +527,7 @@ MmDereferencePage(Page); } } - MmUnlockAddressSpace(AddressSpace); - ExRaiseStatus(STATUS_ACCESS_VIOLATION); + goto cleanup; } } Page = MmGetPfnForProcess(NULL, Address); @@ -539,9 +541,17 @@ MmReferencePage(Page); } } - - MmUnlockAddressSpace(AddressSpace); + +cleanup: + if (OldIrql < DISPATCH_LEVEL) + MmUnlockAddressSpace(AddressSpace); + else + MmReleasePageListLock(OldIrql); + + if (!NT_SUCCESS(Status)) + ExRaiseStatus(STATUS_ACCESS_VIOLATION); Mdl->MdlFlags |= MDL_PAGES_LOCKED; + return; }
/*