mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Allow mapping of MDLs which describe I/O memory (device memory) into usermode. I hope the changes are correct :-/
svn path=/trunk/; revision=14109
This commit is contained in:
parent
23475fc1f9
commit
43bfb5dd4e
4 changed files with 79 additions and 30 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -376,7 +376,7 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
|
|||
|
||||
|
||||
if (Mdl->StartVa >= (PVOID)KERNEL_BASE &&
|
||||
MmGetPfnForProcess(NULL, Mdl->StartVa) > MmPageArraySize)
|
||||
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,9 +430,12 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
|
|||
for (j = 0; j < i; j++)
|
||||
{
|
||||
Page = MdlPages[j];
|
||||
if (Page < MmPageArraySize)
|
||||
{
|
||||
MmUnlockPage(Page);
|
||||
MmDereferencePage(Page);
|
||||
}
|
||||
}
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
ExRaiseStatus(Status);
|
||||
}
|
||||
|
@ -451,15 +454,21 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
|
|||
for (j = 0; j < i; j++)
|
||||
{
|
||||
Page = MdlPages[j];
|
||||
if (Page < MmPageArraySize)
|
||||
{
|
||||
MmUnlockPage(Page);
|
||||
MmDereferencePage(Page);
|
||||
}
|
||||
}
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
ExRaiseStatus(Status);
|
||||
}
|
||||
}
|
||||
Page = MmGetPfnForProcess(NULL, Address);
|
||||
MdlPages[i] = Page;
|
||||
if (Page >= MmPageArraySize)
|
||||
Mdl->MdlFlags |= MDL_IO_SPACE;
|
||||
else
|
||||
MmReferencePage(Page);
|
||||
}
|
||||
|
||||
|
@ -843,6 +852,8 @@ MmMapLockedPagesSpecifyCache ( IN PMDL Mdl,
|
|||
}
|
||||
|
||||
KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
|
||||
|
||||
Mdl->Process = NULL;
|
||||
}
|
||||
|
||||
/* Set the virtual mappings for the MDL pages. */
|
||||
|
@ -853,6 +864,13 @@ MmMapLockedPagesSpecifyCache ( IN PMDL Mdl,
|
|||
Protect |= PAGE_NOCACHE;
|
||||
else if (CacheType == MmWriteCombined)
|
||||
DPRINT("CacheType MmWriteCombined not supported!\n");
|
||||
if (Mdl->MdlFlags & MDL_IO_SPACE)
|
||||
Status = MmCreateVirtualMappingUnsafe(CurrentProcess,
|
||||
Base,
|
||||
Protect,
|
||||
MdlPages,
|
||||
PageCount);
|
||||
else
|
||||
Status = MmCreateVirtualMapping(CurrentProcess,
|
||||
Base,
|
||||
Protect,
|
||||
|
|
|
@ -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,
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue