Author: tkreuzer Date: Wed Oct 8 00:31:09 2014 New Revision: 64588
URL: http://svn.reactos.org/svn/reactos?rev=64588&view=rev Log: [NTOSKRNL] Slightly refactor MiMapViewOfDataSection and NtAllocateVirtualMemory
Modified: trunk/reactos/ntoskrnl/mm/ARM3/section.c trunk/reactos/ntoskrnl/mm/ARM3/virtual.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/section.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/section.c?... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/section.c [iso-8859-1] Wed Oct 8 00:31:09 2014 @@ -1253,7 +1253,9 @@ { PMMVAD_LONG Vad; PETHREAD Thread = PsGetCurrentThread(); + PMMSUPPORT AddressSpace; ULONG_PTR StartAddress, EndingAddress; + ULONG_PTR ViewSizeInPages; PSUBSECTION Subsection; PSEGMENT Segment; PFN_NUMBER PteOffset; @@ -1263,6 +1265,7 @@ MMPTE TempPte; PMMADDRESS_NODE Parent; TABLE_SEARCH_RESULT Result; + DPRINT("Mapping ARM3 data section\n");
/* Get the segment for this section */ Segment = ControlArea->Segment; @@ -1340,75 +1343,8 @@ /* ARM3 does not currently support large pages */ ASSERT(Segment->SegmentFlags.LargePages == 0);
- /* Did the caller specify an address? */ - if (!(*BaseAddress) && !(Section->Address.StartingVpn)) - { - /* ARM3 does not support these flags yet */ - ASSERT(Process->VmTopDown == 0); - ASSERT(ZeroBits == 0); - - /* Which way should we search? */ - if (AllocationType & MEM_TOP_DOWN) - { - /* No, find an address top-down */ - Result = MiFindEmptyAddressRangeDownTree(*ViewSize, - (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS, - _64K, - &Process->VadRoot, - &StartAddress, - &Parent); - } - else - { - /* No, find an address bottom-up */ - Result = MiFindEmptyAddressRangeInTree(*ViewSize, - _64K, - &Process->VadRoot, - &Parent, - &StartAddress); - } - - /* Check if we found a suitable location */ - if (Result == TableFoundNode) - { - DPRINT1("Not enough free space to insert this section!\n"); - MiDereferenceControlArea(ControlArea); - return STATUS_CONFLICTING_ADDRESSES; - } - - /* Get the ending address, which is the last piece we need for the VAD */ - EndingAddress = (StartAddress + *ViewSize - 1) | (PAGE_SIZE - 1); - } - else - { - /* Is it SEC_BASED, or did the caller manually specify an address? */ - if (!(*BaseAddress)) - { - /* It is a SEC_BASED mapping, use the address that was generated */ - StartAddress = Section->Address.StartingVpn + SectionOffset->LowPart; - DPRINT("BASED: 0x%p\n", StartAddress); - } - else - { - /* Just align what the caller gave us */ - StartAddress = ROUND_UP((ULONG_PTR)*BaseAddress, _64K); - } - - /* Get the ending address, which is the last piece we need for the VAD */ - EndingAddress = (StartAddress + *ViewSize - 1) | (PAGE_SIZE - 1); - - /* Make sure it doesn't conflict with an existing allocation */ - Result = MiCheckForConflictingNode(StartAddress >> PAGE_SHIFT, - EndingAddress >> PAGE_SHIFT, - &Process->VadRoot, - &Parent); - if (Result == TableFoundNode) - { - DPRINT1("Conflict with SEC_BASED or manually based section!\n"); - MiDereferenceControlArea(ControlArea); - return STATUS_CONFLICTING_ADDRESSES; - } - } + /* Calculate how many pages the region spans */ + ViewSizeInPages = BYTES_TO_PAGES(*ViewSize);
/* A VAD can now be allocated. Do so and zero it out */ /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */ @@ -1419,12 +1355,11 @@ MiDereferenceControlArea(ControlArea); return STATUS_INSUFFICIENT_RESOURCES; } + RtlZeroMemory(Vad, sizeof(MMVAD_LONG)); Vad->u4.Banked = (PVOID)0xDEADBABE;
/* Write all the data required in the VAD for handling a fault */ - Vad->StartingVpn = StartAddress >> PAGE_SHIFT; - Vad->EndingVpn = EndingAddress >> PAGE_SHIFT; Vad->ControlArea = ControlArea; Vad->u.VadFlags.Protection = ProtectionMask; Vad->u2.VadFlags2.FileOffset = (ULONG)(SectionOffset->QuadPart >> 16); @@ -1438,7 +1373,7 @@
/* Finally, write down the first and last prototype PTE */ Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset]; - PteOffset += (Vad->EndingVpn - Vad->StartingVpn); + PteOffset += ViewSizeInPages - 1; ASSERT(PteOffset < Subsection->PtesInSubsection); Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset];
@@ -1447,19 +1382,6 @@
/* FIXME: Should setup VAD bitmap */ Status = STATUS_SUCCESS; - - /* Pretend as if we own the working set */ - MiLockProcessWorkingSetUnsafe(Process, Thread); - - /* Insert the VAD */ - Process->VadRoot.NodeHint = Vad; - MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result); - - /* Release the working set */ - MiUnlockProcessWorkingSetUnsafe(Process, Thread); - - /* Windows stores this for accounting purposes, do so as well */ - if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress;
/* Check if anything was committed */ if (QuotaCharge) @@ -1498,6 +1420,114 @@ /* Now that we're done, release the lock */ KeReleaseGuardedMutexUnsafe(&MmSectionCommitMutex); } + + /* Is it SEC_BASED, or did the caller manually specify an address? */ + if (*BaseAddress != NULL) + { + /* Just align what the caller gave us */ + StartAddress = ROUND_UP((ULONG_PTR)*BaseAddress, _64K); + } + else if (Section->Address.StartingVpn != 0) + { + /* It is a SEC_BASED mapping, use the address that was generated */ + StartAddress = Section->Address.StartingVpn + SectionOffset->LowPart; + } + else + { + StartAddress = 0; + } + + /* Lock the address space and make sure the process is alive */ + AddressSpace = MmGetCurrentAddressSpace(); + MmLockAddressSpace(AddressSpace); + if (Process->VmDeleted) + { + MmUnlockAddressSpace(AddressSpace); + ExFreePoolWithTag(Vad, 'ldaV'); + DPRINT1("The process is dying\n"); + return STATUS_PROCESS_IS_TERMINATING; + } + + /* Did the caller specify an address? */ + if (StartAddress == 0) + { + /* ARM3 does not support these flags yet */ + ASSERT(Process->VmTopDown == 0); + ASSERT(ZeroBits == 0); + + /* Which way should we search? */ + if (AllocationType & MEM_TOP_DOWN) + { + /* No, find an address top-down */ + Result = MiFindEmptyAddressRangeDownTree(*ViewSize, + (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS, + _64K, + &Process->VadRoot, + &StartAddress, + &Parent); + } + else + { + /* No, find an address bottom-up */ + Result = MiFindEmptyAddressRangeInTree(*ViewSize, + _64K, + &Process->VadRoot, + &Parent, + &StartAddress); + } + + /* Check if we found a suitable location */ + if (Result == TableFoundNode) + { + DPRINT1("Not enough free space to insert this section!\n"); + MmUnlockAddressSpace(AddressSpace); + MiDereferenceControlArea(ControlArea); + ExFreePoolWithTag(Vad, 'ldaV'); + return STATUS_CONFLICTING_ADDRESSES; + } + + /* Get the ending address, which is the last piece we need for the VAD */ + EndingAddress = StartAddress + (ViewSizeInPages * PAGE_SIZE) - 1; + } + else + { + /* Get the ending address, which is the last piece we need for the VAD */ + EndingAddress = StartAddress + (ViewSizeInPages * PAGE_SIZE) - 1; + + /* Make sure it doesn't conflict with an existing allocation */ + Result = MiCheckForConflictingNode(StartAddress >> PAGE_SHIFT, + EndingAddress >> PAGE_SHIFT, + &Process->VadRoot, + &Parent); + if (Result == TableFoundNode) + { + DPRINT1("Conflict with SEC_BASED or manually based section!\n"); + MmUnlockAddressSpace(AddressSpace); + MiDereferenceControlArea(ControlArea); + ExFreePoolWithTag(Vad, 'ldaV'); + return STATUS_CONFLICTING_ADDRESSES; + } + } + + /* Now set the VAD address */ + Vad->StartingVpn = StartAddress >> PAGE_SHIFT; + Vad->EndingVpn = EndingAddress >> PAGE_SHIFT; + + /* Pretend as if we own the working set */ + MiLockProcessWorkingSetUnsafe(Process, Thread); + + /* Insert the VAD */ + Process->VadRoot.NodeHint = Vad; + MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result); + + /* Release the working set */ + MiUnlockProcessWorkingSetUnsafe(Process, Thread); + + /* Unlock the address space */ + MmUnlockAddressSpace(AddressSpace); + + /* Windows stores this for accounting purposes, do so as well */ + if (!Segment->u2.FirstMappedVa) Segment->u2.FirstMappedVa = (PVOID)StartAddress;
/* Finally, let the caller know where, and for what size, the view was mapped */ *ViewSize = (ULONG_PTR)EndingAddress - (ULONG_PTR)StartAddress + 1; @@ -2786,33 +2816,20 @@ Attached = TRUE; }
- /* Lock the address space and make sure the process is alive */ - MmLockAddressSpace(&Process->Vm); - if (!Process->VmDeleted) - { - /* Do the actual mapping */ - DPRINT("Mapping ARM3 data section\n"); - Status = MiMapViewOfDataSection(ControlArea, - Process, - BaseAddress, - SectionOffset, - ViewSize, - Section, - InheritDisposition, - ProtectionMask, - CommitSize, - ZeroBits, - AllocationType); - } - else - { - /* The process is being terminated, fail */ - DPRINT1("The process is dying\n"); - Status = STATUS_PROCESS_IS_TERMINATING; - } - - /* Unlock the address space and detatch if needed, then return status */ - MmUnlockAddressSpace(&Process->Vm); + /* Do the actual mapping */ + Status = MiMapViewOfDataSection(ControlArea, + Process, + BaseAddress, + SectionOffset, + ViewSize, + Section, + InheritDisposition, + ProtectionMask, + CommitSize, + ZeroBits, + AllocationType); + + /* Detatch if needed, then return status */ if (Attached) KeUnstackDetachProcess(&ApcState); return Status; }
Modified: trunk/reactos/ntoskrnl/mm/ARM3/virtual.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/virtual.c?... ============================================================================== --- trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/ARM3/virtual.c [iso-8859-1] Wed Oct 8 00:31:09 2014 @@ -4599,6 +4599,7 @@ Vad->u.VadFlags.Protection = ProtectionMask; Vad->u.VadFlags.PrivateMemory = 1; Vad->u.VadFlags.CommitCharge = AllocationType & MEM_COMMIT ? PageCount : 0; + Vad->ControlArea = NULL; // For Memory-Area hack
// // Lock the address space and make sure the process isn't already dead @@ -4692,7 +4693,6 @@ // Lock the working set and insert the VAD into the process VAD tree // MiLockProcessWorkingSetUnsafe(Process, CurrentThread); - Vad->ControlArea = NULL; // For Memory-Area hack Process->VadRoot.NodeHint = Vad; MiInsertNode(&Process->VadRoot, (PVOID)Vad, Parent, Result); MiUnlockProcessWorkingSetUnsafe(Process, CurrentThread);