ReactOS 0.4.15-dev-8339-g4028de8
mdlsup.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for mdlsup.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 

Functions

static PVOID NTAPI MiMapLockedPagesInUserSpace (_In_ PMDL Mdl, _In_ PVOID StartVa, _In_ MEMORY_CACHING_TYPE CacheType, _In_opt_ PVOID BaseAddress)
 
static VOID NTAPI MiUnmapLockedPagesInUserSpace (_In_ PVOID BaseAddress, _In_ PMDL Mdl)
 
PMDL NTAPI MmCreateMdl (IN PMDL Mdl, IN PVOID Base, IN SIZE_T Length)
 
SIZE_T NTAPI MmSizeOfMdl (IN PVOID Base, IN SIZE_T Length)
 
VOID NTAPI MmBuildMdlForNonPagedPool (IN PMDL Mdl)
 
PMDL NTAPI MmAllocatePagesForMdl (IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes)
 
PMDL NTAPI MmAllocatePagesForMdlEx (IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes, IN MEMORY_CACHING_TYPE CacheType, IN ULONG Flags)
 
VOID NTAPI MmFreePagesFromMdl (IN PMDL Mdl)
 
PVOID NTAPI MmMapLockedPagesSpecifyCache (IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN MEMORY_CACHING_TYPE CacheType, IN PVOID BaseAddress, IN ULONG BugCheckOnFailure, IN ULONG Priority)
 
PVOID NTAPI MmMapLockedPages (IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode)
 
VOID NTAPI MmUnmapLockedPages (IN PVOID BaseAddress, IN PMDL Mdl)
 
