Allow mapping of MDLs which describe I/O memory (device memory) into usermode. I hope the changes are correct :-/ Modified: trunk/reactos/ntoskrnl/include/internal/mm.h Modified: trunk/reactos/ntoskrnl/mm/freelist.c Modified: trunk/reactos/ntoskrnl/mm/mdl.c Modified: trunk/reactos/ntoskrnl/mm/section.c _____
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h --- trunk/reactos/ntoskrnl/include/internal/mm.h 2005-03-15 22:06:41 UTC (rev 14108) +++ trunk/reactos/ntoskrnl/include/internal/mm.h 2005-03-15 22:07:05 UTC (rev 14109) @@ -628,6 +628,7 @@
VOID MmSetLRULastPage(PFN_TYPE Page);
VOID MmLockPage(PFN_TYPE Page); +VOID MmLockPageUnsafe(PFN_TYPE Page);
VOID MmUnlockPage(PFN_TYPE Page);
@@ -712,6 +713,7 @@ VOID MmDereferencePage(PFN_TYPE Page);
VOID MmReferencePage(PFN_TYPE Page); +VOID MmReferencePageUnsafe(PFN_TYPE Page);
BOOLEAN MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
_____
Modified: trunk/reactos/ntoskrnl/mm/freelist.c --- trunk/reactos/ntoskrnl/mm/freelist.c 2005-03-15 22:06:41 UTC (rev 14108) +++ trunk/reactos/ntoskrnl/mm/freelist.c 2005-03-15 22:07:05 UTC (rev 14109) @@ -623,15 +623,15 @@
}
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 @@ 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 @@ }
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); @@ -816,6 +829,19 @@ }
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) { KIRQL oldIrql; _____
Modified: trunk/reactos/ntoskrnl/mm/mdl.c --- trunk/reactos/ntoskrnl/mm/mdl.c 2005-03-15 22:06:41 UTC (rev 14108) +++ trunk/reactos/ntoskrnl/mm/mdl.c 2005-03-15 22:07:05 UTC (rev 14109) @@ -29,7 +29,7 @@
/* 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 @@ /* 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 @@ { 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 @@ 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 @@
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 @@ 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 @@ 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 @@ } 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 @@ }
KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql); + + Mdl->Process = NULL; }
/* Set the virtual mappings for the MDL pages. */ @@ -853,11 +864,18 @@ 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"); _____
Modified: trunk/reactos/ntoskrnl/mm/section.c --- trunk/reactos/ntoskrnl/mm/section.c 2005-03-15 22:06:41 UTC (rev 14108) +++ trunk/reactos/ntoskrnl/mm/section.c 2005-03-15 22:07:05 UTC (rev 14109) @@ -727,6 +727,9 @@
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 @@ * 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 @@ */ if (Locked) { - MmLockPage(Page); + MmLockPageUnsafe(Page); }
/*