[NTOSKRNL]

Apply indentation of 4 spaces, no code change.

svn path=/trunk/; revision=64531
This commit is contained in:
Timo Kreuzer 2014-10-05 06:33:34 +00:00
parent 4b31efff8f
commit c9252b32bd
9 changed files with 5340 additions and 5333 deletions

View File

@ -26,9 +26,9 @@
/* TYPES ********************************************************************/
typedef struct _MM_ALLOCATION_REQUEST
{
PFN_NUMBER Page;
LIST_ENTRY ListEntry;
KEVENT Event;
PFN_NUMBER Page;
LIST_ENTRY ListEntry;
KEVENT Event;
}
MM_ALLOCATION_REQUEST, *PMM_ALLOCATION_REQUEST;
/* GLOBALS ******************************************************************/
@ -52,15 +52,15 @@ INIT_FUNCTION
NTAPI
MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages)
{
memset(MiMemoryConsumers, 0, sizeof(MiMemoryConsumers));
InitializeListHead(&AllocationListHead);
KeInitializeSpinLock(&AllocationListLock);
memset(MiMemoryConsumers, 0, sizeof(MiMemoryConsumers));
InitializeListHead(&AllocationListHead);
KeInitializeSpinLock(&AllocationListLock);
MiNrTotalPages = NrAvailablePages;
MiNrTotalPages = NrAvailablePages;
/* Set up targets. */
MiMinimumAvailablePages = 128;
MiMinimumPagesPerRun = 256;
/* Set up targets. */
MiMinimumAvailablePages = 128;
MiMinimumPagesPerRun = 256;
if ((NrAvailablePages + NrSystemPages) >= 8192)
{
MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 4 * 3;
@ -73,17 +73,17 @@ MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages)
{
MiMemoryConsumers[MC_CACHE].PagesTarget = NrAvailablePages / 8;
}
MiMemoryConsumers[MC_USER].PagesTarget = NrAvailablePages - MiMinimumAvailablePages;
MiMemoryConsumers[MC_USER].PagesTarget = NrAvailablePages - MiMinimumAvailablePages;
}
VOID
INIT_FUNCTION
NTAPI
MmInitializeMemoryConsumer(ULONG Consumer,
NTSTATUS (*Trim)(ULONG Target, ULONG Priority,
PULONG NrFreed))
MmInitializeMemoryConsumer(
ULONG Consumer,
NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed))
{
MiMemoryConsumers[Consumer].Trim = Trim;
MiMemoryConsumers[Consumer].Trim = Trim;
}
VOID
@ -96,42 +96,42 @@ NTSTATUS
NTAPI
MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
{
PMM_ALLOCATION_REQUEST Request;
PLIST_ENTRY Entry;
KIRQL OldIrql;
PMM_ALLOCATION_REQUEST Request;
PLIST_ENTRY Entry;
KIRQL OldIrql;
if (Page == 0)
{
DPRINT1("Tried to release page zero.\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
if (Page == 0)
{
DPRINT1("Tried to release page zero.\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
if (MmGetReferenceCountPage(Page) == 1)
{
if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
(void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
if ((Entry = ExInterlockedRemoveHeadList(&AllocationListHead, &AllocationListLock)) == NULL)
{
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MmDereferencePage(Page);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
}
else
{
Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry);
MiZeroPhysicalPage(Page);
Request->Page = Page;
KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE);
}
}
else
{
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MmDereferencePage(Page);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
}
if (MmGetReferenceCountPage(Page) == 1)
{
if(Consumer == MC_USER) MmRemoveLRUUserPage(Page);
(void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
if ((Entry = ExInterlockedRemoveHeadList(&AllocationListHead, &AllocationListLock)) == NULL)
{
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MmDereferencePage(Page);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
}
else
{
Request = CONTAINING_RECORD(Entry, MM_ALLOCATION_REQUEST, ListEntry);
MiZeroPhysicalPage(Page);
Request->Page = Page;
KeSetEvent(&Request->Event, IO_NO_INCREMENT, FALSE);
}
}
else
{
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
MmDereferencePage(Page);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
}
return(STATUS_SUCCESS);
return(STATUS_SUCCESS);
}
ULONG
@ -230,8 +230,8 @@ MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages)
static BOOLEAN
MiIsBalancerThread(VOID)
{
return (MiBalancerThreadHandle != NULL) &&
(PsGetCurrentThreadId() == MiBalancerThreadId.UniqueThread);
return (MiBalancerThreadHandle != NULL) &&
(PsGetCurrentThreadId() == MiBalancerThreadId.UniqueThread);
}
VOID
@ -257,181 +257,182 @@ NTAPI
MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
PPFN_NUMBER AllocatedPage)
{
ULONG PagesUsed;
PFN_NUMBER Page;
KIRQL OldIrql;
ULONG PagesUsed;
PFN_NUMBER Page;
KIRQL OldIrql;
/*
* Make sure we don't exceed our individual target.
*/
PagesUsed = InterlockedIncrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
if (PagesUsed > MiMemoryConsumers[Consumer].PagesTarget &&
!MiIsBalancerThread())
{
MmRebalanceMemoryConsumers();
}
/*
* Make sure we don't exceed our individual target.
*/
PagesUsed = InterlockedIncrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
if (PagesUsed > MiMemoryConsumers[Consumer].PagesTarget &&
!MiIsBalancerThread())
{
MmRebalanceMemoryConsumers();
}
/*
* Allocate always memory for the non paged pool and for the pager thread.
*/
if ((Consumer == MC_SYSTEM) || MiIsBalancerThread())
{
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MmAllocPage(Consumer);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
if (Page == 0)
{
KeBugCheck(NO_PAGES_AVAILABLE);
}
if (Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page;
if (MmAvailablePages < MiMinimumAvailablePages)
MmRebalanceMemoryConsumers();
return(STATUS_SUCCESS);
}
/*
* Allocate always memory for the non paged pool and for the pager thread.
*/
if ((Consumer == MC_SYSTEM) || MiIsBalancerThread())
{
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MmAllocPage(Consumer);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
if (Page == 0)
{
KeBugCheck(NO_PAGES_AVAILABLE);
}
if (Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page;
if (MmAvailablePages < MiMinimumAvailablePages)
MmRebalanceMemoryConsumers();
return(STATUS_SUCCESS);
}
/*
* Make sure we don't exceed global targets.
*/
if (MmAvailablePages < MiMinimumAvailablePages)
{
MM_ALLOCATION_REQUEST Request;
/*
* Make sure we don't exceed global targets.
*/
if (MmAvailablePages < MiMinimumAvailablePages)
{
MM_ALLOCATION_REQUEST Request;
if (!CanWait)
{
(void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
MmRebalanceMemoryConsumers();
return(STATUS_NO_MEMORY);
}
if (!CanWait)
{
(void)InterlockedDecrementUL(&MiMemoryConsumers[Consumer].PagesUsed);
MmRebalanceMemoryConsumers();
return(STATUS_NO_MEMORY);
}
/* Insert an allocation request. */
Request.Page = 0;
KeInitializeEvent(&Request.Event, NotificationEvent, FALSE);
/* Insert an allocation request. */
Request.Page = 0;
KeInitializeEvent(&Request.Event, NotificationEvent, FALSE);
ExInterlockedInsertTailList(&AllocationListHead, &Request.ListEntry, &AllocationListLock);
MmRebalanceMemoryConsumers();
ExInterlockedInsertTailList(&AllocationListHead, &Request.ListEntry, &AllocationListLock);
MmRebalanceMemoryConsumers();
KeWaitForSingleObject(&Request.Event,
0,
KernelMode,
FALSE,
NULL);
KeWaitForSingleObject(&Request.Event,
0,
KernelMode,
FALSE,
NULL);
Page = Request.Page;
if (Page == 0)
{
KeBugCheck(NO_PAGES_AVAILABLE);
}
Page = Request.Page;
if (Page == 0)
{
KeBugCheck(NO_PAGES_AVAILABLE);
}
if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page;
if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page;
if (MmAvailablePages < MiMinimumAvailablePages)
{
MmRebalanceMemoryConsumers();
}
if (MmAvailablePages < MiMinimumAvailablePages)
{
MmRebalanceMemoryConsumers();
}
return(STATUS_SUCCESS);
}
return(STATUS_SUCCESS);
}
/*
* Actually allocate the page.
*/
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MmAllocPage(Consumer);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
if (Page == 0)
{
KeBugCheck(NO_PAGES_AVAILABLE);
}
if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page;
/*
* Actually allocate the page.
*/
OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Page = MmAllocPage(Consumer);
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
if (Page == 0)
{
KeBugCheck(NO_PAGES_AVAILABLE);
}
if(Consumer == MC_USER) MmInsertLRULastUserPage(Page);
*AllocatedPage = Page;
if (MmAvailablePages < MiMinimumAvailablePages)
{
MmRebalanceMemoryConsumers();
}
if (MmAvailablePages < MiMinimumAvailablePages)
{
MmRebalanceMemoryConsumers();
}
return(STATUS_SUCCESS);
return(STATUS_SUCCESS);
}
VOID NTAPI
MiBalancerThread(PVOID Unused)
{
PVOID WaitObjects[2];
NTSTATUS Status;
ULONG i;
PVOID WaitObjects[2];
NTSTATUS Status;
ULONG i;
WaitObjects[0] = &MiBalancerEvent;
WaitObjects[1] = &MiBalancerTimer;
WaitObjects[0] = &MiBalancerEvent;
WaitObjects[1] = &MiBalancerTimer;
while (1)
{
Status = KeWaitForMultipleObjects(2,
WaitObjects,
WaitAny,
Executive,
KernelMode,
FALSE,
NULL,
NULL);
while (1)
{
Status = KeWaitForMultipleObjects(2,
WaitObjects,
WaitAny,
Executive,
KernelMode,
FALSE,
NULL,
NULL);
if (Status == STATUS_WAIT_0 || Status == STATUS_WAIT_1)
{
ULONG InitialTarget = 0;
if (Status == STATUS_WAIT_0 || Status == STATUS_WAIT_1)
{
ULONG InitialTarget = 0;
#if (_MI_PAGING_LEVELS == 2)
if (!MiIsBalancerThread())
{
/* Clean up the unused PDEs */
ULONG_PTR Address;
PEPROCESS Process = PsGetCurrentProcess();
/* Acquire PFN lock */
KIRQL OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
PMMPDE pointerPde;
for (Address = (ULONG_PTR)MI_LOWEST_VAD_ADDRESS;
Address < (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS;
Address += (PAGE_SIZE * PTE_COUNT))
if (!MiIsBalancerThread())
{
if (MiQueryPageTableReferences((PVOID)Address) == 0)
/* Clean up the unused PDEs */
ULONG_PTR Address;
PEPROCESS Process = PsGetCurrentProcess();
/* Acquire PFN lock */
KIRQL OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
PMMPDE pointerPde;
for (Address = (ULONG_PTR)MI_LOWEST_VAD_ADDRESS;
Address < (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS;
Address += (PAGE_SIZE * PTE_COUNT))
{
pointerPde = MiAddressToPde(Address);
if (pointerPde->u.Hard.Valid)
MiDeletePte(pointerPde, MiPdeToPte(pointerPde), Process, NULL);
ASSERT(pointerPde->u.Hard.Valid == 0);
if (MiQueryPageTableReferences((PVOID)Address) == 0)
{
pointerPde = MiAddressToPde(Address);
if (pointerPde->u.Hard.Valid)
MiDeletePte(pointerPde, MiPdeToPte(pointerPde), Process, NULL);
ASSERT(pointerPde->u.Hard.Valid == 0);
}
}
/* Release lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
}
#endif
do
{
ULONG OldTarget = InitialTarget;
/* Trim each consumer */
for (i = 0; i < MC_MAXIMUM; i++)
{
InitialTarget = MiTrimMemoryConsumer(i, InitialTarget);
}
/* No pages left to swap! */
if (InitialTarget != 0 &&
InitialTarget == OldTarget)
{
/* Game over */
KeBugCheck(NO_PAGES_AVAILABLE);
}
}
/* Release lock */
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
while (InitialTarget != 0);
}
#endif
do
{
ULONG OldTarget = InitialTarget;
/* Trim each consumer */
for (i = 0; i < MC_MAXIMUM; i++)
{
InitialTarget = MiTrimMemoryConsumer(i, InitialTarget);
}
/* No pages left to swap! */
if (InitialTarget != 0 &&
InitialTarget == OldTarget)
{
/* Game over */
KeBugCheck(NO_PAGES_AVAILABLE);
}
} while (InitialTarget != 0);
}
else
{
DPRINT1("KeWaitForMultipleObjects failed, status = %x\n", Status);
KeBugCheck(MEMORY_MANAGEMENT);
}
}
else
{
DPRINT1("KeWaitForMultipleObjects failed, status = %x\n", Status);
KeBugCheck(MEMORY_MANAGEMENT);
}
}
}
VOID
@ -439,44 +440,44 @@ INIT_FUNCTION
NTAPI
MiInitBalancerThread(VOID)
{
KPRIORITY Priority;
NTSTATUS Status;
KPRIORITY Priority;
NTSTATUS Status;
#if !defined(__GNUC__)
LARGE_INTEGER dummyJunkNeeded;
dummyJunkNeeded.QuadPart = -20000000; /* 2 sec */
;
LARGE_INTEGER dummyJunkNeeded;
dummyJunkNeeded.QuadPart = -20000000; /* 2 sec */
;
#endif
KeInitializeEvent(&MiBalancerEvent, SynchronizationEvent, FALSE);
KeInitializeTimerEx(&MiBalancerTimer, SynchronizationTimer);
KeSetTimerEx(&MiBalancerTimer,
KeInitializeEvent(&MiBalancerEvent, SynchronizationEvent, FALSE);
KeInitializeTimerEx(&MiBalancerTimer, SynchronizationTimer);
KeSetTimerEx(&MiBalancerTimer,
#if defined(__GNUC__)
(LARGE_INTEGER)(LONGLONG)-20000000LL, /* 2 sec */
(LARGE_INTEGER)(LONGLONG)-20000000LL, /* 2 sec */
#else
dummyJunkNeeded,
dummyJunkNeeded,
#endif
2000, /* 2 sec */
NULL);
2000, /* 2 sec */
NULL);
Status = PsCreateSystemThread(&MiBalancerThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
&MiBalancerThreadId,
MiBalancerThread,
NULL);
if (!NT_SUCCESS(Status))
{
KeBugCheck(MEMORY_MANAGEMENT);
}
Status = PsCreateSystemThread(&MiBalancerThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
&MiBalancerThreadId,
MiBalancerThread,
NULL);
if (!NT_SUCCESS(Status))
{
KeBugCheck(MEMORY_MANAGEMENT);
}
Priority = LOW_REALTIME_PRIORITY + 1;
NtSetInformationThread(MiBalancerThreadHandle,
ThreadPriority,
&Priority,
sizeof(Priority));
Priority = LOW_REALTIME_PRIORITY + 1;
NtSetInformationThread(MiBalancerThreadHandle,
ThreadPriority,
&Priority,
sizeof(Priority));
}

View File

@ -448,76 +448,76 @@ VOID
NTAPI
MmSetSavedSwapEntryPage(PFN_NUMBER Pfn, SWAPENTRY SwapEntry)
{
KIRQL oldIrql;
PMMPFN Pfn1;
KIRQL oldIrql;
PMMPFN Pfn1;
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Pfn1->u1.SwapEntry = SwapEntry;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Pfn1->u1.SwapEntry = SwapEntry;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
}
SWAPENTRY
NTAPI
MmGetSavedSwapEntryPage(PFN_NUMBER Pfn)
{
SWAPENTRY SwapEntry;
KIRQL oldIrql;
PMMPFN Pfn1;
SWAPENTRY SwapEntry;
KIRQL oldIrql;
PMMPFN Pfn1;
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
SwapEntry = Pfn1->u1.SwapEntry;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
SwapEntry = Pfn1->u1.SwapEntry;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(SwapEntry);
return(SwapEntry);
}
VOID
NTAPI
MmReferencePage(PFN_NUMBER Pfn)
{
PMMPFN Pfn1;
PMMPFN Pfn1;
DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT);
DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT);
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(Pfn != 0);
ASSERT(Pfn <= MmHighestPhysicalPage);
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(Pfn != 0);
ASSERT(Pfn <= MmHighestPhysicalPage);
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
Pfn1->u3.e2.ReferenceCount++;
ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
Pfn1->u3.e2.ReferenceCount++;
}
ULONG
NTAPI
MmGetReferenceCountPage(PFN_NUMBER Pfn)
{
KIRQL oldIrql;
ULONG RCount;
PMMPFN Pfn1;
KIRQL oldIrql;
ULONG RCount;
PMMPFN Pfn1;
DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
oldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
RCount = Pfn1->u3.e2.ReferenceCount;
RCount = Pfn1->u3.e2.ReferenceCount;
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(RCount);
KeReleaseQueuedSpinLock(LockQueuePfnLock, oldIrql);
return(RCount);
}
BOOLEAN
@ -531,17 +531,17 @@ VOID
NTAPI
MmDereferencePage(PFN_NUMBER Pfn)
{
PMMPFN Pfn1;
DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
PMMPFN Pfn1;
DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
Pfn1 = MiGetPfnEntry(Pfn);
ASSERT(Pfn1);
ASSERT_IS_ROS_PFN(Pfn1);
ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
Pfn1->u3.e2.ReferenceCount--;
if (Pfn1->u3.e2.ReferenceCount == 0)
{
ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
Pfn1->u3.e2.ReferenceCount--;
if (Pfn1->u3.e2.ReferenceCount == 0)
{
/* Mark the page temporarily as valid, we're going to make it free soon */
Pfn1->u3.e1.PageLocation = ActiveAndValid;
@ -551,37 +551,37 @@ MmDereferencePage(PFN_NUMBER Pfn)
/* Bring it back into the free list */
DPRINT("Legacy free: %lx\n", Pfn);
MiInsertPageInFreeList(Pfn);
}
}
}
PFN_NUMBER
NTAPI
MmAllocPage(ULONG Type)
{
PFN_NUMBER PfnOffset;
PMMPFN Pfn1;
PFN_NUMBER PfnOffset;
PMMPFN Pfn1;
PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
PfnOffset = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
if (!PfnOffset)
{
DPRINT1("MmAllocPage(): Out of memory\n");
return 0;
}
if (!PfnOffset)
{
DPRINT1("MmAllocPage(): Out of memory\n");
return 0;
}
DPRINT("Legacy allocate: %lx\n", PfnOffset);
Pfn1 = MiGetPfnEntry(PfnOffset);
Pfn1->u3.e2.ReferenceCount = 1;
Pfn1->u3.e1.PageLocation = ActiveAndValid;
DPRINT("Legacy allocate: %lx\n", PfnOffset);
Pfn1 = MiGetPfnEntry(PfnOffset);
Pfn1->u3.e2.ReferenceCount = 1;
Pfn1->u3.e1.PageLocation = ActiveAndValid;
/* This marks the PFN as a ReactOS PFN */
Pfn1->u4.AweAllocation = TRUE;
/* This marks the PFN as a ReactOS PFN */
Pfn1->u4.AweAllocation = TRUE;
/* Allocate the extra ReactOS Data and zero it out */
Pfn1->u1.SwapEntry = 0;
Pfn1->RmapListHead = NULL;
/* Allocate the extra ReactOS Data and zero it out */
Pfn1->u1.SwapEntry = 0;
Pfn1->RmapListHead = NULL;
return PfnOffset;
return PfnOffset;
}
/* EOF */

File diff suppressed because it is too large Load Diff

View File

@ -21,180 +21,180 @@
NTSTATUS
NTAPI
MmpAccessFault(KPROCESSOR_MODE Mode,
ULONG_PTR Address,
BOOLEAN FromMdl)
ULONG_PTR Address,
BOOLEAN FromMdl)
{
PMMSUPPORT AddressSpace;
MEMORY_AREA* MemoryArea;
NTSTATUS Status;
PMMSUPPORT AddressSpace;
MEMORY_AREA* MemoryArea;
NTSTATUS Status;
DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode, Address);
DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode, Address);
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
{
DPRINT1("Page fault at high IRQL was %u\n", KeGetCurrentIrql());
return(STATUS_UNSUCCESSFUL);
}
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
{
DPRINT1("Page fault at high IRQL was %u\n", KeGetCurrentIrql());
return(STATUS_UNSUCCESSFUL);
}
/*
* Find the memory area for the faulting address
*/
if (Address >= (ULONG_PTR)MmSystemRangeStart)
{
/*
* Check permissions
*/
if (Mode != KernelMode)
{
DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode, Address);
return(STATUS_ACCESS_VIOLATION);
}
AddressSpace = MmGetKernelAddressSpace();
}
else
{
AddressSpace = &PsGetCurrentProcess()->Vm;
}
/*
* Find the memory area for the faulting address
*/
if (Address >= (ULONG_PTR)MmSystemRangeStart)
{
/*
* Check permissions
*/
if (Mode != KernelMode)
{
DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode, Address);
return(STATUS_ACCESS_VIOLATION);
}
AddressSpace = MmGetKernelAddressSpace();
}
else
{
AddressSpace = &PsGetCurrentProcess()->Vm;
}
if (!FromMdl)
{
MmLockAddressSpace(AddressSpace);
}
do
{
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address);
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
{
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
return (STATUS_ACCESS_VIOLATION);
}
if (!FromMdl)
{
MmLockAddressSpace(AddressSpace);
}
do
{
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address);
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
{
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
return (STATUS_ACCESS_VIOLATION);
}
switch (MemoryArea->Type)
{
case MEMORY_AREA_SECTION_VIEW:
switch (MemoryArea->Type)
{
case MEMORY_AREA_SECTION_VIEW:
Status = MmAccessFaultSectionView(AddressSpace,
MemoryArea,
(PVOID)Address);
break;
case MEMORY_AREA_CACHE:
case MEMORY_AREA_CACHE:
// This code locks for itself to keep from having to break a lock
// passed in.
if (!FromMdl)
MmUnlockAddressSpace(AddressSpace);
MmUnlockAddressSpace(AddressSpace);
Status = MmAccessFaultCacheSection(Mode, Address, FromMdl);
if (!FromMdl)
MmLockAddressSpace(AddressSpace);
MmLockAddressSpace(AddressSpace);
break;
default:
default:
Status = STATUS_ACCESS_VIOLATION;
break;
}
}
while (Status == STATUS_MM_RESTART_OPERATION);
}
}
while (Status == STATUS_MM_RESTART_OPERATION);
DPRINT("Completed page fault handling\n");
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
return(Status);
DPRINT("Completed page fault handling\n");
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
return(Status);
}
NTSTATUS
NTAPI
MmNotPresentFault(KPROCESSOR_MODE Mode,
ULONG_PTR Address,
BOOLEAN FromMdl)
ULONG_PTR Address,
BOOLEAN FromMdl)
{
PMMSUPPORT AddressSpace;
MEMORY_AREA* MemoryArea;
NTSTATUS Status;
PMMSUPPORT AddressSpace;
MEMORY_AREA* MemoryArea;
NTSTATUS Status;
DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address);
DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address);
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
{
DPRINT1("Page fault at high IRQL was %u, address %x\n", KeGetCurrentIrql(), Address);
return(STATUS_UNSUCCESSFUL);
}
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
{
DPRINT1("Page fault at high IRQL was %u, address %x\n", KeGetCurrentIrql(), Address);
return(STATUS_UNSUCCESSFUL);
}
/*
* Find the memory area for the faulting address
*/
if (Address >= (ULONG_PTR)MmSystemRangeStart)
{
/*
* Check permissions
*/
if (Mode != KernelMode)
{
DPRINT1("Address: %x\n", Address);
return(STATUS_ACCESS_VIOLATION);
}
AddressSpace = MmGetKernelAddressSpace();
}
else
{
AddressSpace = &PsGetCurrentProcess()->Vm;
}
/*
* Find the memory area for the faulting address
*/
if (Address >= (ULONG_PTR)MmSystemRangeStart)
{
/*
* Check permissions
*/
if (Mode != KernelMode)
{
DPRINT1("Address: %x\n", Address);
return(STATUS_ACCESS_VIOLATION);
}
AddressSpace = MmGetKernelAddressSpace();
}
else
{
AddressSpace = &PsGetCurrentProcess()->Vm;
}
if (!FromMdl)
{
MmLockAddressSpace(AddressSpace);
}
if (!FromMdl)
{
MmLockAddressSpace(AddressSpace);
}
/*
* Call the memory area specific fault handler
*/
do
{
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address);
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
{
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
return (STATUS_ACCESS_VIOLATION);
}
/*
* Call the memory area specific fault handler
*/
do
{
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address);
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
{
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
return (STATUS_ACCESS_VIOLATION);
}
switch (MemoryArea->Type)
{
case MEMORY_AREA_SECTION_VIEW:
switch (MemoryArea->Type)
{
case MEMORY_AREA_SECTION_VIEW:
Status = MmNotPresentFaultSectionView(AddressSpace,
MemoryArea,
(PVOID)Address,
FromMdl);
break;
case MEMORY_AREA_CACHE:
case MEMORY_AREA_CACHE:
// This code locks for itself to keep from having to break a lock
// passed in.
if (!FromMdl)
MmUnlockAddressSpace(AddressSpace);
MmUnlockAddressSpace(AddressSpace);
Status = MmNotPresentFaultCacheSection(Mode, Address, FromMdl);
if (!FromMdl)
MmLockAddressSpace(AddressSpace);
MmLockAddressSpace(AddressSpace);
break;
default:
default:
Status = STATUS_ACCESS_VIOLATION;
break;
}
}
while (Status == STATUS_MM_RESTART_OPERATION);
}
}
while (Status == STATUS_MM_RESTART_OPERATION);
DPRINT("Completed page fault handling\n");
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
return(Status);
DPRINT("Completed page fault handling\n");
if (!FromMdl)
{
MmUnlockAddressSpace(AddressSpace);
}
return(Status);
}
extern BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address);
@ -235,8 +235,8 @@ MmAccessFault(IN BOOLEAN StoreInstruction,
/* Is this an ARM3 memory area, or is there no address space yet? */
if (((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3)) ||
(!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) ||
(!MmGetKernelAddressSpace()))
(!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) ||
(!MmGetKernelAddressSpace()))
{
/* This is an ARM3 fault */
DPRINT("ARM3 fault %p\n", MemoryArea);

View File

@ -299,36 +299,36 @@ VOID
NTAPI
MmMpwThreadMain(PVOID Parameter)
{
NTSTATUS Status;
ULONG PagesWritten;
LARGE_INTEGER Timeout;
NTSTATUS Status;
ULONG PagesWritten;
LARGE_INTEGER Timeout;
UNREFERENCED_PARAMETER(Parameter);
UNREFERENCED_PARAMETER(Parameter);
Timeout.QuadPart = -50000000;
Timeout.QuadPart = -50000000;
for(;;)
{
Status = KeWaitForSingleObject(&MpwThreadEvent,
0,
KernelMode,
FALSE,
&Timeout);
if (!NT_SUCCESS(Status))
{
DbgPrint("MpwThread: Wait failed\n");
KeBugCheck(MEMORY_MANAGEMENT);
return;
}
for(;;)
{
Status = KeWaitForSingleObject(&MpwThreadEvent,
0,
KernelMode,
FALSE,
&Timeout);
if (!NT_SUCCESS(Status))
{
DbgPrint("MpwThread: Wait failed\n");
KeBugCheck(MEMORY_MANAGEMENT);
return;
}
PagesWritten = 0;
PagesWritten = 0;
#ifndef NEWCC
// XXX arty -- we flush when evicting pages or destorying cache
// sections.
CcRosFlushDirtyPages(128, &PagesWritten, FALSE);
// XXX arty -- we flush when evicting pages or destorying cache
// sections.
CcRosFlushDirtyPages(128, &PagesWritten, FALSE);
#endif
}
}
}
NTSTATUS
@ -336,31 +336,31 @@ NTAPI
INIT_FUNCTION
MmInitMpwThread(VOID)
{
KPRIORITY Priority;
NTSTATUS Status;
CLIENT_ID MpwThreadId;
KPRIORITY Priority;
NTSTATUS Status;
CLIENT_ID MpwThreadId;
KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE);
Status = PsCreateSystemThread(&MpwThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
&MpwThreadId,
MmMpwThreadMain,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Status = PsCreateSystemThread(&MpwThreadHandle,
THREAD_ALL_ACCESS,
NULL,
NULL,
&MpwThreadId,
MmMpwThreadMain,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Priority = 27;
NtSetInformationThread(MpwThreadHandle,
ThreadPriority,
&Priority,
sizeof(Priority));
Priority = 27;
NtSetInformationThread(MpwThreadHandle,
ThreadPriority,
&Priority,
sizeof(Priority));
return(STATUS_SUCCESS);
return(STATUS_SUCCESS);
}
NTSTATUS
@ -430,8 +430,8 @@ MmInitSystem(IN ULONG Phase,
// by the fault handler.
//
MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool,
sizeof(MMPTE),
' mM');
sizeof(MMPTE),
' mM');
if (!MmSharedUserDataPte) return FALSE;
//

File diff suppressed because it is too large Load Diff

View File

@ -22,12 +22,12 @@ InsertAfterEntry(PLIST_ENTRY Previous,
* FUNCTION: Insert a list entry after another entry in the list
*/
{
Previous->Flink->Blink = Entry;
Previous->Flink->Blink = Entry;
Entry->Flink = Previous->Flink;
Entry->Blink = Previous;
Entry->Flink = Previous->Flink;
Entry->Blink = Previous;
Previous->Flink = Entry;
Previous->Flink = Entry;
}
static PMM_REGION
@ -36,71 +36,71 @@ MmSplitRegion(PMM_REGION InitialRegion, PVOID InitialBaseAddress,
ULONG NewProtect, PMMSUPPORT AddressSpace,
PMM_ALTER_REGION_FUNC AlterFunc)
{
PMM_REGION NewRegion1;
PMM_REGION NewRegion2;
SIZE_T InternalLength;
PMM_REGION NewRegion1;
PMM_REGION NewRegion2;
SIZE_T InternalLength;
/* Allocate this in front otherwise the failure case is too difficult. */
NewRegion2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
TAG_MM_REGION);
if (NewRegion2 == NULL)
{
return(NULL);
}
/* Allocate this in front otherwise the failure case is too difficult. */
NewRegion2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
TAG_MM_REGION);
if (NewRegion2 == NULL)
{
return(NULL);
}
/* Create the new region. */
NewRegion1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
TAG_MM_REGION);
if (NewRegion1 == NULL)
{
ExFreePoolWithTag(NewRegion2, TAG_MM_REGION);
return(NULL);
}
NewRegion1->Type = NewType;
NewRegion1->Protect = NewProtect;
InternalLength = ((char*)InitialBaseAddress + InitialRegion->Length) - (char*)StartAddress;
InternalLength = min(InternalLength, Length);
NewRegion1->Length = InternalLength;
InsertAfterEntry(&InitialRegion->RegionListEntry,
&NewRegion1->RegionListEntry);
/* Create the new region. */
NewRegion1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
TAG_MM_REGION);
if (NewRegion1 == NULL)
{
ExFreePoolWithTag(NewRegion2, TAG_MM_REGION);
return(NULL);
}
NewRegion1->Type = NewType;
NewRegion1->Protect = NewProtect;
InternalLength = ((char*)InitialBaseAddress + InitialRegion->Length) - (char*)StartAddress;
InternalLength = min(InternalLength, Length);
NewRegion1->Length = InternalLength;
InsertAfterEntry(&InitialRegion->RegionListEntry,
&NewRegion1->RegionListEntry);
/*
* Call our helper function to do the changes on the addresses contained
* in the initial region.
*/
AlterFunc(AddressSpace, StartAddress, InternalLength, InitialRegion->Type,
InitialRegion->Protect, NewType, NewProtect);
/*
* Call our helper function to do the changes on the addresses contained
* in the initial region.
*/
AlterFunc(AddressSpace, StartAddress, InternalLength, InitialRegion->Type,
InitialRegion->Protect, NewType, NewProtect);
/*
* If necessary create a new region for the portion of the initial region
* beyond the range of addresses to alter.
*/
if (((char*)InitialBaseAddress + InitialRegion->Length) > ((char*)StartAddress + Length))
{
NewRegion2->Type = InitialRegion->Type;
NewRegion2->Protect = InitialRegion->Protect;
NewRegion2->Length = ((char*)InitialBaseAddress + InitialRegion->Length) -
((char*)StartAddress + Length);
InsertAfterEntry(&NewRegion1->RegionListEntry,
&NewRegion2->RegionListEntry);
}
else
{
ExFreePoolWithTag(NewRegion2, TAG_MM_REGION);
}
/*
* If necessary create a new region for the portion of the initial region
* beyond the range of addresses to alter.
*/
if (((char*)InitialBaseAddress + InitialRegion->Length) > ((char*)StartAddress + Length))
{
NewRegion2->Type = InitialRegion->Type;
NewRegion2->Protect = InitialRegion->Protect;
NewRegion2->Length = ((char*)InitialBaseAddress + InitialRegion->Length) -
((char*)StartAddress + Length);
InsertAfterEntry(&NewRegion1->RegionListEntry,
&NewRegion2->RegionListEntry);
}
else
{
ExFreePoolWithTag(NewRegion2, TAG_MM_REGION);
}
/* Either remove or shrink the initial region. */
if (InitialBaseAddress == StartAddress)
{
RemoveEntryList(&InitialRegion->RegionListEntry);
ExFreePoolWithTag(InitialRegion, TAG_MM_REGION);
}
else
{
InitialRegion->Length = (char*)StartAddress - (char*)InitialBaseAddress;
}
/* Either remove or shrink the initial region. */
if (InitialBaseAddress == StartAddress)
{
RemoveEntryList(&InitialRegion->RegionListEntry);
ExFreePoolWithTag(InitialRegion, TAG_MM_REGION);
}
else
{
InitialRegion->Length = (char*)StartAddress - (char*)InitialBaseAddress;
}
return(NewRegion1);
return(NewRegion1);
}
NTSTATUS
@ -109,129 +109,129 @@ MmAlterRegion(PMMSUPPORT AddressSpace, PVOID BaseAddress,
PLIST_ENTRY RegionListHead, PVOID StartAddress, SIZE_T Length,
ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc)
{
PMM_REGION InitialRegion;
PVOID InitialBaseAddress = NULL;
PMM_REGION NewRegion;
PLIST_ENTRY CurrentEntry;
PMM_REGION CurrentRegion = NULL;
PVOID CurrentBaseAddress;
SIZE_T RemainingLength;
PMM_REGION InitialRegion;
PVOID InitialBaseAddress = NULL;
PMM_REGION NewRegion;
PLIST_ENTRY CurrentEntry;
PMM_REGION CurrentRegion = NULL;
PVOID CurrentBaseAddress;
SIZE_T RemainingLength;
/*
* Find the first region containing part of the range of addresses to
* be altered.
*/
InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress,
&InitialBaseAddress);
/*
* If necessary then split the region into the affected and unaffected parts.
*/
if (InitialRegion->Type != NewType || InitialRegion->Protect != NewProtect)
{
NewRegion = MmSplitRegion(InitialRegion, InitialBaseAddress,
StartAddress, Length, NewType, NewProtect,
AddressSpace, AlterFunc);
if (NewRegion == NULL)
{
return(STATUS_NO_MEMORY);
}
if(NewRegion->Length < Length)
RemainingLength = Length - NewRegion->Length;
else
RemainingLength = 0;
}
else
{
NewRegion = InitialRegion;
if(((ULONG_PTR)InitialBaseAddress + NewRegion->Length) <
((ULONG_PTR)StartAddress + Length))
RemainingLength = ((ULONG_PTR)StartAddress + Length) - ((ULONG_PTR)InitialBaseAddress + NewRegion->Length);
else
RemainingLength = 0;
}
/*
* Find the first region containing part of the range of addresses to
* be altered.
*/
InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress,
&InitialBaseAddress);
/*
* If necessary then split the region into the affected and unaffected parts.
*/
if (InitialRegion->Type != NewType || InitialRegion->Protect != NewProtect)
{
NewRegion = MmSplitRegion(InitialRegion, InitialBaseAddress,
StartAddress, Length, NewType, NewProtect,
AddressSpace, AlterFunc);
if (NewRegion == NULL)
{
return(STATUS_NO_MEMORY);
}
if(NewRegion->Length < Length)
RemainingLength = Length - NewRegion->Length;
else
RemainingLength = 0;
}
else
{
NewRegion = InitialRegion;
if(((ULONG_PTR)InitialBaseAddress + NewRegion->Length) <
((ULONG_PTR)StartAddress + Length))
RemainingLength = ((ULONG_PTR)StartAddress + Length) - ((ULONG_PTR)InitialBaseAddress + NewRegion->Length);
else
RemainingLength = 0;
}
/*
* Free any complete regions that are containing in the range of addresses
* and call the helper function to actually do the changes.
*/
CurrentEntry = NewRegion->RegionListEntry.Flink;
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry);
CurrentBaseAddress = (char*)StartAddress + NewRegion->Length;
while (RemainingLength > 0 && CurrentRegion->Length <= RemainingLength &&
CurrentEntry != RegionListHead)
{
if (CurrentRegion->Type != NewType ||
CurrentRegion->Protect != NewProtect)
{
AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length,
CurrentRegion->Type, CurrentRegion->Protect,
NewType, NewProtect);
}
/*
* Free any complete regions that are containing in the range of addresses
* and call the helper function to actually do the changes.
*/
CurrentEntry = NewRegion->RegionListEntry.Flink;
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry);
CurrentBaseAddress = (char*)StartAddress + NewRegion->Length;
while (RemainingLength > 0 && CurrentRegion->Length <= RemainingLength &&
CurrentEntry != RegionListHead)
{
if (CurrentRegion->Type != NewType ||
CurrentRegion->Protect != NewProtect)
{
AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length,
CurrentRegion->Type, CurrentRegion->Protect,
NewType, NewProtect);
}
CurrentBaseAddress = (PVOID)((ULONG_PTR)CurrentBaseAddress + CurrentRegion->Length);
NewRegion->Length += CurrentRegion->Length;
RemainingLength -= CurrentRegion->Length;
CurrentEntry = CurrentEntry->Flink;
RemoveEntryList(&CurrentRegion->RegionListEntry);
ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry);
}
CurrentBaseAddress = (PVOID)((ULONG_PTR)CurrentBaseAddress + CurrentRegion->Length);
NewRegion->Length += CurrentRegion->Length;
RemainingLength -= CurrentRegion->Length;
CurrentEntry = CurrentEntry->Flink;
RemoveEntryList(&CurrentRegion->RegionListEntry);
ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry);
}
/*
* Split any final region.
*/
if (RemainingLength > 0 && CurrentEntry != RegionListHead)
{
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry);
if (CurrentRegion->Type != NewType ||
CurrentRegion->Protect != NewProtect)
{
AlterFunc(AddressSpace, CurrentBaseAddress, RemainingLength,
CurrentRegion->Type, CurrentRegion->Protect,
NewType, NewProtect);
}
NewRegion->Length += RemainingLength;
CurrentRegion->Length -= RemainingLength;
}
/*
* Split any final region.
*/
if (RemainingLength > 0 && CurrentEntry != RegionListHead)
{
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry);
if (CurrentRegion->Type != NewType ||
CurrentRegion->Protect != NewProtect)
{
AlterFunc(AddressSpace, CurrentBaseAddress, RemainingLength,
CurrentRegion->Type, CurrentRegion->Protect,
NewType, NewProtect);
}
NewRegion->Length += RemainingLength;
CurrentRegion->Length -= RemainingLength;
}
/*
* If the region after the new region has the same type then merge them.
*/
if (NewRegion->RegionListEntry.Flink != RegionListHead)
{
CurrentEntry = NewRegion->RegionListEntry.Flink;
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry);
if (CurrentRegion->Type == NewRegion->Type &&
CurrentRegion->Protect == NewRegion->Protect)
{
NewRegion->Length += CurrentRegion->Length;
RemoveEntryList(&CurrentRegion->RegionListEntry);
ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
}
}
/*
* If the region after the new region has the same type then merge them.
*/
if (NewRegion->RegionListEntry.Flink != RegionListHead)
{
CurrentEntry = NewRegion->RegionListEntry.Flink;
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry);
if (CurrentRegion->Type == NewRegion->Type &&
CurrentRegion->Protect == NewRegion->Protect)
{
NewRegion->Length += CurrentRegion->Length;
RemoveEntryList(&CurrentRegion->RegionListEntry);
ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
}
}
/*
* If the region before the new region has the same type then merge them.
*/
if (NewRegion->RegionListEntry.Blink != RegionListHead)
{
CurrentEntry = NewRegion->RegionListEntry.Blink;
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry);
if (CurrentRegion->Type == NewRegion->Type &&
CurrentRegion->Protect == NewRegion->Protect)
{
NewRegion->Length += CurrentRegion->Length;
RemoveEntryList(&CurrentRegion->RegionListEntry);
ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
}
}
/*
* If the region before the new region has the same type then merge them.
*/
if (NewRegion->RegionListEntry.Blink != RegionListHead)
{
CurrentEntry = NewRegion->RegionListEntry.Blink;
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry);
if (CurrentRegion->Type == NewRegion->Type &&
CurrentRegion->Protect == NewRegion->Protect)
{
NewRegion->Length += CurrentRegion->Length;
RemoveEntryList(&CurrentRegion->RegionListEntry);
ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
}
}
return(STATUS_SUCCESS);
return(STATUS_SUCCESS);
}
VOID
@ -239,17 +239,17 @@ NTAPI
MmInitializeRegion(PLIST_ENTRY RegionListHead, SIZE_T Length, ULONG Type,
ULONG Protect)
{
PMM_REGION Region;
PMM_REGION Region;
Region = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
TAG_MM_REGION);
if (!Region) return;
Region = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
TAG_MM_REGION);
if (!Region) return;
Region->Type = Type;
Region->Protect = Protect;
Region->Length = Length;
InitializeListHead(RegionListHead);
InsertHeadList(RegionListHead, &Region->RegionListEntry);
Region->Type = Type;
Region->Protect = Protect;
Region->Length = Length;
InitializeListHead(RegionListHead);
InsertHeadList(RegionListHead, &Region->RegionListEntry);
}
PMM_REGION
@ -257,29 +257,29 @@ NTAPI
MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address,
PVOID* RegionBaseAddress)
{
PLIST_ENTRY current_entry;
PMM_REGION current;
PVOID StartAddress = BaseAddress;
PLIST_ENTRY current_entry;
PMM_REGION current;
PVOID StartAddress = BaseAddress;
current_entry = RegionListHead->Flink;
while (current_entry != RegionListHead)
{
current = CONTAINING_RECORD(current_entry, MM_REGION, RegionListEntry);
current_entry = RegionListHead->Flink;
while (current_entry != RegionListHead)
{
current = CONTAINING_RECORD(current_entry, MM_REGION, RegionListEntry);
if (StartAddress <= Address &&
((char*)StartAddress + current->Length) > (char*)Address)
{
if (RegionBaseAddress != NULL)
{
*RegionBaseAddress = StartAddress;
}
return(current);
}
if (StartAddress <= Address &&
((char*)StartAddress + current->Length) > (char*)Address)
{
if (RegionBaseAddress != NULL)
{
*RegionBaseAddress = StartAddress;
}
return(current);
}
current_entry = current_entry->Flink;
current_entry = current_entry->Flink;
StartAddress = (PVOID)((ULONG_PTR)StartAddress + current->Length);
StartAddress = (PVOID)((ULONG_PTR)StartAddress + current->Length);
}
return(NULL);
}
return(NULL);
}

