ReactOS  0.4.15-dev-4614-ga5a6101
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;
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,
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 
162  if (!NT_SUCCESS(Status))
163  goto Error;
164 
165  /* Check if this is uncached */
166  if (CacheAttribute != MiCached)
167  {
168  /* Flush all caches */
171  }
172 
173  PointerPte = MiAddressToPte(BaseAddress);
174  while (NumberOfPages != 0 &&
175  *MdlPages != LIST_HEAD)
176  {
177  PointerPde = MiPteToPde(PointerPte);
179  ASSERT(PointerPte->u.Hard.Valid == 0);
180 
181  /* Add a PDE reference for each page */
183 
184  /* Set up our basic user PTE */
186  PointerPte,
187  MM_READWRITE,
188  *MdlPages);
189 
190  EffectiveCacheAttribute = CacheAttribute;
191 
192  /* We need to respect the PFN's caching information in some cases */
193  Pfn2 = MiGetPfnEntry(*MdlPages);
194  if (Pfn2 != NULL)
195  {
196  ASSERT(Pfn2->u3.e2.ReferenceCount != 0);
197 
198  switch (Pfn2->u3.e1.CacheAttribute)
199  {
200  case MiNonCached:
201  if (CacheAttribute != MiNonCached)
202  {
203  MiCacheOverride[1]++;
204  EffectiveCacheAttribute = MiNonCached;
205  }
206  break;
207 
208  case MiCached:
209  if (CacheAttribute != MiCached)
210  {
211  MiCacheOverride[0]++;
212  EffectiveCacheAttribute = MiCached;
213  }
214  break;
215 
216  case MiWriteCombined:
217  if (CacheAttribute != MiWriteCombined)
218  {
219  MiCacheOverride[2]++;
220  EffectiveCacheAttribute = MiWriteCombined;
221  }
222  break;
223 
224  default:
225  /* We don't support AWE magic (MiNotMapped) */
226  DPRINT1("FIXME: MiNotMapped is not supported\n");
227  ASSERT(FALSE);
228  break;
229  }
230  }
231 
232  /* Configure caching */
233  switch (EffectiveCacheAttribute)
234  {
235  case MiNonCached:
238  break;
239  case MiCached:
240  break;
241  case MiWriteCombined:
244  break;
245  default:
246  ASSERT(FALSE);
247  break;
248  }
249 
250  /* Make the page valid */
251  MI_WRITE_VALID_PTE(PointerPte, TempPte);
252 
253  /* Acquire a share count */
254  Pfn1 = MI_PFN_ELEMENT(PointerPde->u.Hard.PageFrameNumber);
255  DPRINT("Incrementing %p from %p\n", Pfn1, _ReturnAddress());
256  OldIrql = MiAcquirePfnLock();
257  Pfn1->u2.ShareCount++;
258  MiReleasePfnLock(OldIrql);
259 
260  /* Next page */
261  MdlPages++;
262  PointerPte++;
263  NumberOfPages--;
265  }
266 
268  ASSERT(AddressSpaceLocked);
270 
271  ASSERT(StartingVa != 0);
272  return (PVOID)((ULONG_PTR)StartingVa + MmGetMdlByteOffset(Mdl));
273 
274 Error:
275  if (AddressSpaceLocked)
276  {
278  }
279  if (Vad != NULL)
280  {
281  ExFreePoolWithTag(Vad, 'ldaV');
282  }
284 }
ULONG_PTR EndingVpn
Definition: mmtypes.h:756
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:102
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1244
NTSTATUS NTAPI PsChargeProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the non paged pool quota of a given process.
Definition: quota.c:811
#define MI_PAGE_WRITE_COMBINED(x)
Definition: mm.h:103
#define MmGetMdlPfnArray(_Mdl)
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define TRUE
Definition: types.h:120
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1639
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:760
enum _TABLE_SEARCH_RESULT TABLE_SEARCH_RESULT
LONG NTSTATUS
Definition: precomp.h:26
#define MM_READWRITE
Definition: bootanim.c:19
#define ExRaiseStatus
Definition: ntoskrnl.h:108
ULONG_PTR Protection
Definition: mmtypes.h:693
ULONG LongVad
Definition: mmtypes.h:708
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 PMMPDE MiPteToPde(PMMPTE PointerPte)
Definition: mm.h:268
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MDL_IO_SPACE
Definition: mmtypes.h:29
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:397
union _MMPFN::@1752 u2
ULONG * PPFN_NUMBER
Definition: ke.h:9
USHORT CacheAttribute
Definition: mm.h:367
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MM_NOIRQL
Definition: mm.h:70
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
ULONG_PTR ShareCount
Definition: mm.h:390
union _MMVAD_LONG::@2569 u2
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:2470
_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 * 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:438
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
Status
Definition: gdiplustypes.h:24
BOOLEAN NTAPI KeInvalidateAllCaches(VOID)
Definition: cpu.c:484
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1174
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG_PTR PrivateMemory
Definition: mmtypes.h:695
#define ASSERT(a)
Definition: mode.c:44
ULONG MiCacheOverride[MiNotMapped+1]
Definition: mdlsup.c:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG64 Valid
Definition: mmtypes.h:150
ULONG_PTR StartingVpn
Definition: mmtypes.h:755
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:768
BOOL Error
Definition: chkdsk.c:66
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define MI_PAGE_WRITE_THROUGH(x)
Definition: mm.h:102
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
FORCEINLINE USHORT MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2478
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1579
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
Definition: mm.h:373
#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:1020
union _MMPFN::@1753 u3
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:832
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:557
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define MmGetMdlByteCount(_Mdl)
#define MI_PAGE_DISABLE_CACHE(x)
Definition: mm.h:101
#define NULL
Definition: types.h:112
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
#define DPRINT1
Definition: precomp.h:8
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:46
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
void * _ReturnAddress(void)
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
struct _MMPFN::@1753::@1759 e2
#define MmGetMdlByteOffset(_Mdl)
union _MMPTE::@2284 u
VOID NTAPI MiInsertVad(_Inout_ PMMVAD Vad, _Inout_ PMM_AVL_TABLE VadRoot)
union _MMVAD_LONG::@2568 u
#define DPRINT
Definition: sndvol32.h:71
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1632
#define BYTE_OFFSET(Va)
ULONG_PTR VadType
Definition: mmtypes.h:691
#define PAGED_CODE()

