ReactOS  0.4.14-dev-583-g2a1ba2c
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 MM_PAGE_PRIORITY 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;
43  KIRQL OldIrql;
44  ULONG_PTR StartingVa;
45  ULONG_PTR EndingVa;
47  PMMVAD_LONG Vad;
48  ULONG NumberOfPages;
49  PMMPTE PointerPte;
50  PMMPDE PointerPde;
51  MMPTE TempPte;
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,
63  MmGetMdlByteCount(Mdl));
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 
77  /* Allocate a VAD for our mapped region */
78  Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
79  if (Vad == NULL)
80  {
82  goto Error;
83  }
84 
85  /* Initialize PhysicalMemory VAD */
86  RtlZeroMemory(Vad, sizeof(*Vad));
87  Vad->u2.VadFlags2.LongVad = 1;
90  Vad->u.VadFlags.PrivateMemory = 1;
91 
92  /* Did the caller specify an address? */
93  if (BaseAddress == NULL)
94  {
95  /* We get to pick the address */
97  AddressSpaceLocked = TRUE;
98  if (Process->VmDeleted)
99  {
101  goto Error;
102  }
103 
106  &Process->VadRoot,
107  &Parent,
108  &StartingVa);
109  if (Result == TableFoundNode)
110  {
112  goto Error;
113  }
114  EndingVa = StartingVa + NumberOfPages * PAGE_SIZE - 1;
115  BaseAddress = (PVOID)StartingVa;
116  }
117  else
118  {
119  /* Caller specified a base address */
120  StartingVa = (ULONG_PTR)BaseAddress;
121  EndingVa = StartingVa + NumberOfPages * PAGE_SIZE - 1;
122 
123  /* Make sure it's valid */
124  if (BYTE_OFFSET(StartingVa) != 0 ||
125  EndingVa <= StartingVa ||
126  EndingVa > (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS)
127  {
129  goto Error;
130  }
131 
133  AddressSpaceLocked = TRUE;
134  if (Process->VmDeleted)
135  {
137  goto Error;
138  }
139 
140  /* Check if it's already in use */
142  EndingVa >> PAGE_SHIFT,
143  &Process->VadRoot,
144  &Parent);
145  if (Result == TableFoundNode)
146  {
148  goto Error;
149  }
150  }
151 
152  Vad->StartingVpn = StartingVa >> PAGE_SHIFT;
153  Vad->EndingVpn = EndingVa >> PAGE_SHIFT;
154 
156 
157  ASSERT(Vad->EndingVpn >= Vad->StartingVpn);
158 
159  MiInsertVad((PMMVAD)Vad, &Process->VadRoot);
160 
161  /* Check if this is uncached */
162  if (CacheAttribute != MiCached)
163  {
164  /* Flush all caches */
167  }
168 
169  PointerPte = MiAddressToPte(BaseAddress);
170  while (NumberOfPages != 0 &&
171  *MdlPages != LIST_HEAD)
172  {
173  PointerPde = MiPteToPde(PointerPte);
175  ASSERT(PointerPte->u.Hard.Valid == 0);
176 
177  /* Add a PDE reference for each page */
179 
180  /* Set up our basic user PTE */
182  PointerPte,
183  MM_READWRITE,
184  *MdlPages);
185 
186  EffectiveCacheAttribute = CacheAttribute;
187 
188  /* We need to respect the PFN's caching information in some cases */
189  Pfn2 = MiGetPfnEntry(*MdlPages);
190  if (Pfn2 != NULL)
191  {
192  ASSERT(Pfn2->u3.e2.ReferenceCount != 0);
193 
194  switch (Pfn2->u3.e1.CacheAttribute)
195  {
196  case MiNonCached:
197  if (CacheAttribute != MiNonCached)
198  {
199  MiCacheOverride[1]++;
200  EffectiveCacheAttribute = MiNonCached;
201  }
202  break;
203 
204  case MiCached:
205  if (CacheAttribute != MiCached)
206  {
207  MiCacheOverride[0]++;
208  EffectiveCacheAttribute = MiCached;
209  }
210  break;
211 
212  case MiWriteCombined:
213  if (CacheAttribute != MiWriteCombined)
214  {
215  MiCacheOverride[2]++;
216  EffectiveCacheAttribute = MiWriteCombined;
217  }
218  break;
219 
220  default:
221  /* We don't support AWE magic (MiNotMapped) */
222  DPRINT1("FIXME: MiNotMapped is not supported\n");
223  ASSERT(FALSE);
224  break;
225  }
226  }
227 
228  /* Configure caching */
229  switch (EffectiveCacheAttribute)
230  {
231  case MiNonCached:
234  break;
235  case MiCached:
236  break;
237  case MiWriteCombined:
240  break;
241  default:
242  ASSERT(FALSE);
243  break;
244  }
245 
246  /* Make the page valid */
247  MI_WRITE_VALID_PTE(PointerPte, TempPte);
248 
249  /* Acquire a share count */
250  Pfn1 = MI_PFN_ELEMENT(PointerPde->u.Hard.PageFrameNumber);
252  Pfn1->u2.ShareCount++;
254 
255  /* Next page */
256  MdlPages++;
257  PointerPte++;
258  NumberOfPages--;
260  }
261 
263  ASSERT(AddressSpaceLocked);
265 
266  ASSERT(StartingVa != 0);
267  return (PVOID)((ULONG_PTR)StartingVa + MmGetMdlByteOffset(Mdl));
268 
269 Error:
270  if (AddressSpaceLocked)
271  {
273  }
274  if (Vad != NULL)
275  {
276  ExFreePoolWithTag(Vad, 'ldaV');
277  }
279 }
ULONG_PTR EndingVpn
Definition: mmtypes.h:759
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
struct _MMPFN::@1748::@1754 e2
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:78
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
union _MMPFN::@1747 u2
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1214
#define MI_PAGE_WRITE_COMBINED(x)
Definition: mm.h:100
#define MmGetMdlPfnArray(_Mdl)
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1431
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:763
enum _TABLE_SEARCH_RESULT TABLE_SEARCH_RESULT
LONG NTSTATUS
Definition: precomp.h:26
#define ExRaiseStatus
Definition: ntoskrnl.h:96
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
union _MMPTE::@2255 u
ULONG_PTR Protection
Definition: mmtypes.h:696
ULONG LongVad
Definition: mmtypes.h:711
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical 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:728
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
#define PAGED_CODE()
Definition: video.h:57
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define MDL_IO_SPACE
Definition: mmtypes.h:29
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:329
ULONG * PPFN_NUMBER
Definition: ke.h:8
USHORT CacheAttribute
Definition: mm.h:299
#define MiAddressToPte(x)
Definition: mmx86.c:19
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:951
ULONG_PTR ShareCount
Definition: mm.h:322
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType]
Definition: iosup.c:27
#define PsGetCurrentProcess
Definition: psfuncs.h:17
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:502
unsigned char BOOLEAN
VOID NTAPI MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
Definition: virtual.c:2371
smooth NULL
Definition: ftsmooth.c:416
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS _In_ MEMORY_CACHING_TYPE CacheType
Definition: mmfuncs.h:214
_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:426
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
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:78
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:413
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
BOOLEAN NTAPI KeInvalidateAllCaches(VOID)
Definition: cpu.c:459
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1144
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
ULONG MiCacheOverride[MiNotMapped+1]
Definition: mdlsup.c:24
union _MMPFN::@1748 u3
ULONG64 Valid
Definition: mmtypes.h:150
ULONG_PTR StartingVpn
Definition: mmtypes.h:758
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:488
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:771
BOOL Error
Definition: chkdsk.c:66
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define MI_PAGE_WRITE_THROUGH(x)
Definition: mm.h:99
union _MMVAD_LONG::@2518 u
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1428
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define MM_READWRITE
Definition: inbv.c:10
#define MM_NOIRQL
Definition: miarm.h:240
Definition: mm.h:305
union _MMVAD_LONG::@2519 u2
#define PAGE_SIZE
Definition: env_spec_w32.h:49
LIST_HEAD(acpi_bus_event_list)
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
Status
Definition: gdiplustypes.h:24
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:822
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MiPteToPde(_Pte)
Definition: mm.h:233
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:543
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define MmGetMdlByteCount(_Mdl)
#define MI_PAGE_DISABLE_CACHE(x)
Definition: mm.h:98
#define DPRINT1
Definition: precomp.h:8
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:43
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
FORCEINLINE VOID MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:1672
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define MmGetMdlByteOffset(_Mdl)
VOID NTAPI MiInsertVad(_Inout_ PMMVAD Vad, _Inout_ PMM_AVL_TABLE VadRoot)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:247
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1424
#define BYTE_OFFSET(Va)
ULONG_PTR VadType
Definition: mmtypes.h:694

