diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 18213340fae..e579470b87c 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -367,6 +367,9 @@ typedef VOID (*PMM_FREE_PAGE_FUNC)(PVOID Context, PMEMORY_AREA MemoryArea, /* FUNCTIONS */ +VOID MmLockPagedPool(VOID); +VOID MmUnlockPagedPool(VOID); + /* aspace.c ******************************************************************/ VOID MmLockAddressSpace(PMADDRESS_SPACE AddressSpace); diff --git a/reactos/ntoskrnl/mm/mdl.c b/reactos/ntoskrnl/mm/mdl.c index d51fefd5c69..c8f740df7e9 100644 --- a/reactos/ntoskrnl/mm/mdl.c +++ b/reactos/ntoskrnl/mm/mdl.c @@ -364,6 +364,7 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, PFN_TYPE Page; PEPROCESS CurrentProcess = PsGetCurrentProcess(); PMADDRESS_SPACE AddressSpace; + BOOLEAN PagedPool; DPRINT("MmProbeAndLockPages(Mdl %x)\n", Mdl); @@ -398,6 +399,7 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, Mode = KernelMode; Mdl->Process = NULL; AddressSpace = MmGetKernelAddressSpace(); + PagedPool = Mdl->StartVa >= MmPagedPoolBase && Mdl->StartVa < MmPagedPoolBase + MmPagedPoolSize ? TRUE : FALSE; } else { @@ -405,14 +407,21 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, 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 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, MmDereferencePage(Page); } } - MmUnlockAddressSpace(AddressSpace); + if (PagedPool) + { + MmUnlockPagedPool(); + } + else + { + MmUnlockAddressSpace(AddressSpace); + } ExRaiseStatus(STATUS_ACCESS_VIOLATION); } } @@ -462,7 +478,14 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, MmDereferencePage(Page); } } - MmUnlockAddressSpace(AddressSpace); + if (PagedPool) + { + MmUnlockPagedPool(); + } + else + { + MmUnlockAddressSpace(AddressSpace); + } ExRaiseStatus(STATUS_ACCESS_VIOLATION); } } @@ -474,7 +497,14 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl, MmReferencePage(Page); } - MmUnlockAddressSpace(AddressSpace); + if (PagedPool) + { + MmUnlockPagedPool(); + } + else + { + MmUnlockAddressSpace(AddressSpace); + } Mdl->MdlFlags |= MDL_PAGES_LOCKED; } diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index 5a54dbcb857..9db3c362f5e 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -215,6 +215,10 @@ NTSTATUS MmAccessFault(KPROCESSOR_MODE Mode, 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 @@ NTSTATUS MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked) 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 MmNotPresentFault(KPROCESSOR_MODE Mode, NTSTATUS Status; BOOLEAN Locked = FromMdl; PFN_TYPE Pfn; + BOOLEAN PagedPool; DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address); @@ -344,16 +347,25 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode, 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 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode, */ 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 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode, DPRINT("Completed page fault handling\n"); if (!FromMdl) { - MmUnlockAddressSpace(AddressSpace); + if (PagedPool) + { + MmUnlockPagedPool(); + } + else + { + MmUnlockAddressSpace(AddressSpace); + } } return(Status); } diff --git a/reactos/ntoskrnl/mm/ppool.c b/reactos/ntoskrnl/mm/ppool.c index 767b739b3b8..14fe1af7fc2 100644 --- a/reactos/ntoskrnl/mm/ppool.c +++ b/reactos/ntoskrnl/mm/ppool.c @@ -41,11 +41,12 @@ PVOID MmPagedPoolBase; 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,6 +61,17 @@ MmInitializePagedPool() PAGE_SIZE ); ExInitializeFastMutex(&MmPagedPool->Mutex); + ExInitializeFastMutex(&MmPagedPoolLock); +} + +VOID MmLockPagedPool(VOID) +{ + ExAcquireFastMutex(&MmPagedPoolLock); +} + +VOID MmUnlockPagedPool(VOID) +{ + ExReleaseFastMutex(&MmPagedPoolLock); } /**********************************************************************