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:
Gregor Anich 2005-03-15 22:07:05 +00:00
parent 23475fc1f9
commit 43bfb5dd4e
4 changed files with 79 additions and 30 deletions

View file

@ -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);

View file

@ -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)
{

View file

@ -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");

View file

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