2 * Higher level memory managment definitions
5 #ifndef __INCLUDE_INTERNAL_MM_H
6 #define __INCLUDE_INTERNAL_MM_H
8 #include <internal/ntoskrnl.h>
9 #include <internal/arch/mm.h>
11 /* TYPES *********************************************************************/
15 struct _MM_RMAP_ENTRY;
17 typedef ULONG SWAPENTRY;
19 #define MEMORY_AREA_INVALID (0)
20 #define MEMORY_AREA_SECTION_VIEW (1)
21 #define MEMORY_AREA_CONTINUOUS_MEMORY (2)
22 #define MEMORY_AREA_NO_CACHE (3)
23 #define MEMORY_AREA_IO_MAPPING (4)
24 #define MEMORY_AREA_SYSTEM (5)
25 #define MEMORY_AREA_MDL_MAPPING (7)
26 #define MEMORY_AREA_VIRTUAL_MEMORY (8)
27 #define MEMORY_AREA_CACHE_SEGMENT (9)
28 #define MEMORY_AREA_SHARED_DATA (10)
29 #define MEMORY_AREA_KERNEL_STACK (11)
30 #define MEMORY_AREA_PAGED_POOL (12)
32 #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
34 #define PAGE_TO_SECTION_PAGE_TABLE_OFFSET(x) \
35 ((((x)) % (4*1024*1024)) / (4*1024))
37 #define NR_SECTION_PAGE_TABLES (1024)
38 #define NR_SECTION_PAGE_ENTRIES (1024)
42 * Additional flags for protection attributes
44 #define PAGE_WRITETHROUGH (1024)
45 #define PAGE_SYSTEM (2048)
46 #define PAGE_FLAGS_VALID_FROM_USER_MODE (PAGE_READONLY | \
51 PAGE_EXECUTE_READWRITE | \
52 PAGE_EXECUTE_WRITECOPY | \
59 ULONG Entry[NR_SECTION_PAGE_ENTRIES];
60 } SECTION_PAGE_TABLE, *PSECTION_PAGE_TABLE;
64 PSECTION_PAGE_TABLE PageTables[NR_SECTION_PAGE_TABLES];
65 } SECTION_PAGE_DIRECTORY, *PSECTION_PAGE_DIRECTORY;
67 #define SEC_PHYSICALMEMORY (0x80000000)
69 #define MM_PAGEFILE_SEGMENT (0x1)
70 #define MM_DATAFILE_SEGMENT (0x2)
72 #define MM_SECTION_SEGMENT_BSS (0x1)
74 typedef struct _MM_SECTION_SEGMENT
83 SECTION_PAGE_DIRECTORY PageDirectory;
86 ULONG Characteristics;
88 } MM_SECTION_SEGMENT, *PMM_SECTION_SEGMENT;
94 LARGE_INTEGER MaximumSize;
95 ULONG SectionPageProtection;
96 ULONG AllocationAttributes;
97 PFILE_OBJECT FileObject;
98 LIST_ENTRY ViewListHead;
99 KSPIN_LOCK ViewListLock;
102 PMM_SECTION_SEGMENT Segments;
108 ULONG MinorSubsystemVersion;
109 ULONG MajorSubsystemVersion;
110 ULONG ImageCharacteristics;
113 } SECTION_OBJECT, *PSECTION_OBJECT;
123 struct _EPROCESS* Process;
124 BOOLEAN DeleteInProgress;
130 SECTION_OBJECT* Section;
132 LIST_ENTRY ViewListEntry;
133 PMM_SECTION_SEGMENT Segment;
134 BOOLEAN WriteCopyView;
135 LIST_ENTRY RegionListHead;
139 LIST_ENTRY RegionListHead;
142 } MEMORY_AREA, *PMEMORY_AREA;
144 typedef struct _MADDRESS_SPACE
146 LIST_ENTRY MAreaListHead;
149 struct _EPROCESS* Process;
150 PUSHORT PageTableRefCountTable;
151 ULONG PageTableRefCountTableSize;
152 } MADDRESS_SPACE, *PMADDRESS_SPACE;
156 VOID MmLockAddressSpace(PMADDRESS_SPACE AddressSpace);
157 VOID MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace);
158 VOID MmInitializeKernelAddressSpace(VOID);
159 PMADDRESS_SPACE MmGetCurrentAddressSpace(VOID);
160 PMADDRESS_SPACE MmGetKernelAddressSpace(VOID);
161 NTSTATUS MmInitializeAddressSpace(struct _EPROCESS* Process,
162 PMADDRESS_SPACE AddressSpace);
163 NTSTATUS MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace);
164 PVOID STDCALL MmAllocateSection (IN ULONG Length);
165 NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process,
166 PMADDRESS_SPACE AddressSpace,
171 MEMORY_AREA** Result,
173 MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
175 NTSTATUS MmInitMemoryAreas(VOID);
176 VOID ExInitNonPagedPool(ULONG BaseAddress);
177 NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
180 VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea,
181 PVOID Address, PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry,
183 PVOID FreePageContext);
184 VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
185 NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
186 NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
187 NTSTATUS MmInitSectionImplementation(VOID);
189 #define MM_LOWEST_USER_ADDRESS (4096)
191 PMEMORY_AREA MmSplitMemoryArea(struct _EPROCESS* Process,
192 PMADDRESS_SPACE AddressSpace,
193 PMEMORY_AREA OriginalMemoryArea,
197 ULONG NewAttributes);
199 MmInitializePageList(PVOID FirstPhysKernelAddress,
200 PVOID LastPhysKernelAddress,
201 ULONG MemorySizeInPages,
202 ULONG LastKernelBase,
203 PADDRESS_RANGE BIOSMemoryMap,
204 ULONG AddressRangeCount);
206 MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry);
207 VOID MmDereferencePage(PHYSICAL_ADDRESS PhysicalAddress);
208 VOID MmReferencePage(PHYSICAL_ADDRESS PhysicalAddress);
209 VOID MmDeletePageTable(struct _EPROCESS* Process,
211 NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src,
212 struct _EPROCESS* Dest);
213 NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
214 NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
216 MmDeleteVirtualMapping(struct _EPROCESS* Process,
220 PHYSICAL_ADDRESS* PhysicalPage);
222 #define MM_PAGE_CLEAN (0)
223 #define MM_PAGE_DIRTY (1)
225 VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages);
226 PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset);
227 VOID MiShutdownMemoryManager(VOID);
229 MmGetPhysicalAddressForProcess(struct _EPROCESS* Process,
232 MmUnmapViewOfSection(struct _EPROCESS* Process, PVOID BaseAddress);
233 VOID MmInitPagingFile(VOID);
235 /* FIXME: it should be in ddk/mmfuncs.h */
239 OUT PSECTION_OBJECT * SectionObject,
240 IN ACCESS_MASK DesiredAccess,
241 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
242 IN PLARGE_INTEGER MaximumSize,
243 IN ULONG SectionPageProtection,
244 IN ULONG AllocationAttributes,
245 IN HANDLE FileHandle OPTIONAL,
246 IN PFILE_OBJECT File OPTIONAL
249 NTSTATUS MmPageFault(ULONG Cs,
256 MmAccessFault(KPROCESSOR_MODE Mode,
260 MmNotPresentFault(KPROCESSOR_MODE Mode,
264 MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
265 MEMORY_AREA* MemoryArea,
269 MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
270 MEMORY_AREA* MemoryArea,
273 NTSTATUS MmWaitForPage(PVOID Page);
274 VOID MmClearWaitPage(PVOID Page);
275 VOID MmSetWaitPage(PVOID Page);
276 BOOLEAN MmIsDirtyPage(struct _EPROCESS* Process, PVOID Address);
277 BOOLEAN MmIsPageTablePresent(PVOID PAddress);
279 MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
280 PMEMORY_AREA MemoryArea,
282 struct _MM_PAGEOP* PageOp);
284 MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
285 PMEMORY_AREA MemoryArea,
287 struct _MM_PAGEOP* PageOp);
288 MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
291 PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length);
292 VOID ExUnmapPage(PVOID Addr);
293 PVOID ExAllocatePage(VOID);
295 VOID MmInitPagingFile(VOID);
296 BOOLEAN MmReserveSwapPages(ULONG Nr);
297 VOID MmDereserveSwapPages(ULONG Nr);
298 SWAPENTRY MmAllocSwapPage(VOID);
299 VOID MmFreeSwapPage(SWAPENTRY Entry);
301 VOID MmInit1(ULONG FirstKernelPhysAddress,
302 ULONG LastKernelPhysAddress,
303 ULONG LastKernelAddress,
304 PADDRESS_RANGE BIOSMemoryMap,
305 ULONG AddressRangeCount);
308 NTSTATUS MmInitPagerThread(VOID);
310 VOID MmInitKernelMap(PVOID BaseAddress);
311 NTSTATUS MmCreatePageTable(PVOID PAddress);
317 ULONG NrReservedPages;
322 ULONG PagingRequestsInLastMinute;
323 ULONG PagingRequestsInLastFiveMinutes;
324 ULONG PagingRequestsInLastFifteenMinutes;
327 extern MM_STATS MmStats;
330 MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process);
332 MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
334 MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
336 MmSetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress, ULONG Flags);
338 MmGetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress);
339 VOID MmSetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress,
340 SWAPENTRY SavedSwapEntry);
341 SWAPENTRY MmGetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress);
342 VOID MmSetCleanPage(struct _EPROCESS* Process, PVOID Address);
343 VOID MmLockPage(PHYSICAL_ADDRESS PhysicalPage);
344 VOID MmUnlockPage(PHYSICAL_ADDRESS PhysicalPage);
346 NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG Count);
347 NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG Count);
349 MmCreatePhysicalMemorySection(VOID);
351 MmGetContinuousPages(ULONG NumberOfBytes,
352 PHYSICAL_ADDRESS HighestAcceptableAddress,
355 #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
358 MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
359 MEMORY_AREA* MemoryArea,
363 MmGetPageProtect(struct _EPROCESS* Process, PVOID Address);
365 ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage);
367 MmGetReferenceCountPage(PHYSICAL_ADDRESS PhysicalAddress);
369 MmIsUsablePage(PHYSICAL_ADDRESS PhysicalAddress);
371 #define MM_PAGEOP_PAGEIN (1)
372 #define MM_PAGEOP_PAGEOUT (2)
373 #define MM_PAGEOP_PAGESYNCH (3)
374 #define MM_PAGEOP_ACCESSFAULT (4)
376 typedef struct _MM_PAGEOP
378 /* Type of operation. */
380 /* Number of threads interested in this operation. */
381 ULONG ReferenceCount;
382 /* Event that will be set when the operation is completed. */
383 KEVENT CompletionEvent;
384 /* Status of the operation once it is completed. */
386 /* TRUE if the operation was abandoned. */
388 /* The memory area to be affected by the operation. */
391 struct _MM_PAGEOP* Next;
392 struct _ETHREAD* Thread;
394 * These fields are used to identify the operation if it is against a
395 * virtual memory area.
400 * These fields are used to identify the operation if it is against a
403 PMM_SECTION_SEGMENT Segment;
405 } MM_PAGEOP, *PMM_PAGEOP;
408 MmReleasePageOp(PMM_PAGEOP PageOp);
411 MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
412 PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType);
414 MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
415 PMM_SECTION_SEGMENT Segment, ULONG Offset);
417 MmInitializePageOp(VOID);
419 MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
421 MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly);
423 MmMarkPageMapped(PHYSICAL_ADDRESS PhysicalAddress);
425 MmMarkPageUnmapped(PHYSICAL_ADDRESS PhysicalAddress);
427 MmFreeSectionSegments(PFILE_OBJECT FileObject);
429 typedef struct _MM_IMAGE_SECTION_OBJECT
432 MM_SECTION_SEGMENT Segments[0];
433 } MM_IMAGE_SECTION_OBJECT, *PMM_IMAGE_SECTION_OBJECT;
436 MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea);
438 MiCopyFromUserPage(PHYSICAL_ADDRESS DestPhysPage, PVOID SourceAddress);
440 MiZeroPage(PHYSICAL_ADDRESS PhysPage);
442 MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
444 #define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001)
447 MmCreateVirtualMappingForKernel(PVOID Address,
449 PHYSICAL_ADDRESS PhysicalAddress);
450 NTSTATUS MmCommitPagedPoolAddress(PVOID Address);
451 NTSTATUS MmCreateVirtualMapping(struct _EPROCESS* Process,
454 PHYSICAL_ADDRESS PhysicalAddress,
457 MmCreateVirtualMappingUnsafe(struct _EPROCESS* Process,
460 PHYSICAL_ADDRESS PhysicalAddress,
463 VOID MmSetPageProtect(struct _EPROCESS* Process,
466 BOOLEAN MmIsPagePresent(struct _EPROCESS* Process,
469 /* Memory balancing. */
471 MmInitializeMemoryConsumer(ULONG Consumer,
472 NTSTATUS (*Trim)(ULONG Target, ULONG Priority,
475 MmInitializeBalancer(ULONG NrAvailablePages);
477 MmReleasePageMemoryConsumer(ULONG Consumer, PHYSICAL_ADDRESS Page);
479 MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
480 PHYSICAL_ADDRESS* AllocatedPage);
485 #define MC_NPPOOL (3)
486 #define MC_MAXIMUM (4)
489 MmSetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress,
490 struct _MM_RMAP_ENTRY* ListHead);
491 struct _MM_RMAP_ENTRY*
492 MmGetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress);
494 MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process,
497 MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress, PVOID Context,
498 VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, PVOID Address));
500 MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process,
503 MmInitializeRmapList(VOID);
505 MmGetLRUNextUserPage(PHYSICAL_ADDRESS PreviousPhysicalAddress);
507 MmGetLRUFirstUserPage(VOID);
509 MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress);
511 MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages);
514 MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalAddr);
515 VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address);
517 MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
518 SWAPENTRY* SwapEntry);
520 MmCreatePageFileMapping(PEPROCESS Process,
522 SWAPENTRY SwapEntry);
523 BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address);
525 MmTransferOwnershipPage(PHYSICAL_ADDRESS PhysicalAddress, ULONG NewConsumer);
526 VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address);
528 MmInitializeMdlImplementation(VOID);
529 extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
532 MmDumpToPagingFile(ULONG BugCode,
533 ULONG BugCodeParameter1,
534 ULONG BugCodeParameter2,
535 ULONG BugCodeParameter3,
536 ULONG BugCodeParameter4,
537 struct _KTRAP_FRAME* TrapFrame);
539 typedef VOID (*PMM_ALTER_REGION_FUNC)(PMADDRESS_SPACE AddressSpace,
540 PVOID BaseAddress, ULONG Length,
541 ULONG OldType, ULONG OldProtect,
542 ULONG NewType, ULONG NewProtect);
544 typedef struct _MM_REGION
549 LIST_ENTRY RegionListEntry;
550 } MM_REGION, *PMM_REGION;
553 MmAlterRegion(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress,
554 PLIST_ENTRY RegionListHead, PVOID StartAddress, ULONG Length,
555 ULONG NewType, ULONG NewProtect,
556 PMM_ALTER_REGION_FUNC AlterFunc);
558 MmInitialiseRegion(PLIST_ENTRY RegionListHead, ULONG Length, ULONG Type,
561 MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address,
562 PVOID* RegionBaseAddress);
564 MmQueryAnonMem(PMEMORY_AREA MemoryArea,
566 PMEMORY_BASIC_INFORMATION Info,
567 PULONG ResultLength);
569 MmQuerySectionView(PMEMORY_AREA MemoryArea,
571 PMEMORY_BASIC_INFORMATION Info,
572 PULONG ResultLength);
574 MmProtectAnonMem(PMADDRESS_SPACE AddressSpace,
575 PMEMORY_AREA MemoryArea,
581 MmProtectSectionView(PMADDRESS_SPACE AddressSpace,
582 PMEMORY_AREA MemoryArea,
588 MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
593 MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
598 MmSetCleanAllRmaps(PHYSICAL_ADDRESS PhysicalAddress);
600 MmSetDirtyAllRmaps(PHYSICAL_ADDRESS PhysicalAddress);
602 MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress);
604 MmIsDirtyPageRmap(PHYSICAL_ADDRESS PhysicalAddress);
605 NTSTATUS MmInitMpwThread(VOID);
607 MmIsAvailableSwapPage(VOID);
609 MmShowOutOfSpaceMessagePagingFile(VOID);