diff --git a/reactos/ntoskrnl/ex/init.c b/reactos/ntoskrnl/ex/init.c index b268e5cadcf..18aee2ae8ac 100644 --- a/reactos/ntoskrnl/ex/init.c +++ b/reactos/ntoskrnl/ex/init.c @@ -298,7 +298,7 @@ ExpInitNls(IN PLOADER_PARAMETER_BLOCK LoaderBlock) NULL, &SectionSize, PAGE_READWRITE, - SEC_COMMIT, + SEC_COMMIT,// | 0x1, NULL); if (!NT_SUCCESS(Status)) { diff --git a/reactos/ntoskrnl/mm/ARM3/miarm.h b/reactos/ntoskrnl/mm/ARM3/miarm.h index 3ba8377d669..06c8fc14a85 100644 --- a/reactos/ntoskrnl/mm/ARM3/miarm.h +++ b/reactos/ntoskrnl/mm/ARM3/miarm.h @@ -1544,6 +1544,15 @@ MiRemoveZeroPageSafe(IN ULONG Color) // // 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) \ diff --git a/reactos/ntoskrnl/mm/ARM3/pagfault.c b/reactos/ntoskrnl/mm/ARM3/pagfault.c index 169a6481f50..4fb5eead326 100644 --- a/reactos/ntoskrnl/mm/ARM3/pagfault.c +++ b/reactos/ntoskrnl/mm/ARM3/pagfault.c @@ -247,12 +247,11 @@ MiZeroPfn(IN PFN_NUMBER PageFrameNumber) 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; @@ -342,11 +341,23 @@ MiResolveDemandZeroFault(IN PVOID Address, /* 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); @@ -494,7 +505,7 @@ MiResolveProtoPteFault(IN BOOLEAN StoreInstruction, /* Resolve the demand zero fault */ Status = MiResolveDemandZeroFault(Address, - (ULONG)PointerProtoPte->u.Soft.Protection, + PointerProtoPte, Process, OldIrql); ASSERT(NT_SUCCESS(Status)); @@ -639,7 +650,7 @@ MiDispatchFault(IN BOOLEAN StoreInstruction, // we want. Go handle it! // Status = MiResolveDemandZeroFault(Address, - (ULONG)PointerPte->u.Soft.Protection, + PointerPte, Process, MM_NOIRQL); ASSERT(KeAreAllApcsDisabled() == TRUE); @@ -884,36 +895,40 @@ UserFault: #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); } @@ -929,11 +944,33 @@ UserFault: #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 @@ -951,7 +988,7 @@ UserFault: { /* Resolve the fault */ MiResolveDemandZeroFault(Address, - (ULONG)PointerPte->u.Soft.Protection, + PointerPte, CurrentProcess, MM_NOIRQL); diff --git a/reactos/ntoskrnl/mm/ARM3/section.c b/reactos/ntoskrnl/mm/ARM3/section.c index 1ff87b78888..9c2f458287a 100644 --- a/reactos/ntoskrnl/mm/ARM3/section.c +++ b/reactos/ntoskrnl/mm/ARM3/section.c @@ -694,7 +694,7 @@ MiMapViewOfDataSection(IN PCONTROL_AREA ControlArea, IN ULONG_PTR ZeroBits, IN ULONG AllocationType) { - PMMVAD Vad; + PMMVAD_LONG Vad; PETHREAD Thread = PsGetCurrentThread(); ULONG_PTR StartAddress, EndingAddress; PSUBSECTION Subsection; @@ -799,9 +799,11 @@ MiMapViewOfDataSection(IN PCONTROL_AREA ControlArea, 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; @@ -833,7 +835,7 @@ MiMapViewOfDataSection(IN PCONTROL_AREA ControlArea, MiLockProcessWorkingSet(Process, Thread); /* Insert the VAD */ - MiInsertVad(Vad, Process); + MiInsertVad((PMMVAD)Vad, Process); /* Release the working set */ MiUnlockProcessWorkingSet(Process, Thread); @@ -844,6 +846,7 @@ MiMapViewOfDataSection(IN PCONTROL_AREA ControlArea, /* 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; } @@ -961,10 +964,10 @@ MmGetFileObjectForSection(IN PVOID SectionObject) 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; } @@ -1012,10 +1015,10 @@ MmGetFileNameForSection(IN PVOID Section, 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"); @@ -1323,6 +1326,9 @@ MmMapViewOfArm3Section(IN PVOID SectionObject, 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; @@ -1334,7 +1340,6 @@ MmMapViewOfArm3Section(IN PVOID SectionObject, 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)) @@ -1416,6 +1421,7 @@ MmMapViewOfArm3Section(IN PVOID SectionObject, if (!Process->VmDeleted) { /* Do the actual mapping */ + DPRINT1("Mapping ARM3 data section\n"); Status = MiMapViewOfDataSection(ControlArea, Process, BaseAddress, @@ -1498,11 +1504,11 @@ NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, 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) @@ -1511,7 +1517,7 @@ NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, 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) { @@ -1519,15 +1525,15 @@ NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, 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) @@ -1536,7 +1542,7 @@ NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, 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) { @@ -1544,23 +1550,23 @@ NtAreMappedFilesTheSame(IN PVOID File1MappedAsAnImage, 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; diff --git a/reactos/ntoskrnl/mm/ARM3/vadnode.c b/reactos/ntoskrnl/mm/ARM3/vadnode.c index 03b9c28bdc8..ff8c01974dd 100644 --- a/reactos/ntoskrnl/mm/ARM3/vadnode.c +++ b/reactos/ntoskrnl/mm/ARM3/vadnode.c @@ -97,13 +97,13 @@ MiInsertNode(IN PMM_AVL_TABLE Table, 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; @@ -129,14 +129,13 @@ MiInsertNode(IN PMM_AVL_TABLE Table, 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; } } } @@ -167,7 +166,7 @@ NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table) { - PMMVAD Vad; + PMMVAD_LONG Vad; /* Call the AVL code */ RtlpDeleteAvlTreeNode(Table, Node); @@ -184,7 +183,7 @@ MiRemoveNode(IN PMMADDRESS_NODE 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; @@ -199,12 +198,15 @@ MiRemoveNode(IN PMMADDRESS_NODE Node, 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); @@ -214,6 +216,18 @@ MiRemoveNode(IN PMMADDRESS_NODE Node, /* 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; + } } } } diff --git a/reactos/ntoskrnl/mm/ARM3/virtual.c b/reactos/ntoskrnl/mm/ARM3/virtual.c index a3fb5101764..7e11bc89d7d 100644 --- a/reactos/ntoskrnl/mm/ARM3/virtual.c +++ b/reactos/ntoskrnl/mm/ARM3/virtual.c @@ -258,7 +258,7 @@ MiDeletePte(IN PMMPTE PointerPte, 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) || diff --git a/reactos/ntoskrnl/mm/i386/page.c b/reactos/ntoskrnl/mm/i386/page.c index b0961f1307b..2a533796c48 100644 --- a/reactos/ntoskrnl/mm/i386/page.c +++ b/reactos/ntoskrnl/mm/i386/page.c @@ -222,11 +222,16 @@ MiSynchronizeSystemPde(PMMPDE PointerPde) 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); @@ -280,14 +285,23 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create) 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); diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 930dbd0d738..b7d56a9bbc7 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -2917,6 +2917,8 @@ MmCreatePageFileSection(PROS_SECTION_OBJECT *SectionObject, * Initialize it */ RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT)); + Section->Type = 'SC'; + Section->Size = 'TN'; Section->SectionPageProtection = SectionPageProtection; Section->AllocationAttributes = AllocationAttributes; Section->MaximumSize = MaximumSize; @@ -2989,6 +2991,8 @@ MmCreateDataFileSection(PROS_SECTION_OBJECT *SectionObject, * Initialize it */ RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT)); + Section->Type = 'SC'; + Section->Size = 'TN'; Section->SectionPageProtection = SectionPageProtection; Section->AllocationAttributes = AllocationAttributes; @@ -3845,6 +3849,8 @@ MmCreateImageSection(PROS_SECTION_OBJECT *SectionObject, * Initialize it */ RtlZeroMemory(Section, sizeof(ROS_SECTION_OBJECT)); + Section->Type = 'SC'; + Section->Size = 'TN'; Section->SectionPageProtection = SectionPageProtection; Section->AllocationAttributes = AllocationAttributes; @@ -4530,9 +4536,10 @@ MmMapViewOfSection(IN PVOID SectionObject, 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, @@ -4866,9 +4873,10 @@ MmMapViewInSystemSpace (IN PVOID SectionObject, 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); @@ -5004,7 +5012,7 @@ MmCreateSection (OUT PVOID * Section, /* 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,