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);
}
/*