3 #include <internal/arch/mm.h>
9 /* TYPES *********************************************************************/
13 extern PMMSUPPORT MmKernelAddressSpace
;
14 extern PFN_COUNT MiFreeSwapPages
;
15 extern PFN_COUNT MiUsedSwapPages
;
16 extern PFN_COUNT MmNumberOfPhysicalPages
;
17 extern UCHAR MmDisablePagingExecutive
;
18 extern PFN_NUMBER MmLowestPhysicalPage
;
19 extern PFN_NUMBER MmHighestPhysicalPage
;
20 extern PFN_NUMBER MmAvailablePages
;
21 extern PFN_NUMBER MmResidentAvailablePages
;
22 extern ULONG MmThrottleTop
;
23 extern ULONG MmThrottleBottom
;
25 extern LIST_ENTRY MmLoadedUserImageList
;
27 extern KMUTANT MmSystemLoadLock
;
29 extern ULONG MmNumberOfPagingFiles
;
31 extern SIZE_T MmTotalNonPagedPoolQuota
;
32 extern SIZE_T MmTotalPagedPoolQuota
;
34 extern PVOID MmUnloadedDrivers
;
35 extern PVOID MmLastUnloadedDrivers
;
36 extern PVOID MmTriageActionTaken
;
37 extern PVOID KernelVerifier
;
38 extern MM_DRIVER_VERIFIER_DATA MmVerifierData
;
40 extern SIZE_T MmTotalCommitLimit
;
41 extern SIZE_T MmTotalCommittedPages
;
42 extern SIZE_T MmSharedCommit
;
43 extern SIZE_T MmDriverCommit
;
44 extern SIZE_T MmProcessCommit
;
45 extern SIZE_T MmPagedPoolCommit
;
46 extern SIZE_T MmPeakCommitment
;
47 extern SIZE_T MmtotalCommitLimitMaximum
;
49 extern PVOID MiDebugMapping
; // internal
50 extern PMMPTE MmDebugPte
; // internal
52 extern KSPIN_LOCK MmPfnLock
;
56 struct _MM_RMAP_ENTRY
;
57 typedef ULONG_PTR SWAPENTRY
;
62 #define MI_QUOTA_NON_PAGED_NEEDED_PAGES 64
63 #define MI_NON_PAGED_QUOTA_MIN_RESIDENT_PAGES 200
64 #define MI_CHARGE_PAGED_POOL_QUOTA 0x80000
65 #define MI_CHARGE_NON_PAGED_POOL_QUOTA 0x10000
68 // Special IRQL value (found in assertions)
70 #define MM_NOIRQL ((KIRQL)0xFFFFFFFF)
73 // MmDbgCopyMemory Flags
75 #define MMDBG_COPY_WRITE 0x00000001
76 #define MMDBG_COPY_PHYSICAL 0x00000002
77 #define MMDBG_COPY_UNSAFE 0x00000004
78 #define MMDBG_COPY_CACHED 0x00000008
79 #define MMDBG_COPY_UNCACHED 0x00000010
80 #define MMDBG_COPY_WRITE_COMBINED 0x00000020
83 // Maximum chunk size per copy
85 #define MMDBG_COPY_MAX_SIZE 0x8
87 #if defined(_X86_) // intenal for marea.c
88 #define MI_STATIC_MEMORY_AREAS (14)
90 #define MI_STATIC_MEMORY_AREAS (13)
93 #define MEMORY_AREA_SECTION_VIEW (1)
95 #define MEMORY_AREA_CACHE (2)
97 #define MEMORY_AREA_OWNED_BY_ARM3 (15)
98 #define MEMORY_AREA_STATIC (0x80000000)
100 /* Although Microsoft says this isn't hardcoded anymore,
101 they won't be able to change it. Stuff depends on it */
102 #define MM_VIRTMEM_GRANULARITY (64 * 1024)
104 #define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001)
107 * Additional flags for protection attributes
109 #define PAGE_WRITETHROUGH (1024)
110 #define PAGE_SYSTEM (2048)
112 #define SEC_PHYSICALMEMORY (0x80000000)
115 #define MC_SYSTEM (1)
116 #define MC_MAXIMUM (2)
118 #define PAGED_POOL_MASK 1
119 #define MUST_SUCCEED_POOL_MASK 2
120 #define CACHE_ALIGNED_POOL_MASK 4
121 #define QUOTA_POOL_MASK 8
122 #define SESSION_POOL_MASK 32
123 #define VERIFIER_POOL_MASK 64
125 #define MAX_PAGING_FILES (16)
127 // FIXME: use ALIGN_UP_BY
128 #define MM_ROUND_UP(x,s) \
129 ((PVOID)(((ULONG_PTR)(x)+(s)-1) & ~((ULONG_PTR)(s)-1)))
131 #define MM_ROUND_DOWN(x,s) \
132 ((PVOID)(((ULONG_PTR)(x)) & ~((ULONG_PTR)(s)-1)))
134 #define PAGE_FLAGS_VALID_FOR_SECTION \
139 PAGE_EXECUTE_READ | \
140 PAGE_EXECUTE_READWRITE | \
141 PAGE_EXECUTE_WRITECOPY | \
145 #define PAGE_IS_READABLE \
149 PAGE_EXECUTE_READ | \
150 PAGE_EXECUTE_READWRITE | \
151 PAGE_EXECUTE_WRITECOPY)
153 #define PAGE_IS_WRITABLE \
156 PAGE_EXECUTE_READWRITE | \
157 PAGE_EXECUTE_WRITECOPY)
159 #define PAGE_IS_EXECUTABLE \
161 PAGE_EXECUTE_READ | \
162 PAGE_EXECUTE_READWRITE | \
163 PAGE_EXECUTE_WRITECOPY)
165 #define PAGE_IS_WRITECOPY \
167 PAGE_EXECUTE_WRITECOPY)
170 // Wait entry for marking pages that are being serviced
173 #define MM_WAIT_ENTRY 0x7ffffc00
174 #elif defined(_M_AMD64)
175 #define MM_WAIT_ENTRY 0x7FFFFFFFFFFFFC00ULL
177 #error Unsupported architecture!
181 #define InterlockedCompareExchangePte(PointerPte, Exchange, Comperand) \
182 InterlockedCompareExchange64((PLONG64)(PointerPte), Exchange, Comperand)
184 #define InterlockedExchangePte(PointerPte, Value) \
185 InterlockedExchange64((PLONG64)(PointerPte), Value)
187 #define InterlockedCompareExchangePte(PointerPte, Exchange, Comperand) \
188 InterlockedCompareExchange((PLONG)(PointerPte), Exchange, Comperand)
190 #define InterlockedExchangePte(PointerPte, Value) \
191 InterlockedExchange((PLONG)(PointerPte), Value)
194 typedef struct _MM_SECTION_SEGMENT
197 PFILE_OBJECT FileObject
;
199 FAST_MUTEX Lock
; /* lock which protects the page directory */
200 LARGE_INTEGER RawLength
; /* length of the segment which is part of the mapped file */
201 LARGE_INTEGER Length
; /* absolute length of the segment */
202 PLONG64 ReferenceCount
;
211 ULONGLONG FileOffset
; /* start offset into the file for image sections */
212 ULONG_PTR VirtualAddress
; /* start offset into the address range for image sections */
213 ULONG Characteristics
;
220 RTL_GENERIC_TABLE PageTable
;
221 } MM_SECTION_SEGMENT
, *PMM_SECTION_SEGMENT
;
223 typedef struct _MM_IMAGE_SECTION_OBJECT
226 PFILE_OBJECT FileObject
;
231 SECTION_IMAGE_INFORMATION ImageInformation
;
234 PMM_SECTION_SEGMENT Segments
;
235 } MM_IMAGE_SECTION_OBJECT
, *PMM_IMAGE_SECTION_OBJECT
;
237 #define MM_PHYSICALMEMORY_SEGMENT (0x1)
238 #define MM_DATAFILE_SEGMENT (0x2)
239 #define MM_SEGMENT_INDELETE (0x4)
240 #define MM_SEGMENT_INCREATE (0x8)
241 #define MM_IMAGE_SECTION_FLUSH_DELETE (0x10)
244 #define MA_GetStartingAddress(_MemoryArea) ((_MemoryArea)->VadNode.StartingVpn << PAGE_SHIFT)
245 #define MA_GetEndingAddress(_MemoryArea) (((_MemoryArea)->VadNode.EndingVpn + 1) << PAGE_SHIFT)
247 typedef struct _MEMORY_AREA
253 BOOLEAN DeleteInProgress
;
260 PMM_SECTION_SEGMENT Segment
;
261 LIST_ENTRY RegionListHead
;
263 } MEMORY_AREA
, *PMEMORY_AREA
;
265 typedef struct _MM_RMAP_ENTRY
267 struct _MM_RMAP_ENTRY
* Next
;
274 MM_RMAP_ENTRY
, *PMM_RMAP_ENTRY
;
277 extern ULONG MI_PFN_CURRENT_USAGE
;
278 extern CHAR MI_PFN_CURRENT_PROCESS_NAME
[16];
279 #define MI_SET_USAGE(x) MI_PFN_CURRENT_USAGE = x
280 #define MI_SET_PROCESS2(x) memcpy(MI_PFN_CURRENT_PROCESS_NAME, x, min(sizeof(x), sizeof(MI_PFN_CURRENT_PROCESS_NAME)))
283 MI_SET_PROCESS(PEPROCESS Process
)
286 MI_SET_PROCESS2("Kernel");
287 else if (Process
== (PEPROCESS
)1)
288 MI_SET_PROCESS2("Hydra");
290 MI_SET_PROCESS2(Process
->ImageFileName
);
295 MI_SET_PROCESS_USTR(PUNICODE_STRING ustr
)
300 if (!ustr
->Buffer
|| ustr
->Length
== 0)
302 MI_PFN_CURRENT_PROCESS_NAME
[0] = 0;
306 pos
= strEnd
= &ustr
->Buffer
[ustr
->Length
/ sizeof(WCHAR
)];
307 while ((*pos
!= L
'\\') && (pos
> ustr
->Buffer
))
313 for (i
= 0; i
< sizeof(MI_PFN_CURRENT_PROCESS_NAME
) && pos
<= strEnd
; i
++, pos
++)
314 MI_PFN_CURRENT_PROCESS_NAME
[i
] = (CHAR
)*pos
;
317 #define MI_SET_USAGE(x)
318 #define MI_SET_PROCESS(x)
319 #define MI_SET_PROCESS2(x)
322 typedef enum _MI_PFN_USAGES
324 MI_USAGE_NOT_SET
= 0,
326 MI_USAGE_NONPAGED_POOL
,
327 MI_USAGE_NONPAGED_POOL_EXPANSION
,
328 MI_USAGE_KERNEL_STACK
,
329 MI_USAGE_KERNEL_STACK_EXPANSION
,
335 MI_USAGE_PAGE_DIRECTORY
,
336 MI_USAGE_LEGACY_PAGE_DIRECTORY
,
337 MI_USAGE_DRIVER_PAGE
,
338 MI_USAGE_CONTINOUS_ALLOCATION
,
340 MI_USAGE_DEMAND_ZERO
,
343 MI_USAGE_PFN_DATABASE
,
344 MI_USAGE_BOOT_DRIVER
,
345 MI_USAGE_INIT_MEMORY
,
353 // These two mappings are actually used by Windows itself, based on the ASSERTS
355 #define StartOfAllocation ReadInProgress
356 #define EndOfAllocation WriteInProgress
358 typedef struct _MMPFNENTRY
361 USHORT ReadInProgress
:1; // StartOfAllocation
362 USHORT WriteInProgress
:1; // EndOfAllocation
363 USHORT PrototypePte
:1;
365 USHORT PageLocation
:3;
366 USHORT RemovalRequested
:1;
367 USHORT CacheAttribute
:2;
369 USHORT ParityError
:1;
373 typedef struct _MMPFN
381 SINGLE_LIST_ENTRY NextStackPfn
;
390 ULONG_PTR ShareCount
;
396 USHORT ReferenceCount
;
401 USHORT ReferenceCount
;
408 LONG AweReferenceCount
;
411 PMM_RMAP_ENTRY RmapListHead
;
415 ULONG_PTR EntireFrame
;
418 ULONG_PTR PteFrame
:25;
419 ULONG_PTR InPageError
:1;
420 ULONG_PTR VerifierAllocation
:1;
421 ULONG_PTR AweAllocation
:1;
422 ULONG_PTR Priority
:3;
423 ULONG_PTR MustBeCached
:1;
427 MI_PFN_USAGES PfnUsage
;
428 CHAR ProcessName
[16];
429 #define MI_SET_PFN_PROCESS_NAME(pfn, x) memcpy(pfn->ProcessName, x, min(sizeof(x), sizeof(pfn->ProcessName)))
433 // HACK until WS lists are supported
435 struct _MMPFN
* NextLRU
;
436 struct _MMPFN
* PreviousLRU
;
439 extern PMMPFN MmPfnDatabase
;
441 typedef struct _MMPFNLIST
447 } MMPFNLIST
, *PMMPFNLIST
;
449 extern MMPFNLIST MmZeroedPageListHead
;
450 extern MMPFNLIST MmFreePageListHead
;
451 extern MMPFNLIST MmStandbyPageListHead
;
452 extern MMPFNLIST MmModifiedPageListHead
;
453 extern MMPFNLIST MmModifiedNoWritePageListHead
;
455 typedef struct _MM_MEMORY_CONSUMER
459 NTSTATUS (*Trim
)(ULONG Target
, ULONG Priority
, PULONG NrFreed
);
460 } MM_MEMORY_CONSUMER
, *PMM_MEMORY_CONSUMER
;
462 typedef struct _MM_REGION
467 LIST_ENTRY RegionListEntry
;
468 } MM_REGION
, *PMM_REGION
;
471 /* Entry describing free pool memory */
472 typedef struct _MMFREE_POOL_ENTRY
477 struct _MMFREE_POOL_ENTRY
*Owner
;
478 } MMFREE_POOL_ENTRY
, *PMMFREE_POOL_ENTRY
;
480 /* Signature of a freed block */
481 #define MM_FREE_POOL_SIGNATURE 'ARM3'
483 /* Paged pool information */
484 typedef struct _MM_PAGED_POOL_INFO
486 PRTL_BITMAP PagedPoolAllocationMap
;
487 PRTL_BITMAP EndOfPagedPoolBitmap
;
488 PMMPTE FirstPteForPagedPool
;
489 PMMPTE LastPteForPagedPool
;
490 PMMPDE NextPdeForPagedPoolExpansion
;
492 SIZE_T PagedPoolCommit
;
493 SIZE_T AllocatedPagedPool
;
494 } MM_PAGED_POOL_INFO
, *PMM_PAGED_POOL_INFO
;
496 extern MM_MEMORY_CONSUMER MiMemoryConsumers
[MC_MAXIMUM
];
498 /* Page file information */
499 typedef struct _MMPAGING_FILE
502 PFN_NUMBER MaximumSize
;
503 PFN_NUMBER MinimumSize
;
504 PFN_NUMBER FreeSpace
;
505 PFN_NUMBER CurrentUsage
;
506 PFILE_OBJECT FileObject
;
507 UNICODE_STRING PageFileName
;
511 MMPAGING_FILE
, *PMMPAGING_FILE
;
513 extern PMMPAGING_FILE MmPagingFile
[MAX_PAGING_FILES
];
516 (*PMM_ALTER_REGION_FUNC
)(
517 PMMSUPPORT AddressSpace
,
527 (*PMM_FREE_PAGE_FUNC
)(
529 PMEMORY_AREA MemoryArea
,
537 // Mm copy support for Kd
549 // Determines if a given address is a session address
569 /* marea.c *******************************************************************/
574 PMMSUPPORT AddressSpace
,
579 PMEMORY_AREA
*Result
,
580 ULONG AllocationFlags
,
581 ULONG AllocationGranularity
586 MmLocateMemoryAreaByAddress(
587 PMMSUPPORT AddressSpace
,
594 PMMSUPPORT AddressSpace
,
595 PMEMORY_AREA MemoryArea
,
596 PMM_FREE_PAGE_FUNC FreePage
,
597 PVOID FreePageContext
602 MiRosCleanupMemoryArea(
608 MmLocateMemoryAreaByRegion(
609 PMMSUPPORT AddressSpace
,
617 PMMSUPPORT AddressSpace
,
619 ULONG_PTR Granularity
,
625 MiRosCheckMemoryAreas(
626 PMMSUPPORT AddressSpace
);
630 MiCheckAllProcessMemoryAreas(VOID
);
632 /* npool.c *******************************************************************/
637 MiInitializeNonPagedPool(VOID
);
642 IN POOL_TYPE PoolType
,
643 IN SIZE_T SizeInBytes
649 IN PVOID VirtualAddress
655 IN PVOID StartingAddress
658 /* pool.c *******************************************************************/
660 _Requires_lock_held_(PspQuotaLock
)
664 _In_ POOL_TYPE PoolType
,
665 _In_ SIZE_T CurrentMaxQuota
,
666 _Out_ PSIZE_T NewMaxQuota
669 _Requires_lock_held_(PspQuotaLock
)
673 _In_ POOL_TYPE PoolType
,
674 _In_ SIZE_T QuotaToReturn
677 /* mdl.c *********************************************************************/
686 /* mminit.c ******************************************************************/
697 MmInitSystem(IN ULONG Phase
,
698 IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
701 /* pagefile.c ****************************************************************/
705 MmAllocSwapPage(VOID
);
709 MmFreeSwapPage(SWAPENTRY Entry
);
714 MmInitPagingFile(VOID
);
718 MmIsFileObjectAPagingFile(PFILE_OBJECT FileObject
);
736 MmShowOutOfSpaceMessagePagingFile(VOID
);
741 _In_ PFN_NUMBER Page
,
742 _In_ ULONG PageFileIndex
,
743 _In_ ULONG_PTR PageFileOffset
);
745 /* process.c ****************************************************************/
749 MmInitializeProcessAddressSpace(
750 IN PEPROCESS Process
,
751 IN PEPROCESS Clone OPTIONAL
,
752 IN PVOID Section OPTIONAL
,
754 IN POBJECT_NAME_INFORMATION
*AuditName OPTIONAL
760 IN PEPROCESS Process
,
761 IN PINITIAL_PEB InitialPeb
,
768 IN PEPROCESS Process
,
769 IN PCLIENT_ID ClientId
,
770 IN PINITIAL_TEB InitialTeb
,
777 struct _EPROCESS
*Process
,
783 MmCleanProcessAddressSpace(IN PEPROCESS Process
);
787 MmDeleteProcessAddressSpace(IN PEPROCESS Process
);
791 MmGetSessionLocaleId(VOID
);
795 MmSetMemoryPriorityProcess(
796 IN PEPROCESS Process
,
797 IN UCHAR MemoryPriority
800 /* i386/pfault.c *************************************************************/
812 /* special.c *****************************************************************/
816 MiInitializeSpecialPool(VOID
);
821 IN SIZE_T NumberOfBytes
,
826 MmIsSpecialPoolAddress(
831 MmIsSpecialPoolAddressFree(
836 MmAllocateSpecialPool(
837 IN SIZE_T NumberOfBytes
,
839 IN POOL_TYPE PoolType
,
840 IN ULONG SpecialType
);
847 /* mm.c **********************************************************************/
854 IN KPROCESSOR_MODE Mode
,
855 IN PVOID TrapInformation
858 /* process.c *****************************************************************/
862 MmCreateKernelStack(BOOLEAN GuiStack
, UCHAR Node
);
866 MmDeleteKernelStack(PVOID Stack
,
869 /* balance.c / pagefile.c******************************************************/
871 FORCEINLINE VOID
UpdateTotalCommittedPages(LONG Delta
)
874 * Add up all the used "Committed" memory + pagefile.
875 * Not sure this is right. 8^\
876 * MmTotalCommittedPages should be adjusted consistently with
877 * other counters at different places.
879 MmTotalCommittedPages = MiMemoryConsumers[MC_SYSTEM].PagesUsed +
880 MiMemoryConsumers[MC_USER].PagesUsed +
884 /* Update Commitment */
885 SIZE_T TotalCommittedPages
= InterlockedExchangeAddSizeT(&MmTotalCommittedPages
, Delta
) + Delta
;
887 /* Update Peak = max(Peak, Total) in a lockless way */
888 SIZE_T PeakCommitment
= MmPeakCommitment
;
889 while (TotalCommittedPages
> PeakCommitment
&&
890 InterlockedCompareExchangeSizeT(&MmPeakCommitment
, TotalCommittedPages
, PeakCommitment
) != PeakCommitment
)
892 PeakCommitment
= MmPeakCommitment
;
896 /* balance.c *****************************************************************/
901 MmInitializeMemoryConsumer(
903 NTSTATUS (*Trim
)(ULONG Target
, ULONG Priority
, PULONG NrFreed
)
909 MmInitializeBalancer(
910 ULONG NrAvailablePages
,
916 MmReleasePageMemoryConsumer(
923 MmRequestPageMemoryConsumer(
926 PPFN_NUMBER AllocatedPage
932 MiInitBalancerThread(VOID
);
936 MmRebalanceMemoryConsumers(VOID
);
938 /* rmap.c **************************************************************/
939 #define RMAP_SEGMENT_MASK ~((ULONG_PTR)0xff)
940 #define RMAP_IS_SEGMENT(x) (((ULONG_PTR)(x) & RMAP_SEGMENT_MASK) == RMAP_SEGMENT_MASK)
944 MmSetRmapListHeadPage(
946 struct _MM_RMAP_ENTRY
* ListHead
949 struct _MM_RMAP_ENTRY
*
951 MmGetRmapListHeadPage(PFN_NUMBER Page
);
957 struct _EPROCESS
*Process
,
966 VOID (*DeleteMapping
)(PVOID Context
, struct _EPROCESS
*Process
, PVOID Address
)
973 struct _EPROCESS
*Process
,
980 MmInitializeRmapList(VOID
);
984 MmPageOutPhysicalAddress(PFN_NUMBER Page
);
988 MmGetSectionAssociation(PFN_NUMBER Page
,
989 PLARGE_INTEGER Offset
);
991 /* freelist.c **********************************************************/
992 _IRQL_raises_(DISPATCH_LEVEL
)
993 _IRQL_requires_max_(DISPATCH_LEVEL
)
994 _Requires_lock_not_held_(MmPfnLock
)
995 _Acquires_lock_(MmPfnLock
)
999 MiAcquirePfnLock(VOID
)
1001 return KeAcquireQueuedSpinLock(LockQueuePfnLock
);
1004 _Requires_lock_held_(MmPfnLock
)
1005 _Releases_lock_(MmPfnLock
)
1006 _IRQL_requires_(DISPATCH_LEVEL
)
1010 _In_ _IRQL_restores_ KIRQL OldIrql
)
1012 KeReleaseQueuedSpinLock(LockQueuePfnLock
, OldIrql
);
1015 _IRQL_requires_min_(DISPATCH_LEVEL
)
1016 _Requires_lock_not_held_(MmPfnLock
)
1017 _Acquires_lock_(MmPfnLock
)
1020 MiAcquirePfnLockAtDpcLevel(VOID
)
1022 PKSPIN_LOCK_QUEUE LockQueue
;
1024 ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL
);
1025 LockQueue
= &KeGetCurrentPrcb()->LockQueue
[LockQueuePfnLock
];
1026 KeAcquireQueuedSpinLockAtDpcLevel(LockQueue
);
1029 _Requires_lock_held_(MmPfnLock
)
1030 _Releases_lock_(MmPfnLock
)
1031 _IRQL_requires_min_(DISPATCH_LEVEL
)
1034 MiReleasePfnLockFromDpcLevel(VOID
)
1036 PKSPIN_LOCK_QUEUE LockQueue
;
1038 LockQueue
= &KeGetCurrentPrcb()->LockQueue
[LockQueuePfnLock
];
1039 KeReleaseQueuedSpinLockFromDpcLevel(LockQueue
);
1040 ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL
);
1043 #define MI_ASSERT_PFN_LOCK_HELD() NT_ASSERT((KeGetCurrentIrql() >= DISPATCH_LEVEL) && (MmPfnLock != 0))
1047 MiGetPfnEntry(IN PFN_NUMBER Pfn
)
1050 extern RTL_BITMAP MiPfnBitMap
;
1052 /* Make sure the PFN number is valid */
1053 if (Pfn
> MmHighestPhysicalPage
) return NULL
;
1055 /* Make sure this page actually has a PFN entry */
1056 if ((MiPfnBitMap
.Buffer
) && !(RtlTestBit(&MiPfnBitMap
, (ULONG
)Pfn
))) return NULL
;
1059 Page
= &MmPfnDatabase
[Pfn
];
1067 MiGetPfnEntryIndex(IN PMMPFN Pfn1
)
1070 // This will return the Page Frame Number (PFN) from the MMPFN
1072 return Pfn1
- MmPfnDatabase
;
1077 MmGetLRUNextUserPage(PFN_NUMBER PreviousPage
, BOOLEAN MoveToLast
);
1081 MmGetLRUFirstUserPage(VOID
);
1085 MmDumpArmPfnDatabase(
1086 IN BOOLEAN StatusOnly
1095 /* hypermap.c *****************************************************************/
1098 MiMapPageInHyperSpace(IN PEPROCESS Process
,
1104 MiUnmapPageInHyperSpace(IN PEPROCESS Process
,
1110 MiMapPagesInZeroSpace(IN PMMPFN Pfn1
,
1111 IN PFN_NUMBER NumberOfPages
);
1115 MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress
,
1116 IN PFN_NUMBER NumberOfPages
);
1118 /* i386/page.c *********************************************************/
1122 MmCreateVirtualMapping(
1123 struct _EPROCESS
* Process
,
1131 MmCreateVirtualMappingUnsafe(
1132 struct _EPROCESS
* Process
,
1140 MmCreatePhysicalMapping(
1141 _Inout_opt_ PEPROCESS Process
,
1143 _In_ ULONG flProtect
,
1144 _In_ PFN_NUMBER Page
);
1149 struct _EPROCESS
* Process
,
1155 struct _EPROCESS
* Process
,
1163 struct _EPROCESS
* Process
,
1170 struct _EPROCESS
* Process
,
1177 MmInitGlobalKernelPageDirectory(VOID
);
1181 MmDeletePageFileMapping(
1182 struct _EPROCESS
*Process
,
1184 SWAPENTRY
* SwapEntry
1189 MmCreatePageFileMapping(
1190 struct _EPROCESS
*Process
,
1197 MmGetPageFileMapping(
1200 SWAPENTRY
*SwapEntry
);
1205 struct _EPROCESS
*Process
,
1217 MmDereferencePage(PFN_NUMBER Page
);
1221 MmReferencePage(PFN_NUMBER Page
);
1225 MmGetReferenceCountPage(PFN_NUMBER Page
);
1229 MmIsPageInUse(PFN_NUMBER Page
);
1233 MmSetSavedSwapEntryPage(
1235 SWAPENTRY SavedSwapEntry
);
1239 MmGetSavedSwapEntryPage(PFN_NUMBER Page
);
1244 struct _EPROCESS
*Process
,
1250 MmSetDirtyBit(PEPROCESS Process
, PVOID Address
, BOOLEAN Bit
);
1251 #define MmSetCleanPage(__P, __A) MmSetDirtyBit(__P, __A, FALSE)
1252 #define MmSetDirtyPage(__P, __A) MmSetDirtyBit(__P, __A, TRUE)
1257 struct _EPROCESS
*Process
,
1264 struct _EPROCESS
*Process
,
1270 MmCreateProcessAddressSpace(
1273 IN PULONG_PTR DirectoryTableBase
1279 MmInitializeHandBuiltProcess(
1280 IN PEPROCESS Process
,
1281 IN PULONG_PTR DirectoryTableBase
1287 MmInitializeHandBuiltProcess2(
1288 IN PEPROCESS Process
1293 MmSetExecuteOptions(IN ULONG ExecuteOptions
);
1297 MmGetExecuteOptions(IN PULONG ExecuteOptions
);
1301 MmDeleteVirtualMapping(
1302 _Inout_opt_ PEPROCESS Process
,
1304 _Out_opt_ BOOLEAN
* WasDirty
,
1305 _Out_opt_ PPFN_NUMBER Page
1310 MmDeletePhysicalMapping(
1311 _Inout_opt_ PEPROCESS Process
,
1313 _Out_opt_ BOOLEAN
* WasDirty
,
1314 _Out_opt_ PPFN_NUMBER Page
1317 /* arch/procsup.c ************************************************************/
1320 MiArchCreateProcessAddressSpace(
1321 _In_ PEPROCESS Process
,
1322 _In_ PULONG_PTR DirectoryTableBase
);
1324 /* wset.c ********************************************************************/
1333 /* region.c ************************************************************/
1338 PMMSUPPORT AddressSpace
,
1340 PLIST_ENTRY RegionListHead
,
1345 PMM_ALTER_REGION_FUNC AlterFunc
1351 PLIST_ENTRY RegionListHead
,
1361 PLIST_ENTRY RegionListHead
,
1363 PVOID
* RegionBaseAddress
1366 /* section.c *****************************************************************/
1368 #define PFN_FROM_SSE(E) ((PFN_NUMBER)((E) >> PAGE_SHIFT))
1369 #define IS_SWAP_FROM_SSE(E) ((E) & 0x00000001)
1370 #define MM_IS_WAIT_PTE(E) \
1371 (IS_SWAP_FROM_SSE(E) && SWAPENTRY_FROM_SSE(E) == MM_WAIT_ENTRY)
1372 #define MAKE_PFN_SSE(P) ((ULONG_PTR)((P) << PAGE_SHIFT))
1373 #define SWAPENTRY_FROM_SSE(E) ((E) >> 1)
1374 #define MAKE_SWAP_SSE(S) (((ULONG_PTR)(S) << 1) | 0x1)
1375 #define DIRTY_SSE(E) ((E) | 2)
1376 #define CLEAN_SSE(E) ((E) & ~2)
1377 #define IS_DIRTY_SSE(E) ((E) & 2)
1378 #define WRITE_SSE(E) ((E) | 4)
1379 #define IS_WRITE_SSE(E) ((E) & 4)
1381 #define PAGE_FROM_SSE(E) ((E) & 0xFFFFFFF000ULL)
1383 #define PAGE_FROM_SSE(E) ((E) & 0xFFFFF000)
1385 #define SHARE_COUNT_FROM_SSE(E) (((E) & 0x00000FFC) >> 3)
1386 #define MAX_SHARE_COUNT 0x1FF
1387 #define MAKE_SSE(P, C) ((ULONG_PTR)((P) | ((C) << 3)))
1388 #define BUMPREF_SSE(E) (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) + 1) << 3) | ((E) & 0x7))
1389 #define DECREF_SSE(E) (PAGE_FROM_SSE(E) | ((SHARE_COUNT_FROM_SSE(E) - 1) << 3) | ((E) & 0x7))
1393 _MmLockSectionSegment(PMM_SECTION_SEGMENT Segment
,
1397 #define MmLockSectionSegment(x) _MmLockSectionSegment(x,__FILE__,__LINE__)
1401 _MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment
,
1405 #define MmUnlockSectionSegment(x) _MmUnlockSectionSegment(x,__FILE__,__LINE__)
1409 MmGetImageInformation(
1410 OUT PSECTION_IMAGE_INFORMATION ImageInformation
1415 MmGetFileObjectForSection(
1420 MmGetFileNameForAddress(
1422 OUT PUNICODE_STRING ModuleName
1427 MmGetFileNameForSection(
1429 OUT POBJECT_NAME_INFORMATION
*ModuleName
1435 PMEMORY_AREA MemoryArea
,
1437 PMEMORY_BASIC_INFORMATION Info
,
1438 PSIZE_T ResultLength
1443 MmProtectSectionView(
1444 PMMSUPPORT AddressSpace
,
1445 PMEMORY_AREA MemoryArea
,
1455 MmInitSectionImplementation(VOID
);
1459 MmNotPresentFaultSectionView(
1460 PMMSUPPORT AddressSpace
,
1461 MEMORY_AREA
* MemoryArea
,
1468 MmPageOutSectionView(
1469 PMMSUPPORT AddressSpace
,
1470 PMEMORY_AREA MemoryArea
,
1478 MmCreatePhysicalMemorySection(VOID
);
1482 MmAccessFaultSectionView(
1483 PMMSUPPORT AddressSpace
,
1484 MEMORY_AREA
* MemoryArea
,
1491 MmFreeSectionSegments(PFILE_OBJECT FileObject
);
1493 /* Exported from NT 6.2 onward. We keep it internal. */
1496 MmMapViewInSystemSpaceEx(
1498 _Outptr_result_bytebuffer_ (*ViewSize
) PVOID
*MappedBase
,
1499 _Inout_ PSIZE_T ViewSize
,
1500 _Inout_ PLARGE_INTEGER SectionOffset
,
1501 _In_ ULONG_PTR Flags
);
1506 _In_ PEPROCESS Process
,
1507 _In_ PVOID BaseAddress
,
1513 _In_ PEPROCESS Process
,
1520 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
,
1521 _In_opt_ PLARGE_INTEGER Offset
,
1523 _Out_opt_ PIO_STATUS_BLOCK Iosb
);
1527 MmMakeDataSectionResident(
1528 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
,
1529 _In_ LONGLONG Offset
,
1531 _In_ PLARGE_INTEGER ValidDataLength
);
1536 _In_ PSECTION_OBJECT_POINTERS SectionObjectPointer
,
1537 _In_opt_ PLARGE_INTEGER Offset
,
1542 MmCheckDirtySegment(
1543 PMM_SECTION_SEGMENT Segment
,
1544 PLARGE_INTEGER Offset
,
1550 MmUnsharePageEntrySectionSegment(PMEMORY_AREA MemoryArea
,
1551 PMM_SECTION_SEGMENT Segment
,
1552 PLARGE_INTEGER Offset
,
1555 ULONG_PTR
*InEntry
);
1557 _When_(OldIrql
== MM_NOIRQL
, _IRQL_requires_max_(DISPATCH_LEVEL
))
1558 _When_(OldIrql
== MM_NOIRQL
, _Requires_lock_not_held_(MmPfnLock
))
1559 _When_(OldIrql
!= MM_NOIRQL
, _Requires_lock_held_(MmPfnLock
))
1560 _When_(OldIrql
!= MM_NOIRQL
, _Releases_lock_(MmPfnLock
))
1561 _When_(OldIrql
!= MM_NOIRQL
, _IRQL_requires_(DISPATCH_LEVEL
))
1564 MmDereferenceSegmentWithLock(
1565 _In_ PMM_SECTION_SEGMENT Segment
,
1566 _In_
_When_(OldIrql
!= MM_NOIRQL
, _IRQL_restores_
) KIRQL OldIrql
);
1568 _IRQL_requires_max_(DISPATCH_LEVEL
)
1569 _Requires_lock_not_held_(MmPfnLock
)
1572 MmDereferenceSegment(PMM_SECTION_SEGMENT Segment
)
1574 MmDereferenceSegmentWithLock(Segment
, MM_NOIRQL
);
1581 _Inout_ PLARGE_INTEGER NewSize
);
1583 /* sptab.c *******************************************************************/
1587 _MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment
,
1588 PLARGE_INTEGER Offset
,
1595 _MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment
,
1596 PLARGE_INTEGER Offset
,
1600 #define MmSetPageEntrySectionSegment(S,O,E) _MmSetPageEntrySectionSegment(S,O,E,__FILE__,__LINE__)
1602 #define MmGetPageEntrySectionSegment(S,O) _MmGetPageEntrySectionSegment(S,O,__FILE__,__LINE__)
1604 /* sysldr.c ******************************************************************/
1609 MiReloadBootLoadedDrivers(
1610 IN PLOADER_PARAMETER_BLOCK LoaderBlock
1616 MiInitializeLoadedModuleList(
1617 IN PLOADER_PARAMETER_BLOCK LoaderBlock
1622 MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask
);
1626 MmMakeKernelResourceSectionWritable(VOID
);
1631 IN PUNICODE_STRING FileName
,
1632 IN PUNICODE_STRING NamePrefix OPTIONAL
,
1633 IN PUNICODE_STRING LoadedName OPTIONAL
,
1635 OUT PVOID
*ModuleObject
,
1636 OUT PVOID
*ImageBaseAddress
1641 MmUnloadSystemImage(
1642 IN PVOID ImageHandle
1648 IN HANDLE ImageHandle
,
1649 IN BOOLEAN PurgeSection
1654 MmCallDllInitialize(
1655 _In_ PLDR_DATA_TABLE_ENTRY LdrEntry
,
1656 _In_ PLIST_ENTRY ModuleListHead
);
1660 MmFreeDriverInitialization(
1661 IN PLDR_DATA_TABLE_ENTRY LdrEntry
);
1663 /* ReactOS-only, used by psmgr.c PspLookupSystemDllEntryPoint() as well */
1666 RtlpFindExportedRoutineByName(
1667 _In_ PVOID ImageBase
,
1668 _In_ PCSTR ExportName
,
1669 _Out_ PVOID
* Function
,
1670 _Out_opt_ PBOOLEAN IsForwarder
,
1671 _In_ NTSTATUS NotFoundStatus
);
1673 /* Exported from NT 10.0 onward. We keep it internal. */
1676 RtlFindExportedRoutineByName(
1677 _In_ PVOID ImageBase
,
1678 _In_ PCSTR ExportName
);
1680 /* procsup.c *****************************************************************/
1685 IN PVOID StackPointer
1691 MmLockAddressSpace(PMMSUPPORT AddressSpace
)
1693 ASSERT(!PsGetCurrentThread()->OwnsProcessWorkingSetExclusive
);
1694 ASSERT(!PsGetCurrentThread()->OwnsProcessWorkingSetShared
);
1695 ASSERT(!PsGetCurrentThread()->OwnsSystemWorkingSetExclusive
);
1696 ASSERT(!PsGetCurrentThread()->OwnsSystemWorkingSetShared
);
1697 ASSERT(!PsGetCurrentThread()->OwnsSessionWorkingSetExclusive
);
1698 ASSERT(!PsGetCurrentThread()->OwnsSessionWorkingSetShared
);
1699 KeAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace
, EPROCESS
, Vm
)->AddressCreationLock
);
1704 MmUnlockAddressSpace(PMMSUPPORT AddressSpace
)
1706 KeReleaseGuardedMutex(&CONTAINING_RECORD(AddressSpace
, EPROCESS
, Vm
)->AddressCreationLock
);
1711 MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace
)
1713 if (AddressSpace
== MmKernelAddressSpace
) return NULL
;
1714 return CONTAINING_RECORD(AddressSpace
, EPROCESS
, Vm
);
1719 MmGetCurrentAddressSpace(VOID
)
1721 return &((PEPROCESS
)KeGetCurrentThread()->ApcState
.Process
)->Vm
;
1726 MmGetKernelAddressSpace(VOID
)
1728 return MmKernelAddressSpace
;
1732 /* expool.c ******************************************************************/
1736 ExpCheckPoolAllocation(
1747 /* mmsup.c *****************************************************************/
1751 MmAdjustWorkingSetSize(
1752 IN SIZE_T WorkingSetMinimumInBytes
,
1753 IN SIZE_T WorkingSetMaximumInBytes
,
1754 IN ULONG SystemCache
,
1755 IN BOOLEAN IncreaseOkay
);
1758 /* session.c *****************************************************************/
1760 _IRQL_requires_max_(APC_LEVEL
)
1764 _Inout_ PVOID SessionEntry
,
1765 _Out_ PKAPC_STATE ApcState
);
1767 _IRQL_requires_max_(APC_LEVEL
)
1771 _Inout_ PVOID SessionEntry
,
1772 _Out_ PKAPC_STATE ApcState
);
1777 _Inout_ PVOID SessionEntry
);
1782 _In_ ULONG SessionId
);
1784 _IRQL_requires_max_(APC_LEVEL
)
1787 MmSetSessionLocaleId(
1788 _In_ LCID LocaleId
);
1790 /* shutdown.c *****************************************************************/
1793 MmShutdownSystem(IN ULONG Phase
);
1795 /* virtual.c *****************************************************************/
1799 MmCopyVirtualMemory(IN PEPROCESS SourceProcess
,
1800 IN PVOID SourceAddress
,
1801 IN PEPROCESS TargetProcess
,
1802 OUT PVOID TargetAddress
,
1803 IN SIZE_T BufferSize
,
1804 IN KPROCESSOR_MODE PreviousMode
,
1805 OUT PSIZE_T ReturnSize
);
1807 /* wslist.cpp ****************************************************************/
1808 _Requires_exclusive_lock_held_(WorkingSet
->WorkingSetMutex
)
1811 MiInitializeWorkingSetList(_Inout_ PMMSUPPORT WorkingSet
);
1818 using MiPfnLockGuard
= const KiQueuedSpinLockGuard
<LockQueuePfnLock
>;
1819 } // namespace ntoskrnl