Author: sir_richard
Date: Tue Oct 5 14:36:09 2010
New Revision: 48997
URL: http://svn.reactos.org/svn/reactos?rev=48997&view=rev
Log:
[NTOS]: Implement ARM3 version of MmMapViewOfSection, only for ARM3 pagefile-backed sections, and without any special flag support. Tested and works great, with the new pagefault code correctly finding the Prototype PTE for the VAD.
[NTOS]: Make every VAD insert also create a MEMORY_AREA. Now the two address space views should be completely synchronized and we can try removing the hack that was done for PEB/TEB support (which will remove the 200 thread regression).
[NTOS]: Implement MiGetNextNode and MiFindEmptyAddressRangeInTree.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/section.c
trunk/reactos/ntoskrnl/mm/ARM3/vadnode.c
trunk/reactos/ntoskrnl/mm/section.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] Tue Oct 5 14:36:09 2010
@@ -460,6 +460,159 @@
/* Return the base adress of the mapping and success */
*MappedBase = Base;
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+MiMapViewOfDataSection(IN PCONTROL_AREA ControlArea,
+ IN PEPROCESS Process,
+ IN PVOID *BaseAddress,
+ IN PLARGE_INTEGER SectionOffset,
+ IN PSIZE_T ViewSize,
+ IN PSECTION Section,
+ IN SECTION_INHERIT InheritDisposition,
+ IN ULONG ProtectionMask,
+ IN ULONG CommitSize,
+ IN ULONG_PTR ZeroBits,
+ IN ULONG AllocationType)
+{
+ PMMVAD Vad;
+ PETHREAD Thread = PsGetCurrentThread();
+ ULONG_PTR StartAddress, EndingAddress;
+ PSUBSECTION Subsection;
+ PSEGMENT Segment;
+ PFN_NUMBER PteOffset;
+ NTSTATUS Status;
+
+ /* Get the segment and subection for this section */
+ Segment = ControlArea->Segment;
+ Subsection = (PSUBSECTION)(ControlArea + 1);
+
+ /* Non-pagefile-backed sections not supported */
+ ASSERT(ControlArea->u.Flags.GlobalOnlyPerSession == 0);
+ ASSERT(ControlArea->u.Flags.Rom == 0);
+ ASSERT(ControlArea->FilePointer == NULL);
+ ASSERT(Segment->SegmentFlags.TotalNumberOfPtes4132 == 0);
+
+ /* Based sections not supported */
+ ASSERT(Section->Address.StartingVpn == 0);
+
+ /* These flags/parameters are not supported */
+ ASSERT((AllocationType & MEM_DOS_LIM) == 0);
+ ASSERT((AllocationType & MEM_RESERVE) == 0);
+ ASSERT((AllocationType & MEM_TOP_DOWN) == 0);
+ ASSERT(Process->VmTopDown == 0);
+ ASSERT(Section->u.Flags.CopyOnWrite == FALSE);
+ ASSERT(ZeroBits == 0);
+
+ /* First, increase the map count. No purging is supported yet */
+ Status = MiCheckPurgeAndUpMapCount(ControlArea, FALSE);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Check if the caller specified the view size */
+ if (!(*ViewSize))
+ {
+ /* The caller did not, so pick a 64K aligned view size based on the offset */
+ SectionOffset->LowPart &= ~(_64K - 1);
+ *ViewSize = Section->SizeOfSection.QuadPart - SectionOffset->QuadPart;
+ }
+ else
+ {
+ /* A size was specified, align it to a 64K boundary */
+ *ViewSize += SectionOffset->LowPart & (_64K - 1);
+
+ /* Align the offset as well to make this an aligned map */
+ SectionOffset->LowPart &= ~((ULONG)_64K - 1);
+ }
+
+ /* We must be dealing with a 64KB aligned offset */
+ ASSERT((SectionOffset->LowPart & ((ULONG)_64K - 1)) == 0);
+
+ /* It's illegal to try to map more than 2GB */
+ if (*ViewSize >= 0x80000000) return STATUS_INVALID_VIEW_SIZE;
+
+ /* Within this section, figure out which PTEs will describe the view */
+ PteOffset = SectionOffset->QuadPart >> PAGE_SHIFT;
+
+ /* The offset must be in this segment's PTE chunk and it must be valid */
+ ASSERT(PteOffset < Segment->TotalNumberOfPtes);
+ ASSERT(((SectionOffset->QuadPart + *ViewSize + PAGE_SIZE - 1) >> PAGE_SHIFT) >= PteOffset);
+
+ /* In ARM3, only one subsection is used for now. It must contain these PTEs */
+ ASSERT(PteOffset < Subsection->PtesInSubsection);
+ ASSERT(Subsection->SubsectionBase != NULL);
+
+ /* In ARM3, only MEM_COMMIT is supported for now. The PTEs must've been committed */
+ ASSERT(Segment->NumberOfCommittedPages >= Segment->TotalNumberOfPtes);
+
+ /* Did the caller specify an address? */
+ if (!(*BaseAddress))
+ {
+ /* No, find an address bottom-up */
+ Status = MiFindEmptyAddressRangeInTree(*ViewSize,
+ _64K,
+ &Process->VadRoot,
+ (PMMADDRESS_NODE*)&Process->VadFreeHint,
+ &StartAddress);
+ ASSERT(NT_SUCCESS(Status));
+ }
+ else
+ {
+ /* This (rather easy) code path is not yet implemented */
+ UNIMPLEMENTED;
+ while (TRUE);
+ }
+
+ /* Get the ending address, which is the last piece we need for the VAD */
+ EndingAddress = (StartAddress + *ViewSize - 1) | (PAGE_SIZE - 1);
+
+ /* A VAD can now be allocated. Do so and zero it out */
+ Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD), 'ldaV');
+ ASSERT(Vad);
+ RtlZeroMemory(Vad, sizeof(MMVAD));
+
+ /* 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 = SectionOffset->QuadPart >> 16;
+ Vad->u2.VadFlags2.Inherit = (InheritDisposition == ViewShare);
+ if ((AllocationType & SEC_NO_CHANGE) || (Section->u.Flags.NoChange))
+ {
+ /* This isn't really implemented yet, but handle setting the flag */
+ Vad->u.VadFlags.NoChange = 1;
+ Vad->u2.VadFlags2.SecNoChange = 1;
+ }
+
+ /* Finally, write down the first and last prototype PTE */
+ Vad->FirstPrototypePte = &Subsection->SubsectionBase[PteOffset];
+ PteOffset += (Vad->EndingVpn - Vad->StartingVpn);
+ Vad->LastContiguousPte = &Subsection->SubsectionBase[PteOffset];
+
+ /* Make sure the last PTE is valid and still within the subsection */
+ ASSERT(PteOffset < Subsection->PtesInSubsection);
+ ASSERT(Vad->FirstPrototypePte <= Vad->LastContiguousPte);
+
+ /* FIXME: Should setup VAD bitmap */
+ Status = STATUS_SUCCESS;
+
+ /* Pretend as if we own the working set */
+ MiLockProcessWorkingSet(Process, Thread);
+
+ /* Insert the VAD */
+ MiInsertVad(Vad, Process);
+
+ /* Release the working set */
+ MiUnlockProcessWorkingSet(Process, Thread);
+
+ /* 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;
+ *BaseAddress = (PVOID)StartAddress;
return STATUS_SUCCESS;
}
@@ -668,6 +821,146 @@
return Status;
}
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+MmMapViewOfArm3Section(IN PVOID SectionObject,
+ IN PEPROCESS Process,
+ IN OUT PVOID *BaseAddress,
+ IN ULONG_PTR ZeroBits,
+ IN SIZE_T CommitSize,
+ IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
+ IN OUT PSIZE_T ViewSize,
+ IN SECTION_INHERIT InheritDisposition,
+ IN ULONG AllocationType,
+ IN ULONG Protect)
+{
+ KAPC_STATE ApcState;
+ BOOLEAN Attached = FALSE;
+ PSECTION Section;
+ PCONTROL_AREA ControlArea;
+ ULONG ProtectionMask;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ /* Get the segment and control area */
+ Section = (PSECTION)SectionObject;
+ ControlArea = Section->Segment->ControlArea;
+
+ /* These flags/states are not yet supported by ARM3 */
+ ASSERT(Section->u.Flags.Image == 0);
+ ASSERT(Section->u.Flags.NoCache == 0);
+ ASSERT(Section->u.Flags.WriteCombined == 0);
+ ASSERT((AllocationType & MEM_RESERVE) == 0);
+ ASSERT(ControlArea->u.Flags.PhysicalMemory == 0);
+
+
+#if 0
+ /* FIXME: Check if the mapping protection is compatible with the create */
+ if (!MiIsProtectionCompatible(Section->InitialPageProtection, Protect))
+ {
+ DPRINT1("Mapping protection is incompatible\n");
+ return STATUS_SECTION_PROTECTION;
+ }
+#endif
+
+ /* Check if the offset and size would cause an overflow */
+ if ((SectionOffset->QuadPart + *ViewSize) < SectionOffset->QuadPart)
+ {
+ DPRINT1("Section offset overflows\n");
+ return STATUS_INVALID_VIEW_SIZE;
+ }
+
+ /* Check if the offset and size are bigger than the section itself */
+ if ((SectionOffset->QuadPart + *ViewSize) > Section->SizeOfSection.QuadPart)
+ {
+ DPRINT1("Section offset is larger than section\n");
+ return STATUS_INVALID_VIEW_SIZE;
+ }
+
+ /* Check if the caller did not specify a view size */
+ if (!(*ViewSize))
+ {
+ /* Compute it for the caller */
+ *ViewSize = Section->SizeOfSection.QuadPart - SectionOffset->QuadPart;
+
+ /* Check if it's larger than 4GB or overflows into kernel-mode */
+ if ((*ViewSize > 0xFFFFFFFF) ||
+ (((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS - (ULONG_PTR)*BaseAddress) < *ViewSize))
+ {
+ DPRINT1("Section view won't fit\n");
+ return STATUS_INVALID_VIEW_SIZE;
+ }
+ }
+
+ /* Check if the commit size is larger than the view size */
+ if (CommitSize > *ViewSize)
+ {
+ DPRINT1("Attempting to commit more than the view itself\n");
+ return STATUS_INVALID_PARAMETER_5;
+ }
+
+ /* Check if the view size is larger than the section */
+ if (*ViewSize > Section->SizeOfSection.QuadPart)
+ {
+ DPRINT1("The view is larger than the section\n");
+ return STATUS_INVALID_VIEW_SIZE;
+ }
+
+ /* Compute and validate the protection mask */
+ ProtectionMask = MiMakeProtectionMask(Protect);
+ if (ProtectionMask == MM_INVALID_PROTECTION)
+ {
+ DPRINT1("The protection is invalid\n");
+ return STATUS_INVALID_PAGE_PROTECTION;
+ }
+
+ /* We only handle pagefile-backed sections, which cannot be writecombined */
+ if (Protect & PAGE_WRITECOMBINE)
+ {
+ DPRINT1("Cannot write combine a pagefile-backed section\n");
+ return STATUS_INVALID_PARAMETER_10;
+ }
+
+ /* Start by attaching to the current process if needed */
+ if (PsGetCurrentProcess() != Process)
+ {
+ KeStackAttachProcess(&Process->Pcb, &ApcState);
+ Attached = TRUE;
+ }
+
+ /* Lock the address space and make sure the process is alive */
+ MmLockAddressSpace(&Process->Vm);
+ if (!Process->VmDeleted)
+ {
+ /* Do the actual mapping */
+ 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);
+ if (Attached) KeUnstackDetachProcess(&ApcState);
+ return Status;
+}
+
/* SYSTEM CALLS ***************************************************************/
NTSTATUS
Modified: trunk/reactos/ntoskrnl/mm/ARM3/vadnode.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/vadnode.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/vadnode.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/vadnode.c [iso-8859-1] Tue Oct 5 14:36:09 2010
@@ -121,6 +121,28 @@
/* 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
@@ -179,6 +201,112 @@
/* Nothing found */
return NULL;
+}
+
+PMMADDRESS_NODE
+NTAPI
+MiGetNextNode(IN PMMADDRESS_NODE Node)
+{
+ PMMADDRESS_NODE Parent;
+
+ /* Get the right child */
+ if (RtlRightChildAvl(Node))
+ {
+ /* Get left-most child */
+ Node = RtlRightChildAvl(Node);
+ while (RtlLeftChildAvl(Node)) Node = RtlLeftChildAvl(Node);
+ return Node;
+ }
+
+ Parent = RtlParentAvl(Node);
+ ASSERT(Parent != NULL);
+ while (Parent != Node)
+ {
+ /* The parent should be a left child, return the real predecessor */
+ if (RtlIsLeftChildAvl(Node))
+ {
+ /* Return it */
+ return Parent;
+ }
+
+ /* Keep lopping until we find our parent */
+ Node = Parent;
+ Parent = RtlParentAvl(Node);
+ }
+
+ /* Nothing found */
+ return NULL;
+}
+
+NTSTATUS
+NTAPI
+MiFindEmptyAddressRangeInTree(IN SIZE_T Length,
+ IN ULONG_PTR Alignment,
+ IN PMM_AVL_TABLE Table,
+ OUT PMMADDRESS_NODE *PreviousVad,
+ OUT PULONG_PTR Base)
+{
+ PMMADDRESS_NODE Node;
+ PMMADDRESS_NODE NextNode;
+ ULONG_PTR StartingVpn, HighestVpn, AlignmentVpn, LengthVpn, LowVpn;
+ ASSERT(Length != 0);
+
+ /* Precompute page numbers for the length, alignment, and starting address */
+ LengthVpn = (Length + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+ AlignmentVpn = Alignment >> PAGE_SHIFT;
+ StartingVpn = ROUND_DOWN((ULONG_PTR)MM_LOWEST_USER_ADDRESS >> PAGE_SHIFT,
+ AlignmentVpn);
+
+ /* Check if the table is free, so the lowest possible address is available */
+ if (!Table->NumberGenericTableElements) goto FoundAtBottom;
+
+ /* Otherwise, follow the leftmost child of the right root node's child */
+ Node = RtlRightChildAvl(&Table->BalancedRoot);
+ while (RtlLeftChildAvl(Node)) Node = RtlLeftChildAvl(Node);
+
+ /* This is the node for the remaining gap at the bottom, can it be used? */
+ if ((Node->StartingVpn > StartingVpn) &&
+ (LengthVpn < Node->StartingVpn - StartingVpn))
+ {
+FoundAtBottom:
+ /* Use this VAD to store the allocation */
+ *PreviousVad = NULL;
+ *Base = StartingVpn << PAGE_SHIFT;
+ return STATUS_SUCCESS;
+ }
+
+ /* Otherwise, we start a search to find a gap */
+ while (TRUE)
+ {
+ /* The last aligned page number in this entry */
+ LowVpn = ROUND_DOWN(Node->EndingVpn + 1, AlignmentVpn);
+
+ /* Keep going as long as there's still a next node */
+ NextNode = MiGetNextNode(Node);
+ if (!NextNode) break;
+
+ /* Can this allocation fit in this node? */
+ if ((LengthVpn <= (NextNode->StartingVpn - LowVpn)) &&
+ (NextNode->StartingVpn > LowVpn))
+ {
+Found:
+ /* Yes! Use this VAD to store the allocation */
+ *PreviousVad = Node;
+ *Base = ROUND_DOWN((Node->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
+ Alignment);
+ return STATUS_SUCCESS;
+ }
+
+ /* Try the next node */
+ Node = NextNode;
+ }
+
+ /* We're down to the last (top) VAD, will this allocation fit inside it? */
+ HighestVpn = ((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1) >> PAGE_SHIFT;
+ if ((HighestVpn > LowVpn) && (LengthVpn <= HighestVpn - LowVpn)) goto Found;
+
+ /* Nyet, there's no free address space for this allocation, so we'll fail */
+ return STATUS_NO_MEMORY;
}
TABLE_SEARCH_RESULT
Modified: trunk/reactos/ntoskrnl/mm/section.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/section.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/section.c [iso-8859-1] Tue Oct 5 14:36:09 2010
@@ -3956,7 +3956,19 @@
-
+NTSTATUS
+NTAPI
+MmMapViewOfArm3Section(IN PVOID SectionObject,
+ IN PEPROCESS Process,
+ IN OUT PVOID *BaseAddress,
+ IN ULONG_PTR ZeroBits,
+ IN SIZE_T CommitSize,
+ IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
+ IN OUT PSIZE_T ViewSize,
+ IN SECTION_INHERIT InheritDisposition,
+ IN ULONG AllocationType,
+ IN ULONG Protect);
+
/**********************************************************************
* NAME EXPORTED
* MmMapViewOfSection
@@ -4023,6 +4035,20 @@
ULONG ViewOffset;
NTSTATUS Status = STATUS_SUCCESS;
+ if ((ULONG_PTR)SectionObject & 1)
+ {
+ return MmMapViewOfArm3Section((PVOID)((ULONG_PTR)SectionObject & ~1),
+ Process,
+ BaseAddress,
+ ZeroBits,
+ CommitSize,
+ SectionOffset,
+ ViewSize,
+ InheritDisposition,
+ AllocationType,
+ Protect);
+ }
+
ASSERT(Process);
if (!Protect || Protect & ~PAGE_FLAGS_VALID_FOR_SECTION)
@@ -4280,10 +4306,10 @@
PROS_SECTION_OBJECT Section;
PMMSUPPORT AddressSpace;
NTSTATUS Status;
-
+ PAGED_CODE();
+
if ((ULONG_PTR)SectionObject & 1)
{
- PAGED_CODE();
extern PVOID MmSession;
return MiMapViewInSystemSpace((PVOID)((ULONG_PTR)SectionObject & ~1),
&MmSession,
Author: sir_richard
Date: Tue Oct 5 08:14:02 2010
New Revision: 48993
URL: http://svn.reactos.org/svn/reactos?rev=48993&view=rev
Log:
[NTOS]: Add the tiny little bit of code required to correctly handle user-mode faults on ARM3 mapped sections in certain limited scenarios.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Tue Oct 5 08:14:02 2010
@@ -27,6 +27,7 @@
OUT PMMVAD *ProtoVad)
{
PMMVAD Vad;
+ PMMPTE PointerPte;
/* No prototype/section support for now */
*ProtoVad = NULL;
@@ -50,15 +51,33 @@
*ProtectCode = MM_NOACCESS;
return NULL;
}
-
- /* This must be a TEB/PEB VAD */
- ASSERT(Vad->u.VadFlags.PrivateMemory == TRUE);
- ASSERT(Vad->u.VadFlags.MemCommit == TRUE);
+
+ /* This must be a VM VAD */
ASSERT(Vad->u.VadFlags.VadType == VadNone);
- /* Return the protection on it */
- *ProtectCode = Vad->u.VadFlags.Protection;
- return NULL;
+ /* Check if it's a section, or just an allocation */
+ if (Vad->u.VadFlags.PrivateMemory == TRUE)
+ {
+ /* This must be a TEB/PEB VAD */
+ ASSERT(Vad->u.VadFlags.MemCommit == TRUE);
+ *ProtectCode = Vad->u.VadFlags.Protection;
+ return NULL;
+ }
+ else
+ {
+ /* Return the proto VAD */
+ ASSERT(Vad->u2.VadFlags2.ExtendableFile == 0);
+ *ProtoVad = Vad;
+
+ /* Get the prototype PTE for this page */
+ PointerPte = (((ULONG_PTR)VirtualAddress >> PAGE_SHIFT) - Vad->StartingVpn) + Vad->FirstPrototypePte;
+ ASSERT(PointerPte <= Vad->LastContiguousPte);
+ ASSERT(PointerPte != NULL);
+
+ /* Return the Prototype PTE and the protection for the page mapping */
+ *ProtectCode = Vad->u.VadFlags.Protection;
+ return PointerPte;
+ }
}
NTSTATUS
@@ -482,8 +501,8 @@
}
else
{
+ /* Resolve the fault -- this will release the PFN lock */
ASSERT(PointerPte->u.Hard.Valid == 0);
- /* Resolve the fault -- this will release the PFN lock */
Status = MiResolveProtoPteFault(StoreInstruction,
Address,
PointerPte,
@@ -505,15 +524,14 @@
}
else
{
- /* We currently only handle the shared user data PTE path */
+ /* We currently only handle very limited paths */
ASSERT(PointerPte->u.Soft.Prototype == 1);
ASSERT(PointerPte->u.Soft.PageFileHigh == MI_PTE_LOOKUP_NEEDED);
- ASSERT(Vad == NULL);
/* Lock the PFN database */
LockIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
- /* For the shared data page, this should be true */
+ /* For our current usage, this should be true */
ASSERT(SuperProtoPte->u.Hard.Valid == 1);
ASSERT(TempPte.u.Hard.Valid == 0);
@@ -972,8 +990,9 @@
}
else
{
- /* The only "prototype PTE" we support is the shared user data path */
- ASSERT(ProtectionCode == MM_READONLY);
+ /* No guard page support yet */
+ ASSERT((ProtectionCode & MM_DECOMMIT) == 0);
+ ASSERT(ProtectionCode != 0x100);
/* Write the prototype PTE */
TempPte = PrototypePte;
@@ -991,7 +1010,7 @@
Vad);
ASSERT(Status == STATUS_PAGE_FAULT_TRANSITION);
ASSERT(PointerPte->u.Hard.Valid == 1);
- ASSERT(PointerPte->u.Hard.PageFrameNumber == MmSharedUserDataPte->u.Hard.PageFrameNumber);
+ ASSERT(PointerPte->u.Hard.PageFrameNumber != 0);
}
/* Release the working set */
Author: sir_richard
Date: Tue Oct 5 05:00:19 2010
New Revision: 48990
URL: http://svn.reactos.org/svn/reactos?rev=48990&view=rev
Log:
[NTOS]: Use the Spare flag in the VAD as a ReactOS/MemoryArea specific flag to signify that this VAD is associated with a MEMORY_AREA and should be unlinked at process exit, but not freed. This is because MemoryAreas themselves are cleaned up later, and in the future their associated VADs (not yet in Trunk) will also be parsed. In the process death scenario, those VADs will be freed, but not unlinked (since it would already have been unlinked).
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/procsup.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/procsup.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/procsup.c [iso-8859-1] Tue Oct 5 05:00:19 2010
@@ -125,7 +125,7 @@
/* Build the rest of the VAD now */
Vad->StartingVpn = (*Base) >> PAGE_SHIFT;
- Vad->EndingVpn = ((*Base) + Size - 1) >> PAGE_SHIFT;
+ Vad->EndingVpn = ((*Base) + Size - 1) >> PAGE_SHIFT;
Vad->u3.Secured.StartVpn = *Base;
Vad->u3.Secured.EndVpn = (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1);
Vad->u1.Parent = NULL;
@@ -1195,6 +1195,14 @@
/* Release the working set */
MiUnlockProcessWorkingSet(Process, Thread);
+ /* 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;
+ continue;
+ }
+
/* Free the VAD memory */
ExFreePool(Vad);
}