mirror of
https://github.com/reactos/reactos.git
synced 2025-05-04 18:31:40 +00:00
[NTOS:MM] Rewrite arch-specifics of the legacy Mm
Properly handle PDE refcounting Clean-up of the internal API Enforce attaching to the process when modifying its memory layout, instead of making circonvoluted mappings which always end up being broken.
This commit is contained in:
parent
b445005c70
commit
43378411fb
5 changed files with 474 additions and 572 deletions
|
@ -1034,8 +1034,7 @@ MmCreateVirtualMapping(
|
|||
struct _EPROCESS* Process,
|
||||
PVOID Address,
|
||||
ULONG flProtect,
|
||||
PPFN_NUMBER Pages,
|
||||
ULONG PageCount
|
||||
PFN_NUMBER Page
|
||||
);
|
||||
|
||||
NTSTATUS
|
||||
|
@ -1044,8 +1043,7 @@ MmCreateVirtualMappingUnsafe(
|
|||
struct _EPROCESS* Process,
|
||||
PVOID Address,
|
||||
ULONG flProtect,
|
||||
PPFN_NUMBER Pages,
|
||||
ULONG PageCount
|
||||
PFN_NUMBER Page
|
||||
);
|
||||
|
||||
ULONG
|
||||
|
@ -1080,13 +1078,6 @@ VOID
|
|||
NTAPI
|
||||
MmInitGlobalKernelPageDirectory(VOID);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmGetPageFileMapping(
|
||||
struct _EPROCESS *Process,
|
||||
PVOID Address,
|
||||
SWAPENTRY* SwapEntry);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmDeletePageFileMapping(
|
||||
|
@ -1103,6 +1094,13 @@ MmCreatePageFileMapping(
|
|||
SWAPENTRY SwapEntry
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmGetPageFileMapping(
|
||||
PEPROCESS Process,
|
||||
PVOID Address,
|
||||
SWAPENTRY *SwapEntry);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
MmIsPageSwapEntry(
|
||||
|
@ -1110,13 +1108,6 @@ MmIsPageSwapEntry(
|
|||
PVOID Address
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmSetDirtyPage(
|
||||
struct _EPROCESS *Process,
|
||||
PVOID Address
|
||||
);
|
||||
|
||||
PFN_NUMBER
|
||||
NTAPI
|
||||
MmAllocPage(
|
||||
|
@ -1156,6 +1147,12 @@ MmSetCleanPage(
|
|||
PVOID Address
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmSetDirtyBit(PEPROCESS Process, PVOID Address, BOOLEAN Bit);
|
||||
#define MmSetCleanPage(__P, __A) MmSetDirtyBit(__P, __A, FALSE)
|
||||
#define MmSetDirtyPage(__P, __A) MmSetDirtyBit(__P, __A, TRUE)
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmDeletePageTable(
|
||||
|
@ -1208,21 +1205,6 @@ MmDeleteVirtualMapping(
|
|||
PPFN_NUMBER Page
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
MmIsDirtyPage(
|
||||
struct _EPROCESS *Process,
|
||||
PVOID Address
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmClearPageAccessedBit(PEPROCESS Process, PVOID Address);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
MmIsPageAccessed(PEPROCESS Process, PVOID Address);
|
||||
|
||||
/* wset.c ********************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -328,24 +328,6 @@ MmFreeMemoryArea(
|
|||
FreePage(FreePageContext, MemoryArea, (PVOID)Address,
|
||||
Page, SwapEntry, (BOOLEAN)Dirty);
|
||||
}
|
||||
#if (_MI_PAGING_LEVELS == 2)
|
||||
/* Remove page table reference */
|
||||
ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
|
||||
if ((SwapEntry || Page) && ((PVOID)Address < MmSystemRangeStart))
|
||||
{
|
||||
ASSERT(AddressSpace != MmGetKernelAddressSpace());
|
||||
if (MiQueryPageTableReferences((PVOID)Address) == 0)
|
||||
{
|
||||
/* No PTE relies on this PDE. Release it */
|
||||
KIRQL OldIrql = MiAcquirePfnLock();
|
||||
PMMPDE PointerPde = MiAddressToPde(Address);
|
||||
ASSERT(PointerPde->u.Hard.Valid == 1);
|
||||
MiDeletePte(PointerPde, MiPdeToPte(PointerPde), Process, NULL);
|
||||
ASSERT(PointerPde->u.Hard.Valid == 0);
|
||||
MiReleasePfnLock(OldIrql);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (Process != NULL &&
|
||||
|
|
|
@ -102,18 +102,26 @@ GetEntry:
|
|||
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
|
||||
if (MmGetPfnForProcess(Process, Address) != Page)
|
||||
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
|
||||
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
|
||||
{
|
||||
/* This changed in the short window where we didn't have any locks */
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||
ObDereferenceObject(Process);
|
||||
goto GetEntry;
|
||||
}
|
||||
|
||||
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
|
||||
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
|
||||
|
||||
/* Attach to it, if needed */
|
||||
ASSERT(PsGetCurrentProcess() == PsInitialSystemProcess);
|
||||
if (Process != PsInitialSystemProcess)
|
||||
KeAttachProcess(&Process->Pcb);
|
||||
|
||||
if (MmGetPfnForProcess(Process, Address) != Page)
|
||||
{
|
||||
/* This changed in the short window where we didn't have any locks */
|
||||
if (Process != PsInitialSystemProcess)
|
||||
KeDetachProcess();
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||
ObDereferenceObject(Process);
|
||||
|
@ -140,6 +148,8 @@ GetEntry:
|
|||
{
|
||||
/* The segment is being read or something. Give up */
|
||||
MmUnlockSectionSegment(Segment);
|
||||
if (Process != PsInitialSystemProcess)
|
||||
KeDetachProcess();
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||
ObDereferenceObject(Process);
|
||||
|
@ -160,11 +170,6 @@ GetEntry:
|
|||
/* This page is private to the process */
|
||||
MmUnlockSectionSegment(Segment);
|
||||
|
||||
/* Attach to it, if needed */
|
||||
ASSERT(PsGetCurrentProcess() == PsInitialSystemProcess);
|
||||
if (Process != PsInitialSystemProcess)
|
||||
KeAttachProcess(&Process->Pcb);
|
||||
|
||||
/* Check if we should write it back to the page file */
|
||||
SwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||
|
||||
|
@ -179,7 +184,7 @@ GetEntry:
|
|||
Address, NULL);
|
||||
|
||||
/* We can't, so let this page in the Process VM */
|
||||
MmCreateVirtualMapping(Process, Address, Region->Protect, &Page, 1);
|
||||
MmCreateVirtualMapping(Process, Address, Region->Protect, Page);
|
||||
MmInsertRmap(Page, Process, Address);
|
||||
MmSetDirtyPage(Process, Address);
|
||||
|
||||
|
@ -219,7 +224,7 @@ GetEntry:
|
|||
MmFreeSwapPage(SwapEntry);
|
||||
|
||||
/* We can't, so let this page in the Process VM */
|
||||
MmCreateVirtualMapping(Process, Address, Region->Protect, &Page, 1);
|
||||
MmCreateVirtualMapping(Process, Address, Region->Protect, Page);
|
||||
MmInsertRmap(Page, Process, Address);
|
||||
MmSetDirtyPage(Process, Address);
|
||||
|
||||
|
@ -241,7 +246,6 @@ GetEntry:
|
|||
}
|
||||
|
||||
/* We can finally let this page go */
|
||||
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
if (Process != PsInitialSystemProcess)
|
||||
KeDetachProcess();
|
||||
|
@ -262,6 +266,8 @@ GetEntry:
|
|||
Released = MmUnsharePageEntrySectionSegment(MemoryArea, Segment, &Offset, Dirty, TRUE, NULL);
|
||||
|
||||
MmUnlockSectionSegment(Segment);
|
||||
if (Process != PsInitialSystemProcess)
|
||||
KeDetachProcess();
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
|
||||
ExReleaseRundownProtection(&Process->RundownProtect);
|
||||
|
|
|
@ -1636,8 +1636,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
Status = MmCreateVirtualMapping(Process,
|
||||
PAddress,
|
||||
Region->Protect,
|
||||
&Page,
|
||||
1);
|
||||
Page);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
|
||||
|
@ -1679,8 +1678,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
Status = MmCreateVirtualMappingUnsafe(Process,
|
||||
PAddress,
|
||||
Region->Protect,
|
||||
&Page,
|
||||
1);
|
||||
Page);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("MmCreateVirtualMappingUnsafe failed, not out of memory\n");
|
||||
|
@ -1729,7 +1727,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
MmSetPageEntrySectionSegment(Segment, &Offset, MAKE_SSE(Page << PAGE_SHIFT, 1));
|
||||
MmUnlockSectionSegment(Segment);
|
||||
|
||||
Status = MmCreateVirtualMapping(Process, PAddress, Attributes, &Page, 1);
|
||||
Status = MmCreateVirtualMapping(Process, PAddress, Attributes, Page);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Unable to create virtual mapping\n");
|
||||
|
@ -1828,8 +1826,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
Status = MmCreateVirtualMapping(Process,
|
||||
PAddress,
|
||||
Attributes,
|
||||
&Page,
|
||||
1);
|
||||
Page);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Unable to create virtual mapping\n");
|
||||
|
@ -1857,8 +1854,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
Status = MmCreateVirtualMapping(Process,
|
||||
PAddress,
|
||||
Attributes,
|
||||
&Page,
|
||||
1);
|
||||
Page);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Unable to create virtual mapping\n");
|
||||
|
@ -1985,8 +1981,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
Status = MmCreateVirtualMapping(Process,
|
||||
PAddress,
|
||||
Region->Protect,
|
||||
&NewPage,
|
||||
1);
|
||||
NewPage);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("MmCreateVirtualMapping failed, unable to create virtual mapping, not out of memory\n");
|
||||
|
|
Loading…
Reference in a new issue