mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -152,42 +152,78 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
|||
KIRQL oldIrql;
|
||||
ULONG RegionSize;
|
||||
ULONG StartingOffset;
|
||||
|
||||
PEPROCESS CurrentProcess, OldProcess;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (AccessMode == UserMode)
|
||||
{
|
||||
DPRINT1("MDL mapping to user-mode not yet handled.\n");
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
/* Calculate the number of pages required. */
|
||||
RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
|
||||
|
||||
/* Allocate that number of pages from the mdl mapping region. */
|
||||
KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
|
||||
if (AccessMode == UserMode)
|
||||
{
|
||||
MEMORY_AREA *Result;
|
||||
LARGE_INTEGER BoundaryAddressMultiple;
|
||||
NTSTATUS Status;
|
||||
|
||||
StartingOffset = RtlFindClearBitsAndSet(&MiMdlMappingRegionAllocMap, RegionSize, MiMdlMappingRegionHint);
|
||||
|
||||
if (StartingOffset == 0xffffffff)
|
||||
{
|
||||
DPRINT1("Out of MDL mapping space\n");
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
BoundaryAddressMultiple.QuadPart = 0;
|
||||
Base = NULL;
|
||||
|
||||
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. */
|
||||
MdlPages = (PULONG)(Mdl + 1);
|
||||
|
@ -198,7 +234,7 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
|||
PHYSICAL_ADDRESS dummyJunkNeeded;
|
||||
dummyJunkNeeded.QuadPart = MdlPages[i];
|
||||
#endif
|
||||
Status = MmCreateVirtualMapping(NULL,
|
||||
Status = MmCreateVirtualMapping(CurrentProcess,
|
||||
(PVOID)((ULONG)Base+(i*PAGE_SIZE)),
|
||||
PAGE_READWRITE,
|
||||
#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. */
|
||||
Mdl->MdlFlags = Mdl->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
|
||||
Mdl->MappedSystemVa = (char*)Base + Mdl->ByteOffset;
|
||||
|
@ -223,7 +264,7 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
|||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID STDCALL
|
||||
VOID STDCALL
|
||||
MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
|
||||
/*
|
||||
* FUNCTION: Releases a mapping set up by a preceding call to MmMapLockedPages
|
||||
|
@ -236,6 +277,7 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
|
|||
ULONG i;
|
||||
ULONG RegionSize;
|
||||
ULONG Base;
|
||||
PEPROCESS CurrentProcess, OldProcess;
|
||||
|
||||
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
|
||||
* 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;
|
||||
}
|
||||
|
||||
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. */
|
||||
RegionSize = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
|
||||
#if defined(__GNUC__)
|
||||
|
@ -263,23 +320,44 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
|
|||
/* Unmap all the pages. */
|
||||
for (i = 0; i < RegionSize; i++)
|
||||
{
|
||||
MmDeleteVirtualMapping(NULL,
|
||||
MmDeleteVirtualMapping(NULL,
|
||||
(char*)BaseAddress + (i * PAGE_SIZE),
|
||||
FALSE,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
|
||||
/* Deallocate all the pages used. */
|
||||
Base = (ULONG)((char*)BaseAddress - (char*)MiMdlMappingRegionBase) / PAGE_SIZE;
|
||||
|
||||
RtlClearBits(&MiMdlMappingRegionAllocMap, Base, RegionSize);
|
||||
if ((DWORD)BaseAddress >= KERNEL_BASE)
|
||||
{
|
||||
KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
|
||||
/* Deallocate all the pages used. */
|
||||
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. */
|
||||
Mdl->MdlFlags = Mdl->MdlFlags & ~MDL_MAPPED_TO_SYSTEM_VA;
|
||||
Mdl->MappedSystemVa = NULL;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* 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
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -35,6 +35,7 @@
|
|||
#include <internal/ntoskrnl.h>
|
||||
#include <internal/io.h>
|
||||
#include <internal/ps.h>
|
||||
#include <reactos/bugcodes.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
@ -78,6 +79,11 @@ NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
|
|||
NULL,
|
||||
NULL);
|
||||
break;
|
||||
|
||||
case MEMORY_AREA_MDL_MAPPING:
|
||||
KEBUGCHECK(PROCESS_HAS_LOCKED_PAGES);
|
||||
break;
|
||||
|
||||
default:
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue