20#ifndef KERNEL_PROCESSOR_X64_VIRTUALADDRESSSPACE_H
21#define KERNEL_PROCESSOR_X64_VIRTUALADDRESSSPACE_H
22#include "pedigree/kernel/Atomic.h"
23#include "pedigree/kernel/Spinlock.h"
24#include "pedigree/kernel/compiler.h"
25#include "pedigree/kernel/processor/VirtualAddressSpace.h"
26#include "pedigree/kernel/processor/types.h"
27#include "pedigree/kernel/utilities/Vector.h"
28#include "pedigree/kernel/utilities/utility.h"
43#define USERSPACE_DYNAMIC_LINKER_LOCATION reinterpret_cast<void*>(0x4FA00000)
45#define USERSPACE_VIRTUAL_START reinterpret_cast<void*>(0x400000)
46#define USERSPACE_VIRTUAL_HEAP reinterpret_cast<void*>(0x50000000)
47#define USERSPACE_RESERVED_START USERSPACE_DYNAMIC_LINKER_LOCATION
48#define USERSPACE_VIRTUAL_STACK_SIZE 0x100000
49#define USERSPACE_VIRTUAL_MAX_STACK_SIZE 0x100000
50#define USERSPACE_DYNAMIC_START reinterpret_cast<void*>(0x100000000)
51#define USERSPACE_DYNAMIC_END reinterpret_cast<void*>(0x00000FFFFFFFFFFF)
52#define USERSPACE_VIRTUAL_LOWEST_STACK \
53 reinterpret_cast<void*>(USERSPACE_DYNAMIC_END + USERSPACE_VIRTUAL_MAX_STACK_SIZE)
54#define USERSPACE_VIRTUAL_STACK \
55 reinterpret_cast<void*>(0x00007FFFEFFFF000)
56#define KERNEL_VIRTUAL_EVENT_BASE \
57 reinterpret_cast<void*>(0x00007FFFF0000000)
59#define KERNEL_SPACE_START reinterpret_cast<void*>(0xFFFF800000000000)
60#define KERNEL_VIRTUAL_PAGESTACK_ABV4GB1 reinterpret_cast<void*>(0xFFFF800100000000)
61#define KERNEL_VIRTUAL_PAGESTACK_ABV4GB2 reinterpret_cast<void*>(0xFFFF801000000000)
62#define KERNEL_VIRTUAL_HEAP reinterpret_cast<void*>(0xFFFF900000000000)
63#define KERNEL_VIRTUAL_CACHE reinterpret_cast<void*>(0xFFFFB00000000000)
64#define KERNEL_VIRTUAL_MEMORYREGION_ADDRESS reinterpret_cast<void*>(0xFFFFF00000000000)
65#define KERNEL_VIRTUAL_PAGESTACK_4GB reinterpret_cast<void*>(0xFFFFFFFF7FC00000)
66#define KERNEL_VIRTUAL_ADDRESS reinterpret_cast<void*>(0xFFFFFFFF7FF00000)
67#define KERNEL_VIRTUAL_INFO_BLOCK reinterpret_cast<void*>(0xFFFFFFFF8FFF0000)
68#define KERNEL_VIRTUAL_MODULE_BASE reinterpret_cast<void*>(0xFFFFFFFF90000000)
69#define KERNEL_VIRTUAL_LOWEST_STACK reinterpret_cast<void*>(0xFFFFFFFFE0000000)
70#define KERNEL_VIRTUAL_STACK reinterpret_cast<void*>(0xFFFFFFFFFFFF7000)
72#define KERNEL_VIRTUAL_MODULE_SIZE \
73 pointer_diff_const(KERNEL_VIRTUAL_MODULE_BASE, KERNEL_VIRTUAL_LOWEST_STACK)
74#define KERNEL_VIRTUAL_HEAP_SIZE pointer_diff_const(KERNEL_VIRTUAL_HEAP, KERNEL_VIRTUAL_CACHE)
75#define KERNEL_VIRTUAL_CACHE_SIZE \
76 pointer_diff_const(KERNEL_VIRTUAL_CACHE, KERNEL_VIRTUAL_MEMORYREGION_ADDRESS)
77#define KERNEL_VIRTUAL_MEMORYREGION_SIZE \
78 pointer_diff_const(KERNEL_VIRTUAL_MEMORYREGION_ADDRESS, KERNEL_VIRTUAL_PAGESTACK_4GB)
79#define KERNEL_STACK_SIZE 0x8000
103 virtual bool isMapped(
void* virtualAddress);
104 virtual size_t runtimeMappingPages(uintptr_t base,
size_t length);
106 virtual bool map(physical_uintptr_t physAddress,
void* virtualAddress,
size_t flags);
107 bool tryMapUserPage(physical_uintptr_t physical,
void* address,
size_t flags,
108 size_t* committedTablePages =
nullptr)
override;
109 bool tryDetachUserPage(
void* address, physical_uintptr_t expected)
override;
110 virtual bool mapHuge(physical_uintptr_t physAddress,
void* virtualAddress,
size_t count,
112 virtual bool getMapping(
void* virtualAddress, physical_uintptr_t& physAddress,
size_t& flags);
114 ResidentCopyStatus
copyResidentUserPage(uintptr_t userAddress,
void* kernelBuffer,
size_t bytes,
115 bool write)
override;
117 virtual bool tryReadUser32(uintptr_t address, uint32_t& value);
118 virtual bool tryReadUserPointer(uintptr_t address, uintptr_t& value);
121 virtual void setFlags(
void* virtualAddress,
size_t newFlags);
123 virtual void unmap(
void* virtualAddress);
124 virtual bool detachMapping(
void* virtualAddress, physical_uintptr_t& physical,
size_t& flags,
125 size_t requiredFlags = 0);
129 __atomic_store_n(&m_RemapPreparationFailure, allocations, __ATOMIC_RELEASE);
155 bool mapPageStructures(physical_uintptr_t physAddress,
void* virtualAddress,
size_t flags);
156 bool mapPageStructuresAbove4GB(physical_uintptr_t physAddress,
void* virtualAddress,
164 return reinterpret_cast<uintptr_t
>(KERNEL_SPACE_START);
169 return reinterpret_cast<uintptr_t
>(USERSPACE_VIRTUAL_START);
174 return reinterpret_cast<uintptr_t
>(USERSPACE_RESERVED_START);
179 return reinterpret_cast<uintptr_t
>(USERSPACE_DYNAMIC_LINKER_LOCATION);
184 return reinterpret_cast<uintptr_t
>(KERNEL_VIRTUAL_HEAP);
189 return reinterpret_cast<uintptr_t
>(KERNEL_VIRTUAL_HEAP) + KERNEL_VIRTUAL_HEAP_SIZE;
194 return reinterpret_cast<uintptr_t
>(USERSPACE_DYNAMIC_START);
199 return reinterpret_cast<uintptr_t
>(USERSPACE_DYNAMIC_END);
204 return reinterpret_cast<uintptr_t
>(KERNEL_VIRTUAL_INFO_BLOCK);
209 return reinterpret_cast<uintptr_t
>(KERNEL_VIRTUAL_CACHE);
214 return reinterpret_cast<uintptr_t
>(KERNEL_VIRTUAL_CACHE) + KERNEL_VIRTUAL_CACHE_SIZE;
219 return reinterpret_cast<uintptr_t
>(KERNEL_VIRTUAL_EVENT_BASE);
224 return reinterpret_cast<uintptr_t
>(KERNEL_VIRTUAL_MODULE_BASE);
229 return reinterpret_cast<uintptr_t
>(KERNEL_VIRTUAL_MODULE_BASE) + KERNEL_VIRTUAL_MODULE_SIZE;
234 return reinterpret_cast<uintptr_t
>(KERNEL_VIRTUAL_PAGESTACK_4GB);
239 return reinterpret_cast<uintptr_t
>(KERNEL_VIRTUAL_PAGESTACK_ABV4GB1);
244 return reinterpret_cast<uintptr_t
>(KERNEL_VIRTUAL_PAGESTACK_ABV4GB2);
249 bool tryAccessUserWord(uintptr_t address,
size_t width, uintptr_t& value,
250 const uintptr_t* replacement);
282 size_t detachEmptyTables(
void* virtualAddress, physical_uintptr_t* detachedTables);
292 uint64_t
toFlags(
size_t flags,
void* virtualAddress,
bool bFinal =
false) const
PURE;
298 size_t fromFlags(uint64_t Flags,
bool bFinal = false) const
PURE;
315 bool mapUnlocked(physical_uintptr_t physAddress,
void* virtualAddress,
size_t flags,
322 bool requireMapped = true);
326 Stack* allocateTrackedUserStack(
size_t size);
332 ssize_t m_RemapPreparationFailure = -1;
A vector / dynamic array.
static VirtualAddressSpace * create()
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
MUST_USE_RESULT bool trySetFlags(void *virtualAddress, size_t newFlags) override
virtual uintptr_t getGlobalInfoBlock() const
X64VirtualAddressSpace & operator=(const X64VirtualAddressSpace &)
bool unmapUnlocked(void *virtualAddress, X64MappingMutationScope &mutation, bool requireMapped=true)
size_t fromFlags(uint64_t Flags, bool bFinal=false) const PURE
virtual bool tryReadUser32(uintptr_t address, uint32_t &value)
virtual bool handleCopyOnWriteFault(void *virtualAddress, bool userMode)
virtual void freeStack(Stack *pStack)
uint64_t toFlags(size_t flags, void *virtualAddress, bool bFinal=false) const PURE
virtual bool mapHuge(physical_uintptr_t physAddress, void *virtualAddress, size_t count, size_t flags)
physical_uintptr_t m_PhysicalPML4
virtual void revertToKernelAddressSpace()
virtual uintptr_t getKernelCacheEnd() const
X64VirtualAddressSpace(const X64VirtualAddressSpace &)
virtual void unmap(void *virtualAddress)
virtual bool isAddressValid(void *virtualAddress)
Vector< Stack * > m_freeStacks
virtual uintptr_t getKernelVirtualPagestackAdd1() const
virtual Stack * allocateStack()
virtual uintptr_t getKernelVirtualPagestack() const
virtual bool detachMapping(void *virtualAddress, physical_uintptr_t &physical, size_t &flags, size_t requiredFlags=0)
static X64VirtualAddressSpace m_KernelSpace
virtual bool memIsInKernelHeap(void *pMem)
virtual bool map(physical_uintptr_t physAddress, void *virtualAddress, size_t flags)
virtual uintptr_t getKernelModulesEnd() const
virtual uintptr_t getDynamicEnd() const
bool invalidateMapping(void *virtualAddress, X64MappingMutationScope &mutation)
virtual uintptr_t getDynamicLinkerAddress() const
bool conditionalTableEntryAllocation(uint64_t *tableEntry, uint64_t flags)
ResidentCopyStatus copyResidentUserPage(uintptr_t userAddress, void *kernelBuffer, size_t bytes, bool write) override
virtual VirtualAddressSpace * clone(bool copyOnWrite=true)
virtual uintptr_t getKernelVirtualPagestackAdd2() const
bool conditionalTableEntryMapping(uint64_t *tableEntry, uint64_t physAddress, uint64_t flags)
virtual uintptr_t getUserReservedStart() const
virtual bool tryCompareExchangeUser32(uintptr_t address, uint32_t &expected, uint32_t desired, bool &exchanged)
size_t detachEmptyTables(void *virtualAddress, physical_uintptr_t *detachedTables)
virtual bool memIsInHeap(void *pMem)
virtual bool tryWriteUser32(uintptr_t address, uint32_t value)
Stack * doAllocateStack(size_t sSize)
RemapStatus prepareRemap(const PageRemapRequest &request, UniquePointer< PreparedPageRemap > &plan) override
virtual bool getMapping(void *virtualAddress, physical_uintptr_t &physAddress, size_t &flags)
virtual uintptr_t getKernelCacheStart() const
virtual ~X64VirtualAddressSpace()
Atomic< uint64_t > m_ResidentProcessors
bool mapPageStructures(physical_uintptr_t physAddress, void *virtualAddress, size_t flags)
virtual void setFlags(void *virtualAddress, size_t newFlags)
virtual uintptr_t getKernelEventBlockStart() const
virtual uintptr_t getKernelModulesStart() const
void setRemapPreparationFailureForTest(ssize_t allocations) override
virtual void * getEndOfHeap()
virtual uintptr_t getKernelStart() const
virtual bool isMapped(void *virtualAddress)
bool getPageTableEntry(void *virtualAddress, uint64_t *&pageTableEntry) const
virtual uintptr_t getKernelHeapEnd() const
virtual uintptr_t getKernelHeapStart() const
bool mapUnlocked(physical_uintptr_t physAddress, void *virtualAddress, size_t flags, X64MappingMutationScope &mutation, bool locked=false)
virtual uintptr_t getUserStart() const
virtual uintptr_t getDynamicStart() const