VOID NTAPI MmProbeAndLockPages (IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
 
VOID NTAPI MmUnlockPages (IN PMDL Mdl)
 
NTSTATUS NTAPI MmAdvanceMdl (IN PMDL Mdl, IN ULONG NumberOfBytes)
 
PVOID NTAPI MmMapLockedPagesWithReservedMapping (IN PVOID MappingAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList, IN MEMORY_CACHING_TYPE CacheType)
 
VOID NTAPI MmUnmapReservedMapping (IN PVOID BaseAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList)
 
NTSTATUS NTAPI MmPrefetchPages (IN ULONG NumberOfLists, IN PREAD_LIST *ReadLists)
 
NTSTATUS NTAPI MmProtectMdlSystemAddress (IN PMDL MemoryDescriptorList, IN ULONG NewProtect)
 
VOID NTAPI MmProbeAndLockProcessPages (IN OUT PMDL MemoryDescriptorList, IN PEPROCESS Process, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
 
VOID NTAPI MmProbeAndLockSelectedPages (IN OUT PMDL MemoryDescriptorList, IN LARGE_INTEGER PageList[], IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
 
VOID NTAPI MmMapMemoryDumpMdl (IN PMDL Mdl)
 

Variables

BOOLEAN MmTrackPtes
 
BOOLEAN MmTrackLockedPages
 
SIZE_T MmSystemLockPagesCount
 
ULONG MiCacheOverride [MiNotMapped+1]
 

Macro Definition Documentation

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 15 of file mdlsup.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file mdlsup.c.

Function Documentation

◆ MiMapLockedPagesInUserSpace()

static PVOID NTAPI MiMapLockedPagesInUserSpace ( _In_ PMDL  Mdl,
_In_ PVOID  StartVa,
_In_ MEMORY_CACHING_TYPE  CacheType,
_In_opt_ PVOID  BaseAddress 
)
static

Definition at line 30 of file mdlsup.c.

35{
40 MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
41 MI_PFN_CACHE_ATTRIBUTE EffectiveCacheAttribute;
42 BOOLEAN IsIoMapping;
44 ULONG_PTR StartingVa;
45 ULONG_PTR EndingVa;
47 PMMVAD_LONG Vad;
48 ULONG NumberOfPages;
49 PMMPTE PointerPte;
50 PMMPDE PointerPde;
52 PPFN_NUMBER MdlPages;
53 PMMPFN Pfn1;
54 PMMPFN Pfn2;
55 BOOLEAN AddressSpaceLocked = FALSE;
56
57 PAGED_CODE();
58
59 DPRINT("MiMapLockedPagesInUserSpace(%p, %p, 0x%x, %p)\n",
60 Mdl, StartVa, CacheType, BaseAddress);
61
62 NumberOfPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(StartVa,
64 MdlPages = MmGetMdlPfnArray(Mdl);
65
67
68 IsIoMapping = (Mdl->MdlFlags & MDL_IO_SPACE) != 0;
69 CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType];
70
71 /* Large pages are always cached, make sure we're not asking for those */
72 if (CacheAttribute != MiCached)
73 {
74 DPRINT1("FIXME: Need to check for large pages\n");
75 }
76
78 if (!NT_SUCCESS(Status))
79 {
80 Vad = NULL;
81 goto Error;
82 }
83
84 /* Allocate a VAD for our mapped region */
85 Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
86 if (Vad == NULL)
87 {
90 goto Error;
91 }
92
93 /* Initialize PhysicalMemory VAD */
94 RtlZeroMemory(Vad, sizeof(*Vad));
95 Vad->u2.VadFlags2.LongVad = 1;
98 Vad->u.VadFlags.PrivateMemory = 1;
99
100 /* Did the caller specify an address? */
101 if (BaseAddress == NULL)
102 {
103 /* We get to pick the address */
105 AddressSpaceLocked = TRUE;
106 if (Process->VmDeleted)
107 {
109 goto Error;
110 }
111
114 &Process->VadRoot,
115 &Parent,
116 &StartingVa);
117 if (Result == TableFoundNode)
118 {
120 goto Error;
121 }
122 EndingVa = StartingVa + NumberOfPages * PAGE_SIZE - 1;
123 BaseAddress = (PVOID)StartingVa;
124 }
125 else
126 {
127 /* Caller specified a base address */
128 StartingVa = (ULONG_PTR)BaseAddress;
129 EndingVa = StartingVa + NumberOfPages * PAGE_SIZE - 1;
130
131 /* Make sure it's valid */
132 if (BYTE_OFFSET(StartingVa) != 0 ||
133 EndingVa <= StartingVa ||
135 {
137 goto Error;
138 }
139
141 AddressSpaceLocked = TRUE;
142 if (Process->VmDeleted)
143 {
145 goto Error;
146 }
147
148 /* Check if it's already in use */
150 EndingVa >> PAGE_SHIFT,
151 &Process->VadRoot,
152 &Parent);
153 if (Result == TableFoundNode)
154 {
156 goto Error;
157 }
158 }
159
160 Vad->StartingVpn = StartingVa >> PAGE_SHIFT;
161 Vad->EndingVpn = EndingVa >> PAGE_SHIFT;
162
164
165 ASSERT(Vad->EndingVpn >= Vad->StartingVpn);
166 MiInsertVad((PMMVAD)Vad, &Process->VadRoot);
167
168 /* Check if this is uncached */
169 if (CacheAttribute != MiCached)
170 {
171 /* Flush all caches */
174 }
175
176 PointerPte = MiAddressToPte(BaseAddress);
177 while (NumberOfPages != 0 &&
178 *MdlPages != LIST_HEAD)
179 {
180 PointerPde = MiPteToPde(PointerPte);
182 ASSERT(PointerPte->u.Hard.Valid == 0);
183
184 /* Add a PDE reference for each page */
186
187 /* Set up our basic user PTE */
189 PointerPte,
191 *MdlPages);
192
193 EffectiveCacheAttribute = CacheAttribute;
194
195 /* We need to respect the PFN's caching information in some cases */
196 Pfn2 = MiGetPfnEntry(*MdlPages);
197 if (Pfn2 != NULL)
198 {
199 ASSERT(Pfn2->u3.e2.ReferenceCount != 0);
200
201 switch (Pfn2->u3.e1.CacheAttribute)
202 {
203 case MiNonCached:
204 if (CacheAttribute != MiNonCached)
205 {
206 MiCacheOverride[1]++;
207 EffectiveCacheAttribute = MiNonCached;
208 }
209 break;
210
211 case MiCached:
212 if (CacheAttribute != MiCached)
213 {
214 MiCacheOverride[0]++;
215 EffectiveCacheAttribute = MiCached;
216 }
217 break;
218
219 case MiWriteCombined:
220 if (CacheAttribute != MiWriteCombined)
221 {
222 MiCacheOverride[2]++;
223 EffectiveCacheAttribute = MiWriteCombined;
224 }
225 break;
226
227 default:
228 /* We don't support AWE magic (MiNotMapped) */
229 DPRINT1("FIXME: MiNotMapped is not supported\n");
230 ASSERT(FALSE);
231 break;
232 }
233 }
234
235 /* Configure caching */
236 switch (EffectiveCacheAttribute)
237 {
238 case MiNonCached:
241 break;
242 case MiCached:
243 break;
244 case MiWriteCombined:
247 break;
248 default:
249 ASSERT(FALSE);
250 break;
251 }
252
253 /* Make the page valid */
254 MI_WRITE_VALID_PTE(PointerPte, TempPte);
255
256 /* Acquire a share count */
257 Pfn1 = MI_PFN_ELEMENT(PointerPde->u.Hard.PageFrameNumber);
258 DPRINT("Incrementing %p from %p\n", Pfn1, _ReturnAddress());
259 OldIrql = MiAcquirePfnLock();
260 Pfn1->u2.ShareCount++;
261 MiReleasePfnLock(OldIrql);
262
263 /* Next page */
264 MdlPages++;
265 PointerPte++;
266 NumberOfPages--;
268 }
269
271 ASSERT(AddressSpaceLocked);
273
274 ASSERT(StartingVa != 0);
275 return (PVOID)((ULONG_PTR)StartingVa + MmGetMdlByteOffset(Mdl));
276
277Error:
278 if (AddressSpaceLocked)
279 {
281 }
282 if (Vad != NULL)
283 {
284 ExFreePoolWithTag(Vad, 'ldaV');
286 }
288}
#define PAGED_CODE()
unsigned char BOOLEAN
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
BOOL Error
Definition: chkdsk.c:66
#define MM_READWRITE
Definition: bootanim.c:19
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ULONG_PTR
Definition: config.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define NonPagedPool
Definition: env_spec_w32.h:307
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
#define _ReturnAddress()
Definition: intrin_arm.h:35
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType]
Definition: iosup.c:27
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:827
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1239
@ MiWriteCombined
Definition: miarm.h:412
@ MiCached
Definition: miarm.h:411
@ MiNonCached
Definition: miarm.h:410
VOID NTAPI MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
Definition: virtual.c:2481
TABLE_SEARCH_RESULT NTAPI MiFindEmptyAddressRangeInTree(IN SIZE_T Length, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PMMADDRESS_NODE *PreviousVad, OUT PULONG_PTR Base)
Definition: vadnode.c:584
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:959
TABLE_SEARCH_RESULT NTAPI MiCheckForConflictingNode(IN ULONG_PTR StartVpn, IN ULONG_PTR EndVpn, IN PMM_AVL_TABLE Table, OUT PMMADDRESS_NODE *NodeOrParent)
Definition: vadnode.c:150
FORCEINLINE USHORT MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2466
VOID NTAPI MiInsertVad(_Inout_ PMMVAD Vad, _Inout_ PMM_AVL_TABLE VadRoot)
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1574
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1169
ULONG MiCacheOverride[MiNotMapped+1]
Definition: mdlsup.c:24
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
@ VadDevicePhysicalMemory
Definition: mmtypes.h:205
#define MI_PAGE_WRITE_COMBINED(x)
Definition: mm.h:103
#define MI_PAGE_DISABLE_CACHE(x)
Definition: mm.h:101
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:46
#define MI_PAGE_WRITE_THROUGH(x)
Definition: mm.h:102
#define MiPteToPde(_Pte)
Definition: mm.h:121
BOOLEAN NTAPI KeInvalidateAllCaches(VOID)
Definition: cpu.c:698
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define MM_NOIRQL
Definition: mm.h:70
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1691
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:102
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1704
#define ExRaiseStatus
Definition: ntoskrnl.h:114
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:652
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:557
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
NTSTATUS NTAPI PsChargeProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the non paged pool quota of a given process.
Definition: quota.c:811
VOID NTAPI PsReturnProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the non paged quota pool that the process was taking up.
Definition: quota.c:938
ULONG * PPFN_NUMBER
Definition: ke.h:9
#define DPRINT
Definition: sndvol32.h:73
USHORT CacheAttribute
Definition: mm.h:367
Definition: mm.h:374
union _MMPFN::@1806 u2
MMPFNENTRY e1
Definition: mm.h:397
ULONG_PTR ShareCount
Definition: mm.h:390
struct _MMPFN::@1807::@1813 e2
union _MMPFN::@1807 u3
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
union _MMPTE::@2342 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG LongVad
Definition: mmtypes.h:711
ULONG_PTR Protection
Definition: mmtypes.h:696
ULONG_PTR VadType
Definition: mmtypes.h:694
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
union _MMVAD_LONG::@2626 u
union _MMVAD_LONG::@2627 u2
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:763
ULONG_PTR EndingVpn
Definition: mmtypes.h:759
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:771
ULONG_PTR StartingVpn
Definition: mmtypes.h:758
#define LIST_HEAD(name, type)
Definition: queue.h:167
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
#define MmGetMdlByteOffset(_Mdl)
#define MmGetMdlByteCount(_Mdl)
#define BYTE_OFFSET(Va)
#define MmGetMdlPfnArray(_Mdl)
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS _In_ MEMORY_CACHING_TYPE CacheType
Definition: mmfuncs.h:217
@ MmWriteCombined
Definition: mmtypes.h:131
#define MDL_IO_SPACE
Definition: mmtypes.h:29
#define PsGetCurrentProcess
Definition: psfuncs.h:17
TABLE_SEARCH_RESULT
Definition: rtltypes.h:386

Referenced by MmMapLockedPagesSpecifyCache().

◆ MiUnmapLockedPagesInUserSpace()

static VOID NTAPI MiUnmapLockedPagesInUserSpace ( _In_ PVOID  BaseAddress,
_In_ PMDL  Mdl 
)
static

Definition at line 293 of file mdlsup.c.