Referenced by MmMapLockedPagesSpecifyCache().

◆ MiUnmapLockedPagesInUserSpace()

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

Definition at line 289 of file mdlsup.c.

292 {
295  PMMVAD Vad;
296  PMMPTE PointerPte;
297  PMMPDE PointerPde;
298  KIRQL OldIrql;
299  ULONG NumberOfPages;
300  PPFN_NUMBER MdlPages;
301  PFN_NUMBER PageTablePage;
302 
303  DPRINT("MiUnmapLockedPagesInUserSpace(%p, %p)\n", BaseAddress, Mdl);
304 
307  ASSERT(NumberOfPages != 0);
308  MdlPages = MmGetMdlPfnArray(Mdl);
309 
310  /* Find the VAD */
313  if (!Vad ||
315  {
316  DPRINT1("MiUnmapLockedPagesInUserSpace invalid for %p\n", BaseAddress);
318  return;
319  }
320 
322 
323  /* Remove it from the process VAD tree */
324  ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
325  MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
327 
328  /* MiRemoveNode should have removed us if we were the hint */
329  ASSERT(Process->VadRoot.NodeHint != Vad);
330 
331  PointerPte = MiAddressToPte(BaseAddress);
332  OldIrql = MiAcquirePfnLock();
333  while (NumberOfPages != 0 &&
334  *MdlPages != LIST_HEAD)
335  {
336  ASSERT(MiAddressToPte(PointerPte)->u.Hard.Valid == 1);
337  ASSERT(PointerPte->u.Hard.Valid == 1);
338 
339  /* Invalidate it */
340  MI_ERASE_PTE(PointerPte);
341 
342  /* We invalidated this PTE, so dereference the PDE */
343  PointerPde = MiAddressToPde(BaseAddress);
344  PageTablePage = PointerPde->u.Hard.PageFrameNumber;
345  MiDecrementShareCount(MiGetPfnEntry(PageTablePage), PageTablePage);
346 
348  {
349  ASSERT(MiIsPteOnPdeBoundary(PointerPte + 1) || (NumberOfPages == 1));
350  MiDeletePde(PointerPde, Process);
351  }
352 
353  /* Next page */
354  PointerPte++;
355  NumberOfPages--;
357  MdlPages++;
358  }
359 
361  MiReleasePfnLock(OldIrql);
364  ExFreePoolWithTag(Vad, 'ldaV');
365 }
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:1011
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1244
#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:1639
FORCEINLINE USHORT MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2504
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:731
uint32_t ULONG_PTR
Definition: typedefs.h:65
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG * PPFN_NUMBER
Definition: ke.h:9
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:48
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:1174
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define ASSERT(a)
Definition: mode.c:44
ULONG64 Valid
Definition: mmtypes.h:150
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
#define PAGE_SIZE
Definition: env_spec_w32.h:49
FORCEINLINE VOID MiDeletePde(_In_ PMMPDE PointerPde, _In_ PEPROCESS CurrentProcess)
Definition: miarm.h:2538
LIST_HEAD(acpi_bus_event_list)
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1020
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:360
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MiIsPteOnPdeBoundary(PointerPte)
Definition: mm.h:306
#define MmGetMdlByteCount(_Mdl)
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
union _MMVAD::@2565 u
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE VOID KeFlushProcessTb(VOID)
Definition: ke.h:268
_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
union _MMPTE::@2284 u
#define DPRINT
Definition: sndvol32.h:71
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
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1632
ULONG_PTR VadType
Definition: mmtypes.h:691

Referenced by MmUnmapLockedPages().

◆ MmAdvanceMdl()

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

Definition at line 1613 of file mdlsup.c.

1615 {
1616  UNIMPLEMENTED;
1617  return STATUS_NOT_IMPLEMENTED;
1618 }
return STATUS_NOT_IMPLEMENTED
#define UNIMPLEMENTED
Definition: debug.h:115

◆ MmAllocatePagesForMdl()

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

Definition at line 485 of file mdlsup.c.

489 {
490  //
491  // Call the internal routine
492  //
493  return MiAllocatePagesForMdl(LowAddress,
494  HighAddress,
495  SkipBytes,
496  TotalBytes,
497  MiNotMapped,
498  0);
499 }
_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:182
_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 506 of file mdlsup.c.

512 {
513  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
514 
515  //
516  // Check for invalid cache type
517  //
519  {
520  //
521  // Normalize to default
522  //
523  CacheAttribute = MiNotMapped;
524  }
525  else
526  {
527  //
528  // Conver to internal caching attribute
529  //
530  CacheAttribute = MiPlatformCacheAttributes[FALSE][CacheType];
531  }
532 
533  //
534  // Only these flags are allowed
535  //
537  {
538  //
539  // Silently fail
540  //
541  return NULL;
542  }
543 
544  //
545  // Call the internal routine
546  //
547  return MiAllocatePagesForMdl(LowAddress,
548  HighAddress,
549  SkipBytes,
550  TotalBytes,
551  CacheAttribute,
552  Flags);
553 }
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
#define FALSE
Definition: types.h:117
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType]
Definition: iosup.c:27
_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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define MM_ALLOCATE_FROM_LOCAL_NODE_ONLY
Definition: mmtypes.h:12
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
#define NULL
Definition: types.h:112
#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:182
_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 420 of file mdlsup.c.

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

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

