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