Author: sir_richard Date: Mon Feb 27 17:10:44 2012 New Revision: 55885
URL: http://svn.reactos.org/svn/reactos?rev=55885&view=rev Log: [NTOS]: Continued preparations for VAD-based Virtual Memory. ASSERT in NtAllocateVirtualMemory any functionality that will not be supported by the VAD-based system (and is not really supported right now either). Make NtFreeVirtualMemory ASSERT that a correct VAD has been found when freeing memory -- which we always expect at this point. Also ASSERT that the VAD has a valid range and flags. [NTOS]: Do a more stringent check to refuse COPY_ON_WRITE flag sent through NtAllocateVirtualMemory. [NTOS]: For VM-based Memory Areas, acquire and then release the process working set lock while inserting the VAD, to simulate what the VAD-based Virtual Memory behavior will look like. [NTOS]: Disable paging for VM-based Memory Areas since this will not be supported with VADs. [KERNEL32]: CopyLoop was requesting 2 zero bits when calling NtAllocateVirtualMemory. Not sure if this was really the intent or not, but both the new as well as the old NtAllocateVirtualMemory do not support this (the new one will ASSERT). Since this functionality never worked, request 0 bits instead to avoid hitting the ASSERT. Any problems with what the VAD system will introduce should be revealed by now. From this build until the one which will have the VAD-based system in place, no further VM-related issues should crop up.
Modified: trunk/reactos/dll/win32/kernel32/client/file/copy.c trunk/reactos/ntoskrnl/mm/anonmem.c trunk/reactos/ntoskrnl/mm/marea.c trunk/reactos/ntoskrnl/mm/rmap.c
Modified: trunk/reactos/dll/win32/kernel32/client/file/copy.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/f... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/file/copy.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/file/copy.c [iso-8859-1] Mon Feb 27 17:10:44 2012 @@ -46,7 +46,7 @@ *KeepDest = FALSE; errCode = NtAllocateVirtualMemory(NtCurrentProcess(), (PVOID *)&lpBuffer, - 2, + 0, &RegionSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
Modified: trunk/reactos/ntoskrnl/mm/anonmem.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/anonmem.c?rev=5... ============================================================================== --- trunk/reactos/ntoskrnl/mm/anonmem.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/anonmem.c [iso-8859-1] Mon Feb 27 17:10:44 2012 @@ -750,23 +750,27 @@ } }
+ /* Now it's for real... assert on the things we don't yet support */ + ASSERT(ZeroBits == 0); + ASSERT((AllocationType & MEM_LARGE_PAGES) == 0); + ASSERT((AllocationType & MEM_PHYSICAL) == 0); + ASSERT((AllocationType & MEM_WRITE_WATCH) == 0); + ASSERT((AllocationType & MEM_TOP_DOWN) == 0); + ASSERT((AllocationType & MEM_RESET) == 0); + ASSERT(Process->VmTopDown == 0); + + /* Do not allow COPY_ON_WRITE through this API */ + if ((Protect & PAGE_WRITECOPY) || (Protect & PAGE_EXECUTE_WRITECOPY)) + { + DPRINT1("Illegal use of CopyOnWrite\n"); + if (Attached) KeUnstackDetachProcess(&ApcState); + if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process); + return STATUS_INVALID_PAGE_PROTECTION; + } + BaseAddress = (PVOID)PAGE_ROUND_DOWN(PBaseAddress); RegionSize = PAGE_ROUND_UP((ULONG_PTR)PBaseAddress + PRegionSize) - PAGE_ROUND_DOWN(PBaseAddress); - - - /* - * Copy on Write is reserved for system use. This case is a certain failure - * but there may be other cases...needs more testing - */ - if ((!BaseAddress || (AllocationType & MEM_RESERVE)) && - (Protect & (PAGE_WRITECOPY | PAGE_EXECUTE_WRITECOPY))) - { - DPRINT1("Copy on write is not supported by VirtualAlloc\n"); - if (Attached) KeUnstackDetachProcess(&ApcState); - if (ProcessHandle != NtCurrentProcess()) ObDereferenceObject(Process); - return STATUS_INVALID_PAGE_PROTECTION; - }
Type = (AllocationType & MEM_COMMIT) ? MEM_COMMIT : MEM_RESERVE; DPRINT("Type %x\n", Type); @@ -1053,6 +1057,8 @@ KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); KAPC_STATE ApcState; BOOLEAN Attached = FALSE; + ULONG_PTR StartingAddress, EndingAddress; + PMMVAD Vad; PAGED_CODE();
/* Only two flags are supported */ @@ -1134,9 +1140,23 @@
BaseAddress = (PVOID)PAGE_ROUND_DOWN((PBaseAddress));
- AddressSpace = &Process->Vm; - + /* Lock address space */ + AddressSpace = MmGetCurrentAddressSpace(); MmLockAddressSpace(AddressSpace); + ASSERT(Process->VmDeleted == 0); + + /* Compute start and end addresses, and locate the VAD */ + StartingAddress = (ULONG_PTR)PAGE_ALIGN(PBaseAddress); + EndingAddress = ((ULONG_PTR)PBaseAddress + PRegionSize - 1) | (PAGE_SIZE - 1); + Vad = MiLocateAddress((PVOID)StartingAddress); + + /* This is the kind of VAD we expect right now */ + ASSERT(Vad); + ASSERT(Vad->EndingVpn >= (EndingAddress >> PAGE_SHIFT)); + ASSERT(Vad->u.VadFlags.PrivateMemory == 1); + ASSERT(Vad->u.VadFlags.NoChange == 0); + ASSERT(Vad->u.VadFlags.VadType == VadNone); + MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress); if (MemoryArea == NULL) {
Modified: trunk/reactos/ntoskrnl/mm/marea.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/marea.c?rev=558... ============================================================================== --- trunk/reactos/ntoskrnl/mm/marea.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/marea.c [iso-8859-1] Mon Feb 27 17:10:44 2012 @@ -373,6 +373,8 @@ PMEMORY_AREA Node; PMEMORY_AREA PreviousNode; ULONG Depth = 0; + PEPROCESS Process = MmGetAddressSpaceOwner(AddressSpace); + PETHREAD CurrentThread = PsGetCurrentThread();
/* Build a lame VAD if this is a user-space allocation */ if ((marea->EndingAddress < MmSystemRangeStart) && (marea->Type != MEMORY_AREA_OWNED_BY_ARM3)) @@ -400,8 +402,16 @@ Vad->u.VadFlags.Spare = 1; Vad->u.VadFlags.PrivateMemory = 1; Vad->u.VadFlags.Protection = MiMakeProtectionMask(marea->Protect); - MiInsertVad(Vad, MmGetAddressSpaceOwner(AddressSpace)); + + /* Pretend as if we own the working set */ + if (marea->Type == MEMORY_AREA_VIRTUAL_MEMORY) MiLockProcessWorkingSet(Process, CurrentThread); + + /* Insert the VAD */ + MiInsertVad(Vad, Process); marea->Vad = Vad; + + /* Release the working set */ + if (marea->Type == MEMORY_AREA_VIRTUAL_MEMORY) MiUnlockProcessWorkingSet(Process, CurrentThread); } else {
Modified: trunk/reactos/ntoskrnl/mm/rmap.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/rmap.c?rev=5588... ============================================================================== --- trunk/reactos/ntoskrnl/mm/rmap.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/mm/rmap.c [iso-8859-1] Mon Feb 27 17:10:44 2012 @@ -159,29 +159,8 @@ } else if (Type == MEMORY_AREA_VIRTUAL_MEMORY) { - PageOp = MmGetPageOp(MemoryArea, Address < MmSystemRangeStart ? Process->UniqueProcessId : NULL, - Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE); - if (PageOp == NULL) - { - MmUnlockAddressSpace(AddressSpace); - if (Address < MmSystemRangeStart) - { - ExReleaseRundownProtection(&Process->RundownProtect); - ObDereferenceObject(Process); - } - return(STATUS_UNSUCCESSFUL); - } - - /* - * Release locks now we have a page op. - */ - MmUnlockAddressSpace(AddressSpace); - - /* - * Do the actual page out work. - */ - Status = MmPageOutVirtualMemory(AddressSpace, MemoryArea, - Address, PageOp); + /* Do not page out virtual memory during ARM3 transition */ + Status = STATUS_SUCCESS; } else {