377 {
378  SIZE_T Size;
379 
380  //
381  // Check if we don't have an MDL built
382  //
383  if (!Mdl)
384  {
385  //
386  // Calculate the size we'll need and allocate the MDL
387  //
390  if (!Mdl) return NULL;
391  }
392 
393  //
394  // Initialize it
395  //
397  return Mdl;
398 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define TAG_MDL
Definition: tag.h:86
#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:405
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define NULL
Definition: types.h:112
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl

Referenced by MiAllocatePagesForMdl().

◆ MmFreePagesFromMdl()

VOID NTAPI MmFreePagesFromMdl ( IN PMDL  Mdl)

Definition at line 560 of file mdlsup.c.

561 {
562  PVOID Base;
563  PPFN_NUMBER Pages;
564  LONG NumberOfPages;
565  PMMPFN Pfn1;
566  KIRQL OldIrql;
567  DPRINT("Freeing MDL: %p\n", Mdl);
568 
569  //
570  // Sanity checks
571  //
573  ASSERT((Mdl->MdlFlags & MDL_IO_SPACE) == 0);
574  ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0);
575 
576  //
577  // Get address and page information
578  //
579  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
580  NumberOfPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
581 
582  //
583  // Acquire PFN lock
584  //
585  OldIrql = MiAcquirePfnLock();
586 
587  //
588  // Loop all the MDL pages
589  //
590  Pages = (PPFN_NUMBER)(Mdl + 1);
591  do
592  {
593  //
594  // Reached the last page
595  //
596  if (*Pages == LIST_HEAD) break;
597 
598  //
599  // Get the page entry
600  //
601  Pfn1 = MiGetPfnEntry(*Pages);
602  ASSERT(Pfn1);
603  ASSERT(Pfn1->u2.ShareCount == 1);
604  ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE);
605  if (Pfn1->u4.PteFrame != 0x1FFEDCB)
606  {
607  /* Corrupted PFN entry or invalid free */
608  KeBugCheckEx(MEMORY_MANAGEMENT, 0x1236, (ULONG_PTR)Mdl, (ULONG_PTR)Pages, *Pages);
609  }
610 
611  //
612  // Clear it
613  //
614  Pfn1->u3.e1.StartOfAllocation = 0;
615  Pfn1->u3.e1.EndOfAllocation = 0;
617  Pfn1->u2.ShareCount = 0;
618 
619  //
620  // Dereference it
621  //
622  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
623  if (Pfn1->u3.e2.ReferenceCount != 1)
624  {
625  /* Just take off one reference */
626  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
627  }
628  else
629  {
630  /* We'll be nuking the whole page */
631  MiDecrementReferenceCount(Pfn1, *Pages);
632  }
633 
634  //
635  // Clear this page and move on
636  //
637  *Pages++ = LIST_HEAD;
638  } while (--NumberOfPages != 0);
639 
640  //
641  // Release the lock
642  //
643  MiReleasePfnLock(OldIrql);
644 
645  //
646  // Remove the pages locked flag
647  //
648  Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
649 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
signed short * PSHORT
Definition: retypes.h:6
#define TRUE
Definition: types.h:120
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
union _MMPFN::@1756 u4
USHORT PageLocation
Definition: mm.h:365
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MDL_IO_SPACE
Definition: mmtypes.h:29
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:397
union _MMPFN::@1752 u2
ULONG * PPFN_NUMBER
Definition: ke.h:9
ULONG_PTR ShareCount
Definition: mm.h:390
long LONG
Definition: pedump.c:60
void * PVOID
Definition: retypes.h:9
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
#define ASSERT(a)
Definition: mode.c:44
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:195
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1224
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
Definition: mm.h:373
#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:1020
union _MMPFN::@1753 u3
#define InterlockedDecrement16
Definition: interlocked.h:139
ULONG_PTR PteFrame
Definition: mm.h:418
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
struct _MMPFN::@1753::@1759 e2
#define DPRINT
Definition: sndvol32.h:71
#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:108

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

