NtAllocateVirtualMemory() should return 64k aligned areas

svn path=/trunk/; revision=11109
This commit is contained in:
Gé van Geldorp 2004-09-28 19:49:21 +00:00
parent 43787ecece
commit d243b55958
5 changed files with 84 additions and 48 deletions

View file

@ -1,4 +1,4 @@
/* $Id: sysinfo.c,v 1.46 2004/09/28 15:02:28 weiden Exp $ /* $Id: sysinfo.c,v 1.47 2004/09/28 19:49:20 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -338,7 +338,7 @@ QSI_DEF(SystemBasicInformation)
Sbi->NumberOfPhysicalPages = MmStats.NrTotalPages; Sbi->NumberOfPhysicalPages = MmStats.NrTotalPages;
Sbi->LowestPhysicalPage = 0; /* FIXME */ Sbi->LowestPhysicalPage = 0; /* FIXME */
Sbi->HighestPhysicalPage = MmStats.NrTotalPages; /* FIXME */ Sbi->HighestPhysicalPage = MmStats.NrTotalPages; /* FIXME */
Sbi->AllocationGranularity = 65536; /* hard coded on Intel? */ Sbi->AllocationGranularity = MM_VIRTMEM_GRANULARITY; /* hard coded on Intel? */
Sbi->LowestUserAddress = 0x10000; /* Top of 64k */ Sbi->LowestUserAddress = 0x10000; /* Top of 64k */
Sbi->HighestUserAddress = (ULONG_PTR)MmHighestUserAddress; Sbi->HighestUserAddress = (ULONG_PTR)MmHighestUserAddress;
Sbi->ActiveProcessors = 0x00000001; /* FIXME */ Sbi->ActiveProcessors = 0x00000001; /* FIXME */

View file

@ -50,6 +50,9 @@ typedef ULONG PFN_TYPE, *PPFN_TYPE;
#define MM_LOWEST_USER_ADDRESS (4096) #define MM_LOWEST_USER_ADDRESS (4096)
#endif #endif
#define MM_VIRTMEM_GRANULARITY (64 * 1024) /* Although Microsoft says this isn't hardcoded anymore,
they won't be able to change it. Stuff depends on it */
#define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001) #define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001)
/* /*
@ -354,7 +357,7 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
PVOID Address, PVOID Address,
ULONG Length); ULONG Length);
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, BOOL TopDown); PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG Granularity, BOOL TopDown);
/* npool.c *******************************************************************/ /* npool.c *******************************************************************/

View file

