[NTOSKRNL]

- Use MI_IS_MAPPED_PTE instead of unportable bit fiddling
- Use MiDecrementPageTableReferences instead of manually messing with MmWorkingSetList, which is not portable
- Make MmGetPhysicalAddress portable

svn path=/trunk/; revision=61086
This commit is contained in:
Timo Kreuzer 2013-11-23 22:34:20 +00:00
parent f09cfef7f5
commit d059077864
5 changed files with 69 additions and 54 deletions

View file

@ -290,6 +290,15 @@ MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte,
ASSERT(MiProtoPteToPte(NewPte) == PointerPte);
}
FORCEINLINE
BOOLEAN
MI_IS_MAPPED_PTE(PMMPTE PointerPte)
{
/// FIXME
__debugbreak();
return (PointerPte->u.Long & 0xFFFFFC01 != 0);
}
VOID
FORCEINLINE
MmInitGlobalKernelPageDirectory(VOID)

View file

@ -950,6 +950,14 @@ MI_MAKE_SUBSECTION_PTE(IN PMMPTE NewPte,
NewPte->u.Subsect.SubsectionAddressHigh = (Offset & 0xFFFFF80) >> 7;
}
FORCEINLINE
BOOLEAN
MI_IS_MAPPED_PTE(PMMPTE PointerPte)
{
/// \todo Make this reasonable code, this is UGLY!
return ((PointerPte->u.Long & 0xFFFFFC01) != 0);
}
#endif
//

View file

@ -503,7 +503,6 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
KIRQL OldIrql;
BOOLEAN AddressGap = FALSE;
PSUBSECTION Subsection;
PUSHORT UsedPageTableEntries;
/* Get out if this is a fake VAD, RosMm will free the marea pages */
if ((Vad) && (Vad->u.VadFlags.Spare == 1)) return;
@ -560,7 +559,6 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
/* Now we should have a valid PDE, mapped in, and still have some VA */
ASSERT(PointerPde->u.Hard.Valid == 1);
ASSERT(Va <= EndingAddress);
UsedPageTableEntries = &MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Va)];
/* Check if this is a section VAD with gaps in it */
if ((AddressGap) && (LastPrototypePte))
@ -590,11 +588,10 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
TempPte = *PointerPte;
if (TempPte.u.Long)
{
*UsedPageTableEntries -= 1;
ASSERT((*UsedPageTableEntries) < PTE_COUNT);
MiDecrementPageTableReferences((PVOID)Va);
/* Check if the PTE is actually mapped in */
if (TempPte.u.Long & 0xFFFFFC01)
if (MI_IS_MAPPED_PTE(&TempPte))
{
/* Are we dealing with section VAD? */
if ((LastPrototypePte) && (PrototypePte > LastPrototypePte))
@ -652,7 +649,8 @@ MiDeleteVirtualAddresses(IN ULONG_PTR Va,
/* The PDE should still be valid at this point */
ASSERT(PointerPde->u.Hard.Valid == 1);
if (*UsedPageTableEntries == 0)
/* Check remaining PTE count (go back 1 page due to above loop) */
if (MiQueryPageTableReferences((PVOID)(Va - PAGE_SIZE)) == 0)
{
if (PointerPde->u.Long != 0)
{
@ -4078,7 +4076,7 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
Status = STATUS_CONFLICTING_ADDRESSES;
goto FailPath;
}
if ((AllocationType & MEM_RESET) == MEM_RESET)
{
/// @todo HACK: pretend success
@ -4253,6 +4251,7 @@ NtAllocateVirtualMemory(IN HANDLE ProcessHandle,
//
TempPte.u.Long = 0;
TempPte.u.Soft.Protection = ProtectionMask;
NT_ASSERT(TempPte.u.Long != 0);
//
// Get the PTE, PDE and the last PTE for this address range
@ -4832,4 +4831,50 @@ FailPath:
return Status;
}
PHYSICAL_ADDRESS
NTAPI
MmGetPhysicalAddress(PVOID Address)
{
PHYSICAL_ADDRESS PhysicalAddress;
MMPDE TempPde;
MMPTE TempPte;
/* Check if the PXE/PPE/PDE is valid */
if (
#if (_MI_PAGING_LEVELS == 4)
(MiAddressToPxe(Address)->u.Hard.Valid) &&
#endif
#if (_MI_PAGING_LEVELS >= 3)
(MiAddressToPpe(Address)->u.Hard.Valid) &&
#endif
(MiAddressToPde(Address)->u.Hard.Valid))
{
/* Check for large pages */
TempPde = *MiAddressToPde(Address);
if (TempPde.u.Hard.LargePage)
{
/* Physical address is base page + large page offset */
PhysicalAddress.QuadPart = TempPde.u.Hard.PageFrameNumber << PAGE_SHIFT;
PhysicalAddress.QuadPart += ((ULONG_PTR)Address & (PAGE_SIZE * PTE_PER_PAGE - 1));
return PhysicalAddress;
}
/* Check if the PTE is valid */
TempPte = *MiAddressToPte(Address);
if (TempPte.u.Hard.Valid)
{
/* Physical address is base page + page offset */
PhysicalAddress.QuadPart = TempPte.u.Hard.PageFrameNumber << PAGE_SHIFT;
PhysicalAddress.QuadPart += ((ULONG_PTR)Address & (PAGE_SIZE - 1));
return PhysicalAddress;
}
}
DPRINT1("MM:MmGetPhysicalAddressFailed base address was %p", Address);
PhysicalAddress.QuadPart = 0;
return PhysicalAddress;
}
/* EOF */

View file

@ -348,27 +348,6 @@ MmGetPfnForProcess(PEPROCESS Process,
return Pte.u.Hard.Valid ? Pte.u.Hard.PageFrameNumber : 0;
}
PHYSICAL_ADDRESS
NTAPI
MmGetPhysicalAddress(PVOID Address)
{
PHYSICAL_ADDRESS p;
MMPTE Pte;
Pte.u.Long = MiGetPteValueForProcess(NULL, Address);
if (Pte.u.Hard.Valid)
{
p.QuadPart = Pte.u.Hard.PageFrameNumber * PAGE_SIZE;
p.u.LowPart |= (ULONG_PTR)Address & (PAGE_SIZE - 1);
}
else
{
p.QuadPart = 0;
}
return p;
}
BOOLEAN
NTAPI
MmIsPagePresent(PEPROCESS Process, PVOID Address)

View file

@ -1004,32 +1004,6 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
MmUnmapPageTable(Pt);
}
/*
* @implemented
*/
PHYSICAL_ADDRESS NTAPI
MmGetPhysicalAddress(PVOID vaddr)
/*
* FUNCTION: Returns the physical address corresponding to a virtual address
*/
{
PHYSICAL_ADDRESS p;
ULONG Pte;
DPRINT("MmGetPhysicalAddress(vaddr %p)\n", vaddr);
Pte = MmGetPageEntryForProcess(NULL, vaddr);
if (Pte != 0 && (Pte & PA_PRESENT))
{
p.QuadPart = PAGE_MASK(Pte);
p.u.LowPart |= (ULONG_PTR)vaddr & (PAGE_SIZE - 1);
}
else
{
p.QuadPart = 0;
}
return p;
}
VOID
INIT_FUNCTION
NTAPI