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)
31 #define MEMORY_AREA_NO_ACCESS (13)
33 #define PAGE_TO_SECTION_PAGE_DIRECTORY_OFFSET(x) \
35 #define PAGE_TO_SECTION_PAGE_TABLE_OFFSET(x) \
36 ((((x)) % (4*1024*1024)) / (4*1024))
38 #define NR_SECTION_PAGE_TABLES (1024)
39 #define NR_SECTION_PAGE_ENTRIES (1024)
43 * Additional flags for protection attributes
45 #define PAGE_WRITETHROUGH (1024)
46 #define PAGE_SYSTEM (2048)
47 #define PAGE_FLAGS_VALID_FROM_USER_MODE (PAGE_READONLY | \
52 PAGE_EXECUTE_READWRITE | \
53 PAGE_EXECUTE_WRITECOPY | \
60 ULONG Entry
[NR_SECTION_PAGE_ENTRIES
];
61 } SECTION_PAGE_TABLE
, *PSECTION_PAGE_TABLE
;
65 PSECTION_PAGE_TABLE PageTables
[NR_SECTION_PAGE_TABLES
];
66 } SECTION_PAGE_DIRECTORY
, *PSECTION_PAGE_DIRECTORY
;
68 #define SEC_PHYSICALMEMORY (0x80000000)
70 #define MM_PAGEFILE_SEGMENT (0x1)
71 #define MM_DATAFILE_SEGMENT (0x2)
73 #define MM_SECTION_SEGMENT_BSS (0x1)
75 typedef struct _MM_SECTION_SEGMENT
84 SECTION_PAGE_DIRECTORY PageDirectory
;
87 ULONG Characteristics
;
89 } MM_SECTION_SEGMENT
, *PMM_SECTION_SEGMENT
;
91 typedef struct _MM_IMAGE_SECTION_OBJECT
98 ULONG MinorSubsystemVersion
;
99 ULONG MajorSubsystemVersion
;
100 ULONG ImageCharacteristics
;
104 MM_SECTION_SEGMENT Segments
[0];
105 } MM_IMAGE_SECTION_OBJECT
, *PMM_IMAGE_SECTION_OBJECT
;
107 typedef struct _SECTION_OBJECT
111 LARGE_INTEGER MaximumSize
;
112 ULONG SectionPageProtection
;
113 ULONG AllocationAttributes
;
114 PFILE_OBJECT FileObject
;
115 LIST_ENTRY ViewListHead
;
116 KSPIN_LOCK ViewListLock
;
119 PMM_IMAGE_SECTION_OBJECT ImageSection
;
120 PMM_SECTION_SEGMENT Segment
;
126 typedef struct _SECTION_OBJECT
*PSECTION_OBJECT
;
128 #endif /* __USE_W32API */
138 struct _EPROCESS
* Process
;
139 BOOLEAN DeleteInProgress
;
145 SECTION_OBJECT
* Section
;
147 LIST_ENTRY ViewListEntry
;
148 PMM_SECTION_SEGMENT Segment
;
149 BOOLEAN WriteCopyView
;
150 LIST_ENTRY RegionListHead
;
154 LIST_ENTRY RegionListHead
;
157 } MEMORY_AREA
, *PMEMORY_AREA
;
159 typedef struct _MADDRESS_SPACE
161 LIST_ENTRY MAreaListHead
;
164 struct _EPROCESS
* Process
;
165 PUSHORT PageTableRefCountTable
;
166 ULONG PageTableRefCountTableSize
;
167 } MADDRESS_SPACE
, *PMADDRESS_SPACE
;
173 extern PVOID MmSystemRangeStart
;
175 #endif /* __USE_W32API */
180 VOID
MmLockAddressSpace(PMADDRESS_SPACE AddressSpace
);
181 VOID
MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace
);
182 VOID
MmInitializeKernelAddressSpace(VOID
);
183 PMADDRESS_SPACE
MmGetCurrentAddressSpace(VOID
);
184 PMADDRESS_SPACE
MmGetKernelAddressSpace(VOID
);
185 NTSTATUS
MmInitializeAddressSpace(struct _EPROCESS
* Process
,
186 PMADDRESS_SPACE AddressSpace
);
187 NTSTATUS
MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace
);
188 PVOID STDCALL
MmAllocateSection (IN ULONG Length
);
189 NTSTATUS
MmCreateMemoryArea(struct _EPROCESS
* Process
,
190 PMADDRESS_SPACE AddressSpace
,
195 MEMORY_AREA
** Result
,
198 MEMORY_AREA
* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace
,
200 NTSTATUS
MmInitMemoryAreas(VOID
);
201 VOID
MiInitializeNonPagedPool(VOID
);
202 NTSTATUS
MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace
,
205 VOID (*FreePage
)(PVOID Context
, MEMORY_AREA
* MemoryArea
,
206 PVOID Address
, PHYSICAL_ADDRESS PhysAddr
, SWAPENTRY SwapEntry
,
208 PVOID FreePageContext
);
209 VOID
MmDumpMemoryAreas(PLIST_ENTRY ListHead
);
210 NTSTATUS
MmLockMemoryArea(MEMORY_AREA
* MemoryArea
);
211 NTSTATUS
MmUnlockMemoryArea(MEMORY_AREA
* MemoryArea
);
212 NTSTATUS
MmInitSectionImplementation(VOID
);
215 #define MM_LOWEST_USER_ADDRESS (4096)
218 PMEMORY_AREA
MmSplitMemoryArea(struct _EPROCESS
* Process
,
219 PMADDRESS_SPACE AddressSpace
,
220 PMEMORY_AREA OriginalMemoryArea
,
224 ULONG NewAttributes
);
226 MmInitializePageList(PVOID FirstPhysKernelAddress
,
227 PVOID LastPhysKernelAddress
,
228 ULONG MemorySizeInPages
,
229 ULONG LastKernelBase
,
230 PADDRESS_RANGE BIOSMemoryMap
,
231 ULONG AddressRangeCount
);
233 MmAllocPage(ULONG Consumer
, SWAPENTRY SavedSwapEntry
);
234 VOID
MmDereferencePage(PHYSICAL_ADDRESS PhysicalAddress
);
235 VOID
MmReferencePage(PHYSICAL_ADDRESS PhysicalAddress
);
236 VOID
MmDeletePageTable(struct _EPROCESS
* Process
,
238 NTSTATUS
MmCopyMmInfo(struct _EPROCESS
* Src
,
239 struct _EPROCESS
* Dest
);
240 NTSTATUS
MmReleaseMmInfo(struct _EPROCESS
* Process
);
241 NTSTATUS
Mmi386ReleaseMmInfo(struct _EPROCESS
* Process
);
243 MmDeleteVirtualMapping(struct _EPROCESS
* Process
,
247 PHYSICAL_ADDRESS
* PhysicalPage
);
248 VOID
MmUpdateStackPageDir(PULONG LocalPageDir
, struct _KTHREAD
* KThread
);
250 #define MM_PAGE_CLEAN (0)
251 #define MM_PAGE_DIRTY (1)
253 VOID
MmBuildMdlFromPages(PMDL Mdl
, PULONG Pages
);
254 PVOID
MmGetMdlPageAddress(PMDL Mdl
, PVOID Offset
);
255 VOID
MiShutdownMemoryManager(VOID
);
257 MmGetPhysicalAddressForProcess(struct _EPROCESS
* Process
,
260 MmUnmapViewOfSection(struct _EPROCESS
* Process
, PVOID BaseAddress
);
261 VOID
MmInitPagingFile(VOID
);
263 /* FIXME: it should be in ddk/mmfuncs.h */
267 OUT PSECTION_OBJECT
* SectionObject
,
268 IN ACCESS_MASK DesiredAccess
,
269 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
270 IN PLARGE_INTEGER MaximumSize
,
271 IN ULONG SectionPageProtection
,
272 IN ULONG AllocationAttributes
,
273 IN HANDLE FileHandle OPTIONAL
,
274 IN PFILE_OBJECT File OPTIONAL
277 NTSTATUS
MmPageFault(ULONG Cs
,
284 MmAccessFault(KPROCESSOR_MODE Mode
,
288 MmNotPresentFault(KPROCESSOR_MODE Mode
,
292 MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace
,
293 MEMORY_AREA
* MemoryArea
,
297 MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace
,
298 MEMORY_AREA
* MemoryArea
,
301 NTSTATUS
MmWaitForPage(PVOID Page
);
302 VOID
MmClearWaitPage(PVOID Page
);
303 VOID
MmSetWaitPage(PVOID Page
);
304 BOOLEAN
MmIsDirtyPage(struct _EPROCESS
* Process
, PVOID Address
);
305 BOOLEAN
MmIsPageTablePresent(PVOID PAddress
);
307 MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace
,
308 PMEMORY_AREA MemoryArea
,
310 struct _MM_PAGEOP
* PageOp
);
312 MmPageOutSectionView(PMADDRESS_SPACE AddressSpace
,
313 PMEMORY_AREA MemoryArea
,
315 struct _MM_PAGEOP
* PageOp
);
316 MEMORY_AREA
* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace
,
319 PVOID
MmFindGap(PMADDRESS_SPACE AddressSpace
, ULONG Length
, BOOL TopDown
);
320 VOID
ExUnmapPage(PVOID Addr
);
321 PVOID
ExAllocatePage(VOID
);
323 BOOLEAN
MmReserveSwapPages(ULONG Nr
);
324 VOID
MmDereserveSwapPages(ULONG Nr
);
325 SWAPENTRY
MmAllocSwapPage(VOID
);
326 VOID
MmFreeSwapPage(SWAPENTRY Entry
);
328 VOID
MmInit1(ULONG FirstKernelPhysAddress
,
329 ULONG LastKernelPhysAddress
,
330 ULONG LastKernelAddress
,
331 PADDRESS_RANGE BIOSMemoryMap
,
332 ULONG AddressRangeCount
,
336 VOID
MiFreeInitMemory(VOID
);
337 NTSTATUS
MmInitPagerThread(VOID
);
338 NTSTATUS
MmInitZeroPageThread(VOID
);
340 VOID
MiInitKernelMap(VOID
);
341 NTSTATUS
MmCreatePageTable(PVOID PAddress
);
347 ULONG NrReservedPages
;
352 ULONG PagingRequestsInLastMinute
;
353 ULONG PagingRequestsInLastFiveMinutes
;
354 ULONG PagingRequestsInLastFifteenMinutes
;
357 extern MM_STATS MmStats
;
360 MmGetDirtyPagesFromWorkingSet(struct _EPROCESS
* Process
);
362 MmWriteToSwapPage(SWAPENTRY SwapEntry
, PMDL Mdl
);
364 MmReadFromSwapPage(SWAPENTRY SwapEntry
, PMDL Mdl
);
366 MmSetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress
, ULONG Flags
);
368 MmGetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress
);
369 VOID
MmSetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress
,
370 SWAPENTRY SavedSwapEntry
);
371 SWAPENTRY
MmGetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress
);
372 VOID
MmSetCleanPage(struct _EPROCESS
* Process
, PVOID Address
);
373 VOID
MmLockPage(PHYSICAL_ADDRESS PhysicalPage
);
374 VOID
MmUnlockPage(PHYSICAL_ADDRESS PhysicalPage
);
375 ULONG
MmGetLockCountPage(PHYSICAL_ADDRESS PhysicalPage
);
377 NTSTATUS
MmSafeCopyFromUser(PVOID Dest
, const VOID
*Src
, ULONG Count
);
378 NTSTATUS
MmSafeCopyToUser(PVOID Dest
, const VOID
*Src
, ULONG Count
);
380 MmCreatePhysicalMemorySection(VOID
);
382 MmGetContinuousPages(ULONG NumberOfBytes
,
383 PHYSICAL_ADDRESS HighestAcceptableAddress
,
386 #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
389 MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace
,
390 MEMORY_AREA
* MemoryArea
,
394 MmGetPageProtect(struct _EPROCESS
* Process
, PVOID Address
);
396 ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage
);
398 MmGetReferenceCountPage(PHYSICAL_ADDRESS PhysicalAddress
);
400 MmIsUsablePage(PHYSICAL_ADDRESS PhysicalAddress
);
402 #define MM_PAGEOP_PAGEIN (1)
403 #define MM_PAGEOP_PAGEOUT (2)
404 #define MM_PAGEOP_PAGESYNCH (3)
405 #define MM_PAGEOP_ACCESSFAULT (4)
407 typedef struct _MM_PAGEOP
409 /* Type of operation. */
411 /* Number of threads interested in this operation. */
412 ULONG ReferenceCount
;
413 /* Event that will be set when the operation is completed. */
414 KEVENT CompletionEvent
;
415 /* Status of the operation once it is completed. */
417 /* TRUE if the operation was abandoned. */
419 /* The memory area to be affected by the operation. */
422 struct _MM_PAGEOP
* Next
;
423 struct _ETHREAD
* Thread
;
425 * These fields are used to identify the operation if it is against a
426 * virtual memory area.
431 * These fields are used to identify the operation if it is against a
434 PMM_SECTION_SEGMENT Segment
;
436 } MM_PAGEOP
, *PMM_PAGEOP
;
439 MmReleasePageOp(PMM_PAGEOP PageOp
);
442 MmGetPageOp(PMEMORY_AREA MArea
, ULONG Pid
, PVOID Address
,
443 PMM_SECTION_SEGMENT Segment
, ULONG Offset
, ULONG OpType
);
445 MmCheckForPageOp(PMEMORY_AREA MArea
, ULONG Pid
, PVOID Address
,
446 PMM_SECTION_SEGMENT Segment
, ULONG Offset
);
448 MmInitializePageOp(VOID
);
450 MiDebugDumpNonPagedPool(BOOLEAN NewOnly
);
452 MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly
);
454 MmMarkPageMapped(PHYSICAL_ADDRESS PhysicalAddress
);
456 MmMarkPageUnmapped(PHYSICAL_ADDRESS PhysicalAddress
);
458 MmFreeSectionSegments(PFILE_OBJECT FileObject
);
463 MmFreeVirtualMemory(struct _EPROCESS
* Process
, PMEMORY_AREA MemoryArea
);
465 MiCopyFromUserPage(PHYSICAL_ADDRESS DestPhysPage
, PVOID SourceAddress
);
467 MiZeroPage(PHYSICAL_ADDRESS PhysPage
);
469 MmIsAccessedAndResetAccessPage(struct _EPROCESS
* Process
, PVOID Address
);
471 #define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001)
474 MmCreateVirtualMappingForKernel(PVOID Address
,
476 PHYSICAL_ADDRESS PhysicalAddress
);
477 NTSTATUS
MmCommitPagedPoolAddress(PVOID Address
);
478 NTSTATUS
MmCreateVirtualMapping(struct _EPROCESS
* Process
,
481 PHYSICAL_ADDRESS PhysicalAddress
,
484 MmCreateVirtualMappingUnsafe(struct _EPROCESS
* Process
,
487 PHYSICAL_ADDRESS PhysicalAddress
,
490 VOID
MmSetPageProtect(struct _EPROCESS
* Process
,
493 BOOLEAN
MmIsPagePresent(struct _EPROCESS
* Process
,
496 VOID
MmInitGlobalKernelPageDirectory(VOID
);
498 /* Memory balancing. */
500 MmInitializeMemoryConsumer(ULONG Consumer
,
501 NTSTATUS (*Trim
)(ULONG Target
, ULONG Priority
,
504 MmInitializeBalancer(ULONG NrAvailablePages
);
506 MmReleasePageMemoryConsumer(ULONG Consumer
, PHYSICAL_ADDRESS Page
);
508 MmRequestPageMemoryConsumer(ULONG Consumer
, BOOLEAN CanWait
,
509 PHYSICAL_ADDRESS
* AllocatedPage
);
514 #define MC_NPPOOL (3)
515 #define MC_MAXIMUM (4)
518 MmSetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress
,
519 struct _MM_RMAP_ENTRY
* ListHead
);
520 struct _MM_RMAP_ENTRY
*
521 MmGetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress
);
523 MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress
, PEPROCESS Process
,
526 MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
, PVOID Context
,
527 VOID (*DeleteMapping
)(PVOID Context
, PEPROCESS Process
, PVOID Address
));
529 MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress
, PEPROCESS Process
,
532 MmInitializeRmapList(VOID
);
534 MmGetLRUNextUserPage(PHYSICAL_ADDRESS PreviousPhysicalAddress
);
536 MmGetLRUFirstUserPage(VOID
);
538 MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress
);
540 MmTrimUserMemory(ULONG Target
, ULONG Priority
, PULONG NrFreedPages
);
543 MmDisableVirtualMapping(PEPROCESS Process
, PVOID Address
, BOOL
* WasDirty
, PHYSICAL_ADDRESS
* PhysicalAddr
);
544 VOID
MmEnableVirtualMapping(PEPROCESS Process
, PVOID Address
);
546 MmDeletePageFileMapping(PEPROCESS Process
, PVOID Address
,
547 SWAPENTRY
* SwapEntry
);
549 MmCreatePageFileMapping(PEPROCESS Process
,
551 SWAPENTRY SwapEntry
);
552 BOOLEAN
MmIsPageSwapEntry(PEPROCESS Process
, PVOID Address
);
554 MmTransferOwnershipPage(PHYSICAL_ADDRESS PhysicalAddress
, ULONG NewConsumer
);
555 VOID
MmSetDirtyPage(PEPROCESS Process
, PVOID Address
);
557 MmInitializeMdlImplementation(VOID
);
558 extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress
;
561 MmDumpToPagingFile(ULONG BugCode
,
562 ULONG BugCodeParameter1
,
563 ULONG BugCodeParameter2
,
564 ULONG BugCodeParameter3
,
565 ULONG BugCodeParameter4
,
566 struct _KTRAP_FRAME
* TrapFrame
);
568 typedef VOID (*PMM_ALTER_REGION_FUNC
)(PMADDRESS_SPACE AddressSpace
,
569 PVOID BaseAddress
, ULONG Length
,
570 ULONG OldType
, ULONG OldProtect
,
571 ULONG NewType
, ULONG NewProtect
);
573 typedef struct _MM_REGION
578 LIST_ENTRY RegionListEntry
;
579 } MM_REGION
, *PMM_REGION
;
582 MmAlterRegion(PMADDRESS_SPACE AddressSpace
, PVOID BaseAddress
,
583 PLIST_ENTRY RegionListHead
, PVOID StartAddress
, ULONG Length
,
584 ULONG NewType
, ULONG NewProtect
,
585 PMM_ALTER_REGION_FUNC AlterFunc
);
587 MmInitialiseRegion(PLIST_ENTRY RegionListHead
, ULONG Length
, ULONG Type
,
590 MmFindRegion(PVOID BaseAddress
, PLIST_ENTRY RegionListHead
, PVOID Address
,
591 PVOID
* RegionBaseAddress
);
593 MmQueryAnonMem(PMEMORY_AREA MemoryArea
,
595 PMEMORY_BASIC_INFORMATION Info
,
596 PULONG ResultLength
);
598 MmQuerySectionView(PMEMORY_AREA MemoryArea
,
600 PMEMORY_BASIC_INFORMATION Info
,
601 PULONG ResultLength
);
603 MmProtectAnonMem(PMADDRESS_SPACE AddressSpace
,
604 PMEMORY_AREA MemoryArea
,
610 MmProtectSectionView(PMADDRESS_SPACE AddressSpace
,
611 PMEMORY_AREA MemoryArea
,
617 MmWritePageSectionView(PMADDRESS_SPACE AddressSpace
,
622 MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace
,
627 MmSetCleanAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
);
629 MmSetDirtyAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
);
631 MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress
);
633 MmIsDirtyPageRmap(PHYSICAL_ADDRESS PhysicalAddress
);
634 NTSTATUS
MmInitMpwThread(VOID
);
636 MmIsAvailableSwapPage(VOID
);
638 MmShowOutOfSpaceMessagePagingFile(VOID
);
640 MmRebalanceMemoryConsumers(VOID
);
642 MiIsPagerThread(VOID
);
644 MiStartPagerThread(VOID
);
646 MmSetLRULastPage(PHYSICAL_ADDRESS PhysicalAddress
);
648 MmRawDeleteVirtualMapping(PVOID Address
);
650 MiStopPagerThread(VOID
);
652 MmCreateVirtualMappingDump(PVOID Address
,
654 PHYSICAL_ADDRESS PhysicalAddress
);