[NTOS]: Implement VAD-based Virtual Memory Management. MEMORY_AREA_VIRTUAL_MEMORY is gone. Tested for 3 days with various experiments and handled all the cases and issues that appeared. Some code paths are not implemented because they were not encountered. Will consider implementing them if anything breaks -- note however that those code paths were not handled in RosMM either, so no new regressions are expected.

Hoping this will work on other configurations other than just my test virtual machine. If so, it is a big day in Mm history. Only sections and cache still use the old Mm functionality. I -will- revert this if all hell breaks loose.

svn path=/trunk/; revision=55977
This commit is contained in:
Sir Richard 2012-03-03 22:34:35 +00:00
parent 297eb4a462
commit 08e91a3df6
7 changed files with 1045 additions and 955 deletions

View file

@ -214,10 +214,6 @@ MiReadFilePage
PMEMORY_AREA MemoryArea,
PMM_REQUIRED_RESOURCES RequiredResources);
ULONG
NTAPI
MiChecksumPage(PFN_NUMBER Page, BOOLEAN Lock);
NTSTATUS
NTAPI
MiGetOnePage

View file

@ -153,59 +153,6 @@ MiReadFilePage
return STATUS_SUCCESS;
}
ULONG
NTAPI
MiChecksumPage(PFN_NUMBER Page, BOOLEAN Lock)
{
int i;
NTSTATUS Status;
ULONG Total = 0;
PULONG PageBuf = NULL;
PMEMORY_AREA TmpArea;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
BoundaryAddressMultiple.QuadPart = 0;
if (Lock) MmLockAddressSpace(MmGetKernelAddressSpace());
Status = MmCreateMemoryArea
(MmGetKernelAddressSpace(),
MEMORY_AREA_VIRTUAL_MEMORY,
(PVOID*)&PageBuf,
PAGE_SIZE,
PAGE_READWRITE,
&TmpArea,
FALSE,
MEM_TOP_DOWN,
BoundaryAddressMultiple);
DPRINT("Status %x, PageBuf %x\n", Status, PageBuf);
if (!NT_SUCCESS(Status))
{
DPRINT1("STATUS_NO_MEMORY: %x\n", Status);
if (Lock) MmUnlockAddressSpace(MmGetKernelAddressSpace());
return 0;
}
Status = MmCreateVirtualMapping(NULL, PageBuf, PAGE_READWRITE, &Page, 1);
if (!NT_SUCCESS(Status))
{
MmFreeMemoryArea(MmGetKernelAddressSpace(), TmpArea, NULL, NULL);
if (Lock) MmUnlockAddressSpace(MmGetKernelAddressSpace());
DPRINT1("Status: %x\n", Status);
return Status;
}
for (i = 0; i < 1024; i++) {
Total += PageBuf[i];
}
MmFreeMemoryArea(MmGetKernelAddressSpace(), TmpArea, NULL, NULL);
if (Lock) MmUnlockAddressSpace(MmGetKernelAddressSpace());
return Total;
}
NTSTATUS
NTAPI
MiSwapInPage

View file

@ -74,8 +74,7 @@ typedef ULONG_PTR SWAPENTRY;
#endif
#define MEMORY_AREA_SECTION_VIEW (1)
#define MEMORY_AREA_CACHE (2)
#define MEMORY_AREA_VIRTUAL_MEMORY (8)
#define MEMORY_AREA_CACHE (2)
#define MEMORY_AREA_OWNED_BY_ARM3 (15)
#define MEMORY_AREA_STATIC (0x80000000)
@ -1772,13 +1771,17 @@ VOID
MmLockAddressSpace(PMMSUPPORT AddressSpace)
{
KeAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock);
//ASSERT(Thread->OwnsProcessAddressSpaceExclusive == 0);
//Thread->OwnsProcessAddressSpaceExclusive = TRUE;
}
FORCEINLINE
VOID
MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
{
//ASSERT(Thread->OwnsProcessAddressSpaceExclusive == 1);
KeReleaseGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock);
//Thread->OwnsProcessAddressSpaceExclusive = 0;
}
FORCEINLINE

File diff suppressed because it is too large Load diff

View file

