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 MM_PAGEFILE_SECTION (0x1)
68 #define MM_IMAGE_SECTION (0x2)
70 * Flags for section objects
72 #define SO_PHYSICAL_MEMORY (0x4)
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
;
96 LARGE_INTEGER MaximumSize
;
97 ULONG SectionPageProtection
;
98 ULONG AllocateAttributes
;
99 PFILE_OBJECT FileObject
;
100 LIST_ENTRY ViewListHead
;
101 KSPIN_LOCK ViewListLock
;
105 PMM_SECTION_SEGMENT Segments
;
111 ULONG MinorSubsystemVersion
;
112 ULONG MajorSubsystemVersion
;
113 ULONG ImageCharacteristics
;
116 } SECTION_OBJECT
, *PSECTION_OBJECT
;
126 struct _EPROCESS
* Process
;
127 BOOLEAN DeleteInProgress
;
133 SECTION_OBJECT
* Section
;
135 LIST_ENTRY ViewListEntry
;
136 PMM_SECTION_SEGMENT Segment
;
137 BOOLEAN WriteCopyView
;
138 LIST_ENTRY RegionListHead
;
142 LIST_ENTRY RegionListHead
;
145 } MEMORY_AREA
, *PMEMORY_AREA
;
147 typedef struct _MADDRESS_SPACE
149 LIST_ENTRY MAreaListHead
;
152 struct _EPROCESS
* Process
;
153 PUSHORT PageTableRefCountTable
;
154 ULONG PageTableRefCountTableSize
;
155 } MADDRESS_SPACE
, *PMADDRESS_SPACE
;
159 VOID
MmLockAddressSpace(PMADDRESS_SPACE AddressSpace
);
160 VOID
MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace
);
161 VOID
MmInitializeKernelAddressSpace(VOID
);
162 PMADDRESS_SPACE
MmGetCurrentAddressSpace(VOID
);
163 PMADDRESS_SPACE
MmGetKernelAddressSpace(VOID
);
164 NTSTATUS
MmInitializeAddressSpace(struct _EPROCESS
* Process
,
165 PMADDRESS_SPACE AddressSpace
);
166 NTSTATUS
MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace
);
167 PVOID STDCALL
MmAllocateSection (IN ULONG Length
);
168 NTSTATUS
MmCreateMemoryArea(struct _EPROCESS
* Process
,
169 PMADDRESS_SPACE AddressSpace
,
174 MEMORY_AREA
** Result
,
176 MEMORY_AREA
* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace
,
178 NTSTATUS
MmInitMemoryAreas(VOID
);
179 VOID
ExInitNonPagedPool(ULONG BaseAddress
);
180 NTSTATUS
MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace
,
183 VOID (*FreePage
)(PVOID Context
, MEMORY_AREA
* MemoryArea
,
184 PVOID Address
, PHYSICAL_ADDRESS PhysAddr
, SWAPENTRY SwapEntry
,
186 PVOID FreePageContext
);
187 VOID
MmDumpMemoryAreas(PLIST_ENTRY ListHead
);
188 NTSTATUS
MmLockMemoryArea(MEMORY_AREA
* MemoryArea
);
189 NTSTATUS
MmUnlockMemoryArea(MEMORY_AREA
* MemoryArea
);
190 NTSTATUS
MmInitSectionImplementation(VOID
);
192 #define MM_LOWEST_USER_ADDRESS (4096)
194 PMEMORY_AREA
MmSplitMemoryArea(struct _EPROCESS
* Process
,
195 PMADDRESS_SPACE AddressSpace
,
196 PMEMORY_AREA OriginalMemoryArea
,
200 ULONG NewAttributes
);
202 MmInitializePageList(PVOID FirstPhysKernelAddress
,
203 PVOID LastPhysKernelAddress
,
204 ULONG MemorySizeInPages
,
205 ULONG LastKernelBase
,
206 PADDRESS_RANGE BIOSMemoryMap
,
207 ULONG AddressRangeCount
);
209 MmAllocPage(ULONG Consumer
, SWAPENTRY SavedSwapEntry
);
210 VOID
MmDereferencePage(PHYSICAL_ADDRESS PhysicalAddress
);
211 VOID
MmReferencePage(PHYSICAL_ADDRESS PhysicalAddress
);
212 VOID
MmDeletePageTable(struct _EPROCESS
* Process
,
214 NTSTATUS
MmCopyMmInfo(struct _EPROCESS
* Src
,
215 struct _EPROCESS
* Dest
);
216 NTSTATUS
MmReleaseMmInfo(struct _EPROCESS
* Process
);
217 NTSTATUS
Mmi386ReleaseMmInfo(struct _EPROCESS
* Process
);
219 MmDeleteVirtualMapping(struct _EPROCESS
* Process
,
223 PHYSICAL_ADDRESS
* PhysicalPage
);
225 #define MM_PAGE_CLEAN (0)
226 #define MM_PAGE_DIRTY (1)
228 VOID
MmBuildMdlFromPages(PMDL Mdl
, PULONG Pages
);
229 PVOID
MmGetMdlPageAddress(PMDL Mdl
, PVOID Offset
);
230 VOID
MiShutdownMemoryManager(VOID
);
232 MmGetPhysicalAddressForProcess(struct _EPROCESS
* Process
,
235 MmUnmapViewOfSection(struct _EPROCESS
* Process
, PVOID BaseAddress
);
236 VOID
MmInitPagingFile(VOID
);
238 /* FIXME: it should be in ddk/mmfuncs.h */
242 OUT PSECTION_OBJECT
* SectionObject
,
243 IN ACCESS_MASK DesiredAccess
,
244 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL
,
245 IN PLARGE_INTEGER MaximumSize
,
246 IN ULONG SectionPageProtection
,
247 IN ULONG AllocationAttributes
,
248 IN HANDLE FileHandle OPTIONAL
,
249 IN PFILE_OBJECT File OPTIONAL
252 NTSTATUS
MmPageFault(ULONG Cs
,
259 MmAccessFault(KPROCESSOR_MODE Mode
,
263 MmNotPresentFault(KPROCESSOR_MODE Mode
,
267 MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace
,
268 MEMORY_AREA
* MemoryArea
,
272 MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace
,
273 MEMORY_AREA
* MemoryArea
,
276 NTSTATUS
MmWaitForPage(PVOID Page
);
277 VOID
MmClearWaitPage(PVOID Page
);
278 VOID
MmSetWaitPage(PVOID Page
);
279 BOOLEAN
MmIsPageDirty(struct _EPROCESS
* Process
, PVOID Address
);
280 BOOLEAN
MmIsPageTablePresent(PVOID PAddress
);
282 MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace
,
283 PMEMORY_AREA MemoryArea
,
285 struct _MM_PAGEOP
* PageOp
);
287 MmPageOutSectionView(PMADDRESS_SPACE AddressSpace
,
288 PMEMORY_AREA MemoryArea
,
290 struct _MM_PAGEOP
* PageOp
);
291 MEMORY_AREA
* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace
,
295 VOID
ExUnmapPage(PVOID Addr
);
296 PVOID
ExAllocatePage(VOID
);
298 VOID
MmInitPagingFile(VOID
);
299 BOOLEAN
MmReserveSwapPages(ULONG Nr
);
300 VOID
MmDereserveSwapPages(ULONG Nr
);
301 SWAPENTRY
MmAllocSwapPage(VOID
);
302 VOID
MmFreeSwapPage(SWAPENTRY Entry
);
304 VOID
MmInit1(ULONG FirstKernelPhysAddress
,
305 ULONG LastKernelPhysAddress
,
306 ULONG LastKernelAddress
,
307 PADDRESS_RANGE BIOSMemoryMap
,
308 ULONG AddressRangeCount
);
311 NTSTATUS
MmInitPagerThread(VOID
);
313 VOID
MmInitKernelMap(PVOID BaseAddress
);
314 NTSTATUS
MmCreatePageTable(PVOID PAddress
);
320 ULONG NrReservedPages
;
325 ULONG PagingRequestsInLastMinute
;
326 ULONG PagingRequestsInLastFiveMinutes
;
327 ULONG PagingRequestsInLastFifteenMinutes
;
330 extern MM_STATS MmStats
;
333 MmWritePageSectionView(PMADDRESS_SPACE AddressSpace
,
337 MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace
,
341 MmGetDirtyPagesFromWorkingSet(struct _EPROCESS
* Process
);
343 MmWriteToSwapPage(SWAPENTRY SwapEntry
, PMDL Mdl
);
345 MmReadFromSwapPage(SWAPENTRY SwapEntry
, PMDL Mdl
);
347 MmSetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress
, ULONG Flags
);
349 MmGetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress
);
350 VOID
MmSetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress
,
351 SWAPENTRY SavedSwapEntry
);
352 SWAPENTRY
MmGetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress
);
353 VOID
MmSetCleanPage(struct _EPROCESS
* Process
, PVOID Address
);
354 VOID
MmLockPage(PHYSICAL_ADDRESS PhysicalPage
);
355 VOID
MmUnlockPage(PHYSICAL_ADDRESS PhysicalPage
);
357 NTSTATUS
MmSafeCopyFromUser(PVOID Dest
, PVOID Src
, ULONG Count
);
358 NTSTATUS
MmSafeCopyToUser(PVOID Dest
, PVOID Src
, ULONG Count
);
360 MmCreatePhysicalMemorySection(VOID
);
362 MmGetContinuousPages(ULONG NumberOfBytes
,
363 PHYSICAL_ADDRESS HighestAcceptableAddress
,
366 #define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
369 MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace
,
370 MEMORY_AREA
* MemoryArea
,
374 MmGetPageProtect(struct _EPROCESS
* Process
, PVOID Address
);
376 ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage
);
378 MmGetReferenceCountPage(PHYSICAL_ADDRESS PhysicalAddress
);
380 MmIsUsablePage(PHYSICAL_ADDRESS PhysicalAddress
);
382 #define MM_PAGEOP_PAGEIN (1)
383 #define MM_PAGEOP_PAGEOUT (2)
384 #define MM_PAGEOP_PAGESYNCH (3)
385 #define MM_PAGEOP_ACCESSFAULT (4)
387 typedef struct _MM_PAGEOP
389 /* Type of operation. */
391 /* Number of threads interested in this operation. */
392 ULONG ReferenceCount
;
393 /* Event that will be set when the operation is completed. */
394 KEVENT CompletionEvent
;
395 /* Status of the operation once it is completed. */
397 /* TRUE if the operation was abandoned. */
399 /* The memory area to be affected by the operation. */
402 struct _MM_PAGEOP
* Next
;
403 struct _ETHREAD
* Thread
;
405 * These fields are used to identify the operation if it is against a
406 * virtual memory area.
411 * These fields are used to identify the operation if it is against a
414 PMM_SECTION_SEGMENT Segment
;
416 } MM_PAGEOP
, *PMM_PAGEOP
;
419 MmReleasePageOp(PMM_PAGEOP PageOp
);
422 MmGetPageOp(PMEMORY_AREA MArea
, ULONG Pid
, PVOID Address
,
423 PMM_SECTION_SEGMENT Segment
, ULONG Offset
, ULONG OpType
);
426 MiDebugDumpNonPagedPool(BOOLEAN NewOnly
);
428 MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly
);
430 MmMarkPageMapped(PHYSICAL_ADDRESS PhysicalAddress
);
432 MmMarkPageUnmapped(PHYSICAL_ADDRESS PhysicalAddress
);
434 MmFreeSectionSegments(PFILE_OBJECT FileObject
);
436 typedef struct _MM_IMAGE_SECTION_OBJECT
439 MM_SECTION_SEGMENT Segments
[0];
440 } MM_IMAGE_SECTION_OBJECT
, *PMM_IMAGE_SECTION_OBJECT
;
443 MmFreeVirtualMemory(struct _EPROCESS
* Process
, PMEMORY_AREA MemoryArea
);
445 MiCopyFromUserPage(PHYSICAL_ADDRESS DestPhysPage
, PVOID SourceAddress
);
447 MiZeroPage(PHYSICAL_ADDRESS PhysPage
);
449 MmIsAccessedAndResetAccessPage(struct _EPROCESS
* Process
, PVOID Address
);
451 #define STATUS_MM_RESTART_OPERATION (0xD0000001)
454 MmCreateVirtualMappingForKernel(PVOID Address
,
456 PHYSICAL_ADDRESS PhysicalAddress
);
457 NTSTATUS
MmCommitPagedPoolAddress(PVOID Address
);
458 NTSTATUS
MmCreateVirtualMapping(struct _EPROCESS
* Process
,
461 PHYSICAL_ADDRESS PhysicalAddress
,
464 MmCreateVirtualMappingUnsafe(struct _EPROCESS
* Process
,
467 PHYSICAL_ADDRESS PhysicalAddress
,
470 VOID
MmSetPageProtect(struct _EPROCESS
* Process
,
473 BOOLEAN
MmIsPagePresent(struct _EPROCESS
* Process
,
476 /* Memory balancing. */
478 MmInitializeMemoryConsumer(ULONG Consumer
,
479 NTSTATUS (*Trim
)(ULONG Target
, ULONG Priority
,
482 MmInitializeBalancer(ULONG NrAvailablePages
);
484 MmReleasePageMemoryConsumer(ULONG Consumer
, PHYSICAL_ADDRESS Page
);
486 MmRequestPageMemoryConsumer(ULONG Consumer
, BOOLEAN CanWait
,
487 PHYSICAL_ADDRESS
* AllocatedPage
);
492 #define MC_NPPOOL (3)
493 #define MC_MAXIMUM (4)
496 MmSetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress
,
497 struct _MM_RMAP_ENTRY
* ListHead
);
498 struct _MM_RMAP_ENTRY
*
499 MmGetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress
);
501 MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress
, PEPROCESS Process
,
504 MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress
, PVOID Context
,
505 VOID (*DeleteMapping
)(PVOID Context
, PEPROCESS Process
, PVOID Address
));
507 MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress
, PEPROCESS Process
,
510 MmInitializeRmapList(VOID
);
512 MmGetLRUNextUserPage(PHYSICAL_ADDRESS PreviousPhysicalAddress
);
514 MmGetLRUFirstUserPage(VOID
);
516 MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress
);
518 MmTrimUserMemory(ULONG Target
, ULONG Priority
, PULONG NrFreedPages
);
521 MmDisableVirtualMapping(PEPROCESS Process
, PVOID Address
, BOOL
* WasDirty
, ULONG
* PhysicalAddr
);
522 VOID
MmEnableVirtualMapping(PEPROCESS Process
, PVOID Address
);
524 MmDeletePageFileMapping(PEPROCESS Process
, PVOID Address
,
525 SWAPENTRY
* SwapEntry
);
527 MmCreatePageFileMapping(PEPROCESS Process
,
529 SWAPENTRY SwapEntry
);
530 BOOLEAN
MmIsPageSwapEntry(PEPROCESS Process
, PVOID Address
);
532 MmTransferOwnershipPage(PHYSICAL_ADDRESS PhysicalAddress
, ULONG NewConsumer
);
533 VOID
MmSetDirtyPage(PEPROCESS Process
, PVOID Address
);
535 MmInitializeMdlImplementation(VOID
);
536 extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress
;
538 MmCheckForPageOp(PMEMORY_AREA MArea
, ULONG Pid
, PVOID Address
,
539 PMM_SECTION_SEGMENT Segment
, ULONG Offset
);
542 MmDumpToPagingFile(ULONG BugCode
,
543 ULONG BugCodeParameter1
,
544 ULONG BugCodeParameter2
,
545 ULONG BugCodeParameter3
,
546 ULONG BugCodeParameter4
,
547 struct _KTRAP_FRAME
* TrapFrame
);
549 typedef VOID (*PMM_ALTER_REGION_FUNC
)(PMADDRESS_SPACE AddressSpace
,
550 PVOID BaseAddress
, ULONG Length
,
551 ULONG OldType
, ULONG OldProtect
,
552 ULONG NewType
, ULONG NewProtect
);
554 typedef struct _MM_REGION
559 LIST_ENTRY RegionListEntry
;
560 } MM_REGION
, *PMM_REGION
;
563 MmAlterRegion(PMADDRESS_SPACE AddressSpace
, PVOID BaseAddress
,
564 PLIST_ENTRY RegionListHead
, PVOID StartAddress
, ULONG Length
,
565 ULONG NewType
, ULONG NewProtect
,
566 PMM_ALTER_REGION_FUNC AlterFunc
);
568 MmInitialiseRegion(PLIST_ENTRY RegionListHead
, ULONG Length
, ULONG Type
,
571 MmFindRegion(PVOID BaseAddress
, PLIST_ENTRY RegionListHead
, PVOID Address
,
572 PVOID
* RegionBaseAddress
);
574 MmQueryAnonMem(PMEMORY_AREA MemoryArea
,
576 PMEMORY_BASIC_INFORMATION Info
,
577 PULONG ResultLength
);
579 MmQuerySectionView(PMEMORY_AREA MemoryArea
,
581 PMEMORY_BASIC_INFORMATION Info
,
582 PULONG ResultLength
);
584 MmProtectAnonMem(PMADDRESS_SPACE AddressSpace
,
585 PMEMORY_AREA MemoryArea
,
591 MmProtectSectionView(PMADDRESS_SPACE AddressSpace
,
592 PMEMORY_AREA MemoryArea
,