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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

@ -299,36 +299,36 @@ VOID
NTAPI NTAPI
MmMpwThreadMain(PVOID Parameter) MmMpwThreadMain(PVOID Parameter)
{ {
NTSTATUS Status; NTSTATUS Status;
ULONG PagesWritten; ULONG PagesWritten;
LARGE_INTEGER Timeout; LARGE_INTEGER Timeout;
UNREFERENCED_PARAMETER(Parameter); UNREFERENCED_PARAMETER(Parameter);
Timeout.QuadPart = -50000000; Timeout.QuadPart = -50000000;
for(;;) for(;;)
{ {
Status = KeWaitForSingleObject(&MpwThreadEvent, Status = KeWaitForSingleObject(&MpwThreadEvent,
0, 0,
KernelMode, KernelMode,
FALSE, FALSE,
&Timeout); &Timeout);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DbgPrint("MpwThread: Wait failed\n"); DbgPrint("MpwThread: Wait failed\n");
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
return; return;
} }
PagesWritten = 0; PagesWritten = 0;
#ifndef NEWCC #ifndef NEWCC
// XXX arty -- we flush when evicting pages or destorying cache // XXX arty -- we flush when evicting pages or destorying cache
// sections. // sections.
CcRosFlushDirtyPages(128, &PagesWritten, FALSE); CcRosFlushDirtyPages(128, &PagesWritten, FALSE);
#endif #endif
} }
} }
NTSTATUS NTSTATUS
@ -336,31 +336,31 @@ NTAPI
INIT_FUNCTION INIT_FUNCTION
MmInitMpwThread(VOID) MmInitMpwThread(VOID)
{ {
KPRIORITY Priority; KPRIORITY Priority;
NTSTATUS Status; NTSTATUS Status;
CLIENT_ID MpwThreadId; CLIENT_ID MpwThreadId;
KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE); KeInitializeEvent(&MpwThreadEvent, SynchronizationEvent, FALSE);
Status = PsCreateSystemThread(&MpwThreadHandle, Status = PsCreateSystemThread(&MpwThreadHandle,
THREAD_ALL_ACCESS, THREAD_ALL_ACCESS,
NULL, NULL,
NULL, NULL,
&MpwThreadId, &MpwThreadId,
MmMpwThreadMain, MmMpwThreadMain,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(Status); return(Status);
} }
Priority = 27; Priority = 27;
NtSetInformationThread(MpwThreadHandle, NtSetInformationThread(MpwThreadHandle,
ThreadPriority, ThreadPriority,
&Priority, &Priority,
sizeof(Priority)); sizeof(Priority));
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS NTSTATUS
@ -430,8 +430,8 @@ MmInitSystem(IN ULONG Phase,
// by the fault handler. // by the fault handler.
// //
MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool, MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool,
sizeof(MMPTE), sizeof(MMPTE),
' mM'); ' mM');
if (!MmSharedUserDataPte) return FALSE; 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 * FUNCTION: Insert a list entry after another entry in the list
*/ */
{ {
Previous->Flink->Blink = Entry; Previous->Flink->Blink = Entry;
Entry->Flink = Previous->Flink; Entry->Flink = Previous->Flink;
Entry->Blink = Previous; Entry->Blink = Previous;
Previous->Flink = Entry; Previous->Flink = Entry;
} }
static PMM_REGION static PMM_REGION
@ -36,71 +36,71 @@ MmSplitRegion(PMM_REGION InitialRegion, PVOID InitialBaseAddress,
ULONG NewProtect, PMMSUPPORT AddressSpace, ULONG NewProtect, PMMSUPPORT AddressSpace,
PMM_ALTER_REGION_FUNC AlterFunc) PMM_ALTER_REGION_FUNC AlterFunc)
{ {
PMM_REGION NewRegion1; PMM_REGION NewRegion1;
PMM_REGION NewRegion2; PMM_REGION NewRegion2;
SIZE_T InternalLength; SIZE_T InternalLength;
/* Allocate this in front otherwise the failure case is too difficult. */ /* Allocate this in front otherwise the failure case is too difficult. */
NewRegion2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), NewRegion2 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
TAG_MM_REGION); TAG_MM_REGION);
if (NewRegion2 == NULL) if (NewRegion2 == NULL)
{ {
return(NULL); return(NULL);
} }
/* Create the new region. */ /* Create the new region. */
NewRegion1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), NewRegion1 = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
TAG_MM_REGION); TAG_MM_REGION);
if (NewRegion1 == NULL) if (NewRegion1 == NULL)
{ {
ExFreePoolWithTag(NewRegion2, TAG_MM_REGION); ExFreePoolWithTag(NewRegion2, TAG_MM_REGION);
return(NULL); return(NULL);
} }
NewRegion1->Type = NewType; NewRegion1->Type = NewType;
NewRegion1->Protect = NewProtect; NewRegion1->Protect = NewProtect;
InternalLength = ((char*)InitialBaseAddress + InitialRegion->Length) - (char*)StartAddress; InternalLength = ((char*)InitialBaseAddress + InitialRegion->Length) - (char*)StartAddress;
InternalLength = min(InternalLength, Length); InternalLength = min(InternalLength, Length);
NewRegion1->Length = InternalLength; NewRegion1->Length = InternalLength;
InsertAfterEntry(&InitialRegion->RegionListEntry, InsertAfterEntry(&InitialRegion->RegionListEntry,
&NewRegion1->RegionListEntry); &NewRegion1->RegionListEntry);
/* /*
* Call our helper function to do the changes on the addresses contained * Call our helper function to do the changes on the addresses contained
* in the initial region. * in the initial region.
*/ */
AlterFunc(AddressSpace, StartAddress, InternalLength, InitialRegion->Type, AlterFunc(AddressSpace, StartAddress, InternalLength, InitialRegion->Type,
InitialRegion->Protect, NewType, NewProtect); InitialRegion->Protect, NewType, NewProtect);
/* /*
* If necessary create a new region for the portion of the initial region * If necessary create a new region for the portion of the initial region
* beyond the range of addresses to alter. * beyond the range of addresses to alter.
*/ */
if (((char*)InitialBaseAddress + InitialRegion->Length) > ((char*)StartAddress + Length)) if (((char*)InitialBaseAddress + InitialRegion->Length) > ((char*)StartAddress + Length))
{ {
NewRegion2->Type = InitialRegion->Type; NewRegion2->Type = InitialRegion->Type;
NewRegion2->Protect = InitialRegion->Protect; NewRegion2->Protect = InitialRegion->Protect;
NewRegion2->Length = ((char*)InitialBaseAddress + InitialRegion->Length) - NewRegion2->Length = ((char*)InitialBaseAddress + InitialRegion->Length) -
((char*)StartAddress + Length); ((char*)StartAddress + Length);
InsertAfterEntry(&NewRegion1->RegionListEntry, InsertAfterEntry(&NewRegion1->RegionListEntry,
&NewRegion2->RegionListEntry); &NewRegion2->RegionListEntry);
} }
else else
{ {
ExFreePoolWithTag(NewRegion2, TAG_MM_REGION); ExFreePoolWithTag(NewRegion2, TAG_MM_REGION);
} }
/* Either remove or shrink the initial region. */ /* Either remove or shrink the initial region. */
if (InitialBaseAddress == StartAddress) if (InitialBaseAddress == StartAddress)
{ {
RemoveEntryList(&InitialRegion->RegionListEntry); RemoveEntryList(&InitialRegion->RegionListEntry);
ExFreePoolWithTag(InitialRegion, TAG_MM_REGION); ExFreePoolWithTag(InitialRegion, TAG_MM_REGION);
} }
else else
{ {
InitialRegion->Length = (char*)StartAddress - (char*)InitialBaseAddress; InitialRegion->Length = (char*)StartAddress - (char*)InitialBaseAddress;
} }
return(NewRegion1); return(NewRegion1);
} }
NTSTATUS NTSTATUS
@ -109,129 +109,129 @@ MmAlterRegion(PMMSUPPORT AddressSpace, PVOID BaseAddress,
PLIST_ENTRY RegionListHead, PVOID StartAddress, SIZE_T Length, PLIST_ENTRY RegionListHead, PVOID StartAddress, SIZE_T Length,
ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc) ULONG NewType, ULONG NewProtect, PMM_ALTER_REGION_FUNC AlterFunc)
{ {
PMM_REGION InitialRegion; PMM_REGION InitialRegion;
PVOID InitialBaseAddress = NULL; PVOID InitialBaseAddress = NULL;
PMM_REGION NewRegion; PMM_REGION NewRegion;
PLIST_ENTRY CurrentEntry; PLIST_ENTRY CurrentEntry;
PMM_REGION CurrentRegion = NULL; PMM_REGION CurrentRegion = NULL;
PVOID CurrentBaseAddress; PVOID CurrentBaseAddress;
SIZE_T RemainingLength; SIZE_T RemainingLength;
/* /*
* Find the first region containing part of the range of addresses to * Find the first region containing part of the range of addresses to
* be altered. * be altered.
*/ */
InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress, InitialRegion = MmFindRegion(BaseAddress, RegionListHead, StartAddress,
&InitialBaseAddress); &InitialBaseAddress);
/* /*
* If necessary then split the region into the affected and unaffected parts. * If necessary then split the region into the affected and unaffected parts.
*/ */
if (InitialRegion->Type != NewType || InitialRegion->Protect != NewProtect) if (InitialRegion->Type != NewType || InitialRegion->Protect != NewProtect)
{ {
NewRegion = MmSplitRegion(InitialRegion, InitialBaseAddress, NewRegion = MmSplitRegion(InitialRegion, InitialBaseAddress,
StartAddress, Length, NewType, NewProtect, StartAddress, Length, NewType, NewProtect,
AddressSpace, AlterFunc); AddressSpace, AlterFunc);
if (NewRegion == NULL) if (NewRegion == NULL)
{ {
return(STATUS_NO_MEMORY); return(STATUS_NO_MEMORY);
} }
if(NewRegion->Length < Length) if(NewRegion->Length < Length)
RemainingLength = Length - NewRegion->Length; RemainingLength = Length - NewRegion->Length;
else else
RemainingLength = 0; RemainingLength = 0;
} }
else else
{ {
NewRegion = InitialRegion; NewRegion = InitialRegion;
if(((ULONG_PTR)InitialBaseAddress + NewRegion->Length) < if(((ULONG_PTR)InitialBaseAddress + NewRegion->Length) <
((ULONG_PTR)StartAddress + Length)) ((ULONG_PTR)StartAddress + Length))
RemainingLength = ((ULONG_PTR)StartAddress + Length) - ((ULONG_PTR)InitialBaseAddress + NewRegion->Length); RemainingLength = ((ULONG_PTR)StartAddress + Length) - ((ULONG_PTR)InitialBaseAddress + NewRegion->Length);
else else
RemainingLength = 0; RemainingLength = 0;
} }
/* /*
* Free any complete regions that are containing in the range of addresses * Free any complete regions that are containing in the range of addresses
* and call the helper function to actually do the changes. * and call the helper function to actually do the changes.
*/ */
CurrentEntry = NewRegion->RegionListEntry.Flink; CurrentEntry = NewRegion->RegionListEntry.Flink;
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry); RegionListEntry);
CurrentBaseAddress = (char*)StartAddress + NewRegion->Length; CurrentBaseAddress = (char*)StartAddress + NewRegion->Length;
while (RemainingLength > 0 && CurrentRegion->Length <= RemainingLength && while (RemainingLength > 0 && CurrentRegion->Length <= RemainingLength &&
CurrentEntry != RegionListHead) CurrentEntry != RegionListHead)
{ {
if (CurrentRegion->Type != NewType || if (CurrentRegion->Type != NewType ||
CurrentRegion->Protect != NewProtect) CurrentRegion->Protect != NewProtect)
{ {
AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length, AlterFunc(AddressSpace, CurrentBaseAddress, CurrentRegion->Length,
CurrentRegion->Type, CurrentRegion->Protect, CurrentRegion->Type, CurrentRegion->Protect,
NewType, NewProtect); NewType, NewProtect);
} }
CurrentBaseAddress = (PVOID)((ULONG_PTR)CurrentBaseAddress + CurrentRegion->Length); CurrentBaseAddress = (PVOID)((ULONG_PTR)CurrentBaseAddress + CurrentRegion->Length);
NewRegion->Length += CurrentRegion->Length; NewRegion->Length += CurrentRegion->Length;
RemainingLength -= CurrentRegion->Length; RemainingLength -= CurrentRegion->Length;
CurrentEntry = CurrentEntry->Flink; CurrentEntry = CurrentEntry->Flink;
RemoveEntryList(&CurrentRegion->RegionListEntry); RemoveEntryList(&CurrentRegion->RegionListEntry);
ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION); ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry); RegionListEntry);
} }
/* /*
* Split any final region. * Split any final region.
*/ */
if (RemainingLength > 0 && CurrentEntry != RegionListHead) if (RemainingLength > 0 && CurrentEntry != RegionListHead)
{ {
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry); RegionListEntry);
if (CurrentRegion->Type != NewType || if (CurrentRegion->Type != NewType ||
CurrentRegion->Protect != NewProtect) CurrentRegion->Protect != NewProtect)
{ {
AlterFunc(AddressSpace, CurrentBaseAddress, RemainingLength, AlterFunc(AddressSpace, CurrentBaseAddress, RemainingLength,
CurrentRegion->Type, CurrentRegion->Protect, CurrentRegion->Type, CurrentRegion->Protect,
NewType, NewProtect); NewType, NewProtect);
} }
NewRegion->Length += RemainingLength; NewRegion->Length += RemainingLength;
CurrentRegion->Length -= RemainingLength; CurrentRegion->Length -= RemainingLength;
} }
/* /*
* If the region after the new region has the same type then merge them. * If the region after the new region has the same type then merge them.
*/ */
if (NewRegion->RegionListEntry.Flink != RegionListHead) if (NewRegion->RegionListEntry.Flink != RegionListHead)
{ {
CurrentEntry = NewRegion->RegionListEntry.Flink; CurrentEntry = NewRegion->RegionListEntry.Flink;
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry); RegionListEntry);
if (CurrentRegion->Type == NewRegion->Type && if (CurrentRegion->Type == NewRegion->Type &&
CurrentRegion->Protect == NewRegion->Protect) CurrentRegion->Protect == NewRegion->Protect)
{ {
NewRegion->Length += CurrentRegion->Length; NewRegion->Length += CurrentRegion->Length;
RemoveEntryList(&CurrentRegion->RegionListEntry); RemoveEntryList(&CurrentRegion->RegionListEntry);
ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION); ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
} }
} }
/* /*
* If the region before the new region has the same type then merge them. * If the region before the new region has the same type then merge them.
*/ */
if (NewRegion->RegionListEntry.Blink != RegionListHead) if (NewRegion->RegionListEntry.Blink != RegionListHead)
{ {
CurrentEntry = NewRegion->RegionListEntry.Blink; CurrentEntry = NewRegion->RegionListEntry.Blink;
CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION, CurrentRegion = CONTAINING_RECORD(CurrentEntry, MM_REGION,
RegionListEntry); RegionListEntry);
if (CurrentRegion->Type == NewRegion->Type && if (CurrentRegion->Type == NewRegion->Type &&
CurrentRegion->Protect == NewRegion->Protect) CurrentRegion->Protect == NewRegion->Protect)
{ {
NewRegion->Length += CurrentRegion->Length; NewRegion->Length += CurrentRegion->Length;
RemoveEntryList(&CurrentRegion->RegionListEntry); RemoveEntryList(&CurrentRegion->RegionListEntry);
ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION); ExFreePoolWithTag(CurrentRegion, TAG_MM_REGION);
} }
} }
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
VOID VOID
@ -239,17 +239,17 @@ NTAPI
MmInitializeRegion(PLIST_ENTRY RegionListHead, SIZE_T Length, ULONG Type, MmInitializeRegion(PLIST_ENTRY RegionListHead, SIZE_T Length, ULONG Type,
ULONG Protect) ULONG Protect)
{ {
PMM_REGION Region; PMM_REGION Region;
Region = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION), Region = ExAllocatePoolWithTag(NonPagedPool, sizeof(MM_REGION),
TAG_MM_REGION); TAG_MM_REGION);
if (!Region) return; if (!Region) return;
Region->Type = Type; Region->Type = Type;
Region->Protect = Protect; Region->Protect = Protect;
Region->Length = Length; Region->Length = Length;
InitializeListHead(RegionListHead); InitializeListHead(RegionListHead);
InsertHeadList(RegionListHead, &Region->RegionListEntry); InsertHeadList(RegionListHead, &Region->RegionListEntry);
} }
PMM_REGION PMM_REGION
@ -257,29 +257,29 @@ NTAPI
MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address, MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address,
PVOID* RegionBaseAddress) PVOID* RegionBaseAddress)
{ {
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
PMM_REGION current; PMM_REGION current;
PVOID StartAddress = BaseAddress; PVOID StartAddress = BaseAddress;
current_entry = RegionListHead->Flink; current_entry = RegionListHead->Flink;
while (current_entry != RegionListHead) while (current_entry != RegionListHead)
{ {
current = CONTAINING_RECORD(current_entry, MM_REGION, RegionListEntry); current = CONTAINING_RECORD(current_entry, MM_REGION, RegionListEntry);
if (StartAddress <= Address && if (StartAddress <= Address &&
((char*)StartAddress + current->Length) > (char*)Address) ((char*)StartAddress + current->Length) > (char*)Address)
{ {
if (RegionBaseAddress != NULL) if (RegionBaseAddress != NULL)
{ {
*RegionBaseAddress = StartAddress; *RegionBaseAddress = StartAddress;
} }
return(current); 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 NTAPI
MmInitializeRmapList(VOID) MmInitializeRmapList(VOID)
{ {
ExInitializeFastMutex(&RmapListLock); ExInitializeFastMutex(&RmapListLock);
ExInitializeNPagedLookasideList (&RmapLookasideList, ExInitializeNPagedLookasideList (&RmapLookasideList,
NULL, NULL,
RmapListFree, RmapListFree,
0, 0,
sizeof(MM_RMAP_ENTRY), sizeof(MM_RMAP_ENTRY),
TAG_RMAP, TAG_RMAP,
50); 50);
} }
NTSTATUS NTSTATUS
NTAPI NTAPI
MmPageOutPhysicalAddress(PFN_NUMBER Page) MmPageOutPhysicalAddress(PFN_NUMBER Page)
{ {
PMM_RMAP_ENTRY entry; PMM_RMAP_ENTRY entry;
PMEMORY_AREA MemoryArea; PMEMORY_AREA MemoryArea;
PMMSUPPORT AddressSpace; PMMSUPPORT AddressSpace;
ULONG Type; ULONG Type;
PVOID Address; PVOID Address;
PEPROCESS Process; PEPROCESS Process;
ULONGLONG Offset; ULONGLONG Offset;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&RmapListLock);
entry = MmGetRmapListHeadPage(Page); entry = MmGetRmapListHeadPage(Page);
#ifdef NEWCC #ifdef NEWCC
// Special case for NEWCC: we can have a page that's only in a segment // Special case for NEWCC: we can have a page that's only in a segment
// page table // page table
if (entry && RMAP_IS_SEGMENT(entry->Address) && entry->Next == NULL) if (entry && RMAP_IS_SEGMENT(entry->Address) && entry->Next == NULL)
{ {
/* NEWCC does locking itself */ /* NEWCC does locking itself */
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
return MmpPageOutPhysicalAddress(Page); return MmpPageOutPhysicalAddress(Page);
} }
#endif #endif
while (entry && RMAP_IS_SEGMENT(entry->Address)) while (entry && RMAP_IS_SEGMENT(entry->Address))
entry = entry->Next; entry = entry->Next;
if (entry == NULL) if (entry == NULL)
{ {
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
Process = entry->Process; Process = entry->Process;
Address = entry->Address; Address = entry->Address;
if ((((ULONG_PTR)Address) & 0xFFF) != 0) if ((((ULONG_PTR)Address) & 0xFFF) != 0)
{ {
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
if (Address < MmSystemRangeStart) if (Address < MmSystemRangeStart)
{ {
if (!ExAcquireRundownProtection(&Process->RundownProtect)) if (!ExAcquireRundownProtection(&Process->RundownProtect))
{ {
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
return STATUS_PROCESS_IS_TERMINATING; return STATUS_PROCESS_IS_TERMINATING;
} }
Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode); Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode);
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
ExReleaseRundownProtection(&Process->RundownProtect); ExReleaseRundownProtection(&Process->RundownProtect);
return Status; return Status;
} }
AddressSpace = &Process->Vm; AddressSpace = &Process->Vm;
} }
else else
{ {
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
AddressSpace = MmGetKernelAddressSpace(); AddressSpace = MmGetKernelAddressSpace();
} }
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address); MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
if (MemoryArea == NULL || MemoryArea->DeleteInProgress) if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
{ {
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);
if (Address < MmSystemRangeStart) 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)
{
ExReleaseRundownProtection(&Process->RundownProtect); ExReleaseRundownProtection(&Process->RundownProtect);
ObDereferenceObject(Process); 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. * Get or create a pageop
*/ */
MmUnlockSectionSegment(MemoryArea->Data.SectionData.Segment); Entry = MmGetPageEntrySectionSegment(MemoryArea->Data.SectionData.Segment,
MmUnlockAddressSpace(AddressSpace); (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);
}
/* MmSetPageEntrySectionSegment(MemoryArea->Data.SectionData.Segment, (PLARGE_INTEGER)&Offset, MAKE_SWAP_SSE(MM_WAIT_ENTRY));
* 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) /*
{ * Release locks now we have a page op.
ExReleaseRundownProtection(&Process->RundownProtect); */
ObDereferenceObject(Process); MmUnlockSectionSegment(MemoryArea->Data.SectionData.Segment);
} MmUnlockAddressSpace(AddressSpace);
return(Status);
/*
* 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 VOID
NTAPI NTAPI
MmSetCleanAllRmaps(PFN_NUMBER Page) MmSetCleanAllRmaps(PFN_NUMBER Page)
{ {
PMM_RMAP_ENTRY current_entry; PMM_RMAP_ENTRY current_entry;
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page); current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL) if (current_entry == NULL)
{ {
DPRINT1("MmIsDirtyRmap: No rmaps.\n"); DPRINT1("MmIsDirtyRmap: No rmaps.\n");
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
while (current_entry != NULL) while (current_entry != NULL)
{ {
if (!RMAP_IS_SEGMENT(current_entry->Address)) if (!RMAP_IS_SEGMENT(current_entry->Address))
MmSetCleanPage(current_entry->Process, current_entry->Address); MmSetCleanPage(current_entry->Process, current_entry->Address);
current_entry = current_entry->Next; current_entry = current_entry->Next;
} }
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
} }
VOID VOID
NTAPI NTAPI
MmSetDirtyAllRmaps(PFN_NUMBER Page) MmSetDirtyAllRmaps(PFN_NUMBER Page)
{ {
PMM_RMAP_ENTRY current_entry; PMM_RMAP_ENTRY current_entry;
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page); current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL) if (current_entry == NULL)
{ {
DPRINT1("MmIsDirtyRmap: No rmaps.\n"); DPRINT1("MmIsDirtyRmap: No rmaps.\n");
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
while (current_entry != NULL) while (current_entry != NULL)
{ {
if (!RMAP_IS_SEGMENT(current_entry->Address)) if (!RMAP_IS_SEGMENT(current_entry->Address))
MmSetDirtyPage(current_entry->Process, current_entry->Address); MmSetDirtyPage(current_entry->Process, current_entry->Address);
current_entry = current_entry->Next; current_entry = current_entry->Next;
} }
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
} }
BOOLEAN BOOLEAN
NTAPI NTAPI
MmIsDirtyPageRmap(PFN_NUMBER Page) MmIsDirtyPageRmap(PFN_NUMBER Page)
{ {
PMM_RMAP_ENTRY current_entry; PMM_RMAP_ENTRY current_entry;
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page); current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL) if (current_entry == NULL)
{ {
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
return(FALSE); return(FALSE);
} }
while (current_entry != NULL) while (current_entry != NULL)
{ {
if ( if (
!RMAP_IS_SEGMENT(current_entry->Address) && !RMAP_IS_SEGMENT(current_entry->Address) &&
MmIsDirtyPage(current_entry->Process, current_entry->Address)) MmIsDirtyPage(current_entry->Process, current_entry->Address))
{ {
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
return(TRUE); return(TRUE);
} }
current_entry = current_entry->Next; current_entry = current_entry->Next;
} }
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
return(FALSE); return(FALSE);
} }
VOID VOID
@ -267,75 +267,75 @@ NTAPI
MmInsertRmap(PFN_NUMBER Page, PEPROCESS Process, MmInsertRmap(PFN_NUMBER Page, PEPROCESS Process,
PVOID Address) PVOID Address)
{ {
PMM_RMAP_ENTRY current_entry; PMM_RMAP_ENTRY current_entry;
PMM_RMAP_ENTRY new_entry; PMM_RMAP_ENTRY new_entry;
ULONG PrevSize; ULONG PrevSize;
if (!RMAP_IS_SEGMENT(Address)) if (!RMAP_IS_SEGMENT(Address))
Address = (PVOID)PAGE_ROUND_DOWN(Address); Address = (PVOID)PAGE_ROUND_DOWN(Address);
new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList); new_entry = ExAllocateFromNPagedLookasideList(&RmapLookasideList);
if (new_entry == NULL) if (new_entry == NULL)
{ {
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
new_entry->Address = Address; new_entry->Address = Address;
new_entry->Process = (PEPROCESS)Process; new_entry->Process = (PEPROCESS)Process;
#if DBG #if DBG
#ifdef __GNUC__ #ifdef __GNUC__
new_entry->Caller = __builtin_return_address(0); new_entry->Caller = __builtin_return_address(0);
#else #else
new_entry->Caller = _ReturnAddress(); new_entry->Caller = _ReturnAddress();
#endif #endif
#endif #endif
if ( if (
!RMAP_IS_SEGMENT(Address) && !RMAP_IS_SEGMENT(Address) &&
MmGetPfnForProcess(Process, Address) != Page) MmGetPfnForProcess(Process, Address) != Page)
{ {
DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical " DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical "
"address 0x%.8X\n", Process ? Process->UniqueProcessId : 0, "address 0x%.8X\n", Process ? Process->UniqueProcessId : 0,
Address, Address,
MmGetPfnForProcess(Process, Address) << PAGE_SHIFT, MmGetPfnForProcess(Process, Address) << PAGE_SHIFT,
Page << PAGE_SHIFT); Page << PAGE_SHIFT);
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page); current_entry = MmGetRmapListHeadPage(Page);
new_entry->Next = current_entry; new_entry->Next = current_entry;
#if DBG #if DBG
while (current_entry) while (current_entry)
{ {
if (current_entry->Address == new_entry->Address && current_entry->Process == new_entry->Process) 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 ", DbgPrint("MmInsertRmap tries to add a second rmap entry for address %p\n current caller ",
current_entry->Address); current_entry->Address);
DbgPrint("%p", new_entry->Caller); DbgPrint("%p", new_entry->Caller);
DbgPrint("\n previous caller "); DbgPrint("\n previous caller ");
DbgPrint("%p", current_entry->Caller); DbgPrint("%p", current_entry->Caller);
DbgPrint("\n"); DbgPrint("\n");
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
current_entry = current_entry->Next; current_entry = current_entry->Next;
} }
#endif #endif
MmSetRmapListHeadPage(Page, new_entry); MmSetRmapListHeadPage(Page, new_entry);
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
if (!RMAP_IS_SEGMENT(Address)) if (!RMAP_IS_SEGMENT(Address))
{ {
if (Process == NULL) if (Process == NULL)
{ {
Process = PsInitialSystemProcess; Process = PsInitialSystemProcess;
} }
if (Process) if (Process)
{ {
PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE); PrevSize = InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, PAGE_SIZE);
if (PrevSize >= Process->Vm.PeakWorkingSetSize) if (PrevSize >= Process->Vm.PeakWorkingSetSize)
{ {
Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE; Process->Vm.PeakWorkingSetSize = PrevSize + PAGE_SIZE;
} }
} }
} }
} }
VOID VOID
@ -344,47 +344,47 @@ MmDeleteAllRmaps(PFN_NUMBER Page, PVOID Context,
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process,
PVOID Address)) PVOID Address))
{ {
PMM_RMAP_ENTRY current_entry; PMM_RMAP_ENTRY current_entry;
PMM_RMAP_ENTRY previous_entry; PMM_RMAP_ENTRY previous_entry;
PEPROCESS Process; PEPROCESS Process;
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page); current_entry = MmGetRmapListHeadPage(Page);
if (current_entry == NULL) if (current_entry == NULL)
{ {
DPRINT1("MmDeleteAllRmaps: No rmaps.\n"); DPRINT1("MmDeleteAllRmaps: No rmaps.\n");
KeBugCheck(MEMORY_MANAGEMENT); KeBugCheck(MEMORY_MANAGEMENT);
} }
MmSetRmapListHeadPage(Page, NULL); MmSetRmapListHeadPage(Page, NULL);
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
while (current_entry != NULL) while (current_entry != NULL)
{ {
previous_entry = current_entry; previous_entry = current_entry;
current_entry = current_entry->Next; current_entry = current_entry->Next;
if (!RMAP_IS_SEGMENT(previous_entry->Address)) if (!RMAP_IS_SEGMENT(previous_entry->Address))
{ {
if (DeleteMapping) if (DeleteMapping)
{ {
DeleteMapping(Context, previous_entry->Process, DeleteMapping(Context, previous_entry->Process,
previous_entry->Address); previous_entry->Address);
} }
Process = previous_entry->Process; Process = previous_entry->Process;
ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry); ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
if (Process == NULL) if (Process == NULL)
{ {
Process = PsInitialSystemProcess; Process = PsInitialSystemProcess;
} }
if (Process) if (Process)
{ {
(void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE); (void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
} }
} }
else else
{ {
ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry); ExFreeToNPagedLookasideList(&RmapLookasideList, previous_entry);
} }
} }
} }
VOID VOID
@ -392,44 +392,44 @@ NTAPI
MmDeleteRmap(PFN_NUMBER Page, PEPROCESS Process, MmDeleteRmap(PFN_NUMBER Page, PEPROCESS Process,
PVOID Address) PVOID Address)
{ {
PMM_RMAP_ENTRY current_entry, previous_entry; PMM_RMAP_ENTRY current_entry, previous_entry;
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&RmapListLock);
previous_entry = NULL; previous_entry = NULL;
current_entry = MmGetRmapListHeadPage(Page); current_entry = MmGetRmapListHeadPage(Page);
while (current_entry != NULL) while (current_entry != NULL)
{ {
if (current_entry->Process == (PEPROCESS)Process && if (current_entry->Process == (PEPROCESS)Process &&
current_entry->Address == Address) current_entry->Address == Address)
{ {
if (previous_entry == NULL) 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)
{ {
Process = PsInitialSystemProcess; MmSetRmapListHeadPage(Page, current_entry->Next);
} }
if (Process) else
{ {
(void)InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE); previous_entry->Next = current_entry->Next;
} }
} ExReleaseFastMutex(&RmapListLock);
return; ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
} if (!RMAP_IS_SEGMENT(Address))
previous_entry = current_entry; {
current_entry = current_entry->Next; if (Process == NULL)
} {
KeBugCheck(MEMORY_MANAGEMENT); 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 NTAPI
MmGetSegmentRmap(PFN_NUMBER Page, PULONG RawOffset) MmGetSegmentRmap(PFN_NUMBER Page, PULONG RawOffset)
{ {
PCACHE_SECTION_PAGE_TABLE Result = NULL; PCACHE_SECTION_PAGE_TABLE Result = NULL;
PMM_RMAP_ENTRY current_entry;//, previous_entry; PMM_RMAP_ENTRY current_entry;//, previous_entry;
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&RmapListLock);
//previous_entry = NULL; //previous_entry = NULL;
current_entry = MmGetRmapListHeadPage(Page); current_entry = MmGetRmapListHeadPage(Page);
while (current_entry != NULL) while (current_entry != NULL)
{ {
if (RMAP_IS_SEGMENT(current_entry->Address)) if (RMAP_IS_SEGMENT(current_entry->Address))
{ {
Result = (PCACHE_SECTION_PAGE_TABLE)current_entry->Process; Result = (PCACHE_SECTION_PAGE_TABLE)current_entry->Process;
*RawOffset = (ULONG_PTR)current_entry->Address & ~RMAP_SEGMENT_MASK; *RawOffset = (ULONG_PTR)current_entry->Address & ~RMAP_SEGMENT_MASK;
InterlockedIncrementUL(&Result->Segment->ReferenceCount); InterlockedIncrementUL(&Result->Segment->ReferenceCount);
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
return Result; return Result;
} }
//previous_entry = current_entry; //previous_entry = current_entry;
current_entry = current_entry->Next; current_entry = current_entry->Next;
} }
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
return NULL; return NULL;
} }
/* /*
@ -483,29 +483,29 @@ VOID
NTAPI NTAPI
MmDeleteSectionAssociation(PFN_NUMBER Page) MmDeleteSectionAssociation(PFN_NUMBER Page)
{ {
PMM_RMAP_ENTRY current_entry, previous_entry; PMM_RMAP_ENTRY current_entry, previous_entry;
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&RmapListLock);
previous_entry = NULL; previous_entry = NULL;
current_entry = MmGetRmapListHeadPage(Page); current_entry = MmGetRmapListHeadPage(Page);
while (current_entry != NULL) while (current_entry != NULL)
{ {
if (RMAP_IS_SEGMENT(current_entry->Address)) if (RMAP_IS_SEGMENT(current_entry->Address))
{ {
if (previous_entry == NULL) if (previous_entry == NULL)
{ {
MmSetRmapListHeadPage(Page, current_entry->Next); MmSetRmapListHeadPage(Page, current_entry->Next);
} }
else else
{ {
previous_entry->Next = current_entry->Next; previous_entry->Next = current_entry->Next;
} }
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry); ExFreeToNPagedLookasideList(&RmapLookasideList, current_entry);
return; return;
} }
previous_entry = current_entry; previous_entry = current_entry;
current_entry = current_entry->Next; current_entry = current_entry->Next;
} }
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&RmapListLock);
} }

File diff suppressed because it is too large Load diff