mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 23:03:00 +00:00
- Checked in MmMapLockedPages patch from Anich Gregor.
svn path=/trunk/; revision=8689
This commit is contained in:
parent
35f3e5b524
commit
988f1d5968
2 changed files with 121 additions and 37 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: mdl.c,v 1.59 2004/03/06 22:21:20 dwelch Exp $
|
/* $Id: mdl.c,v 1.60 2004/03/13 19:14:16 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -152,42 +152,78 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
ULONG RegionSize;
|
ULONG RegionSize;
|
||||||
ULONG StartingOffset;
|
ULONG StartingOffset;
|
||||||
|
PEPROCESS CurrentProcess, OldProcess;
|
||||||
|
|
||||||
DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode);
|
DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode);
|
||||||
|
|
||||||
if (Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)
|
if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) && AccessMode != UserMode)
|
||||||
{
|
{
|
||||||
return(Mdl->MappedSystemVa);
|
return(Mdl->MappedSystemVa);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AccessMode == UserMode)
|
|
||||||
{
|
|
||||||
DPRINT1("MDL mapping to user-mode not yet handled.\n");
|
|
||||||
KEBUGCHECK(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calculate the number of pages required. */
|
/* Calculate the number of pages required. */
|
||||||
RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
|
RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
|
||||||
|
|
||||||
/* Allocate that number of pages from the mdl mapping region. */
|
if (AccessMode == UserMode)
|
||||||
KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
|
{
|
||||||
|
MEMORY_AREA *Result;
|
||||||
|
LARGE_INTEGER BoundaryAddressMultiple;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
StartingOffset = RtlFindClearBitsAndSet(&MiMdlMappingRegionAllocMap, RegionSize, MiMdlMappingRegionHint);
|
BoundaryAddressMultiple.QuadPart = 0;
|
||||||
|
Base = NULL;
|
||||||
if (StartingOffset == 0xffffffff)
|
|
||||||
{
|
|
||||||
DPRINT1("Out of MDL mapping space\n");
|
|
||||||
KEBUGCHECK(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Base = (char*)MiMdlMappingRegionBase + StartingOffset * PAGE_SIZE;
|
CurrentProcess = OldProcess = PsGetCurrentProcess();
|
||||||
|
if (Mdl->Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeAttachProcess(Mdl->Process);
|
||||||
|
CurrentProcess = Mdl->Process;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmLockAddressSpace(&CurrentProcess->AddressSpace);
|
||||||
|
Status = MmCreateMemoryArea(CurrentProcess,
|
||||||
|
&CurrentProcess->AddressSpace,
|
||||||
|
MEMORY_AREA_MDL_MAPPING,
|
||||||
|
&Base,
|
||||||
|
RegionSize * PAGE_SIZE,
|
||||||
|
0, /* PAGE_READWRITE? */
|
||||||
|
&Result,
|
||||||
|
FALSE,
|
||||||
|
FALSE,
|
||||||
|
BoundaryAddressMultiple);
|
||||||
|
MmUnlockAddressSpace(&CurrentProcess->AddressSpace);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
/* FIXME: handle this? */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentProcess = OldProcess = NULL;
|
||||||
|
|
||||||
|
/* Allocate that number of pages from the mdl mapping region. */
|
||||||
|
KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
|
||||||
|
|
||||||
|
StartingOffset = RtlFindClearBitsAndSet(&MiMdlMappingRegionAllocMap, RegionSize, MiMdlMappingRegionHint);
|
||||||
|
|
||||||
|
if (StartingOffset == 0xffffffff)
|
||||||
|
{
|
||||||
|
DPRINT1("Out of MDL mapping space\n");
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Base = (char*)MiMdlMappingRegionBase + StartingOffset * PAGE_SIZE;
|
||||||
|
|
||||||
|
if (MiMdlMappingRegionHint == StartingOffset)
|
||||||
|
{
|
||||||
|
MiMdlMappingRegionHint +=RegionSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
if (MiMdlMappingRegionHint == StartingOffset)
|
|
||||||
{
|
|
||||||
MiMdlMappingRegionHint +=RegionSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
|
|
||||||
|
|
||||||
/* Set the virtual mappings for the MDL pages. */
|
/* Set the virtual mappings for the MDL pages. */
|
||||||
MdlPages = (PULONG)(Mdl + 1);
|
MdlPages = (PULONG)(Mdl + 1);
|
||||||
|
@ -198,7 +234,7 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||||
PHYSICAL_ADDRESS dummyJunkNeeded;
|
PHYSICAL_ADDRESS dummyJunkNeeded;
|
||||||
dummyJunkNeeded.QuadPart = MdlPages[i];
|
dummyJunkNeeded.QuadPart = MdlPages[i];
|
||||||
#endif
|
#endif
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(CurrentProcess,
|
||||||
(PVOID)((ULONG)Base+(i*PAGE_SIZE)),
|
(PVOID)((ULONG)Base+(i*PAGE_SIZE)),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
|
@ -214,6 +250,11 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AccessMode == UserMode && CurrentProcess != OldProcess)
|
||||||
|
{
|
||||||
|
KeDetachProcess();
|
||||||
|
}
|
||||||
|
|
||||||
/* Mark the MDL has having being mapped. */
|
/* Mark the MDL has having being mapped. */
|
||||||
Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
|
Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
|
||||||
Mdl->MappedSystemVa = (char*)Base + Mdl->ByteOffset;
|
Mdl->MappedSystemVa = (char*)Base + Mdl->ByteOffset;
|
||||||
|
@ -223,7 +264,7 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
|
MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Releases a mapping set up by a preceding call to MmMapLockedPages
|
* FUNCTION: Releases a mapping set up by a preceding call to MmMapLockedPages
|
||||||
|
@ -236,6 +277,7 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG RegionSize;
|
ULONG RegionSize;
|
||||||
ULONG Base;
|
ULONG Base;
|
||||||
|
PEPROCESS CurrentProcess, OldProcess;
|
||||||
|
|
||||||
DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", BaseAddress, Mdl);
|
DPRINT("MmUnmapLockedPages(BaseAddress %x, Mdl %x)\n", BaseAddress, Mdl);
|
||||||
|
|
||||||
|
@ -243,11 +285,26 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
|
||||||
* In this case, the MDL has the same system address as the base address
|
* In this case, the MDL has the same system address as the base address
|
||||||
* so there is no need to free it
|
* so there is no need to free it
|
||||||
*/
|
*/
|
||||||
if (Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL)
|
if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) &&
|
||||||
|
((ULONG_PTR)BaseAddress >= KERNEL_BASE))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((ULONG_PTR)BaseAddress >= KERNEL_BASE)
|
||||||
|
{
|
||||||
|
CurrentProcess = OldProcess = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CurrentProcess = OldProcess = PsGetCurrentProcess();
|
||||||
|
if (Mdl->Process != CurrentProcess)
|
||||||
|
{
|
||||||
|
KeAttachProcess(Mdl->Process);
|
||||||
|
CurrentProcess = Mdl->Process;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Calculate the number of pages we mapped. */
|
/* Calculate the number of pages we mapped. */
|
||||||
RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
|
RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
|
@ -263,23 +320,44 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
|
||||||
/* Unmap all the pages. */
|
/* Unmap all the pages. */
|
||||||
for (i = 0; i < RegionSize; i++)
|
for (i = 0; i < RegionSize; i++)
|
||||||
{
|
{
|
||||||
MmDeleteVirtualMapping(NULL,
|
MmDeleteVirtualMapping(NULL,
|
||||||
(char*)BaseAddress + (i * PAGE_SIZE),
|
(char*)BaseAddress + (i * PAGE_SIZE),
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
|
if ((DWORD)BaseAddress >= KERNEL_BASE)
|
||||||
/* Deallocate all the pages used. */
|
{
|
||||||
Base = (ULONG)((char*)BaseAddress - (char*)MiMdlMappingRegionBase) / PAGE_SIZE;
|
KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
|
||||||
|
/* Deallocate all the pages used. */
|
||||||
RtlClearBits(&MiMdlMappingRegionAllocMap, Base, RegionSize);
|
Base = (ULONG)((char*)BaseAddress - (char*)MiMdlMappingRegionBase) / PAGE_SIZE;
|
||||||
|
|
||||||
MiMdlMappingRegionHint = min (MiMdlMappingRegionHint, Base);
|
RtlClearBits(&MiMdlMappingRegionAllocMap, Base, RegionSize);
|
||||||
|
|
||||||
|
MiMdlMappingRegionHint = min (MiMdlMappingRegionHint, Base);
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MEMORY_AREA *Marea;
|
||||||
|
|
||||||
|
Marea = MmOpenMemoryAreaByAddress( &CurrentProcess->AddressSpace, BaseAddress );
|
||||||
|
if (Marea == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1( "Couldn't open memory area when unmapping user-space pages!\n" );
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
MmFreeMemoryArea( &CurrentProcess->AddressSpace, Marea->BaseAddress, 0, NULL, NULL );
|
||||||
|
|
||||||
|
if (CurrentProcess != OldProcess)
|
||||||
|
{
|
||||||
|
KeDetachProcess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
|
|
||||||
|
|
||||||
/* Reset the MDL state. */
|
/* Reset the MDL state. */
|
||||||
Mdl->MdlFlags = Mdl->MdlFlags & ~MDL_MAPPED_TO_SYSTEM_VA;
|
Mdl->MdlFlags = Mdl->MdlFlags & ~MDL_MAPPED_TO_SYSTEM_VA;
|
||||||
Mdl->MappedSystemVa = NULL;
|
Mdl->MappedSystemVa = NULL;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: mm.c,v 1.68 2004/02/15 19:03:29 hbirr Exp $
|
/* $Id: mm.c,v 1.69 2004/03/13 19:14:15 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -35,6 +35,7 @@
|
||||||
#include <internal/ntoskrnl.h>
|
#include <internal/ntoskrnl.h>
|
||||||
#include <internal/io.h>
|
#include <internal/io.h>
|
||||||
#include <internal/ps.h>
|
#include <internal/ps.h>
|
||||||
|
#include <reactos/bugcodes.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
@ -78,6 +79,11 @@ NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
|
||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MEMORY_AREA_MDL_MAPPING:
|
||||||
|
KEBUGCHECK(PROCESS_HAS_LOCKED_PAGES);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue