- 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.

svn path=/trunk/; revision=34920
This commit is contained in:
Art Yerkes 2008-07-28 22:05:56 +00:00
parent 67821bff32
commit 298e26754b
5 changed files with 120 additions and 104 deletions

View file

@ -4405,8 +4405,7 @@ SpiCompletionRoutine(PDEVICE_OBJECT DeviceObject,
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;
}

View file

@ -1009,6 +1009,22 @@ ULONG
NTAPI
MmGetLockCountPage(PFN_TYPE Page);
FORCEINLINE
VOID
NTAPI
MmAcquirePageListLock()
{
KeAcquireQueuedSpinLock(LockQueuePfnLock);
}
FORCEINLINE
VOID
NTAPI
MmReleasePageListLock(KIRQL oldIrql)
{
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
VOID
NTAPI
MmInitializePageList(

View file

@ -682,31 +682,24 @@ IoBuildAsynchronousFsdRequest(IN ULONG MajorFunction,
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;
}

View file

@ -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 @@ MmGetLRUFirstUserPage(VOID)
{
PLIST_ENTRY NextListEntry;
PHYSICAL_PAGE* PageDescriptor;
KIRQL oldIrql;
KIRQL oldIrql = KeGetCurrentIrql();
KeAcquireSpinLock(&PageListLock, &oldIrql);
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 @@ VOID
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 @@ MmGetLRUNextUserPage(PFN_TYPE PreviousPfn)
{
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 @@ MmGetContinuousPages(ULONG NumberOfBytes,
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 @@ MmGetContinuousPages(ULONG NumberOfBytes,
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 @@ MmGetContinuousPages(ULONG NumberOfBytes,
return start;
}
}
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return 0;
}
@ -243,7 +242,6 @@ MmInitializePageList(VOID)
PMEMORY_ALLOCATION_DESCRIPTOR Md;
/* Initialize the page lists */
KeInitializeSpinLock(&PageListLock);
InitializeListHead(&UserPageListHead);
InitializeListHead(&FreeUnzeroedPageListHead);
InitializeListHead(&FreeZeroedPageListHead);
@ -372,34 +370,34 @@ VOID
NTAPI
MmSetFlagsPage(PFN_TYPE Pfn, ULONG Flags)
{
KIRQL oldIrql;
KIRQL oldIrql = KeGetCurrentIrql();
KeAcquireSpinLock(&PageListLock, &oldIrql);
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 @@ VOID
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 @@ MmMarkPageMapped(PFN_TYPE Pfn)
}
Page->MapCount++;
Page->ReferenceCount++;
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
}
@ -430,12 +428,12 @@ VOID
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 @@ MmMarkPageUnmapped(PFN_TYPE Pfn)
}
Page->MapCount--;
Page->ReferenceCount--;
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
}
@ -457,12 +455,12 @@ ULONG
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 @@ VOID
NTAPI
MmSetSavedSwapEntryPage(PFN_TYPE Pfn, SWAPENTRY SavedSwapEntry)
{
KIRQL oldIrql;
KIRQL oldIrql = KeGetCurrentIrql();
KeAcquireSpinLock(&PageListLock, &oldIrql);
KeAcquireQueuedSpinLock(LockQueuePfnLock);
MiGetPfnEntry(Pfn)->SavedSwapEntry = SavedSwapEntry;
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
SWAPENTRY
@ -484,11 +482,11 @@ NTAPI
MmGetSavedSwapEntryPage(PFN_TYPE Pfn)
{
SWAPENTRY SavedSwapEntry;
KIRQL oldIrql;
KIRQL oldIrql = KeGetCurrentIrql();
KeAcquireSpinLock(&PageListLock, &oldIrql);
KeAcquireQueuedSpinLock(LockQueuePfnLock);
SavedSwapEntry = MiGetPfnEntry(Pfn)->SavedSwapEntry;
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(SavedSwapEntry);
}
@ -497,7 +495,7 @@ VOID
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 @@ MmReferencePageUnsafe(PFN_TYPE Pfn)
return;
}
KeAcquireSpinLock(&PageListLock, &oldIrql);
KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MiGetPfnEntry(Pfn);
if (Page->Flags.Type != MM_PHYSICAL_PAGE_USED)
@ -517,7 +515,7 @@ MmReferencePageUnsafe(PFN_TYPE Pfn)
}
Page->ReferenceCount++;
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
VOID
@ -533,13 +531,13 @@ ULONG
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 @@ MmGetReferenceCountPage(PFN_TYPE Pfn)
RCount = Page->ReferenceCount;
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(RCount);
}
@ -567,12 +565,12 @@ VOID
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 @@ MmDereferencePage(PFN_TYPE Pfn)
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 @@ MmGetLockCountPage(PFN_TYPE Pfn)
}
LockCount = Page->LockCount;
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(LockCount);
}
@ -662,12 +660,12 @@ VOID
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 @@ MmLockPageUnsafe(PFN_TYPE Pfn)
}
Page->LockCount++;
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
VOID
@ -693,12 +691,12 @@ VOID
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 @@ MmUnlockPage(PFN_TYPE Pfn)
}
Page->LockCount--;
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
PFN_TYPE
@ -718,12 +716,12 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
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 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
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 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
MmStats.NrSystemPages++;
MmStats.NrFreePages--;
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
PfnOffset = PageDescriptor - MmPageArray;
if (NeedClear)
@ -805,7 +803,7 @@ MmAllocPagesSpecifyRange(ULONG Consumer,
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 @@ MmAllocPagesSpecifyRange(ULONG Consumer,
if (HighestPage > MmPageArraySize)
HighestPage = MmPageArraySize;
KeAcquireSpinLock(&PageListLock, &oldIrql);
KeAcquireQueuedSpinLock(LockQueuePfnLock);
if (LowestPage == 0 && HighestPage == MmPageArraySize)
{
PLIST_ENTRY ListEntry;
@ -854,7 +852,7 @@ MmAllocPagesSpecifyRange(ULONG Consumer,
{
if (NumberOfPagesFound == 0)
{
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
DPRINT1("MmAllocPagesSpecifyRange(): Out of memory\n");
return -1;
}
@ -925,7 +923,7 @@ MmAllocPagesSpecifyRange(ULONG Consumer,
break;
}
}
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
/* Zero unzero-ed pages */
for (i = 0; i < NumberOfPagesFound; i++)
@ -949,7 +947,7 @@ NTAPI
MmZeroPageThreadMain(PVOID Ignored)
{
NTSTATUS Status;
KIRQL oldIrql;
KIRQL oldIrql = KeGetCurrentIrql();
PLIST_ENTRY ListEntry;
PPHYSICAL_PAGE PageDescriptor;
PFN_TYPE Pfn;
@ -981,7 +979,7 @@ MmZeroPageThreadMain(PVOID Ignored)
return STATUS_SUCCESS;
}
Count = 0;
KeAcquireSpinLock(&PageListLock, &oldIrql);
KeAcquireQueuedSpinLock(LockQueuePfnLock);
while (!IsListEmpty(&FreeUnzeroedPageListHead))
{
ListEntry = RemoveTailList(&FreeUnzeroedPageListHead);
@ -989,11 +987,11 @@ MmZeroPageThreadMain(PVOID Ignored)
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 @@ MmZeroPageThreadMain(PVOID Ignored)
}
DPRINT("Zeroed %d pages.\n", Count);
KeResetEvent(&ZeroPageThreadEvent);
KeReleaseSpinLock(&PageListLock, oldIrql);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
return STATUS_SUCCESS;

View file

@ -391,11 +391,12 @@ MmProbeAndLockPages(IN PMDL Mdl,
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 @@ MmProbeAndLockPages(IN PMDL Mdl,
/*
* Lock the pages
*/
MmLockAddressSpace(AddressSpace);
if (OldIrql < DISPATCH_LEVEL)
MmLockAddressSpace(AddressSpace);
else
MmAcquirePageListLock(&OldIrql);
for (i = 0; i < NrPages; i++)
{
@ -500,8 +504,7 @@ MmProbeAndLockPages(IN PMDL Mdl,
Status = MmAccessFault(FALSE, Address, AccessMode, NULL);
if (!NT_SUCCESS(Status))
{
MmUnlockAddressSpace(AddressSpace);
ExRaiseStatus(STATUS_ACCESS_VIOLATION);
goto cleanup;
}
}
else
@ -524,8 +527,7 @@ MmProbeAndLockPages(IN PMDL Mdl,
MmDereferencePage(Page);
}
}
MmUnlockAddressSpace(AddressSpace);
ExRaiseStatus(STATUS_ACCESS_VIOLATION);
goto cleanup;
}
}
Page = MmGetPfnForProcess(NULL, Address);
@ -539,9 +541,17 @@ MmProbeAndLockPages(IN PMDL Mdl,
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;
}
/*