◆ MmMapLockedPages()

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

Definition at line 814 of file mdlsup.c.

816 {
817  //
818  // Call the extended version
819  //
821  AccessMode,
822  MmCached,
823  NULL,
824  TRUE,
826 }
#define TRUE
Definition: types.h:120
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:656
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
#define NULL
Definition: types.h:112
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl

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

662 {
663  PVOID Base;
664  PPFN_NUMBER MdlPages, LastPage;
665  PFN_COUNT PageCount;
666  BOOLEAN IsIoMapping;
667  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
668  PMMPTE PointerPte;
669  MMPTE TempPte;
670 
671  //
672  // Sanity check
673  //
674  ASSERT(Mdl->ByteCount != 0);
675 
676  //
677  // Get the base
678  //
679  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
680 
681  //
682  // Handle kernel case first
683  //
684  if (AccessMode == KernelMode)
685  {
686  //
687  // Get the list of pages and count
688  //
689  MdlPages = (PPFN_NUMBER)(Mdl + 1);
690  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
691  LastPage = MdlPages + PageCount;
692 
693  //
694  // Sanity checks
695  //
696  ASSERT((Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
699  ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED | MDL_PARTIAL)) != 0);
700 
701  //
702  // Get the correct cache type
703  //
704  IsIoMapping = (Mdl->MdlFlags & MDL_IO_SPACE) != 0;
705  CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType];
706 
707  //
708  // Reserve the PTEs
709  //
710  PointerPte = MiReserveSystemPtes(PageCount, SystemPteSpace);
711  if (!PointerPte)
712  {
713  //
714  // If it can fail, return NULL
715  //
716  if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL) return NULL;
717 
718  //
719  // Should we bugcheck?
720  //
721  if (!BugCheckOnFailure) return NULL;
722 
723  //
724  // Yes, crash the system
725  //
726  KeBugCheckEx(NO_MORE_SYSTEM_PTES, 0, PageCount, 0, 0);
727  }
728 
729  //
730  // Get the mapped address
731  //
732  Base = (PVOID)((ULONG_PTR)MiPteToAddress(PointerPte) + Mdl->ByteOffset);
733 
734  //
735  // Get the template
736  //
738  switch (CacheAttribute)
739  {
740  case MiNonCached:
741 
742  //
743  // Disable caching
744  //
747  break;
748 
749  case MiWriteCombined:
750 
751  //
752  // Enable write combining
753  //
756  break;
757 
758  default:
759  //
760  // Nothing to do
761  //
762  break;
763  }
764 
765  //
766  // Loop all PTEs
767  //
768  do
769  {
770  //
771  // We're done here
772  //
773  if (*MdlPages == LIST_HEAD) break;
774 
775  //
776  // Write the PTE
777  //
778  TempPte.u.Hard.PageFrameNumber = *MdlPages;
779  MI_WRITE_VALID_PTE(PointerPte++, TempPte);
780  } while (++MdlPages < LastPage);
781 
782  //
783  // Mark it as mapped
784  //
785  ASSERT((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0);
786  Mdl->MappedSystemVa = Base;
787  Mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
788 
789  //
790  // Check if it was partial
791  //
792  if (Mdl->MdlFlags & MDL_PARTIAL)
793  {
794  //
795  // Write the appropriate flag here too
796  //
797  Mdl->MdlFlags |= MDL_PARTIAL_HAS_BEEN_MAPPED;
798  }
799 
800  //
801  // Return the mapped address
802  //
803  return Base;
804  }
805 
807 }
#define MI_PAGE_WRITE_COMBINED(x)
Definition: mm.h:103
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:2386
#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:65
#define MDL_IO_SPACE
Definition: mmtypes.h:29
ULONG * PPFN_NUMBER
Definition: ke.h:9
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType]
Definition: iosup.c:27
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
#define MDL_MAPPING_CAN_FAIL
Definition: mmtypes.h:31
unsigned char BOOLEAN
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS _In_ MEMORY_CACHING_TYPE CacheType
Definition: mmfuncs.h:214
#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 ASSERT(a)
Definition: mode.c:44
#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:102
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:101
#define NULL
Definition: types.h:112
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
#define MDL_PARTIAL
Definition: mmtypes.h:22
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
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
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 1625 of file mdlsup.c.