Referenced by MmMapLockedPagesSpecifyCache().

◆ MiUnmapLockedPagesInUserSpace()

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

Definition at line 284 of file mdlsup.c.

287 {
290  PMMVAD Vad;
291  PMMPTE PointerPte;
292  PMMPDE PointerPde;
293  KIRQL OldIrql;
294  ULONG NumberOfPages;
295  PPFN_NUMBER MdlPages;
296  PFN_NUMBER PageTablePage;
297 
298  DPRINT("MiUnmapLockedPagesInUserSpace(%p, %p)\n", BaseAddress, Mdl);
299 
301  MmGetMdlByteCount(Mdl));
302  ASSERT(NumberOfPages != 0);
303  MdlPages = MmGetMdlPfnArray(Mdl);
304 
305  /* Find the VAD */
308  if (!Vad ||
310  {
311  DPRINT1("MiUnmapLockedPagesInUserSpace invalid for %p\n", BaseAddress);
313  return;
314  }
315 
317 
318  /* Remove it from the process VAD tree */
319  ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
320  MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
321 
322  /* MiRemoveNode should have removed us if we were the hint */
323  ASSERT(Process->VadRoot.NodeHint != Vad);
324 
325  PointerPte = MiAddressToPte(BaseAddress);
327  while (NumberOfPages != 0 &&
328  *MdlPages != LIST_HEAD)
329  {
330  ASSERT(MiAddressToPte(PointerPte)->u.Hard.Valid == 1);
331  ASSERT(PointerPte->u.Hard.Valid == 1);
332 
333  /* Dereference the page */
335 
336  /* Invalidate it */
337  MI_ERASE_PTE(PointerPte);
338 
339  /* We invalidated this PTE, so dereference the PDE */
340  PointerPde = MiAddressToPde(BaseAddress);
341  PageTablePage = PointerPde->u.Hard.PageFrameNumber;
342  MiDecrementShareCount(MiGetPfnEntry(PageTablePage), PageTablePage);
343 
344  /* Next page */
345  PointerPte++;
346  NumberOfPages--;
348  MdlPages++;
349 
350  /* Moving to a new PDE? */
351  if (PointerPde != MiAddressToPde(BaseAddress))
352  {
353  /* See if we should delete it */
355  PointerPde = MiPteToPde(PointerPte - 1);
356  ASSERT(PointerPde->u.Hard.Valid == 1);
358  {
359  ASSERT(PointerPde->u.Long != 0);
360  MiDeletePte(PointerPde,
361  MiPteToAddress(PointerPde),
362  Process,
363  NULL);
364  }
365  }
366  }
367 
372  ExFreePoolWithTag(Vad, 'ldaV');
373 }
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
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:994
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1214
#define MmGetMdlPfnArray(_Mdl)
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define MmGetMdlVirtualAddress(_Mdl)
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1431
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
FORCEINLINE USHORT MiQueryPageTableReferences(IN PVOID Address)
Definition: miarm.h:1696
union _MMPTE::@2255 u
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
VOID NTAPI MiDeletePte(IN PMMPTE PointerPte, IN PVOID VirtualAddress, IN PEPROCESS CurrentProcess, IN PMMPTE PrototypePte)
Definition: virtual.c:391
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG * PPFN_NUMBER
Definition: ke.h:8
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:48
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1133
void * PVOID
Definition: retypes.h:9
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1144
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
FORCEINLINE VOID MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:1684
ULONG64 Valid
Definition: mmtypes.h:150
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
union _MMVAD::@2515 u
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define PAGE_SIZE
Definition: env_spec_w32.h:49
LIST_HEAD(acpi_bus_event_list)
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:360
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MiPteToPde(_Pte)
Definition: mm.h:233
#define MmGetMdlByteCount(_Mdl)
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE VOID KeFlushProcessTb(VOID)
Definition: ke.h:209
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1424
ULONG_PTR VadType
Definition: mmtypes.h:694