@ -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: anonmem.c,v 1.31 2004/08/15 16:39:06 chorns Exp $ /* $Id: anonmem.c,v 1.32 2004/09/28 19:49:20 gvg Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/anonmem.c * FILE: ntoskrnl/mm/anonmem.c
@ -636,17 +636,17 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
return(Status); return(Status);
} }
MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead, MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
RegionSize, Type, Protect); MemoryArea->Length, Type, Protect);
if ((AllocationType & MEM_COMMIT) && if ((AllocationType & MEM_COMMIT) &&
((Protect & PAGE_READWRITE) || ((Protect & PAGE_READWRITE) ||
(Protect & PAGE_EXECUTE_READWRITE))) (Protect & PAGE_EXECUTE_READWRITE)))
{ {
MmReserveSwapPages(RegionSize); MmReserveSwapPages(MemoryArea->Length);
} }
*UBaseAddress = BaseAddress; *UBaseAddress = BaseAddress;
*URegionSize = RegionSize; *URegionSize = MemoryArea->Length;
DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress, RegionSize); DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress, RegionSize);
MmUnlockAddressSpace(AddressSpace); MmUnlockAddressSpace(AddressSpace);

View file

@ -201,8 +201,10 @@ static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace,
InsertTailList(ListHead,inserted_entry); InsertTailList(ListHead,inserted_entry);
} }
#define ROUND_DOWN_POW2(Addr, Boundary) ((ULONG_PTR) (Addr) & ~ ((Boundary) - 1))
#define ROUND_UP_POW2(Addr, Boundary) ROUND_DOWN_POW2((ULONG_PTR) (Addr) + (Boundary) - 1, Boundary)
PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length) static PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG Granularity)
{ {
PLIST_ENTRY ListHead; PLIST_ENTRY ListHead;
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
@ -213,6 +215,10 @@ PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length)
DPRINT("MmFindGapBottomUp(Length %x)\n",Length); DPRINT("MmFindGapBottomUp(Length %x)\n",Length);
#ifdef DBG
Length += PAGE_SIZE; /* For a guard page following the area */
#endif
ListHead = &AddressSpace->MAreaListHead; ListHead = &AddressSpace->MAreaListHead;
current_entry = ListHead->Flink; current_entry = ListHead->Flink;
@ -220,35 +226,49 @@ PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length)
{ {
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry); next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry);
Address = (PVOID) ((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length));
#ifdef DBG
Address = (PVOID) ((char *) Address + PAGE_SIZE); /* For a guard page preceding the area */
#endif
Address = (PVOID) ROUND_UP_POW2(Address, Granularity);
if (Address < next->BaseAddress)
{
Gap = (char*)next->BaseAddress - ((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length)); Gap = (char*)next->BaseAddress - ((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length));
if (Gap >= Length) if (Gap >= Length)
{ {
return((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length)); return Address;
}
} }
current_entry = current_entry->Flink; current_entry = current_entry->Flink;
} }
if (current_entry == ListHead) if (current_entry == ListHead)
{ {
Address = (PVOID)AddressSpace->LowestAddress; Address = (PVOID) ROUND_UP_POW2(AddressSpace->LowestAddress, Granularity);
} }
else else
{ {
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
Address = (char*)current->BaseAddress + PAGE_ROUND_UP(current->Length); Address = (char*)current->BaseAddress + PAGE_ROUND_UP(current->Length);
#ifdef DBG
Address = (PVOID) ((char *) Address + PAGE_SIZE); /* For a guard page preceding the area */
#endif
Address = (PVOID) ROUND_UP_POW2(Address, Granularity);
} }
/* Check if enough space for the block */ /* Check if enough space for the block */
if (AddressSpace->LowestAddress < KERNEL_BASE) if (AddressSpace->LowestAddress < KERNEL_BASE)
{ {
if ((ULONG)Address >= KERNEL_BASE || Length > KERNEL_BASE - (ULONG)Address) if ((ULONG_PTR) Address >= KERNEL_BASE || Length > KERNEL_BASE - (ULONG_PTR) Address)
{ {
DPRINT1("Failed to find gap\n");
return NULL; return NULL;
} }
} }
else else
{ {
if (Length >= 0xFFFFFFFF - (ULONG)Address) if (Length >= ~ ((ULONG_PTR) 0) - (ULONG_PTR) Address)
{ {
DPRINT1("Failed to find gap\n");
return NULL; return NULL;
} }
} }
@ -256,7 +276,7 @@ PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length)
} }
PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length) static PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG Granularity)
{ {
PLIST_ENTRY ListHead; PLIST_ENTRY ListHead;
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
@ -269,6 +289,10 @@ PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length)
DPRINT("MmFindGapTopDown(Length %lx)\n",Length); DPRINT("MmFindGapTopDown(Length %lx)\n",Length);
#ifdef DBG
Length += PAGE_SIZE; /* For a guard page following the area */
#endif
if (AddressSpace->LowestAddress < KERNEL_BASE) //(ULONG_PTR)MmSystemRangeStart) if (AddressSpace->LowestAddress < KERNEL_BASE) //(ULONG_PTR)MmSystemRangeStart)
{ {
HighestAddress = MmHighestUserAddress; HighestAddress = MmHighestUserAddress;
@ -286,45 +310,49 @@ PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length)
{ {
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry); current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
BottomAddress = (char*)current->BaseAddress + PAGE_ROUND_UP(current->Length); BottomAddress = (char*)current->BaseAddress + PAGE_ROUND_UP(current->Length);
#ifdef DBG
BottomAddress = (PVOID) ((char *) BottomAddress + PAGE_SIZE); /* For a guard page preceding the area */
#endif
BottomAddress = (PVOID) ROUND_UP_POW2(BottomAddress, Granularity);
DPRINT("Base %p Length %lx\n", current->BaseAddress, PAGE_ROUND_UP(current->Length)); DPRINT("Base %p Length %lx\n", current->BaseAddress, PAGE_ROUND_UP(current->Length));
if (BottomAddress < HighestAddress) if (BottomAddress < TopAddress && BottomAddress < HighestAddress)
{ {
Gap = (char*)TopAddress - (char*) BottomAddress + 1; Gap = (char*)TopAddress - (char*) BottomAddress + 1;
DPRINT("Bottom %p Top %p Gap %lx\n", BottomAddress, TopAddress, Gap); DPRINT("Bottom %p Top %p Gap %lx\n", BottomAddress, TopAddress, Gap);
if (Gap >= Length) if (Gap >= Length)
{ {
DPRINT("Found gap at %p\n", (char*) TopAddress - Length); DPRINT("Found gap at %p\n", (char*) TopAddress - Length);
return((char*)TopAddress - Length + 1); return (PVOID) ROUND_DOWN_POW2((char*) TopAddress - Length + 1, Granularity);
}
} }
TopAddress = (char*)current->BaseAddress - 1; TopAddress = (char*)current->BaseAddress - 1;
}
current_entry = current_entry->Blink; current_entry = current_entry->Blink;
} }
if (current_entry == ListHead) if (current_entry == ListHead)
{ {
Address = (char*)HighestAddress - Length + 1; Address = (PVOID) ROUND_DOWN_POW2((char*) HighestAddress - Length + 1, Granularity);
} }
else else
{ {
Address = (char*)TopAddress - Length + 1; Address = (PVOID) ROUND_DOWN_POW2((char*)TopAddress - Length + 1, Granularity);
} }
/* Check if enough space for the block */ /* Check if enough space for the block */
if (AddressSpace->LowestAddress < KERNEL_BASE) if (AddressSpace->LowestAddress < KERNEL_BASE)
{ {
if ((ULONG)Address >= KERNEL_BASE || Length > KERNEL_BASE - (ULONG)Address) if ((ULONG_PTR) Address >= KERNEL_BASE || Length > KERNEL_BASE - (ULONG_PTR) Address)
{ {
DPRINT("Failed to find gap\n"); DPRINT1("Failed to find gap\n");
return NULL; return NULL;
} }
} }
else else
{ {
if (Length >= 0xFFFFFFFF - (ULONG)Address) if (Length >= ~ ((ULONG_PTR) 0) - (ULONG_PTR) Address)
{ {
DPRINT("Failed to find gap\n"); DPRINT1("Failed to find gap\n");
return NULL; return NULL;
} }
} }
@ -334,12 +362,12 @@ PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length)
} }
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, BOOL TopDown) PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG Granularity, BOOL TopDown)
{ {
if (TopDown) if (TopDown)
return MmFindGapTopDown(AddressSpace, Length); return MmFindGapTopDown(AddressSpace, Length, Granularity);
return MmFindGapBottomUp(AddressSpace, Length); return MmFindGapBottomUp(AddressSpace, Length, Granularity);
} }
ULONG MmFindGapAtAddress(PMADDRESS_SPACE AddressSpace, PVOID Address) ULONG MmFindGapAtAddress(PMADDRESS_SPACE AddressSpace, PVOID Address)
@ -546,38 +574,30 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
*/ */
{ {
PVOID EndAddress; PVOID EndAddress;
ULONG Granularity;
ULONG tmpLength; ULONG tmpLength;
DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %x," DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %x,"
"*BaseAddress %x, Length %x, Attributes %x, Result %x)\n", "*BaseAddress %x, Length %x, Attributes %x, Result %x)\n",
Type,BaseAddress,*BaseAddress,Length,Attributes,Result); Type,BaseAddress,*BaseAddress,Length,Attributes,Result);
Granularity = (MEMORY_AREA_VIRTUAL_MEMORY == Type ? MM_VIRTMEM_GRANULARITY : PAGE_SIZE);
if ((*BaseAddress) == 0 && !FixedAddress) if ((*BaseAddress) == 0 && !FixedAddress)
{ {
tmpLength = PAGE_ROUND_UP(Length); tmpLength = PAGE_ROUND_UP(Length);
*BaseAddress = MmFindGap(AddressSpace, *BaseAddress = MmFindGap(AddressSpace,
PAGE_ROUND_UP(Length) +(PAGE_SIZE*2), PAGE_ROUND_UP(Length),
Granularity,
TopDown); TopDown);
if ((*BaseAddress) == 0) if ((*BaseAddress) == 0)
{ {
DPRINT("No suitable gap\n"); DPRINT("No suitable gap\n");
return(STATUS_NO_MEMORY); return STATUS_NO_MEMORY;
} }
#if defined(__GNUC__)
(*BaseAddress)=(*BaseAddress)+PAGE_SIZE;
#else
{
char* pTemp = *BaseAddress;
pTemp += PAGE_SIZE;
*BaseAddress = pTemp;
}
#endif
} }
else else
{ {
tmpLength = (ULONG)*BaseAddress + Length - PAGE_ROUND_DOWN((*BaseAddress)); tmpLength = Length + ((ULONG_PTR) *BaseAddress - ROUND_DOWN_POW2(*BaseAddress, Granularity));
(*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress)); (*BaseAddress) = (PVOID) ROUND_DOWN_POW2(*BaseAddress, Granularity);
if (AddressSpace->LowestAddress == KERNEL_BASE && if (AddressSpace->LowestAddress == KERNEL_BASE &&
(*BaseAddress) < (PVOID)KERNEL_BASE) (*BaseAddress) < (PVOID)KERNEL_BASE)
@ -602,7 +622,7 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
tmpLength)!=NULL) tmpLength)!=NULL)
{ {
DPRINT("Memory area already occupied\n"); DPRINT("Memory area already occupied\n");
return(STATUS_CONFLICTING_ADDRESSES); return STATUS_CONFLICTING_ADDRESSES;
} }
} }
@ -621,5 +641,5 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
MmInsertMemoryArea(AddressSpace, *Result); MmInsertMemoryArea(AddressSpace, *Result);
DPRINT("MmCreateMemoryArea() succeeded\n"); DPRINT("MmCreateMemoryArea() succeeded\n");
return(STATUS_SUCCESS); return STATUS_SUCCESS;
} }

View file

@ -1,4 +1,4 @@
/* $Id: process.c,v 1.142 2004/09/28 15:02:29 weiden Exp $ /* $Id: process.c,v 1.143 2004/09/28 19:49:21 gvg Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -431,7 +431,20 @@ PsCreatePeb(HANDLE ProcessHandle,
(PVOID*)&Peb, (PVOID*)&Peb,
0, 0,
&PebSize, &PebSize,
MEM_RESERVE | MEM_COMMIT, MEM_RESERVE,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtAllocateVirtualMemory() failed (Status %lx)\n", Status);
return(Status);
}
Peb = (PPEB)PEB_BASE;
PebSize = PAGE_SIZE;
Status = NtAllocateVirtualMemory(ProcessHandle,
(PVOID*)&Peb,
0,
&PebSize,
MEM_COMMIT,
PAGE_READWRITE); PAGE_READWRITE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {