mirror of
https://github.com/reactos/reactos.git
synced 2024-06-28 00:41:36 +00:00
- 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:
parent
67821bff32
commit
298e26754b
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue