ReactOS 0.4.17-dev-1190-g4c812f4
mm.h
Go to the documentation of this file.
1/*
2 * kernel internal memory management definitions for amd64
3 */
4#pragma once
5
7
8#define _MI_PAGING_LEVELS 4
9#define _MI_HAS_NO_EXECUTE 1
10
11/* Memory layout base addresses (This is based on Vista!) */
12#define MI_USER_PROBE_ADDRESS (PVOID)0x000007FFFFFF0000ULL
13#define MI_DEFAULT_SYSTEM_RANGE_START (PVOID)0xFFFF080000000000ULL
14#define MI_REAL_SYSTEM_RANGE_START 0xFFFF800000000000ULL
15//#define MI_PAGE_TABLE_BASE 0xFFFFF68000000000ULL // 512 GB page tables
16#define HYPER_SPACE 0xFFFFF70000000000ULL // 512 GB hyper space [MiVaProcessSpace]
17#define HYPER_SPACE_END 0xFFFFF77FFFFFFFFFULL
18//#define MI_SHARED_SYSTEM_PAGE 0xFFFFF78000000000ULL
19#define MI_SYSTEM_CACHE_WS_START 0xFFFFF78000001000ULL // 512 GB - 4 KB system cache working set
20//#define MI_LOADER_MAPPINGS 0xFFFFF80000000000ULL // 512 GB loader mappings aka KSEG0_BASE (NDK) [MiVaBootLoaded]
21#define MM_SYSTEM_SPACE_START 0xFFFFF88000000000ULL // 128 GB system PTEs [MiVaSystemPtes]
22#define MI_DEBUG_MAPPING (PVOID)0xFFFFF89FFFFFF000ULL // FIXME should be allocated from System PTEs
23#define MI_PAGED_POOL_START (PVOID)0xFFFFF8A000000000ULL // 128 GB paged pool [MiVaPagedPool]
24//#define MI_PAGED_POOL_END 0xFFFFF8BFFFFFFFFFULL
25//#define MI_SESSION_SPACE_START 0xFFFFF90000000000ULL // 512 GB session space [MiVaSessionSpace]
26//#define MI_SESSION_VIEW_END 0xFFFFF97FFF000000ULL
27#define MI_SESSION_SPACE_END 0xFFFFF98000000000ULL
28#define MI_SYSTEM_CACHE_START 0xFFFFF98000000000ULL // 1 TB system cache (on Vista+ this is dynamic VA space) [MiVaSystemCache,MiVaSpecialPoolPaged,MiVaSpecialPoolNonPaged]
29#define MI_SYSTEM_CACHE_END 0xFFFFFA7FFFFFFFFFULL
30#define MI_PFN_DATABASE 0xFFFFFA8000000000ULL // up to 5.5 TB PFN database followed by non paged pool [MiVaPfnDatabase/MiVaNonPagedPool]
31#define MI_NONPAGED_POOL_END (PVOID)0xFFFFFFFFFFBFFFFFULL
32//#define MM_HAL_VA_START 0xFFFFFFFFFFC00000ULL // 4 MB HAL mappings, defined in NDK [MiVaHal]
33#define MI_HIGHEST_SYSTEM_ADDRESS (PVOID)0xFFFFFFFFFFFFFFFFULL
34#define MmSystemRangeStart ((PVOID)MI_REAL_SYSTEM_RANGE_START)
35
36/* WOW64 address definitions */
37#define MM_HIGHEST_USER_ADDRESS_WOW64 0x7FFEFFFF
38#define MM_SYSTEM_RANGE_START_WOW64 0x80000000
39
40/* The size of the virtual memory area that is mapped using a single PDE */
41#define PDE_MAPPED_VA (PTE_PER_PAGE * PAGE_SIZE)
42
43/* Misc address definitions */
44//#define MI_NON_PAGED_SYSTEM_START_MIN MM_SYSTEM_SPACE_START // FIXME
45//#define MI_SYSTEM_PTE_START MM_SYSTEM_SPACE_START
46//#define MI_SYSTEM_PTE_END (MI_SYSTEM_PTE_START + MI_NUMBER_SYSTEM_PTES * PAGE_SIZE - 1)
47#define MI_SYSTEM_PTE_BASE (PVOID)MiAddressToPte(KSEG0_BASE)
48#define MM_HIGHEST_VAD_ADDRESS (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
49#define MI_MAPPING_RANGE_START HYPER_SPACE
50#define MI_MAPPING_RANGE_END (MI_MAPPING_RANGE_START + MI_HYPERSPACE_PTES * PAGE_SIZE)
51#define MI_DUMMY_PTE (MI_MAPPING_RANGE_END + PAGE_SIZE)
52#define MI_VAD_BITMAP (MI_DUMMY_PTE + PAGE_SIZE)
53#define MI_WORKING_SET_LIST (MI_VAD_BITMAP + PAGE_SIZE)
54
55/* Memory sizes */
56#define MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING ((255 * _1MB) >> PAGE_SHIFT)
57#define MI_MIN_PAGES_FOR_SYSPTE_TUNING ((19 * _1MB) >> PAGE_SHIFT)
58#define MI_MIN_PAGES_FOR_SYSPTE_BOOST ((32 * _1MB) >> PAGE_SHIFT)
59#define MI_MIN_PAGES_FOR_SYSPTE_BOOST_BOOST ((256 * _1MB) >> PAGE_SHIFT)
60#define MI_MIN_INIT_PAGED_POOLSIZE (32 * _1MB)
61#define MI_MAX_INIT_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024)
62#define MI_MAX_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024)
63#define MI_SYSTEM_VIEW_SIZE (512 * _1MB)
64#define MI_SESSION_VIEW_SIZE (512 * _1MB)
65#define MI_SESSION_POOL_SIZE (64 * _1MB)
66#define MI_SESSION_IMAGE_SIZE (16 * _1MB)
67#define MI_SESSION_WORKING_SET_SIZE (16 * _1MB)
68#define MI_SESSION_SIZE (MI_SESSION_VIEW_SIZE + \
69 MI_SESSION_POOL_SIZE + \
70 MI_SESSION_IMAGE_SIZE + \
71 MI_SESSION_WORKING_SET_SIZE)
72#define MI_MIN_ALLOCATION_FRAGMENT (4 * _1KB)
73#define MI_ALLOCATION_FRAGMENT (64 * _1KB)
74#define MI_MAX_ALLOCATION_FRAGMENT (2 * _1MB)
75
76/* Misc constants */
77#define MM_PTE_SOFTWARE_PROTECTION_BITS 5
78#define MI_MIN_SECONDARY_COLORS 8
79#define MI_SECONDARY_COLORS 64
80#define MI_MAX_SECONDARY_COLORS 1024
81#define MI_NUMBER_SYSTEM_PTES (22000 * 22)
82#define MI_MAX_FREE_PAGE_LISTS 4
83#define MI_HYPERSPACE_PTES (256 - 1)
84#define MI_ZERO_PTES (32)
85#define MI_MAX_ZERO_BITS 53
86#define SESSION_POOL_LOOKASIDES 21
87
88/* MMPTE related defines */
89#define MM_EMPTY_PTE_LIST ((ULONG64)0xFFFFFFFF)
90#define MM_EMPTY_LIST ((ULONG_PTR)-1)
91
92
93/* Easy accessing PFN in PTE */
94#define PFN_FROM_PTE(v) ((v)->u.Hard.PageFrameNumber)
95#define PFN_FROM_PDE(v) ((v)->u.Hard.PageFrameNumber)
96#define PFN_FROM_PPE(v) ((v)->u.Hard.PageFrameNumber)
97#define PFN_FROM_PXE(v) ((v)->u.Hard.PageFrameNumber)
98
99/* Macros for portable PTE modification */
100#define MI_MAKE_DIRTY_PAGE(x) ((x)->u.Hard.Dirty = 1)
101#define MI_MAKE_CLEAN_PAGE(x) ((x)->u.Hard.Dirty = 0)
102#define MI_MAKE_ACCESSED_PAGE(x) ((x)->u.Hard.Accessed = 1)
103#define MI_IS_PAGE_LARGE(x) ((x)->u.Hard.LargePage == 1)
104#if !defined(CONFIG_SMP)
105#define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Write == 1)
106#else
107#define MI_IS_PAGE_WRITEABLE(x) ((x)->u.Hard.Writable == 1)
108#endif
109#define MI_IS_PAGE_COPY_ON_WRITE(x)((x)->u.Hard.CopyOnWrite == 1)
110#define MI_IS_PAGE_EXECUTABLE(x) ((x)->u.Hard.NoExecute == 0)
111#define MI_IS_PAGE_DIRTY(x) ((x)->u.Hard.Dirty == 1)
112#define MI_MAKE_OWNER_PAGE(x) ((x)->u.Hard.Owner = 1)
113#if !defined(CONFIG_SMP)
114#define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Write = 1)
115#else
116#define MI_MAKE_WRITE_PAGE(x) ((x)->u.Hard.Writable = 1)
117#endif
118
119/* Macros to identify the page fault reason from the error code */
120#define MI_IS_NOT_PRESENT_FAULT(FaultCode) !BooleanFlagOn(FaultCode, 0x00000001)
121#define MI_IS_WRITE_ACCESS(FaultCode) BooleanFlagOn(FaultCode, 0x00000002)
122// 0x00000004: user-mode access.
123// 0x00000008: reserved bit violation.
124#define MI_IS_INSTRUCTION_FETCH(FaultCode) BooleanFlagOn(FaultCode, 0x00000010)
125// 0x00000020: protection-key violation.
126// 0x00000040: shadow-stack access.
127// Bits 7-14: reserved.
128// 0x00008000: violation of SGX-specific access-control requirements.
129// Bits 16-31: reserved.
130
131/* On x64, these are the same */
132#define MI_WRITE_VALID_PPE MI_WRITE_VALID_PTE
133#define ValidKernelPpe ValidKernelPde
134
135/* Convert an address to a corresponding PTE */
137PMMPTE
139{
141 Offset &= 0xFFFFFFFFFULL << 3;
142 return (PMMPTE)(PTE_BASE + Offset);
143}
144#define MiAddressToPte(x) _MiAddressToPte((PVOID)(x))
145
146/* Convert an address to a corresponding PDE */
148PMMPTE
150{
152 Offset &= 0x7FFFFFF << 3;
153 return (PMMPTE)(PDE_BASE + Offset);
154}
155#define MiAddressToPde(x) _MiAddressToPde((PVOID)(x))
156
157/* Convert an address to a corresponding PPE */
159PMMPTE
161{
163 Offset &= 0x3FFFF << 3;
164 return (PMMPTE)(PPE_BASE + Offset);
165}
166
167/* Convert an address to a corresponding PXE */
169PMMPTE
171{
173 Offset &= PXI_MASK << 3;
174 return (PMMPTE)(PXE_BASE + Offset);
175}
176
177/* Convert an address to a corresponding PTE offset/index */
179ULONG
181{
182 return ((((ULONG64)Address) >> PTI_SHIFT) & 0x1FF);
183}
184#define MiAddressToPteOffset(x) MiAddressToPti(x) // FIXME: bad name
185
186/* Convert an address to a corresponding PDE offset/index */
188ULONG
190{
191 return ((((ULONG64)Address) >> PDI_SHIFT) & 0x1FF);
192}
193#define MiAddressToPdeOffset(x) MiAddressToPdi(x)
194#define MiGetPdeOffset(x) MiAddressToPdi(x)
195
196/* Convert an address to a corresponding PXE offset/index */
198ULONG
200{
201 return ((((ULONG64)Address) >> PXI_SHIFT) & 0x1FF);
202}
203
204/* Convert a PTE into a corresponding address */
206PVOID
208{
209 /* Use signed math */
210 return (PVOID)(((LONG64)PointerPte << 25) >> 16);
211}
212
213/* Convert a PDE into a corresponding address */
215PVOID
217{
218 /* Use signed math */
219 return (PVOID)(((LONG64)PointerPde << 34) >> 16);
220}
221
222/* Convert a PPE into a corresponding address */
224PVOID
226{
227 /* Use signed math */
228 return (PVOID)(((LONG64)PointerPpe << 43) >> 16);
229}
230
231/* Convert a PXE into a corresponding address */
233PVOID
235{
236 /* Use signed math */
237 return (PVOID)(((LONG64)PointerPxe << 52) >> 16);
238}
239
240/* Convert a PDE into its lowest PTE */
242PMMPTE
244{
245 return (PMMPTE)MiPteToAddress(PointerPde);
246}
247
248/* Convert a PPE into its lowest PTE */
250PMMPTE
252{
253 return (PMMPTE)MiPdeToAddress(PointerPpe);
254}
255
256/* Convert a PXE into its lowest PTE */
258PMMPTE
260{
261 return (PMMPTE)MiPpeToAddress(PointerPxe);
262}
263
264/* Convert a PTE to a corresponding PDE */
266PMMPDE
268{
269 return (PMMPDE)MiAddressToPte(PointerPte);
270}
271
272/* Convert a PTE to a corresponding PPE */
274PMMPPE
276{
277 return (PMMPPE)MiAddressToPde(PointerPte);
278}
279
280/* Convert a PTE to a corresponding PXE */
282PMMPXE
284{
285 return (PMMPXE)MiAddressToPpe(PointerPte);
286}
287
288/* Convert a PDE to a corresponding PPE */
290PMMPDE
292{
293 return (PMMPPE)MiAddressToPte(PointerPde);
294}
295
296/* Convert a PDE to a corresponding PXE */
298PMMPXE
300{
301 return (PMMPXE)MiAddressToPde(PointerPde);
302}
303
304/* Check P*E boundaries */
305#define MiIsPteOnPdeBoundary(PointerPte) \
306 ((((ULONG_PTR)(PointerPte)) & (PAGE_SIZE - 1)) == 0)
307#define MiIsPteOnPpeBoundary(PointerPte) \
308 ((((ULONG_PTR)(PointerPte)) & (PDE_PER_PAGE * PAGE_SIZE - 1)) == 0)
309#define MiIsPteOnPxeBoundary(PointerPte) \
310 ((((ULONG_PTR)(PointerPte)) & (PPE_PER_PAGE * PDE_PER_PAGE * PAGE_SIZE - 1)) == 0)
311
312//
313// Decodes a Prototype PTE into the underlying PTE
314//
315#define MiProtoPteToPte(x) \
316 (PMMPTE)(((LONG64)(x)->u.Long) >> 16) /* Sign extend 48 bits */
317
318//
319// Decodes a Prototype PTE into the underlying PTE
320// The 48 bit signed value gets sign-extended to 64 bits.
321//
322#define MiSubsectionPteToSubsection(x) \
323 (PMMPTE)((LONG64)(x)->u.Subsect.SubsectionAddress)
324
326VOID
328 _Out_ PMMPTE NewPte,
330{
331 /* Mark this as a prototype */
332 NewPte->u.Long = 0;
333 NewPte->u.Subsect.Prototype = 1;
334
335 /* Store the lower 48 bits of the Segment address */
336 NewPte->u.Subsect.SubsectionAddress = ((ULONG_PTR)Segment & 0x0000FFFFFFFFFFFF);
337}
338
340VOID
342 IN PMMPTE PointerPte)
343{
344 /* Store the Address */
345 NewPte->u.Long = (ULONG64)PointerPte << 16;
346
347 /* Mark this as a prototype PTE */
348 NewPte->u.Proto.Prototype = 1;
349
350 ASSERT(MiProtoPteToPte(NewPte) == PointerPte);
351}
352
356{
357 return ((PointerPte->u.Hard.Valid != 0) ||
358 (PointerPte->u.Proto.Prototype != 0) ||
359 (PointerPte->u.Trans.Transition != 0) ||
360 (PointerPte->u.Hard.PageFrameNumber != 0));
361}
362
366{
367 return ((MiAddressToPxe(Address)->u.Hard.Valid) &&
368 (MiAddressToPpe(Address)->u.Hard.Valid) &&
369 (MiAddressToPde(Address)->u.Hard.Valid));
370}
371
unsigned char BOOLEAN
Definition: actypes.h:127
#define PDE_BASE
Definition: winldr.c:21
#define PTE_BASE
Definition: winldr.c:20
#define ULONG_PTR
Definition: config.h:101
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define ASSERT(a)
Definition: mode.c:44
unsigned __int64 ULONG64
Definition: imports.h:198
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
FORCEINLINE ULONG MiAddressToPxi(PVOID Address)
Definition: mm.h:199
FORCEINLINE PMMPXE MiPdeToPxe(PMMPDE PointerPde)
Definition: mm.h:299
#define MiAddressToPte(x)
Definition: mm.h:144
FORCEINLINE PVOID MiPpeToAddress(PMMPTE PointerPpe)
Definition: mm.h:225
FORCEINLINE PMMPDE MiPdeToPpe(PMMPDE PointerPde)
Definition: mm.h:291
FORCEINLINE PMMPPE MiPteToPpe(PMMPTE PointerPte)
Definition: mm.h:275
FORCEINLINE PMMPTE MiPxeToPte(PMMPXE PointerPxe)
Definition: mm.h:259
FORCEINLINE ULONG MiAddressToPdi(PVOID Address)
Definition: mm.h:189
FORCEINLINE VOID MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte, IN PMMPTE PointerPte)
Definition: mm.h:341
FORCEINLINE BOOLEAN MiIsPdeForAddressValid(PVOID Address)
Definition: mm.h:365
FORCEINLINE PMMPTE MiPpeToPte(PMMPPE PointerPpe)
Definition: mm.h:251
FORCEINLINE PMMPTE _MiAddressToPte(PVOID Address)
Definition: mm.h:138
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:160
#define MiProtoPteToPte(x)
Definition: mm.h:315
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:170
FORCEINLINE ULONG MiAddressToPti(PVOID Address)
Definition: mm.h:180
FORCEINLINE BOOLEAN MI_IS_MAPPED_PTE(PMMPTE PointerPte)
Definition: mm.h:355
#define MiAddressToPde(x)
Definition: mm.h:155
FORCEINLINE PMMPTE _MiAddressToPde(PVOID Address)
Definition: mm.h:149
FORCEINLINE VOID MI_MAKE_SUBSECTION_PTE(_Out_ PMMPTE NewPte, _In_ PVOID Segment)
Definition: mm.h:327
FORCEINLINE PMMPXE MiPteToPxe(PMMPTE PointerPte)
Definition: mm.h:283
FORCEINLINE PVOID MiPxeToAddress(PMMPTE PointerPxe)
Definition: mm.h:234
#define MiPdeToAddress(_Pde)
Definition: mm.h:132
#define MiPteToPde(_Pte)
Definition: mm.h:136
#define MiPteToAddress(_Pte)
Definition: mm.h:131
#define MiPdeToPte(_Pde)
Definition: mm.h:135
static WCHAR Address[46]
Definition: ping.c:68
#define PXE_BASE
#define PDI_SHIFT
#define PPE_BASE
#define PXI_SHIFT
#define PXI_MASK
#define PPI_SHIFT
#define PTI_SHIFT
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
ULONG64 Prototype
Definition: mmtypes.h:121
ULONG64 Transition
Definition: mmtypes.h:105
union _MMPTE::@2788 u
MMPTE_TRANSITION Trans
Definition: mmtypes.h:220
MMPTE_PROTOTYPE Proto
Definition: mmtypes.h:218
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
int64_t LONG64
Definition: typedefs.h:68
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define FORCEINLINE
Definition: wdftypes.h:67
_Inout_ PVOID Segment
Definition: exfuncs.h:1101