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
;
19 struct _MM_RMAP_ENTRY
;
21 typedef ULONG SWAPENTRY
;
23 #define MEMORY_AREA_INVALID (0)
24 #define MEMORY_AREA_SECTION_VIEW (1)
25 #define MEMORY_AREA_CONTINUOUS_MEMORY (2)
26 #define MEMORY_AREA_NO_CACHE (3)
27 #define MEMORY_AREA_IO_MAPPING (4)
28 #define MEMORY_AREA_SYSTEM (5)
29 #define MEMORY_AREA_MDL_MAPPING (7)
30 #define MEMORY_AREA_VIRTUAL_MEMORY (8)
31 #define MEMORY_AREA_CACHE_SEGMENT (9)
32 #define MEMORY_AREA_SHARED_DATA (10)
33 #define MEMORY_AREA_KERNEL_STACK (11)
34 #define MEMORY_AREA_PAGED_POOL (12)
35 #define MEMORY_AREA_NO_ACCESS (13)
37 #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
39 #define PAGE_TO_SECTION_PAGE_TABLE_OFFSET(x) \
40 ((((x)) % (4*1024*1024)) / (4*1024))
42 #define NR_SECTION_PAGE_TABLES (1024)
43 #define NR_SECTION_PAGE_ENTRIES (1024)
47 * Additional flags for protection attributes
49 #define PAGE_WRITETHROUGH (1024)
50 #define PAGE_SYSTEM (2048)
51 #define PAGE_FLAGS_VALID_FROM_USER_MODE (PAGE_READONLY | \
56 PAGE_EXECUTE_READWRITE | \
57 PAGE_EXECUTE_WRITECOPY | \
64 ULONG Entry
[NR_SECTION_PAGE_ENTRIES
];
65 } SECTION_PAGE_TABLE
, *PSECTION_PAGE_TABLE
;
69 PSECTION_PAGE_TABLE PageTables
[NR_SECTION_PAGE_TABLES
];
70 } SECTION_PAGE_DIRECTORY
, *PSECTION_PAGE_DIRECTORY
;
72 #define SEC_PHYSICALMEMORY (0x80000000)
74 #define MM_PAGEFILE_SEGMENT (0x1)
75 #define MM_DATAFILE_SEGMENT (0x2)
77 #define MM_SECTION_SEGMENT_BSS (0x1)
79 typedef struct _MM_SECTION_SEGMENT
88 SECTION_PAGE_DIRECTORY PageDirectory
;
91 ULONG Characteristics
;
93 } MM_SECTION_SEGMENT
, *PMM_SECTION_SEGMENT
;
95 typedef struct _MM_IMAGE_SECTION_OBJECT
102 ULONG MinorSubsystemVersion
;
103 ULONG MajorSubsystemVersion
;
104 ULONG ImageCharacteristics
;
108 MM_SECTION_SEGMENT Segments
[0];
109 } MM_IMAGE_SECTION_OBJECT
, *PMM_IMAGE_SECTION_OBJECT
;
111 typedef struct _SECTION_OBJECT
115 LARGE_INTEGER MaximumSize
;
116 ULONG SectionPageProtection
;
117 ULONG AllocationAttributes
;
118 PFILE_OBJECT FileObject
;
119 LIST_ENTRY ViewListHead
;
120 KSPIN_LOCK ViewListLock
;
123 PMM_IMAGE_SECTION_OBJECT ImageSection
;
124 PMM_SECTION_SEGMENT Segment
;
130 typedef struct _SECTION_OBJECT
*PSECTION_OBJECT
;
132 #endif /* __USE_W32API */
142 struct _EPROCESS
* Process
;
143 BOOLEAN DeleteInProgress
;
149 SECTION_OBJECT
* Section
;
151 LIST_ENTRY ViewListEntry
;
152 PMM_SECTION_SEGMENT Segment
;
153 BOOLEAN WriteCopyView
;
154 LIST_ENTRY RegionListHead
;
158 LIST_ENTRY RegionListHead
;
161 } MEMORY_AREA
, *PMEMORY_AREA
;
163 typedef struct _MADDRESS_SPACE
165 LIST_ENTRY MAreaListHead
;
168 struct _EPROCESS
* Process
;
169 PUSHORT PageTableRefCountTable
;
170 ULONG PageTableRefCountTableSize
;
171 } MADDRESS_SPACE
, *PMADDRESS_SPACE
;
177 extern PVOID MmSystemRangeStart
;
179 #endif /* __USE_W32API */
184 VOID
MmLockAddressSpace(PMADDRESS_SPACE AddressSpace
);
185 VOID
MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace
);
186 VOID
MmInitializeKernelAddressSpace(VOID
);
187 PMADDRESS_SPACE
MmGetCurrentAddressSpace(VOID
);
188 PMADDRESS_SPACE
MmGetKernelAddressSpace(VOID
);
189 NTSTATUS
MmInitializeAddressSpace(struct _EPROCESS
* Process
,
190 PMADDRESS_SPACE AddressSpace
);
191 NTSTATUS
MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace
);
192 PVOID STDCALL
MmAllocateSection (IN ULONG Length
);
193 NTSTATUS
MmCreateMemoryArea(struct _EPROCESS
* Process
,
194 PMADDRESS_SPACE AddressSpace
,
199 MEMORY_AREA
** Result
,
202 PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL
);
203 MEMORY_AREA
* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace
,
205 ULONG
MmFindGapAtAddress(PMADDRESS_SPACE AddressSpace
,
207 NTSTATUS
MmInitMemoryAreas(VOID
);
208 VOID
MiInitializeNonPagedPool(VOID
);
209 NTSTATUS
MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace
,
212 VOID (*FreePage
)(PVOID Context
, MEMORY_AREA
* MemoryArea
,
213 PVOID Address
, PHYSICAL_ADDRESS PhysAddr
, SWAPENTRY SwapEntry
,
215 PVOID FreePageContext
);
216 VOID
MmDumpMemoryAreas(PLIST_ENTRY ListHead
);
217 NTSTATUS
MmLockMemoryArea(MEMORY_AREA
* MemoryArea
);
218 NTSTATUS
MmUnlockMemoryArea(MEMORY_AREA
* MemoryArea
);
219 NTSTATUS
MmInitSectionImplementation(VOID
);
222 #define MM_LOWEST_USER_ADDRESS (4096)
225 PMEMORY_AREA
MmSplitMemoryArea(struct _EPROCESS
* Process
,
226 PMADDRESS_SPACE AddressSpace
,
227 PMEMORY_AREA OriginalMemoryArea
,
231 ULONG NewAttributes
);
233 MmInitializePageList(PVOID FirstPhysKernelAddress
,
234 PVOID LastPhysKernelAddress
,
235 ULONG MemorySizeInPages
,
236 ULONG LastKernelBase
,
237 PADDRESS_RANGE BIOSMemoryMap
,
238 ULONG AddressRangeCount
);
240 MmAllocPage(ULONG Consumer
, SWAPENTRY SavedSwapEntry
);
241 VOID
MmDereferencePage(PHYSICAL_ADDRESS PhysicalAddress
);
242 VOID
MmReferencePage(PHYSICAL_ADDRESS PhysicalAddress
);
243 VOID
MmDeletePageTable(struct _EPROCESS
* Process
,
245 NTSTATUS
MmCopyMmInfo(struct _EPROCESS
* Src
,
246 struct _EPROCESS
* Dest
);
247 NTSTATUS
MmReleaseMmInfo(struct _EPROCESS
* Process
);
248 NTSTATUS
Mmi386ReleaseMmInfo(struct _EPROCESS
* Process
);
250 MmDeleteVirtualMapping(struct _EPROCESS
* Process
,
254 PHYSICAL_ADDRESS
* PhysicalPage
);
255 VOID
MmUpdateStackPageDir(PULONG LocalPageDir
, struct _KTHREAD
* KThread
);
257 #define MM_PAGE_CLEAN (0)
258 #define MM_PAGE_DIRTY (1)
260 VOID
MmBuildMdlFromPages(PMDL Mdl
, PULONG Pages
);
261 PVOID
MmGetMdlPageAddress(PMDL Mdl
, PVOID Offset
);
262 VOID
MiShutdownMemoryManager(VOID
);
264 MmGetPhysicalAddressForProcess(struct _EPROCESS
* Process
,
267 MmUnmapViewOfSection(struct _EPROCESS
* Process
, PVOID BaseAddress
);
268 VOID
MmInitPagingFile(VOID
);
270 /* FIXME: it should be in ddk/mmfuncs.h */
274 OUT PSECTION_OBJECT
* SectionObject
,
275 IN ACCESS_MASK DesiredAccess
,
276 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
277 IN PLARGE_INTEGER MaximumSize
,
278 IN ULONG SectionPageProtection
,
279 IN ULONG AllocationAttributes
,
280 IN HANDLE FileHandle OPTIONAL
,
281 IN PFILE_OBJECT File OPTIONAL
284 NTSTATUS
MmPageFault(ULONG Cs
,
291 MmAccessFault(KPROCESSOR_MODE Mode
,
295 MmNotPresentFault(KPROCESSOR_MODE Mode
,
299 MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace
,
300 MEMORY_AREA
* MemoryArea
,
304 MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace
,
305 MEMORY_AREA
* MemoryArea
,
308 NTSTATUS
MmWaitForPage(PVOID Page
);
309 VOID
MmClearWaitPage(PVOID Page
);
310 VOID
MmSetWaitPage(PVOID Page
);
311 BOOLEAN
MmIsDirtyPage(struct _EPROCESS
* Process
, PVOID Address
);
312 BOOLEAN
MmIsPageTablePresent(PVOID PAddress
);
314 MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace
,
315 PMEMORY_AREA MemoryArea
,
317 struct _MM_PAGEOP
* PageOp
);
319 MmPageOutSectionView(PMADDRESS_SPACE AddressSpace
,
320 PMEMORY_AREA MemoryArea
,
322 struct _MM_PAGEOP
* PageOp
);
323 MEMORY_AREA
* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace
,
326 PVOID
MmFindGap(PMADDRESS_SPACE AddressSpace
, ULONG Length
, BOOL TopDown
);
327 VOID
ExUnmapPage(PVOID Addr
);
328 PVOID
ExAllocatePage(VOID
);
330 BOOLEAN
MmReserveSwapPages(ULONG Nr
);
331 VOID
MmDereserveSwapPages(ULONG Nr
);
332 SWAPENTRY
MmAllocSwapPage(VOID
);
333 VOID
MmFreeSwapPage(SWAPENTRY Entry
);
335 VOID
MmInit1(ULONG FirstKernelPhysAddress
,
336 ULONG LastKernelPhysAddress
,
337 ULONG LastKernelAddress
,
338 PADDRESS_RANGE BIOSMemoryMap
,
339 ULONG AddressRangeCount
,
343 VOID
MiFreeInitMemory(VOID
);
345 NTSTATUS
MmInitPagerThread(VOID
);
347 VOID
MiInitBalancerThread(VOID
);
348 NTSTATUS
MmInitZeroPageThread(VOID
);
350 VOID
MiInitKernelMap(VOID
);
351 NTSTATUS
MmCreatePageTable(PVOID PAddress
);
357 ULONG NrReservedPages
;
362 ULONG PagingRequestsInLastMinute
;
363 ULONG PagingRequestsInLastFiveMinutes
;
364 ULONG PagingRequestsInLastFifteenMinutes
;
367 extern MM_STATS MmStats
;
370 MmGetDirtyPagesFromWorkingSet(struct _EPROCESS
* Process
);
372 MmWriteToSwapPage(SWAPENTRY SwapEntry
, PHYSICAL_ADDRESS
* Page
);
374 MmReadFromSwapPage(SWAPENTRY SwapEntry
, PHYSICAL_ADDRESS
* Page
);
376 MmSetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress
, ULONG Flags
);
378 MmGetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress
);
379 VOID
MmSetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress
,
380 SWAPENTRY SavedSwapEntry
);
381 SWAPENTRY
MmGetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress
);
382 VOID
MmSetCleanPage(struct _EPROCESS
* Process
, PVOID Address
);
383 VOID
MmLockPage(PHYSICAL_ADDRESS PhysicalPage
);
384 VOID
MmUnlockPage(PHYSICAL_ADDRESS PhysicalPage
);
385 ULONG
MmGetLockCountPage(PHYSICAL_ADDRESS PhysicalPage
);
387 NTSTATUS
MmSafeCopyFromUser(PVOID Dest
, const VOID
*Src
, ULONG Count
);
388 NTSTATUS
MmSafeCopyToUser(PVOID Dest
, const VOID
*Src
, ULONG Count
);
390 MmCreatePhysicalMemorySection(VOID
);
392 MmGetContinuousPages(ULONG NumberOfBytes
,
393 PHYSICAL_ADDRESS LowestAcceptableAddress
,
394 PHYSICAL_ADDRESS HighestAcceptableAddress
,
397 #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
400 MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace
,
401 MEMORY_AREA
* MemoryArea
,
405 MmGetPageProtect(struct _EPROCESS
* Process
, PVOID Address
);
407 ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage
);
409 MmGetReferenceCountPage(PHYSICAL_ADDRESS PhysicalAddress
);
411 MmIsUsablePage(PHYSICAL_ADDRESS PhysicalAddress
);
413 #define MM_PAGEOP_PAGEIN (1)
414 #define MM_PAGEOP_PAGEOUT (2)
415 #define MM_PAGEOP_PAGESYNCH (3)
416 #define MM_PAGEOP_ACCESSFAULT (4)
418 typedef struct _MM_PAGEOP
420 /* Type of operation. */
422 /* Number of threads interested in this operation. */
423 ULONG ReferenceCount
;
424 /* Event that will be set when the operation is completed. */
425 KEVENT CompletionEvent
;
426 /* Status of the operation once it is completed. */
428 /* TRUE if the operation was abandoned. */
430 /* The memory area to be affected by the operation. */
433 struct _MM_PAGEOP
* Next
;
434 struct _ETHREAD
* Thread
;
436 * These fields are used to identify the operation if it is against a
437 * virtual memory area.
442 * These fields are used to identify the operation if it is against a
445 PMM_SECTION_SEGMENT Segment
;
447 } MM_PAGEOP
, *PMM_PAGEOP
;
450 MmReleasePageOp(PMM_PAGEOP PageOp
);
453 MmGetPageOp(PMEMORY_AREA MArea
, ULONG Pid
, PVOID Address
,
454 PMM_SECTION_SEGMENT Segment
, ULONG Offset
, ULONG OpType
, BOOL First
);
456 MmCheckForPageOp(PMEMORY_AREA MArea
, ULONG Pid
, PVOID Address
,
457 PMM_SECTION_SEGMENT Segment
, ULONG Offset
);
459 MmInitializePageOp(VOID
);
461 MiDebugDumpNonPagedPool(BOOLEAN NewOnly
);
463 MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly
);
465 MmMarkPageMapped(PHYSICAL_ADDRESS PhysicalAddress
);
467 MmMarkPageUnmapped(PHYSICAL_ADDRESS PhysicalAddress
);
469 MmFreeSectionSegments(PFILE_OBJECT FileObject
);
474 MmFreeVirtualMemory(struct _EPROCESS
* Process
, PMEMORY_AREA MemoryArea
);
476 MiCopyFromUserPage(PHYSICAL_ADDRESS DestPhysPage
, PVOID SourceAddress
);
478 MiZeroPage(PHYSICAL_ADDRESS PhysPage
);
480 MmIsAccessedAndResetAccessPage(struct _EPROCESS
* Process
, PVOID Address
);
482 #define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001)
485 MmCreateVirtualMappingForKernel(PVOID Address
,
487 PHYSICAL_ADDRESS PhysicalAddress
);
488 NTSTATUS
MmCommitPagedPoolAddress(PVOID Address
, BOOLEAN Locked
);
489 NTSTATUS
MmCreateVirtualMapping(struct _EPROCESS
* Process
,
492 PHYSICAL_ADDRESS PhysicalAddress
,
495 MmCreateVirtualMappingUnsafe(struct _EPROCESS
* Process
,
498 PHYSICAL_ADDRESS PhysicalAddress
,
501 VOID
MmSetPageProtect(struct _EPROCESS
* Process
,
504 BOOLEAN
MmIsPagePresent(struct _EPROCESS
* Process
,
507 VOID
MmInitGlobalKernelPageDirectory(VOID
);
509 /* Memory balancing. */
511 MmInitializeMemoryConsumer(ULONG Consumer
,
512 NTSTATUS (*Trim
)(ULONG Target
, ULONG Priority
,
515 MmInitializeBalancer(ULONG NrAvailablePages
, ULONG NrSystemPages
);
517 MmReleasePageMemoryConsumer(ULONG Consumer
, PHYSICAL_ADDRESS Page
);
519 MmRequestPageMemoryConsumer(ULONG Consumer
, BOOLEAN CanWait
,
520 PHYSICAL_ADDRESS
* AllocatedPage
);
525 #define MC_NPPOOL (3)
526 #define MC_MAXIMUM (4)
529 typedef struct _MM_MEMORY_CONSUMER
533 NTSTATUS (*Trim
)(ULONG Target
, ULONG Priority
, PULONG NrFreed
);
535 MM_MEMORY_CONSUMER
, *PMM_MEMORY_CONSUMER
;
537 extern MM_MEMORY_CONSUMER MiMemoryConsumers
[MC_MAXIMUM
];
540 MmSetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress
,
541 struct _MM_RMAP_ENTRY
* ListHead
);
542 struct _MM_RMAP_ENTRY
*
543 MmGetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress
);
545 MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress
, PEPROCESS Process
,
548 MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
, PVOID Context
,
549 VOID (*DeleteMapping
)(PVOID Context
, PEPROCESS Process
, PVOID Address
));
551 MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress
, PEPROCESS Process
,
554 MmInitializeRmapList(VOID
);
556 MmGetLRUNextUserPage(PHYSICAL_ADDRESS PreviousPhysicalAddress
);
558 MmGetLRUFirstUserPage(VOID
);
560 MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress
);
562 MmTrimUserMemory(ULONG Target
, ULONG Priority
, PULONG NrFreedPages
);
565 MmDisableVirtualMapping(PEPROCESS Process
, PVOID Address
, BOOL
* WasDirty
, PHYSICAL_ADDRESS
* PhysicalAddr
);
566 VOID
MmEnableVirtualMapping(PEPROCESS Process
, PVOID Address
);
568 MmDeletePageFileMapping(PEPROCESS Process
, PVOID Address
,
569 SWAPENTRY
* SwapEntry
);
571 MmCreatePageFileMapping(PEPROCESS Process
,
573 SWAPENTRY SwapEntry
);
574 BOOLEAN
MmIsPageSwapEntry(PEPROCESS Process
, PVOID Address
);
576 MmTransferOwnershipPage(PHYSICAL_ADDRESS PhysicalAddress
, ULONG NewConsumer
);
577 VOID
MmSetDirtyPage(PEPROCESS Process
, PVOID Address
);
579 MmInitializeMdlImplementation(VOID
);
580 extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress
;
583 MmDumpToPagingFile(ULONG BugCode
,
584 ULONG BugCodeParameter1
,
585 ULONG BugCodeParameter2
,
586 ULONG BugCodeParameter3
,
587 ULONG BugCodeParameter4
,
588 struct _KTRAP_FRAME
* TrapFrame
);
590 typedef VOID (*PMM_ALTER_REGION_FUNC
)(PMADDRESS_SPACE AddressSpace
,
591 PVOID BaseAddress
, ULONG Length
,
592 ULONG OldType
, ULONG OldProtect
,
593 ULONG NewType
, ULONG NewProtect
);
595 typedef struct _MM_REGION
600 LIST_ENTRY RegionListEntry
;
601 } MM_REGION
, *PMM_REGION
;
604 MmAlterRegion(PMADDRESS_SPACE AddressSpace
, PVOID BaseAddress
,
605 PLIST_ENTRY RegionListHead
, PVOID StartAddress
, ULONG Length
,
606 ULONG NewType
, ULONG NewProtect
,
607 PMM_ALTER_REGION_FUNC AlterFunc
);
609 MmInitialiseRegion(PLIST_ENTRY RegionListHead
, ULONG Length
, ULONG Type
,
612 MmFindRegion(PVOID BaseAddress
, PLIST_ENTRY RegionListHead
, PVOID Address
,
613 PVOID
* RegionBaseAddress
);
615 MmQueryAnonMem(PMEMORY_AREA MemoryArea
,
617 PMEMORY_BASIC_INFORMATION Info
,
618 PULONG ResultLength
);
620 MmQuerySectionView(PMEMORY_AREA MemoryArea
,
622 PMEMORY_BASIC_INFORMATION Info
,
623 PULONG ResultLength
);
625 MmProtectAnonMem(PMADDRESS_SPACE AddressSpace
,
626 PMEMORY_AREA MemoryArea
,
632 MmProtectSectionView(PMADDRESS_SPACE AddressSpace
,
633 PMEMORY_AREA MemoryArea
,
639 MmWritePageSectionView(PMADDRESS_SPACE AddressSpace
,
644 MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace
,
649 MmSetCleanAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
);
651 MmSetDirtyAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
);
653 MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress
);
655 MmIsDirtyPageRmap(PHYSICAL_ADDRESS PhysicalAddress
);
656 NTSTATUS
MmInitMpwThread(VOID
);
658 MmIsAvailableSwapPage(VOID
);
660 MmShowOutOfSpaceMessagePagingFile(VOID
);
662 MmRebalanceMemoryConsumers(VOID
);
664 MiIsPagerThread(VOID
);
666 MiStartPagerThread(VOID
);
668 MmSetLRULastPage(PHYSICAL_ADDRESS PhysicalAddress
);
670 MmRawDeleteVirtualMapping(PVOID Address
);
672 MiStopPagerThread(VOID
);