Referenced by MmUnmapLockedPages().

◆ MmAdvanceMdl()

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

Definition at line 1621 of file mdlsup.c.

1623 {
1624  UNIMPLEMENTED;
1625  return STATUS_NOT_IMPLEMENTED;
1626 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define UNIMPLEMENTED
Definition: debug.h:114

◆ MmAllocatePagesForMdl()

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

Definition at line 493 of file mdlsup.c.

497 {
498  //
499  // Call the internal routine
500  //
501  return MiAllocatePagesForMdl(LowAddress,
502  HighAddress,
503  SkipBytes,
504  TotalBytes,
505  MiNotMapped,
506  0);
507 }
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
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:150
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_ SIZE_T TotalBytes
Definition: mmfuncs.h:226

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 514 of file mdlsup.c.

520 {
521  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
522 
523  //
524  // Check for invalid cache type
525  //
527  {
528  //
529  // Normalize to default
530  //
531  CacheAttribute = MiNotMapped;
532  }
533  else
534  {
535  //
536  // Conver to internal caching attribute
537  //
538  CacheAttribute = MiPlatformCacheAttributes[FALSE][CacheType];
539  }
540 
541  //
542  // Only these flags are allowed
543  //
545  {
546  //
547  // Silently fail
548  //
549  return NULL;
550  }
551 
552  //
553  // Call the internal routine
554  //
555  return MiAllocatePagesForMdl(LowAddress,
556  HighAddress,
557  SkipBytes,
558  TotalBytes,
559  CacheAttribute,
560  Flags);
561 }
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType]
Definition: iosup.c:27
smooth NULL
Definition: ftsmooth.c:416
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS _In_ MEMORY_CACHING_TYPE CacheType
Definition: mmfuncs.h:214
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
#define MM_ALLOCATE_FROM_LOCAL_NODE_ONLY
Definition: mmtypes.h:12
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
#define MM_DONT_ZERO_ALLOCATION
Definition: mmtypes.h:11
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:150
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_ SIZE_T TotalBytes
Definition: mmfuncs.h:226

