1 #pragma once 2 3 #include <internal/arch/mm.h> 4 5 /* TYPES *********************************************************************/ 6 7 #define PFN_FROM_SSE(E) ((PFN_NUMBER)((E) >> PAGE_SHIFT)) 8 #define IS_SWAP_FROM_SSE(E) ((E) & 0x00000001) 9 #define MM_IS_WAIT_PTE(E) \ 10 (IS_SWAP_FROM_SSE(E) && SWAPENTRY_FROM_SSE(E) == MM_WAIT_ENTRY) 11 #define MAKE_PFN_SSE(P) ((ULONG_PTR)((P) << PAGE_SHIFT)) 12 #define SWAPENTRY_FROM_SSE(E) ((E) >> 1) 13 #define MAKE_SWAP_SSE(S) (((ULONG_PTR)(S) << 1) | 0x1) 14 #define DIRTY_SSE(E) ((E) | 2) 15 #define CLEAN_SSE(E) ((E) & ~2) 16 #define IS_DIRTY_SSE(E) ((E) & 2) 17 #define PAGE_FROM_SSE(E) ((E) & 0xFFFFF000) 18 #define SHARE_COUNT_FROM_SSE(E) (((E) & 0x00000FFC) >> 2) 19 #define MAX_SHARE_COUNT 0x3FF 20 #define MAKE_SSE(P, C) ((ULONG_PTR)((P) | ((C) << 2))) 21 22 #define MM_SEGMENT_FINALIZE (0x40000000) 23 24 #define RMAP_SEGMENT_MASK ~((ULONG_PTR)0xff) 25 #define RMAP_IS_SEGMENT(x) (((ULONG_PTR)(x) & RMAP_SEGMENT_MASK) == RMAP_SEGMENT_MASK) 26 27 #define MIN(x,y) (((x)<(y))?(x):(y)) 28 #define MAX(x,y) (((x)>(y))?(x):(y)) 29 30 /* Determine what's needed to make paged pool fit in this category. 31 * it seems that something more is required to satisfy arm3. */ 32 #define BALANCER_CAN_EVICT(Consumer) \ 33 (((Consumer) == MC_USER) || \ 34 ((Consumer) == MC_CACHE)) 35 36 #define SEC_CACHE (0x20000000) 37 38 #define MiWaitForPageEvent(Process,Address) do { \ 39 DPRINT("MiWaitForPageEvent %p:%p #\n", Process, Address); \ 40 KeWaitForSingleObject(&MmWaitPageEvent, 0, KernelMode, FALSE, NULL); \ 41 } while(0) 42 43 #define MiSetPageEvent(Process,Address) do { \ 44 DPRINT("MiSetPageEvent %p:%p #\n",Process, (PVOID)(Address)); \ 45 KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE); \ 46 } while(0) 47 48 /* We store 8 bits of location with a page association */ 49 #define ENTRIES_PER_ELEMENT 256 50 51 extern KEVENT MmWaitPageEvent; 52 53 typedef struct _CACHE_SECTION_PAGE_TABLE 54 { 55 LARGE_INTEGER FileOffset; 56 PMM_SECTION_SEGMENT Segment; 57 ULONG Refcount; 58 ULONG_PTR PageEntries[ENTRIES_PER_ELEMENT]; 59 } CACHE_SECTION_PAGE_TABLE, *PCACHE_SECTION_PAGE_TABLE; 60 61 struct _MM_REQUIRED_RESOURCES; 62 63 typedef NTSTATUS (NTAPI * AcquireResource)( 64 PMMSUPPORT AddressSpace, 65 struct _MEMORY_AREA *MemoryArea, 66 struct _MM_REQUIRED_RESOURCES *Required); 67 68 typedef NTSTATUS (NTAPI * NotPresentFaultHandler)( 69 PMMSUPPORT AddressSpace, 70 struct _MEMORY_AREA *MemoryArea, 71 PVOID Address, 72 BOOLEAN Locked, 73 struct _MM_REQUIRED_RESOURCES *Required); 74 75 typedef NTSTATUS (NTAPI * FaultHandler)( 76 PMMSUPPORT AddressSpace, 77 struct _MEMORY_AREA *MemoryArea, 78 PVOID Address, 79 struct _MM_REQUIRED_RESOURCES *Required); 80 81 typedef struct _MM_REQUIRED_RESOURCES 82 { 83 ULONG Consumer; 84 ULONG Amount; 85 ULONG Offset; 86 ULONG State; 87 PVOID Context; 88 LARGE_INTEGER FileOffset; 89 AcquireResource DoAcquisition; 90 PFN_NUMBER Page[2]; 91 PVOID Buffer[2]; 92 SWAPENTRY SwapEntry; 93 const char *File; 94 int Line; 95 } MM_REQUIRED_RESOURCES, *PMM_REQUIRED_RESOURCES; 96 97 NTSTATUS 98 NTAPI 99 MmCreateCacheSection(PROS_SECTION_OBJECT *SectionObject, 100 ACCESS_MASK DesiredAccess, 101 POBJECT_ATTRIBUTES ObjectAttributes, 102 PLARGE_INTEGER UMaximumSize, 103 ULONG SectionPageProtection, 104 ULONG AllocationAttributes, 105 PFILE_OBJECT FileObject); 106 107 PFN_NUMBER 108 NTAPI 109 MmWithdrawSectionPage(PMM_SECTION_SEGMENT Segment, 110 PLARGE_INTEGER FileOffset, 111 BOOLEAN *Dirty); 112 113 NTSTATUS 114 NTAPI 115 MmFinalizeSectionPageOut(PMM_SECTION_SEGMENT Segment, 116 PLARGE_INTEGER FileOffset, 117 PFN_NUMBER Page, 118 BOOLEAN Dirty); 119 120 /* sptab.c *******************************************************************/ 121 122 VOID 123 NTAPI 124 MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment); 125 126 NTSTATUS 127 NTAPI 128 _MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, 129 PLARGE_INTEGER Offset, 130 ULONG_PTR Entry, 131 const char *file, 132 int line); 133 134 ULONG_PTR 135 NTAPI 136 _MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment, 137 PLARGE_INTEGER Offset, 138 const char *file, 139 int line); 140 141 #define MmSetPageEntrySectionSegment(S,O,E) _MmSetPageEntrySectionSegment(S,O,E,__FILE__,__LINE__) 142 143 #define MmGetPageEntrySectionSegment(S,O) _MmGetPageEntrySectionSegment(S,O,__FILE__,__LINE__) 144 145 typedef VOID (NTAPI *FREE_SECTION_PAGE_FUN)( 146 PMM_SECTION_SEGMENT Segment, 147 PLARGE_INTEGER Offset); 148 149 VOID 150 NTAPI 151 MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment, 152 FREE_SECTION_PAGE_FUN FreePage); 153 154 /* Yields a lock */ 155 PMM_SECTION_SEGMENT 156 NTAPI 157 MmGetSectionAssociation(PFN_NUMBER Page, 158 PLARGE_INTEGER Offset); 159 160 NTSTATUS 161 NTAPI 162 MmSetSectionAssociation(PFN_NUMBER Page, 163 PMM_SECTION_SEGMENT Segment, 164 PLARGE_INTEGER Offset); 165 166 VOID 167 NTAPI 168 MmDeleteSectionAssociation(PFN_NUMBER Page); 169 170 NTSTATUS 171 NTAPI 172 MmpPageOutPhysicalAddress(PFN_NUMBER Page); 173 174 /* io.c **********************************************************************/ 175 176 NTSTATUS 177 MmspWaitForFileLock(PFILE_OBJECT File); 178 179 NTSTATUS 180 NTAPI 181 MiSimpleRead(PFILE_OBJECT FileObject, 182 PLARGE_INTEGER FileOffset, 183 PVOID Buffer, 184 ULONG Length, 185 BOOLEAN Paging, 186 PIO_STATUS_BLOCK ReadStatus); 187 188 NTSTATUS 189 NTAPI 190 _MiSimpleWrite(PFILE_OBJECT FileObject, 191 PLARGE_INTEGER FileOffset, 192 PVOID Buffer, 193 ULONG Length, 194 PIO_STATUS_BLOCK ReadStatus, 195 const char *file, 196 int line); 197 198 #define MiSimpleWrite(F,O,B,L,R) _MiSimpleWrite(F,O,B,L,R,__FILE__,__LINE__) 199 200 NTSTATUS 201 NTAPI 202 _MiWriteBackPage(PFILE_OBJECT FileObject, 203 PLARGE_INTEGER Offset, 204 ULONG Length, 205 PFN_NUMBER Page, 206 const char *File, 207 int Line); 208 209 #define MiWriteBackPage(F,O,L,P) _MiWriteBackPage(F,O,L,P,__FILE__,__LINE__) 210 211 /* section.c *****************************************************************/ 212 213 NTSTATUS 214 NTAPI 215 MmAccessFaultCacheSection(KPROCESSOR_MODE Mode, 216 ULONG_PTR Address, 217 BOOLEAN FromMdl); 218 219 NTSTATUS 220 NTAPI 221 MiReadFilePage(PMMSUPPORT AddressSpace, 222 PMEMORY_AREA MemoryArea, 223 PMM_REQUIRED_RESOURCES RequiredResources); 224 225 NTSTATUS 226 NTAPI 227 MiGetOnePage(PMMSUPPORT AddressSpace, 228 PMEMORY_AREA MemoryArea, 229 PMM_REQUIRED_RESOURCES RequiredResources); 230 231 NTSTATUS 232 NTAPI 233 MiSwapInPage(PMMSUPPORT AddressSpace, 234 PMEMORY_AREA MemoryArea, 235 PMM_REQUIRED_RESOURCES RequiredResources); 236 237 NTSTATUS 238 NTAPI 239 MiWriteSwapPage(PMMSUPPORT AddressSpace, 240 PMEMORY_AREA MemoryArea, 241 PMM_REQUIRED_RESOURCES Resources); 242 243 NTSTATUS 244 NTAPI 245 MiWriteFilePage(PMMSUPPORT AddressSpace, 246 PMEMORY_AREA MemoryArea, 247 PMM_REQUIRED_RESOURCES Resources); 248 249 VOID 250 NTAPI 251 MiFreeSegmentPage(PMM_SECTION_SEGMENT Segment, 252 PLARGE_INTEGER FileOffset); 253 254 _Success_(1) 255 _When_(return==STATUS_MORE_PROCESSING_REQUIRED, _At_(Required->DoAcquisition, _Post_notnull_)) 256 NTSTATUS 257 NTAPI 258 MiCowCacheSectionPage ( 259 _In_ PMMSUPPORT AddressSpace, 260 _In_ PMEMORY_AREA MemoryArea, 261 _In_ PVOID Address, 262 _In_ BOOLEAN Locked, 263 _Inout_ PMM_REQUIRED_RESOURCES Required); 264 265 VOID 266 MmPageOutDeleteMapping(PVOID Context, 267 PEPROCESS Process, 268 PVOID Address); 269 270 VOID 271 NTAPI 272 _MmLockSectionSegment(PMM_SECTION_SEGMENT Segment, 273 const char *file, 274 int line); 275 276 #define MmLockSectionSegment(x) _MmLockSectionSegment(x,__FILE__,__LINE__) 277 278 VOID 279 NTAPI 280 _MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment, 281 const char *file, 282 int line); 283 284 #define MmUnlockSectionSegment(x) _MmUnlockSectionSegment(x,__FILE__,__LINE__) 285 286 VOID 287 MmFreeCacheSectionPage(PVOID Context, 288 MEMORY_AREA* MemoryArea, 289 PVOID Address, 290 PFN_NUMBER Page, 291 SWAPENTRY SwapEntry, 292 BOOLEAN Dirty); 293 294 NTSTATUS 295 NTAPI 296 _MiFlushMappedSection(PVOID BaseAddress, 297 PLARGE_INTEGER BaseOffset, 298 PLARGE_INTEGER FileSize, 299 BOOLEAN Dirty, 300 const char *File, 301 int Line); 302 303 #define MiFlushMappedSection(A,O,S,D) _MiFlushMappedSection(A,O,S,D,__FILE__,__LINE__) 304 305 VOID 306 NTAPI 307 MmFinalizeSegment(PMM_SECTION_SEGMENT Segment); 308 309 VOID 310 NTAPI 311 MmFreeSectionSegments(PFILE_OBJECT FileObject); 312 313 NTSTATUS 314 NTAPI 315 MmMapCacheViewInSystemSpaceAtOffset(IN PMM_SECTION_SEGMENT Segment, 316 OUT PVOID* MappedBase, 317 IN PLARGE_INTEGER ViewOffset, 318 IN OUT PULONG ViewSize); 319 320 NTSTATUS 321 NTAPI 322 _MiMapViewOfSegment(PMMSUPPORT AddressSpace, 323 PMM_SECTION_SEGMENT Segment, 324 PVOID* BaseAddress, 325 SIZE_T ViewSize, 326 ULONG Protect, 327 PLARGE_INTEGER ViewOffset, 328 ULONG AllocationType, 329 const char *file, 330 int line); 331 332 #define MiMapViewOfSegment(AddressSpace,Segment,BaseAddress,ViewSize,Protect,ViewOffset,AllocationType) \ 333 _MiMapViewOfSegment(AddressSpace,Segment,BaseAddress,ViewSize,Protect,ViewOffset,AllocationType,__FILE__,__LINE__) 334 335 NTSTATUS 336 NTAPI 337 MmUnmapViewOfCacheSegment(PMMSUPPORT AddressSpace, 338 PVOID BaseAddress); 339 340 NTSTATUS 341 NTAPI 342 MmUnmapCacheViewInSystemSpace(PVOID Address); 343 344 _Success_(1) 345 _When_(return==STATUS_MORE_PROCESSING_REQUIRED, _At_(Required->DoAcquisition, _Post_notnull_)) 346 NTSTATUS 347 NTAPI 348 MmNotPresentFaultCachePage ( 349 _In_ PMMSUPPORT AddressSpace, 350 _In_ MEMORY_AREA* MemoryArea, 351 _In_ PVOID Address, 352 _In_ BOOLEAN Locked, 353 _Inout_ PMM_REQUIRED_RESOURCES Required); 354 355 NTSTATUS 356 NTAPI 357 MmPageOutPageFileView(PMMSUPPORT AddressSpace, 358 PMEMORY_AREA MemoryArea, 359 PVOID Address, 360 PMM_REQUIRED_RESOURCES Required); 361 362 FORCEINLINE 363 BOOLEAN 364 _MmTryToLockAddressSpace(IN PMMSUPPORT AddressSpace, 365 const char *file, 366 int line) 367 { 368 BOOLEAN Result = KeTryToAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock); 369 //DbgPrint("(%s:%d) Try Lock Address Space %x -> %s\n", file, line, AddressSpace, Result ? "true" : "false"); 370 return Result; 371 } 372 373 #define MmTryToLockAddressSpace(x) _MmTryToLockAddressSpace(x,__FILE__,__LINE__) 374 375 NTSTATUS 376 NTAPI 377 MiWidenSegment(PMMSUPPORT AddressSpace, 378 PMEMORY_AREA MemoryArea, 379 PMM_REQUIRED_RESOURCES RequiredResources); 380 381 NTSTATUS 382 NTAPI 383 MiSwapInSectionPage(PMMSUPPORT AddressSpace, 384 PMEMORY_AREA MemoryArea, 385 PMM_REQUIRED_RESOURCES RequiredResources); 386 387 NTSTATUS 388 NTAPI 389 MmExtendCacheSection(PROS_SECTION_OBJECT Section, 390 PLARGE_INTEGER NewSize, 391 BOOLEAN ExtendFile); 392 393 NTSTATUS 394 NTAPI 395 _MiFlushMappedSection(PVOID BaseAddress, 396 PLARGE_INTEGER BaseOffset, 397 PLARGE_INTEGER FileSize, 398 BOOLEAN Dirty, 399 const char *File, 400 int Line); 401 402 #define MiFlushMappedSection(A,O,S,D) _MiFlushMappedSection(A,O,S,D,__FILE__,__LINE__) 403 404 PVOID 405 NTAPI 406 MmGetSegmentRmap(PFN_NUMBER Page, 407 PULONG RawOffset); 408 409 NTSTATUS 410 NTAPI 411 MmNotPresentFaultCacheSection(KPROCESSOR_MODE Mode, 412 ULONG_PTR Address, 413 BOOLEAN FromMdl); 414 415 ULONG 416 NTAPI 417 MiCacheEvictPages(PMM_SECTION_SEGMENT Segment, 418 ULONG Target); 419 420 NTSTATUS 421 MiRosTrimCache(ULONG Target, 422 ULONG Priority, 423 PULONG NrFreed); 424