296{
299 PMMVAD Vad;
300 PMMPTE PointerPte;
301 PMMPDE PointerPde;
303 ULONG NumberOfPages;
304 PPFN_NUMBER MdlPages;
305 PFN_NUMBER PageTablePage;
306
307 DPRINT("MiUnmapLockedPagesInUserSpace(%p, %p)\n", BaseAddress, Mdl);
308
311 ASSERT(NumberOfPages != 0);
312 MdlPages = MmGetMdlPfnArray(Mdl);
313
314 /* Find the VAD */
317 if (!Vad ||
319 {
320 DPRINT1("MiUnmapLockedPagesInUserSpace invalid for %p\n", BaseAddress);
322 return;
323 }
324
326
327 /* Remove it from the process VAD tree */
328 ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
329 MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
331
332 /* MiRemoveNode should have removed us if we were the hint */
333 ASSERT(Process->VadRoot.NodeHint != Vad);
334
335 PointerPte = MiAddressToPte(BaseAddress);
336 OldIrql = MiAcquirePfnLock();
337 while (NumberOfPages != 0 &&
338 *MdlPages != LIST_HEAD)
339 {
340 ASSERT(MiAddressToPte(PointerPte)->u.Hard.Valid == 1);
341 ASSERT(PointerPte->u.Hard.Valid == 1);
342
343 /* Invalidate it */
344 MI_ERASE_PTE(PointerPte);
345
346 /* We invalidated this PTE, so dereference the PDE */
347 PointerPde = MiAddressToPde(BaseAddress);
348 PageTablePage = PointerPde->u.Hard.PageFrameNumber;
349 MiDecrementShareCount(MiGetPfnEntry(PageTablePage), PageTablePage);
350
352 {
353 ASSERT(MiIsPteOnPdeBoundary(PointerPte + 1) || (NumberOfPages == 1));
354 MiDeletePde(PointerPde, Process);
355 }
356
357 /* Next page */
358 PointerPte++;
359 NumberOfPages--;
361 MdlPages++;
362 }
363
365 MiReleasePfnLock(OldIrql);
368 ExFreePoolWithTag(Vad, 'ldaV');
369}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:116
FORCEINLINE VOID MiDeletePde(_In_ PMMPDE PointerPde, _In_ PEPROCESS CurrentProcess)
Definition: miarm.h:2526
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:440
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:1006
FORCEINLINE USHORT MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2492
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
#define MiAddressToPde(x)
Definition: mmx86.c:20
FORCEINLINE VOID KeFlushProcessTb(VOID)
Definition: ke.h:272
#define MiIsPteOnPdeBoundary(PointerPte)
Definition: mm.h:306
ULONG PFN_NUMBER
Definition: ke.h:9
union _MMVAD::@2623 u
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
#define MmGetMdlVirtualAddress(_Mdl)

Referenced by MmUnmapLockedPages().

◆ MmAdvanceMdl()

NTSTATUS NTAPI MmAdvanceMdl ( IN PMDL  Mdl,
IN ULONG  NumberOfBytes 
)

Definition at line 1617 of file mdlsup.c.

1619{
1622}
#define UNIMPLEMENTED
Definition: debug.h:118
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

◆ MmAllocatePagesForMdl()

PMDL NTAPI MmAllocatePagesForMdl ( IN PHYSICAL_ADDRESS  LowAddress,
IN PHYSICAL_ADDRESS  HighAddress,
IN PHYSICAL_ADDRESS  SkipBytes,
IN SIZE_T  TotalBytes 
)

Definition at line 489 of file mdlsup.c.

493{
494 //
495 // Call the internal routine
496 //
497 return MiAllocatePagesForMdl(LowAddress,
499 SkipBytes,
502 0);
503}
PMDL NTAPI MiAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes, IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute, IN ULONG Flags)
Definition: freelist.c:182
@ MiNotMapped
Definition: miarm.h:413
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:227
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_ SIZE_T TotalBytes
Definition: mmfuncs.h:228

Referenced by TestMmAllocatePagesForMdl().

◆ MmAllocatePagesForMdlEx()

PMDL NTAPI MmAllocatePagesForMdlEx ( IN PHYSICAL_ADDRESS  LowAddress,
IN PHYSICAL_ADDRESS  HighAddress,
IN PHYSICAL_ADDRESS  SkipBytes,
IN SIZE_T  TotalBytes,
IN MEMORY_CACHING_TYPE  CacheType,
IN ULONG  Flags 
)

Definition at line 510 of file mdlsup.c.

516{
517 MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
518
519 //
520 // Check for invalid cache type
521 //
523 {
524 //
525 // Normalize to default
526 //
527 CacheAttribute = MiNotMapped;
528 }
529 else
530 {
531 //
532 // Conver to internal caching attribute
533 //
534 CacheAttribute = MiPlatformCacheAttributes[FALSE][CacheType];
535 }
536
537 //
538 // Only these flags are allowed
539 //
541 {
542 //
543 // Silently fail
544 //
545 return NULL;
546 }
547
548 //
549 // Call the internal routine
550 //
551 return MiAllocatePagesForMdl(LowAddress,
553 SkipBytes,
555 CacheAttribute,
556 Flags);
557}
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define MM_DONT_ZERO_ALLOCATION
Definition: mmtypes.h:11
#define MM_ALLOCATE_FROM_LOCAL_NODE_ONLY
Definition: mmtypes.h:12

◆ MmBuildMdlForNonPagedPool()

VOID NTAPI MmBuildMdlForNonPagedPool ( IN PMDL  Mdl)

Definition at line 424 of file mdlsup.c.

425{
426 PPFN_NUMBER MdlPages, EndPage;
427 PFN_NUMBER Pfn, PageCount;
428 PVOID Base;
429 PMMPTE PointerPte;
430
431 //
432 // Sanity checks
433 //
434 ASSERT(Mdl->ByteCount != 0);
435 ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED |
438 MDL_PARTIAL)) == 0);
439
440 //
441 // We know the MDL isn't associated to a process now
442 //
443 Mdl->Process = NULL;
444
445 //
446 // Get page and VA information
447 //
448 MdlPages = (PPFN_NUMBER)(Mdl + 1);
449 Base = Mdl->StartVa;
450
451 //
452 // Set the system address and now get the page count
453 //
454 Mdl->MappedSystemVa = (PVOID)((ULONG_PTR)Base + Mdl->ByteOffset);
455 PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Mdl->MappedSystemVa,
456 Mdl->ByteCount);
457 ASSERT(PageCount != 0);
458 EndPage = MdlPages + PageCount;
459
460 //
461 // Loop the PTEs
462 //
463 PointerPte = MiAddressToPte(Base);
464 do
465 {
466 //
467 // Write the PFN
468 //
469 Pfn = PFN_FROM_PTE(PointerPte++);
470 *MdlPages++ = Pfn;
471 } while (MdlPages < EndPage);
472
473 //
474 // Set the nonpaged pool flag
475 //
476 Mdl->MdlFlags |= MDL_SOURCE_IS_NONPAGED_POOL;
477
478 //
479 // Check if this is an I/O mapping
480 //
481 if (!MiGetPfnEntry(Pfn)) Mdl->MdlFlags |= MDL_IO_SPACE;
482}
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2451
#define PFN_FROM_PTE(v)
Definition: mm.h:92
int WINAPI EndPage(_In_ HDC)
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define MDL_PARTIAL
Definition: mmtypes.h:22
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18

Referenced by __attribute__(), _Success_(), ClasspInitializeGesn(), CreateDMA(), DiskInfoExceptionCheck(), Ext2CreateMdl(), FatBuildZeroMdl(), KbdHid_StartDevice(), MouHid_StartDevice(), Mx::MxBuildMdlForNonPagedPool(), NdisAllocateBuffer(), read_data(), TestMmBuildMdlForNonPagedPool(), TestProviderInfo(), USBPORT_SendSetupPacket(), USBPORT_ValidateTransferParametersURB(), USBSTOR_AllocateIrp(), USBSTOR_SendInternalCdb(), USBSTOR_SendRequest(), and write_superblock().

◆ MmCreateMdl()

PMDL NTAPI MmCreateMdl ( IN PMDL  Mdl,
IN PVOID  Base,
IN SIZE_T  Length 
)

Definition at line 378 of file mdlsup.c.

381{
382 SIZE_T Size;
383
384 //
385 // Check if we don't have an MDL built
386 //
387 if (!Mdl)
388 {
389 //
390 // Calculate the size we'll need and allocate the MDL
391 //
394 if (!Mdl) return NULL;
395 }
396
397 //
398 // Initialize it
399 //
401 return Mdl;
402}
SIZE_T NTAPI MmSizeOfMdl(IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:409
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define TAG_MDL
Definition: tag.h:89
ULONG_PTR SIZE_T
Definition: typedefs.h:80
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)