◆ MmBuildMdlForNonPagedPool()

VOID NTAPI MmBuildMdlForNonPagedPool ( IN PMDL  Mdl)

Definition at line 428 of file mdlsup.c.

429 {
430  PPFN_NUMBER MdlPages, EndPage;
431  PFN_NUMBER Pfn, PageCount;
432  PVOID Base;
433  PMMPTE PointerPte;
434 
435  //
436  // Sanity checks
437  //
438  ASSERT(Mdl->ByteCount != 0);
439  ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED |
442  MDL_PARTIAL)) == 0);
443 
444  //
445  // We know the MDL isn't associated to a process now
446  //
447  Mdl->Process = NULL;
448 
449  //
450  // Get page and VA information
451  //
452  MdlPages = (PPFN_NUMBER)(Mdl + 1);
453  Base = Mdl->StartVa;
454 
455  //
456  // Set the system address and now get the page count
457  //
458  Mdl->MappedSystemVa = (PVOID)((ULONG_PTR)Base + Mdl->ByteOffset);
459  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Mdl->MappedSystemVa,
460  Mdl->ByteCount);
461  ASSERT(PageCount != 0);
462  EndPage = MdlPages + PageCount;
463 
464  //
465  // Loop the PTEs
466  //
467  PointerPte = MiAddressToPte(Base);
468  do
469  {
470  //
471  // Write the PFN
472  //
473  Pfn = PFN_FROM_PTE(PointerPte++);
474  *MdlPages++ = Pfn;
475  } while (MdlPages < EndPage);
476 
477  //
478  // Set the nonpaged pool flag
479  //
480  Mdl->MdlFlags |= MDL_SOURCE_IS_NONPAGED_POOL;
481 
482  //
483  // Check if this is an I/O mapping
484  //
485  if (!MiGetPfnEntry(Pfn)) Mdl->MdlFlags |= MDL_IO_SPACE;
486 }
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
int WINAPI EndPage(_In_ HDC)
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define MDL_IO_SPACE
Definition: mmtypes.h:29
ULONG * PPFN_NUMBER
Definition: ke.h:8
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
smooth NULL
Definition: ftsmooth.c:416
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
void * PVOID
Definition: retypes.h:9
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
#define MDL_PARTIAL
Definition: mmtypes.h:22
#define PFN_FROM_PTE(v)
Definition: mm.h:89

Referenced by CdRomAllocateMmcResources(), CdRomDeviceControlDvdSendKey(), CdRomDeviceControlDvdStartSessionReadKey(), CdRomSetVolumeIntermediateCompletion(), CdRomStartIo(), CdRomUpdateCapacity(), ClasspInitializeGesn(), ClassSendSrbAsynchronous(), CUSBDevice::CreateDeviceDescriptor(), CreateDMA(), DiskInfoExceptionCheck(), Ext2CreateMdl(), FatBuildZeroMdl(), CUSBDevice::GetConfigurationDescriptor(), KbdHid_StartDevice(), MouHid_StartDevice(), NdisAllocateBuffer(), prepare_raid0_write(), prepare_raid10_write(), prepare_raid5_write(), prepare_raid6_write(), read_data(), ScsiCdRomStartIo(), ScsiClassSendSrbAsynchronous(), CUSBDevice::SubmitSetupPacket(), TestMmBuildMdlForNonPagedPool(), TestProviderInfo(), ToshibaProcessError(), 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 382 of file mdlsup.c.