1629 {
1630  UNIMPLEMENTED;
1631  return 0;
1632 }
#define UNIMPLEMENTED
Definition: debug.h:115

Referenced by TestMap().

◆ MmMapMemoryDumpMdl()

VOID NTAPI MmMapMemoryDumpMdl ( IN PMDL  Mdl)

Definition at line 1702 of file mdlsup.c.

1703 {
1704  UNIMPLEMENTED;
1705 }
#define UNIMPLEMENTED
Definition: debug.h:115

◆ MmPrefetchPages()

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

Definition at line 1651 of file mdlsup.c.

1653 {
1654  UNIMPLEMENTED;
1655  return STATUS_NOT_IMPLEMENTED;
1656 }
return STATUS_NOT_IMPLEMENTED
#define UNIMPLEMENTED
Definition: debug.h:115

Referenced by FatPrefetchPages().

◆ MmProbeAndLockPages()

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

Definition at line 927 of file mdlsup.c.

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

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

1679 {
1680  UNIMPLEMENTED;
1681 }
#define UNIMPLEMENTED
Definition: debug.h:115

◆ MmProbeAndLockSelectedPages()

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

Definition at line 1689 of file mdlsup.c.

1693 {
1694  UNIMPLEMENTED;
1695 }
#define UNIMPLEMENTED
Definition: debug.h:115

