NULL,
&SectionSize,
PAGE_READWRITE,
- SEC_COMMIT,
+ SEC_COMMIT,// | 0x1,
NULL);
if (!NT_SUCCESS(Status))
{
//
// New ARM3<->RosMM PAGE Architecture
//
+BOOLEAN
+FORCEINLINE
+MiIsRosSectionObject(IN PVOID Section)
+{
+ PROS_SECTION_OBJECT RosSection = Section;
+ if ((RosSection->Type == 'SC') && (RosSection->Size == 'TN')) return TRUE;
+ return FALSE;
+}
+
#ifdef _WIN64
// HACK ON TOP OF HACK ALERT!!!
#define MI_GET_ROS_DATA(x) \
NTSTATUS
NTAPI
MiResolveDemandZeroFault(IN PVOID Address,
- IN ULONG Protection,
+ IN PMMPTE PointerPte,
IN PEPROCESS Process,
IN KIRQL OldIrql)
{
PFN_NUMBER PageFrameNumber = 0;
- PMMPTE PointerPte = MiAddressToPte(Address);
MMPTE TempPte;
BOOLEAN NeedZero = FALSE, HaveLock = FALSE;
ULONG Color;
/* Zero the page if need be */
if (NeedZero) MiZeroPfn(PageFrameNumber);
- /* Build the PTE */
- MI_MAKE_HARDWARE_PTE(&TempPte,
- PointerPte,
- Protection,
- PageFrameNumber);
+ /* Fault on user PDE, or fault on user PTE? */
+ if (PointerPte <= MiHighestUserPte)
+ {
+ /* User fault, build a user PTE */
+ MI_MAKE_HARDWARE_PTE_USER(&TempPte,
+ PointerPte,
+ PointerPte->u.Soft.Protection,
+ PageFrameNumber);
+ }
+ else
+ {
+ /* This is a user-mode PDE, create a kernel PTE for it */
+ MI_MAKE_HARDWARE_PTE(&TempPte,
+ PointerPte,
+ PointerPte->u.Soft.Protection,
+ PageFrameNumber);
+ }
/* Set it dirty if it's a writable page */
if (MI_IS_PAGE_WRITEABLE(&TempPte)) MI_MAKE_DIRTY_PAGE(&TempPte);
/* Resolve the demand zero fault */
Status = MiResolveDemandZeroFault(Address,
- (ULONG)PointerProtoPte->u.Soft.Protection,
+ PointerProtoPte,
Process,
OldIrql);
ASSERT(NT_SUCCESS(Status));
// we want. Go handle it!
//
Status = MiResolveDemandZeroFault(Address,
- (ULONG)PointerPte->u.Soft.Protection,
+ PointerPte,
Process,
MM_NOIRQL);
ASSERT(KeAreAllApcsDisabled() == TRUE);
#endif
#if (_MI_PAGING_LEVELS == 4)
+// Note to Timo: You should call MiCheckVirtualAddress and also check if it's zero pte
+// also this is missing the page count increment
/* Check if the PXE is valid */
if (PointerPxe->u.Hard.Valid == 0)
{
/* Right now, we only handle scenarios where the PXE is totally empty */
ASSERT(PointerPxe->u.Long == 0);
-
+#if 0
/* Resolve a demand zero fault */
Status = MiResolveDemandZeroFault(PointerPpe,
MM_READWRITE,
CurrentProcess,
MM_NOIRQL);
-
+#endif
/* We should come back with a valid PXE */
ASSERT(PointerPxe->u.Hard.Valid == 1);
}
#endif
#if (_MI_PAGING_LEVELS >= 3)
+// Note to Timo: You should call MiCheckVirtualAddress and also check if it's zero pte
+// also this is missing the page count increment
/* Check if the PPE is valid */
if (PointerPpe->u.Hard.Valid == 0)
{
/* Right now, we only handle scenarios where the PPE is totally empty */
ASSERT(PointerPpe->u.Long == 0);
-
+#if 0
/* Resolve a demand zero fault */
Status = MiResolveDemandZeroFault(PointerPde,
MM_READWRITE,
CurrentProcess,
MM_NOIRQL);
-
+#endif
/* We should come back with a valid PPE */
ASSERT(PointerPpe->u.Hard.Valid == 1);
}
#if MI_TRACE_PFNS
UserPdeFault = TRUE;
#endif
- /* Resolve a demand zero fault */
- Status = MiResolveDemandZeroFault(PointerPte,
- MM_READWRITE,
- CurrentProcess,
- MM_NOIRQL);
+ MiCheckVirtualAddress(Address, &ProtectionCode, &Vad);
+ if (ProtectionCode == MM_NOACCESS)
+ {
+#if (_MI_PAGING_LEVELS == 2)
+ /* Could be a page table for paged pool */
+ MiCheckPdeForPagedPool(Address);
+#endif
+ /* Has the code above changed anything -- is this now a valid PTE? */
+ Status = (PointerPte->u.Hard.Valid == 1) ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION;
+
+ /* Either this was a bogus VA or we've fixed up a paged pool PDE */
+ MiUnlockProcessWorkingSet(CurrentProcess, CurrentThread);
+ return Status;
+ }
+
+ /* Write a demand-zero PDE */
+ MI_WRITE_INVALID_PTE(PointerPde, DemandZeroPde);
+
+ /* Dispatch the fault */
+ Status = MiDispatchFault(TRUE,
+ PointerPte,
+ PointerPde,
+ NULL,
+ FALSE,
+ PsGetCurrentProcess(),
+ TrapInformation,
+ NULL);
#if MI_TRACE_PFNS
UserPdeFault = FALSE;
#endif
{
/* Resolve the fault */
MiResolveDemandZeroFault(Address,
- (ULONG)PointerPte->u.Soft.Protection,
+ PointerPte,
CurrentProcess,
MM_NOIRQL);
IN ULONG_PTR ZeroBits,
IN ULONG AllocationType)
{
- PMMVAD Vad;
+ PMMVAD_LONG Vad;
PETHREAD Thread = PsGetCurrentThread();
ULONG_PTR StartAddress, EndingAddress;
PSUBSECTION Subsection;
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');
+ /* FIXME: we are allocating a LONG VAD for ReactOS compatibility only */
+ Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
ASSERT(Vad);
- RtlZeroMemory(Vad, sizeof(MMVAD));
+ 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;
MiLockProcessWorkingSet(Process, Thread);
/* Insert the VAD */
- MiInsertVad(Vad, Process);
+ MiInsertVad((PMMVAD)Vad, Process);
/* Release the working set */
MiUnlockProcessWorkingSet(Process, Thread);
/* 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;
+ DPRINT1("Start and region: 0x%p, 0x%p\n", *BaseAddress, *ViewSize);
return STATUS_SUCCESS;
}
ASSERT(SectionObject != NULL);
/* Check if it's an ARM3, or ReactOS section */
- if ((ULONG_PTR)SectionObject & 1)
+ if (MiIsRosSectionObject(SectionObject) == FALSE)
{
/* Return the file pointer stored in the control area */
- Section = (PVOID)((ULONG_PTR)SectionObject & ~1);
+ Section = SectionObject;
return Section->Segment->ControlArea->FilePointer;
}
PFILE_OBJECT FileObject;
/* Make sure it's an image section */
- if ((ULONG_PTR)Section & 1)
+ if (MiIsRosSectionObject(Section) == FALSE)
{
/* Check ARM3 Section flag */
- if (((PSECTION)((ULONG_PTR)Section & ~1))->u.Flags.Image == 0)
+ if (((PSECTION)Section)->u.Flags.Image == 0)
{
/* It's not, fail */
DPRINT1("Not an image section\n");
NTSTATUS Status;
PAGED_CODE();
+ /* Force PAGE_READWRITE for everything, for now */
+ Protect = PAGE_READWRITE;
+
/* Get the segment and control area */
Section = (PSECTION)SectionObject;
ControlArea = Section->Segment->ControlArea;
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))
if (!Process->VmDeleted)
{
/* Do the actual mapping */
+ DPRINT1("Mapping ARM3 data section\n");
Status = MiMapViewOfDataSection(ControlArea,
Process,
BaseAddress,
PVOID AddressSpace;
PMEMORY_AREA MemoryArea1, MemoryArea2;
PROS_SECTION_OBJECT Section1, Section2;
-
+
/* Lock address space */
AddressSpace = MmGetCurrentAddressSpace();
MmLockAddressSpace(AddressSpace);
-
+
/* Locate the memory area for the process by address */
MemoryArea1 = MmLocateMemoryAreaByAddress(AddressSpace, File1MappedAsAnImage);
if (!MemoryArea1)
MmUnlockAddressSpace(AddressSpace);
return STATUS_INVALID_ADDRESS;
}
-
+
/* Check if it's a section view (RosMm section) or ARM3 section */
if (MemoryArea1->Type != MEMORY_AREA_SECTION_VIEW)
{
MmUnlockAddressSpace(AddressSpace);
return STATUS_CONFLICTING_ADDRESSES;
}
-
+
/* Get the section pointer to the SECTION_OBJECT */
Section1 = MemoryArea1->Data.SectionData.Section;
if (Section1->FileObject == NULL)
{
MmUnlockAddressSpace(AddressSpace);
- return STATUS_CONFLICTING_ADDRESSES;
+ return STATUS_CONFLICTING_ADDRESSES;
}
-
+
/* Locate the memory area for the process by address */
MemoryArea2 = MmLocateMemoryAreaByAddress(AddressSpace, File2MappedAsFile);
if (!MemoryArea2)
MmUnlockAddressSpace(AddressSpace);
return STATUS_INVALID_ADDRESS;
}
-
+
/* Check if it's a section view (RosMm section) or ARM3 section */
if (MemoryArea2->Type != MEMORY_AREA_SECTION_VIEW)
{
MmUnlockAddressSpace(AddressSpace);
return STATUS_CONFLICTING_ADDRESSES;
}
-
+
/* Get the section pointer to the SECTION_OBJECT */
Section2 = MemoryArea2->Data.SectionData.Section;
if (Section2->FileObject == NULL)
{
MmUnlockAddressSpace(AddressSpace);
- return STATUS_CONFLICTING_ADDRESSES;
+ return STATUS_CONFLICTING_ADDRESSES;
}
-
+
/* The shared cache map seems to be the same if both of these are equal */
if (Section1->FileObject->SectionObjectPointer->SharedCacheMap ==
Section2->FileObject->SectionObjectPointer->SharedCacheMap)
{
MmUnlockAddressSpace(AddressSpace);
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-
+
/* Unlock address space */
MmUnlockAddressSpace(AddressSpace);
return STATUS_NOT_SAME_DEVICE;
IN PMMADDRESS_NODE Parent,
IN TABLE_SEARCH_RESULT Result)
{
- PMMVAD Vad;
+ PMMVAD_LONG Vad;
/* 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 */
- Vad = (PMMVAD)NewNode;
+ Vad = (PMMVAD_LONG)NewNode;
if (Vad->u.VadFlags.Spare == 0)
{
NTSTATUS Status;
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. Store the MAREA here for now */
- DPRINT("Storing %p in %p\n", MemoryArea, Vad);
- Vad->ControlArea->WaitingForDeletion = (PVOID)MemoryArea;
+ ASSERT(Vad->u4.Banked = (PVOID)0xDEADBABE);
+ Vad->u4.Banked = (PVOID)MemoryArea;
}
}
}
MiRemoveNode(IN PMMADDRESS_NODE Node,
IN PMM_AVL_TABLE Table)
{
- PMMVAD Vad;
+ PMMVAD_LONG Vad;
/* Call the AVL code */
RtlpDeleteAvlTreeNode(Table, Node);
}
/* Free the node from ReactOS view as well */
- Vad = (PMMVAD)Node;
+ Vad = (PMMVAD_LONG)Node;
if (Vad->u.VadFlags.Spare == 0)
{
PMEMORY_AREA MemoryArea;
else
{
/* This is a section VAD. We store the ReactOS MEMORY_AREA here */
- MemoryArea = (PMEMORY_AREA)Vad->ControlArea->WaitingForDeletion;
+ MemoryArea = (PMEMORY_AREA)Vad->u4.Banked;
}
/* Make sure one actually still exists */
if (MemoryArea)
{
+ /* Make sure we have not already freed it */
+ ASSERT(MemoryArea != (PVOID)0xDEADBAB1);
+
/* Get the process */
Process = CONTAINING_RECORD(Table, EPROCESS, VadRoot);
/* Free it */
MmFreeMemoryArea(&Process->Vm, MemoryArea, NULL, NULL);
+
+ /* Check if this is VM VAD */
+ if (Vad->ControlArea == NULL)
+ {
+ /* Delete the pointer to it */
+ Vad->FirstPrototypePte = (PVOID)0xDEADBAB1;
+ }
+ else
+ {
+ /* Delete the pointer to it */
+ Vad->u4.Banked = (PVOID)0xDEADBAB1;
+ }
}
}
}
MiDecrementShareCount(Pfn1, PageFrameIndex);
/* Either a fork, or this is the shared user data page */
- if (PointerPte <= MiHighestUserPte)
+ if ((PointerPte <= MiHighestUserPte) && (PrototypePte != Pfn1->PteAddress))
{
/* If it's not the shared user page, then crash, since there's no fork() yet */
if ((PAGE_ALIGN(VirtualAddress) != (PVOID)USER_SHARED_DATA) ||
NTSTATUS
NTAPI
-MiResolveDemandZeroFault(IN PVOID Address,
- IN ULONG Protection,
- IN PEPROCESS Process,
- IN KIRQL OldIrql);
-VOID
+MiDispatchFault(IN BOOLEAN StoreInstruction,
+ IN PVOID Address,
+ IN PMMPTE PointerPte,
+ IN PMMPTE PointerProtoPte,
+ IN BOOLEAN Recursive,
+ IN PEPROCESS Process,
+ IN PVOID TrapInformation,
+ IN PVOID Vad);
+
+NTSTATUS
NTAPI
MiFillSystemPageDirectory(IN PVOID Base,
IN SIZE_T NumberOfBytes);
Pt = (PULONG)MiAddressToPte(Address);
if (PointerPde->u.Hard.Valid == 0)
{
+ NTSTATUS Status;
if (Create == FALSE)
{
return NULL;
}
- MiResolveDemandZeroFault(Pt,
- MM_READWRITE,
- Process,
- MM_NOIRQL);
+ ASSERT(PointerPde->u.Long == 0);
+
+ MI_WRITE_INVALID_PTE(PointerPde, DemandZeroPde);
+ Status = MiDispatchFault(TRUE,
+ Pt,
+ PointerPde,
+ NULL,
+ FALSE,
+ PsGetCurrentProcess(),
+ NULL,
+ NULL);
+ ASSERT(KeAreAllApcsDisabled() == TRUE);
ASSERT(PointerPde->u.Hard.Valid == 1);
}
return (PULONG)MiAddressToPte(Address);
* Initialize it
*/
RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
+ Section->Type = 'SC';
+ Section->Size = 'TN';
Section->SectionPageProtection = SectionPageProtection;
Section->AllocationAttributes = AllocationAttributes;
Section->MaximumSize = MaximumSize;
* Initialize it
*/
RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
+ Section->Type = 'SC';
+ Section->Size = 'TN';
Section->SectionPageProtection = SectionPageProtection;
Section->AllocationAttributes = AllocationAttributes;
* Initialize it
*/
RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT));
+ Section->Type = 'SC';
+ Section->Size = 'TN';
Section->SectionPageProtection = SectionPageProtection;
Section->AllocationAttributes = AllocationAttributes;
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN NotAtBase = FALSE;
- if ((ULONG_PTR)SectionObject & 1)
+ if (MiIsRosSectionObject(SectionObject) == FALSE)
{
- return MmMapViewOfArm3Section((PVOID)((ULONG_PTR)SectionObject & ~1),
+ DPRINT1("Mapping ARM3 section into %s\n", Process->ImageFileName);
+ return MmMapViewOfArm3Section(SectionObject,
Process,
BaseAddress,
ZeroBits,
NTSTATUS Status;
PAGED_CODE();
- if ((ULONG_PTR)SectionObject & 1)
+ if (MiIsRosSectionObject(SectionObject) == FALSE)
{
- return MiMapViewInSystemSpace((PVOID)((ULONG_PTR)SectionObject & ~1),
+ DPRINT1("ARM3 System Mapping\n");
+ return MiMapViewInSystemSpace(SectionObject,
&MmSession,
MappedBase,
ViewSize);
/* Check if an ARM3 section is being created instead */
if (AllocationAttributes & 1)
{
- DPRINT1("arm 3 path\n");
+ DPRINT1("Creating ARM3 section\n");
return MmCreateArm3Section(Section,
DesiredAccess,
ObjectAttributes,