385 {
386  SIZE_T Size;
387 
388  //
389  // Check if we don't have an MDL built
390  //
391  if (!Mdl)
392  {
393  //
394  // Calculate the size we'll need and allocate the MDL
395  //
398  if (!Mdl) return NULL;
399  }
400 
401  //
402  // Initialize it
403  //
404  MmInitializeMdl(Mdl, Base, Length);
405  return Mdl;
406 }
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
smooth NULL
Definition: ftsmooth.c:416
#define TAG_MDL
Definition: tag.h:86
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
SIZE_T NTAPI MmSizeOfMdl(IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:413
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
ULONG_PTR SIZE_T
Definition: typedefs.h:78

Referenced by MiAllocatePagesForMdl().

◆ MmFreePagesFromMdl()

VOID NTAPI MmFreePagesFromMdl ( IN PMDL  Mdl)

Definition at line 568 of file mdlsup.c.

569 {
570  PVOID Base;
571  PPFN_NUMBER Pages;
572  LONG NumberOfPages;
573  PMMPFN Pfn1;
574  KIRQL OldIrql;
575  DPRINT("Freeing MDL: %p\n", Mdl);
576 
577  //
578  // Sanity checks
579  //
581  ASSERT((Mdl->MdlFlags & MDL_IO_SPACE) == 0);
582  ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0);
583 
584  //
585  // Get address and page information
586  //
587  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
588  NumberOfPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
589 
590  //
591  // Acquire PFN lock
592  //
594 
595  //
596  // Loop all the MDL pages
597  //
598  Pages = (PPFN_NUMBER)(Mdl + 1);
599  do
600  {
601  //
602  // Reached the last page
603  //
604  if (*Pages == LIST_HEAD) break;
605 
606  //
607  // Get the page entry
608  //
609  Pfn1 = MiGetPfnEntry(*Pages);
610  ASSERT(Pfn1);
611  ASSERT(Pfn1->u2.ShareCount == 1);
612  ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE);
613  if (Pfn1->u4.PteFrame != 0x1FFEDCB)
614  {
615  /* Corrupted PFN entry or invalid free */
616  KeBugCheckEx(MEMORY_MANAGEMENT, 0x1236, (ULONG_PTR)Mdl, (ULONG_PTR)Pages, *Pages);
617  }
618 
619  //
620  // Clear it
621  //
622  Pfn1->u3.e1.StartOfAllocation = 0;
623  Pfn1->u3.e1.EndOfAllocation = 0;
625  Pfn1->u2.ShareCount = 0;
626 
627  //
628  // Dereference it
629  //
630  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
631  if (Pfn1->u3.e2.ReferenceCount != 1)
632  {
633  /* Just take off one reference */
634  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
635  }
636  else
637  {
638  /* We'll be nuking the whole page */
639  MiDecrementReferenceCount(Pfn1, *Pages);
640  }
641 
642  //
643  // Clear this page and move on
644  //
645  *Pages++ = LIST_HEAD;
646  } while (--NumberOfPages != 0);
647 
648  //
649  // Release the lock
650  //
652 
653  //
654  // Remove the pages locked flag
655  //
656  Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
657 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
struct _MMPFN::@1748::@1754 e2
#define TRUE
Definition: types.h:120
union _MMPFN::@1747 u2
signed short * PSHORT
Definition: retypes.h:6
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
USHORT PageLocation
Definition: mm.h:297
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define MDL_IO_SPACE
Definition: mmtypes.h:29
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:329
ULONG * PPFN_NUMBER
Definition: ke.h:8
ULONG_PTR ShareCount
Definition: mm.h:322
long LONG
Definition: pedump.c:60
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
union _MMPFN::@1748 u3
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:199
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1222
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: mm.h:305
#define PAGE_SIZE
Definition: env_spec_w32.h:49
LIST_HEAD(acpi_bus_event_list)
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
#define InterlockedDecrement16
Definition: interlocked.h:139
ULONG_PTR PteFrame
Definition: mm.h:350
#define APC_LEVEL
Definition: env_spec_w32.h:695
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:107
union _MMPFN::@1751 u4

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

◆ MmMapLockedPages()

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

Definition at line 822 of file mdlsup.c.

824 {
825  //
826  // Call the extended version
827  //
828  return MmMapLockedPagesSpecifyCache(Mdl,
829  AccessMode,
830  MmCached,
831  NULL,
832  TRUE,
834 }
#define TRUE
Definition: types.h:120
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
smooth NULL
Definition: ftsmooth.c:416
PVOID NTAPI MmMapLockedPagesSpecifyCache(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN MEMORY_CACHING_TYPE CacheType, IN PVOID BaseAddress, IN ULONG BugCheckOnFailure, IN MM_PAGE_PRIORITY Priority)
Definition: mdlsup.c:664

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 MM_PAGE_PRIORITY  Priority 
)