View File

@ -42,224 +42,224 @@ INIT_FUNCTION
NTAPI
MmInitializeRmapList(VOID)
{
ExInitializeFastMutex(&RmapListLock);
ExInitializeNPagedLookasideList (&RmapLookasideList,
NULL,
RmapListFree,
0,
sizeof(MM_RMAP_ENTRY),
TAG_RMAP,
50);
ExInitializeFastMutex(&RmapListLock);
ExInitializeNPagedLookasideList (&RmapLookasideList,
NULL,
RmapListFree,
0,
sizeof(MM_RMAP_ENTRY),
TAG_RMAP,
50);
}
NTSTATUS
NTAPI
MmPageOutPhysicalAddress(PFN_NUMBER Page)
{
PMM_RMAP_ENTRY entry;
PMEMORY_AREA MemoryArea;
PMMSUPPORT AddressSpace;
ULONG Type;
PVOID Address;
PEPROCESS Process;
ULONGLONG Offset;
NTSTATUS Status = STATUS_SUCCESS;
PMM_RMAP_ENTRY entry;
PMEMORY_AREA MemoryArea;
PMMSUPPORT AddressSpace;
ULONG Type;
PVOID Address;
PEPROCESS Process;
ULONGLONG Offset;
NTSTATUS Status = STATUS_SUCCESS;
ExAcquireFastMutex(&RmapListLock);
entry = MmGetRmapListHeadPage(Page);
ExAcquireFastMutex(&RmapListLock);
entry = MmGetRmapListHeadPage(Page);
#ifdef NEWCC
// Special case for NEWCC: we can have a page that's only in a segment
// page table
if (entry && RMAP_IS_SEGMENT(entry->Address) && entry->Next == NULL)
{
/* NEWCC does locking itself */
ExReleaseFastMutex(&RmapListLock);
return MmpPageOutPhysicalAddress(Page);
}
// Special case for NEWCC: we can have a page that's only in a segment
// page table
if (entry && RMAP_IS_SEGMENT(entry->Address) && entry->Next == NULL)
{
/* NEWCC does locking itself */
ExReleaseFastMutex(&RmapListLock);
return MmpPageOutPhysicalAddress(Page);
}
#endif
while (entry && RMAP_IS_SEGMENT(entry->Address))
entry = entry->Next;
while (entry && RMAP_IS_SEGMENT(entry->Address))
entry = entry->Next;
if (entry == NULL)
{
ExReleaseFastMutex(&RmapListLock);
return(STATUS_UNSUCCESSFUL);
}
if (entry == NULL)
{
ExReleaseFastMutex(&RmapListLock);
return(STATUS_UNSUCCESSFUL);
}
Process = entry->Process;
Process = entry->Process;
Address = entry->Address;
Address = entry->Address;
if ((((ULONG_PTR)Address) & 0xFFF) != 0)
{
KeBugCheck(MEMORY_MANAGEMENT);
}
if ((((ULONG_PTR)Address) & 0xFFF) != 0)
{
KeBugCheck(MEMORY_MANAGEMENT);
}
if (Address < MmSystemRangeStart)
{
if (!ExAcquireRundownProtection(&Process->RundownProtect))
{
ExReleaseFastMutex(&RmapListLock);
return STATUS_PROCESS_IS_TERMINATING;
}
if (Address < MmSystemRangeStart)
{
if (!ExAcquireRundownProtection(&Process->RundownProtect))
{
ExReleaseFastMutex(&RmapListLock);
return STATUS_PROCESS_IS_TERMINATING;
}
Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode);
ExReleaseFastMutex(&RmapListLock);
if (!NT_SUCCESS(Status))
{
ExReleaseRundownProtection(&Process->RundownProtect);
return Status;
}
AddressSpace = &Process->Vm;
}
else
{
ExReleaseFastMutex(&RmapListLock);
AddressSpace = MmGetKernelAddressSpace();
}
Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode);
ExReleaseFastMutex(&RmapListLock);
if (!NT_SUCCESS(Status))
{
ExReleaseRundownProtection(&Process->RundownProtect);
return Status;
}
AddressSpace = &Process->Vm;
}
else
{
ExReleaseFastMutex(&RmapListLock);
AddressSpace = MmGetKernelAddressSpace();
}
MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
{
MmUnlockAddressSpace(AddressSpace);
if (Address < MmSystemRangeStart)
{
ExReleaseRundownProtection(&Process->RundownProtect);
ObDereferenceObject(Process);
}
return(STATUS_UNSUCCESSFUL);
}
Type = MemoryArea->Type;
if (Type == MEMORY_AREA_SECTION_VIEW)
{
ULONG_PTR Entry;
Offset = MemoryArea->Data.SectionData.ViewOffset.QuadPart +
((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress);
MmLockSectionSegment(MemoryArea->Data.SectionData.Segment);
/*
* Get or create a pageop
*/
Entry = MmGetPageEntrySectionSegment(MemoryArea->Data.SectionData.Segment,
(PLARGE_INTEGER)&Offset);
if (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY)
{
MmUnlockSectionSegment(MemoryArea->Data.SectionData.Segment);
MmUnlockAddressSpace(AddressSpace);
if (Address < MmSystemRangeStart)
{
MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
{
MmUnlockAddressSpace(AddressSpace);
if (Address < MmSystemRangeStart)
{
ExReleaseRundownProtection(&Process->RundownProtect);
ObDereferenceObject(Process);
}
return(STATUS_UNSUCCESSFUL);
}
}
return(STATUS_UNSUCCESSFUL);
}
Type = MemoryArea->Type;
if (Type == MEMORY_AREA_SECTION_VIEW)
{
ULONG_PTR Entry;
Offset = MemoryArea->Data.SectionData.ViewOffset.QuadPart +
((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress);
MmSetPageEntrySectionSegment(MemoryArea->Data.SectionData.Segment, (PLARGE_INTEGER)&Offset, MAKE_SWAP_SSE(MM_WAIT_ENTRY));
MmLockSectionSegment(MemoryArea->Data.SectionData.Segment);
/*
* Release locks now we have a page op.
*/
MmUnlockSectionSegment(MemoryArea->Data.SectionData.Segment);
MmUnlockAddressSpace(AddressSpace);
/*
* Get or create a pageop
*/
Entry = MmGetPageEntrySectionSegment(MemoryArea->Data.SectionData.Segment,
(PLARGE_INTEGER)&Offset);
if (Entry && IS_SWAP_FROM_SSE(Entry) && SWAPENTRY_FROM_SSE(Entry) == MM_WAIT_ENTRY)
{
MmUnlockSectionSegment(MemoryArea->Data.SectionData.Segment);
MmUnlockAddressSpace(AddressSpace);
if (Address < MmSystemRangeStart)
{
ExReleaseRundownProtection(&Process->RundownProtect);
ObDereferenceObject(Process);
}
return(STATUS_UNSUCCESSFUL);
}
/*
* Do the actual page out work.
*/
Status = MmPageOutSectionView(AddressSpace, MemoryArea, Address, Entry);
}
else if (Type == MEMORY_AREA_CACHE)
{
/* NEWCC does locking itself */
MmUnlockAddressSpace(AddressSpace);
Status = MmpPageOutPhysicalAddress(Page);
}
else
{
KeBugCheck(MEMORY_MANAGEMENT);
}
MmSetPageEntrySectionSegment(MemoryArea->Data.SectionData.Segment, (PLARGE_INTEGER)&Offset, MAKE_SWAP_SSE(MM_WAIT_ENTRY));
if (Address < MmSystemRangeStart)
{
ExReleaseRundownProtection(&Process->RundownProtect);
ObDereferenceObject(Process);
}
return(Status);
/*
* Release locks now we have a page op.
*/
MmUnlockSectionSegment(MemoryArea->Data.SectionData.Segment);
MmUnlockAddressSpace(AddressSpace);
/*
* Do the actual page out work.
*/
Status = MmPageOutSectionView(AddressSpace, MemoryArea, Address, Entry);
}
else if (Type == MEMORY_AREA_CACHE)
{
/* NEWCC does locking itself */
MmUnlockAddressSpace(AddressSpace);
Status = MmpPageOutPhysicalAddress(Page);
}
else
{
KeBugCheck(MEMORY_MANAGEMENT);
}
if (Address < MmSystemRangeStart)
{
ExReleaseRundownProtection(&Process->RundownProtect);
ObDereferenceObject(Process);
}
return(Status);
}
VOID
NTAPI
MmSetCleanAllRmaps(PFN_NUMBER Page)
{
PMM_RMAP_ENTRY current_entry;
PMM_RMAP_ENTRY current_entry;
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL)
{
DPRINT1("MmIsDirtyRmap: No rmaps.\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
while (current_entry != NULL)
{
if (!RMAP_IS_SEGMENT(current_entry->Address))
MmSetCleanPage(current_entry->Process, current_entry->Address);
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL)
{
DPRINT1("MmIsDirtyRmap: No rmaps.\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
while (current_entry != NULL)
{
if (!RMAP_IS_SEGMENT(current_entry->Address))
MmSetCleanPage(current_entry->Process, current_entry->Address);
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
}
VOID
NTAPI
MmSetDirtyAllRmaps(PFN_NUMBER Page)
{
PMM_RMAP_ENTRY current_entry;
PMM_RMAP_ENTRY current_entry;
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL)
{
DPRINT1("MmIsDirtyRmap: No rmaps.\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
while (current_entry != NULL)
{
if (!RMAP_IS_SEGMENT(current_entry->Address))
MmSetDirtyPage(current_entry->Process, current_entry->Address);
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL)
{
DPRINT1("MmIsDirtyRmap: No rmaps.\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
while (current_entry != NULL)
{
if (!RMAP_IS_SEGMENT(current_entry->Address))
MmSetDirtyPage(current_entry->Process, current_entry->Address);
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
}
BOOLEAN
NTAPI
MmIsDirtyPageRmap(PFN_NUMBER Page)
{
PMM_RMAP_ENTRY current_entry;
PMM_RMAP_ENTRY current_entry;
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL)
{
ExReleaseFastMutex(&RmapListLock);
return(FALSE);
}
while (current_entry != NULL)
{
if (
!RMAP_IS_SEGMENT(current_entry->Address) &&
MmIsDirtyPage(current_entry->Process, current_entry->Address))
{
ExReleaseFastMutex(&RmapListLock);
return(TRUE);
}
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
return(FALSE);
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL)
{
ExReleaseFastMutex(&RmapListLock);
return(FALSE);
}
while (current_entry != NULL)
{
if (
!RMAP_IS_SEGMENT(current_entry->Address) &&
MmIsDirtyPage(current_entry->Process, current_entry->Address))
{
ExReleaseFastMutex(&RmapListLock);
return(TRUE);
}
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
return(FALSE);
}
VOID
@ -267,75 +267,75 @@ NTAPI
MmInsertRmap(PFN_NUMBER Page, PEPROCESS Process,
PVOID Address)
{
PMM_RMAP_ENTRY current_entry;
PMM_RMAP_ENTRY new_entry;
ULONG PrevSize;
if (!RMAP_IS_SEGMENT(Address))
Address = (PVOID)PAGE_ROUND_DOWN(Address);
PMM_RMAP_ENTRY current_entry;
PMM_RMAP_ENTRY new_entry;
ULONG PrevSize;
if (!RMAP_IS_SEGMENT(Address))
Address = (PVOID)PAGE_ROUND_DOWN(Address);
new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList);
if (new_entry == NULL)
{
KeBugCheck(MEMORY_MANAGEMENT);
}
new_entry->Address = Address;
new_entry->Process = (PEPROCESS)Process;
new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList);
if (new_entry == NULL)
{
KeBugCheck(MEMORY_MANAGEMENT);
}
new_entry->Address = Address;
new_entry->Process = (PEPROCESS)Process;
#if DBG
#ifdef __GNUC__
new_entry->Caller = __builtin_return_address(0);
new_entry->Caller = __builtin_return_address(0);
#else
new_entry->Caller = _ReturnAddress();
new_entry->Caller = _ReturnAddress();
#endif
#endif
if (
!RMAP_IS_SEGMENT(Address) &&
MmGetPfnForProcess(Process, Address) != Page)
{
DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical "
"address 0x%.8X\n", Process ? Process->UniqueProcessId : 0,
Address,
MmGetPfnForProcess(Process, Address) << PAGE_SHIFT,
Page << PAGE_SHIFT);
KeBugCheck(MEMORY_MANAGEMENT);
}
if (
!RMAP_IS_SEGMENT(Address) &&
MmGetPfnForProcess(Process, Address) != Page)
{
DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical "
"address 0x%.8X\n", Process ? Process->UniqueProcessId : 0,
Address,
MmGetPfnForProcess(Process, Address) << PAGE_SHIFT,
Page << PAGE_SHIFT);
KeBugCheck(MEMORY_MANAGEMENT);
}
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
new_entry->Next = current_entry;
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
new_entry->Next = current_entry;
#if DBG
while (current_entry)
{
if (current_entry->Address == new_entry->Address && current_entry->Process == new_entry->Process)
{
DbgPrint("MmInsertRmap tries to add a second rmap entry for address %p\n current caller ",
current_entry->Address);
DbgPrint("%p", new_entry->Caller);
DbgPrint("\n previous caller ");
DbgPrint("%p", current_entry->Caller);
DbgPrint("\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
current_entry = current_entry->Next;
}
while (current_entry)
{
if (current_entry->Address == new_entry->Address && current_entry->Process == new_entry->Process)
{
DbgPrint("MmInsertRmap tries to add a second rmap entry for address %p\n current caller ",
current_entry->Address);
DbgPrint("%p", new_entry->Caller);
DbgPrint("\n previous caller ");
DbgPrint("%p", current_entry->Caller);
DbgPrint("\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
current_entry = current_entry->Next;
}
#endif
MmSetRmapListHeadPage(Page, new_entry);
ExReleaseFastMutex(&RmapListLock);
if (!RMAP_IS_SEGMENT(Address))
{
if (Process == NULL)
{
Process = PsInitialSystemProcess;
}
if (Process)
{
PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE);
if (PrevSize >= Process->Vm.PeakWorkingSetSize)
{
Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE;
}
}
}
MmSetRmapListHeadPage(Page, new_entry);
ExReleaseFastMutex(&RmapListLock);
if (!RMAP_IS_SEGMENT(Address))
{
if (Process == NULL)
{
Process = PsInitialSystemProcess;
}
if (Process)
{
PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE);
if (PrevSize >= Process->Vm.PeakWorkingSetSize)
{
Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE;
}
}
}
}
VOID
@ -344,47 +344,47 @@ MmDeleteAllRmaps(PFN_NUMBER Page, PVOID Context,
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process,
PVOID Address))
{
PMM_RMAP_ENTRY current_entry;
PMM_RMAP_ENTRY previous_entry;
PEPROCESS Process;
PMM_RMAP_ENTRY current_entry;
PMM_RMAP_ENTRY previous_entry;
PEPROCESS Process;
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL)
{
DPRINT1("MmDeleteAllRmaps: No rmaps.\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
MmSetRmapListHeadPage(Page, NULL);
ExReleaseFastMutex(&RmapListLock);
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL)
{
DPRINT1("MmDeleteAllRmaps: No rmaps.\n");
KeBugCheck(MEMORY_MANAGEMENT);
}
MmSetRmapListHeadPage(Page, NULL);
ExReleaseFastMutex(&RmapListLock);
while (current_entry != NULL)
{
previous_entry = current_entry;
current_entry = current_entry->Next;
if (!RMAP_IS_SEGMENT(previous_entry->Address))
{
if (DeleteMapping)
{
DeleteMapping(Context, previous_entry->Process,
previous_entry->Address);
}
Process = previous_entry->Process;
ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
if (Process == NULL)
{
Process = PsInitialSystemProcess;
}
if (Process)
{
(void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
}
}
else
{
ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
}
}
while (current_entry != NULL)
{
previous_entry = current_entry;
current_entry = current_entry->Next;
if (!RMAP_IS_SEGMENT(previous_entry->Address))
{
if (DeleteMapping)
{
DeleteMapping(Context, previous_entry->Process,
previous_entry->Address);
}
Process = previous_entry->Process;
ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
if (Process == NULL)
{
Process = PsInitialSystemProcess;
}
if (Process)
{
(void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
}
}
else
{
ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
}
}
}
VOID
@ -392,44 +392,44 @@ NTAPI
MmDeleteRmap(PFN_NUMBER Page, PEPROCESS Process,
PVOID Address)
{
PMM_RMAP_ENTRY current_entry, previous_entry;
PMM_RMAP_ENTRY current_entry, previous_entry;
ExAcquireFastMutex(&RmapListLock);
previous_entry = NULL;
current_entry = MmGetRmapListHeadPage(Page);
ExAcquireFastMutex(&RmapListLock);
previous_entry = NULL;
current_entry = MmGetRmapListHeadPage(Page);
while (current_entry != NULL)
{
if (current_entry->Process == (PEPROCESS)Process &&
current_entry->Address == Address)
{
if (previous_entry == NULL)
{
MmSetRmapListHeadPage(Page, current_entry->Next);
}
else
{
previous_entry->Next = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
if (!RMAP_IS_SEGMENT(Address))
{
if (Process == NULL)
while (current_entry != NULL)
{
if (current_entry->Process == (PEPROCESS)Process &&
current_entry->Address == Address)
{
if (previous_entry == NULL)
{
Process = PsInitialSystemProcess;
MmSetRmapListHeadPage(Page, current_entry->Next);
}
if (Process)
else
{
(void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
previous_entry->Next = current_entry->Next;
}
}
return;
}
previous_entry = current_entry;
current_entry = current_entry->Next;
}
KeBugCheck(MEMORY_MANAGEMENT);
ExReleaseFastMutex(&RmapListLock);
ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
if (!RMAP_IS_SEGMENT(Address))
{
if (Process == NULL)
{
Process = PsInitialSystemProcess;
}
if (Process)
{
(void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
}
}
return;
}
previous_entry = current_entry;
current_entry = current_entry->Next;
}
KeBugCheck(MEMORY_MANAGEMENT);
}
/*
@ -450,27 +450,27 @@ PVOID
NTAPI
MmGetSegmentRmap(PFN_NUMBER Page, PULONG RawOffset)
{
PCACHE_SECTION_PAGE_TABLE Result = NULL;
PMM_RMAP_ENTRY current_entry;//, previous_entry;
PCACHE_SECTION_PAGE_TABLE Result = NULL;
PMM_RMAP_ENTRY current_entry;//, previous_entry;
ExAcquireFastMutex(&RmapListLock);
//previous_entry = NULL;
current_entry = MmGetRmapListHeadPage(Page);
while (current_entry != NULL)
{
if (RMAP_IS_SEGMENT(current_entry->Address))
{
Result = (PCACHE_SECTION_PAGE_TABLE)current_entry->Process;
*RawOffset = (ULONG_PTR)current_entry->Address & ~RMAP_SEGMENT_MASK;
InterlockedIncrementUL(&Result->Segment->ReferenceCount);
ExReleaseFastMutex(&RmapListLock);
return Result;
}
//previous_entry = current_entry;
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
return NULL;
ExAcquireFastMutex(&RmapListLock);
//previous_entry = NULL;
current_entry = MmGetRmapListHeadPage(Page);
while (current_entry != NULL)
{
if (RMAP_IS_SEGMENT(current_entry->Address))
{
Result = (PCACHE_SECTION_PAGE_TABLE)current_entry->Process;
*RawOffset = (ULONG_PTR)current_entry->Address & ~RMAP_SEGMENT_MASK;
InterlockedIncrementUL(&Result->Segment->ReferenceCount);
ExReleaseFastMutex(&RmapListLock);
return Result;
}
//previous_entry = current_entry;
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
return NULL;
}
/*
@ -483,29 +483,29 @@ VOID
NTAPI
MmDeleteSectionAssociation(PFN_NUMBER Page)
{
PMM_RMAP_ENTRY current_entry, previous_entry;
PMM_RMAP_ENTRY current_entry, previous_entry;
ExAcquireFastMutex(&RmapListLock);
previous_entry = NULL;
current_entry = MmGetRmapListHeadPage(Page);
while (current_entry != NULL)
{
if (RMAP_IS_SEGMENT(current_entry->Address))
{
if (previous_entry == NULL)
{
MmSetRmapListHeadPage(Page, current_entry->Next);
}
else
{
previous_entry->Next = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
return;
}
previous_entry = current_entry;
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
ExAcquireFastMutex(&RmapListLock);
previous_entry = NULL;
current_entry = MmGetRmapListHeadPage(Page);
while (current_entry != NULL)
{
if (RMAP_IS_SEGMENT(current_entry->Address))
{
if (previous_entry == NULL)
{
MmSetRmapListHeadPage(Page, current_entry->Next);
}
else
{
previous_entry->Next = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
return;
}
previous_entry = current_entry;
current_entry = current_entry->Next;
}
ExReleaseFastMutex(&RmapListLock);
}

File diff suppressed because it is too large Load Diff