From 0cb645cb12a6bbd1c7f25cc649f7fe19245fa259 Mon Sep 17 00:00:00 2001 From: Art Yerkes Date: Thu, 11 Nov 2010 08:15:50 +0000 Subject: [PATCH] Part 1 of fixes: For some reason beyond me, I had abbreviated MiCowSectionPage to always assume CoW rather than always not CoW for cache sections. Make sure we're looking for cache type sections rather than (as we were in the branch) data file sections. More needed. svn path=/trunk/; revision=49555 --- reactos/ntoskrnl/cache/section/data.c | 9 ++++-- reactos/ntoskrnl/cache/section/fault.c | 40 +++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/reactos/ntoskrnl/cache/section/data.c b/reactos/ntoskrnl/cache/section/data.c index 89cdf74c5de..4e2d81bcc32 100644 --- a/reactos/ntoskrnl/cache/section/data.c +++ b/reactos/ntoskrnl/cache/section/data.c @@ -107,7 +107,7 @@ MiZeroFillSection PMEMORY_AREA MemoryArea; PMM_CACHE_SECTION_SEGMENT Segment; LARGE_INTEGER FileOffset = *FileOffsetPtr, End, FirstMapped; - DPRINT1("MiZeroFillSection(Address %x,Offset %x,Length %x)\n", Address, FileOffset.LowPart, Length); + DPRINT("MiZeroFillSection(Address %x,Offset %x,Length %x)\n", Address, FileOffset.LowPart, Length); AddressSpace = MmGetKernelAddressSpace(); MmLockAddressSpace(AddressSpace); MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address); @@ -178,13 +178,14 @@ _MiFlushMappedSection PFN_NUMBER Page; PPFN_NUMBER Pages; - DPRINT1("MiFlushMappedSection(%x,%08x,%x,%d,%s:%d)\n", BaseAddress, BaseOffset->LowPart, FileSize, WriteData, File, Line); + DPRINT("MiFlushMappedSection(%x,%08x,%x,%d,%s:%d)\n", BaseAddress, BaseOffset->LowPart, FileSize, WriteData, File, Line); MmLockAddressSpace(AddressSpace); MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, BaseAddress); - if (!MemoryArea || MemoryArea->Type != MEMORY_AREA_SECTION_VIEW) + if (!MemoryArea || MemoryArea->Type != MEMORY_AREA_CACHE) { MmUnlockAddressSpace(AddressSpace); + DPRINT("STATUS_NOT_MAPPED_DATA\n"); return STATUS_NOT_MAPPED_DATA; } BeginningAddress = PAGE_ROUND_DOWN((ULONG_PTR)MemoryArea->StartingAddress); @@ -206,6 +207,8 @@ _MiFlushMappedSection ASSERT(FALSE); } + DPRINT("Getting pages in range %08x-%08x\n", BeginningAddress, EndingAddress); + for (PageAddress = BeginningAddress; PageAddress < EndingAddress; PageAddress += PAGE_SIZE) diff --git a/reactos/ntoskrnl/cache/section/fault.c b/reactos/ntoskrnl/cache/section/fault.c index 81d6a0171e2..204c264b579 100644 --- a/reactos/ntoskrnl/cache/section/fault.c +++ b/reactos/ntoskrnl/cache/section/fault.c @@ -247,7 +247,7 @@ MiCowCacheSectionPage * Lock the segment */ MmLockCacheSectionSegment(Segment); - + /* * Find the offset of the page */ @@ -255,6 +255,44 @@ MiCowCacheSectionPage Offset.QuadPart = (ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress + MemoryArea->Data.CacheData.ViewOffset.QuadPart; +#if 0 // XXX Cache sections are not CoW. For now, treat all access violations this way. + if ((!Segment->WriteCopy && + !MemoryArea->Data.CacheData.WriteCopyView) || + Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED) +#endif + { +#if 0 // XXX Cache sections don't have regions at present, which streamlines things + if (Region->Protect == PAGE_READWRITE || + Region->Protect == PAGE_EXECUTE_READWRITE) +#endif + { + DPRINTC("setting non-cow page %x %x:%x offset %x (%x) to writable\n", Segment, Process, PAddress, Offset.u.LowPart, MmGetPfnForProcess(Process, Address)); + if (Segment->FileObject) + { + DPRINTC("file %wZ\n", &Segment->FileObject->FileName); + } + ULONG Entry = MiGetPageEntryCacheSectionSegment(Segment, &Offset); + DPRINT("Entry %x\n", Entry); + if (Entry && + !IS_SWAP_FROM_SSE(Entry) && + PFN_FROM_SSE(Entry) == MmGetPfnForProcess(Process, Address)) { + MiSetPageEntryCacheSectionSegment(Segment, &Offset, DIRTY_SSE(Entry)); + } + MmSetPageProtect(Process, PAddress, PAGE_READWRITE); + MmUnlockCacheSectionSegment(Segment); + DPRINT("Done\n"); + return STATUS_SUCCESS; + } +#if 0 + else + { + DPRINT("Not supposed to be writable\n"); + MmUnlockCacheSectionSegment(Segment); + return STATUS_ACCESS_VIOLATION; + } +#endif + } + if (!Required->Page[0]) { SWAPENTRY SwapEntry;