Definition at line 664 of file mdlsup.c.

670 {
671  PVOID Base;
672  PPFN_NUMBER MdlPages, LastPage;
673  PFN_COUNT PageCount;
674  BOOLEAN IsIoMapping;
675  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
676  PMMPTE PointerPte;
677  MMPTE TempPte;
678 
679  //
680  // Sanity check
681  //
682  ASSERT(Mdl->ByteCount != 0);
683 
684  //
685  // Get the base
686  //
687  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
688 
689  //
690  // Handle kernel case first
691  //
692  if (AccessMode == KernelMode)
693  {
694  //
695  // Get the list of pages and count
696  //
697  MdlPages = (PPFN_NUMBER)(Mdl + 1);
698  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
699  LastPage = MdlPages + PageCount;
700 
701  //
702  // Sanity checks
703  //
704  ASSERT((Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
707  ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED | MDL_PARTIAL)) != 0);
708 
709  //
710  // Get the correct cache type
711  //
712  IsIoMapping = (Mdl->MdlFlags & MDL_IO_SPACE) != 0;
713  CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType];
714 
715  //
716  // Reserve the PTEs
717  //
718  PointerPte = MiReserveSystemPtes(PageCount, SystemPteSpace);
719  if (!PointerPte)
720  {
721  //
722  // If it can fail, return NULL
723  //
724  if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL) return NULL;
725 
726  //
727  // Should we bugcheck?
728  //
729  if (!BugCheckOnFailure) return NULL;
730 
731  //
732  // Yes, crash the system
733  //
734  KeBugCheckEx(NO_MORE_SYSTEM_PTES, 0, PageCount, 0, 0);
735  }
736 
737  //
738  // Get the mapped address
739  //
740  Base = (PVOID)((ULONG_PTR)MiPteToAddress(PointerPte) + Mdl->ByteOffset);
741 
742  //
743  // Get the template
744  //
746  switch (CacheAttribute)
747  {
748  case MiNonCached:
749 
750  //
751  // Disable caching
752  //
755  break;
756 
757  case MiWriteCombined:
758 
759  //
760  // Enable write combining
761  //
764  break;
765 
766  default:
767  //
768  // Nothing to do
769  //
770  break;
771  }
772 
773  //
774  // Loop all PTEs
775  //
776  do
777  {
778  //
779  // We're done here
780  //
781  if (*MdlPages == LIST_HEAD) break;
782 
783  //
784  // Write the PTE
785  //
786  TempPte.u.Hard.PageFrameNumber = *MdlPages;
787  MI_WRITE_VALID_PTE(PointerPte++, TempPte);
788  } while (++MdlPages < LastPage);
789 
790  //
791  // Mark it as mapped
792  //
793  ASSERT((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0);
794  Mdl->MappedSystemVa = Base;
795  Mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
796 
797  //
798  // Check if it was partial
799  //
800  if (Mdl->MdlFlags & MDL_PARTIAL)
801  {
802  //
803  // Write the appropriate flag here too
804  //
805  Mdl->MdlFlags |= MDL_PARTIAL_HAS_BEEN_MAPPED;
806  }
807 
808  //
809  // Return the mapped address
810  //
811  return Base;
812  }
813 
815 }
#define MI_PAGE_WRITE_COMBINED(x)
Definition: mm.h:100
ULONG PFN_COUNT
Definition: mmtypes.h:102
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define MDL_IO_SPACE
Definition: mmtypes.h:29
ULONG * PPFN_NUMBER
Definition: ke.h:8
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:951
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType]
Definition: iosup.c:27
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
#define MDL_MAPPING_CAN_FAIL
Definition: mmtypes.h:31
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS _In_ MEMORY_CACHING_TYPE CacheType
Definition: mmfuncs.h:214
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
void * PVOID
Definition: retypes.h:9
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
static PVOID NTAPI MiMapLockedPagesInUserSpace(_In_ PMDL Mdl, _In_ PVOID StartVa, _In_ MEMORY_CACHING_TYPE CacheType, _In_opt_ PVOID BaseAddress)
Definition: mdlsup.c:30
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
MMPTE ValidKernelPte
Definition: init.c:29
#define MI_PAGE_WRITE_THROUGH(x)
Definition: mm.h:99
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
LIST_HEAD(acpi_bus_event_list)
#define MDL_PARTIAL_HAS_BEEN_MAPPED
Definition: mmtypes.h:23
#define MI_PAGE_DISABLE_CACHE(x)
Definition: mm.h:98
#define MDL_PARTIAL
Definition: mmtypes.h:22
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:107
ULONG PageFrameNumber
Definition: mmtypes.h:109

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 1633 of file mdlsup.c.

