mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 08:15:41 +00:00
[NTOSKRNL/MM]
- Some more cleanup. - Work with page rounded down addresses in SectionView page faults. - You should not create a virtual mapping on a non page-aligned address range : ASSERT about that. - Flush Tlb each time we change it - Fix logic I broke in MmCreateVirtualMapping (thanks to Thomas Faber) svn path=/trunk/; revision=54392
This commit is contained in:
parent
a9801fa996
commit
50632f02d1
2 changed files with 58 additions and 56 deletions
|
@ -284,37 +284,34 @@ MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
|
|||
PageDir = (PULONG)MiAddressToPde(Address);
|
||||
if (0 == InterlockedCompareExchangePte(PageDir, 0, 0))
|
||||
{
|
||||
if (Address >= MmSystemRangeStart)
|
||||
if (0 == InterlockedCompareExchangePte(&MmGlobalKernelPageDirectory[PdeOffset], 0, 0))
|
||||
{
|
||||
if (0 == InterlockedCompareExchangePte(&MmGlobalKernelPageDirectory[PdeOffset], 0, 0))
|
||||
if (Create == FALSE)
|
||||
{
|
||||
if (Create == FALSE)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
MI_SET_USAGE(MI_USAGE_LEGACY_PAGE_DIRECTORY);
|
||||
if (Process) MI_SET_PROCESS2(Process->ImageFileName);
|
||||
if (!Process) MI_SET_PROCESS2("Kernel Legacy");
|
||||
Status = MmRequestPageMemoryConsumer(MC_SYSTEM, FALSE, &Pfn);
|
||||
if (!NT_SUCCESS(Status) || Pfn == 0)
|
||||
{
|
||||
KeBugCheck(MEMORY_MANAGEMENT);
|
||||
}
|
||||
Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE;
|
||||
if(0 != InterlockedCompareExchangePte(&MmGlobalKernelPageDirectory[PdeOffset], Entry, 0))
|
||||
{
|
||||
MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
|
||||
}
|
||||
InterlockedExchangePte(PageDir, MmGlobalKernelPageDirectory[PdeOffset]);
|
||||
RtlZeroMemory(MiPteToAddress(PageDir), PAGE_SIZE);
|
||||
return (PULONG)MiAddressToPte(Address);
|
||||
return NULL;
|
||||
}
|
||||
MI_SET_USAGE(MI_USAGE_LEGACY_PAGE_DIRECTORY);
|
||||
if (Process) MI_SET_PROCESS2(Process->ImageFileName);
|
||||
if (!Process) MI_SET_PROCESS2("Kernel Legacy");
|
||||
Status = MmRequestPageMemoryConsumer(MC_SYSTEM, FALSE, &Pfn);
|
||||
if (!NT_SUCCESS(Status) || Pfn == 0)
|
||||
{
|
||||
KeBugCheck(MEMORY_MANAGEMENT);
|
||||
}
|
||||
Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE;
|
||||
if(0 != InterlockedCompareExchangePte(&MmGlobalKernelPageDirectory[PdeOffset], Entry, 0))
|
||||
{
|
||||
MmReleasePageMemoryConsumer(MC_SYSTEM, Pfn);
|
||||
}
|
||||
InterlockedExchangePte(PageDir, MmGlobalKernelPageDirectory[PdeOffset]);
|
||||
/* Flush it before accessing it */
|
||||
KeInvalidateTlbEntry(MiPteToAddress(PageDir));
|
||||
RtlZeroMemory(MiPteToAddress(PageDir), PAGE_SIZE);
|
||||
return (PULONG)MiAddressToPte(Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
InterlockedExchangePte(PageDir, MmGlobalKernelPageDirectory[PdeOffset]);
|
||||
/* Flush it before accessing it */
|
||||
KeInvalidateTlbEntry(MiPteToAddress(PageDir));
|
||||
}
|
||||
return (PULONG)MiAddressToPte(Address);
|
||||
}
|
||||
|
@ -700,15 +697,8 @@ MmCreatePageFileMapping(PEPROCESS Process,
|
|||
}
|
||||
Pte = *Pt;
|
||||
InterlockedExchangePte(Pt, SwapEntry << 1);
|
||||
if (Pte != 0)
|
||||
{
|
||||
MiFlushTlb(Pt, Address);
|
||||
}
|
||||
else
|
||||
{
|
||||
MmUnmapPageTable(Pt);
|
||||
}
|
||||
|
||||
MiFlushTlb(Pt, Address);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -729,6 +719,8 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
|||
ULONG Pte;
|
||||
DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
|
||||
Process, Address, flProtect, Pages, *Pages, PageCount);
|
||||
|
||||
ASSERT(((ULONG_PTR)Address % PAGE_SIZE) == 0);
|
||||
|
||||
if (Process == NULL)
|
||||
{
|
||||
|
@ -772,6 +764,8 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
|||
}
|
||||
|
||||
Addr = Address;
|
||||
/* MmGetPageTableForProcess should be called on the first run, so
|
||||
* let this trigger it */
|
||||
oldPdeOffset = ADDR_TO_PDE_OFFSET(Addr) + 1;
|
||||
for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
|
||||
{
|
||||
|
@ -785,6 +779,7 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
|||
PdeOffset = ADDR_TO_PDE_OFFSET(Addr);
|
||||
if (oldPdeOffset != PdeOffset)
|
||||
{
|
||||
if(Pt) MmUnmapPageTable(Pt);
|
||||
Pt = MmGetPageTableForProcess(Process, Addr, TRUE);
|
||||
if (Pt == NULL)
|
||||
{
|
||||
|
@ -805,9 +800,19 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
|||
KeBugCheck(MEMORY_MANAGEMENT);
|
||||
}
|
||||
InterlockedExchangePte(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
|
||||
MiFlushTlb(Pt, Addr);
|
||||
/* flush if currently mapped, just continue editing if hyperspace
|
||||
* NOTE : Do not call MiFlushTlb, as it will unmap the page table,
|
||||
* and we might need it afterwards */
|
||||
if (Address > MmSystemRangeStart ||
|
||||
(Pt >= (PULONG)PAGETABLE_MAP && Pt < (PULONG)PAGETABLE_MAP + 1024*1024))
|
||||
{
|
||||
KeInvalidateTlbEntry(Addr);
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(Addr > Address);
|
||||
MmUnmapPageTable(Pt);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -1314,7 +1314,6 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
ULONG Offset;
|
||||
PFN_NUMBER Page;
|
||||
NTSTATUS Status;
|
||||
PVOID PAddress;
|
||||
PROS_SECTION_OBJECT Section;
|
||||
PMM_SECTION_SEGMENT Segment;
|
||||
ULONG_PTR Entry;
|
||||
|
@ -1343,8 +1342,8 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
|
||||
Offset = (ULONG)((ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
|
||||
Address = MM_ROUND_DOWN(Address, PAGE_SIZE);
|
||||
Offset = (ULONG)((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
|
||||
+ MemoryArea->Data.SectionData.ViewOffset);
|
||||
|
||||
Segment = MemoryArea->Data.SectionData.Segment;
|
||||
|
@ -1432,7 +1431,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
if (!MmIsPagePresent(Process, Address))
|
||||
{
|
||||
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
|
||||
HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
|
||||
HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)Address);
|
||||
|
||||
if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry)
|
||||
{
|
||||
|
@ -1461,7 +1460,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
DPRINT1("Unable to create virtual mapping\n");
|
||||
KeBugCheck(MEMORY_MANAGEMENT);
|
||||
}
|
||||
MmInsertRmap(Page, Process, (PVOID)PAddress);
|
||||
MmInsertRmap(Page, Process, Address);
|
||||
}
|
||||
MmUnlockSectionSegment(Segment);
|
||||
PageOp->Status = STATUS_SUCCESS;
|
||||
|
@ -1470,7 +1469,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
HasSwapEntry = MmIsPageSwapEntry(Process, (PVOID)PAddress);
|
||||
HasSwapEntry = MmIsPageSwapEntry(Process, Address);
|
||||
if (HasSwapEntry)
|
||||
{
|
||||
/*
|
||||
|
@ -1488,7 +1487,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
}
|
||||
|
||||
MmUnlockSectionSegment(Segment);
|
||||
MmDeletePageFileMapping(Process, (PVOID)PAddress, &SwapEntry);
|
||||
MmDeletePageFileMapping(Process, Address, &SwapEntry);
|
||||
|
||||
MmUnlockAddressSpace(AddressSpace);
|
||||
MI_SET_USAGE(MI_USAGE_SECTION);
|
||||
|
@ -1527,8 +1526,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
/*
|
||||
* Add the page to the process's working set
|
||||
*/
|
||||
MmInsertRmap(Page, Process, (PVOID)PAddress);
|
||||
|
||||
MmInsertRmap(Page, Process, Address);
|
||||
/*
|
||||
* Finish the operation
|
||||
*/
|
||||
|
@ -1600,7 +1598,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
KeBugCheck(MEMORY_MANAGEMENT);
|
||||
return(Status);
|
||||
}
|
||||
MmInsertRmap(Page, Process, (PVOID)PAddress);
|
||||
MmInsertRmap(Page, Process, Address);
|
||||
|
||||
/*
|
||||
* Cleanup and release locks
|
||||
|
@ -1699,7 +1697,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
DPRINT1("Unable to create virtual mapping\n");
|
||||
KeBugCheck(MEMORY_MANAGEMENT);
|
||||
}
|
||||
MmInsertRmap(Page, Process, (PVOID)PAddress);
|
||||
MmInsertRmap(Page, Process, Address);
|
||||
|
||||
PageOp->Status = STATUS_SUCCESS;
|
||||
MmspCompleteAndReleasePageOp(PageOp);
|
||||
|
@ -1772,7 +1770,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
DPRINT1("Unable to create virtual mapping\n");
|
||||
KeBugCheck(MEMORY_MANAGEMENT);
|
||||
}
|
||||
MmInsertRmap(Page, Process, (PVOID)PAddress);
|
||||
MmInsertRmap(Page, Process, Address);
|
||||
PageOp->Status = STATUS_SUCCESS;
|
||||
MmspCompleteAndReleasePageOp(PageOp);
|
||||
DPRINT("Address 0x%.8X\n", Address);
|
||||
|
@ -1800,7 +1798,7 @@ MmNotPresentFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
DPRINT1("Unable to create virtual mapping\n");
|
||||
KeBugCheck(MEMORY_MANAGEMENT);
|
||||
}
|
||||
MmInsertRmap(Page, Process, (PVOID)PAddress);
|
||||
MmInsertRmap(Page, Process, Address);
|
||||
PageOp->Status = STATUS_SUCCESS;
|
||||
MmspCompleteAndReleasePageOp(PageOp);
|
||||
DPRINT("Address 0x%.8X\n", Address);
|
||||
|
@ -1819,7 +1817,6 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
PFN_NUMBER OldPage;
|
||||
PFN_NUMBER NewPage;
|
||||
NTSTATUS Status;
|
||||
PVOID PAddress;
|
||||
ULONG Offset;
|
||||
PMM_PAGEOP PageOp;
|
||||
PMM_REGION Region;
|
||||
|
@ -1840,8 +1837,8 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
/*
|
||||
* Find the offset of the page
|
||||
*/
|
||||
PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
|
||||
Offset = (ULONG)((ULONG_PTR)PAddress - (ULONG_PTR)MemoryArea->StartingAddress
|
||||
Address = MM_ROUND_DOWN(Address, PAGE_SIZE);
|
||||
Offset = (ULONG)((ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
|
||||
+ MemoryArea->Data.SectionData.ViewOffset);
|
||||
|
||||
Segment = MemoryArea->Data.SectionData.Segment;
|
||||
|
@ -1874,7 +1871,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
PFN_FROM_SSE(Entry) != OldPage)
|
||||
{
|
||||
/* This is a private page. We must only change the page protection. */
|
||||
MmSetPageProtect(Process, PAddress, Region->Protect);
|
||||
MmSetPageProtect(Process, Address, Region->Protect);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -1938,7 +1935,7 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
/*
|
||||
* Copy the old page
|
||||
*/
|
||||
MiCopyFromUserPage(NewPage, PAddress);
|
||||
MiCopyFromUserPage(NewPage, Address);
|
||||
|
||||
MmLockAddressSpace(AddressSpace);
|
||||
/*
|
||||
|
@ -1969,8 +1966,8 @@ MmAccessFaultSectionView(PMMSUPPORT AddressSpace,
|
|||
/*
|
||||
* Unshare the old page.
|
||||
*/
|
||||
MmDeleteRmap(OldPage, Process, PAddress);
|
||||
MmInsertRmap(NewPage, Process, PAddress);
|
||||
MmDeleteRmap(OldPage, Process, Address);
|
||||
MmInsertRmap(NewPage, Process, Address);
|
||||
MmLockSectionSegment(Segment);
|
||||
MmUnsharePageEntrySectionSegment(Section, Segment, Offset, FALSE, FALSE);
|
||||
MmUnlockSectionSegment(Segment);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue