2#include "pedigree/kernel/LockGuard.h"
3#include "pedigree/kernel/process/Process.h"
4#include "pedigree/kernel/process/Thread.h"
5#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
6#include "pedigree/kernel/processor/Processor.h"
7#include "pedigree/kernel/processor/ProcessorInformation.h"
13 FileResidencyAccess,
void*) {
18 FileResidencyAccess access,
void* credentials) {
25 if (displacement > ~
size_t(0) -
m_Offset)
27 const size_t offset =
m_Offset + displacement;
29 if (physical == ~physical_uintptr_t(0))
35void MemoryMappedFile::releaseDetachedPageUnlocked(uintptr_t oldAddress,
46 if (page.mapped && !borrowed)
51void MemoryMappedFile::releaseDetachedPage(uintptr_t oldAddress,
54 releaseDetachedPageUnlocked(oldAddress, page);
57void MemoryMappedFile::discardRange(
VirtualAddressSpace& space, uintptr_t base,
size_t length) {
59#if PEDIGREE_BENCHMARK_VM_DIAGNOSTICS
60 size_t trackedPages = 0, mappedPages = 0;
62 uintptr_t cursor = base;
64 physical_uintptr_t tracked = 0;
70#if PEDIGREE_BENCHMARK_VM_DIAGNOSTICS
75#if PEDIGREE_BENCHMARK_VM_DIAGNOSTICS
79 releaseDetachedPageUnlocked(
address, page);
81#if PEDIGREE_BENCHMARK_VM_DIAGNOSTICS
83 process->recordBenchmarkVmCounter(Process::VmDiscardTrackedPages, trackedPages);
84 process->recordBenchmarkVmCounter(Process::VmDiscardMappedPages, mappedPages);
88MemoryMapManager::VmStatus MemoryMapManager::residency(uintptr_t base,
size_t length,
89 unsigned char* kernelVector,
90 FileResidencyAccess access,
92 OperationGuard operation(*
this);
94 if ((base & (pageSize - 1)) || (length & (pageSize - 1)) || length > ~uintptr_t(0) - base)
95 return VmStatus::InvalidRange;
98 for (uintptr_t address = base; address < base + length; address += pageSize) {
101 for (
auto*
object : *objects) {
102 if (object->matches(address)) {
108 bool present =
false;
110 present = selected->resident(space, address, access, credentials);
111 else if (!(present = space.
isMapped(
reinterpret_cast<void*
>(address))))
112 return VmStatus::Unmapped;
113 kernelVector[(address - base) / pageSize] = present ? 1 : 0;
115 return VmStatus::Success;
118MemoryMapManager::VmStatus MemoryMapManager::discard(uintptr_t base,
size_t length) {
119 OperationGuard operation(*
this);
121 const size_t pageMask = pageSize - 1;
122 if ((base & pageMask) || (length & pageMask) || length > ~uintptr_t(0) - base)
123 return VmStatus::InvalidRange;
125 return VmStatus::Success;
127 return VmStatus::Unsupported;
130 if (hasLockedMemory(space, base, length))
131 return VmStatus::InvalidRange;
134 return VmStatus::Unmapped;
135 const uintptr_t end = base + length;
136 uintptr_t cursor = base;
137 while (cursor < end) {
139 uintptr_t selectedEnd = 0;
140 for (
auto*
object : *objects) {
141 const uintptr_t objectEnd = (
object->address() +
object->length() + pageMask) & ~pageMask;
142 if (object->address() <= cursor && cursor < objectEnd) {
144 selectedEnd = objectEnd;
149 return VmStatus::Unmapped;
150 if (selected->backingFile() && selected->backingFile()->isDirectPhysicalMapping())
151 return VmStatus::Unsupported;
152 cursor = selectedEnd < end ? selectedEnd : end;
154 for (
auto*
object : *objects) {
155 const uintptr_t objectEnd = (
object->address() +
object->length() + pageMask) & ~pageMask;
156 const uintptr_t first =
object->
address() > base ?
object->address() : base;
157 const uintptr_t last = objectEnd < end ? objectEnd : end;
159 object->discardRange(space, first, last - first);
161 return VmStatus::Success;
Memory-mapped file interface.
virtual physical_uintptr_t getPhysicalPage(size_t offset)
virtual void returnPhysicalPage(size_t offset)
Tree< VirtualAddressSpace *, MmObjectList * > m_MmObjectLists
Tree< uintptr_t, physical_uintptr_t > m_Mappings
void untrackMapping(uintptr_t)
physical_uintptr_t getMapping(uintptr_t)
uintptr_t address() const
static PhysicalMemoryManager & instance()
static constexpr size_t getPageSize() PURE
virtual void freePage(physical_uintptr_t page)=0
static ProcessorInformation & information()
bool contains(const K &key) const
bool lowerBound(const K &key, K &foundKey, E &foundValue) const
static const size_t Borrowed
virtual bool isMapped(void *virtualAddress)=0
virtual bool detachMapping(void *virtualAddress, physical_uintptr_t &physical, size_t &flags, size_t requiredFlags=0)