kernel
Loading...
Searching...
No Matches
mm.h
Go to the documentation of this file.
1#ifndef X86_MATANEL_MEMORY_H
2#define X86_MATANEL_MEMORY_H
3
4/*++
5
6Module Name:
7
8 mm.h
9
10Purpose:
11
12 This module contains the header files required for memory management (virtual, physical, PFN, VAD, MMIO, init, etc.)
13
14Author:
15
16 slep (Matanel) 2025.
17
18Revision History:
19
20--*/
21
22// Base Includes
23#include <stdint.h>
24#include <stdbool.h>
25#include "annotations.h"
26#include "macros.h"
27#include "../mtstatus.h"
30
31// Needed for linked list and spinlocks
32#include "ms.h"
33#include "core.h"
34#include "efi.h"
35
36// ------------------ HEADER SPECIFIC MACROS ------------------
37
38#define PML4_INDEX_BITS 9
39#define PML4_INDEX_SHIFT 39
40#define PML4_INDEX_MASK ((1ULL << PML4_INDEX_BITS) - 1ULL)
41
42#define PML4_INDEX_FROM_VA(VA) ( ( (uintptr_t)(VA) >> PML4_INDEX_SHIFT ) & PML4_INDEX_MASK )
43
44/* If PhysicalMemoryOffset is the kernel VA base that maps physical 0:
45 index in PML4 for physical address PHYS is the index of (PHYS + PhysicalMemoryOffset) */
46#define PML4_INDEX_FROM_PHYS(PHYS) PML4_INDEX_FROM_VA( (uintptr_t)(PHYS) + (uintptr_t)PhysicalMemoryOffset )
47
48 /* safer typed helper */
49static inline int MiConvertVaToPml4Offset(uint64_t va) {
50 return (int)((va >> PML4_INDEX_SHIFT) & PML4_INDEX_MASK);
51}
52
53#define VirtualPageSize 4096ULL // Same as each physical frame.
54#define PhysicalFrameSize 4096ULL // Each physical frame.
55#define KernelVaStart 0xfffff80000000000ULL
56#define PhysicalMemoryOffset 0xffff880000000000ULL // Defines the offset in arithmetic for quick mapping
57#define RECURSIVE_INDEX 0x1FF
58
59#ifndef __INTELLISENSE__
60#ifndef __OFFSET_GENERATOR__
61/* Convert a PFN index to a PPFN_ENTRY pointer */
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)
67/* single-CPU build (no IPI shootdown code) */
68#ifdef MT_UP
69
70#define MI_WRITE_PTE(_PtePointer, _Va, _Pa, _Flags) \
71do { \
72 MMPTE* _pte = (MMPTE*)(_PtePointer); \
73 uint64_t _val = (((uintptr_t)(_Pa)) & ~0xFFFULL) | (uint64_t)(_Flags); \
74 MiAtomicExchangePte(_pte, _val); \
75 __asm__ volatile("" ::: "memory"); \
76 \
77 /* Only set PFN->PTE link if PFN database is initialized */ \
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; \
83 } \
84 \
85 invlpg((void*)(uintptr_t)(_Va)); \
86} while (0)
87
88#else /* SMP build: include TLB shootdown via IPI */
89
90#define MI_WRITE_PTE(_PtePointer, _Va, _Pa, _Flags) \
91do { \
92 MMPTE* _pte = (MMPTE*)(_PtePointer); \
93 uint64_t _val = (((uintptr_t)(_Pa)) & ~0xFFFULL) | (uint64_t)(_Flags); \
94 MiAtomicExchangePte(_pte, _val); \
95 __asm__ volatile("" ::: "memory"); \
96 \
97 /* Only set PFN->PTE link if PFN database is initialized */ \
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; \
103 } \
104 \
105 invlpg((void*)(uintptr_t)(_Va)); \
106 \
107 /* Send IPIs if SMP is initialized (and all APs are on) */ \
108 if (smpInitialized && allApsInitialized) { \
109 IPI_PARAMS _Params; \
110 _Params.pageParams.addressToInvalidate = (uint64_t)(_Va); \
111 MhSendActionToCpusAndWait(CPU_ACTION_PERFORM_TLB_SHOOTDOWN, _Params);\
112 } \
113} while (0)
114
115#define MI_WRITE_PTE_NO_IPI(_PtePointer, _Va, _Pa, _Flags) \
116do { \
117 MMPTE* _pte = (MMPTE*)(_PtePointer); \
118 uint64_t _val = (((uintptr_t)(_Pa)) & ~0xFFFULL) | (uint64_t)(_Flags); \
119 MiAtomicExchangePte(_pte, _val); \
120 __asm__ volatile("" ::: "memory"); \
121 \
122 /* Only set PFN->PTE link if PFN database is initialized */ \
123 if (MmPfnDatabaseInitialized) { \
124 PPFN_ENTRY _pfn = PHYSICAL_TO_PPFN(_Pa); \
125 _pfn->Descriptor.Mapping.PteAddress = (PMMPTE)_pte; \
126 _pfn->State = PfnStateActive; \
127 _pfn->Flags = PFN_FLAG_NONPAGED; \
128 } \
129 \
130 invlpg((void*)(uintptr_t)(_Va)); \
131 \
132} while (0)
133
134#endif
135#define PPFN_TO_INDEX(PPFN) ((size_t)((PPFN) - PfnDatabase.PfnEntries))
136#define PPFN_TO_PHYSICAL_ADDRESS(PPFN) \
137 ((uint64_t)((uint64_t)PPFN_TO_INDEX(PPFN) * (uint64_t)PhysicalFrameSize))
138#define VA_OFFSET(_VirtualAddress) ((uintptr_t)(_VirtualAddress) & 0xFFF)
139#define MM_IS_DEMAND_ZERO_PTE(pte) \
140 (((pte).Soft.SoftwareFlags & MI_DEMAND_ZERO_BIT) != 0)
141#define MM_SET_DEMAND_ZERO_PTE(pte, prot_flags, nx) \
142 do { \
143 (pte).Value = 0; \
144 (pte).Soft.SoftwareFlags = (prot_flags) | MI_DEMAND_ZERO_BIT; \
145 (pte).Soft.NoExecute = (nx); \
146 } while(0)
147#define MM_UNSET_DEMAND_ZERO_PTE(pte) \
148 do { \
149 (pte).Soft.SoftwareFlags &= ~MI_DEMAND_ZERO_BIT; \
150 } while(0)
151#endif
152#else
153#define PTE_TO_PHYSICAL(PMMPTE) (0)
154#define MI_WRITE_PTE(_PtePointer, _Va, _Pa, _Flags) ((void)0)
155#define MI_WRITE_PTE_NO_IPI(_PtePointer, _Va, _Pa, _Flags) ((void)0)
156#define PPFN_TO_INDEX(PPFN) (0)
157#define PPFN_TO_PHYSICAL_ADDRESS(PPFN) (0)
158#define INDEX_TO_PPFN(Index) (NULL)
159#define PHYSICAL_TO_PPFN(PHYS) (NULL)
160#define VA_OFFSET(_VirtualAddress) (uintptr_t)(NULL)
161#define MM_IS_DEMAND_ZERO_PTE(pte) (NULL)
162#define MM_SET_DEMAND_ZERO_PTE(pte, prot_flags, nx) ((void)0)
163#define MM_UNSET_DEMAND_ZERO_PTE(pte) (NULL)
164#endif
165
166// Convert bytes to pages (rounding up)
167#define BYTES_TO_PAGES(Bytes) (((Bytes) + VirtualPageSize - 1) / VirtualPageSize)
168// Convert pages to bytes
169#define PAGES_TO_BYTES(Pages) ((Pages) * VirtualPageSize)
170
171// Align the page (down)
172#define PAGE_ALIGN(Va) ((void*)((uint64_t)(Va) & ~(VirtualPageSize - 1)))
173
174#define MAX_POOL_DESCRIPTORS 7 // Allows for: 32, 64, 128, 256, 512, 1024, 2048 Bytes Per pool
175#define _32B_POOL 1
176#define _64B_POOL 2
177#define _128B_POOL 3
178#define _256B_POOL 4
179#define _512B_POOL 5
180#define _1024B_POOL 6
181#define _2048B_POOL 7
182#define POOL_MIN_ALLOC 32 // Bytes
183// You are allowed to request bytes above max allocation, the global pool would be used.
184#define POOL_MAX_ALLOC 2048
185// Pool sizes
186#define MI_NONPAGED_POOL_SIZE ((size_t)16ULL * 1024 * 1024 * 1024) // 16 GiB
187#define MI_PAGED_POOL_SIZE ((size_t)32ULL * 1024 * 1024 * 1024) // 32 GiB
188
189// Total pages in each pool
190#define NONPAGED_POOL_VA_TOTAL_PAGES (MI_NONPAGED_POOL_SIZE / VirtualPageSize)
191#define PAGED_POOL_VA_TOTAL_PAGES (MI_PAGED_POOL_SIZE / VirtualPageSize)
192
193// Bitmap QWORDs
194#define NONPAGED_POOL_VA_BITMAP_QWORDS ((NONPAGED_POOL_VA_TOTAL_PAGES + 63) / 64)
195#define PAGED_POOL_VA_BITMAP_QWORDS ((PAGED_POOL_VA_TOTAL_PAGES + 63) / 64)
196
197// Number of pages needed for each bitmap (page-aligned)
198#define MI_NONPAGED_BITMAP_PAGES_NEEDED ((NONPAGED_POOL_VA_BITMAP_QWORDS * sizeof(uint64_t) + VirtualPageSize - 1) / VirtualPageSize)
199#define MI_PAGED_BITMAP_PAGES_NEEDED ((PAGED_POOL_VA_BITMAP_QWORDS * sizeof(uint64_t) + VirtualPageSize - 1) / VirtualPageSize)
200
201// Alignment helper
202#define ALIGN_UP(x, align) (((uintptr_t)(x) + ((align)-1)) & ~((uintptr_t)((align)-1)))
203
204// Bitmap memory allocations (physical pages)
205#define MI_NONPAGED_BITMAP_BASE ALIGN_UP(LK_KERNEL_END, VirtualPageSize)
206#define MI_NONPAGED_BITMAP_END (MI_NONPAGED_BITMAP_BASE + MI_NONPAGED_BITMAP_PAGES_NEEDED * VirtualPageSize)
207
208#define MI_PAGED_BITMAP_BASE ALIGN_UP(MI_NONPAGED_BITMAP_END, VirtualPageSize)
209#define MI_PAGED_BITMAP_END (MI_PAGED_BITMAP_BASE + MI_PAGED_BITMAP_PAGES_NEEDED * VirtualPageSize)
210
211// Pool virtual address ranges (page-aligned)
212#define MI_NONPAGED_POOL_BASE ALIGN_UP(MI_PAGED_BITMAP_END, VirtualPageSize)
213#define MI_NONPAGED_POOL_END (MI_NONPAGED_POOL_BASE + MI_NONPAGED_POOL_SIZE)
214
215#define MI_PAGED_POOL_BASE ALIGN_UP(MI_NONPAGED_POOL_END, VirtualPageSize)
216#define MI_PAGED_POOL_END (MI_PAGED_POOL_BASE + MI_PAGED_POOL_SIZE)
217
218// Address Manipulation And Checks
219#define MI_IS_CANONICAL_ADDR(va) \
220({ \
221 uint64_t _va = (uint64_t)(va); \
222 uint64_t _mask = ~((1ULL << 48) - 1); /* bits 63:48 */ \
223 ((_va & _mask) == 0 || (_va & _mask) == _mask); \
224})
225
226#define PFN_TO_PHYS(Pfn) PPFN_TO_PHYSICAL_ADDRESS(INDEX_TO_PPFN(Pfn))
227#define PHYS_TO_INDEX(PhysicalAddress) PPFN_TO_INDEX(PHYSICAL_TO_PPFN(PhysicalAddress))
228
229#define PFN_ERROR UINT64_T_MAX
230
231// Lazy allocations macros
232#define PROT_KERNEL_READ (1ULL << 0)
233#define PROT_KERNEL_WRITE (1ULL << 1)
234#define PROT_KERNEL_NOEXECUTE (1ULL << 2)
235#define PROT_KERNEL_USER (1ULL << 3)
236#define MI_DEMAND_ZERO_BIT (1ULL << 16)
237
238// Tags
239#define MM_POOL_CANARY 'BEKA'
240
241// Stack sizes & protections.
242#define MI_STACK_SIZE 0x4000 // 16KiB
243#define MI_LARGE_STACK_SIZE 0xf000 // 60 KiB
244#define MI_GUARD_PAGE_PROTECTION (1ULL << 17)
245#define MI_DEFAULT_USER_STACK_SIZE 0x100000 // 1 MiB
246
247// Barriers
248
249// Prevents CPU Reordering as well as the MmBarrier functionality.
250#define MmFullBarrier() __sync_synchronize()
251
252// Ensure ordedring of memory operations (memory should be visible before continuing)
253#define MmBarrier() __asm__ __volatile__("mfence" ::: "memory")
254
255// ------------------ TYPE DEFINES ------------------
256typedef uint64_t PAGE_INDEX;
257
258#define MmIsAddressValid(VirtualAddress) MmIsAddressPresent(VirtualAddress)
259
260// ------------------ ACCESS RIGHTS ------------------
261
262#define MT_SECTION_QUERY 0x0001 // Query section info (size, attributes)
263#define MT_SECTION_MAP_WRITE 0x0002 // Map section with write permissions
264#define MT_SECTION_MAP_READ 0x0004 // Map section with read permissions
265#define MT_SECTION_MAP_EXECUTE 0x0008 // Map section with execute permissions
266#define MT_SECTION_EXTEND_SIZE 0x0010 // Extend section size (file-backed sections)
267#define MT_SECTION_MAP_EXECUTE_EXPL 0x0020 // Explicit executable mapping (DEP / NX override)
268
269// All valid section rights
270#define MT_SECTION_ALL_ACCESS 0x003F
271
272typedef int32_t HANDLE, * PHANDLE;
273// ------------------ ENUMERATORS ------------------
274
275typedef enum _PFN_STATE {
276 PfnStateActive, // Actively mapped in a process (RefCount > 0)
277 PfnStateStandby, // Clean, in RAM, not mapped (RefCount == 0)
278 PfnStateModified, // Dirty, in RAM, not mapped (RefCount == 0)
279 PfnStateFree, // Contents are garbage (RefCount == 0)
280 PfnStateZeroed, // Contents are all zeros (RefCount == 0)
281 PfnStateTransition, // Locked for I/O (e.g being paged in/out)
282 PfnStateBad // Unusable (hardware error)
284
285// Page FLAGS (attributes that can be combined)
286typedef enum _PFN_FLAGS {
288 PFN_FLAG_NONPAGED = (1U << 0), // This PFN holds a nonpaged virtual address (not backed by a file), BIT 3 must NOT be set if this bit is active.
289 PFN_FLAG_COPY_ON_WRITE = (1U << 1), // This is a COW page
290 PFN_FLAG_MAPPED_FILE = (1U << 2), // Backed by a file (not swap)
291 PFN_FLAG_LOCKED_FOR_IO = (1U << 3) // Page is pinned for DMA, etc.
293
294typedef enum _VAD_FLAGS {
295 VAD_FLAG_NONE = 0, // No flags, base value.
296 VAD_FLAG_READ = (1U << 0), // Allowed to read from this address.
297 VAD_FLAG_WRITE = (1U << 1), // Allowed to write to this address
298 VAD_FLAG_EXECUTE = (1U << 2), // Instruction execution is permitted on the address.
299 VAD_FLAG_PRIVATE = (1U << 3), // Private (backed by swap file, like pagefile.mtsys)
300 VAD_FLAG_MAPPED_FILE = (1U << 4), // Backed by a file (lets say data.mtdll)
301 VAD_FLAG_COPY_ON_WRITE = (1U << 5), // Allocation comes from a shared physical memory address(s), this can be shared between executables.
302 VAD_FLAG_RESERVED = (1U << 6), // Allocation WILL NOT happen if this flag is set, it takes precedence.
303 VAD_FLAG_GUARD_PAGE = (1U << 7), // This allocation signifies a guard page, if a memory operation is performed on this page, an MT_GUARD_PAGE_VIOLATION exception is raised, and the page turns to a normal stack page.
305
306typedef enum _PAGE_FLAGS {
307 PAGE_PRESENT = 1 << 0, // Bit 0
308 // 0 = page not present (access causes page fault)
309 // 1 = page is present, MMU translates virtual addresses
310
311 PAGE_RW = 1 << 1, // Bit 1
312 // 0 = read-only
313 // 1 = read/write
314
315 PAGE_USER = 1 << 2, // Bit 2
316 // 0 = supervisor (kernel) only
317 // 1 = user-mode access allowed
318
319 PAGE_PWT = 0x8, // Bit 3
320 // Page Write-Through
321 // 0 = write-back caching
322 // 1 = write-through caching
323
324 PAGE_PCD = 0x10, // Bit 4
325 // Page Cache Disable
326 // 0 = cacheable
327 // 1 = cache disabled
328
329 PAGE_ACCESSED = 0x20, // Bit 5
330 // Set by CPU when page is read or written
331
332 PAGE_DIRTY = 0x40, // Bit 6
333 // Set by CPU when page is written to
334
335 PAGE_PS = 0x80, // Bit 7
336 // Page Size
337 // 0 = normal 4KB page
338 // 1 = large page (4MB in PDE, 2MB in PTE for PAE/long mode)
339
340#define PAGE_PAT (1ULL << 7)
341 // PAGE_PAT, Look at MEMORY_CACHING_TYPE enum.
342
343 PAGE_GLOBAL = 0x100, // Bit 8
344 // Global page
345 // Not flushed from TLB on CR3 reload
346
347 PAGE_NX = (1ULL << 63) // Bit 63
348 // No-Execute region
349 // Execution cannot happen in this page.
351
352// NonPagedPools - Allocations occur at max DISPATCH_LEVEL (inclusive). (e.g assert(IRQL == DISPATCH/PASSIVE/APC_LEVEL)
353// PagedPools - Allocations occur at max DISPATCH_LEVEL (exclusive) (e.g assert(IRQL == PASSIVE/APC_LEVEL)
354typedef enum _POOL_TYPE {
355 NonPagedPool = 0, // Non-pageable kernel pool (instant map, available at all IRQLs) (IMPLEMENTED)
356 PagedPool = 1, // Pageable pool (can only be used when IRQL < DISPATCH_LEVEL). (IMPLEMENTED) (NOEXECUTE)
357 NonPagedPoolCacheAligned = 2, // Non-paged, cache-aligned (UNIMPLEMENTED)
358 PagedPoolCacheAligned = 3, // Paged, cache-aligned (UNIMPLEMENTED)
359 NonPagedPoolNx = 4, // Non-paged, non-executable (NX) (IMPLEMENTED)
360 // No MustSucceeds, these are a bad concept, handle errors gracefully.
362
369
374
376
377 MmNonCached = 0, // UC (Uncacheable)
378 // CPU never caches reads/writes.
379 // Every access goes directly to RAM or device.
380 // Most MMIO devices require this.
381
382 MmCached, // WB (Write-Back) (default)
383 // Normal DRAM caching behavior.
384 // Reads/writes go through CPU caches; writes may be delayed.
385 // Fastest and default for regular memory.
386
387 MmWriteCombined, // WC (Write-Combining)
388 // Writes are buffered and combined, NOT cached.
389 // Ideal for framebuffers / GPUs.
390 // Fast sequential writes; CPU collects them and bursts to memory.
391
392 MmWriteThrough, // WT (Write-Through)
393 // Reads are cached, but writes go straight to memory.
394 // Ensures memory is always coherent but slower for writes.
395 // Rarely used today.
396
397 MmNonCachedUnordered, // UC- (Uncacheable Minus)
398 // Similar to UC but allows some reordering and speculative reads.
399 // Safe for some device memory but not all.
400 // Used mostly by OSes for special mappings.
401
402 MmUSWCCached, // USWC (Uncached Speculative Write Combining)
403 // Read = UC-, Write = WC.
404 // Used for some high-end GPU/PCIe devices.
405 // Allows speculative reads + write-combined writes.
406
407 MmHardwareCoherentCached, // WB or WT depending on device
408 // For coherent DMA-capable devices.
409 // Typically WB unless device explicitly requires WT.
411
416
417// ------------------ STRUCTURES ------------------
418
419typedef struct _MMPTE
420{
421 union
422 {
423 uint64_t Value; // Raw 64-bit PTE value
424
425 //
426 // Hardware format when the page is present in memory
427 //
428 struct
429 {
430 uint64_t Present : 1; // 1 = Present
431 uint64_t Write : 1; // Writable
432 uint64_t User : 1; // User-accessible
433 uint64_t WriteThrough : 1; // Write-through cache
434 uint64_t CacheDisable : 1; // Disable caching
435 uint64_t Accessed : 1; // Set by CPU when accessed
436 uint64_t Dirty : 1; // Set by CPU when written
437 uint64_t LargePage : 1; // Large page flag (2MB/1GB) (valid only in PDE)
438 uint64_t Global : 1; // Global TLB entry
439 uint64_t CopyOnWrite : 1; // Software: copy-on-write
440 uint64_t Prototype : 1; // Software: prototype PTE (section)
441 uint64_t Reserved0 : 1; // VAD PTE?
442 uint64_t PageFrameNumber : 40;// Physical page frame number
443 uint64_t Reserved1 : 11; // Reserved by hardware
444 uint64_t NoExecute : 1; // NX bit
446
447 //
448 // Software format when not present
449 // (Paged out / transition / pagefile / prototype)
450 //
451 struct
452 {
453 uint64_t Present : 1; // 0 = Not present
454 uint64_t Write : 1; // Meaning depends on context
455 uint64_t Transition : 1; // 1 = Page is in transition (has PFN) (used for StandBy List)
456 uint64_t Prototype : 1; // 1 = Prototype PTE (mapped section)
457 uint64_t PageFile : 1; // 1 = Paged to disk (pagefile)
458 uint64_t Reserved : 7; // i'm sorry, h.c (sorry for cringing out whoever sees this)
459 uint64_t PageFrameNumber : 32; // Pagefile offset or PFN (if transition)
460 uint64_t SoftwareFlags : 19; // e.g. protection mask, pool type
461 uint64_t NoExecute : 1; // NX still meaningful in software
463 };
465// Guess why I had to put this here? Because the Soft struct took 65 bits, which made it take 16 bytes, overflowing to the next PTE.
466// fun, very fun..
467_Static_assert(sizeof(MMPTE) == 8, "The size of a PTE in a 64bit system is always 8 bytes");
468
469typedef struct _PFN_ENTRY {
470 volatile uint32_t RefCount; // Atomic Reference Count
471 uint8_t State; // PFN_STATE of this Page.
472 uint8_t Flags; // Bitfield of PFN_FLAGS
473 // The Descriptor of the PFN (contains mapping data, the doubly linked list, and file offset, all that depend on the State)
474 union {
475 // State: PfnStateFree, PfnStateZeroed,
476 // PfnStateStandby, PfnStateModified (Used when - INACTIVE)
478
479 // State: PfnStateActive (this is the reverse mapping information) (Used when - ACTIVE, IN USE)
480 struct {
481 struct _MMVAD* Vad; // Pointer to VAD in memory. (might not always be in use)
482 PMMPTE PteAddress; // Pointer to PTE in memory. (is always valid when in use)
484
485 // State: PfnStateStandby or PfnStateModified (for file backed pages) (Used when - SEMI-ACTIVE, PAGED TO DISK, NOT IN CURRENT USE)
486 uint64_t FileOffset; // Offset of bytes in pagefile.mtsys
487
490
491typedef struct _MM_PFN_LIST {
492 struct _DOUBLY_LINKED_LIST ListEntry; // List Head
493 volatile uint64_t Count; // Number of pages in this list.
494 SPINLOCK PfnListLock; // Spinlock for each PFN List to ensure atomicity.
496
497typedef struct _MM_PFN_DATABASE {
498 PPFN_ENTRY PfnEntries; // Pointer to base of the PFN_ENTRY array.
499 size_t TotalPageCount; // Total count of pages in the PFN database.
500 SPINLOCK PfnDatabaseLock; // Global spinlock for adding/popping memory.
501
502 // Page lists
503 MM_PFN_LIST FreePageList; // Pages with garbage data.
504 MM_PFN_LIST ZeroedPageList; // Pages pre-filled with zeros for optimization purposes.
505 MM_PFN_LIST StandbyPageList; // Clean pages, candidates for reuse. (used for loading processes fast)
506 MM_PFN_LIST ModifiedPageList; // Dirty pages, must be written to disk for backing.
507 MM_PFN_LIST BadPageList; // List of bad memory pages
508
509 // Statistics
510 volatile size_t AvailablePages; // Free + Zeroed + Standby
511 volatile size_t TotalReserved; // Kernel, drivers, etc.
513
514typedef struct _MMVAD {
515 uintptr_t StartVa; // Starting Virtual Address.
516 uintptr_t EndVa; // Ending Virtual Address.
517 VAD_FLAGS Flags; // VAD_FLAGS Bitfield
518
519 // VAD Are per process, stored in an AVL.
522 struct _MMVAD* Parent;
523
524 // Height of the node in the tree.
526
527 // If VAD_FLAG_MAPPED_FILE bit is set.
528 struct _FILE_OBJECT* File; // FILE_OBJECT Ptr.
529 uint64_t FileOffset; // Offset into the file this region starts in. (in bytes, so compute arithemetic with addresses and not pages!!)
530
531 // Pointer to owner process.
534
535typedef struct _POOL_HEADER
536{
537 uint32_t PoolCanary; // Must always be equal to - 'BEKA'
538 union
539 {
540 // When the block is FREE, it's part of a list.
542
543 // When the block is ALLOCATED, we store actual metadata info.
544 struct
545 {
546 uint16_t BlockSize; // Size of this block
547 uint16_t PoolIndex; // Index of the slab it came from
548 };
550 uint32_t PoolTag; // Tag of pool. (default - 'ADIR')
552
553typedef struct _POOL_DESCRIPTOR {
554 SINGLE_LINKED_LIST FreeListHead; // Head of the free list
555 size_t BlockSize; // The size of the block + header (so if this is a 32 byte slab, it would be (32 + sizeof(POOL_HEADER))
556 volatile uint64_t FreeCount; // Number of blocks on the free list
557 volatile uint64_t TotalBlocks; // Total blocks ever allocated (statistics)
558 SPINLOCK PoolLock; // Spinlock for this specific pool descriptor.
559 enum _POOL_TYPE PoolType; // The type of the pools this descriptor holds.
561
562typedef struct {
563 uint64_t r_offset; /* Address (RVA) */
564 uint64_t r_info; /* Relocation type and symbol index */
565 int64_t r_addend; /* Addend */
566} Rela;
567
568#define R_X86_64_RELATIVE 8
569
570#pragma pack(push, 1)
571typedef struct {
572 uint8_t Magic[4];
573 uint64_t PreferredImageBase; /* __image_base */
574 uint64_t EntryRVA; /* __entry_rva */
575 uint64_t TextRVA; /* __text_rva */
576 uint64_t TextSize;
577 uint64_t DataRVA;
578 uint64_t DataSize;
579 uint64_t BssSize;
580 uint64_t exports_rva;
581 uint64_t exports_size;
582 uint64_t reloc_rva;
583 uint64_t reloc_size;
584 uint64_t imports_rva; // RVA To import array, then absolute addresses.
585 uint64_t imports_size; // Size of total imports (to find out total we divide by MT_IMPORT_ENTRIES)
586 uint8_t Reserved[20]; /* pad the rest to 128 bytes */
587} MTE_HEADER;
588#pragma pack(pop)
589
591
592// Exports are RVA
593typedef struct {
594 uint64_t name_rva;
595 uint64_t func_rva;
597
598// Imports are absolutes.
599typedef struct {
600 uint64_t lib_name_absolute; // RVA to string "kernel32.dll"
601 uint64_t func_name_absolute; // RVA to string "PrintString"
602 uint64_t iat_addr_absolute; // RVA to the function pointer to be patched
604
605// Represents a section in the file (.text, .data)
606typedef struct _MM_SUBSECTION {
607 uint64_t FileOffset; // Where in the file this data lives
608 uint64_t VirtualSize; // How much RAM it needs
609 VAD_FLAGS Protection; // VAD_FLAGS (Read, Write, Exec)
610 uint32_t IsDemandZero; // 1 for .bss (no file backing), 0 for .text/.data
612
613// Represents the loaded Executable/DLL
614typedef struct _MM_SECTION {
616 uintptr_t PreferredBase;
618
619 // We have 3 distinct regions in our MTE format.
623
625 uint64_t ImageSize; // Total size in Virtual Memory
627
628// ------------------ FUNCTIONS ------------------
629extern MM_PFN_DATABASE PfnDatabase; // Database defined in 'pfn.c'
630
631// Global Externals for signals & constants.
632extern bool MmPfnDatabaseInitialized;
634extern uintptr_t MmSystemRangeStart;
635extern uintptr_t MmHighestUserAddress;
636extern uintptr_t MmUserStartAddress;
637extern uintptr_t MmUserProbeAddress;
638extern uintptr_t MmNonPagedPoolStart;
639extern uintptr_t MmNonPagedPoolEnd;
640extern uintptr_t MmPagedPoolStart;
641extern uintptr_t MmPagedPoolEnd;
642extern uint64_t MmTotalMemory;
643extern uint64_t MmTotalUsableMemory;
644
645
646#define USER_VA_END 0x00007FFFFFFFFFFF
647#define USER_VA_START 0x10000
648
649// general functions
650uint64_t* pml4_from_recursive(void);
651
652// Memory Set.
654void*
656 void* dest, int64_t val, uint64_t len
657)
658{
659 uint8_t* ptr = dest;
660 for (size_t i = 0; i < (size_t)len; i++) {
661 ptr[i] = (uint8_t)val;
662 }
663 return dest;
664}
665
666// Memory copy
668void*
670 void* dest, const void* src, size_t len
671)
672{
673 uint8_t* d = (uint8_t*)dest;
674 const uint8_t* s = (const uint8_t*)src;
675 for (size_t i = 0; i < len; i++) d[i] = s[i];
676 return dest;
677}
678
680int
682 const void* s1, const void* s2, size_t n
683)
684{
685 const uint8_t* p1 = (const uint8_t*)s1;
686 const uint8_t* p2 = (const uint8_t*)s2;
687
688 for (size_t i = 0; i < n; i++) {
689 if (p1[i] != p2[i])
690 return (int)(p1[i] - p2[i]);
691 }
692 return 0;
693}
694
696uint64_t
698{
699 switch (type)
700 {
701 case MmCached: // WB
702 return 0;
703
704 case MmWriteThrough: // WT
705 return PAGE_PWT;
706
707 case MmNonCached: // UC
708 return PAGE_PCD | PAGE_PWT;
709
710 case MmWriteCombined: // WC
711 return PAGE_PAT; // (Index 5)
712
713 case MmNonCachedUnordered: // UC-
714 return PAGE_PAT | PAGE_PCD; // (Index 6)
715
716 case MmUSWCCached: // USWC (UC- reads + WC writes)
717 return PAGE_PAT | PAGE_PWT; // (Index 7 = UC, but write behavior is WC)
718
719 case MmHardwareCoherentCached: // Usually WB; fallback WT if required
720 return 0;
721
722 default:
723 return 0;
724 }
725}
726
730 uint64_t ErrorCode
731)
732
733{
734 FAULT_OPERATION operation;
735
736 // Any of the operations below can also occur not only because of a non-present page (PTE), but a non-present page directory (or above)
737 if (ErrorCode & (1 << 4)) {
738 operation = ExecuteOperation; // Execute (NX Fault) (NX Bit set, and CPU attempted execution on an instruction with it present.)
739 }
740 else if (ErrorCode & (1 << 1)) {
741 operation = WriteOperation; // Write fault (read only page \ not present)
742 }
743 else {
744 operation = ReadOperation; // Read Fault (not present?)
745 }
746
747 return operation;
748}
749
751uint64_t
753 void
754)
755
756{
757 return __read_cr2();
758}
759
761void
763 PMMPTE PtePtr,
764 uint64_t NewPteValue
765)
766
767{
768 InterlockedExchangeU64((volatile uint64_t*)PtePtr, NewPteValue);
769}
770
772bool
774 IN PAGE_INDEX Pfn
775)
776
777{
778 return Pfn <= MmHighestPfn;
779}
780
781// module: pfn.c
782
785 IN PBOOT_INFO BootInfo
786);
787
789HOT
792 IN PFN_STATE ListType
793);
794
795bool
797 void* VirtualAddress
798);
799
800void
802 IN PAGE_INDEX PfnIndex
803);
804
805void
807 PPFN_ENTRY pfn
808);
809
810void
812 PPFN_ENTRY pfn
813);
814
815// module: map.c
816
817void
819 IN void* VirtualAddress
820);
821
822void
824 void
825);
826
827PMMPTE
829 IN uintptr_t va
830);
831
832PMMPTE
834 IN uintptr_t va
835);
836
837PMMPTE
839 IN uintptr_t va
840);
841
842PMMPTE
844 IN uintptr_t va
845);
846
847uintptr_t
849 IN PMMPTE pte
850);
851
854 IN PMMPTE pte
855);
856
857bool
859 IN PMMPTE Pte,
860 IN PAGE_INDEX Pfn
861);
862
863uintptr_t
865 IN void* VirtualAddress
866);
867
868void
870 IN PMMPTE pte
871);
872
873bool
875 IN uintptr_t VirtualAddress
876);
877
878// module: hypermap.c
879
881void*
883 IN uint64_t PfnIndex,
884 OUT PIRQL OldIrql
885);
886
887void
889 IN IRQL OldIrql
890);
891
892// module: pool.c
893
896 void
897);
898
899// Only NonPagedPool and PagedPool are implemented out of the POOL_TYPE enumerator.
901HOT
902void*
904 IN enum _POOL_TYPE PoolType,
905 IN size_t NumberOfBytes,
906 IN uint32_t Tag
907);
908
909void
911 IN void* buf
912);
913
914// module: mmproc.c
915
917void*
919 IN bool LargeStack
920);
921
922void
924 IN void* AllocatedStackTop,
925 IN bool LargeStack
926);
927
930 OUT void** DirectoryTable
931);
932
935 IN PEPROCESS Process,
936 IN uintptr_t PageDirectoryPhysical
937);
938
941 IN PEPROCESS Process,
942 OUT void** OutStackTop,
943 _In_Opt size_t StackReserveSize
944);
945
948 IN PEPROCESS Process,
949 OUT void** OutPeb,
950 OUT void** OutBasicMtdllTypes
951);
952
955 IN PETHREAD Thread,
956 OUT void** OutTeb
957);
958
959// module: vad.c
960
963 IN PEPROCESS Process,
964 _In_Opt _Out_Opt void** BaseAddress,
965 IN size_t NumberOfBytes,
966 IN VAD_FLAGS VadFlags
967);
968
970// TODO Free with explicit size, split vad if needed.
972 IN PEPROCESS Process,
973 IN void* BaseAddress
974);
975
977PMMVAD
979 IN PEPROCESS Process,
980 IN uintptr_t VirtualAddress
981);
982
984uintptr_t
986 IN PEPROCESS Process,
987 IN size_t NumberOfBytes,
988 IN uintptr_t SearchStart,
989 IN uintptr_t SearchEnd // exclusive
990);
991
995 PEPROCESS Process,
996 uintptr_t StartVa,
997 uintptr_t EndVa
998);
999
1000// module: va.c
1001
1002bool
1004 void
1005);
1006
1008uintptr_t
1010 IN POOL_TYPE PoolType,
1011 IN size_t NumberOfBytes
1012);
1013
1014void
1016 IN uintptr_t va,
1017 IN size_t NumberOfBytes,
1018 IN POOL_TYPE PoolType
1019);
1020
1021// module: fault.c
1022
1025 IN uint64_t FaultBits,
1026 IN uint64_t VirtualAddress,
1027 IN PRIVILEGE_MODE PreviousMode,
1028 IN PTRAP_FRAME TrapFrame
1029);
1030
1032bool
1034 void
1035);
1036
1037// module: mmio.c
1038
1039bool
1041 IN void* StartAddress,
1042 IN size_t NumberOfBytes
1043);
1044
1046void*
1048 IN size_t NumberOfBytes,
1049 IN uint64_t HighestAcceptableAddress
1050);
1051
1052void
1054 IN void* BaseAddress,
1055 IN size_t NumberOfBytes
1056);
1057
1059void*
1061 IN uintptr_t PhysicalAddress,
1062 IN size_t NumberOfBytes,
1063 IN MEMORY_CACHING_TYPE CacheType
1064);
1065
1066void
1068 IN void* VirtualAddress,
1069 IN size_t NumberOfBytes
1070);
1071
1072// module: mminit.c
1073
1074bool
1076 IN uint8_t Phase,
1077 IN PBOOT_INFO BootInformation
1078);
1079
1080void
1082 IN PBOOT_INFO BootInfo
1083);
1084
1087 void
1088);
1089
1090// module: section.c
1091
1094 OUT PHANDLE SectionHandle,
1095 IN struct _FILE_OBJECT* FileObject
1096);
1097
1100 IN HANDLE SectionHandle,
1101 IN PEPROCESS Process,
1102 OUT void** EntryPointAddress,
1103 OUT void** BaseAddress
1104);
1105
1106// used by Ob, private.
1107void
1109 void* Object
1110);
1111
1112#endif
#define VALIDATE_SIZE(struc, size)
Definition annotations.h:75
#define HOT
Definition annotations.h:48
#define _In_Opt
Definition annotations.h:10
#define FORCEINLINE
Definition annotations.h:23
#define _Out_Opt
Definition annotations.h:11
#define IN
Definition annotations.h:8
#define OUT
Definition annotations.h:9
#define MUST_USE_RESULT
Definition annotations.h:42
FORCEINLINE uint64_t InterlockedExchangeU64(volatile uint64_t *target, uint64_t value)
Definition atomic.h:42
int32_t * PHANDLE
Definition core.h:58
enum _IRQL IRQL
enum _IRQL * PIRQL
int32_t HANDLE
Definition core.h:58
EPROCESS * PEPROCESS
Definition core.h:52
TRAP_FRAME * PTRAP_FRAME
Definition core.h:56
ETHREAD * PETHREAD
Definition core.h:44
struct _SINGLE_LINKED_LIST SINGLE_LINKED_LIST
struct _BOOT_INFO * PBOOT_INFO
FORCEINLINE unsigned long __read_cr2(void)
Definition intrin.h:82
_PAGE_FLAGS
Definition mm.h:306
@ PAGE_RW
Definition mm.h:311
@ PAGE_ACCESSED
Definition mm.h:329
@ PAGE_PWT
Definition mm.h:319
@ PAGE_DIRTY
Definition mm.h:332
@ PAGE_GLOBAL
Definition mm.h:343
@ PAGE_USER
Definition mm.h:315
@ PAGE_PRESENT
Definition mm.h:307
@ PAGE_NX
Definition mm.h:347
@ PAGE_PCD
Definition mm.h:324
@ PAGE_PS
Definition mm.h:335
MUST_USE_RESULT void * MiCreateKernelStack(IN bool LargeStack)
Definition mmproc.c:26
void MmFreeContigiousMemory(IN void *BaseAddress, IN size_t NumberOfBytes)
Definition mmio.c:213
enum _SYSTEM_PHASE_ROUTINE SYSTEM_PHASE_ROUTINE
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)
Definition fault.c:28
_PFN_STATE
Definition mm.h:275
@ PfnStateTransition
Definition mm.h:281
@ PfnStateFree
Definition mm.h:279
@ PfnStateZeroed
Definition mm.h:280
@ PfnStateModified
Definition mm.h:278
@ PfnStateActive
Definition mm.h:276
@ PfnStateStandby
Definition mm.h:277
@ PfnStateBad
Definition mm.h:282
FORCEINLINE void MiAtomicExchangePte(PMMPTE PtePtr, uint64_t NewPteValue)
Definition mm.h:762
bool MiCheckForContigiousMemory(IN void *StartAddress, IN size_t NumberOfBytes)
Definition mmio.c:25
MUST_USE_RESULT bool MmInvalidAccessAllowed(void)
Definition fault.c:496
FORCEINLINE uint64_t MiRetrieveLastFaultyAddress(void)
Definition mm.h:752
uintptr_t MiTranslateVirtualToPhysical(IN void *VirtualAddress)
Definition map.c:512
enum _PFN_STATE PFN_STATE
uintptr_t MiTranslatePteToVa(IN PMMPTE pte)
Definition map.c:337
void MiUnlinkPageFromList(PPFN_ENTRY pfn)
Definition pfn.c:530
struct _MM_SUBSECTION * PMM_SUBSECTION
MUST_USE_RESULT uintptr_t MiAllocatePoolVa(IN POOL_TYPE PoolType, IN size_t NumberOfBytes)
Definition va.c:213
_SYSTEM_PHASE_ROUTINE
Definition mm.h:412
@ SYSTEM_PHASE_INITIALIZE_PAT_ONLY
Definition mm.h:414
@ SYSTEM_PHASE_INITIALIZE_ALL
Definition mm.h:413
_POOL_TYPE
Definition mm.h:354
@ PagedPoolCacheAligned
Definition mm.h:358
@ NonPagedPoolCacheAligned
Definition mm.h:357
@ NonPagedPool
Definition mm.h:355
@ PagedPool
Definition mm.h:356
@ NonPagedPoolNx
Definition mm.h:359
FORCEINLINE int kmemcmp(const void *s1, const void *s2, size_t n)
Definition mm.h:681
FORCEINLINE bool MiIsValidPfn(IN PAGE_INDEX Pfn)
Definition mm.h:773
_VAD_FLAGS
Definition mm.h:294
@ VAD_FLAG_NONE
Definition mm.h:295
@ VAD_FLAG_READ
Definition mm.h:296
@ VAD_FLAG_RESERVED
Definition mm.h:302
@ VAD_FLAG_COPY_ON_WRITE
Definition mm.h:301
@ VAD_FLAG_PRIVATE
Definition mm.h:299
@ VAD_FLAG_GUARD_PAGE
Definition mm.h:303
@ VAD_FLAG_MAPPED_FILE
Definition mm.h:300
@ VAD_FLAG_EXECUTE
Definition mm.h:298
@ VAD_FLAG_WRITE
Definition mm.h:297
enum _MEMORY_CACHING_TYPE MEMORY_CACHING_TYPE
MUST_USE_RESULT void * MmMapIoSpace(IN uintptr_t PhysicalAddress, IN size_t NumberOfBytes, IN MEMORY_CACHING_TYPE CacheType)
Definition mmio.c:269
MTSTATUS MmMapViewOfSection(IN HANDLE SectionHandle, IN PEPROCESS Process, OUT void **EntryPointAddress, OUT void **BaseAddress)
Definition section.c:110
MUST_USE_RESULT MTSTATUS MmIsAddressRangeFree(PEPROCESS Process, uintptr_t StartVa, uintptr_t EndVa)
Definition vad.c:860
struct _MM_SECTION * PMM_SECTION
void MmpDeleteSection(void *Object)
Definition section.c:198
_MEMORY_CACHING_TYPE
Definition mm.h:375
@ MmUSWCCached
Definition mm.h:402
@ MmCached
Definition mm.h:382
@ MmNonCached
Definition mm.h:377
@ MmWriteThrough
Definition mm.h:392
@ MmNonCachedUnordered
Definition mm.h:397
@ MmWriteCombined
Definition mm.h:387
@ MmHardwareCoherentCached
Definition mm.h:407
void MiReloadTLBs(void)
Definition map.c:499
enum _FAULT_OPERATION * PFAULT_OPERATION
enum _PRIVILEGE_MODE * PPRIVILEGE_MODE
enum _POOL_TYPE POOL_TYPE
enum _FAULT_OPERATION FAULT_OPERATION
void MmUnmapIoSpace(IN void *VirtualAddress, IN size_t NumberOfBytes)
Definition mmio.c:335
struct _MMPTE * PMMPTE
void MiReleasePhysicalPage(IN PAGE_INDEX PfnIndex)
Definition pfn.c:441
struct _MM_SUBSECTION MM_SUBSECTION
struct _POOL_DESCRIPTOR POOL_DESCRIPTOR
MUST_USE_RESULT void * MiMapPageInHyperspace(IN uint64_t PfnIndex, OUT PIRQL OldIrql)
Definition hypermap.c:37
FORCEINLINE FAULT_OPERATION MiRetrieveOperationFromErrorCode(uint64_t ErrorCode)
Definition mm.h:729
FORCEINLINE void * kmemcpy(void *dest, const void *src, size_t len)
Definition mm.h:669
struct _MM_PFN_DATABASE MM_PFN_DATABASE
void MiFreePoolVaContiguous(IN uintptr_t va, IN size_t NumberOfBytes, IN POOL_TYPE PoolType)
Definition va.c:367
FORCEINLINE uint64_t MiCacheToFlags(MEMORY_CACHING_TYPE type)
Definition mm.h:697
struct _PFN_ENTRY PFN_ENTRY
MTSTATUS MmCreateProcessAddressSpace(OUT void **DirectoryTable)
Definition mmproc.c:221
MTSTATUS MiInitializePoolSystem(void)
Definition pool.c:36
#define PAGE_PAT
Definition mm.h:340
enum _PRIVILEGE_MODE PRIVILEGE_MODE
bool MiIsWithinBoundsOfReleasePhysicalPage(void *VirtualAddress)
Definition pfn.c:516
MUST_USE_RESULT void * MmAllocateContigiousMemory(IN size_t NumberOfBytes, IN uint64_t HighestAcceptableAddress)
Definition mmio.c:87
struct _MMVAD MMVAD
uint64_t PAGE_INDEX
Definition mm.h:256
FORCEINLINE void * kmemset(void *dest, int64_t val, uint64_t len)
Definition mm.h:655
struct _POOL_DESCRIPTOR * PPOOL_DESCRIPTOR
PMMPTE MiGetPdptePointer(IN uintptr_t va)
Definition map.c:177
enum _VAD_FLAGS VAD_FLAGS
struct _MM_SECTION MM_SECTION
MTSTATUS MmFreeVirtualMemory(IN PEPROCESS Process, IN void *BaseAddress)
Definition vad.c:871
MTSTATUS MmCreateUserStack(IN PEPROCESS Process, OUT void **OutStackTop, _In_Opt size_t StackReserveSize)
Definition mmproc.c:436
_FAULT_OPERATION
Definition mm.h:363
@ ExecuteOperation
Definition mm.h:367
@ ReadOperation
Definition mm.h:365
@ WriteOperation
Definition mm.h:366
@ FaultOpInvalid
Definition mm.h:364
#define PML4_INDEX_SHIFT
Definition mm.h:39
MTSTATUS MmDeleteProcessAddressSpace(IN PEPROCESS Process, IN uintptr_t PageDirectoryPhysical)
Definition mmproc.c:391
MUST_USE_RESULT HOT PAGE_INDEX MiRequestPhysicalPage(IN PFN_STATE ListType)
Definition pfn.c:333
void MiMoveUefiDataToHigherHalf(IN PBOOT_INFO BootInfo)
Definition mminit.c:176
MTSTATUS MiInitializePfnDatabase(IN PBOOT_INFO BootInfo)
Definition pfn.c:102
PMMPTE MiGetPdePointer(IN uintptr_t va)
Definition map.c:219
uint64_t * pml4_from_recursive(void)
Definition map.c:31
MTSTATUS MmAllocateVirtualMemory(IN PEPROCESS Process, _In_Opt _Out_Opt void **BaseAddress, IN size_t NumberOfBytes, IN VAD_FLAGS VadFlags)
Definition vad.c:740
MUST_USE_RESULT PMMVAD MiFindVad(IN PEPROCESS Process, IN uintptr_t VirtualAddress)
Definition vad.c:352
bool MmIsAddressPresent(IN uintptr_t VirtualAddress)
Definition map.c:544
enum _PAGE_FLAGS PAGE_FLAGS
PMMPTE MiGetPml4ePointer(IN uintptr_t va)
Definition map.c:147
bool MmInitSystem(IN uint8_t Phase, IN PBOOT_INFO BootInformation)
Definition mminit.c:77
PAGE_INDEX MiTranslatePteToPfn(IN PMMPTE pte)
Definition map.c:310
MTSTATUS MmCreateTeb(IN PETHREAD Thread, OUT void **OutTeb)
Definition mmproc.c:536
struct _POOL_HEADER POOL_HEADER
struct _MMVAD * PMMVAD
void MmFreePool(IN void *buf)
Definition pool.c:632
void MiFreeKernelStack(IN void *AllocatedStackTop, IN bool LargeStack)
Definition mmproc.c:149
void MiUnmapHyperSpaceMap(IN IRQL OldIrql)
Definition hypermap.c:95
MUST_USE_RESULT uintptr_t MmFindFreeAddressSpace(IN PEPROCESS Process, IN size_t NumberOfBytes, IN uintptr_t SearchStart, IN uintptr_t SearchEnd)
Definition vad.c:725
struct _PFN_ENTRY * PPFN_ENTRY
struct _MMPTE MMPTE
_PFN_FLAGS
Definition mm.h:286
@ PFN_FLAG_NONE
Definition mm.h:287
@ PFN_FLAG_MAPPED_FILE
Definition mm.h:290
@ PFN_FLAG_COPY_ON_WRITE
Definition mm.h:289
@ PFN_FLAG_NONPAGED
Definition mm.h:288
@ PFN_FLAG_LOCKED_FOR_IO
Definition mm.h:291
bool MiInitializePoolVaSpace(void)
Definition va.c:35
PMMPTE MiGetPtePointer(IN uintptr_t va)
Definition map.c:76
MUST_USE_RESULT HOT void * MmAllocatePoolWithTag(IN enum _POOL_TYPE PoolType, IN size_t NumberOfBytes, IN uint32_t Tag)
Definition pool.c:443
void MiInvalidateTlbForVa(IN void *VirtualAddress)
Definition map.c:273
void MiUnmapPte(IN PMMPTE pte)
Definition map.c:385
bool MiAtomicSetTransitionPte(IN PMMPTE Pte, IN PAGE_INDEX Pfn)
Definition map.c:438
enum _PFN_FLAGS PFN_FLAGS
struct _POOL_HEADER * PPOOL_HEADER
#define PML4_INDEX_MASK
Definition mm.h:40
_PRIVILEGE_MODE
Definition mm.h:370
@ KernelMode
Definition mm.h:371
@ UserMode
Definition mm.h:372
MTSTATUS MmCreateSection(OUT PHANDLE SectionHandle, IN struct _FILE_OBJECT *FileObject)
Definition section.c:25
MTSTATUS MmCreatePeb(IN PEPROCESS Process, OUT void **OutPeb, OUT void **OutBasicMtdllTypes)
Definition mmproc.c:502
MTSTATUS MmInitSections(void)
Definition mminit.c:58
struct _SPINLOCK SPINLOCK
int32_t MTSTATUS
Definition mtstatus.h:12
PAGE_INDEX MmHighestPfn
Definition pfn.c:31
bool MmPfnDatabaseInitialized
Definition pfn.c:30
uint64_t MmTotalUsableMemory
Definition pfn.c:34
MM_PFN_DATABASE PfnDatabase
Definition pfn.c:29
uint64_t MmTotalMemory
Definition pfn.c:33
uintptr_t MmNonPagedPoolEnd
Definition pool.c:31
uintptr_t MmNonPagedPoolStart
Definition pool.c:30
uintptr_t MmPagedPoolStart
Definition pool.c:32
uintptr_t MmPagedPoolEnd
Definition pool.c:33
uintptr_t MmSystemRangeStart
Definition process.c:31
uintptr_t MmUserProbeAddress
Definition process.c:34
uintptr_t MmUserStartAddress
Definition process.c:33
uintptr_t MmHighestUserAddress
Definition process.c:32
MM_PFN_LIST StandbyPageList
Definition mm.h:505
volatile size_t AvailablePages
Definition mm.h:510
MM_PFN_LIST BadPageList
Definition mm.h:507
size_t TotalPageCount
Definition mm.h:499
MM_PFN_LIST ModifiedPageList
Definition mm.h:506
volatile size_t TotalReserved
Definition mm.h:511
PPFN_ENTRY PfnEntries
Definition mm.h:498
MM_PFN_LIST ZeroedPageList
Definition mm.h:504
SPINLOCK PfnDatabaseLock
Definition mm.h:500
MM_PFN_LIST FreePageList
Definition mm.h:503
volatile uint64_t Count
Definition mm.h:493
SPINLOCK PfnListLock
Definition mm.h:494
struct _DOUBLY_LINKED_LIST ListEntry
Definition mm.h:492
uint64_t EntryPointOffset
Definition mm.h:624
MM_SUBSECTION Text
Definition mm.h:620
MM_SUBSECTION Data
Definition mm.h:621
uint64_t ImageSize
Definition mm.h:625
struct _FILE_OBJECT * FileObject
Definition mm.h:615
MM_SUBSECTION Bss
Definition mm.h:622
MM_SUBSECTION WholeFileSection
Definition mm.h:617
uintptr_t PreferredBase
Definition mm.h:616
uint32_t IsDemandZero
Definition mm.h:610
uint64_t FileOffset
Definition mm.h:607
uint64_t VirtualSize
Definition mm.h:608
VAD_FLAGS Protection
Definition mm.h:609
Definition mm.h:420
uint64_t Accessed
Definition mm.h:435
uint64_t Prototype
Definition mm.h:440
uint64_t Global
Definition mm.h:438
struct _MMPTE::@172372265215056352375070220246156106027174106113::@200357034104227323320222006243127050212100105247 Hard
uint64_t Dirty
Definition mm.h:436
uint64_t CopyOnWrite
Definition mm.h:439
uint64_t Reserved0
Definition mm.h:441
uint64_t Write
Definition mm.h:431
uint64_t PageFile
Definition mm.h:457
uint64_t PageFrameNumber
Definition mm.h:442
uint64_t WriteThrough
Definition mm.h:433
uint64_t Reserved
Definition mm.h:458
uint64_t Present
Definition mm.h:430
uint64_t Transition
Definition mm.h:455
uint64_t User
Definition mm.h:432
uint64_t LargePage
Definition mm.h:437
uint64_t Value
Definition mm.h:423
uint64_t CacheDisable
Definition mm.h:434
uint64_t NoExecute
Definition mm.h:444
uint64_t SoftwareFlags
Definition mm.h:460
struct _MMPTE::@172372265215056352375070220246156106027174106113::@277354034164206104264133322054061025100052052376 Soft
uint64_t Reserved1
Definition mm.h:443
Definition mm.h:514
VAD_FLAGS Flags
Definition mm.h:517
uintptr_t EndVa
Definition mm.h:516
struct _MMVAD * Parent
Definition mm.h:522
uintptr_t StartVa
Definition mm.h:515
uint64_t FileOffset
Definition mm.h:529
int Height
Definition mm.h:525
struct _FILE_OBJECT * File
Definition mm.h:528
struct _EPROCESS * OwningProcess
Definition mm.h:532
struct _MMVAD * LeftChild
Definition mm.h:520
struct _MMVAD * RightChild
Definition mm.h:521
union _PFN_ENTRY::@217024126340164016372152071216274230164113211246 Descriptor
volatile uint32_t RefCount
Definition mm.h:470
struct _PFN_ENTRY::@217024126340164016372152071216274230164113211246::@301110335271023021153236134322146064331241142124 Mapping
uint8_t State
Definition mm.h:471
uint64_t FileOffset
Definition mm.h:486
PMMPTE PteAddress
Definition mm.h:482
struct _MMVAD * Vad
Definition mm.h:481
struct _DOUBLY_LINKED_LIST ListEntry
Definition mm.h:477
uint8_t Flags
Definition mm.h:472
enum _POOL_TYPE PoolType
Definition mm.h:559
size_t BlockSize
Definition mm.h:555
SPINLOCK PoolLock
Definition mm.h:558
volatile uint64_t FreeCount
Definition mm.h:556
volatile uint64_t TotalBlocks
Definition mm.h:557
SINGLE_LINKED_LIST FreeListHead
Definition mm.h:554
uint16_t BlockSize
Definition mm.h:546
uint16_t PoolIndex
Definition mm.h:547
SINGLE_LINKED_LIST FreeListEntry
Definition mm.h:541
uint32_t PoolCanary
Definition mm.h:537
uint32_t PoolTag
Definition mm.h:550
union _POOL_HEADER::@321115223011072362277073135231015025151337071364 Metadata
uint64_t func_rva
Definition mm.h:595
uint64_t name_rva
Definition mm.h:594
uint64_t lib_name_absolute
Definition mm.h:600
uint64_t func_name_absolute
Definition mm.h:601
uint64_t iat_addr_absolute
Definition mm.h:602
uint64_t DataSize
Definition mm.h:578
uint8_t Magic[4]
Definition mm.h:572
uint64_t reloc_rva
Definition mm.h:582
uint64_t DataRVA
Definition mm.h:577
uint64_t EntryRVA
Definition mm.h:574
uint64_t PreferredImageBase
Definition mm.h:573
uint64_t imports_size
Definition mm.h:585
uint64_t imports_rva
Definition mm.h:584
uint64_t TextSize
Definition mm.h:576
uint64_t reloc_size
Definition mm.h:583
uint64_t exports_rva
Definition mm.h:580
uint64_t TextRVA
Definition mm.h:575
uint64_t BssSize
Definition mm.h:579
uint8_t Reserved[20]
Definition mm.h:586
uint64_t exports_size
Definition mm.h:581
Definition mm.h:562
uint64_t r_offset
Definition mm.h:563
uint64_t r_info
Definition mm.h:564
int64_t r_addend
Definition mm.h:565