[NTOSKRNL]

Insert kernel memory areas into a "kernel VAD table".

svn path=/trunk/; revision=67792
This commit is contained in:
Timo Kreuzer 2015-05-16 23:36:42 +00:00
parent 3964d05fb8
commit 53a77173f5
3 changed files with 40 additions and 27 deletions

View file

@ -2039,13 +2039,6 @@ MiCheckSecuredVad(
IN ULONG ProtectionMask
);
VOID
NTAPI
MiInsertVad(
IN PMMVAD Vad,
IN PEPROCESS Process
);
NTSTATUS
NTAPI
MiInsertVadEx(

View file

@ -181,24 +181,22 @@ MiInsertNode(IN PMM_AVL_TABLE Table,
VOID
NTAPI
MiInsertVad(IN PMMVAD Vad,
IN PEPROCESS Process)
IN PMM_AVL_TABLE VadRoot)
{
TABLE_SEARCH_RESULT Result;
PMMADDRESS_NODE Parent = NULL;
/* 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

View file

@ -359,7 +359,7 @@ MmRebalanceTree(
VOID
NTAPI
MiInsertVad(IN PMMVAD Vad,
IN PEPROCESS Process);
IN PMM_AVL_TABLE VadRoot);
ULONG
NTAPI
@ -367,6 +367,9 @@ MiMakeProtectionMask(
IN ULONG Protect
);
MM_AVL_TABLE MiRosKernelVadRoot;
BOOLEAN MiRosKernelVadRootInitialized;
static VOID
MmInsertMemoryArea(
PMMSUPPORT AddressSpace,
@ -377,23 +380,37 @@ MmInsertMemoryArea(
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 ((MA_GetEndingAddress(marea) < (ULONG_PTR)MmSystemRangeStart) &&
(marea->Type != MEMORY_AREA_OWNED_BY_ARM3))
if (MA_GetEndingAddress(marea) < (ULONG_PTR)MmSystemRangeStart)
{
ASSERT(marea->Type == MEMORY_AREA_SECTION_VIEW || marea->Type == MEMORY_AREA_CACHE);
if (marea->Type != MEMORY_AREA_OWNED_BY_ARM3)
{
ASSERT(marea->Type == MEMORY_AREA_SECTION_VIEW || marea->Type == MEMORY_AREA_CACHE);
marea->VadNode.StartingVpn = marea->StartingVpn;
marea->VadNode.EndingVpn = marea->EndingVpn;
marea->VadNode.u.VadFlags.Spare = 1;
marea->VadNode.u.VadFlags.Protection = MiMakeProtectionMask(marea->Protect);
/* Insert the VAD */
MiInsertVad(&marea->VadNode, Process);
marea->Vad = &marea->VadNode;
/* Insert the VAD */
MiLockProcessWorkingSetUnsafe(PsGetCurrentProcess(), PsGetCurrentThread());
MiInsertVad(&marea->VadNode, &Process->VadRoot);
MiUnlockProcessWorkingSetUnsafe(PsGetCurrentProcess(), PsGetCurrentThread());
marea->Vad = &marea->VadNode;
}
}
else
{
if (!MiRosKernelVadRootInitialized)
{
MiRosKernelVadRoot.BalancedRoot.u1.Parent = &MiRosKernelVadRoot.BalancedRoot;
MiRosKernelVadRootInitialized = TRUE;
}
/* Insert the VAD */
MiLockWorkingSet(PsGetCurrentThread(), &MmSystemCacheWs);
MiInsertVad(&marea->VadNode, &MiRosKernelVadRoot);
MiUnlockWorkingSet(PsGetCurrentThread(), &MmSystemCacheWs);
marea->Vad = NULL;
}
@ -797,20 +814,25 @@ MmFreeMemoryArea(
KeDetachProcess();
}
//if (MemoryArea->VadNode.StartingVpn < (ULONG_PTR)MmSystemRangeStart >> PAGE_SHIFT
if (MemoryArea->Vad)
{
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);
}
MemoryArea->Vad = NULL;
}
else
{
MiRemoveNode((PMMADDRESS_NODE)&MemoryArea->VadNode, &MiRosKernelVadRoot);
}
}
/* Remove the tree item. */