◆ MmProtectMdlSystemAddress()

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

Definition at line 1663 of file mdlsup.c.

1665 {
1666  UNIMPLEMENTED;
1667  return STATUS_NOT_IMPLEMENTED;
1668 }
return STATUS_NOT_IMPLEMENTED
#define UNIMPLEMENTED
Definition: debug.h:115

◆ MmSizeOfMdl()

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

Definition at line 405 of file mdlsup.c.

407 {
408  //
409  // Return the MDL size
410  //
411  return sizeof(MDL) +
413 }
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
ULONG PFN_NUMBER
Definition: ke.h:9
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
MDL
Definition: mmtypes.h:117

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

◆ MmUnlockPages()

VOID NTAPI MmUnlockPages ( IN PMDL  Mdl)

Definition at line 1431 of file mdlsup.c.

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

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

835 {
836  PVOID Base;
837  PFN_COUNT PageCount, ExtraPageCount;
838  PPFN_NUMBER MdlPages;
839  PMMPTE PointerPte;
840 
841  //
842  // Sanity check
843  //
844  ASSERT(Mdl->ByteCount != 0);
845 
846  //
847  // Check if this is a kernel request
848  //
850  {
851  //
852  // Get base and count information
853  //
854  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
855  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
856 
857  //
858  // Sanity checks
859  //
860  ASSERT((Mdl->MdlFlags & MDL_PARENT_MAPPED_SYSTEM_VA) == 0);
861  ASSERT(PageCount != 0);
862  ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
863 
864  //
865  // Get the PTE
866  //
867  PointerPte = MiAddressToPte(BaseAddress);
868 
869  //
870  // This should be a resident system PTE
871  //
872  ASSERT(PointerPte >= MmSystemPtesStart[SystemPteSpace]);
873  ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
874  ASSERT(PointerPte->u.Hard.Valid == 1);
875 
876  //
877  // Check if the caller wants us to free advanced pages
878  //
879  if (Mdl->MdlFlags & MDL_FREE_EXTRA_PTES)
880  {
881  //
882  // Get the MDL page array
883  //
884  MdlPages = MmGetMdlPfnArray(Mdl);
885 
886  /* Number of extra pages stored after the PFN array */
887  ExtraPageCount = (PFN_COUNT)*(MdlPages + PageCount);
888 
889  //
890  // Do the math
891  //
892  PageCount += ExtraPageCount;
893  PointerPte -= ExtraPageCount;
894  ASSERT(PointerPte >= MmSystemPtesStart[SystemPteSpace]);
895  ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
896 
897  //
898  // Get the new base address
899  //
901  (ExtraPageCount << PAGE_SHIFT));
902  }
903 
904  //
905  // Remove flags
906  //
907  Mdl->MdlFlags &= ~(MDL_MAPPED_TO_SYSTEM_VA |
910 
911  //
912  // Release the system PTEs
913  //
914  MiReleaseSystemPtes(PointerPte, PageCount, SystemPteSpace);
915  }
916  else
917  {
919  }
920 }
#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:289
#define MmGetMdlPfnArray(_Mdl)
PMMPTE MmSystemPtesEnd[MaximumPtePoolTypes]
Definition: syspte.c:23
ULONG PFN_COUNT
Definition: mmtypes.h:102
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG * PPFN_NUMBER
Definition: ke.h:9
#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:264
#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
#define ASSERT(a)
Definition: mode.c:44
ULONG64 Valid
Definition: mmtypes.h:150
#define MDL_PARTIAL_HAS_BEEN_MAPPED
Definition: mmtypes.h:23
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
union _MMPTE::@2284 u

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

1642 {
1643  UNIMPLEMENTED;
1644 }
#define UNIMPLEMENTED
Definition: debug.h:115

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.