@ -374,14 +374,13 @@ MmInsertMemoryArea(
PMEMORY_AREA PreviousNode;
ULONG Depth = 0;
PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace);
PETHREAD CurrentThread = PsGetCurrentThread();
/* Build a lame VAD if this is a user-space allocation */
if ((marea->EndingAddress < MmSystemRangeStart) && (marea->Type != MEMORY_AREA_OWNED_BY_ARM3))
{
PMMVAD Vad;
ASSERT(marea->Type == MEMORY_AREA_VIRTUAL_MEMORY || marea->Type == MEMORY_AREA_SECTION_VIEW || marea->Type == MEMORY_AREA_CACHE);
ASSERT(marea->Type == MEMORY_AREA_SECTION_VIEW || marea->Type == MEMORY_AREA_CACHE);
Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD), TAG_MVAD);
ASSERT(Vad);
RtlZeroMemory(Vad, sizeof(MMVAD));
@ -403,15 +402,9 @@ MmInsertMemoryArea(
Vad->u.VadFlags.PrivateMemory = 1;
Vad->u.VadFlags.Protection = MiMakeProtectionMask(marea->Protect);
/* Pretend as if we own the working set */
if (marea->Type == MEMORY_AREA_VIRTUAL_MEMORY) MiLockProcessWorkingSet(Process, CurrentThread);
/* Insert the VAD */
MiInsertVad(Vad, Process);
marea->Vad = Vad;
/* Release the working set */
if (marea->Type == MEMORY_AREA_VIRTUAL_MEMORY) MiUnlockProcessWorkingSet(Process, CurrentThread);
}
else
{
@ -782,7 +775,7 @@ MmFreeMemoryArea(
if (MemoryArea->Vad)
{
ASSERT(MemoryArea->EndingAddress < MmSystemRangeStart);
ASSERT(MemoryArea->Type == MEMORY_AREA_VIRTUAL_MEMORY || MemoryArea->Type == MEMORY_AREA_SECTION_VIEW || MemoryArea->Type == MEMORY_AREA_CACHE);
ASSERT(MemoryArea->Type == MEMORY_AREA_SECTION_VIEW || MemoryArea->Type == MEMORY_AREA_CACHE);
/* MmCleanProcessAddressSpace might have removed it (and this would be MmDeleteProcessAdressSpace) */
ASSERT(((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare != 0);
@ -908,7 +901,7 @@ MmCreateMemoryArea(PMMSUPPORT AddressSpace,
Type, BaseAddress, *BaseAddress, Length, AllocationFlags,
FixedAddress, Result);
Granularity = (MEMORY_AREA_VIRTUAL_MEMORY == Type ? MM_VIRTMEM_GRANULARITY : PAGE_SIZE);
Granularity = PAGE_SIZE;
if ((*BaseAddress) == 0 && !FixedAddress)
{
tmpLength = (ULONG_PTR)MM_ROUND_UP(Length, Granularity);
@ -1069,10 +1062,6 @@ MmDeleteProcessAddressSpace(PEPROCESS Process)
MmLockAddressSpace(&Process->Vm);
break;
case MEMORY_AREA_VIRTUAL_MEMORY:
MmFreeVirtualMemory(Process, MemoryArea);
break;
case MEMORY_AREA_OWNED_BY_ARM3:
MmFreeMemoryArea(&Process->Vm,
MemoryArea,

View file

@ -80,10 +80,6 @@ MmpAccessFault(KPROCESSOR_MODE Mode,
(PVOID)Address);
break;
case MEMORY_AREA_VIRTUAL_MEMORY:
Status = STATUS_ACCESS_VIOLATION;
break;
case MEMORY_AREA_CACHE:
// This code locks for itself to keep from having to break a lock
// passed in.
@ -176,12 +172,6 @@ MmNotPresentFault(KPROCESSOR_MODE Mode,
FromMdl);
break;
case MEMORY_AREA_VIRTUAL_MEMORY:
Status = MmNotPresentFaultVirtualMemory(AddressSpace,
MemoryArea,
(PVOID)Address);
break;
case MEMORY_AREA_CACHE:
// This code locks for itself to keep from having to break a lock
// passed in.

View file

@ -163,12 +163,6 @@ MmPageOutPhysicalAddress(PFN_NUMBER Page)
MmUnlockAddressSpace(AddressSpace);
Status = MmpPageOutPhysicalAddress(Page);
}
else if (Type == MEMORY_AREA_VIRTUAL_MEMORY)
{
/* Do not page out virtual memory during ARM3 transition */
MmUnlockAddressSpace(AddressSpace);
Status = STATUS_SUCCESS;
}
else
{
KeBugCheck(MEMORY_MANAGEMENT);