Referenced by MiAllocatePagesForMdl().

◆ MmFreePagesFromMdl()

VOID NTAPI MmFreePagesFromMdl ( IN PMDL  Mdl)

Definition at line 564 of file mdlsup.c.

565{
566 PVOID Base;
567 PPFN_NUMBER Pages;
568 LONG NumberOfPages;
569 PMMPFN Pfn1;
571 DPRINT("Freeing MDL: %p\n", Mdl);
572
573 //
574 // Sanity checks
575 //
577 ASSERT((Mdl->MdlFlags & MDL_IO_SPACE) == 0);
578 ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0);
579
580 //
581 // Get address and page information
582 //
583 Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
584 NumberOfPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
585
586 //
587 // Acquire PFN lock
588 //
589 OldIrql = MiAcquirePfnLock();
590
591 //
592 // Loop all the MDL pages
593 //
594 Pages = (PPFN_NUMBER)(Mdl + 1);
595 do
596 {
597 //
598 // Reached the last page
599 //
600 if (*Pages == LIST_HEAD) break;
601
602 //
603 // Get the page entry
604 //
605 Pfn1 = MiGetPfnEntry(*Pages);
606 ASSERT(Pfn1);
607 ASSERT(Pfn1->u2.ShareCount == 1);
608 ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE);
609 if (Pfn1->u4.PteFrame != 0x1FFEDCB)
610 {
611 /* Corrupted PFN entry or invalid free */
612 KeBugCheckEx(MEMORY_MANAGEMENT, 0x1236, (ULONG_PTR)Mdl, (ULONG_PTR)Pages, *Pages);
613 }
614
615 //
616 // Clear it
617 //
618 Pfn1->u3.e1.StartOfAllocation = 0;
619 Pfn1->u3.e1.EndOfAllocation = 0;
621 Pfn1->u2.ShareCount = 0;
622
623 //
624 // Dereference it
625 //
626 ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
627 if (Pfn1->u3.e2.ReferenceCount != 1)
628 {
629 /* Just take off one reference */
630 InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
631 }
632 else
633 {
634 /* We'll be nuking the whole page */
635 MiDecrementReferenceCount(Pfn1, *Pages);
636 }
637
638 //
639 // Clear this page and move on
640 //
641 *Pages++ = LIST_HEAD;
642 } while (--NumberOfPages != 0);
643
644 //
645 // Release the lock
646 //
647 MiReleasePfnLock(OldIrql);
648
649 //
650 // Remove the pages locked flag
651 //
652 Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
653}
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define InterlockedDecrement16
Definition: interlocked.h:139
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1236
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:195
@ StandbyPageList
Definition: mmtypes.h:155
long LONG
Definition: pedump.c:60
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
USHORT PageLocation
Definition: mm.h:365
union _MMPFN::@1810 u4
ULONG_PTR PteFrame
Definition: mm.h:418
int16_t * PSHORT
Definition: typedefs.h:55

Referenced by MmAllocateNonCachedMemory(), MmFreeNonCachedMemory(), TestMap(), and TestMmAllocatePagesForMdl().

◆ MmMapLockedPages()

PVOID NTAPI MmMapLockedPages ( IN PMDL  Mdl,
IN KPROCESSOR_MODE  AccessMode 
)

Definition at line 818 of file mdlsup.c.

820{
821 //
822 // Call the extended version
823 //
826 MmCached,
827 NULL,
828 TRUE,
830}
PVOID NTAPI MmMapLockedPagesSpecifyCache(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN MEMORY_CACHING_TYPE CacheType, IN PVOID BaseAddress, IN ULONG BugCheckOnFailure, IN ULONG Priority)
Definition: mdlsup.c:660
@ HighPagePriority
Definition: imports.h:57
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
@ MmCached
Definition: mmtypes.h:130

Referenced by KsProbeStreamIrp(), MmGetSystemAddressForMdlSafer(), NtStartProfile(), SatisfyPacketRecvRequest(), SendComplete(), and TryToSatisfyRecvRequestFromBuffer().

◆ MmMapLockedPagesSpecifyCache()

PVOID NTAPI MmMapLockedPagesSpecifyCache ( IN PMDL  Mdl,
IN KPROCESSOR_MODE  AccessMode,
IN MEMORY_CACHING_TYPE  CacheType,
IN PVOID  BaseAddress,
IN ULONG  BugCheckOnFailure,
IN ULONG  Priority 
)

Definition at line 660 of file mdlsup.c.

666{
667 PVOID Base;
668 PPFN_NUMBER MdlPages, LastPage;
669 PFN_COUNT PageCount;
670 BOOLEAN IsIoMapping;
671 MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
672 PMMPTE PointerPte;
674
675 //
676 // Sanity check
677 //
678 ASSERT(Mdl->ByteCount != 0);
679
680 //
681 // Get the base
682 //
683 Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
684
685 //
686 // Handle kernel case first
687 //
688 if (AccessMode == KernelMode)
689 {
690 //
691 // Get the list of pages and count
692 //
693 MdlPages = (PPFN_NUMBER)(Mdl + 1);
694 PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
695 LastPage = MdlPages + PageCount;
696
697 //
698 // Sanity checks
699 //
700 ASSERT((Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
703 ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED | MDL_PARTIAL)) != 0);
704
705 //
706 // Get the correct cache type
707 //
708 IsIoMapping = (Mdl->MdlFlags & MDL_IO_SPACE) != 0;
709 CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType];
710
711 //
712 // Reserve the PTEs
713 //
714 PointerPte = MiReserveSystemPtes(PageCount, SystemPteSpace);
715 if (!PointerPte)
716 {
717 //
718 // If it can fail, return NULL
719 //
720 if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL) return NULL;
721
722 //
723 // Should we bugcheck?
724 //
725 if (!BugCheckOnFailure) return NULL;
726
727 //
728 // Yes, crash the system
729 //
730 KeBugCheckEx(NO_MORE_SYSTEM_PTES, 0, PageCount, 0, 0);
731 }
732
733 //
734 // Get the mapped address
735 //
736 Base = (PVOID)((ULONG_PTR)MiPteToAddress(PointerPte) + Mdl->ByteOffset);
737
738 //
739 // Get the template
740 //
742 switch (CacheAttribute)
743 {
744 case MiNonCached:
745
746 //
747 // Disable caching
748 //
751 break;
752
753 case MiWriteCombined:
754
755 //
756 // Enable write combining
757 //
760 break;
761
762 default:
763 //
764 // Nothing to do
765 //
766 break;
767 }
768
769 //
770 // Loop all PTEs
771 //
772 do
773 {
774 //
775 // We're done here
776 //
777 if (*MdlPages == LIST_HEAD) break;
778
779 //
780 // Write the PTE
781 //
782 TempPte.u.Hard.PageFrameNumber = *MdlPages;
783 MI_WRITE_VALID_PTE(PointerPte++, TempPte);
784 } while (++MdlPages < LastPage);
785
786 //
787 // Mark it as mapped
788 //
789 ASSERT((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0);
790 Mdl->MappedSystemVa = Base;
791 Mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
792
793 //
794 // Check if it was partial
795 //
796 if (Mdl->MdlFlags & MDL_PARTIAL)
797 {
798 //
799 // Write the appropriate flag here too
800 //
801 Mdl->MdlFlags |= MDL_PARTIAL_HAS_BEEN_MAPPED;
802 }
803
804 //
805 // Return the mapped address
806 //
807 return Base;
808 }
809
811}
@ SystemPteSpace
Definition: miarm.h:403
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
static PVOID NTAPI MiMapLockedPagesInUserSpace(_In_ PMDL Mdl, _In_ PVOID StartVa, _In_ MEMORY_CACHING_TYPE CacheType, _In_opt_ PVOID BaseAddress)
Definition: mdlsup.c:30
#define KernelMode
Definition: asm.h:34
#define MiPteToAddress(_Pte)
Definition: mm.h:116
MMPTE ValidKernelPte
Definition: init.c:29
ULONG PageFrameNumber
Definition: mmtypes.h:109
#define MDL_PARTIAL_HAS_BEEN_MAPPED
Definition: mmtypes.h:23
#define MDL_MAPPING_CAN_FAIL
Definition: mmtypes.h:31
ULONG PFN_COUNT
Definition: mmtypes.h:102

