mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 17:45:41 +00:00
- Lock always the address space if we changing the virtual mapping.
This is necessary because we can create or remove a page table. - If we unmap a section, we have to wait for all pending pageops for the section within the current process. We do this by waiting for all pageops for the section. svn path=/trunk/; revision=18849
This commit is contained in:
parent
470db6b8eb
commit
5e158693d9
1 changed files with 65 additions and 7 deletions
|
@ -1278,6 +1278,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
MiCopyFromUserPage(NewPage, PAddress);
|
MiCopyFromUserPage(NewPage, PAddress);
|
||||||
|
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
/*
|
/*
|
||||||
* Delete the old entry.
|
* Delete the old entry.
|
||||||
*/
|
*/
|
||||||
|
@ -1286,7 +1287,6 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Set the PTE to point to the new page
|
* Set the PTE to point to the new page
|
||||||
*/
|
*/
|
||||||
MmLockAddressSpace(AddressSpace);
|
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
||||||
Address,
|
Address,
|
||||||
Region->Protect,
|
Region->Protect,
|
||||||
|
@ -1298,7 +1298,6 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
MmInsertRmap(NewPage, AddressSpace->Process, PAddress);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
@ -1314,6 +1313,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* Unshare the old page.
|
* Unshare the old page.
|
||||||
*/
|
*/
|
||||||
MmDeleteRmap(OldPage, AddressSpace->Process, PAddress);
|
MmDeleteRmap(OldPage, AddressSpace->Process, PAddress);
|
||||||
|
MmInsertRmap(NewPage, AddressSpace->Process, PAddress);
|
||||||
MmLockSectionSegment(Segment);
|
MmLockSectionSegment(Segment);
|
||||||
MmUnsharePageEntrySectionSegment(Section, Segment, Offset, FALSE, FALSE);
|
MmUnsharePageEntrySectionSegment(Section, Segment, Offset, FALSE, FALSE);
|
||||||
MmUnlockSectionSegment(Segment);
|
MmUnlockSectionSegment(Segment);
|
||||||
|
@ -1332,6 +1332,11 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
|
||||||
PFN_TYPE Page;
|
PFN_TYPE Page;
|
||||||
|
|
||||||
PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
|
PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
|
||||||
|
if (Process)
|
||||||
|
{
|
||||||
|
MmLockAddressSpace(&Process->AddressSpace);
|
||||||
|
}
|
||||||
|
|
||||||
MmDeleteVirtualMapping(Process,
|
MmDeleteVirtualMapping(Process,
|
||||||
Address,
|
Address,
|
||||||
FALSE,
|
FALSE,
|
||||||
|
@ -1343,13 +1348,20 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
|
||||||
}
|
}
|
||||||
if (!PageOutContext->Private)
|
if (!PageOutContext->Private)
|
||||||
{
|
{
|
||||||
|
MmLockSectionSegment(PageOutContext->Segment);
|
||||||
MmUnsharePageEntrySectionSegment(PageOutContext->Section,
|
MmUnsharePageEntrySectionSegment(PageOutContext->Section,
|
||||||
PageOutContext->Segment,
|
PageOutContext->Segment,
|
||||||
PageOutContext->Offset,
|
PageOutContext->Offset,
|
||||||
PageOutContext->WasDirty,
|
PageOutContext->WasDirty,
|
||||||
TRUE);
|
TRUE);
|
||||||
|
MmUnlockSectionSegment(PageOutContext->Segment);
|
||||||
}
|
}
|
||||||
else
|
if (Process)
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(&Process->AddressSpace);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PageOutContext->Private)
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_USER, Page);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
}
|
}
|
||||||
|
@ -1561,9 +1573,11 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
else if (!Context.WasDirty && Context.Private && SwapEntry != 0)
|
else if (!Context.WasDirty && Context.Private && SwapEntry != 0)
|
||||||
{
|
{
|
||||||
MmSetSavedSwapEntryPage(Page, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
Status = MmCreatePageFileMapping(AddressSpace->Process,
|
Status = MmCreatePageFileMapping(AddressSpace->Process,
|
||||||
Address,
|
Address,
|
||||||
SwapEntry);
|
SwapEntry);
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
|
@ -1583,7 +1597,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
if (SwapEntry == 0)
|
if (SwapEntry == 0)
|
||||||
{
|
{
|
||||||
MmShowOutOfSpaceMessagePagingFile();
|
MmShowOutOfSpaceMessagePagingFile();
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
/*
|
/*
|
||||||
* For private pages restore the old mappings.
|
* For private pages restore the old mappings.
|
||||||
*/
|
*/
|
||||||
|
@ -1618,6 +1632,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
|
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
|
||||||
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
|
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
|
||||||
}
|
}
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
MmspCompleteAndReleasePageOp(PageOp);
|
MmspCompleteAndReleasePageOp(PageOp);
|
||||||
return(STATUS_PAGEFILE_QUOTA);
|
return(STATUS_PAGEFILE_QUOTA);
|
||||||
|
@ -1636,6 +1651,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* As above: undo our actions.
|
* As above: undo our actions.
|
||||||
* FIXME: Also free the swap page.
|
* FIXME: Also free the swap page.
|
||||||
*/
|
*/
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
if (Context.Private)
|
if (Context.Private)
|
||||||
{
|
{
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
||||||
|
@ -1662,6 +1678,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
|
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
|
||||||
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
|
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
|
||||||
}
|
}
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
MmspCompleteAndReleasePageOp(PageOp);
|
MmspCompleteAndReleasePageOp(PageOp);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
@ -1684,9 +1701,11 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
|
|
||||||
if (Context.Private)
|
if (Context.Private)
|
||||||
{
|
{
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
Status = MmCreatePageFileMapping(AddressSpace->Process,
|
Status = MmCreatePageFileMapping(AddressSpace->Process,
|
||||||
Address,
|
Address,
|
||||||
SwapEntry);
|
SwapEntry);
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
|
@ -3797,7 +3816,7 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
STATIC NTSTATUS
|
||||||
MmUnmapViewOfSegment(PMADDRESS_SPACE AddressSpace,
|
MmUnmapViewOfSegment(PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID BaseAddress)
|
PVOID BaseAddress)
|
||||||
{
|
{
|
||||||
|
@ -3860,6 +3879,8 @@ MmUnmapViewOfSection(PEPROCESS Process,
|
||||||
PMEMORY_AREA MemoryArea;
|
PMEMORY_AREA MemoryArea;
|
||||||
PMADDRESS_SPACE AddressSpace;
|
PMADDRESS_SPACE AddressSpace;
|
||||||
PSECTION_OBJECT Section;
|
PSECTION_OBJECT Section;
|
||||||
|
PMM_PAGEOP PageOp;
|
||||||
|
ULONG_PTR Offset;
|
||||||
|
|
||||||
DPRINT("Opening memory area Process %x BaseAddress %x\n",
|
DPRINT("Opening memory area Process %x BaseAddress %x\n",
|
||||||
Process, BaseAddress);
|
Process, BaseAddress);
|
||||||
|
@ -3867,15 +3888,53 @@ MmUnmapViewOfSection(PEPROCESS Process,
|
||||||
ASSERT(Process);
|
ASSERT(Process);
|
||||||
|
|
||||||
AddressSpace = &Process->AddressSpace;
|
AddressSpace = &Process->AddressSpace;
|
||||||
|
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
|
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
|
||||||
BaseAddress);
|
BaseAddress);
|
||||||
if (MemoryArea == NULL ||
|
if (MemoryArea == NULL ||
|
||||||
MemoryArea->Type != MEMORY_AREA_SECTION_VIEW ||
|
MemoryArea->Type != MEMORY_AREA_SECTION_VIEW ||
|
||||||
MemoryArea->DeleteInProgress)
|
MemoryArea->DeleteInProgress)
|
||||||
{
|
{
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
return STATUS_NOT_MAPPED_VIEW;
|
return STATUS_NOT_MAPPED_VIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemoryArea->DeleteInProgress = TRUE;
|
||||||
|
|
||||||
|
while (MemoryArea->PageOpCount)
|
||||||
|
{
|
||||||
|
Offset = PAGE_ROUND_UP((ULONG_PTR)MemoryArea->EndingAddress - (ULONG_PTR)MemoryArea->StartingAddress);
|
||||||
|
|
||||||
|
while (Offset)
|
||||||
|
{
|
||||||
|
Offset -= PAGE_SIZE;
|
||||||
|
PageOp = MmCheckForPageOp(MemoryArea, NULL, NULL,
|
||||||
|
MemoryArea->Data.SectionData.Segment,
|
||||||
|
Offset + MemoryArea->Data.SectionData.ViewOffset);
|
||||||
|
if (PageOp)
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
Status = MmspWaitForPageOpCompletionEvent(PageOp);
|
||||||
|
if (Status != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to wait for page op, status = %x\n", Status);
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
MmLockAddressSpace(AddressSpace);
|
||||||
|
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace,
|
||||||
|
BaseAddress);
|
||||||
|
if (MemoryArea == NULL ||
|
||||||
|
MemoryArea->Type != MEMORY_AREA_SECTION_VIEW)
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
return STATUS_NOT_MAPPED_VIEW;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Section = MemoryArea->Data.SectionData.Section;
|
Section = MemoryArea->Data.SectionData.Section;
|
||||||
|
|
||||||
if (Section->AllocationAttributes & SEC_IMAGE)
|
if (Section->AllocationAttributes & SEC_IMAGE)
|
||||||
|
@ -3925,6 +3984,7 @@ MmUnmapViewOfSection(PEPROCESS Process,
|
||||||
{
|
{
|
||||||
Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
|
Status = MmUnmapViewOfSegment(AddressSpace, BaseAddress);
|
||||||
}
|
}
|
||||||
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3970,9 +4030,7 @@ NtUnmapViewOfSection (HANDLE ProcessHandle,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
MmLockAddressSpace(&Process->AddressSpace);
|
|
||||||
Status = MmUnmapViewOfSection(Process, BaseAddress);
|
Status = MmUnmapViewOfSection(Process, BaseAddress);
|
||||||
MmUnlockAddressSpace(&Process->AddressSpace);
|
|
||||||
|
|
||||||
ObDereferenceObject(Process);
|
ObDereferenceObject(Process);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue