2 * Higher level memory managment definitions
5 #ifndef __INCLUDE_INTERNAL_MM_H
6 #define __INCLUDE_INTERNAL_MM_H
10 #include <internal/ntoskrnl.h>
11 #include <internal/arch/mm.h>
13 /* TYPES *********************************************************************/
17 struct _MM_RMAP_ENTRY
;
19 typedef ULONG SWAPENTRY
;
21 #define MEMORY_AREA_INVALID (0)
22 #define MEMORY_AREA_SECTION_VIEW (1)
23 #define MEMORY_AREA_CONTINUOUS_MEMORY (2)
24 #define MEMORY_AREA_NO_CACHE (3)
25 #define MEMORY_AREA_IO_MAPPING (4)
26 #define MEMORY_AREA_SYSTEM (5)
27 #define MEMORY_AREA_MDL_MAPPING (7)
28 #define MEMORY_AREA_VIRTUAL_MEMORY (8)
29 #define MEMORY_AREA_CACHE_SEGMENT (9)
30 #define MEMORY_AREA_SHARED_DATA (10)
31 #define MEMORY_AREA_KERNEL_STACK (11)
32 #define MEMORY_AREA_PAGED_POOL (12)
34 #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
36 #define PAGE_TO_SECTION_PAGE_TABLE_OFFSET(x) \
37 ((((x)) % (4*1024*1024)) / (4*1024))
39 #define NR_SECTION_PAGE_TABLES (1024)
40 #define NR_SECTION_PAGE_ENTRIES (1024)
44 * Additional flags for protection attributes
46 #define PAGE_WRITETHROUGH (1024)
47 #define PAGE_SYSTEM (2048)
48 #define PAGE_FLAGS_VALID_FROM_USER_MODE (PAGE_READONLY | \
53 PAGE_EXECUTE_READWRITE | \
54 PAGE_EXECUTE_WRITECOPY | \
61 ULONG Entry
[NR_SECTION_PAGE_ENTRIES
];
62 } SECTION_PAGE_TABLE
, *PSECTION_PAGE_TABLE
;
66 PSECTION_PAGE_TABLE PageTables
[NR_SECTION_PAGE_TABLES
];
67 } SECTION_PAGE_DIRECTORY
, *PSECTION_PAGE_DIRECTORY
;
69 #define SEC_PHYSICALMEMORY (0x80000000)
71 #define MM_PAGEFILE_SEGMENT (0x1)
72 #define MM_DATAFILE_SEGMENT (0x2)
74 #define MM_SECTION_SEGMENT_BSS (0x1)
76 typedef struct _MM_SECTION_SEGMENT
85 SECTION_PAGE_DIRECTORY PageDirectory
;
88 ULONG Characteristics
;
90 } MM_SECTION_SEGMENT
, *PMM_SECTION_SEGMENT
;
92 typedef struct _SECTION_OBJECT
96 LARGE_INTEGER MaximumSize
;
97 ULONG SectionPageProtection
;
98 ULONG AllocationAttributes
;
99 PFILE_OBJECT FileObject
;
100 LIST_ENTRY ViewListHead
;
101 KSPIN_LOCK ViewListLock
;
104 PMM_SECTION_SEGMENT Segments
;
110 ULONG MinorSubsystemVersion
;
111 ULONG MajorSubsystemVersion
;
112 ULONG ImageCharacteristics
;
115 } SECTION_OBJECT
, *PSECTION_OBJECT
;
125 struct _EPROCESS
* Process
;
126 BOOLEAN DeleteInProgress
;
132 SECTION_OBJECT
* Section
;
134 LIST_ENTRY ViewListEntry
;
135 PMM_SECTION_SEGMENT Segment
;
136 BOOLEAN WriteCopyView
;
137 LIST_ENTRY RegionListHead
;
141 LIST_ENTRY RegionListHead
;
144 } MEMORY_AREA
, *PMEMORY_AREA
;
148 VOID
MmLockAddressSpace(PMADDRESS_SPACE AddressSpace
);
149 VOID
MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace
);
150 VOID
MmInitializeKernelAddressSpace(VOID
);
151 PMADDRESS_SPACE
MmGetCurrentAddressSpace(VOID
);
152 PMADDRESS_SPACE
MmGetKernelAddressSpace(VOID
);
153 NTSTATUS
MmInitializeAddressSpace(struct _EPROCESS
* Process
,
154 PMADDRESS_SPACE AddressSpace
);
155 NTSTATUS
MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace
);
156 PVOID STDCALL
MmAllocateSection (IN ULONG Length
);
157 NTSTATUS
MmCreateMemoryArea(struct _EPROCESS
* Process
,
158 PMADDRESS_SPACE AddressSpace
,
163 MEMORY_AREA
** Result
,
165 MEMORY_AREA
* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace
,
167 NTSTATUS
MmInitMemoryAreas(VOID
);
168 VOID
ExInitNonPagedPool(ULONG BaseAddress
);
169 NTSTATUS
MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace
,
172 VOID (*FreePage
)(PVOID Context
, MEMORY_AREA
* MemoryArea
,
173 PVOID Address
, PHYSICAL_ADDRESS PhysAddr
, SWAPENTRY SwapEntry
,
175 PVOID FreePageContext
);
176 VOID
MmDumpMemoryAreas(PLIST_ENTRY ListHead
);
177 NTSTATUS
MmLockMemoryArea(MEMORY_AREA
* MemoryArea
);
178 NTSTATUS
MmUnlockMemoryArea(MEMORY_AREA
* MemoryArea
);
179 NTSTATUS
MmInitSectionImplementation(VOID
);
181 PMEMORY_AREA
MmSplitMemoryArea(struct _EPROCESS
* Process
,
182 PMADDRESS_SPACE AddressSpace
,
183 PMEMORY_AREA OriginalMemoryArea
,
187 ULONG NewAttributes
);
189 MmInitializePageList(PVOID FirstPhysKernelAddress
,
190 PVOID LastPhysKernelAddress
,
191 ULONG MemorySizeInPages
,
192 ULONG LastKernelBase
,
193 PADDRESS_RANGE BIOSMemoryMap
,
194 ULONG AddressRangeCount
);
196 MmAllocPage(ULONG Consumer
, SWAPENTRY SavedSwapEntry
);
197 VOID
MmDereferencePage(PHYSICAL_ADDRESS PhysicalAddress
);
198 VOID
MmReferencePage(PHYSICAL_ADDRESS PhysicalAddress
);
199 VOID
MmDeletePageTable(struct _EPROCESS
* Process
,
201 NTSTATUS
MmCopyMmInfo(struct _EPROCESS
* Src
,
202 struct _EPROCESS
* Dest
);
203 NTSTATUS
MmReleaseMmInfo(struct _EPROCESS
* Process
);
204 NTSTATUS
Mmi386ReleaseMmInfo(struct _EPROCESS
* Process
);
206 MmDeleteVirtualMapping(struct _EPROCESS
* Process
,
210 PHYSICAL_ADDRESS
* PhysicalPage
);
212 #define MM_PAGE_CLEAN (0)
213 #define MM_PAGE_DIRTY (1)
215 VOID
MmBuildMdlFromPages(PMDL Mdl
, PULONG Pages
);
216 PVOID
MmGetMdlPageAddress(PMDL Mdl
, PVOID Offset
);
217 VOID
MiShutdownMemoryManager(VOID
);
219 MmGetPhysicalAddressForProcess(struct _EPROCESS
* Process
,
222 MmUnmapViewOfSection(struct _EPROCESS
* Process
, PVOID BaseAddress
);
223 VOID
MmInitPagingFile(VOID
);
225 /* FIXME: it should be in ddk/mmfuncs.h */
229 OUT PSECTION_OBJECT
* SectionObject
,
230 IN ACCESS_MASK DesiredAccess
,
231 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
232 IN PLARGE_INTEGER MaximumSize
,
233 IN ULONG SectionPageProtection
,
234 IN ULONG AllocationAttributes
,
235 IN HANDLE FileHandle OPTIONAL
,
236 IN PFILE_OBJECT File OPTIONAL
239 NTSTATUS
MmPageFault(ULONG Cs
,
246 MmAccessFault(KPROCESSOR_MODE Mode
,
250 MmNotPresentFault(KPROCESSOR_MODE Mode
,
254 MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace
,
255 MEMORY_AREA
* MemoryArea
,
259 MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace
,
260 MEMORY_AREA
* MemoryArea
,
263 NTSTATUS
MmWaitForPage(PVOID Page
);
264 VOID
MmClearWaitPage(PVOID Page
);
265 VOID
MmSetWaitPage(PVOID Page
);
266 BOOLEAN
MmIsDirtyPage(struct _EPROCESS
* Process
, PVOID Address
);
267 BOOLEAN
MmIsPageTablePresent(PVOID PAddress
);
269 MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace
,
270 PMEMORY_AREA MemoryArea
,
272 struct _MM_PAGEOP
* PageOp
);
274 MmPageOutSectionView(PMADDRESS_SPACE AddressSpace
,
275 PMEMORY_AREA MemoryArea
,
277 struct _MM_PAGEOP
* PageOp
);
278 MEMORY_AREA
* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace
,
281 PVOID
MmFindGap(PMADDRESS_SPACE AddressSpace
, ULONG Length
);
282 VOID
ExUnmapPage(PVOID Addr
);
283 PVOID
ExAllocatePage(VOID
);
285 VOID
MmInitPagingFile(VOID
);
286 BOOLEAN
MmReserveSwapPages(ULONG Nr
);
287 VOID
MmDereserveSwapPages(ULONG Nr
);
288 SWAPENTRY
MmAllocSwapPage(VOID
);
289 VOID
MmFreeSwapPage(SWAPENTRY Entry
);
291 VOID
MmInit1(ULONG FirstKernelPhysAddress
,
292 ULONG LastKernelPhysAddress
,
293 ULONG LastKernelAddress
,
294 PADDRESS_RANGE BIOSMemoryMap
,
295 ULONG AddressRangeCount
);
298 NTSTATUS
MmInitPagerThread(VOID
);
300 VOID
MmInitKernelMap(PVOID BaseAddress
);
301 NTSTATUS
MmCreatePageTable(PVOID PAddress
);
307 ULONG NrReservedPages
;
312 ULONG PagingRequestsInLastMinute
;
313 ULONG PagingRequestsInLastFiveMinutes
;
314 ULONG PagingRequestsInLastFifteenMinutes
;
317 extern MM_STATS MmStats
;
320 MmGetDirtyPagesFromWorkingSet(struct _EPROCESS
* Process
);
322 MmWriteToSwapPage(SWAPENTRY SwapEntry
, PMDL Mdl
);
324 MmReadFromSwapPage(SWAPENTRY SwapEntry
, PMDL Mdl
);
326 MmSetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress
, ULONG Flags
);
328 MmGetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress
);
329 VOID
MmSetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress
,
330 SWAPENTRY SavedSwapEntry
);
331 SWAPENTRY
MmGetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress
);
332 VOID
MmSetCleanPage(struct _EPROCESS
* Process
, PVOID Address
);
333 VOID
MmLockPage(PHYSICAL_ADDRESS PhysicalPage
);
334 VOID
MmUnlockPage(PHYSICAL_ADDRESS PhysicalPage
);
336 NTSTATUS
MmSafeCopyFromUser(PVOID Dest
, PVOID Src
, ULONG Count
);
337 NTSTATUS
MmSafeCopyToUser(PVOID Dest
, PVOID Src
, ULONG Count
);
339 MmCreatePhysicalMemorySection(VOID
);
341 MmGetContinuousPages(ULONG NumberOfBytes
,
342 PHYSICAL_ADDRESS HighestAcceptableAddress
,
345 #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
348 MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace
,
349 MEMORY_AREA
* MemoryArea
,
353 MmGetPageProtect(struct _EPROCESS
* Process
, PVOID Address
);
355 ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage
);
357 MmGetReferenceCountPage(PHYSICAL_ADDRESS PhysicalAddress
);
359 MmIsUsablePage(PHYSICAL_ADDRESS PhysicalAddress
);
361 #define MM_PAGEOP_PAGEIN (1)
362 #define MM_PAGEOP_PAGEOUT (2)
363 #define MM_PAGEOP_PAGESYNCH (3)
364 #define MM_PAGEOP_ACCESSFAULT (4)
366 typedef struct _MM_PAGEOP
368 /* Type of operation. */
370 /* Number of threads interested in this operation. */
371 ULONG ReferenceCount
;
372 /* Event that will be set when the operation is completed. */
373 KEVENT CompletionEvent
;
374 /* Status of the operation once it is completed. */
376 /* TRUE if the operation was abandoned. */
378 /* The memory area to be affected by the operation. */
381 struct _MM_PAGEOP
* Next
;
382 struct _ETHREAD
* Thread
;
384 * These fields are used to identify the operation if it is against a
385 * virtual memory area.
390 * These fields are used to identify the operation if it is against a
393 PMM_SECTION_SEGMENT Segment
;
395 } MM_PAGEOP
, *PMM_PAGEOP
;
398 MmReleasePageOp(PMM_PAGEOP PageOp
);
401 MmGetPageOp(PMEMORY_AREA MArea
, ULONG Pid
, PVOID Address
,
402 PMM_SECTION_SEGMENT Segment
, ULONG Offset
, ULONG OpType
);
405 MiDebugDumpNonPagedPool(BOOLEAN NewOnly
);
407 MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly
);
409 MmMarkPageMapped(PHYSICAL_ADDRESS PhysicalAddress
);
411 MmMarkPageUnmapped(PHYSICAL_ADDRESS PhysicalAddress
);
413 MmFreeSectionSegments(PFILE_OBJECT FileObject
);
415 typedef struct _MM_IMAGE_SECTION_OBJECT
418 MM_SECTION_SEGMENT Segments
[0];
419 } MM_IMAGE_SECTION_OBJECT
, *PMM_IMAGE_SECTION_OBJECT
;
422 MmFreeVirtualMemory(struct _EPROCESS
* Process
, PMEMORY_AREA MemoryArea
);
424 MiCopyFromUserPage(PHYSICAL_ADDRESS DestPhysPage
, PVOID SourceAddress
);
426 MiZeroPage(PHYSICAL_ADDRESS PhysPage
);
428 MmIsAccessedAndResetAccessPage(struct _EPROCESS
* Process
, PVOID Address
);
430 #define STATUS_MM_RESTART_OPERATION (0xD0000001)
433 MmCreateVirtualMappingForKernel(PVOID Address
,
435 PHYSICAL_ADDRESS PhysicalAddress
);
436 NTSTATUS
MmCommitPagedPoolAddress(PVOID Address
);
437 NTSTATUS
MmCreateVirtualMapping(struct _EPROCESS
* Process
,
440 PHYSICAL_ADDRESS PhysicalAddress
,
443 MmCreateVirtualMappingUnsafe(struct _EPROCESS
* Process
,
446 PHYSICAL_ADDRESS PhysicalAddress
,
449 VOID
MmSetPageProtect(struct _EPROCESS
* Process
,
452 BOOLEAN
MmIsPagePresent(struct _EPROCESS
* Process
,
455 /* Memory balancing. */
457 MmInitializeMemoryConsumer(ULONG Consumer
,
458 NTSTATUS (*Trim
)(ULONG Target
, ULONG Priority
,
461 MmInitializeBalancer(ULONG NrAvailablePages
);
463 MmReleasePageMemoryConsumer(ULONG Consumer
, PHYSICAL_ADDRESS Page
);
465 MmRequestPageMemoryConsumer(ULONG Consumer
, BOOLEAN CanWait
,
466 PHYSICAL_ADDRESS
* AllocatedPage
);
471 #define MC_NPPOOL (3)
472 #define MC_MAXIMUM (4)
475 MmSetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress
,
476 struct _MM_RMAP_ENTRY
* ListHead
);
477 struct _MM_RMAP_ENTRY
*
478 MmGetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress
);
480 MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress
, PEPROCESS Process
,
483 MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
, PVOID Context
,
484 VOID (*DeleteMapping
)(PVOID Context
, PEPROCESS Process
, PVOID Address
));
486 MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress
, PEPROCESS Process
,
489 MmInitializeRmapList(VOID
);
491 MmGetLRUNextUserPage(PHYSICAL_ADDRESS PreviousPhysicalAddress
);
493 MmGetLRUFirstUserPage(VOID
);
495 MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress
);
497 MmTrimUserMemory(ULONG Target
, ULONG Priority
, PULONG NrFreedPages
);
500 MmDisableVirtualMapping(PEPROCESS Process
, PVOID Address
, BOOL
* WasDirty
, PHYSICAL_ADDRESS
* PhysicalAddr
);
501 VOID
MmEnableVirtualMapping(PEPROCESS Process
, PVOID Address
);
503 MmDeletePageFileMapping(PEPROCESS Process
, PVOID Address
,
504 SWAPENTRY
* SwapEntry
);
506 MmCreatePageFileMapping(PEPROCESS Process
,
508 SWAPENTRY SwapEntry
);
509 BOOLEAN
MmIsPageSwapEntry(PEPROCESS Process
, PVOID Address
);
511 MmTransferOwnershipPage(PHYSICAL_ADDRESS PhysicalAddress
, ULONG NewConsumer
);
512 VOID
MmSetDirtyPage(PEPROCESS Process
, PVOID Address
);
514 MmInitializeMdlImplementation(VOID
);
515 extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress
;
517 MmCheckForPageOp(PMEMORY_AREA MArea
, ULONG Pid
, PVOID Address
,
518 PMM_SECTION_SEGMENT Segment
, ULONG Offset
);
521 MmDumpToPagingFile(ULONG BugCode
,
522 ULONG BugCodeParameter1
,
523 ULONG BugCodeParameter2
,
524 ULONG BugCodeParameter3
,
525 ULONG BugCodeParameter4
,
526 struct _KTRAP_FRAME
* TrapFrame
);
528 typedef VOID (*PMM_ALTER_REGION_FUNC
)(PMADDRESS_SPACE AddressSpace
,
529 PVOID BaseAddress
, ULONG Length
,
530 ULONG OldType
, ULONG OldProtect
,
531 ULONG NewType
, ULONG NewProtect
);
533 typedef struct _MM_REGION
538 LIST_ENTRY RegionListEntry
;
539 } MM_REGION
, *PMM_REGION
;
542 MmAlterRegion(PMADDRESS_SPACE AddressSpace
, PVOID BaseAddress
,
543 PLIST_ENTRY RegionListHead
, PVOID StartAddress
, ULONG Length
,
544 ULONG NewType
, ULONG NewProtect
,
545 PMM_ALTER_REGION_FUNC AlterFunc
);
547 MmInitialiseRegion(PLIST_ENTRY RegionListHead
, ULONG Length
, ULONG Type
,
550 MmFindRegion(PVOID BaseAddress
, PLIST_ENTRY RegionListHead
, PVOID Address
,
551 PVOID
* RegionBaseAddress
);
553 MmQueryAnonMem(PMEMORY_AREA MemoryArea
,
555 PMEMORY_BASIC_INFORMATION Info
,
556 PULONG ResultLength
);
558 MmQuerySectionView(PMEMORY_AREA MemoryArea
,
560 PMEMORY_BASIC_INFORMATION Info
,
561 PULONG ResultLength
);
563 MmProtectAnonMem(PMADDRESS_SPACE AddressSpace
,
564 PMEMORY_AREA MemoryArea
,
570 MmProtectSectionView(PMADDRESS_SPACE AddressSpace
,
571 PMEMORY_AREA MemoryArea
,
578 MmWritePageSectionView(PMADDRESS_SPACE AddressSpace
,
583 MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace
,
589 MmSetCleanAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
);
591 MmSetDirtyAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
);
593 MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress
);
595 MmIsDirtyPageRmap(PHYSICAL_ADDRESS PhysicalAddress
);
596 NTSTATUS
MmInitMpwThread(VOID
);
598 MmIsAvailableSwapPage(VOID
);
600 MmShowOutOfSpaceMessagePagingFile(VOID
);
602 #endif /* !AS_INVOKED */