Referenced by get_block_bh_mdl(), marshal_nfs41_dirquery(), marshal_nfs41_open(), marshal_nfs41_rw(), MiDoMappedCopy(), MmMapLockedPages(), RamdiskReadWriteReal(), TestMessageHandler(), and TestMmAllocatePagesForMdl().

◆ MmMapLockedPagesWithReservedMapping()

PVOID NTAPI MmMapLockedPagesWithReservedMapping ( IN PVOID  MappingAddress,
IN ULONG  PoolTag,
IN PMDL  MemoryDescriptorList,
IN MEMORY_CACHING_TYPE  CacheType 
)

Definition at line 1629 of file mdlsup.c.

1633{
1635 return 0;
1636}

Referenced by TestMap().

◆ MmMapMemoryDumpMdl()

VOID NTAPI MmMapMemoryDumpMdl ( IN PMDL  Mdl)

Definition at line 1706 of file mdlsup.c.

1707{
1709}

◆ MmPrefetchPages()

NTSTATUS NTAPI MmPrefetchPages ( IN ULONG  NumberOfLists,
IN PREAD_LIST ReadLists 
)

Definition at line 1655 of file mdlsup.c.

1657{
1660}

Referenced by FatPrefetchPages().

◆ MmProbeAndLockPages()

VOID NTAPI MmProbeAndLockPages ( IN PMDL  Mdl,
IN KPROCESSOR_MODE  AccessMode,
IN LOCK_OPERATION  Operation 
)

Definition at line 931 of file mdlsup.c.