1637 {
1638  UNIMPLEMENTED;
1639  return 0;
1640 }
#define UNIMPLEMENTED
Definition: debug.h:114

Referenced by TestMap().

◆ MmMapMemoryDumpMdl()

VOID NTAPI MmMapMemoryDumpMdl ( IN PMDL  Mdl)

Definition at line 1710 of file mdlsup.c.

1711 {
1712  UNIMPLEMENTED;
1713 }
#define UNIMPLEMENTED
Definition: debug.h:114

◆ MmPrefetchPages()

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

Definition at line 1659 of file mdlsup.c.

1661 {
1662  UNIMPLEMENTED;
1663  return STATUS_NOT_IMPLEMENTED;
1664 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define UNIMPLEMENTED
Definition: debug.h:114

Referenced by FatPrefetchPages().

◆ MmProbeAndLockPages()

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

Definition at line 935 of file mdlsup.c.

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

Referenced by add_thread_job(), AfdGetSockName(), BuildAndSubmitIrp(), BuildDeviceInputMdl(), CcReadVirtualAddress(), CcWriteVirtualAddress(), CdCreateUserMdl(), ClassSendDeviceIoControlSynchronous(), ClassSendSrbSynchronous(), DispTdiQueryInformationEx(), DriverIoControl(), ExLockUserBuffer(), Ext2CreateMdl(), Ext2LockUserBuffer(), FatLockUserBuffer(), FatSingleNonAlignedSync(), FFSLockUserBuffer(), HackSecureVirtualMemory(), IoBuildAsynchronousFsdRequest(), IoBuildDeviceIoControlRequest(), IopDeviceFsIoControl(), KsProbeStreamIrp(), LockBuffers(), LockRequest(), MapAndLockUserBuffer(), MiDoMappedCopy(), MupBuildIoControlRequest(), nfs41_QueryDirectory(), NtfsLockUserBuffer(), NtQueryDirectoryFile(), NtReadFile(), NtStartProfile(), NtWriteFile(), prepare_raid0_write(), prepare_raid10_write(), prepare_raid5_write(), prepare_raid6_write(), read_data(), RfsdLockUserBuffer(), RxLockUserBuffer(), scrub_chunk_raid56_stripe_run(), scrub_extent(), sync_read_phys(), TdiQueryMaxDatagramLength(), TdiReceive(), TdiReceiveDatagram(), TdiSend(), TdiSendDatagram(), TestMessageHandler(), UDFGetCallersBuffer(), UDFLockCallersBuffer(), VfatLockUserBuffer(), VideoPortLockBuffer(), write_data(), write_data_phys(), and write_file2().

◆ MmProbeAndLockProcessPages()

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

Definition at line 1683 of file mdlsup.c.

1687 {
1688  UNIMPLEMENTED;
1689 }
#define UNIMPLEMENTED
Definition: debug.h:114

◆ MmProbeAndLockSelectedPages()

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

Definition at line 1697 of file mdlsup.c.

1701 {
1702  UNIMPLEMENTED;
1703 }
#define UNIMPLEMENTED
Definition: debug.h:114

◆ MmProtectMdlSystemAddress()

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

Definition at line 1671 of file mdlsup.c.

1673 {
1674  UNIMPLEMENTED;
1675  return STATUS_NOT_IMPLEMENTED;
1676 }
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
#define UNIMPLEMENTED
Definition: debug.h:114

◆ MmSizeOfMdl()

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

Definition at line 413 of file mdlsup.c.

415 {
416  //
417  // Return the MDL size
418  //
419  return sizeof(MDL) +
421 }
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
ULONG PFN_NUMBER
Definition: ke.h:8
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
MDL
Definition: mmtypes.h:117

Referenced by CcZeroData(), and MmCreateMdl().

◆ MmUnlockPages()

VOID NTAPI MmUnlockPages ( IN PMDL  Mdl)

Definition at line 1439 of file mdlsup.c.

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

Referenced by _Function_class_(), CcMdlReadComplete2(), CcReadVirtualAddress(), CcWriteVirtualAddress(), ClassAsynchronousCompletion(), ClassCompletionRoutine(), ClasspSendSynchronousCompletion(), ClassSendDeviceIoControlSynchronous(), CommonForwardedIoCompletionRoutine(), DispTdiQueryInformationEx(), DispTdiQueryInformationExComplete(), DriverCleanup(), DriverIoControl(), ExpDeleteProfile(), Ext2DestroyMdl(), ExUnlockUserBuffer(), FatSingleNonAlignedSync(), free_write_data_stripes(), FreeDeviceInputMdl(), HackSecureVirtualMemory(), HackUnsecureVirtualMemory(), IoCompletion(), IofCompleteRequest(), LockRequest(), MiDoMappedCopy(), MmProbeAndLockPages(), nfs41_QueryDirectory(), NtStopProfile(), read_data(), scrub_chunk_raid56_stripe_run(), scrub_extent(), ScsiClassAsynchronousCompletion(), SpiCompletionRoutine(), sync_read_phys(), TestCleanEverything(), UDFAsyncCompletionRoutine(), UnlockBuffers(), UnlockRequest(), VideoPortUnlockBuffer(), write_data(), write_data_phys(), write_file2(), and write_superblocks().

◆ MmUnmapLockedPages()

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

Definition at line 841 of file mdlsup.c.

843 {
844  PVOID Base;
845  PFN_COUNT PageCount, ExtraPageCount;
846  PPFN_NUMBER MdlPages;
847  PMMPTE PointerPte;
848 
849  //
850  // Sanity check
851  //
852  ASSERT(Mdl->ByteCount != 0);
853 
854  //
855  // Check if this is a kernel request
856  //
858  {
859  //
860  // Get base and count information
861  //
862  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
863  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
864 
865  //
866  // Sanity checks
867  //
868  ASSERT((Mdl->MdlFlags & MDL_PARENT_MAPPED_SYSTEM_VA) == 0);
869  ASSERT(PageCount != 0);
870  ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
871 
872  //
873  // Get the PTE
874  //
875  PointerPte = MiAddressToPte(BaseAddress);
876 
877  //
878  // This should be a resident system PTE
879  //
880  ASSERT(PointerPte >= MmSystemPtesStart[SystemPteSpace]);
881  ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
882  ASSERT(PointerPte->u.Hard.Valid == 1);
883 
884  //
885  // Check if the caller wants us to free advanced pages
886  //
887  if (Mdl->MdlFlags & MDL_FREE_EXTRA_PTES)
888  {
889  //
890  // Get the MDL page array
891  //
892  MdlPages = MmGetMdlPfnArray(Mdl);
893 
894  /* Number of extra pages stored after the PFN array */
895  ExtraPageCount = (PFN_COUNT)*(MdlPages + PageCount);
896 
897  //
898  // Do the math
899  //
900  PageCount += ExtraPageCount;
901  PointerPte -= ExtraPageCount;
902  ASSERT(PointerPte >= MmSystemPtesStart[SystemPteSpace]);
903  ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
904 
905  //
906  // Get the new base address
907  //
909  (ExtraPageCount << PAGE_SHIFT));
910  }
911 
912  //
913  // Remove flags
914  //
915  Mdl->MdlFlags &= ~(MDL_MAPPED_TO_SYSTEM_VA |
918 
919  //
920  // Release the system PTEs
921  //
922  MiReleaseSystemPtes(PointerPte, PageCount, SystemPteSpace);
923  }
924  else
925  {
927  }
928 }
#define MM_HIGHEST_USER_ADDRESS
Definition: armddk.h:17
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
static VOID NTAPI MiUnmapLockedPagesInUserSpace(_In_ PVOID BaseAddress, _In_ PMDL Mdl)
Definition: mdlsup.c:284
#define MmGetMdlPfnArray(_Mdl)
PMMPTE MmSystemPtesEnd[MaximumPtePoolTypes]
Definition: syspte.c:23
ULONG PFN_COUNT
Definition: mmtypes.h:102
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2343
union _MMPTE::@2255 u
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG * PPFN_NUMBER
Definition: ke.h:8
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MDL_FREE_EXTRA_PTES
Definition: mmtypes.h:27
#define MDL_PARENT_MAPPED_SYSTEM_VA
Definition: mmtypes.h:26
void * PVOID
Definition: retypes.h:9
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:275
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
PMMPTE MmSystemPtesStart[MaximumPtePoolTypes]
Definition: syspte.c:22
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG64 Valid
Definition: mmtypes.h:150
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define MDL_PARTIAL_HAS_BEEN_MAPPED
Definition: mmtypes.h:23
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217

Referenced by CcZeroData(), ExpDeleteProfile(), free_buffer_head(), MiDoMappedCopy(), MiReadFilePage(), MiReadPageFile(), 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 1647 of file mdlsup.c.

1650 {
1651  UNIMPLEMENTED;
1652 }
#define UNIMPLEMENTED
Definition: debug.h:114

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.