1#ifndef X86_MATANEL_MEMORY_H
2#define X86_MATANEL_MEMORY_H
38#define PML4_INDEX_BITS 9
39#define PML4_INDEX_SHIFT 39
40#define PML4_INDEX_MASK ((1ULL << PML4_INDEX_BITS) - 1ULL)
42#define PML4_INDEX_FROM_VA(VA) ( ( (uintptr_t)(VA) >> PML4_INDEX_SHIFT ) & PML4_INDEX_MASK )
46#define PML4_INDEX_FROM_PHYS(PHYS) PML4_INDEX_FROM_VA( (uintptr_t)(PHYS) + (uintptr_t)PhysicalMemoryOffset )
49static inline int MiConvertVaToPml4Offset(uint64_t va) {
53#define VirtualPageSize 4096ULL
54#define PhysicalFrameSize 4096ULL
55#define KernelVaStart 0xfffff80000000000ULL
56#define PhysicalMemoryOffset 0xffff880000000000ULL
57#define RECURSIVE_INDEX 0x1FF
59#ifndef __INTELLISENSE__
60#ifndef __OFFSET_GENERATOR__
62#define INDEX_TO_PPFN(Index) \
63 (&(PfnDatabase.PfnEntries[(size_t)(Index)]))
64#define PHYSICAL_TO_PPFN(PHYS) \
65 (&PfnDatabase.PfnEntries[(size_t)((PHYS) / (uint64_t)PhysicalFrameSize)])
66#define PTE_TO_PHYSICAL(PMMPTE) ((PMMPTE)->Value & ~0xFFFULL)
70#define MI_WRITE_PTE(_PtePointer, _Va, _Pa, _Flags) \
72 MMPTE* _pte = (MMPTE*)(_PtePointer); \
73 uint64_t _val = (((uintptr_t)(_Pa)) & ~0xFFFULL) | (uint64_t)(_Flags); \
74 MiAtomicExchangePte(_pte, _val); \
75 __asm__ volatile("" ::: "memory"); \
78 if (MmPfnDatabaseInitialized) { \
79 PPFN_ENTRY _pfn = PHYSICAL_TO_PPFN(_Pa); \
80 _pfn->Descriptor.Mapping.PteAddress = (PMMPTE)_pte; \
81 _pfn->State = PfnStateActive; \
82 _pfn->Flags = PFN_FLAG_NONPAGED; \
85 invlpg((void*)(uintptr_t)(_Va)); \
90#define MI_WRITE_PTE(_PtePointer, _Va, _Pa, _Flags) \
92 MMPTE* _pte = (MMPTE*)(_PtePointer); \
93 uint64_t _val = (((uintptr_t)(_Pa)) & ~0xFFFULL) | (uint64_t)(_Flags); \
94 MiAtomicExchangePte(_pte, _val); \
95 __asm__ volatile("" ::: "memory"); \
98 if (MmPfnDatabaseInitialized) { \
99 PPFN_ENTRY _pfn = PHYSICAL_TO_PPFN(_Pa); \
100 _pfn->Descriptor.Mapping.PteAddress = (PMMPTE)_pte; \
101 _pfn->State = PfnStateActive; \
102 _pfn->Flags = PFN_FLAG_NONPAGED; \
105 invlpg((void*)(uintptr_t)(_Va)); \
108 if (smpInitialized && allApsInitialized) { \
109 IPI_PARAMS _Params; \
110 _Params.pageParams.addressToInvalidate = (uint64_t)(_Va); \
111 MhSendActionToCpusAndWait(CPU_ACTION_PERFORM_TLB_SHOOTDOWN, _Params);\
116#define PPFN_TO_INDEX(PPFN) ((size_t)((PPFN) - PfnDatabase.PfnEntries))
117#define PPFN_TO_PHYSICAL_ADDRESS(PPFN) \
118 ((uint64_t)((uint64_t)PPFN_TO_INDEX(PPFN) * (uint64_t)PhysicalFrameSize))
119#define VA_OFFSET(_VirtualAddress) ((uintptr_t)(_VirtualAddress) & 0xFFF)
120#define MM_IS_DEMAND_ZERO_PTE(pte) \
121 (((pte).Soft.SoftwareFlags & MI_DEMAND_ZERO_BIT) != 0)
122#define MM_SET_DEMAND_ZERO_PTE(pte, prot_flags, nx) \
125 (pte).Soft.SoftwareFlags = (prot_flags) | MI_DEMAND_ZERO_BIT; \
126 (pte).Soft.NoExecute = (nx); \
128#define MM_UNSET_DEMAND_ZERO_PTE(pte) \
130 (pte).Soft.SoftwareFlags &= ~MI_DEMAND_ZERO_BIT; \
134#define PTE_TO_PHYSICAL(PMMPTE) (0)
135#define MI_WRITE_PTE(_PtePointer, _Va, _Pa, _Flags) ((void)0)
136#define PPFN_TO_INDEX(PPFN) (0)
137#define PPFN_TO_PHYSICAL_ADDRESS(PPFN) (0)
138#define INDEX_TO_PPFN(Index) (NULL)
139#define PHYSICAL_TO_PPFN(PHYS) (NULL)
140#define VA_OFFSET(_VirtualAddress) (uintptr_t)(NULL)
141#define MM_IS_DEMAND_ZERO_PTE(pte) (NULL)
142#define MM_SET_DEMAND_ZERO_PTE(pte, prot_flags, nx) ((void)0)
143#define MM_UNSET_DEMAND_ZERO_PTE(pte) (NULL)
147#define BYTES_TO_PAGES(Bytes) (((Bytes) + VirtualPageSize - 1) / VirtualPageSize)
149#define PAGES_TO_BYTES(Pages) ((Pages) * VirtualPageSize)
151#define MAX_POOL_DESCRIPTORS 7
157#define _1024KB_POOL 6
158#define _2048KB_POOL 7
159#define POOL_MIN_ALLOC 32
160#define USER_VA_END 0x00007FFFFFFFFFFF
161#define USER_VA_START 0x10000
163#define POOL_MAX_ALLOC 2048
165#define MI_NONPAGED_POOL_SIZE ((size_t)16ULL * 1024 * 1024 * 1024)
166#define MI_PAGED_POOL_SIZE ((size_t)32ULL * 1024 * 1024 * 1024)
169#define NONPAGED_POOL_VA_TOTAL_PAGES (MI_NONPAGED_POOL_SIZE / VirtualPageSize)
170#define PAGED_POOL_VA_TOTAL_PAGES (MI_PAGED_POOL_SIZE / VirtualPageSize)
173#define NONPAGED_POOL_VA_BITMAP_QWORDS ((NONPAGED_POOL_VA_TOTAL_PAGES + 63) / 64)
174#define PAGED_POOL_VA_BITMAP_QWORDS ((PAGED_POOL_VA_TOTAL_PAGES + 63) / 64)
177#define MI_NONPAGED_BITMAP_PAGES_NEEDED ((NONPAGED_POOL_VA_BITMAP_QWORDS * sizeof(uint64_t) + VirtualPageSize - 1) / VirtualPageSize)
178#define MI_PAGED_BITMAP_PAGES_NEEDED ((PAGED_POOL_VA_BITMAP_QWORDS * sizeof(uint64_t) + VirtualPageSize - 1) / VirtualPageSize)
181#define ALIGN_UP(x, align) (((uintptr_t)(x) + ((align)-1)) & ~((uintptr_t)((align)-1)))
184#define MI_NONPAGED_BITMAP_BASE ALIGN_UP(LK_KERNEL_END, VirtualPageSize)
185#define MI_NONPAGED_BITMAP_END (MI_NONPAGED_BITMAP_BASE + MI_NONPAGED_BITMAP_PAGES_NEEDED * VirtualPageSize)
187#define MI_PAGED_BITMAP_BASE ALIGN_UP(MI_NONPAGED_BITMAP_END, VirtualPageSize)
188#define MI_PAGED_BITMAP_END (MI_PAGED_BITMAP_BASE + MI_PAGED_BITMAP_PAGES_NEEDED * VirtualPageSize)
191#define MI_NONPAGED_POOL_BASE ALIGN_UP(MI_NONPAGED_BITMAP_END, VirtualPageSize)
192#define MI_NONPAGED_POOL_END (MI_NONPAGED_POOL_BASE + MI_NONPAGED_POOL_SIZE)
194#define MI_PAGED_POOL_BASE ALIGN_UP(MI_NONPAGED_POOL_END, VirtualPageSize)
195#define MI_PAGED_POOL_END (MI_PAGED_POOL_BASE + MI_PAGED_POOL_SIZE)
198#define MI_IS_CANONICAL_ADDR(va) \
200 uint64_t _va = (uint64_t)(va); \
201 uint64_t _mask = ~((1ULL << 48) - 1); \
202 ((_va & _mask) == 0 || (_va & _mask) == _mask); \
205#define PFN_TO_PHYS(Pfn) PPFN_TO_PHYSICAL_ADDRESS(INDEX_TO_PPFN(Pfn))
206#define PHYS_TO_INDEX(PhysicalAddress) PPFN_TO_INDEX(PHYSICAL_TO_PPFN(PhysicalAddress))
208#define PFN_ERROR UINT64_T_MAX
211#define PROT_KERNEL_READ 0x1
212#define PROT_KERNEL_WRITE 0x2
213#define MI_DEMAND_ZERO_BIT (1ULL << 16)
216#define MM_POOL_CANARY 'BEKA'
219#define MI_STACK_SIZE 0x4000
220#define MI_LARGE_STACK_SIZE 0xf000
221#define MI_GUARD_PAGE_PROTECTION (1ULL << 17)
226#define MmFullBarrier() __sync_synchronize()
229#define MmBarrier() __asm__ __volatile__("mfence" ::: "memory")
234#define MmIsAddressValid(VirtualAddress) MmIsAddressPresent(VirtualAddress)
301#define PAGE_PAT (1ULL << 7)
541 void* dest, int64_t val, uint64_t len
545 for (
size_t i = 0; i < (size_t)len; i++) {
546 ptr[i] = (uint8_t)val;
555 void* dest,
const void* src,
size_t len
558 uint8_t* d = (uint8_t*)dest;
559 const uint8_t* s = (
const uint8_t*)src;
560 for (
size_t i = 0; i < len; i++) d[i] = s[i];
567 const void* s1,
const void* s2,
size_t n
570 const uint8_t* p1 = (
const uint8_t*)s1;
571 const uint8_t* p2 = (
const uint8_t*)s2;
573 for (
size_t i = 0; i < n; i++) {
575 return (
int)(p1[i] - p2[i]);
626 if (ErrorCode & (1 << 4)) {
629 else if (ErrorCode & (1 << 1)) {
662 IN void* VirtualAddress
731 IN void* VirtualAddress
741 IN uintptr_t VirtualAddress
748 IN uint64_t PfnIndex,
768 IN size_t NumberOfBytes,
786 IN void* AllocatedStackTop,
792 OUT void** DirectoryTable
801 IN size_t NumberOfBytes,
815 IN uintptr_t VirtualAddress
826 IN size_t NumberOfBytes,
827 IN uintptr_t SearchStart,
828 IN uintptr_t SearchEnd
841 IN size_t NumberOfBytes
847 IN size_t NumberOfBytes,
855 IN uint64_t FaultBits,
856 IN uint64_t VirtualAddress,
870 IN void* StartAddress,
871 IN size_t NumberOfBytes
876 IN size_t NumberOfBytes,
877 IN uint64_t HighestAcceptableAddress
882 IN void* BaseAddress,
883 IN size_t NumberOfBytes
888 IN uintptr_t PhysicalAddress,
889 IN size_t NumberOfBytes,
FORCEINLINE uint64_t InterlockedExchangeU64(volatile uint64_t *target, uint64_t value)
struct _SINGLE_LINKED_LIST SINGLE_LINKED_LIST
struct _BOOT_INFO * PBOOT_INFO
FORCEINLINE unsigned long __read_cr2(void)
void MmFreeContigiousMemory(IN void *BaseAddress, IN size_t NumberOfBytes)
enum _SYSTEM_PHASE_ROUTINE SYSTEM_PHASE_ROUTINE
PAGE_INDEX MiRequestPhysicalPage(IN PFN_STATE ListType)
struct _MM_PFN_LIST MM_PFN_LIST
MTSTATUS MmAccessFault(IN uint64_t FaultBits, IN uint64_t VirtualAddress, IN PRIVILEGE_MODE PreviousMode, IN PTRAP_FRAME TrapFrame)
FORCEINLINE void MiAtomicExchangePte(PMMPTE PtePtr, uint64_t NewPteValue)
bool MiCheckForContigiousMemory(IN void *StartAddress, IN size_t NumberOfBytes)
FORCEINLINE uint64_t MiRetrieveLastFaultyAddress(void)
uintptr_t MiTranslateVirtualToPhysical(IN void *VirtualAddress)
enum _PFN_STATE PFN_STATE
void MiUnlinkPageFromList(PPFN_ENTRY pfn)
bool MmInvalidAccessAllowed(void)
@ SYSTEM_PHASE_INITIALIZE_PAT_ONLY
@ SYSTEM_PHASE_INITIALIZE_ALL
@ NonPagedPoolCacheAligned
FORCEINLINE int kmemcmp(const void *s1, const void *s2, size_t n)
FORCEINLINE bool MiIsValidPfn(IN PAGE_INDEX Pfn)
enum _MEMORY_CACHING_TYPE MEMORY_CACHING_TYPE
void * MiCreateKernelStack(IN bool LargeStack)
@ MmHardwareCoherentCached
enum _FAULT_OPERATION * PFAULT_OPERATION
void * MmMapIoSpace(IN uintptr_t PhysicalAddress, IN size_t NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
enum _PRIVILEGE_MODE * PPRIVILEGE_MODE
enum _POOL_TYPE POOL_TYPE
enum _FAULT_OPERATION FAULT_OPERATION
uintptr_t MiAllocatePoolVa(IN POOL_TYPE PoolType, IN size_t NumberOfBytes)
void MiReleasePhysicalPage(IN PAGE_INDEX PfnIndex)
struct _POOL_DESCRIPTOR POOL_DESCRIPTOR
FORCEINLINE FAULT_OPERATION MiRetrieveOperationFromErrorCode(uint64_t ErrorCode)
FORCEINLINE void * kmemcpy(void *dest, const void *src, size_t len)
struct _MM_PFN_DATABASE MM_PFN_DATABASE
void MiFreePoolVaContiguous(IN uintptr_t va, IN size_t NumberOfBytes, IN POOL_TYPE PoolType)
FORCEINLINE uint64_t MiCacheToFlags(MEMORY_CACHING_TYPE type)
struct _PFN_ENTRY PFN_ENTRY
MTSTATUS MmCreateProcessAddressSpace(OUT void **DirectoryTable)
MTSTATUS MiInitializePoolSystem(void)
enum _PRIVILEGE_MODE PRIVILEGE_MODE
FORCEINLINE void * kmemset(void *dest, int64_t val, uint64_t len)
struct _POOL_DESCRIPTOR * PPOOL_DESCRIPTOR
PMMPTE MiGetPdptePointer(IN uintptr_t va)
enum _VAD_FLAGS VAD_FLAGS
MTSTATUS MmFreeVirtualMemory(IN PEPROCESS Process, IN void *BaseAddress)
PMMVAD MiFindVad(IN PMMVAD Root, IN uintptr_t VirtualAddress)
void * MiMapPageInHyperspace(IN uint64_t PfnIndex, OUT PIRQL OldIrql)
void MiMoveUefiDataToHigherHalf(IN PBOOT_INFO BootInfo)
MTSTATUS MiInitializePfnDatabase(IN PBOOT_INFO BootInfo)
PMMPTE MiGetPdePointer(IN uintptr_t va)
uint64_t * pml4_from_recursive(void)
MTSTATUS MmAllocateVirtualMemory(IN PEPROCESS Process, _In_Opt _Out_Opt void **BaseAddress, IN size_t NumberOfBytes, IN VAD_FLAGS VadFlags)
bool MmIsAddressPresent(IN uintptr_t VirtualAddress)
enum _PAGE_FLAGS PAGE_FLAGS
PMMPTE MiGetPml4ePointer(IN uintptr_t va)
bool MmInitSystem(IN uint8_t Phase, IN PBOOT_INFO BootInformation)
PAGE_INDEX MiTranslatePteToPfn(IN PMMPTE pte)
struct _POOL_HEADER POOL_HEADER
uintptr_t MmFindFreeAddressSpace(IN PEPROCESS Process, IN size_t NumberOfBytes, IN uintptr_t SearchStart, IN uintptr_t SearchEnd)
void * MmAllocateContigiousMemory(IN size_t NumberOfBytes, IN uint64_t HighestAcceptableAddress)
void MmFreePool(IN void *buf)
void MiFreeKernelStack(IN void *AllocatedStackTop, IN bool LargeStack)
uint64_t MiTranslatePteToVa(IN PMMPTE pte)
void MiUnmapHyperSpaceMap(IN IRQL OldIrql)
struct _PFN_ENTRY * PPFN_ENTRY
bool MiInitializePoolVaSpace(void)
PMMPTE MiGetPtePointer(IN uintptr_t va)
void MiInvalidateTlbForVa(IN void *VirtualAddress)
void MiUnmapPte(IN PMMPTE pte)
void * MmAllocatePoolWithTag(IN enum _POOL_TYPE PoolType, IN size_t NumberOfBytes, IN uint32_t Tag)
enum _PFN_FLAGS PFN_FLAGS
struct _POOL_HEADER * PPOOL_HEADER
struct _SPINLOCK SPINLOCK
bool MmPfnDatabaseInitialized
MM_PFN_DATABASE PfnDatabase
uintptr_t MmNonPagedPoolEnd
uintptr_t MmNonPagedPoolStart
uintptr_t MmPagedPoolStart
uintptr_t MmSystemRangeStart
uintptr_t MmUserProbeAddress
uintptr_t MmHighestUserAddress
MM_PFN_LIST StandbyPageList
volatile size_t AvailablePages
MM_PFN_LIST ModifiedPageList
volatile size_t TotalReserved
MM_PFN_LIST ZeroedPageList
struct _DOUBLY_LINKED_LIST ListEntry
struct _MMPTE::@172372265215056352375070220246156106027174106113::@200357034104227323320222006243127050212100105247 Hard
struct _MMPTE::@172372265215056352375070220246156106027174106113::@277354034164206104264133322054061025100052052376 Soft
struct _FILE_OBJECT * File
struct _EPROCESS * OwningProcess
struct _MMVAD * LeftChild
struct _MMVAD * RightChild
union _PFN_ENTRY::@217024126340164016372152071216274230164113211246 Descriptor
volatile uint32_t RefCount
struct _PFN_ENTRY::@217024126340164016372152071216274230164113211246::@301110335271023021153236134322146064331241142124 Mapping
struct _DOUBLY_LINKED_LIST ListEntry
volatile uint64_t FreeCount
volatile uint64_t TotalBlocks
SINGLE_LINKED_LIST FreeListHead
SINGLE_LINKED_LIST FreeListEntry
union _POOL_HEADER::@321115223011072362277073135231015025151337071364 Metadata