934{
935 PPFN_NUMBER MdlPages;
936 PVOID Base, Address, LastAddress, StartAddress;
937 ULONG LockPages, TotalPages;
939 PEPROCESS CurrentProcess;
940 NTSTATUS ProbeStatus;
941 PMMPTE PointerPte, LastPte;
942 PMMPDE PointerPde;
943#if (_MI_PAGING_LEVELS >= 3)
944 PMMPDE PointerPpe;
945#endif
946#if (_MI_PAGING_LEVELS == 4)
947 PMMPDE PointerPxe;
948#endif
949 PFN_NUMBER PageFrameIndex;
950 BOOLEAN UsePfnLock;
952 PMMPFN Pfn1;
953 DPRINT("Probing MDL: %p\n", Mdl);
954
955 //
956 // Sanity checks
957 //
958 ASSERT(Mdl->ByteCount != 0);
959 ASSERT(((ULONG)Mdl->ByteOffset & ~(PAGE_SIZE - 1)) == 0);
960 ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0);
961 ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED |
965 MDL_IO_SPACE)) == 0);
966
967 //
968 // Get page and base information
969 //
970 MdlPages = (PPFN_NUMBER)(Mdl + 1);
971 Base = Mdl->StartVa;
972
973 //
974 // Get the addresses and how many pages we span (and need to lock)
975 //
976 Address = (PVOID)((ULONG_PTR)Base + Mdl->ByteOffset);
977 LastAddress = (PVOID)((ULONG_PTR)Address + Mdl->ByteCount);
978 LockPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Address, Mdl->ByteCount);
979 ASSERT(LockPages != 0);
980
981 /* Block invalid access */
982 if ((AccessMode != KernelMode) &&
983 ((LastAddress > (PVOID)MM_USER_PROBE_ADDRESS) || (Address >= LastAddress)))
984 {
985 /* Caller should be in SEH, raise the error */
986 *MdlPages = LIST_HEAD;
988 }
989
990 //
991 // Get the process
992 //
994 {
995 //
996 // Get the process
997 //
998 CurrentProcess = PsGetCurrentProcess();
999 }
1000 else
1001 {
1002 //
1003 // No process
1004 //
1005 CurrentProcess = NULL;
1006 }
1007
1008 //
1009 // Save the number of pages we'll have to lock, and the start address
1010 //
1011 TotalPages = LockPages;
1012 StartAddress = Address;
1013
1014 /* Large pages not supported */
1016
1017 //
1018 // Now probe them
1019 //
1020 ProbeStatus = STATUS_SUCCESS;
1021 _SEH2_TRY
1022 {
1023 //
1024 // Enter probe loop
1025 //
1026 do
1027 {
1028 //
1029 // Assume failure
1030 //
1031 *MdlPages = LIST_HEAD;
1032
1033 //
1034 // Read
1035 //
1036 *(volatile CHAR*)Address;
1037
1038 //
1039 // Check if this is write access (only probe for user-mode)
1040 //
1041 if ((Operation != IoReadAccess) &&
1043 {
1044 //
1045 // Probe for write too
1046 //
1048 }
1049
1050 //
1051 // Next address...
1052 //
1054
1055 //
1056 // Next page...
1057 //
1058 LockPages--;
1059 MdlPages++;
1060 } while (Address < LastAddress);
1061
1062 //
1063 // Reset back to the original page
1064 //
1065 ASSERT(LockPages == 0);
1066 MdlPages = (PPFN_NUMBER)(Mdl + 1);
1067 }
1069 {
1070 //
1071 // Oops :(
1072 //
1073 ProbeStatus = _SEH2_GetExceptionCode();
1074 }
1075 _SEH2_END;
1076
1077 //
1078 // So how did that go?
1079 //
1080 if (ProbeStatus != STATUS_SUCCESS)
1081 {
1082 //
1083 // Fail
1084 //
1085 DPRINT1("MDL PROBE FAILED!\n");
1086 Mdl->Process = NULL;
1087 ExRaiseStatus(ProbeStatus);
1088 }
1089
1090 //
1091 // Get the PTE and PDE
1092 //
1093 PointerPte = MiAddressToPte(StartAddress);
1094 PointerPde = MiAddressToPde(StartAddress);
1095#if (_MI_PAGING_LEVELS >= 3)
1096 PointerPpe = MiAddressToPpe(StartAddress);
1097#endif
1098#if (_MI_PAGING_LEVELS == 4)
1099 PointerPxe = MiAddressToPxe(StartAddress);
1100#endif
1101
1102 //
1103 // Sanity check
1104 //
1105 ASSERT(MdlPages == (PPFN_NUMBER)(Mdl + 1));
1106
1107 //
1108 // Check what kind of operation this is
1109 //
1110 if (Operation != IoReadAccess)
1111 {
1112 //
1113 // Set the write flag
1114 //
1115 Mdl->MdlFlags |= MDL_WRITE_OPERATION;
1116 }
1117 else
1118 {
1119 //
1120 // Remove the write flag
1121 //
1122 Mdl->MdlFlags &= ~(MDL_WRITE_OPERATION);
1123 }
1124
1125 //
1126 // Mark the MDL as locked *now*
1127 //
1128 Mdl->MdlFlags |= MDL_PAGES_LOCKED;
1129
1130 //
1131 // Check if this came from kernel mode
1132 //
1134 {
1135 //
1136 // We should not have a process
1137 //
1138 ASSERT(CurrentProcess == NULL);
1139 Mdl->Process = NULL;
1140
1141 //
1142 // In kernel mode, we don't need to check for write access
1143 //
1145
1146 //
1147 // Use the PFN lock
1148 //
1149 UsePfnLock = TRUE;
1150 OldIrql = MiAcquirePfnLock();
1151 }
1152 else
1153 {
1154 //
1155 // Sanity checks
1156 //
1157 ASSERT(TotalPages != 0);
1158 ASSERT(CurrentProcess == PsGetCurrentProcess());
1159
1160 //
1161 // Track locked pages
1162 //
1164 TotalPages);
1165
1166 //
1167 // Save the process
1168 //
1169 Mdl->Process = CurrentProcess;
1170
1171 /* Lock the process working set */
1173 UsePfnLock = FALSE;
1175 }
1176
1177 //
1178 // Get the last PTE
1179 //
1180 LastPte = MiAddressToPte((PVOID)((ULONG_PTR)LastAddress - 1));
1181
1182 //
1183 // Loop the pages
1184 //
1185 do
1186 {
1187 //
1188 // Assume failure and check for non-mapped pages
1189 //
1190 *MdlPages = LIST_HEAD;
1191 while (
1192#if (_MI_PAGING_LEVELS == 4)
1193 (PointerPxe->u.Hard.Valid == 0) ||
1194#endif
1195#if (_MI_PAGING_LEVELS >= 3)
1196 (PointerPpe->u.Hard.Valid == 0) ||
1197#endif
1198 (PointerPde->u.Hard.Valid == 0) ||
1199 (PointerPte->u.Hard.Valid == 0))
1200 {
1201 //
1202 // What kind of lock were we using?
1203 //
1204 if (UsePfnLock)
1205 {
1206 //
1207 // Release PFN lock
1208 //
1209 MiReleasePfnLock(OldIrql);
1210 }
1211 else
1212 {
1213 /* Release process working set */
1215 }
1216
1217 //
1218 // Access the page
1219 //
1220 Address = MiPteToAddress(PointerPte);
1221
1222 //HACK: Pass a placeholder TrapInformation so the fault handler knows we're unlocked
1223 Status = MmAccessFault(FALSE, Address, KernelMode, (PVOID)(ULONG_PTR)0xBADBADA3BADBADA3ULL);
1224 if (!NT_SUCCESS(Status))
1225 {
1226 //
1227 // Fail
1228 //
1229 DPRINT1("Access fault failed\n");
1230 goto Cleanup;
1231 }
1232
1233 //
1234 // What lock should we use?
1235 //
1236 if (UsePfnLock)
1237 {
1238 //
1239 // Grab the PFN lock
1240 //
1241 OldIrql = MiAcquirePfnLock();
1242 }
1243 else
1244 {
1245 /* Lock the process working set */
1247 }
1248 }
1249
1250 //
1251 // Check if this was a write or modify
1252 //
1253 if (Operation != IoReadAccess)
1254 {
1255 //
1256 // Check if the PTE is not writable
1257 //
1258 if (MI_IS_PAGE_WRITEABLE(PointerPte) == FALSE)
1259 {
1260 //
1261 // Check if it's copy on write
1262 //
1263 if (MI_IS_PAGE_COPY_ON_WRITE(PointerPte))
1264 {
1265 //
1266 // Get the base address and allow a change for user-mode
1267 //
1268 Address = MiPteToAddress(PointerPte);
1270 {
1271 //
1272 // What kind of lock were we using?
1273 //
1274 if (UsePfnLock)
1275 {
1276 //
1277 // Release PFN lock
1278 //
1279 MiReleasePfnLock(OldIrql);
1280 }
1281 else
1282 {
1283 /* Release process working set */
1285 }
1286
1287 //
1288 // Access the page
1289 //
1290
1291 //HACK: Pass a placeholder TrapInformation so the fault handler knows we're unlocked
1292 Status = MmAccessFault(TRUE, Address, KernelMode, (PVOID)(ULONG_PTR)0xBADBADA3BADBADA3ULL);
1293 if (!NT_SUCCESS(Status))
1294 {
1295 //
1296 // Fail
1297 //
1298 DPRINT1("Access fault failed\n");
1299 goto Cleanup;
1300 }
1301
1302 //
1303 // Re-acquire the lock
1304 //
1305 if (UsePfnLock)
1306 {
1307 //
1308 // Grab the PFN lock
1309 //
1310 OldIrql = MiAcquirePfnLock();
1311 }
1312 else
1313 {
1314 /* Lock the process working set */
1316 }
1317
1318 //
1319 // Start over
1320 //
1321 continue;
1322 }
1323 }
1324
1325 //
1326 // Fail, since we won't allow this
1327 //
1329 goto CleanupWithLock;
1330 }
1331 }
1332
1333 //
1334 // Grab the PFN
1335 //
1336 PageFrameIndex = PFN_FROM_PTE(PointerPte);
1337 Pfn1 = MiGetPfnEntry(PageFrameIndex);
1338 if (Pfn1)
1339 {
1340 /* Either this is for kernel-mode, or the working set is held */
1341 ASSERT((CurrentProcess == NULL) || (UsePfnLock == FALSE));
1342
1343 /* No Physical VADs supported yet */
1344 if (CurrentProcess) ASSERT(CurrentProcess->PhysicalVadRoot == NULL);
1345
1346 /* This address should already exist and be fully valid */
1348 }
1349 else
1350 {
1351 //
1352 // For I/O addresses, just remember this
1353 //
1354 Mdl->MdlFlags |= MDL_IO_SPACE;
1355 }
1356
1357 //
1358 // Write the page and move on
1359 //
1360 *MdlPages++ = PageFrameIndex;
1361 PointerPte++;
1362
1363 /* Check if we're on a PDE boundary */
1364 if (MiIsPteOnPdeBoundary(PointerPte)) PointerPde++;
1365#if (_MI_PAGING_LEVELS >= 3)
1366 if (MiIsPteOnPpeBoundary(PointerPte)) PointerPpe++;
1367#endif
1368#if (_MI_PAGING_LEVELS == 4)
1369 if (MiIsPteOnPxeBoundary(PointerPte)) PointerPxe++;
1370#endif
1371
1372 } while (PointerPte <= LastPte);
1373
1374 //
1375 // What kind of lock were we using?
1376 //
1377 if (UsePfnLock)
1378 {
1379 //
1380 // Release PFN lock
1381 //
1382 MiReleasePfnLock(OldIrql);
1383 }
1384 else
1385 {
1386 /* Release process working set */
1388 }
1389
1390 //
1391 // Sanity check
1392 //
1393 ASSERT((Mdl->MdlFlags & MDL_DESCRIBES_AWE) == 0);
1394 return;
1395
1396CleanupWithLock:
1397 //
1398 // This is the failure path
1399 //
1401
1402 //
1403 // What kind of lock were we using?
1404 //
1405 if (UsePfnLock)
1406 {
1407 //
1408 // Release PFN lock
1409 //
1410 MiReleasePfnLock(OldIrql);
1411 }
1412 else
1413 {
1414 /* Release process working set */
1416 }
1417Cleanup:
1418 //
1419 // Pages must be locked so MmUnlock can work
1420 //
1421 ASSERT(Mdl->MdlFlags & MDL_PAGES_LOCKED);
1423
1424 //
1425 // Raise the error
1426 //
1428}
#define MM_USER_PROBE_ADDRESS
Definition: armddk.h:19
#define MM_HIGHEST_USER_ADDRESS
Definition: armddk.h:17
static const WCHAR Cleanup[]
Definition: register.c:80
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
FP_OP Operation
Definition: fpcontrol.c:150
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
if(dx< 0)
Definition: linetemp.h:194
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:945
FORCEINLINE VOID MiUnlockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1194
FORCEINLINE VOID MiReferenceProbedPageAndBumpLockCount(IN PMMPFN Pfn1)
Definition: miarm.h:1687
FORCEINLINE VOID MiLockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1124
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
#define MI_IS_PAGE_COPY_ON_WRITE(x)
Definition: mm.h:110
#define MI_IS_PAGE_WRITEABLE(x)
Definition: mm.h:106
#define MiIsPteOnPpeBoundary(PointerPte)
Definition: mm.h:308
#define _MI_PAGING_LEVELS
Definition: mm.h:6
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:161
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:171
#define MiIsPteOnPxeBoundary(PointerPte)
Definition: mm.h:310
NTSTATUS NTAPI MmAccessFault(IN ULONG FaultCode, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
Definition: mmfault.c:209
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
static WCHAR Address[46]
Definition: ping.c:68
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define ProbeForWriteChar(Ptr)
Definition: probe.h:33
#define STATUS_SUCCESS
Definition: shellext.h:65
PMM_AVL_TABLE PhysicalVadRoot
Definition: pstypes.h:1298
PFN_NUMBER NumberOfLockedPages
Definition: pstypes.h:1301
@ IoReadAccess
Definition: ketypes.h:863
#define PAGE_ALIGN(Va)
#define MDL_WRITE_OPERATION
Definition: mmtypes.h:25
#define MDL_DESCRIBES_AWE
Definition: mmtypes.h:28
char CHAR
Definition: xmlstorage.h:175

Referenced by __attribute__(), add_thread_job(), AfdGetSockName(), BuildAndSubmitIrp(), CdCreateUserMdl(), ClasspBuildDeviceMdl(), ClassSendDeviceIoControlSynchronous(), ClassSendSrbSynchronous(), DispTdiQueryInformationEx(), DriverIoControl(), ExLockUserBuffer(), Ext2CreateMdl(), Ext2LockUserBuffer(), FatLockUserBuffer(), FatSingleNonAlignedSync(), FxProbeAndLockForRead(), FxProbeAndLockForWrite(), FxProbeAndLockWithAccess(), HackSecureVirtualMemory(), IoBuildAsynchronousFsdRequest(), IoBuildDeviceIoControlRequest(), IopDeviceFsIoControl(), KsProbeStreamIrp(), LockBuffers(), LockRequest(), MapAndLockUserBuffer(), MiDoMappedCopy(), MupBuildIoControlRequest(), nfs41_QueryDirectory(), NtfsLockUserBuffer(), NtQueryDirectoryFile(), NtReadFile(), NtStartProfile(), NtWriteFile(), read_data(), RxLockUserBuffer(), scrub_chunk_raid56_stripe_run(), scrub_extent(), sync_read_phys(), TdiQueryMaxDatagramLength(), TdiReceive(), TdiReceiveDatagram(), TdiSend(), TdiSendDatagram(), TestMessageHandler(), UDFGetCallersBuffer(), UDFLockCallersBuffer(), VfatLockUserBuffer(), VideoPortLockBuffer(), and write_data_phys().

◆ MmProbeAndLockProcessPages()

VOID NTAPI MmProbeAndLockProcessPages ( IN OUT PMDL  MemoryDescriptorList,
IN PEPROCESS  Process,
IN KPROCESSOR_MODE  AccessMode,
IN LOCK_OPERATION  Operation 
)

Definition at line 1679 of file mdlsup.c.

1683{
1685}

◆ MmProbeAndLockSelectedPages()

VOID NTAPI MmProbeAndLockSelectedPages ( IN OUT PMDL  MemoryDescriptorList,
IN LARGE_INTEGER  PageList[],
IN KPROCESSOR_MODE  AccessMode,
IN LOCK_OPERATION  Operation 
)

Definition at line 1693 of file mdlsup.c.

1697{
1699}

◆ MmProtectMdlSystemAddress()

NTSTATUS NTAPI MmProtectMdlSystemAddress ( IN PMDL  MemoryDescriptorList,
IN ULONG  NewProtect 
)

Definition at line 1667 of file mdlsup.c.

1669{
1672}

◆ MmSizeOfMdl()

SIZE_T NTAPI MmSizeOfMdl ( IN PVOID  Base,
IN SIZE_T  Length 
)

Definition at line 409 of file mdlsup.c.

411{
412 //
413 // Return the MDL size
414 //
415 return sizeof(MDL) +
417}
MDL
Definition: mmtypes.h:117

Referenced by FxRequestBuffer::GetOrAllocateMdlWorker(), and MmCreateMdl().

◆ MmUnlockPages()

VOID NTAPI MmUnlockPages ( IN PMDL  Mdl)

Definition at line 1435 of file mdlsup.c.

1436{
1437 PPFN_NUMBER MdlPages, LastPage;
1439 PVOID Base;
1440 ULONG Flags, PageCount;
1441 KIRQL OldIrql;
1442 PMMPFN Pfn1;
1443 DPRINT("Unlocking MDL: %p\n", Mdl);
1444
1445 //
1446 // Sanity checks
1447 //
1448 ASSERT((Mdl->MdlFlags & MDL_PAGES_LOCKED) != 0);
1449 ASSERT((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0);
1450 ASSERT((Mdl->MdlFlags & MDL_PARTIAL) == 0);
1451 ASSERT(Mdl->ByteCount != 0);
1452
1453 //
1454 // Get the process associated and capture the flags which are volatile
1455 //
1456 Process = Mdl->Process;
1457 Flags = Mdl->MdlFlags;
1458
1459 //
1460 // Automagically undo any calls to MmGetSystemAddressForMdl's for this MDL
1461 //
1462 if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
1463 {
1464 //
1465 // Unmap the pages from system space
1466 //
1467 MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
1468 }
1469
1470 //
1471 // Get the page count
1472 //
1473 MdlPages = (PPFN_NUMBER)(Mdl + 1);
1474 Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
1475 PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
1476 ASSERT(PageCount != 0);
1477
1478 //
1479 // We don't support AWE
1480 //
1482
1483 //
1484 // Check if the buffer is mapped I/O space
1485 //
1486 if (Flags & MDL_IO_SPACE)
1487 {
1488 //
1489 // Acquire PFN lock
1490 //
1491 OldIrql = MiAcquirePfnLock();
1492
1493 //
1494 // Loop every page
1495 //
1496 LastPage = MdlPages + PageCount;
1497 do
1498 {
1499 //
1500 // Last page, break out
1501 //
1502 if (*MdlPages == LIST_HEAD) break;
1503
1504 //
1505 // Check if this page is in the PFN database
1506 //
1507 Pfn1 = MiGetPfnEntry(*MdlPages);
1508 if (Pfn1) MiDereferencePfnAndDropLockCount(Pfn1);
1509 } while (++MdlPages < LastPage);
1510
1511 //
1512 // Release the lock
1513 //
1514 MiReleasePfnLock(OldIrql);
1515
1516 //
1517 // Check if we have a process
1518 //
1519 if (Process)
1520 {
1521 //
1522 // Handle the accounting of locked pages
1523 //
1524 ASSERT(Process->NumberOfLockedPages > 0);
1525 InterlockedExchangeAddSizeT(&Process->NumberOfLockedPages,
1526 -(LONG_PTR)PageCount);
1527 }
1528
1529 //
1530 // We're done
1531 //
1532 Mdl->MdlFlags &= ~MDL_IO_SPACE;
1533 Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1534 return;
1535 }
1536
1537 //
1538 // Check if we have a process
1539 //
1540 if (Process)
1541 {
1542 //
1543 // Handle the accounting of locked pages
1544 //
1545 ASSERT(Process->NumberOfLockedPages > 0);
1546 InterlockedExchangeAddSizeT(&Process->NumberOfLockedPages,
1547 -(LONG_PTR)PageCount);
1548 }
1549
1550 //
1551 // Loop every page
1552 //
1553 LastPage = MdlPages + PageCount;
1554 do
1555 {
1556 //
1557 // Last page reached
1558 //
1559 if (*MdlPages == LIST_HEAD)
1560 {
1561 //
1562 // Were there no pages at all?
1563 //
1564 if (MdlPages == (PPFN_NUMBER)(Mdl + 1))
1565 {
1566 //
1567 // We're already done
1568 //
1569 Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1570 return;
1571 }
1572
1573 //
1574 // Otherwise, stop here
1575 //
1576 LastPage = MdlPages;
1577 break;
1578 }
1579
1580 /* Save the PFN entry instead for the secondary loop */
1581 *MdlPages = (PFN_NUMBER)MiGetPfnEntry(*MdlPages);
1582 ASSERT(*MdlPages != 0);
1583 } while (++MdlPages < LastPage);
1584
1585 //
1586 // Reset pointer
1587 //
1588 MdlPages = (PPFN_NUMBER)(Mdl + 1);
1589
1590 //
1591 // Now grab the PFN lock for the actual unlock and dereference
1592 //
1593 OldIrql = MiAcquirePfnLock();
1594 do
1595 {
1596 /* Get the current entry and reference count */
1597 Pfn1 = (PMMPFN)*MdlPages;
1599 } while (++MdlPages < LastPage);
1600
1601 //
1602 // Release the lock
1603 //
1604 MiReleasePfnLock(OldIrql);
1605
1606 //
1607 // We're done
1608 //
1609 Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1610}
FORCEINLINE VOID MiDereferencePfnAndDropLockCount(IN PMMPFN Pfn1)
Definition: miarm.h:1615
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:837
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
struct _MMPFN * PMMPFN

Referenced by __attribute__(), _Function_class_(), CcMdlReadComplete2(), ClassAsynchronousCompletion(), ClasspFreeDeviceMdl(), ClasspSendSynchronousCompletion(), ClassSendDeviceIoControlSynchronous(), CommonForwardedIoCompletionRoutine(), DispTdiQueryInformationEx(), DispTdiQueryInformationExComplete(), DriverCleanup(), DriverIoControl(), ExpDeleteProfile(), Ext2DestroyMdl(), ExUnlockUserBuffer(), FatSingleNonAlignedSync(), FxRequestBase::FreeMdls(), HackSecureVirtualMemory(), HackUnsecureVirtualMemory(), IoCompletion(), IofCompleteRequest(), LockRequest(), MiDoMappedCopy(), MmProbeAndLockPages(), Mx::MxUnlockPages(), nfs41_QueryDirectory(), NtStopProfile(), read_data(), FxIoContext::ReleaseAndRestore(), FxUsbPipeTransferContext::ReleaseAndRestore(), scrub_chunk_raid56_stripe_run(), scrub_extent(), SpiSenseCompletionRoutine(), sync_read_phys(), TestCleanEverything(), UDFAsyncCompletionRoutine(), UnlockBuffers(), UnlockRequest(), VideoPortUnlockBuffer(), write_data_phys(), write_superblocks(), and FxIoContext::~FxIoContext().

◆ MmUnmapLockedPages()

VOID NTAPI MmUnmapLockedPages ( IN PVOID  BaseAddress,
IN PMDL  Mdl 
)

Definition at line 837 of file mdlsup.c.

839{
840 PVOID Base;
841 PFN_COUNT PageCount, ExtraPageCount;
842 PPFN_NUMBER MdlPages;
843 PMMPTE PointerPte;
844
845 //
846 // Sanity check
847 //
848 ASSERT(Mdl->ByteCount != 0);
849
850 //
851 // Check if this is a kernel request
852 //
854 {
855 //
856 // Get base and count information
857 //
858 Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
859 PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
860
861 //
862 // Sanity checks
863 //
864 ASSERT((Mdl->MdlFlags & MDL_PARENT_MAPPED_SYSTEM_VA) == 0);
865 ASSERT(PageCount != 0);
867
868 //
869 // Get the PTE
870 //
871 PointerPte = MiAddressToPte(BaseAddress);
872
873 //
874 // This should be a resident system PTE
875 //
877 ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
878 ASSERT(PointerPte->u.Hard.Valid == 1);
879
880 //
881 // Check if the caller wants us to free advanced pages
882 //
883 if (Mdl->MdlFlags & MDL_FREE_EXTRA_PTES)
884 {
885 //
886 // Get the MDL page array
887 //
888 MdlPages = MmGetMdlPfnArray(Mdl);
889
890 /* Number of extra pages stored after the PFN array */
891 ExtraPageCount = (PFN_COUNT)*(MdlPages + PageCount);
892
893 //
894 // Do the math
895 //
896 PageCount += ExtraPageCount;
897 PointerPte -= ExtraPageCount;
899 ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
900
901 //
902 // Get the new base address
903 //
905 (ExtraPageCount << PAGE_SHIFT));
906 }
907
908 //
909 // Remove flags
910 //
911 Mdl->MdlFlags &= ~(MDL_MAPPED_TO_SYSTEM_VA |
914
915 //
916 // Release the system PTEs
917 //
918 MiReleaseSystemPtes(PointerPte, PageCount, SystemPteSpace);
919 }
920 else
921 {
923 }
924}
PMMPTE MmSystemPtesStart[MaximumPtePoolTypes]
Definition: syspte.c:22
PMMPTE MmSystemPtesEnd[MaximumPtePoolTypes]
Definition: syspte.c:23
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:264
static VOID NTAPI MiUnmapLockedPagesInUserSpace(_In_ PVOID BaseAddress, _In_ PMDL Mdl)
Definition: mdlsup.c:293
#define MDL_FREE_EXTRA_PTES
Definition: mmtypes.h:27
#define MDL_PARENT_MAPPED_SYSTEM_VA
Definition: mmtypes.h:26

Referenced by CcZeroData(), ExpDeleteProfile(), free_buffer_head(), MiDoMappedCopy(), MiReadFilePage(), MiReadPageFile(), MiWritePage(), MmMakeSegmentResident(), MmUnlockPages(), MmWriteToSwapPage(), nfs41_downcall(), NtStopProfile(), SatisfyPacketRecvRequest(), SendComplete(), TestCleanEverything(), TestMmAllocatePagesForMdl(), TryToSatisfyRecvRequestFromBuffer(), unmarshal_nfs41_dirquery(), unmarshal_nfs41_open(), and unmarshal_nfs41_rw().

◆ MmUnmapReservedMapping()

VOID NTAPI MmUnmapReservedMapping ( IN PVOID  BaseAddress,
IN ULONG  PoolTag,
IN PMDL  MemoryDescriptorList 
)

Definition at line 1643 of file mdlsup.c.

1646{
1648}

Referenced by TestMap().

Variable Documentation

◆ MiCacheOverride

ULONG MiCacheOverride[MiNotMapped+1]

Definition at line 24 of file mdlsup.c.

Referenced by MiMapLockedPagesInUserSpace().

◆ MmSystemLockPagesCount

◆ MmTrackLockedPages

BOOLEAN MmTrackLockedPages

Definition at line 21 of file mdlsup.c.

◆ MmTrackPtes

BOOLEAN MmTrackPtes

Definition at line 20 of file mdlsup.c.