diff --git a/reactos/ntoskrnl/ex/sysinfo.c b/reactos/ntoskrnl/ex/sysinfo.c index 03a1045b41c..377e13370dc 100644 --- a/reactos/ntoskrnl/ex/sysinfo.c +++ b/reactos/ntoskrnl/ex/sysinfo.c @@ -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 */ diff --git a/reactos/ntoskrnl/include/internal/mm.h b/reactos/ntoskrnl/include/internal/mm.h index 0382c52f91d..7bef406740c 100644 --- a/reactos/ntoskrnl/include/internal/mm.h +++ b/reactos/ntoskrnl/include/internal/mm.h @@ -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 *******************************************************************/ diff --git a/reactos/ntoskrnl/mm/anonmem.c b/reactos/ntoskrnl/mm/anonmem.c index a16b130409a..29d008263c6 100644 --- a/reactos/ntoskrnl/mm/anonmem.c +++ b/reactos/ntoskrnl/mm/anonmem.c @@ -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); diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index 04913eb7000..1c7cf164cc7 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -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; } diff --git a/reactos/ntoskrnl/ps/process.c b/reactos/ntoskrnl/ps/process.c index a7c15015dd7..4775cfffa82 100644 --- a/reactos/ntoskrnl/ps/process.c +++ b/reactos/ntoskrnl/ps/process.c @@ -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)) {