Index: ntoskrnl/cache/section/data.c =================================================================== --- ntoskrnl/cache/section/data.c (revision 64688) +++ ntoskrnl/cache/section/data.c (working copy) @@ -160,8 +160,8 @@ DPRINT("STATUS_NOT_MAPPED_DATA\n"); return STATUS_NOT_MAPPED_DATA; } - BeginningAddress = PAGE_ROUND_DOWN((ULONG_PTR)MemoryArea->StartingAddress); - EndingAddress = PAGE_ROUND_UP((ULONG_PTR)MemoryArea->EndingAddress); + BeginningAddress = PAGE_ROUND_DOWN(MA_GetStartingAddress(MemoryArea)); + EndingAddress = PAGE_ROUND_UP(MA_GetEndingAddress(MemoryArea)); Segment = MemoryArea->Data.SectionData.Segment; ViewOffset.QuadPart = MemoryArea->Data.SectionData.ViewOffset.QuadPart; @@ -554,7 +554,6 @@ ViewSize, Protect, &MArea, - FALSE, AllocationType, *BaseAddress ? PAGE_SIZE : MM_ALLOCATION_GRANULARITY); @@ -684,7 +683,7 @@ Process = MmGetAddressSpaceOwner(AddressSpace); Address = (PVOID)PAGE_ROUND_DOWN(Address); Segment = ContextData[1]; - Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress + + Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea) + MemoryArea->Data.SectionData.ViewOffset.QuadPart; Entry = MmGetPageEntrySectionSegment(Segment, &Offset); @@ -735,7 +734,7 @@ DPRINT("MmFreeMemoryArea(%p,%p)\n", MmGetAddressSpaceOwner(AddressSpace), - MemoryArea->StartingAddress); + MA_GetStartingAddress(MemoryArea)); MmLockAddressSpace(AddressSpace); Index: ntoskrnl/cache/section/fault.c =================================================================== --- ntoskrnl/cache/section/fault.c (revision 64688) +++ ntoskrnl/cache/section/fault.c (working copy) @@ -122,8 +122,8 @@ DPRINT("Not Present: %p %p (%p-%p)\n", AddressSpace, Address, - MemoryArea->StartingAddress, - MemoryArea->EndingAddress); + MA_GetStartingAddress(MemoryArea), + MA_GetEndingAddress(MemoryArea)); /* * There is a window between taking the page fault and locking the @@ -138,7 +138,7 @@ PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE); TotalOffset.QuadPart = (ULONG_PTR)PAddress - - (ULONG_PTR)MemoryArea->StartingAddress; + MA_GetStartingAddress(MemoryArea); Segment = MemoryArea->Data.SectionData.Segment; @@ -345,7 +345,7 @@ /* Find the offset of the page */ PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE); - Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress + + Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea) + MemoryArea->Data.SectionData.ViewOffset.QuadPart; if (!Segment->WriteCopy /*&& @@ -584,8 +584,8 @@ DPRINT("Type %x (%p -> %p)\n", MemoryArea->Type, - MemoryArea->StartingAddress, - MemoryArea->EndingAddress); + MA_GetStartingAddress(MemoryArea), + MA_GetEndingAddress(MemoryArea)); Resources.DoAcquisition = NULL; @@ -660,8 +660,8 @@ DPRINT1("Completed page fault handling %Ix %x\n", Address, Status); DPRINT1("Type %x (%p -> %p)\n", MemoryArea->Type, - MemoryArea->StartingAddress, - MemoryArea->EndingAddress); + MA_GetStartingAddress(MemoryArea), + MA_GetEndingAddress(MemoryArea)); } if (!FromMdl) @@ -788,9 +788,9 @@ DPRINTC("Type %x (%p -> %08Ix -> %p) in %p\n", MemoryArea->Type, - MemoryArea->StartingAddress, + MA_GetStartingAddress(MemoryArea), Address, - MemoryArea->EndingAddress, + MA_GetEndingAddress(MemoryArea), PsGetCurrentThread()); Resources.DoAcquisition = NULL; Index: ntoskrnl/cache/section/swapout.c =================================================================== --- ntoskrnl/cache/section/swapout.c (revision 64688) +++ ntoskrnl/cache/section/swapout.c (working copy) @@ -289,7 +289,8 @@ PMM_SECTION_SEGMENT Segment; PVOID PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE); - TotalOffset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress + + TotalOffset.QuadPart = (ULONG_PTR)PAddress - + MA_GetStartingAddress(MemoryArea) + MemoryArea->Data.SectionData.ViewOffset.QuadPart; Segment = MemoryArea->Data.SectionData.Segment; @@ -456,8 +457,8 @@ DPRINTC("Type %x (%p -> %p)\n", MemoryArea->Type, - MemoryArea->StartingAddress, - MemoryArea->EndingAddress); + MA_GetStartingAddress(MemoryArea), + MA_GetEndingAddress(MemoryArea)); Resources.DoAcquisition = NULL; Resources.Page[0] = Page; Index: ntoskrnl/cc/view.c =================================================================== --- ntoskrnl/cc/view.c (revision 64688) +++ ntoskrnl/cc/view.c (working copy) @@ -595,7 +595,6 @@ VACB_MAPPING_GRANULARITY, PAGE_READWRITE, (PMEMORY_AREA*)&Vacb->MemoryArea, - FALSE, 0, PAGE_SIZE); MmUnlockAddressSpace(MmGetKernelAddressSpace()); Index: ntoskrnl/include/internal/mm.h =================================================================== --- ntoskrnl/include/internal/mm.h (revision 64688) +++ ntoskrnl/include/internal/mm.h (working copy) @@ -199,10 +199,14 @@ }; } ROS_SECTION_OBJECT, *PROS_SECTION_OBJECT; +#define MA_GetStartingAddress(_MemoryArea) ((_MemoryArea)->StartingVpn << PAGE_SHIFT) +#define MA_GetEndingAddress(_MemoryArea) (((_MemoryArea)->EndingVpn + 1) << PAGE_SHIFT) + typedef struct _MEMORY_AREA { - PVOID StartingAddress; - PVOID EndingAddress; + MMVAD VadNode; + ULONG_PTR StartingVpn; + ULONG_PTR EndingVpn; struct _MEMORY_AREA *Parent; struct _MEMORY_AREA *LeftChild; struct _MEMORY_AREA *RightChild; @@ -483,7 +487,6 @@ SIZE_T Length, ULONG Protection, PMEMORY_AREA *Result, - BOOLEAN FixedAddress, ULONG AllocationFlags, ULONG AllocationGranularity ); @@ -495,14 +498,6 @@ PVOID Address ); -// fixme: unused? -ULONG_PTR -NTAPI -MmFindGapAtAddress_( - PMMSUPPORT AddressSpace, - PVOID Address -); - NTSTATUS NTAPI MmFreeMemoryArea( @@ -512,6 +507,12 @@ PVOID FreePageContext ); +VOID +NTAPI +MiRosCleanupMemoryArea( + PEPROCESS Process, + PMMVAD Vad); + NTSTATUS NTAPI MmFreeMemoryAreaByPtr( Index: ntoskrnl/mm/ARM3/miarm.h =================================================================== --- ntoskrnl/mm/ARM3/miarm.h (revision 64688) +++ ntoskrnl/mm/ARM3/miarm.h (working copy) @@ -2137,13 +2137,6 @@ IN ULONG ProtectionMask ); -VOID -NTAPI -MiInsertVad( - IN PMMVAD Vad, - IN PEPROCESS Process -); - NTSTATUS NTAPI MiInsertVadEx( Index: ntoskrnl/mm/ARM3/procsup.c =================================================================== --- ntoskrnl/mm/ARM3/procsup.c (revision 64688) +++ ntoskrnl/mm/ARM3/procsup.c (working copy) @@ -38,7 +38,6 @@ PAGE_SIZE, PAGE_READWRITE, &MemoryArea, - TRUE, 0, PAGE_SIZE); ASSERT(NT_SUCCESS(Status)); @@ -1307,11 +1306,14 @@ MiUnlockProcessWorkingSetUnsafe(Process, Thread); } - /* Skip ARM3 fake VADs, they'll be freed by MmDeleteProcessAddresSpace */ + /* Skip ARM3 fake VADs, they'll be freed by MmDeleteProcessAddresSpace */ if (Vad->u.VadFlags.Spare == 1) { /* Set a flag so MmDeleteMemoryArea knows to free, but not to remove */ Vad->u.VadFlags.Spare = 2; + + /* Let RosMm handle this */ + MiRosCleanupMemoryArea(Process, Vad); continue; } Index: ntoskrnl/mm/ARM3/vadnode.c =================================================================== --- ntoskrnl/mm/ARM3/vadnode.c (revision 64688) +++ ntoskrnl/mm/ARM3/vadnode.c (working copy) @@ -146,6 +146,13 @@ PVOID AllocatedBase = (PVOID)(Vad->StartingVpn << PAGE_SHIFT); Size = ((Vad->EndingVpn + 1) - Vad->StartingVpn) << PAGE_SHIFT; + + if (AllocatedBase == NULL) + { + AllocatedBase = (PVOID)(ULONG_PTR)1; + Size -= 1; + } + Status = MmCreateMemoryArea(&Process->Vm, MEMORY_AREA_OWNED_BY_ARM3, &AllocatedBase, @@ -152,7 +159,6 @@ Size, PAGE_READWRITE, &MemoryArea, - TRUE, 0, PAGE_SIZE); ASSERT(NT_SUCCESS(Status)); @@ -175,7 +181,7 @@ VOID NTAPI MiInsertVad(IN PMMVAD Vad, - IN PEPROCESS Process) + IN PMM_AVL_TABLE VadRoot) { TABLE_SEARCH_RESULT Result; PMMADDRESS_NODE Parent = NULL; @@ -182,17 +188,15 @@ /* Validate the VAD and set it as the current hint */ ASSERT(Vad->EndingVpn >= Vad->StartingVpn); - Process->VadRoot.NodeHint = Vad; + VadRoot->NodeHint = Vad; /* Find the parent VAD and where this child should be inserted */ - Result = RtlpFindAvlTableNodeOrParent(&Process->VadRoot, (PVOID)Vad->StartingVpn, &Parent); + Result = RtlpFindAvlTableNodeOrParent(VadRoot, (PVOID)Vad->StartingVpn, &Parent); ASSERT(Result != TableFoundNode); ASSERT((Parent != NULL) || (Result == TableEmptyTree)); /* Do the actual insert operation */ - MiLockProcessWorkingSetUnsafe(PsGetCurrentProcess(), PsGetCurrentThread()); - MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result); - MiUnlockProcessWorkingSetUnsafe(PsGetCurrentProcess(), PsGetCurrentThread()); + MiInsertNode(VadRoot, (PVOID)Vad, Parent, Result); } NTSTATUS Index: ntoskrnl/mm/ARM3/virtual.c =================================================================== --- ntoskrnl/mm/ARM3/virtual.c (revision 64688) +++ ntoskrnl/mm/ARM3/virtual.c (working copy) @@ -1885,7 +1885,7 @@ if (!NT_SUCCESS(Status)) { DPRINT1("MmQuerySectionView failed. MemoryArea=%p (%p-%p), BaseAddress=%p\n", - MemoryArea, MemoryArea->StartingAddress, MemoryArea->EndingAddress, BaseAddress); + MemoryArea, MA_GetStartingAddress(MemoryArea), MA_GetEndingAddress(MemoryArea), BaseAddress); NT_ASSERT(NT_SUCCESS(Status)); } } @@ -5313,10 +5313,10 @@ Vad->u.VadFlags.CommitCharge -= CommitReduction; // For ReactOS: shrink the corresponding memory area MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)StartingAddress); - ASSERT(Vad->StartingVpn << PAGE_SHIFT == (ULONG_PTR)MemoryArea->StartingAddress); - ASSERT((Vad->EndingVpn + 1) << PAGE_SHIFT == (ULONG_PTR)MemoryArea->EndingAddress); - Vad->EndingVpn = ((ULONG_PTR)StartingAddress - 1) >> PAGE_SHIFT; - MemoryArea->EndingAddress = (PVOID)(StartingAddress); + ASSERT(Vad->StartingVpn == MemoryArea->StartingVpn); + ASSERT(Vad->EndingVpn == MemoryArea->EndingVpn); + Vad->EndingVpn = (StartingAddress - 1) >> PAGE_SHIFT; + MemoryArea->EndingVpn = Vad->EndingVpn; } else { Index: ntoskrnl/mm/marea.c =================================================================== --- ntoskrnl/mm/marea.c (revision 64688) +++ ntoskrnl/mm/marea.c (working copy) @@ -51,6 +51,9 @@ MEMORY_AREA MiStaticMemoryAreas[MI_STATIC_MEMORY_AREAS]; ULONG MiStaticMemoryAreaCount; +MM_AVL_TABLE MiRosKernelVadRoot; +BOOLEAN MiRosKernelVadRootInitialized; + /* FUNCTIONS *****************************************************************/ /** @@ -162,9 +165,10 @@ PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress( PMMSUPPORT AddressSpace, - PVOID Address) + PVOID Address_) { PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; + ULONG_PTR Address = (ULONG_PTR)Address_; DPRINT("MmLocateMemoryAreaByAddress(AddressSpace %p, Address %p)\n", AddressSpace, Address); @@ -171,14 +175,14 @@ while (Node != NULL) { - if (Address < Node->StartingAddress) + if (Address < MA_GetStartingAddress(Node)) Node = Node->LeftChild; - else if (Address >= Node->EndingAddress) + else if (Address >= MA_GetEndingAddress(Node)) Node = Node->RightChild; else { DPRINT("MmLocateMemoryAreaByAddress(%p): %p [%p - %p]\n", - Address, Node, Node->StartingAddress, Node->EndingAddress); + Address, Node, MA_GetStartingAddress(Node), MA_GetEndingAddress(Node)); return Node; } } @@ -187,14 +191,65 @@ return NULL; } -PMEMORY_AREA NTAPI +PMEMORY_AREA +NTAPI MmLocateMemoryAreaByRegion( PMMSUPPORT AddressSpace, - PVOID Address, + PVOID Address_, ULONG_PTR Length) { + ULONG_PTR StartVpn = (ULONG_PTR)Address_ / PAGE_SIZE; + ULONG_PTR EndVpn = ((ULONG_PTR)Address_ + Length - 1) / PAGE_SIZE; + PEPROCESS Process; + PMM_AVL_TABLE Table; + PMMADDRESS_NODE Node; + PMEMORY_AREA MemoryArea; + TABLE_SEARCH_RESULT Result; + PMMVAD_LONG Vad; + + Process = MmGetAddressSpaceOwner(AddressSpace); + Table = (Process != NULL) ? &Process->VadRoot : &MiRosKernelVadRoot; + + Result = MiCheckForConflictingNode(StartVpn, EndVpn, Table, &Node); + if (Result != TableFoundNode) + { + return NULL; + } + + Vad = (PMMVAD_LONG)Node; + if (Vad->u.VadFlags.Spare == 0) + { + /* Check if this is VM VAD */ + if (Vad->ControlArea == NULL) + { + /* We store the reactos MEMORY_AREA here */ + MemoryArea = (PMEMORY_AREA)Vad->FirstPrototypePte; + } + else + { + /* This is a section VAD. Store the MAREA here for now */ + MemoryArea = (PMEMORY_AREA)Vad->u4.Banked; + } + } + else + { + MemoryArea = (PMEMORY_AREA)Node; + } + + ASSERT(MemoryArea != NULL); + return MemoryArea; +} + +PMEMORY_AREA +NTAPI +MmLocateMemoryAreaByRegionOld( + PMMSUPPORT AddressSpace, + PVOID Address_, + ULONG_PTR Length) +{ PMEMORY_AREA Node; - PVOID Extent = (PVOID)((ULONG_PTR)Address + Length); + ULONG_PTR Address = (ULONG_PTR)Address_; + ULONG_PTR Extent = Address + Length; /* Special case for empty tree. */ if (AddressSpace->WorkingSetExpansionLinks.Flink == NULL) @@ -205,31 +260,31 @@ Node != NULL; Node = MmIterateNextNode(Node)) { - if (Node->StartingAddress >= Address && - Node->StartingAddress < Extent) + if (MA_GetStartingAddress(Node) >= Address && + MA_GetStartingAddress(Node) < Extent) { DPRINT("MmLocateMemoryAreaByRegion(%p - %p): %p - %p\n", - Address, (ULONG_PTR)Address + Length, Node->StartingAddress, - Node->EndingAddress); + Address, (ULONG_PTR)Address + Length, MA_GetStartingAddress(Node), + MA_GetEndingAddress(Node)); return Node; } - if (Node->EndingAddress > Address && - Node->EndingAddress < Extent) + if (MA_GetEndingAddress(Node) > Address && + MA_GetEndingAddress(Node) < Extent) { DPRINT("MmLocateMemoryAreaByRegion(%p - %p): %p - %p\n", - Address, (ULONG_PTR)Address + Length, Node->StartingAddress, - Node->EndingAddress); + Address, (ULONG_PTR)Address + Length, MA_GetStartingAddress(Node), + MA_GetEndingAddress(Node)); return Node; } - if (Node->StartingAddress <= Address && - Node->EndingAddress >= Extent) + if (MA_GetStartingAddress(Node) <= Address && + MA_GetEndingAddress(Node) >= Extent) { DPRINT("MmLocateMemoryAreaByRegion(%p - %p): %p - %p\n", - Address, (ULONG_PTR)Address + Length, Node->StartingAddress, - Node->EndingAddress); + Address, (ULONG_PTR)Address + Length, MA_GetStartingAddress(Node), + MA_GetEndingAddress(Node)); return Node; } - if (Node->StartingAddress >= Extent) + if (MA_GetStartingAddress(Node) >= Extent) { DPRINT("Finished MmLocateMemoryAreaByRegion() = NULL\n"); return NULL; @@ -357,7 +412,7 @@ VOID NTAPI MiInsertVad(IN PMMVAD Vad, - IN PEPROCESS Process); + IN PMM_AVL_TABLE VadRoot); ULONG NTAPI @@ -365,6 +420,7 @@ IN ULONG Protect ); + static VOID MmInsertMemoryArea( PMMSUPPORT AddressSpace, @@ -375,38 +431,37 @@ ULONG Depth = 0; PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); + marea->VadNode.StartingVpn = marea->StartingVpn; + marea->VadNode.EndingVpn = marea->EndingVpn; + marea->VadNode.u.VadFlags.Spare = 1; + marea->VadNode.u.VadFlags.Protection = MiMakeProtectionMask(marea->Protect); + /* Build a lame VAD if this is a user-space allocation */ - if ((marea->EndingAddress < MmSystemRangeStart) && (marea->Type != MEMORY_AREA_OWNED_BY_ARM3)) + if (MA_GetEndingAddress(marea) < (ULONG_PTR)MmSystemRangeStart) { - PMMVAD Vad; + if (marea->Type != MEMORY_AREA_OWNED_BY_ARM3) + { + ASSERT(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)); - Vad->StartingVpn = PAGE_ROUND_DOWN(marea->StartingAddress) >> PAGE_SHIFT; - /* - * For some strange reason, it is perfectly valid to create a MAREA from 0x1000 to... 0x1000. - * In a normal OS/Memory Manager, this would be retarded, but ReactOS allows this (how it works - * I don't even want to know). - */ - if (marea->EndingAddress != marea->StartingAddress) - { - Vad->EndingVpn = PAGE_ROUND_DOWN((ULONG_PTR)marea->EndingAddress - 1) >> PAGE_SHIFT; + /* Insert the VAD */ + MiLockProcessWorkingSetUnsafe(PsGetCurrentProcess(), PsGetCurrentThread()); + MiInsertVad(&marea->VadNode, &Process->VadRoot); + MiUnlockProcessWorkingSetUnsafe(PsGetCurrentProcess(), PsGetCurrentThread()); + marea->Vad = &marea->VadNode; } - else + } + else + { + if (!MiRosKernelVadRootInitialized) { - Vad->EndingVpn = Vad->StartingVpn; + MiRosKernelVadRoot.BalancedRoot.u1.Parent = &MiRosKernelVadRoot.BalancedRoot; + MiRosKernelVadRootInitialized = TRUE; } - Vad->u.VadFlags.Spare = 1; - Vad->u.VadFlags.Protection = MiMakeProtectionMask(marea->Protect); /* Insert the VAD */ - MiInsertVad(Vad, Process); - marea->Vad = Vad; - } - else - { + //MiLockProcessWorkingSetUnsafe(PsGetCurrentProcess(), PsGetCurrentThread()); + MiInsertVad(&marea->VadNode, &MiRosKernelVadRoot); + //MiUnlockProcessWorkingSetUnsafe(PsGetCurrentProcess(), PsGetCurrentThread()); marea->Vad = NULL; } @@ -420,17 +475,17 @@ Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; do { - DPRINT("marea->EndingAddress: %p Node->StartingAddress: %p\n", - marea->EndingAddress, Node->StartingAddress); - DPRINT("marea->StartingAddress: %p Node->EndingAddress: %p\n", - marea->StartingAddress, Node->EndingAddress); - ASSERT(marea->EndingAddress <= Node->StartingAddress || - marea->StartingAddress >= Node->EndingAddress); - ASSERT(marea->StartingAddress != Node->StartingAddress); + DPRINT("MA_GetEndingAddress(marea): %p Node->StartingAddress: %p\n", + MA_GetEndingAddress(marea), MA_GetStartingAddress(Node)); + DPRINT("marea->StartingAddress: %p MA_GetEndingAddress(Node): %p\n", + MA_GetStartingAddress(marea), MA_GetEndingAddress(Node)); + ASSERT(MA_GetEndingAddress(marea) <= MA_GetStartingAddress(Node) || + MA_GetStartingAddress(marea) >= MA_GetEndingAddress(Node)); + ASSERT(MA_GetStartingAddress(marea) != MA_GetStartingAddress(Node)); PreviousNode = Node; - if (marea->StartingAddress < Node->StartingAddress) + if (MA_GetStartingAddress(marea) < MA_GetStartingAddress(Node)) Node = Node->LeftChild; else Node = Node->RightChild; @@ -449,7 +504,7 @@ marea->LeftChild = marea->RightChild = NULL; marea->Parent = PreviousNode; - if (marea->StartingAddress < PreviousNode->StartingAddress) + if (MA_GetStartingAddress(marea) < MA_GetStartingAddress(PreviousNode)) PreviousNode->LeftChild = marea; else PreviousNode->RightChild = marea; @@ -487,16 +542,16 @@ /* Go to the node with lowest address in the tree. */ Node = Root ? MmIterateFirstNode(Root) : NULL; - while (Node && ((ULONG_PTR)Node->EndingAddress < LowestAddress)) + while (Node && ((ULONG_PTR)MA_GetEndingAddress(Node) < LowestAddress)) { Node = MmIterateNextNode(Node); } /* Traverse the tree from low to high addresses */ - while (Node && ((ULONG_PTR)Node->EndingAddress < HighestAddress)) + while (Node && ((ULONG_PTR)MA_GetEndingAddress(Node) < HighestAddress)) { /* Check if the memory area fits before the current node */ - if ((ULONG_PTR)Node->StartingAddress >= (Candidate + Length)) + if (MA_GetStartingAddress(Node) >= (Candidate + Length)) { DPRINT("MmFindGapBottomUp: %p\n", Candidate); ASSERT(Candidate >= LowestAddress); @@ -504,10 +559,10 @@ } /* Calculate next possible adress above this node */ - Candidate = ALIGN_UP_BY((ULONG_PTR)Node->EndingAddress, Granularity); + Candidate = ALIGN_UP_BY((ULONG_PTR)MA_GetEndingAddress(Node), Granularity); /* Check for overflow */ - if ((Candidate + Length) < (ULONG_PTR)Node->EndingAddress) return NULL; + if ((Candidate + Length) < (ULONG_PTR)MA_GetEndingAddress(Node)) return NULL; /* Go to the next higher node */ Node = MmIterateNextNode(Node); @@ -558,16 +613,16 @@ /* Go to the node with highest address in the tree. */ Node = Root ? MmIterateLastNode(Root) : NULL; - while (Node && ((ULONG_PTR)Node->StartingAddress > HighestAddress)) + while (Node && (MA_GetStartingAddress(Node) > HighestAddress)) { Node = MmIteratePrevNode(Node); } /* Traverse the tree from high to low addresses */ - while (Node && ((ULONG_PTR)Node->StartingAddress > LowestAddress)) + while (Node && (MA_GetStartingAddress(Node) > LowestAddress)) { /* Check if the memory area fits after the current node */ - if ((ULONG_PTR)Node->EndingAddress <= Candidate) + if ((ULONG_PTR)MA_GetEndingAddress(Node) <= Candidate) { DPRINT("MmFindGapTopDown: %p\n", Candidate); return (PVOID)Candidate; @@ -574,11 +629,11 @@ } /* Calculate next possible adress below this node */ - Candidate = ALIGN_DOWN_BY((ULONG_PTR)Node->StartingAddress - Length, + Candidate = ALIGN_DOWN_BY(MA_GetStartingAddress(Node) - Length, Granularity); /* Check for overflow. */ - if (Candidate > (ULONG_PTR)Node->StartingAddress) + if (Candidate > MA_GetStartingAddress(Node)) return NULL; /* Go to the next lower node */ @@ -610,66 +665,6 @@ return MmFindGapBottomUp(AddressSpace, Length, Granularity); } -ULONG_PTR NTAPI -MmFindGapAtAddress( - PMMSUPPORT AddressSpace, - PVOID Address) -{ - PMEMORY_AREA Node = (PMEMORY_AREA)AddressSpace->WorkingSetExpansionLinks.Flink; - PMEMORY_AREA RightNeighbour = NULL; - PVOID LowestAddress = MmGetAddressSpaceOwner(AddressSpace) ? MM_LOWEST_USER_ADDRESS : MmSystemRangeStart; - PVOID HighestAddress = MmGetAddressSpaceOwner(AddressSpace) ? - (PVOID)((ULONG_PTR)MmSystemRangeStart - 1) : (PVOID)MAXULONG_PTR; - - Address = MM_ROUND_DOWN(Address, PAGE_SIZE); - - if (LowestAddress < MmSystemRangeStart) - { - if (Address >= MmSystemRangeStart) - { - return 0; - } - } - else - { - if (Address < LowestAddress) - { - return 0; - } - } - - while (Node != NULL) - { - if (Address < Node->StartingAddress) - { - RightNeighbour = Node; - Node = Node->LeftChild; - } - else if (Address >= Node->EndingAddress) - { - Node = Node->RightChild; - } - else - { - DPRINT("MmFindGapAtAddress: 0\n"); - return 0; - } - } - - if (RightNeighbour) - { - DPRINT("MmFindGapAtAddress: %p [%p]\n", Address, - (ULONG_PTR)RightNeighbour->StartingAddress - (ULONG_PTR)Address); - return (ULONG_PTR)RightNeighbour->StartingAddress - (ULONG_PTR)Address; - } - else - { - DPRINT("MmFindGapAtAddress: %p [%p]\n", Address, - (ULONG_PTR)HighestAddress - (ULONG_PTR)Address); - return (ULONG_PTR)HighestAddress - (ULONG_PTR)Address; - } -} - VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, @@ -687,10 +682,10 @@ /* Check some fields */ ASSERT(Node->Magic == 'erAM'); - ASSERT(PAGE_ALIGN(Node->StartingAddress) == Node->StartingAddress); - ASSERT(Node->EndingAddress != NULL); - ASSERT(PAGE_ALIGN(Node->EndingAddress) == Node->EndingAddress); - ASSERT((ULONG_PTR)Node->StartingAddress < (ULONG_PTR)Node->EndingAddress); + ASSERT(PAGE_ALIGN(MA_GetStartingAddress(Node)) == (PVOID)MA_GetStartingAddress(Node)); + ASSERT(MA_GetEndingAddress(Node) != 0); + ASSERT(PAGE_ALIGN(MA_GetEndingAddress(Node)) == (PVOID)MA_GetEndingAddress(Node)); + ASSERT(MA_GetStartingAddress(Node) < MA_GetEndingAddress(Node)); ASSERT((Node->Type == 0) || (Node->Type == MEMORY_AREA_CACHE) || // (Node->Type == MEMORY_AREA_CACHE_SEGMENT) || @@ -822,8 +817,8 @@ KeAttachProcess(&Process->Pcb); } - EndAddress = MM_ROUND_UP(MemoryArea->EndingAddress, PAGE_SIZE); - for (Address = (ULONG_PTR)MemoryArea->StartingAddress; + EndAddress = MM_ROUND_UP(MA_GetEndingAddress(MemoryArea), PAGE_SIZE); + for (Address = MA_GetStartingAddress(MemoryArea); Address < (ULONG_PTR)EndAddress; Address += PAGE_SIZE) { @@ -870,21 +865,25 @@ KeDetachProcess(); } + //if (MemoryArea->VadNode.StartingVpn < (ULONG_PTR)MmSystemRangeStart >> PAGE_SHIFT if (MemoryArea->Vad) { - ASSERT(MemoryArea->EndingAddress < MmSystemRangeStart); + ASSERT(MA_GetEndingAddress(MemoryArea) < (ULONG_PTR)MmSystemRangeStart); 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); + ASSERT(MemoryArea->VadNode.u.VadFlags.Spare != 0); if (((PMMVAD)MemoryArea->Vad)->u.VadFlags.Spare == 1) { - MiRemoveNode(MemoryArea->Vad, &Process->VadRoot); + MiRemoveNode((PMMADDRESS_NODE)&MemoryArea->VadNode, &Process->VadRoot); } - ExFreePoolWithTag(MemoryArea->Vad, TAG_MVAD); MemoryArea->Vad = NULL; } + else + { + MiRemoveNode((PMMADDRESS_NODE)&MemoryArea->VadNode, &MiRosKernelVadRoot); + } } /* Remove the tree item. */ @@ -981,7 +980,6 @@ ULONG_PTR Length, ULONG Protect, PMEMORY_AREA *Result, - BOOLEAN FixedAddress, ULONG AllocationFlags, ULONG Granularity) { @@ -991,12 +989,47 @@ DPRINT("MmCreateMemoryArea(Type 0x%lx, BaseAddress %p, " "*BaseAddress %p, Length %p, AllocationFlags %x, " - "FixedAddress %x, Result %p)\n", + "Result %p)\n", Type, BaseAddress, *BaseAddress, Length, AllocationFlags, - FixedAddress, Result); + Result); - if ((*BaseAddress) == 0 && !FixedAddress) + // + // Is this a static memory area? + // + if (Type & MEMORY_AREA_STATIC) { + // + // Use the static array instead of the pool + // + ASSERT(MiStaticMemoryAreaCount < MI_STATIC_MEMORY_AREAS); + MemoryArea = &MiStaticMemoryAreas[MiStaticMemoryAreaCount++]; + } + else + { + // + // Allocate the memory area from nonpaged pool + // + MemoryArea = ExAllocatePoolWithTag(NonPagedPool, + sizeof(MEMORY_AREA), + TAG_MAREA); + } + + if (!MemoryArea) + { + DPRINT1("Not enough memory.\n"); + return STATUS_NO_MEMORY; + } + + RtlZeroMemory(MemoryArea, sizeof(MEMORY_AREA)); + MemoryArea->Type = Type & ~MEMORY_AREA_STATIC; + MemoryArea->Protect = Protect; + MemoryArea->Flags = AllocationFlags; + //MemoryArea->LockCount = 0; + MemoryArea->Magic = 'erAM'; + MemoryArea->DeleteInProgress = FALSE; + + if (*BaseAddress == 0) + { tmpLength = (ULONG_PTR)MM_ROUND_UP(Length, PAGE_SIZE); *BaseAddress = MmFindGap(AddressSpace, tmpLength, @@ -1005,8 +1038,13 @@ if ((*BaseAddress) == 0) { DPRINT("No suitable gap\n"); + if (!(Type & MEMORY_AREA_STATIC)) ExFreePoolWithTag(MemoryArea, TAG_MAREA); return STATUS_NO_MEMORY; } + + MemoryArea->StartingVpn = (ULONG_PTR)*BaseAddress >> PAGE_SHIFT; + MemoryArea->EndingVpn = ((ULONG_PTR)*BaseAddress + tmpLength - 1) >> PAGE_SHIFT; + MmInsertMemoryArea(AddressSpace, MemoryArea); } else { @@ -1016,6 +1054,8 @@ if (!MmGetAddressSpaceOwner(AddressSpace) && *BaseAddress < MmSystemRangeStart) { + ASSERT(FALSE); + if (!(Type & MEMORY_AREA_STATIC)) ExFreePoolWithTag(MemoryArea, TAG_MAREA); return STATUS_ACCESS_VIOLATION; } @@ -1023,58 +1063,40 @@ (ULONG_PTR)(*BaseAddress) + tmpLength > (ULONG_PTR)MmSystemRangeStart) { DPRINT("Memory area for user mode address space exceeds MmSystemRangeStart\n"); + if (!(Type & MEMORY_AREA_STATIC)) ExFreePoolWithTag(MemoryArea, TAG_MAREA); return STATUS_ACCESS_VIOLATION; } - if (MmLocateMemoryAreaByRegion(AddressSpace, - *BaseAddress, - tmpLength) != NULL) + /* Check if this is a region owned by ARM3 */ + if (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3) { - DPRINT("Memory area already occupied\n"); - return STATUS_CONFLICTING_ADDRESSES; + /* ARM3 is inserting this MA to synchronize the old tree, use the old tree */ + if (MmLocateMemoryAreaByRegionOld(AddressSpace, + *BaseAddress, + tmpLength) != NULL) + { + DPRINT("Memory area already occupied\n"); + if (!(Type & MEMORY_AREA_STATIC)) ExFreePoolWithTag(MemoryArea, TAG_MAREA); + return STATUS_CONFLICTING_ADDRESSES; + } } - } + else + { + if (MmLocateMemoryAreaByRegion(AddressSpace, + *BaseAddress, + tmpLength) != NULL) + { + DPRINT("Memory area already occupied\n"); + if (!(Type & MEMORY_AREA_STATIC)) ExFreePoolWithTag(MemoryArea, TAG_MAREA); + return STATUS_CONFLICTING_ADDRESSES; + } + } - // - // Is this a static memory area? - // - if (Type & MEMORY_AREA_STATIC) - { - // - // Use the static array instead of the pool - // - ASSERT(MiStaticMemoryAreaCount < MI_STATIC_MEMORY_AREAS); - MemoryArea = &MiStaticMemoryAreas[MiStaticMemoryAreaCount++]; - Type &= ~MEMORY_AREA_STATIC; + MemoryArea->StartingVpn = (ULONG_PTR)*BaseAddress >> PAGE_SHIFT; + MemoryArea->EndingVpn = ((ULONG_PTR)*BaseAddress + tmpLength - 1) >> PAGE_SHIFT; + MmInsertMemoryArea(AddressSpace, MemoryArea); } - else - { - // - // Allocate the memory area from nonpaged pool - // - MemoryArea = ExAllocatePoolWithTag(NonPagedPool, - sizeof(MEMORY_AREA), - TAG_MAREA); - } - if (!MemoryArea) - { - DPRINT1("Not enough memory.\n"); - return STATUS_NO_MEMORY; - } - - RtlZeroMemory(MemoryArea, sizeof(MEMORY_AREA)); - MemoryArea->Type = Type; - MemoryArea->StartingAddress = *BaseAddress; - MemoryArea->EndingAddress = (PVOID)((ULONG_PTR)*BaseAddress + tmpLength); - MemoryArea->Protect = Protect; - MemoryArea->Flags = AllocationFlags; - //MemoryArea->LockCount = 0; - MemoryArea->Magic = 'erAM'; - MemoryArea->DeleteInProgress = FALSE; - - MmInsertMemoryArea(AddressSpace, MemoryArea); - *Result = MemoryArea; DPRINT("MmCreateMemoryArea() succeeded (%p)\n", *BaseAddress); @@ -1081,7 +1103,40 @@ return STATUS_SUCCESS; } +VOID +NTAPI +MiRosCleanupMemoryArea( + PEPROCESS Process, + PMMVAD Vad) +{ + PMEMORY_AREA MemoryArea; + PVOID BaseAddress; + NTSTATUS Status; + /* We must be called from MmCleanupAddressSpace and nowhere else! + Make sure things are as expected... */ + ASSERT(Process == PsGetCurrentProcess()); + ASSERT(Process->VmDeleted == TRUE); + ASSERT(((PsGetCurrentThread()->ThreadsProcess == Process) && + (Process->ActiveThreads == 1)) || + (Process->ActiveThreads == 0)); + + MemoryArea = (PMEMORY_AREA)Vad; + ASSERT(MemoryArea->Type == MEMORY_AREA_SECTION_VIEW); + BaseAddress = (PVOID)MA_GetStartingAddress(MemoryArea); + + /* We are in cleanup, we don't need to synchronize */ + MmUnlockAddressSpace(&Process->Vm); + + Status = MiRosUnmapViewOfSection(Process, BaseAddress, 0); + + /* Make sure this worked! */ + ASSERT(NT_SUCCESS(Status)); + + /* Lock the address space again */ + MmLockAddressSpace(&Process->Vm); +} + VOID NTAPI MmDeleteProcessAddressSpace2(IN PEPROCESS Process); @@ -1106,7 +1161,7 @@ switch (MemoryArea->Type) { case MEMORY_AREA_SECTION_VIEW: - Address = (PVOID)MemoryArea->StartingAddress; + Address = (PVOID)MA_GetStartingAddress(MemoryArea); MmUnlockAddressSpace(&Process->Vm); MmUnmapViewOfSection(Process, Address); MmLockAddressSpace(&Process->Vm); @@ -1113,7 +1168,7 @@ break; case MEMORY_AREA_CACHE: - Address = (PVOID)MemoryArea->StartingAddress; + Address = (PVOID)MA_GetStartingAddress(MemoryArea); MmUnlockAddressSpace(&Process->Vm); MmUnmapViewOfCacheSegment(&Process->Vm, Address); MmLockAddressSpace(&Process->Vm); Index: ntoskrnl/mm/mminit.c =================================================================== --- ntoskrnl/mm/mminit.c (revision 64688) +++ ntoskrnl/mm/mminit.c (working copy) @@ -57,7 +57,6 @@ MmBootImageSize, PAGE_EXECUTE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -72,7 +71,6 @@ PTE_TOP - PTE_BASE + 1, PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -87,7 +85,6 @@ HYPER_SPACE_END - HYPER_SPACE + 1, PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -102,7 +99,6 @@ (MxPfnAllocation << PAGE_SHIFT), PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -117,7 +113,6 @@ MmSizeOfNonPagedPoolInBytes, PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -132,7 +127,6 @@ MiNonPagedSystemSize, PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -147,7 +141,6 @@ MmSystemViewSize, PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -163,7 +156,6 @@ (ULONG_PTR)MmSessionBase, PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -178,7 +170,6 @@ MmSizeOfPagedPoolInBytes, PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -193,7 +184,6 @@ PAGE_SIZE * KeNumberProcessors, PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -208,7 +198,6 @@ PAGE_SIZE, PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -223,7 +212,6 @@ PAGE_SIZE, PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); @@ -239,7 +227,6 @@ PAGE_SIZE * 2, PAGE_READWRITE, &MArea, - TRUE, 0, PAGE_SIZE); ASSERT(Status == STATUS_SUCCESS); Index: ntoskrnl/mm/rmap.c =================================================================== --- ntoskrnl/mm/rmap.c (revision 64688) +++ ntoskrnl/mm/rmap.c (working copy) @@ -137,7 +137,7 @@ { ULONG_PTR Entry; Offset = MemoryArea->Data.SectionData.ViewOffset.QuadPart + - ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress); + ((ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)); MmLockSectionSegment(MemoryArea->Data.SectionData.Segment); Index: ntoskrnl/mm/section.c =================================================================== --- ntoskrnl/mm/section.c (revision 64688) +++ ntoskrnl/mm/section.c (working copy) @@ -1322,12 +1322,12 @@ } PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE); - Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress + Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea) + MemoryArea->Data.SectionData.ViewOffset.QuadPart; Segment = MemoryArea->Data.SectionData.Segment; Section = MemoryArea->Data.SectionData.Section; - Region = MmFindRegion(MemoryArea->StartingAddress, + Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea), &MemoryArea->Data.SectionData.RegionListHead, Address, NULL); ASSERT(Region != NULL); @@ -1699,12 +1699,12 @@ * Find the offset of the page */ PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE); - Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress + Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea) + MemoryArea->Data.SectionData.ViewOffset.QuadPart; Segment = MemoryArea->Data.SectionData.Segment; Section = MemoryArea->Data.SectionData.Section; - Region = MmFindRegion(MemoryArea->StartingAddress, + Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea), &MemoryArea->Data.SectionData.RegionListHead, Address, NULL); ASSERT(Region != NULL); @@ -1894,7 +1894,7 @@ Context.SectionEntry = Entry; Context.CallingProcess = Process; - Context.Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress + Context.Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea) + MemoryArea->Data.SectionData.ViewOffset.QuadPart; FileOffset = Context.Offset.QuadPart + Context.Segment->Image.FileOffset; @@ -2291,7 +2291,7 @@ Address = (PVOID)PAGE_ROUND_DOWN(Address); - Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress + Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea) + MemoryArea->Data.SectionData.ViewOffset.QuadPart; /* @@ -2473,7 +2473,7 @@ ULONG_PTR Entry; PFN_NUMBER Page; - Offset.QuadPart = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress + Offset.QuadPart = (ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea) + MemoryArea->Data.SectionData.ViewOffset.QuadPart; Entry = MmGetPageEntrySectionSegment(Segment, &Offset); /* @@ -2515,11 +2515,11 @@ NTSTATUS Status; ULONG_PTR MaxLength; - MaxLength = (ULONG_PTR)MemoryArea->EndingAddress - (ULONG_PTR)BaseAddress; + MaxLength = MA_GetEndingAddress(MemoryArea) - (ULONG_PTR)BaseAddress; if (Length > MaxLength) Length = (ULONG)MaxLength; - Region = MmFindRegion(MemoryArea->StartingAddress, + Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea), &MemoryArea->Data.SectionData.RegionListHead, BaseAddress, NULL); ASSERT(Region != NULL); @@ -2531,7 +2531,7 @@ } *OldProtect = Region->Protect; - Status = MmAlterRegion(AddressSpace, MemoryArea->StartingAddress, + Status = MmAlterRegion(AddressSpace, (PVOID)MA_GetStartingAddress(MemoryArea), &MemoryArea->Data.SectionData.RegionListHead, BaseAddress, Length, Region->Type, Protect, MmAlterViewAttributes); @@ -2550,7 +2550,7 @@ PROS_SECTION_OBJECT Section; PMM_SECTION_SEGMENT Segment; - Region = MmFindRegion((PVOID)MemoryArea->StartingAddress, + Region = MmFindRegion((PVOID)MA_GetStartingAddress(MemoryArea), &MemoryArea->Data.SectionData.RegionListHead, Address, &RegionBaseAddress); if (Region == NULL) @@ -2562,12 +2562,12 @@ if (Section->AllocationAttributes & SEC_IMAGE) { Segment = MemoryArea->Data.SectionData.Segment; - Info->AllocationBase = (PUCHAR)MemoryArea->StartingAddress - Segment->Image.VirtualAddress; + Info->AllocationBase = (PUCHAR)MA_GetStartingAddress(MemoryArea) - Segment->Image.VirtualAddress; Info->Type = MEM_IMAGE; } else { - Info->AllocationBase = MemoryArea->StartingAddress; + Info->AllocationBase = (PVOID)MA_GetStartingAddress(MemoryArea); Info->Type = MEM_MAPPED; } Info->BaseAddress = RegionBaseAddress; @@ -3960,7 +3960,6 @@ ViewSize, Protect, &MArea, - FALSE, AllocationType, Granularity); if (!NT_SUCCESS(Status)) @@ -4001,7 +4000,7 @@ Address = (PVOID)PAGE_ROUND_DOWN(Address); - Offset.QuadPart = ((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress) + + Offset.QuadPart = ((ULONG_PTR)Address - MA_GetStartingAddress(MemoryArea)) + MemoryArea->Data.SectionData.ViewOffset.QuadPart; Section = MemoryArea->Data.SectionData.Section;