mirror of
https://github.com/reactos/reactos.git
synced 2024-12-22 18:43:30 +08:00
[NTOSKRNL]
Apply indentation of 4 spaces, no code change. svn path=/trunk/; revision=64531
This commit is contained in:
parent
4b31efff8f
commit
c9252b32bd
@ -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));
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
@ -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);
|
||||
|
@ -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
@ -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);
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user