[NTOS]: Complete the VAD-to-MAREA Synchronization hack by removing fake MAREAs that were added when inserting real VADs. To do this, we have to track the fake MAREA associated with a VAD, so we overload the FirstProtoTypePte field in the VAD, if this is NOT a section VAD (which we don't use yet). We'll figure something out for section VADs later.

[NTOS]: Now that VAD and MAREA views are synchronized, remove the VAD limit and let VADs be created at any address. Also do not create an arbitrary 16MB VAD memory area anymore. This basically now allows for as many PEB/TEBs as can fit in the address space, fixing the recent known regression that limited the number of threads a process could have.

svn path=/trunk/; revision=49193
This commit is contained in:
Sir Richard 2010-10-18 13:10:54 +00:00
parent 7c151f3f05
commit 26c20f3857
4 changed files with 78 additions and 32 deletions

View file

@ -45,9 +45,7 @@
#define MM_HIGHEST_VAD_ADDRESS \
(PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
/* The range 0x10000->0x7FEFFFFF is reserved for the ROSMM MAREA Allocator */
#define MI_LOWEST_VAD_ADDRESS (PVOID)0x7FF00000
#define MI_LOWEST_VAD_ADDRESS (PVOID)MM_LOWEST_USER_ADDRESS
#endif /* !_M_AMD64 */

View file

@ -29,14 +29,14 @@ MiRosTakeOverPebTebRanges(IN PEPROCESS Process)
NTSTATUS Status;
PMEMORY_AREA MemoryArea;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
PVOID AllocatedBase = (PVOID)MI_LOWEST_VAD_ADDRESS;
PVOID AllocatedBase = (PVOID)USER_SHARED_DATA;
BoundaryAddressMultiple.QuadPart = 0;
Status = MmCreateMemoryArea(&Process->Vm,
MEMORY_AREA_OWNED_BY_ARM3,
&AllocatedBase,
((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - 1) -
(ULONG_PTR)MI_LOWEST_VAD_ADDRESS,
(ULONG_PTR)USER_SHARED_DATA,
PAGE_READWRITE,
&MemoryArea,
TRUE,
@ -141,6 +141,8 @@ MiCreatePebOrTeb(IN PEPROCESS Process,
Process->VadRoot.NodeHint = Vad;
Vad->ControlArea = NULL; // For Memory-Area hack
Vad->FirstPrototypePte = NULL;
DPRINT("VAD: %p\n", Vad);
DPRINT("Allocated PEB/TEB at: 0x%p for %16s\n", *Base, Process->ImageFileName);
MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result);
/* Release the working set */
@ -150,7 +152,6 @@ MiCreatePebOrTeb(IN PEPROCESS Process,
KeReleaseGuardedMutex(&Process->AddressCreationLock);
/* Return the status */
DPRINT("Allocated PEB/TEB at: 0x%p for %16s\n", *Base, Process->ImageFileName);
return Status;
}

View file

@ -100,6 +100,43 @@ MiInsertNode(IN PMM_AVL_TABLE Table,
{
/* Insert it into the tree */
RtlpInsertAvlTreeNode(Table, NewNode, Parent, Result);
/* Now insert an ARM3 MEMORY_AREA for this node, unless the insert was already from the MEMORY_AREA code */
PMMVAD Vad = (PMMVAD)NewNode;
if (Vad->u.VadFlags.Spare == 0)
{
NTSTATUS Status;
PMEMORY_AREA MemoryArea;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
SIZE_T Size;
PEPROCESS Process = CONTAINING_RECORD(Table, EPROCESS, VadRoot);
PVOID AllocatedBase = (PVOID)(Vad->StartingVpn << PAGE_SHIFT);
BoundaryAddressMultiple.QuadPart = 0;
Size = ((Vad->EndingVpn + 1) - Vad->StartingVpn) << PAGE_SHIFT;
Status = MmCreateMemoryArea(&Process->Vm,
MEMORY_AREA_OWNED_BY_ARM3,
&AllocatedBase,
Size,
PAGE_READWRITE,
&MemoryArea,
TRUE,
0,
BoundaryAddressMultiple);
ASSERT(NT_SUCCESS(Status));
/* Check if this is VM VAD */
if (Vad->ControlArea == NULL)
{
/* We store the reactos MEMORY_AREA here */
DPRINT("Storing %p in %p\n", MemoryArea, Vad);
Vad->FirstPrototypePte = (PMMPTE)MemoryArea;
}
else
{
/* This is a section VAD, this code doesn't happen yet */
ASSERT(FALSE);
}
}
}
VOID
@ -121,28 +158,6 @@ MiInsertVad(IN PMMVAD Vad,
/* Do the actual insert operation */
MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result);
/* Now insert an ARM3 MEMORY_AREA for this node, unless the insert was already from the MEMORY_AREA code */
if (Vad->u.VadFlags.Spare == 0)
{
NTSTATUS Status;
PMEMORY_AREA MemoryArea;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
SIZE_T Size;
PVOID AllocatedBase = (PVOID)(Vad->StartingVpn << PAGE_SHIFT);
BoundaryAddressMultiple.QuadPart = 0;
Size = ((Vad->EndingVpn + 1) - Vad->StartingVpn) << PAGE_SHIFT;
Status = MmCreateMemoryArea(&Process->Vm,
MEMORY_AREA_OWNED_BY_ARM3,
&AllocatedBase,
Size,
PAGE_READWRITE,
&MemoryArea,
TRUE,
0,
BoundaryAddressMultiple);
ASSERT(NT_SUCCESS(Status));
}
}
VOID
@ -163,6 +178,38 @@ MiRemoveNode(IN PMMADDRESS_NODE Node,
if (!Table->NumberGenericTableElements) Table->NodeHint = NULL;
else Table->NodeHint = Table->BalancedRoot.RightChild;
}
/* Free the node from ReactOS view as well */
PMMVAD Vad = (PMMVAD)Node;
if (Vad->u.VadFlags.Spare == 0)
{
PMEMORY_AREA MemoryArea;
PEPROCESS Process;
/* Check if this is VM VAD */
if (Vad->ControlArea == NULL)
{
/* We store the ReactOS MEMORY_AREA here */
MemoryArea = (PMEMORY_AREA)Vad->FirstPrototypePte;
if (MemoryArea)
{
/* Get the process */
Process = CONTAINING_RECORD(Table, EPROCESS, VadRoot);
/* We only create fake memory-areas for ARM3 VADs */
ASSERT(MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3);
ASSERT(MemoryArea->Vad == NULL);
/* Free it */
MmFreeMemoryArea(&Process->Vm, MemoryArea, NULL, NULL);
}
}
else
{
/* This is a section VAD, this code doesn't happen yet */
ASSERT(FALSE);
}
}
}
PMMADDRESS_NODE

View file

@ -241,12 +241,12 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
/* We usually only get a VAD when it's not a VM address */
if (Vad)
{
/* At process deletion, we may get a VAD, but it should be a VM VAD */
ASSERT(Vad->u.VadFlags.PrivateMemory);
ASSERT(Vad->FirstPrototypePte == NULL);
/* Get out if this is a fake VAD, RosMm will free the marea pages */
if (Vad->u.VadFlags.Spare == 1) return;
/* At process deletion, we may get a VAD, but it should be a VM VAD */
ASSERT(Vad->u.VadFlags.PrivateMemory);
//ASSERT(Vad->FirstPrototypePte == NULL); memory_area fuckers
}
/* In all cases, we don't support fork() yet */