diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 31b0cac99dd..91fc8d9967a 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -628,6 +628,7 @@ PFN_TYPE MmGetLRUFirstUserPage(VOID); VOID MmSetLRULastPage(PFN_TYPE Page); VOID MmLockPage(PFN_TYPE Page); +VOID MmLockPageUnsafe(PFN_TYPE Page); VOID MmUnlockPage(PFN_TYPE Page); @@ -712,6 +713,7 @@ LONG MmAllocPagesSpecifyRange(ULONG Consumer, VOID MmDereferencePage(PFN_TYPE Page); VOID MmReferencePage(PFN_TYPE Page); +VOID MmReferencePageUnsafe(PFN_TYPE Page); BOOLEAN MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address); diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index 0e6038467a1..02bcd736b07 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -623,15 +623,15 @@ MmGetSavedSwapEntryPage(PFN_TYPE Pfn) } VOID -MmReferencePage(PFN_TYPE Pfn) +MmReferencePageUnsafe(PFN_TYPE Pfn) { KIRQL oldIrql; - DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT); + DPRINT("MmReferencePageUnsafe(PysicalAddress %x)\n", Pfn << PAGE_SHIFT); if (Pfn == 0 || Pfn >= MmPageArraySize) { - KEBUGCHECK(0); + return; } KeAcquireSpinLock(&PageListLock, &oldIrql); @@ -646,6 +646,19 @@ MmReferencePage(PFN_TYPE Pfn) KeReleaseSpinLock(&PageListLock, oldIrql); } +VOID +MmReferencePage(PFN_TYPE Pfn) +{ + DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT); + + if (Pfn == 0 || Pfn >= MmPageArraySize) + { + KEBUGCHECK(0); + } + + MmReferencePageUnsafe(Pfn); +} + ULONG MmGetReferenceCountPage(PFN_TYPE Pfn) { @@ -792,15 +805,15 @@ MmGetLockCountPage(PFN_TYPE Pfn) } VOID -MmLockPage(PFN_TYPE Pfn) +MmLockPageUnsafe(PFN_TYPE Pfn) { KIRQL oldIrql; - DPRINT("MmLockPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); + DPRINT("MmLockPageUnsafe(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); if (Pfn == 0 || Pfn >= MmPageArraySize) { - KEBUGCHECK(0); + return; } KeAcquireSpinLock(&PageListLock, &oldIrql); @@ -815,6 +828,19 @@ MmLockPage(PFN_TYPE Pfn) KeReleaseSpinLock(&PageListLock, oldIrql); } +VOID +MmLockPage(PFN_TYPE Pfn) +{ + DPRINT("MmLockPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT); + + if (Pfn == 0 || Pfn >= MmPageArraySize) + { + KEBUGCHECK(0); + } + + MmLockPageUnsafe(Pfn); +} + VOID MmUnlockPage(PFN_TYPE Pfn) { diff --git a/reactos/ntoskrnl/mm/mdl.c b/reactos/ntoskrnl/mm/mdl.c index 934080c06a4..be8ff7294f5 100644 --- a/reactos/ntoskrnl/mm/mdl.c +++ b/reactos/ntoskrnl/mm/mdl.c @@ -29,7 +29,7 @@ extern ULONG MmPageArraySize; /* MDL Flags desc. -MDL_PAGES_LOCKED MmProbelAndLockPages has been called for this mdl +MDL_PAGES_LOCKED MmProbeAndLockPages has been called for this mdl MDL_SOURCE_IS_NONPAGED_POOL mdl has been build by MmBuildMdlForNonPagedPool MDL_PARTIAL mdl has been built by IoBuildPartialMdl MDL_MAPPING_CAN_FAIL in case of an error, MmMapLockedPages will return NULL instead of to bugcheck @@ -233,7 +233,7 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl) /* Unmap all the pages. */ for (i = 0; i < PageCount; i++) { - MmDeleteVirtualMapping(NULL, + MmDeleteVirtualMapping(Mdl->Process, (char*)BaseAddress + (i * PAGE_SIZE), FALSE, NULL, @@ -300,7 +300,7 @@ MmBuildMdlFromPages(PMDL Mdl, PPFN_TYPE Pages) { memcpy(Mdl + 1, Pages, sizeof(PFN_TYPE) * (PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGE_SIZE)); - //FIXME: this flag should be set by the caller perhaps? + /* FIXME: this flag should be set by the caller perhaps? */ Mdl->MdlFlags |= MDL_IO_PAGE_READ; } @@ -375,8 +375,8 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, ASSERT(NrPages <= (Mdl->Size - sizeof(MDL))/sizeof(PFN_TYPE)); - if (Mdl->StartVa >= (PVOID)KERNEL_BASE && - MmGetPfnForProcess(NULL, Mdl->StartVa) > MmPageArraySize) + if (Mdl->StartVa >= (PVOID)KERNEL_BASE && + MmGetPfnForProcess(NULL, Mdl->StartVa) >= MmPageArraySize) { /* phys addr is not phys memory so this must be io memory */ @@ -392,14 +392,14 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, if (Mdl->StartVa >= (PVOID)KERNEL_BASE) { - //FIXME: why isn't AccessMode used? + /* FIXME: why isn't AccessMode used? */ Mode = KernelMode; Mdl->Process = NULL; AddressSpace = MmGetKernelAddressSpace(); } else { - //FIXME: why isn't AccessMode used? + /* FIXME: why isn't AccessMode used? */ Mode = UserMode; Mdl->Process = CurrentProcess; AddressSpace = &CurrentProcess->AddressSpace; @@ -430,8 +430,11 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, for (j = 0; j < i; j++) { Page = MdlPages[j]; - MmUnlockPage(Page); - MmDereferencePage(Page); + if (Page < MmPageArraySize) + { + MmUnlockPage(Page); + MmDereferencePage(Page); + } } MmUnlockAddressSpace(AddressSpace); ExRaiseStatus(Status); @@ -451,8 +454,11 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, for (j = 0; j < i; j++) { Page = MdlPages[j]; - MmUnlockPage(Page); - MmDereferencePage(Page); + if (Page < MmPageArraySize) + { + MmUnlockPage(Page); + MmDereferencePage(Page); + } } MmUnlockAddressSpace(AddressSpace); ExRaiseStatus(Status); @@ -460,7 +466,10 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, } Page = MmGetPfnForProcess(NULL, Address); MdlPages[i] = Page; - MmReferencePage(Page); + if (Page >= MmPageArraySize) + Mdl->MdlFlags |= MDL_IO_SPACE; + else + MmReferencePage(Page); } MmUnlockAddressSpace(AddressSpace); @@ -843,6 +852,8 @@ MmMapLockedPagesSpecifyCache ( IN PMDL Mdl, } KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql); + + Mdl->Process = NULL; } /* Set the virtual mappings for the MDL pages. */ @@ -853,11 +864,18 @@ MmMapLockedPagesSpecifyCache ( IN PMDL Mdl, Protect |= PAGE_NOCACHE; else if (CacheType == MmWriteCombined) DPRINT("CacheType MmWriteCombined not supported!\n"); - Status = MmCreateVirtualMapping(CurrentProcess, - Base, - Protect, - MdlPages, - PageCount); + if (Mdl->MdlFlags & MDL_IO_SPACE) + Status = MmCreateVirtualMappingUnsafe(CurrentProcess, + Base, + Protect, + MdlPages, + PageCount); + else + Status = MmCreateVirtualMapping(CurrentProcess, + Base, + Protect, + MdlPages, + PageCount); if (!NT_SUCCESS(Status)) { DbgPrint("Unable to create virtual mapping\n"); diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 3587bff37a4..2a6a35fd882 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -727,6 +727,9 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, MmSharePageEntrySectionSegment(Segment, Offset); + /* FIXME: Should we call MmCreateVirtualMappingUnsafe if + * (Section->AllocationAttributes & SEC_PHYSICALMEMORY) is true? + */ Status = MmCreateVirtualMapping(MemoryArea->Process, Address, Attributes, @@ -829,14 +832,14 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, * Just map the desired physical page */ Page = (Offset + MemoryArea->Data.SectionData.ViewOffset) >> PAGE_SHIFT; - Status = MmCreateVirtualMapping(AddressSpace->Process, - Address, - Region->Protect, - &Page, - 1); + Status = MmCreateVirtualMappingUnsafe(AddressSpace->Process, + Address, + Region->Protect, + &Page, + 1); if (!NT_SUCCESS(Status)) { - DPRINT("MmCreateVirtualMapping failed, not out of memory\n"); + DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n"); KEBUGCHECK(0); return(Status); } @@ -846,7 +849,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace, */ if (Locked) { - MmLockPage(Page); + MmLockPageUnsafe(Page); } /*