3 #include <internal/arch/mm.h>
5 /* TYPES *********************************************************************/
7 #define PFN_FROM_SSE(E) ((PFN_NUMBER)((E) >> PAGE_SHIFT))
8 #define IS_SWAP_FROM_SSE(E) ((E) & 0x00000001)
9 #define MM_IS_WAIT_PTE(E) \
10 (IS_SWAP_FROM_SSE(E) && SWAPENTRY_FROM_SSE(E) == MM_WAIT_ENTRY)
11 #define MAKE_PFN_SSE(P) ((ULONG_PTR)((P) << PAGE_SHIFT))
12 #define SWAPENTRY_FROM_SSE(E) ((E) >> 1)
13 #define MAKE_SWAP_SSE(S) (((ULONG_PTR)(S) << 1) | 0x1)
14 #define DIRTY_SSE(E) ((E) | 2)
15 #define CLEAN_SSE(E) ((E) & ~2)
16 #define IS_DIRTY_SSE(E) ((E) & 2)
17 #define PAGE_FROM_SSE(E) ((E) & 0xFFFFF000)
18 #define SHARE_COUNT_FROM_SSE(E) (((E) & 0x00000FFC) >> 2)
19 #define MAX_SHARE_COUNT 0x3FF
20 #define MAKE_SSE(P, C) ((ULONG_PTR)((P) | ((C) << 2)))
22 #define MM_SEGMENT_FINALIZE (0x40000000)
24 #define RMAP_SEGMENT_MASK ~((ULONG_PTR)0xff)
25 #define RMAP_IS_SEGMENT(x) (((ULONG_PTR)(x) & RMAP_SEGMENT_MASK) == RMAP_SEGMENT_MASK)
27 #define MIN(x,y) (((x)<(y))?(x):(y))
28 #define MAX(x,y) (((x)>(y))?(x):(y))
30 /* Determine what's needed to make paged pool fit in this category.
31 * it seems that something more is required to satisfy arm3. */
32 #define BALANCER_CAN_EVICT(Consumer) \
33 (((Consumer) == MC_USER) || \
34 ((Consumer) == MC_CACHE))
36 #define SEC_CACHE (0x20000000)
38 #define MiWaitForPageEvent(Process,Address) do { \
39 DPRINT("MiWaitForPageEvent %p:%p #\n", Process, Address); \
40 KeWaitForSingleObject(&MmWaitPageEvent, 0, KernelMode, FALSE, NULL); \
43 #define MiSetPageEvent(Process,Address) do { \
44 DPRINT("MiSetPageEvent %p:%p #\n",Process, (PVOID)(Address)); \
45 KeSetEvent(&MmWaitPageEvent, IO_NO_INCREMENT, FALSE); \
48 /* We store 8 bits of location with a page association */
49 #define ENTRIES_PER_ELEMENT 256
51 extern KEVENT MmWaitPageEvent
;
53 typedef struct _CACHE_SECTION_PAGE_TABLE
55 LARGE_INTEGER FileOffset
;
56 PMM_SECTION_SEGMENT Segment
;
58 ULONG_PTR PageEntries
[ENTRIES_PER_ELEMENT
];
59 } CACHE_SECTION_PAGE_TABLE
, *PCACHE_SECTION_PAGE_TABLE
;
61 struct _MM_REQUIRED_RESOURCES
;
63 typedef NTSTATUS (NTAPI
* AcquireResource
)(
64 PMMSUPPORT AddressSpace
,
65 struct _MEMORY_AREA
*MemoryArea
,
66 struct _MM_REQUIRED_RESOURCES
*Required
);
68 typedef NTSTATUS (NTAPI
* NotPresentFaultHandler
)(
69 PMMSUPPORT AddressSpace
,
70 struct _MEMORY_AREA
*MemoryArea
,
73 struct _MM_REQUIRED_RESOURCES
*Required
);
75 typedef NTSTATUS (NTAPI
* FaultHandler
)(
76 PMMSUPPORT AddressSpace
,
77 struct _MEMORY_AREA
*MemoryArea
,
79 struct _MM_REQUIRED_RESOURCES
*Required
);
81 typedef struct _MM_REQUIRED_RESOURCES
88 LARGE_INTEGER FileOffset
;
89 AcquireResource DoAcquisition
;
95 } MM_REQUIRED_RESOURCES
, *PMM_REQUIRED_RESOURCES
;
99 MmCreateCacheSection(PROS_SECTION_OBJECT
*SectionObject
,
100 ACCESS_MASK DesiredAccess
,
101 POBJECT_ATTRIBUTES ObjectAttributes
,
102 PLARGE_INTEGER UMaximumSize
,
103 ULONG SectionPageProtection
,
104 ULONG AllocationAttributes
,
105 PFILE_OBJECT FileObject
);
109 MmWithdrawSectionPage(PMM_SECTION_SEGMENT Segment
,
110 PLARGE_INTEGER FileOffset
,
115 MmFinalizeSectionPageOut(PMM_SECTION_SEGMENT Segment
,
116 PLARGE_INTEGER FileOffset
,
120 /* sptab.c *******************************************************************/
124 MiInitializeSectionPageTable(PMM_SECTION_SEGMENT Segment
);
128 _MmSetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment
,
129 PLARGE_INTEGER Offset
,
136 _MmGetPageEntrySectionSegment(PMM_SECTION_SEGMENT Segment
,
137 PLARGE_INTEGER Offset
,
141 #define MmSetPageEntrySectionSegment(S,O,E) _MmSetPageEntrySectionSegment(S,O,E,__FILE__,__LINE__)
143 #define MmGetPageEntrySectionSegment(S,O) _MmGetPageEntrySectionSegment(S,O,__FILE__,__LINE__)
145 typedef VOID (NTAPI
*FREE_SECTION_PAGE_FUN
)(
146 PMM_SECTION_SEGMENT Segment
,
147 PLARGE_INTEGER Offset
);
151 MmFreePageTablesSectionSegment(PMM_SECTION_SEGMENT Segment
,
152 FREE_SECTION_PAGE_FUN FreePage
);
157 MmGetSectionAssociation(PFN_NUMBER Page
,
158 PLARGE_INTEGER Offset
);
162 MmSetSectionAssociation(PFN_NUMBER Page
,
163 PMM_SECTION_SEGMENT Segment
,
164 PLARGE_INTEGER Offset
);
168 MmDeleteSectionAssociation(PFN_NUMBER Page
);
172 MmpPageOutPhysicalAddress(PFN_NUMBER Page
);
174 /* io.c **********************************************************************/
177 MmspWaitForFileLock(PFILE_OBJECT File
);
181 MiSimpleRead(PFILE_OBJECT FileObject
,
182 PLARGE_INTEGER FileOffset
,
186 PIO_STATUS_BLOCK ReadStatus
);
190 _MiSimpleWrite(PFILE_OBJECT FileObject
,
191 PLARGE_INTEGER FileOffset
,
194 PIO_STATUS_BLOCK ReadStatus
,
198 #define MiSimpleWrite(F,O,B,L,R) _MiSimpleWrite(F,O,B,L,R,__FILE__,__LINE__)
202 _MiWriteBackPage(PFILE_OBJECT FileObject
,
203 PLARGE_INTEGER Offset
,
209 #define MiWriteBackPage(F,O,L,P) _MiWriteBackPage(F,O,L,P,__FILE__,__LINE__)
211 /* section.c *****************************************************************/
215 MmAccessFaultCacheSection(KPROCESSOR_MODE Mode
,
221 MiReadFilePage(PMMSUPPORT AddressSpace
,
222 PMEMORY_AREA MemoryArea
,
223 PMM_REQUIRED_RESOURCES RequiredResources
);
227 MiGetOnePage(PMMSUPPORT AddressSpace
,
228 PMEMORY_AREA MemoryArea
,
229 PMM_REQUIRED_RESOURCES RequiredResources
);
233 MiSwapInPage(PMMSUPPORT AddressSpace
,
234 PMEMORY_AREA MemoryArea
,
235 PMM_REQUIRED_RESOURCES RequiredResources
);
239 MiWriteSwapPage(PMMSUPPORT AddressSpace
,
240 PMEMORY_AREA MemoryArea
,
241 PMM_REQUIRED_RESOURCES Resources
);
245 MiWriteFilePage(PMMSUPPORT AddressSpace
,
246 PMEMORY_AREA MemoryArea
,
247 PMM_REQUIRED_RESOURCES Resources
);
251 MiFreeSegmentPage(PMM_SECTION_SEGMENT Segment
,
252 PLARGE_INTEGER FileOffset
);
255 _When_(return==STATUS_MORE_PROCESSING_REQUIRED
, _At_(Required
->DoAcquisition
, _Post_notnull_
))
258 MiCowCacheSectionPage (
259 _In_ PMMSUPPORT AddressSpace
,
260 _In_ PMEMORY_AREA MemoryArea
,
263 _Inout_ PMM_REQUIRED_RESOURCES Required
);
267 MiZeroFillSection(PVOID Address
,
268 PLARGE_INTEGER FileOffsetPtr
,
272 MmPageOutDeleteMapping(PVOID Context
,
278 _MmLockSectionSegment(PMM_SECTION_SEGMENT Segment
,
282 #define MmLockSectionSegment(x) _MmLockSectionSegment(x,__FILE__,__LINE__)
286 _MmUnlockSectionSegment(PMM_SECTION_SEGMENT Segment
,
290 #define MmUnlockSectionSegment(x) _MmUnlockSectionSegment(x,__FILE__,__LINE__)
293 MmFreeCacheSectionPage(PVOID Context
,
294 MEMORY_AREA
* MemoryArea
,
302 _MiFlushMappedSection(PVOID BaseAddress
,
303 PLARGE_INTEGER BaseOffset
,
304 PLARGE_INTEGER FileSize
,
309 #define MiFlushMappedSection(A,O,S,D) _MiFlushMappedSection(A,O,S,D,__FILE__,__LINE__)
313 MmFinalizeSegment(PMM_SECTION_SEGMENT Segment
);
317 MmFreeSectionSegments(PFILE_OBJECT FileObject
);
321 MmMapCacheViewInSystemSpaceAtOffset(IN PMM_SECTION_SEGMENT Segment
,
322 OUT PVOID
* MappedBase
,
323 IN PLARGE_INTEGER ViewOffset
,
324 IN OUT PULONG ViewSize
);
328 _MiMapViewOfSegment(PMMSUPPORT AddressSpace
,
329 PMM_SECTION_SEGMENT Segment
,
333 PLARGE_INTEGER ViewOffset
,
334 ULONG AllocationType
,
338 #define MiMapViewOfSegment(AddressSpace,Segment,BaseAddress,ViewSize,Protect,ViewOffset,AllocationType) \
339 _MiMapViewOfSegment(AddressSpace,Segment,BaseAddress,ViewSize,Protect,ViewOffset,AllocationType,__FILE__,__LINE__)
343 MmUnmapViewOfCacheSegment(PMMSUPPORT AddressSpace
,
348 MmUnmapCacheViewInSystemSpace(PVOID Address
);
351 _When_(return==STATUS_MORE_PROCESSING_REQUIRED
, _At_(Required
->DoAcquisition
, _Post_notnull_
))
354 MmNotPresentFaultCachePage (
355 _In_ PMMSUPPORT AddressSpace
,
356 _In_ MEMORY_AREA
* MemoryArea
,
359 _Inout_ PMM_REQUIRED_RESOURCES Required
);
363 MmPageOutPageFileView(PMMSUPPORT AddressSpace
,
364 PMEMORY_AREA MemoryArea
,
366 PMM_REQUIRED_RESOURCES Required
);
370 _MmTryToLockAddressSpace(IN PMMSUPPORT AddressSpace
,
374 BOOLEAN Result
= KeTryToAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace
, EPROCESS
, Vm
)->AddressCreationLock
);
375 //DbgPrint("(%s:%d) Try Lock Address Space %x -> %s\n", file, line, AddressSpace, Result ? "true" : "false");
379 #define MmTryToLockAddressSpace(x) _MmTryToLockAddressSpace(x,__FILE__,__LINE__)
383 MiWidenSegment(PMMSUPPORT AddressSpace
,
384 PMEMORY_AREA MemoryArea
,
385 PMM_REQUIRED_RESOURCES RequiredResources
);
389 MiSwapInSectionPage(PMMSUPPORT AddressSpace
,
390 PMEMORY_AREA MemoryArea
,
391 PMM_REQUIRED_RESOURCES RequiredResources
);
395 MmExtendCacheSection(PROS_SECTION_OBJECT Section
,
396 PLARGE_INTEGER NewSize
,
401 _MiFlushMappedSection(PVOID BaseAddress
,
402 PLARGE_INTEGER BaseOffset
,
403 PLARGE_INTEGER FileSize
,
408 #define MiFlushMappedSection(A,O,S,D) _MiFlushMappedSection(A,O,S,D,__FILE__,__LINE__)
412 MmGetSegmentRmap(PFN_NUMBER Page
,
417 MmNotPresentFaultCacheSection(KPROCESSOR_MODE Mode
,
423 MiCacheEvictPages(PMM_SECTION_SEGMENT Segment
,
427 MiRosTrimCache(ULONG Target
,