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
This commit is contained in:
Art Yerkes 2010-11-11 08:15:50 +00:00
parent 64e92d2d8e
commit 0cb645cb12
2 changed files with 45 additions and 4 deletions

View file

@ -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)

View file

@ -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;