Don't lock the kernel address space while solving faults from the paged
pool.
It is possible, that someone try to access memory from paged pool
while the kernel address space is already locked.
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
Modified: trunk/reactos/ntoskrnl/mm/mdl.c
Modified: trunk/reactos/ntoskrnl/mm/mm.c
Modified: trunk/reactos/ntoskrnl/mm/ppool.c
_____
Modified: trunk/reactos/ntoskrnl/include/internal/mm.h
--- trunk/reactos/ntoskrnl/include/internal/mm.h 2005-06-05
12:53:22 UTC (rev 15804)
+++ trunk/reactos/ntoskrnl/include/internal/mm.h 2005-06-05
14:01:58 UTC (rev 15805)
@@ -367,6 +367,9 @@
/* FUNCTIONS */
+VOID MmLockPagedPool(VOID);
+VOID MmUnlockPagedPool(VOID);
+
/* aspace.c
******************************************************************/
VOID MmLockAddressSpace(PMADDRESS_SPACE AddressSpace);
_____
Modified: trunk/reactos/ntoskrnl/mm/mdl.c
--- trunk/reactos/ntoskrnl/mm/mdl.c 2005-06-05 12:53:22 UTC (rev
15804)
+++ trunk/reactos/ntoskrnl/mm/mdl.c 2005-06-05 14:01:58 UTC (rev
15805)
@@ -364,6 +364,7 @@
PFN_TYPE Page;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
PMADDRESS_SPACE AddressSpace;
+ BOOLEAN PagedPool;
DPRINT("MmProbeAndLockPages(Mdl %x)\n", Mdl);
@@ -398,6 +399,7 @@
Mode = KernelMode;
Mdl->Process = NULL;
AddressSpace = MmGetKernelAddressSpace();
+ PagedPool = Mdl->StartVa >= MmPagedPoolBase && Mdl->StartVa <
MmPagedPoolBase + MmPagedPoolSize ? TRUE : FALSE;
}
else
{
@@ -405,14 +407,21 @@
Mode = UserMode;
Mdl->Process = CurrentProcess;
AddressSpace = &CurrentProcess->AddressSpace;
+ PagedPool = FALSE;
}
+ if (PagedPool)
+ {
+ MmLockPagedPool();
+ }
+ else
+ {
+ MmLockAddressSpace(AddressSpace);
+ }
/*
* Lock the pages
*/
- MmLockAddressSpace(AddressSpace);
-
for (i = 0; i < NrPages; i++)
{
PVOID Address;
@@ -438,7 +447,14 @@
MmDereferencePage(Page);
}
}
- MmUnlockAddressSpace(AddressSpace);
+ if (PagedPool)
+ {
+ MmUnlockPagedPool();
+ }
+ else
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ }
ExRaiseStatus(STATUS_ACCESS_VIOLATION);
}
}
@@ -462,7 +478,14 @@
MmDereferencePage(Page);
}
}
- MmUnlockAddressSpace(AddressSpace);
+ if (PagedPool)
+ {
+ MmUnlockPagedPool();
+ }
+ else
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ }
ExRaiseStatus(STATUS_ACCESS_VIOLATION);
}
}
@@ -474,7 +497,14 @@
MmReferencePage(Page);
}
- MmUnlockAddressSpace(AddressSpace);
+ if (PagedPool)
+ {
+ MmUnlockPagedPool();
+ }
+ else
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ }
Mdl->MdlFlags |= MDL_PAGES_LOCKED;
}
_____
Modified: trunk/reactos/ntoskrnl/mm/mm.c
--- trunk/reactos/ntoskrnl/mm/mm.c 2005-06-05 12:53:22 UTC (rev
15804)
+++ trunk/reactos/ntoskrnl/mm/mm.c 2005-06-05 14:01:58 UTC (rev
15805)
@@ -215,6 +215,10 @@
DbgPrint("%s:%d\n",__FILE__,__LINE__);
return(STATUS_UNSUCCESSFUL);
}
+ if (Address >= (ULONG_PTR)MmPagedPoolBase && Address <
(ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize)
+ {
+ return STATUS_SUCCESS;
+ }
AddressSpace = MmGetKernelAddressSpace();
}
else
@@ -285,9 +289,7 @@
Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE,
&AllocatedPage);
if (!NT_SUCCESS(Status))
{
- MmUnlockAddressSpace(MmGetKernelAddressSpace());
- Status = MmRequestPageMemoryConsumer(MC_PPOOL, TRUE,
&AllocatedPage);
- MmLockAddressSpace(MmGetKernelAddressSpace());
+ return Status;
}
Status =
MmCreateVirtualMapping(NULL,
@@ -311,6 +313,7 @@
NTSTATUS Status;
BOOLEAN Locked = FromMdl;
PFN_TYPE Pfn;
+ BOOLEAN PagedPool;
DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address);
@@ -344,16 +347,25 @@
CPRINT("Address: %x\n", Address);
return(STATUS_UNSUCCESSFUL);
}
+ PagedPool = Address >= (ULONG_PTR)MmPagedPoolBase && Address <
(ULONG_PTR)MmPagedPoolBase + MmPagedPoolSize ? TRUE : FALSE;
AddressSpace = MmGetKernelAddressSpace();
}
else
{
+ PagedPool = FALSE;
AddressSpace = &PsGetCurrentProcess()->AddressSpace;
}
if (!FromMdl)
{
- MmLockAddressSpace(AddressSpace);
+ if (PagedPool)
+ {
+ MmLockPagedPool();
+ }
+ else
+ {
+ MmLockAddressSpace(AddressSpace);
+ }
}
/*
@@ -361,56 +373,56 @@
*/
do
{
- MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
(PVOID)Address);
- if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
+ if (PagedPool)
{
- if (!FromMdl)
- {
- MmUnlockAddressSpace(AddressSpace);
- }
- return (STATUS_UNSUCCESSFUL);
+ Status = MmCommitPagedPoolAddress((PVOID)Address, Locked);
}
-
- switch (MemoryArea->Type)
+ else
{
- case MEMORY_AREA_PAGED_POOL:
+ MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
(PVOID)Address);
+ if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
+ {
+ if (!FromMdl)
{
- Status = MmCommitPagedPoolAddress((PVOID)Address,
Locked);
- break;
+ MmUnlockAddressSpace(AddressSpace);
}
+ return (STATUS_UNSUCCESSFUL);
+ }
- case MEMORY_AREA_SYSTEM:
- Status = STATUS_UNSUCCESSFUL;
- break;
+ switch (MemoryArea->Type)
+ {
+ case MEMORY_AREA_SYSTEM:
+ Status = STATUS_UNSUCCESSFUL;
+ break;
- case MEMORY_AREA_SECTION_VIEW:
- Status = MmNotPresentFaultSectionView(AddressSpace,
- MemoryArea,
- (PVOID)Address,
- Locked);
- break;
+ case MEMORY_AREA_SECTION_VIEW:
+ Status = MmNotPresentFaultSectionView(AddressSpace,
+ MemoryArea,
+ (PVOID)Address,
+ Locked);
+ break;
- case MEMORY_AREA_VIRTUAL_MEMORY:
- case MEMORY_AREA_PEB_OR_TEB:
- Status = MmNotPresentFaultVirtualMemory(AddressSpace,
- MemoryArea,
- (PVOID)Address,
- Locked);
- break;
+ case MEMORY_AREA_VIRTUAL_MEMORY:
+ case MEMORY_AREA_PEB_OR_TEB:
+ Status = MmNotPresentFaultVirtualMemory(AddressSpace,
+ MemoryArea,
+ (PVOID)Address,
+ Locked);
+ break;
- case MEMORY_AREA_SHARED_DATA:
- Pfn = MmSharedDataPagePhysicalAddress.QuadPart >>
PAGE_SHIFT;
- Status =
- MmCreateVirtualMapping(PsGetCurrentProcess(),
- (PVOID)PAGE_ROUND_DOWN(Address),
- PAGE_READONLY,
- &Pfn,
- 1);
- break;
+ case MEMORY_AREA_SHARED_DATA:
+ Pfn = MmSharedDataPagePhysicalAddress.QuadPart >>
PAGE_SHIFT;
+ Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
+
(PVOID)PAGE_ROUND_DOWN(Address),
+ PAGE_READONLY,
+ &Pfn,
+ 1);
+ break;
- default:
- Status = STATUS_UNSUCCESSFUL;
- break;
+ default:
+ Status = STATUS_UNSUCCESSFUL;
+ break;
+ }
}
}
while (Status == STATUS_MM_RESTART_OPERATION);
@@ -418,7 +430,14 @@
DPRINT("Completed page fault handling\n");
if (!FromMdl)
{
- MmUnlockAddressSpace(AddressSpace);
+ if (PagedPool)
+ {
+ MmUnlockPagedPool();
+ }
+ else
+ {
+ MmUnlockAddressSpace(AddressSpace);
+ }
}
return(Status);
}
_____
Modified: trunk/reactos/ntoskrnl/mm/ppool.c
--- trunk/reactos/ntoskrnl/mm/ppool.c 2005-06-05 12:53:22 UTC (rev
15804)
+++ trunk/reactos/ntoskrnl/mm/ppool.c 2005-06-05 14:01:58 UTC (rev
15805)
@@ -41,11 +41,12 @@
ULONG MmPagedPoolSize;
ULONG MmTotalPagedPoolQuota = 0; // TODO FIXME commented out until we
use it
static PR_POOL MmPagedPool = NULL;
+static FAST_MUTEX MmPagedPoolLock;
/* FUNCTIONS
*****************************************************************/
VOID INIT_FUNCTION
-MmInitializePagedPool()
+MmInitializePagedPool(VOID)
{
/*
* We are still at a high IRQL level at this point so explicitly
commit
@@ -60,8 +61,19 @@
PAGE_SIZE );
ExInitializeFastMutex(&MmPagedPool->Mutex);
+ ExInitializeFastMutex(&MmPagedPoolLock);
}
+VOID MmLockPagedPool(VOID)
+{
+ ExAcquireFastMutex(&MmPagedPoolLock);
+}
+
+VOID MmUnlockPagedPool(VOID)
+{
+ ExReleaseFastMutex(&MmPagedPoolLock);
+}
+
/**********************************************************************
* NAME INTERNAL
* ExAllocatePagedPoolWithTag@12