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
* PROJECT: ReactOS kernel
@ -338,7 +338,7 @@ QSI_DEF(SystemBasicInformation)
Sbi->NumberOfPhysicalPages = MmStats.NrTotalPages;
Sbi->LowestPhysicalPage = 0; /* 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->HighestUserAddress = (ULONG_PTR)MmHighestUserAddress;
Sbi->ActiveProcessors = 0x00000001; /* FIXME */

View file

@ -50,6 +50,9 @@ typedef ULONG PFN_TYPE, *PPFN_TYPE;
#define MM_LOWEST_USER_ADDRESS (4096)
#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)
/*
@ -354,7 +357,7 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
PVOID Address,
ULONG Length);
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, BOOL TopDown);
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, ULONG Granularity, BOOL TopDown);
/* npool.c *******************************************************************/

View file

@ -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: 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
* FILE: ntoskrnl/mm/anonmem.c
@ -636,17 +636,17 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
return(Status);
}
MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
RegionSize, Type, Protect);
MemoryArea->Length, Type, Protect);
if ((AllocationType & MEM_COMMIT) &&
((Protect & PAGE_READWRITE) ||
(Protect & PAGE_EXECUTE_READWRITE)))
{
MmReserveSwapPages(RegionSize);
MmReserveSwapPages(MemoryArea->Length);
}
*UBaseAddress = BaseAddress;
*URegionSize = RegionSize;
*URegionSize = MemoryArea->Length;
DPRINT("*UBaseAddress %x *URegionSize %x\n", BaseAddress, RegionSize);
MmUnlockAddressSpace(AddressSpace);

View file

@ -201,8 +201,10 @@ static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace,
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 current_entry;
@ -213,6 +215,10 @@ PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length)
DPRINT("MmFindGapBottomUp(Length %x)\n",Length);
#ifdef DBG
Length += PAGE_SIZE; /* For a guard page following the area */
#endif
ListHead = &AddressSpace->MAreaListHead;
current_entry = ListHead->Flink;
@ -220,35 +226,49 @@ PVOID MmFindGapBottomUp(PMADDRESS_SPACE AddressSpace, ULONG Length)
{
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
next = CONTAINING_RECORD(current_entry->Flink,MEMORY_AREA,Entry);
Gap = (char*)next->BaseAddress - ((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length));
if (Gap >= Length)
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)
{
return((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length));
Gap = (char*)next->BaseAddress - ((char*)current->BaseAddress + PAGE_ROUND_UP(current->Length));
if (Gap >= Length)
{
return Address;
}
}
current_entry = current_entry->Flink;
}
if (current_entry == ListHead)
{
Address = (PVOID)AddressSpace->LowestAddress;
Address = (PVOID) ROUND_UP_POW2(AddressSpace->LowestAddress, Granularity);
}
else
{
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
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 */
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;
}
}
else
{
if (Length >= 0xFFFFFFFF - (ULONG)Address)
if (Length >= ~ ((ULONG_PTR) 0) - (ULONG_PTR) Address)
{
DPRINT1("Failed to find gap\n");
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 current_entry;
@ -269,6 +289,10 @@ PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG 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)
{
HighestAddress = MmHighestUserAddress;
@ -286,45 +310,49 @@ PVOID MmFindGapTopDown(PMADDRESS_SPACE AddressSpace, ULONG Length)
{
current = CONTAINING_RECORD(current_entry,MEMORY_AREA,Entry);
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));
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);
if (Gap >= Length)
{
DPRINT("Found gap at %p\n", (char*)TopAddress - Length);
return((char*)TopAddress - Length + 1);
DPRINT("Found gap at %p\n", (char*) TopAddress - Length);
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;
}
if (current_entry == ListHead)
{
Address = (char*)HighestAddress - Length + 1;
Address = (PVOID) ROUND_DOWN_POW2((char*) HighestAddress - Length + 1, Granularity);
}
else
{
Address = (char*)TopAddress - Length + 1;
Address = (PVOID) ROUND_DOWN_POW2((char*)TopAddress - Length + 1, Granularity);
}
/* Check if enough space for the block */
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;
}
}
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;
}
}
@ -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)
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)
@ -546,38 +574,30 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
*/
{
PVOID EndAddress;
ULONG Granularity;
ULONG tmpLength;
DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %x,"
"*BaseAddress %x, Length %x, Attributes %x, Result %x)\n",
Type,BaseAddress,*BaseAddress,Length,Attributes,Result);
Granularity = (MEMORY_AREA_VIRTUAL_MEMORY == Type ? MM_VIRTMEM_GRANULARITY : PAGE_SIZE);
if ((*BaseAddress) == 0 && !FixedAddress)
{
tmpLength = PAGE_ROUND_UP(Length);
*BaseAddress = MmFindGap(AddressSpace,
PAGE_ROUND_UP(Length) +(PAGE_SIZE*2),
PAGE_ROUND_UP(Length),
Granularity,
TopDown);
if ((*BaseAddress) == 0)
{
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
{
tmpLength = (ULONG)*BaseAddress + Length - PAGE_ROUND_DOWN((*BaseAddress));
(*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress));
tmpLength = Length + ((ULONG_PTR) *BaseAddress - ROUND_DOWN_POW2(*BaseAddress, Granularity));
(*BaseAddress) = (PVOID) ROUND_DOWN_POW2(*BaseAddress, Granularity);
if (AddressSpace->LowestAddress == KERNEL_BASE &&
(*BaseAddress) < (PVOID)KERNEL_BASE)
@ -602,7 +622,7 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
tmpLength)!=NULL)
{
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);
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
* PROJECT: ReactOS kernel
@ -431,7 +431,20 @@ PsCreatePeb(HANDLE ProcessHandle,
(PVOID*)&Peb,
0,
&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);
if (!NT_SUCCESS(Status))
{