diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 4ffc1b4698f..518733c63ea 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -364,7 +364,8 @@ NTSTATUS MmCreatePhysicalMemorySection(VOID); PVOID MmGetContinuousPages(ULONG NumberOfBytes, - PHYSICAL_ADDRESS HighestAcceptableAddress); + PHYSICAL_ADDRESS HighestAcceptableAddress, + ULONG Alignment); #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8) diff --git a/reactos/ntoskrnl/mm/cont.c b/reactos/ntoskrnl/mm/cont.c index 14aa35c72a3..ead284b1139 100644 --- a/reactos/ntoskrnl/mm/cont.c +++ b/reactos/ntoskrnl/mm/cont.c @@ -1,4 +1,4 @@ -/* $Id: cont.c,v 1.7 2001/02/10 22:51:10 dwelch Exp $ +/* $Id: cont.c,v 1.8 2001/02/28 18:23:32 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -30,6 +30,51 @@ MmFreeContinuousPage(PVOID Context, PVOID Address) } } +PVOID STDCALL +MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes, + IN PHYSICAL_ADDRESS HighestAcceptableAddress, + IN ULONG Alignment) +{ + PMEMORY_AREA MArea; + NTSTATUS Status; + PVOID BaseAddress; + PVOID PBase; + ULONG i; + + Status = MmCreateMemoryArea(NULL, + MmGetKernelAddressSpace(), + MEMORY_AREA_CONTINUOUS_MEMORY, + &BaseAddress, + NumberOfBytes, + 0, + &MArea); + if (!NT_SUCCESS(Status)) + { + return(NULL); + } + + PBase = MmGetContinuousPages(NumberOfBytes, + HighestAcceptableAddress, + Alignment); + if (PBase == NULL) + { + MmFreeMemoryArea(MmGetKernelAddressSpace(), + BaseAddress, + 0, + NULL, + NULL); + return(NULL); + } + for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / 4096); i++) + { + MmCreateVirtualMapping(NULL, + BaseAddress + (i * 4096), + PAGE_EXECUTE_READWRITE | PAGE_SYSTEM, + (ULONG)(PBase + (i * 4096))); + } + return(BaseAddress); +} + /********************************************************************** * NAME EXPORTED * MmAllocateContiguousMemory@12 @@ -60,43 +105,9 @@ PVOID STDCALL MmAllocateContiguousMemory (IN ULONG NumberOfBytes, IN PHYSICAL_ADDRESS HighestAcceptableAddress) { - PMEMORY_AREA MArea; - NTSTATUS Status; - PVOID BaseAddress; - PVOID PBase; - ULONG i; - - Status = MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_CONTINUOUS_MEMORY, - &BaseAddress, - NumberOfBytes, - 0, - &MArea); - if (!NT_SUCCESS(Status)) - { - return(NULL); - } - - PBase = MmGetContinuousPages(NumberOfBytes, - HighestAcceptableAddress); - if (PBase == NULL) - { - MmFreeMemoryArea(MmGetKernelAddressSpace(), - BaseAddress, - 0, - NULL, - NULL); - return(NULL); - } - for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / 4096); i++) - { - MmCreateVirtualMapping(NULL, - BaseAddress + (i * 4096), - PAGE_EXECUTE_READWRITE | PAGE_SYSTEM, - (ULONG)(PBase + (i * 4096))); - } - return(BaseAddress); + return(MmAllocateContiguousAlignedMemory(NumberOfBytes, + HighestAcceptableAddress, + PAGESIZE)); } diff --git a/reactos/ntoskrnl/mm/freelist.c b/reactos/ntoskrnl/mm/freelist.c index 51f5e66f8db..433665b14bf 100644 --- a/reactos/ntoskrnl/mm/freelist.c +++ b/reactos/ntoskrnl/mm/freelist.c @@ -50,7 +50,8 @@ static LIST_ENTRY BiosPageListHead; PVOID MmGetContinuousPages(ULONG NumberOfBytes, - PHYSICAL_ADDRESS HighestAcceptableAddress) + PHYSICAL_ADDRESS HighestAcceptableAddress, + ULONG Alignment) { ULONG NrPages; ULONG i; @@ -64,7 +65,7 @@ MmGetContinuousPages(ULONG NumberOfBytes, start = -1; length = 0; - for (i = 0; i < (HighestAcceptableAddress.QuadPart / PAGESIZE); i++) + for (i = 0; i < (HighestAcceptableAddress.QuadPart / PAGESIZE); ) { if (MmPageArray[i].Flags & MM_PHYSICAL_PAGE_FREE) { @@ -77,6 +78,7 @@ MmGetContinuousPages(ULONG NumberOfBytes, { length++; } + i++; if (length == NrPages) { break; @@ -85,9 +87,13 @@ MmGetContinuousPages(ULONG NumberOfBytes, else if (start != -1) { start = -1; + /* + * Fast forward to the base of the next aligned region + */ + i = i + (Alignment / PAGESIZE); } } - if (start == -1) + if (start == -1 || length != NrPages) { KeReleaseSpinLock(&PageListLock, oldIrql); return(NULL);