mirror of
https://github.com/reactos/reactos.git
synced 2025-07-27 15:11:41 +00:00
[NTOS/MM] Introduce MmArePagesResident and MmMakePagesResident
This commit is contained in:
parent
f1631b44e1
commit
e4047d1521
2 changed files with 154 additions and 0 deletions
|
@ -1323,6 +1323,20 @@ MmMapViewInSystemSpaceEx (
|
||||||
_Inout_ PLARGE_INTEGER SectionOffset
|
_Inout_ PLARGE_INTEGER SectionOffset
|
||||||
);
|
);
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
MmArePagesResident(
|
||||||
|
_In_ PEPROCESS Process,
|
||||||
|
_In_ PVOID BaseAddress,
|
||||||
|
_In_ ULONG Length);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MmMakePagesResident(
|
||||||
|
_In_ PEPROCESS Process,
|
||||||
|
_In_ PVOID Address,
|
||||||
|
_In_ ULONG Length);
|
||||||
|
|
||||||
/* sysldr.c ******************************************************************/
|
/* sysldr.c ******************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -5076,4 +5076,144 @@ MmCreateSection (OUT PVOID * Section,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
MmArePagesResident(
|
||||||
|
_In_ PEPROCESS Process,
|
||||||
|
_In_ PVOID Address,
|
||||||
|
_In_ ULONG Length)
|
||||||
|
{
|
||||||
|
PMEMORY_AREA MemoryArea;
|
||||||
|
BOOLEAN Ret = TRUE;
|
||||||
|
PMM_SECTION_SEGMENT Segment;
|
||||||
|
LARGE_INTEGER SegmentOffset, RangeEnd;
|
||||||
|
|
||||||
|
MmLockAddressSpace(&Process->Vm);
|
||||||
|
|
||||||
|
MemoryArea = MmLocateMemoryAreaByAddress(&Process->Vm, Address);
|
||||||
|
if (MemoryArea == NULL)
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(&Process->Vm);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only supported in old Mm for now */
|
||||||
|
ASSERT(MemoryArea->Type == MEMORY_AREA_SECTION_VIEW);
|
||||||
|
/* For file mappings */
|
||||||
|
ASSERT(MemoryArea->VadNode.u.VadFlags.VadType != VadImageMap);
|
||||||
|
|
||||||
|
Segment = MemoryArea->SectionData.Segment;
|
||||||
|
MmLockSectionSegment(Segment);
|
||||||
|
|
||||||
|
SegmentOffset.QuadPart = PAGE_ROUND_DOWN(Address) - MA_GetStartingAddress(MemoryArea)
|
||||||
|
+ MemoryArea->SectionData.ViewOffset.QuadPart;
|
||||||
|
RangeEnd.QuadPart = PAGE_ROUND_UP((ULONG_PTR)Address + Length) - MA_GetStartingAddress(MemoryArea)
|
||||||
|
+ MemoryArea->SectionData.ViewOffset.QuadPart;
|
||||||
|
|
||||||
|
while (SegmentOffset.QuadPart < RangeEnd.QuadPart)
|
||||||
|
{
|
||||||
|
ULONG_PTR Entry = MmGetPageEntrySectionSegment(Segment, &SegmentOffset);
|
||||||
|
if ((Entry == 0) || IS_SWAP_FROM_SSE(Entry))
|
||||||
|
{
|
||||||
|
Ret = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SegmentOffset.QuadPart += PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmUnlockSectionSegment(Segment);
|
||||||
|
|
||||||
|
MmUnlockAddressSpace(&Process->Vm);
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
MmMakePagesResident(
|
||||||
|
_In_ PEPROCESS Process,
|
||||||
|
_In_ PVOID Address,
|
||||||
|
_In_ ULONG Length)
|
||||||
|
{
|
||||||
|
PMEMORY_AREA MemoryArea;
|
||||||
|
PMM_SECTION_SEGMENT Segment;
|
||||||
|
LARGE_INTEGER SegmentOffset, RangeEnd;
|
||||||
|
|
||||||
|
MmLockAddressSpace(&Process->Vm);
|
||||||
|
|
||||||
|
MemoryArea = MmLocateMemoryAreaByAddress(&Process->Vm, Address);
|
||||||
|
if (MemoryArea == NULL)
|
||||||
|
{
|
||||||
|
MmUnlockAddressSpace(&Process->Vm);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only supported in old Mm for now */
|
||||||
|
ASSERT(MemoryArea->Type == MEMORY_AREA_SECTION_VIEW);
|
||||||
|
/* For file mappings */
|
||||||
|
ASSERT(MemoryArea->VadNode.u.VadFlags.VadType != VadImageMap);
|
||||||
|
|
||||||
|
Segment = MemoryArea->SectionData.Segment;
|
||||||
|
MmLockSectionSegment(Segment);
|
||||||
|
|
||||||
|
SegmentOffset.QuadPart = PAGE_ROUND_DOWN(Address) - MA_GetStartingAddress(MemoryArea)
|
||||||
|
+ MemoryArea->SectionData.ViewOffset.QuadPart;
|
||||||
|
RangeEnd.QuadPart = PAGE_ROUND_UP((ULONG_PTR)Address + Length) - MA_GetStartingAddress(MemoryArea)
|
||||||
|
+ MemoryArea->SectionData.ViewOffset.QuadPart;
|
||||||
|
|
||||||
|
while (SegmentOffset.QuadPart < RangeEnd.QuadPart)
|
||||||
|
{
|
||||||
|
ULONG_PTR Entry = MmGetPageEntrySectionSegment(Segment, &SegmentOffset);
|
||||||
|
|
||||||
|
/* Let any pending read proceed */
|
||||||
|
while (MM_IS_WAIT_PTE(Entry))
|
||||||
|
{
|
||||||
|
MmUnlockSectionSegment(Segment);
|
||||||
|
MmUnlockAddressSpace(&Process->Vm);
|
||||||
|
MiWaitForPageEvent(NULL, NULL);
|
||||||
|
MmLockAddressSpace(&Process->Vm);
|
||||||
|
MmLockSectionSegment(Segment);
|
||||||
|
Entry = MmGetPageEntrySectionSegment(Segment, &SegmentOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We are called from Cc, this can't be backed by the page files */
|
||||||
|
ASSERT(!IS_SWAP_FROM_SSE(Entry));
|
||||||
|
|
||||||
|
/* At this point, there may be a valid page there */
|
||||||
|
if (Entry == 0)
|
||||||
|
{
|
||||||
|
PFN_NUMBER Page;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Release all our locks and read in the page from disk
|
||||||
|
*/
|
||||||
|
MmSetPageEntrySectionSegment(Segment, &SegmentOffset, MAKE_SWAP_SSE(MM_WAIT_ENTRY));
|
||||||
|
MmUnlockSectionSegment(Segment);
|
||||||
|
MmUnlockAddressSpace(&Process->Vm);
|
||||||
|
|
||||||
|
/* FIXME: Read the whole range at once instead of one page at a time */
|
||||||
|
Status = MiReadPage(MemoryArea, SegmentOffset.QuadPart, &Page);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Reset the Segment entry and fail */
|
||||||
|
MmLockSectionSegment(Segment);
|
||||||
|
MmSetPageEntrySectionSegment(Segment, &SegmentOffset, 0);
|
||||||
|
MmUnlockSectionSegment(Segment);
|
||||||
|
MiSetPageEvent(Process, Address);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmLockAddressSpace(&Process->Vm);
|
||||||
|
MmLockSectionSegment(Segment);
|
||||||
|
MmSetPageEntrySectionSegment(Segment, &SegmentOffset, MAKE_SSE(Page << PAGE_SHIFT, 1));
|
||||||
|
}
|
||||||
|
SegmentOffset.QuadPart += PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
MmUnlockSectionSegment(Segment);
|
||||||
|
|
||||||
|
MmUnlockAddressSpace(&Process->Vm);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue