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 *********************************************************************/
13 extern ULONG MiFreeSwapPages
;
14 extern ULONG MiUsedSwapPages
;
15 extern ULONG MmPagedPoolSize
;
16 extern ULONG MiNrAvailablePages
;
20 struct _MM_RMAP_ENTRY
;
22 typedef ULONG SWAPENTRY
;
24 #define MEMORY_AREA_INVALID (0)
25 #define MEMORY_AREA_SECTION_VIEW (1)
26 #define MEMORY_AREA_CONTINUOUS_MEMORY (2)
27 #define MEMORY_AREA_NO_CACHE (3)
28 #define MEMORY_AREA_IO_MAPPING (4)
29 #define MEMORY_AREA_SYSTEM (5)
30 #define MEMORY_AREA_MDL_MAPPING (7)
31 #define MEMORY_AREA_VIRTUAL_MEMORY (8)
32 #define MEMORY_AREA_CACHE_SEGMENT (9)
33 #define MEMORY_AREA_SHARED_DATA (10)
34 #define MEMORY_AREA_KERNEL_STACK (11)
35 #define MEMORY_AREA_PAGED_POOL (12)
36 #define MEMORY_AREA_NO_ACCESS (13)
38 #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
40 #define PAGE_TO_SECTION_PAGE_TABLE_OFFSET(x) \
41 ((((x)) % (4*1024*1024)) / (4*1024))
43 #define NR_SECTION_PAGE_TABLES (1024)
44 #define NR_SECTION_PAGE_ENTRIES (1024)
48 * Additional flags for protection attributes
50 #define PAGE_WRITETHROUGH (1024)
51 #define PAGE_SYSTEM (2048)
52 #define PAGE_FLAGS_VALID_FROM_USER_MODE (PAGE_READONLY | \
57 PAGE_EXECUTE_READWRITE | \
58 PAGE_EXECUTE_WRITECOPY | \
65 ULONG Entry
[NR_SECTION_PAGE_ENTRIES
];
66 } SECTION_PAGE_TABLE
, *PSECTION_PAGE_TABLE
;
70 PSECTION_PAGE_TABLE PageTables
[NR_SECTION_PAGE_TABLES
];
71 } SECTION_PAGE_DIRECTORY
, *PSECTION_PAGE_DIRECTORY
;
73 #define SEC_PHYSICALMEMORY (0x80000000)
75 #define MM_PAGEFILE_SEGMENT (0x1)
76 #define MM_DATAFILE_SEGMENT (0x2)
78 #define MM_SECTION_SEGMENT_BSS (0x1)
80 typedef struct _MM_SECTION_SEGMENT
89 SECTION_PAGE_DIRECTORY PageDirectory
;
92 ULONG Characteristics
;
94 } MM_SECTION_SEGMENT
, *PMM_SECTION_SEGMENT
;
96 typedef struct _MM_IMAGE_SECTION_OBJECT
103 ULONG MinorSubsystemVersion
;
104 ULONG MajorSubsystemVersion
;
105 ULONG ImageCharacteristics
;
109 MM_SECTION_SEGMENT Segments
[0];
110 } MM_IMAGE_SECTION_OBJECT
, *PMM_IMAGE_SECTION_OBJECT
;
112 typedef struct _SECTION_OBJECT
116 LARGE_INTEGER MaximumSize
;
117 ULONG SectionPageProtection
;
118 ULONG AllocationAttributes
;
119 PFILE_OBJECT FileObject
;
120 LIST_ENTRY ViewListHead
;
121 KSPIN_LOCK ViewListLock
;
124 PMM_IMAGE_SECTION_OBJECT ImageSection
;
125 PMM_SECTION_SEGMENT Segment
;
131 typedef struct _SECTION_OBJECT
*PSECTION_OBJECT
;
133 #endif /* __USE_W32API */
143 struct _EPROCESS
* Process
;
144 BOOLEAN DeleteInProgress
;
150 SECTION_OBJECT
* Section
;
152 LIST_ENTRY ViewListEntry
;
153 PMM_SECTION_SEGMENT Segment
;
154 BOOLEAN WriteCopyView
;
155 LIST_ENTRY RegionListHead
;
159 LIST_ENTRY RegionListHead
;
162 } MEMORY_AREA
, *PMEMORY_AREA
;
164 typedef struct _MADDRESS_SPACE
166 LIST_ENTRY MAreaListHead
;
169 struct _EPROCESS
* Process
;
170 PUSHORT PageTableRefCountTable
;
171 ULONG PageTableRefCountTableSize
;
172 } MADDRESS_SPACE
, *PMADDRESS_SPACE
;
178 extern PVOID MmSystemRangeStart
;
180 #endif /* __USE_W32API */
185 VOID
MmLockAddressSpace(PMADDRESS_SPACE AddressSpace
);
186 VOID
MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace
);
187 VOID
MmInitializeKernelAddressSpace(VOID
);
188 PMADDRESS_SPACE
MmGetCurrentAddressSpace(VOID
);
189 PMADDRESS_SPACE
MmGetKernelAddressSpace(VOID
);
190 NTSTATUS
MmInitializeAddressSpace(struct _EPROCESS
* Process
,
191 PMADDRESS_SPACE AddressSpace
);
192 NTSTATUS
MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace
);
193 PVOID STDCALL
MmAllocateSection (IN ULONG Length
);
194 NTSTATUS
MmCreateMemoryArea(struct _EPROCESS
* Process
,
195 PMADDRESS_SPACE AddressSpace
,
200 MEMORY_AREA
** Result
,
203 PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL
);
204 MEMORY_AREA
* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace
,
206 NTSTATUS
MmInitMemoryAreas(VOID
);
207 VOID
MiInitializeNonPagedPool(VOID
);
208 NTSTATUS
MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace
,
211 VOID (*FreePage
)(PVOID Context
, MEMORY_AREA
* MemoryArea
,
212 PVOID Address
, PHYSICAL_ADDRESS PhysAddr
, SWAPENTRY SwapEntry
,
214 PVOID FreePageContext
);
215 VOID
MmDumpMemoryAreas(PLIST_ENTRY ListHead
);
216 NTSTATUS
MmLockMemoryArea(MEMORY_AREA
* MemoryArea
);
217 NTSTATUS
MmUnlockMemoryArea(MEMORY_AREA
* MemoryArea
);
218 NTSTATUS
MmInitSectionImplementation(VOID
);
221 #define MM_LOWEST_USER_ADDRESS (4096)
224 PMEMORY_AREA
MmSplitMemoryArea(struct _EPROCESS
* Process
,
225 PMADDRESS_SPACE AddressSpace
,
226 PMEMORY_AREA OriginalMemoryArea
,
230 ULONG NewAttributes
);
232 MmInitializePageList(PVOID FirstPhysKernelAddress
,
233 PVOID LastPhysKernelAddress
,
234 ULONG MemorySizeInPages
,
235 ULONG LastKernelBase
,
236 PADDRESS_RANGE BIOSMemoryMap
,
237 ULONG AddressRangeCount
);
239 MmAllocPage(ULONG Consumer
, SWAPENTRY SavedSwapEntry
);
240 VOID
MmDereferencePage(PHYSICAL_ADDRESS PhysicalAddress
);
241 VOID
MmReferencePage(PHYSICAL_ADDRESS PhysicalAddress
);
242 VOID
MmDeletePageTable(struct _EPROCESS
* Process
,
244 NTSTATUS
MmCopyMmInfo(struct _EPROCESS
* Src
,
245 struct _EPROCESS
* Dest
);
246 NTSTATUS
MmReleaseMmInfo(struct _EPROCESS
* Process
);
247 NTSTATUS
Mmi386ReleaseMmInfo(struct _EPROCESS
* Process
);
249 MmDeleteVirtualMapping(struct _EPROCESS
* Process
,
253 PHYSICAL_ADDRESS
* PhysicalPage
);
254 VOID
MmUpdateStackPageDir(PULONG LocalPageDir
, struct _KTHREAD
* KThread
);
256 #define MM_PAGE_CLEAN (0)
257 #define MM_PAGE_DIRTY (1)
259 VOID
MmBuildMdlFromPages(PMDL Mdl
, PULONG Pages
);
260 PVOID
MmGetMdlPageAddress(PMDL Mdl
, PVOID Offset
);
261 VOID
MiShutdownMemoryManager(VOID
);
263 MmGetPhysicalAddressForProcess(struct _EPROCESS
* Process
,
266 MmUnmapViewOfSection(struct _EPROCESS
* Process
, PVOID BaseAddress
);
267 VOID
MmInitPagingFile(VOID
);
269 /* FIXME: it should be in ddk/mmfuncs.h */
273 OUT PSECTION_OBJECT
* SectionObject
,
274 IN ACCESS_MASK DesiredAccess
,
275 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
276 IN PLARGE_INTEGER MaximumSize
,
277 IN ULONG SectionPageProtection
,
278 IN ULONG AllocationAttributes
,
279 IN HANDLE FileHandle OPTIONAL
,
280 IN PFILE_OBJECT File OPTIONAL
283 NTSTATUS
MmPageFault(ULONG Cs
,
290 MmAccessFault(KPROCESSOR_MODE Mode
,
294 MmNotPresentFault(KPROCESSOR_MODE Mode
,
298 MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace
,
299 MEMORY_AREA
* MemoryArea
,
303 MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace
,
304 MEMORY_AREA
* MemoryArea
,
307 NTSTATUS
MmWaitForPage(PVOID Page
);
308 VOID
MmClearWaitPage(PVOID Page
);
309 VOID
MmSetWaitPage(PVOID Page
);
310 BOOLEAN
MmIsDirtyPage(struct _EPROCESS
* Process
, PVOID Address
);
311 BOOLEAN
MmIsPageTablePresent(PVOID PAddress
);
313 MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace
,
314 PMEMORY_AREA MemoryArea
,
316 struct _MM_PAGEOP
* PageOp
);
318 MmPageOutSectionView(PMADDRESS_SPACE AddressSpace
,
319 PMEMORY_AREA MemoryArea
,
321 struct _MM_PAGEOP
* PageOp
);
322 MEMORY_AREA
* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace
,
325 PVOID
MmFindGap(PMADDRESS_SPACE AddressSpace
, ULONG Length
, BOOL TopDown
);
326 VOID
ExUnmapPage(PVOID Addr
);
327 PVOID
ExAllocatePage(VOID
);
329 BOOLEAN
MmReserveSwapPages(ULONG Nr
);
330 VOID
MmDereserveSwapPages(ULONG Nr
);
331 SWAPENTRY
MmAllocSwapPage(VOID
);
332 VOID
MmFreeSwapPage(SWAPENTRY Entry
);
334 VOID
MmInit1(ULONG FirstKernelPhysAddress
,
335 ULONG LastKernelPhysAddress
,
336 ULONG LastKernelAddress
,
337 PADDRESS_RANGE BIOSMemoryMap
,
338 ULONG AddressRangeCount
,
342 VOID
MiFreeInitMemory(VOID
);
344 NTSTATUS
MmInitPagerThread(VOID
);
346 VOID
MiInitBalancerThread(VOID
);
347 NTSTATUS
MmInitZeroPageThread(VOID
);
349 VOID
MiInitKernelMap(VOID
);
350 NTSTATUS
MmCreatePageTable(PVOID PAddress
);
356 ULONG NrReservedPages
;
361 ULONG PagingRequestsInLastMinute
;
362 ULONG PagingRequestsInLastFiveMinutes
;
363 ULONG PagingRequestsInLastFifteenMinutes
;
366 extern MM_STATS MmStats
;
369 MmGetDirtyPagesFromWorkingSet(struct _EPROCESS
* Process
);
371 MmWriteToSwapPage(SWAPENTRY SwapEntry
, PMDL Mdl
);
373 MmReadFromSwapPage(SWAPENTRY SwapEntry
, PMDL Mdl
);
375 MmSetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress
, ULONG Flags
);
377 MmGetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress
);
378 VOID
MmSetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress
,
379 SWAPENTRY SavedSwapEntry
);
380 SWAPENTRY
MmGetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress
);
381 VOID
MmSetCleanPage(struct _EPROCESS
* Process
, PVOID Address
);
382 VOID
MmLockPage(PHYSICAL_ADDRESS PhysicalPage
);
383 VOID
MmUnlockPage(PHYSICAL_ADDRESS PhysicalPage
);
384 ULONG
MmGetLockCountPage(PHYSICAL_ADDRESS PhysicalPage
);
386 NTSTATUS
MmSafeCopyFromUser(PVOID Dest
, const VOID
*Src
, ULONG Count
);
387 NTSTATUS
MmSafeCopyToUser(PVOID Dest
, const VOID
*Src
, ULONG Count
);
389 MmCreatePhysicalMemorySection(VOID
);
391 MmGetContinuousPages(ULONG NumberOfBytes
,
392 PHYSICAL_ADDRESS LowestAcceptableAddress
,
393 PHYSICAL_ADDRESS HighestAcceptableAddress
,
396 #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
399 MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace
,
400 MEMORY_AREA
* MemoryArea
,
404 MmGetPageProtect(struct _EPROCESS
* Process
, PVOID Address
);
406 ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage
);
408 MmGetReferenceCountPage(PHYSICAL_ADDRESS PhysicalAddress
);
410 MmIsUsablePage(PHYSICAL_ADDRESS PhysicalAddress
);
412 #define MM_PAGEOP_PAGEIN (1)
413 #define MM_PAGEOP_PAGEOUT (2)
414 #define MM_PAGEOP_PAGESYNCH (3)
415 #define MM_PAGEOP_ACCESSFAULT (4)
417 typedef struct _MM_PAGEOP
419 /* Type of operation. */
421 /* Number of threads interested in this operation. */
422 ULONG ReferenceCount
;
423 /* Event that will be set when the operation is completed. */
424 KEVENT CompletionEvent
;
425 /* Status of the operation once it is completed. */
427 /* TRUE if the operation was abandoned. */
429 /* The memory area to be affected by the operation. */
432 struct _MM_PAGEOP
* Next
;
433 struct _ETHREAD
* Thread
;
435 * These fields are used to identify the operation if it is against a
436 * virtual memory area.
441 * These fields are used to identify the operation if it is against a
444 PMM_SECTION_SEGMENT Segment
;
446 } MM_PAGEOP
, *PMM_PAGEOP
;
449 MmReleasePageOp(PMM_PAGEOP PageOp
);
452 MmGetPageOp(PMEMORY_AREA MArea
, ULONG Pid
, PVOID Address
,
453 PMM_SECTION_SEGMENT Segment
, ULONG Offset
, ULONG OpType
, BOOL First
);
455 MmCheckForPageOp(PMEMORY_AREA MArea
, ULONG Pid
, PVOID Address
,
456 PMM_SECTION_SEGMENT Segment
, ULONG Offset
);
458 MmInitializePageOp(VOID
);
460 MiDebugDumpNonPagedPool(BOOLEAN NewOnly
);
462 MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly
);
464 MmMarkPageMapped(PHYSICAL_ADDRESS PhysicalAddress
);
466 MmMarkPageUnmapped(PHYSICAL_ADDRESS PhysicalAddress
);
468 MmFreeSectionSegments(PFILE_OBJECT FileObject
);
473 MmFreeVirtualMemory(struct _EPROCESS
* Process
, PMEMORY_AREA MemoryArea
);
475 MiCopyFromUserPage(PHYSICAL_ADDRESS DestPhysPage
, PVOID SourceAddress
);
477 MiZeroPage(PHYSICAL_ADDRESS PhysPage
);
479 MmIsAccessedAndResetAccessPage(struct _EPROCESS
* Process
, PVOID Address
);
481 #define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001)
484 MmCreateVirtualMappingForKernel(PVOID Address
,
486 PHYSICAL_ADDRESS PhysicalAddress
);
487 NTSTATUS
MmCommitPagedPoolAddress(PVOID Address
, BOOLEAN Locked
);
488 NTSTATUS
MmCreateVirtualMapping(struct _EPROCESS
* Process
,
491 PHYSICAL_ADDRESS PhysicalAddress
,
494 MmCreateVirtualMappingUnsafe(struct _EPROCESS
* Process
,
497 PHYSICAL_ADDRESS PhysicalAddress
,
500 VOID
MmSetPageProtect(struct _EPROCESS
* Process
,
503 BOOLEAN
MmIsPagePresent(struct _EPROCESS
* Process
,
506 VOID
MmInitGlobalKernelPageDirectory(VOID
);
508 /* Memory balancing. */
510 MmInitializeMemoryConsumer(ULONG Consumer
,
511 NTSTATUS (*Trim
)(ULONG Target
, ULONG Priority
,
514 MmInitializeBalancer(ULONG NrAvailablePages
, ULONG NrSystemPages
);
516 MmReleasePageMemoryConsumer(ULONG Consumer
, PHYSICAL_ADDRESS Page
);
518 MmRequestPageMemoryConsumer(ULONG Consumer
, BOOLEAN CanWait
,
519 PHYSICAL_ADDRESS
* AllocatedPage
);
524 #define MC_NPPOOL (3)
525 #define MC_MAXIMUM (4)
528 typedef struct _MM_MEMORY_CONSUMER
532 NTSTATUS (*Trim
)(ULONG Target
, ULONG Priority
, PULONG NrFreed
);
534 MM_MEMORY_CONSUMER
, *PMM_MEMORY_CONSUMER
;
536 extern MM_MEMORY_CONSUMER MiMemoryConsumers
[MC_MAXIMUM
];
539 MmSetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress
,
540 struct _MM_RMAP_ENTRY
* ListHead
);
541 struct _MM_RMAP_ENTRY
*
542 MmGetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress
);
544 MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress
, PEPROCESS Process
,
547 MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
, PVOID Context
,
548 VOID (*DeleteMapping
)(PVOID Context
, PEPROCESS Process
, PVOID Address
));
550 MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress
, PEPROCESS Process
,
553 MmInitializeRmapList(VOID
);
555 MmGetLRUNextUserPage(PHYSICAL_ADDRESS PreviousPhysicalAddress
);
557 MmGetLRUFirstUserPage(VOID
);
559 MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress
);
561 MmTrimUserMemory(ULONG Target
, ULONG Priority
, PULONG NrFreedPages
);
564 MmDisableVirtualMapping(PEPROCESS Process
, PVOID Address
, BOOL
* WasDirty
, PHYSICAL_ADDRESS
* PhysicalAddr
);
565 VOID
MmEnableVirtualMapping(PEPROCESS Process
, PVOID Address
);
567 MmDeletePageFileMapping(PEPROCESS Process
, PVOID Address
,
568 SWAPENTRY
* SwapEntry
);
570 MmCreatePageFileMapping(PEPROCESS Process
,
572 SWAPENTRY SwapEntry
);
573 BOOLEAN
MmIsPageSwapEntry(PEPROCESS Process
, PVOID Address
);
575 MmTransferOwnershipPage(PHYSICAL_ADDRESS PhysicalAddress
, ULONG NewConsumer
);
576 VOID
MmSetDirtyPage(PEPROCESS Process
, PVOID Address
);
578 MmInitializeMdlImplementation(VOID
);
579 extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress
;
582 MmDumpToPagingFile(ULONG BugCode
,
583 ULONG BugCodeParameter1
,
584 ULONG BugCodeParameter2
,
585 ULONG BugCodeParameter3
,
586 ULONG BugCodeParameter4
,
587 struct _KTRAP_FRAME
* TrapFrame
);
589 typedef VOID (*PMM_ALTER_REGION_FUNC
)(PMADDRESS_SPACE AddressSpace
,
590 PVOID BaseAddress
, ULONG Length
,
591 ULONG OldType
, ULONG OldProtect
,
592 ULONG NewType
, ULONG NewProtect
);
594 typedef struct _MM_REGION
599 LIST_ENTRY RegionListEntry
;
600 } MM_REGION
, *PMM_REGION
;
603 MmAlterRegion(PMADDRESS_SPACE AddressSpace
, PVOID BaseAddress
,
604 PLIST_ENTRY RegionListHead
, PVOID StartAddress
, ULONG Length
,
605 ULONG NewType
, ULONG NewProtect
,
606 PMM_ALTER_REGION_FUNC AlterFunc
);
608 MmInitialiseRegion(PLIST_ENTRY RegionListHead
, ULONG Length
, ULONG Type
,
611 MmFindRegion(PVOID BaseAddress
, PLIST_ENTRY RegionListHead
, PVOID Address
,
612 PVOID
* RegionBaseAddress
);
614 MmQueryAnonMem(PMEMORY_AREA MemoryArea
,
616 PMEMORY_BASIC_INFORMATION Info
,
617 PULONG ResultLength
);
619 MmQuerySectionView(PMEMORY_AREA MemoryArea
,
621 PMEMORY_BASIC_INFORMATION Info
,
622 PULONG ResultLength
);
624 MmProtectAnonMem(PMADDRESS_SPACE AddressSpace
,
625 PMEMORY_AREA MemoryArea
,
631 MmProtectSectionView(PMADDRESS_SPACE AddressSpace
,
632 PMEMORY_AREA MemoryArea
,
638 MmWritePageSectionView(PMADDRESS_SPACE AddressSpace
,
643 MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace
,
648 MmSetCleanAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
);
650 MmSetDirtyAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
);
652 MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress
);
654 MmIsDirtyPageRmap(PHYSICAL_ADDRESS PhysicalAddress
);
655 NTSTATUS
MmInitMpwThread(VOID
);
657 MmIsAvailableSwapPage(VOID
);
659 MmShowOutOfSpaceMessagePagingFile(VOID
);
661 MmRebalanceMemoryConsumers(VOID
);
663 MiIsPagerThread(VOID
);
665 MiStartPagerThread(VOID
);
667 MmSetLRULastPage(PHYSICAL_ADDRESS PhysicalAddress
);
669 MmRawDeleteVirtualMapping(PVOID Address
);
671 MiStopPagerThread(VOID
);