ReactOS  0.4.15-dev-3440-g915569a
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 
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);
251  DPRINT("Incrementing %p from %p\n", Pfn1, _ReturnAddress());
252  OldIrql = MiAcquirePfnLock();
253  Pfn1->u2.ShareCount++;
254  MiReleasePfnLock(OldIrql);
255 
256  /* Next page */
257  MdlPages++;
258  PointerPte++;
259  NumberOfPages--;
261  }
262 
264  ASSERT(AddressSpaceLocked);
266 
267  ASSERT(StartingVa != 0);
268  return (PVOID)((ULONG_PTR)StartingVa + MmGetMdlByteOffset(Mdl));
269 
270 Error:
271  if (AddressSpaceLocked)
272  {
274  }
275  if (Vad != NULL)
276  {
277  ExFreePoolWithTag(Vad, 'ldaV');
278  }
280 }
ULONG_PTR EndingVpn
Definition: mmtypes.h:756
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:91
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1244
#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:1619
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:760
enum _TABLE_SEARCH_RESULT TABLE_SEARCH_RESULT
LONG NTSTATUS
Definition: precomp.h:26
#define ExRaiseStatus
Definition: ntoskrnl.h:104
union _MMPFN::@1749 u3
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
struct _MMPFN::@1749::@1755 e2
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:386
ULONG * PPFN_NUMBER
Definition: ke.h:9
USHORT CacheAttribute
Definition: mm.h:356
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MM_NOIRQL
Definition: mm.h:59
#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:379
union _MMVAD_LONG::@2538 u
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:403
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
Status
Definition: gdiplustypes.h:24
BOOLEAN NTAPI KeInvalidateAllCaches(VOID)
Definition: cpu.c:449
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
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
union _MMPTE::@2275 u
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:790
#define MM_READWRITE
Definition: inbv.c:12
union _MMVAD_LONG::@2539 u2
Definition: mm.h:362
#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:1000
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
union _MMPFN::@1748 u2
#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
#define MmGetMdlByteOffset(_Mdl)
VOID NTAPI MiInsertVad(_Inout_ PMMVAD Vad, _Inout_ PMM_AVL_TABLE VadRoot)
#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:1612
#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 285 of file mdlsup.c.

288 {
291  PMMVAD Vad;
292  PMMPTE PointerPte;
293  PMMPDE PointerPde;
294  KIRQL OldIrql;
295  ULONG NumberOfPages;
296  PPFN_NUMBER MdlPages;
297  PFN_NUMBER PageTablePage;
298 
299  DPRINT("MiUnmapLockedPagesInUserSpace(%p, %p)\n", BaseAddress, Mdl);
300 
303  ASSERT(NumberOfPages != 0);
304  MdlPages = MmGetMdlPfnArray(Mdl);
305 
306  /* Find the VAD */
309  if (!Vad ||
311  {
312  DPRINT1("MiUnmapLockedPagesInUserSpace invalid for %p\n", BaseAddress);
314  return;
315  }
316 
318 
319  /* Remove it from the process VAD tree */
320  ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
321  MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
322 
323  /* MiRemoveNode should have removed us if we were the hint */
324  ASSERT(Process->VadRoot.NodeHint != Vad);
325 
326  PointerPte = MiAddressToPte(BaseAddress);
327  OldIrql = MiAcquirePfnLock();
328  while (NumberOfPages != 0 &&
329  *MdlPages != LIST_HEAD)
330  {
331  ASSERT(MiAddressToPte(PointerPte)->u.Hard.Valid == 1);
332  ASSERT(PointerPte->u.Hard.Valid == 1);
333 
334  /* Invalidate it */
335  MI_ERASE_PTE(PointerPte);
336 
337  /* We invalidated this PTE, so dereference the PDE */
338  PointerPde = MiAddressToPde(BaseAddress);
339  PageTablePage = PointerPde->u.Hard.PageFrameNumber;
340  MiDecrementShareCount(MiGetPfnEntry(PageTablePage), PageTablePage);
341 
343  {
344  ASSERT(MiIsPteOnPdeBoundary(PointerPte + 1) || (NumberOfPages == 1));
345  MiDeletePde(PointerPde, Process);
346  }
347 
348  /* Next page */
349  PointerPte++;
350  NumberOfPages--;
352  MdlPages++;
353  }
354 
356  MiReleasePfnLock(OldIrql);
359  ExFreePoolWithTag(Vad, 'ldaV');
360 }
union _MMVAD::@2535 u
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:1619
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
union _MMPTE::@2275 u
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#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:1000
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
#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
#define DPRINT
Definition: sndvol32.h:71
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1612
ULONG_PTR VadType
Definition: mmtypes.h:691

Referenced by MmUnmapLockedPages().

◆ MmAdvanceMdl()

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

Definition at line 1608 of file mdlsup.c.

1610 {
1611  UNIMPLEMENTED;
1612  return STATUS_NOT_IMPLEMENTED;
1613 }
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 480 of file mdlsup.c.

484 {
485  //
486  // Call the internal routine
487  //
488  return MiAllocatePagesForMdl(LowAddress,
489  HighAddress,
490  SkipBytes,
491  TotalBytes,
492  MiNotMapped,
493  0);
494 }
_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 501 of file mdlsup.c.

507 {
508  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
509 
510  //
511  // Check for invalid cache type
512  //
514  {
515  //
516  // Normalize to default
517  //
518  CacheAttribute = MiNotMapped;
519  }
520  else
521  {
522  //
523  // Conver to internal caching attribute
524  //
525  CacheAttribute = MiPlatformCacheAttributes[FALSE][CacheType];
526  }
527 
528  //
529  // Only these flags are allowed
530  //
532  {
533  //
534  // Silently fail
535  //
536  return NULL;
537  }
538 
539  //
540  // Call the internal routine
541  //
542  return MiAllocatePagesForMdl(LowAddress,
543  HighAddress,
544  SkipBytes,
545  TotalBytes,
546  CacheAttribute,
547  Flags);
548 }
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 415 of file mdlsup.c.

416 {
417  PPFN_NUMBER MdlPages, EndPage;
418  PFN_NUMBER Pfn, PageCount;
419  PVOID Base;
420  PMMPTE PointerPte;
421 
422  //
423  // Sanity checks
424  //
425  ASSERT(Mdl->ByteCount != 0);
426  ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED |
429  MDL_PARTIAL)) == 0);
430 
431  //
432  // We know the MDL isn't associated to a process now
433  //
434  Mdl->Process = NULL;
435 
436  //
437  // Get page and VA information
438  //
439  MdlPages = (PPFN_NUMBER)(Mdl + 1);
440  Base = Mdl->StartVa;
441 
442  //
443  // Set the system address and now get the page count
444  //
445  Mdl->MappedSystemVa = (PVOID)((ULONG_PTR)Base + Mdl->ByteOffset);
446  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Mdl->MappedSystemVa,
447  Mdl->ByteCount);
448  ASSERT(PageCount != 0);
449  EndPage = MdlPages + PageCount;
450 
451  //
452  // Loop the PTEs
453  //
454  PointerPte = MiAddressToPte(Base);
455  do
456  {
457  //
458  // Write the PFN
459  //
460  Pfn = PFN_FROM_PTE(PointerPte++);
461  *MdlPages++ = Pfn;
462  } while (MdlPages < EndPage);
463 
464  //
465  // Set the nonpaged pool flag
466  //
467  Mdl->MdlFlags |= MDL_SOURCE_IS_NONPAGED_POOL;
468 
469  //
470  // Check if this is an I/O mapping
471  //
472  if (!MiGetPfnEntry(Pfn)) Mdl->MdlFlags |= MDL_IO_SPACE;
473 }
_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:1000
#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 _Success_(), ClasspInitializeGesn(), CreateDMA(), DiskInfoExceptionCheck(), Ext2CreateMdl(), FatBuildZeroMdl(), KbdHid_StartDevice(), MouHid_StartDevice(), Mx::MxBuildMdlForNonPagedPool(), NdisAllocateBuffer(), prepare_raid0_write(), prepare_raid10_write(), prepare_raid5_write(), prepare_raid6_write(), 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 369 of file mdlsup.c.

372 {
373  SIZE_T Size;
374 
375  //
376  // Check if we don't have an MDL built
377  //
378  if (!Mdl)
379  {
380  //
381  // Calculate the size we'll need and allocate the MDL
382  //
385  if (!Mdl) return NULL;
386  }
387 
388  //
389  // Initialize it
390  //
392  return Mdl;
393 }
_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:400
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 555 of file mdlsup.c.

556 {
557  PVOID Base;
558  PPFN_NUMBER Pages;
559  LONG NumberOfPages;
560  PMMPFN Pfn1;
561  KIRQL OldIrql;
562  DPRINT("Freeing MDL: %p\n", Mdl);
563 
564  //
565  // Sanity checks
566  //
568  ASSERT((Mdl->MdlFlags & MDL_IO_SPACE) == 0);
569  ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0);
570 
571  //
572  // Get address and page information
573  //
574  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
575  NumberOfPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
576 
577  //
578  // Acquire PFN lock
579  //
580  OldIrql = MiAcquirePfnLock();
581 
582  //
583  // Loop all the MDL pages
584  //
585  Pages = (PPFN_NUMBER)(Mdl + 1);
586  do
587  {
588  //
589  // Reached the last page
590  //
591  if (*Pages == LIST_HEAD) break;
592 
593  //
594  // Get the page entry
595  //
596  Pfn1 = MiGetPfnEntry(*Pages);
597  ASSERT(Pfn1);
598  ASSERT(Pfn1->u2.ShareCount == 1);
599  ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE);
600  if (Pfn1->u4.PteFrame != 0x1FFEDCB)
601  {
602  /* Corrupted PFN entry or invalid free */
603  KeBugCheckEx(MEMORY_MANAGEMENT, 0x1236, (ULONG_PTR)Mdl, (ULONG_PTR)Pages, *Pages);
604  }
605 
606  //
607  // Clear it
608  //
609  Pfn1->u3.e1.StartOfAllocation = 0;
610  Pfn1->u3.e1.EndOfAllocation = 0;
612  Pfn1->u2.ShareCount = 0;
613 
614  //
615  // Dereference it
616  //
617  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
618  if (Pfn1->u3.e2.ReferenceCount != 1)
619  {
620  /* Just take off one reference */
621  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
622  }
623  else
624  {
625  /* We'll be nuking the whole page */
626  MiDecrementReferenceCount(Pfn1, *Pages);
627  }
628 
629  //
630  // Clear this page and move on
631  //
632  *Pages++ = LIST_HEAD;
633  } while (--NumberOfPages != 0);
634 
635  //
636  // Release the lock
637  //
638  MiReleasePfnLock(OldIrql);
639 
640  //
641  // Remove the pages locked flag
642  //
643  Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
644 }
#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::@1749 u3
struct _MMPFN::@1749::@1755 e2
USHORT PageLocation
Definition: mm.h:354
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:386
ULONG * PPFN_NUMBER
Definition: ke.h:9
ULONG_PTR ShareCount
Definition: mm.h:379
long LONG
Definition: pedump.c:60
void * PVOID
Definition: retypes.h:9
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
union _MMPFN::@1752 u4
#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:790
Definition: mm.h:362
#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:1000
#define InterlockedDecrement16
Definition: interlocked.h:139
ULONG_PTR PteFrame
Definition: mm.h:407
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
union _MMPFN::@1748 u2
#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 809 of file mdlsup.c.

811 {
812  //
813  // Call the extended version
814  //
816  AccessMode,
817  MmCached,
818  NULL,
819  TRUE,
821 }
#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:651
_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 651 of file mdlsup.c.

657 {
658  PVOID Base;
659  PPFN_NUMBER MdlPages, LastPage;
660  PFN_COUNT PageCount;
661  BOOLEAN IsIoMapping;
662  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
663  PMMPTE PointerPte;
664  MMPTE TempPte;
665 
666  //
667  // Sanity check
668  //
669  ASSERT(Mdl->ByteCount != 0);
670 
671  //
672  // Get the base
673  //
674  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
675 
676  //
677  // Handle kernel case first
678  //
679  if (AccessMode == KernelMode)
680  {
681  //
682  // Get the list of pages and count
683  //
684  MdlPages = (PPFN_NUMBER)(Mdl + 1);
685  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
686  LastPage = MdlPages + PageCount;
687 
688  //
689  // Sanity checks
690  //
691  ASSERT((Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
694  ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED | MDL_PARTIAL)) != 0);
695 
696  //
697  // Get the correct cache type
698  //
699  IsIoMapping = (Mdl->MdlFlags & MDL_IO_SPACE) != 0;
700  CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType];
701 
702  //
703  // Reserve the PTEs
704  //
705  PointerPte = MiReserveSystemPtes(PageCount, SystemPteSpace);
706  if (!PointerPte)
707  {
708  //
709  // If it can fail, return NULL
710  //
711  if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL) return NULL;
712 
713  //
714  // Should we bugcheck?
715  //
716  if (!BugCheckOnFailure) return NULL;
717 
718  //
719  // Yes, crash the system
720  //
721  KeBugCheckEx(NO_MORE_SYSTEM_PTES, 0, PageCount, 0, 0);
722  }
723 
724  //
725  // Get the mapped address
726  //
727  Base = (PVOID)((ULONG_PTR)MiPteToAddress(PointerPte) + Mdl->ByteOffset);
728 
729  //
730  // Get the template
731  //
733  switch (CacheAttribute)
734  {
735  case MiNonCached:
736 
737  //
738  // Disable caching
739  //
742  break;
743 
744  case MiWriteCombined:
745 
746  //
747  // Enable write combining
748  //
751  break;
752 
753  default:
754  //
755  // Nothing to do
756  //
757  break;
758  }
759 
760  //
761  // Loop all PTEs
762  //
763  do
764  {
765  //
766  // We're done here
767  //
768  if (*MdlPages == LIST_HEAD) break;
769 
770  //
771  // Write the PTE
772  //
773  TempPte.u.Hard.PageFrameNumber = *MdlPages;
774  MI_WRITE_VALID_PTE(PointerPte++, TempPte);
775  } while (++MdlPages < LastPage);
776 
777  //
778  // Mark it as mapped
779  //
780  ASSERT((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0);
781  Mdl->MappedSystemVa = Base;
782  Mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
783 
784  //
785  // Check if it was partial
786  //
787  if (Mdl->MdlFlags & MDL_PARTIAL)
788  {
789  //
790  // Write the appropriate flag here too
791  //
792  Mdl->MdlFlags |= MDL_PARTIAL_HAS_BEEN_MAPPED;
793  }
794 
795  //
796  // Return the mapped address
797  //
798  return Base;
799  }
800 
802 }
#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 1620 of file mdlsup.c.

1624 {
1625  UNIMPLEMENTED;
1626  return 0;
1627 }
#define UNIMPLEMENTED
Definition: debug.h:115

Referenced by TestMap().

◆ MmMapMemoryDumpMdl()

VOID NTAPI MmMapMemoryDumpMdl ( IN PMDL  Mdl)

Definition at line 1697 of file mdlsup.c.

1698 {
1699  UNIMPLEMENTED;
1700 }
#define UNIMPLEMENTED
Definition: debug.h:115

◆ MmPrefetchPages()

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

Definition at line 1646 of file mdlsup.c.

1648 {
1649  UNIMPLEMENTED;
1650  return STATUS_NOT_IMPLEMENTED;
1651 }
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 922 of file mdlsup.c.

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

1674 {
1675  UNIMPLEMENTED;
1676 }
#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 1684 of file mdlsup.c.

1688 {
1689  UNIMPLEMENTED;
1690 }
#define UNIMPLEMENTED
Definition: debug.h:115

◆ MmProtectMdlSystemAddress()

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

Definition at line 1658 of file mdlsup.c.

1660 {
1661  UNIMPLEMENTED;
1662  return STATUS_NOT_IMPLEMENTED;
1663 }
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 400 of file mdlsup.c.

402 {
403  //
404  // Return the MDL size
405  //
406  return sizeof(MDL) +
408 }
_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 1426 of file mdlsup.c.

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

◆ MmUnmapLockedPages()

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

Definition at line 828 of file mdlsup.c.

830 {
831  PVOID Base;
832  PFN_COUNT PageCount, ExtraPageCount;
833  PPFN_NUMBER MdlPages;
834  PMMPTE PointerPte;
835 
836  //
837  // Sanity check
838  //
839  ASSERT(Mdl->ByteCount != 0);
840 
841  //
842  // Check if this is a kernel request
843  //
845  {
846  //
847  // Get base and count information
848  //
849  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
850  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
851 
852  //
853  // Sanity checks
854  //
855  ASSERT((Mdl->MdlFlags & MDL_PARENT_MAPPED_SYSTEM_VA) == 0);
856  ASSERT(PageCount != 0);
857  ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
858 
859  //
860  // Get the PTE
861  //
862  PointerPte = MiAddressToPte(BaseAddress);
863 
864  //
865  // This should be a resident system PTE
866  //
867  ASSERT(PointerPte >= MmSystemPtesStart[SystemPteSpace]);
868  ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
869  ASSERT(PointerPte->u.Hard.Valid == 1);
870 
871  //
872  // Check if the caller wants us to free advanced pages
873  //
874  if (Mdl->MdlFlags & MDL_FREE_EXTRA_PTES)
875  {
876  //
877  // Get the MDL page array
878  //
879  MdlPages = MmGetMdlPfnArray(Mdl);
880 
881  /* Number of extra pages stored after the PFN array */
882  ExtraPageCount = (PFN_COUNT)*(MdlPages + PageCount);
883 
884  //
885  // Do the math
886  //
887  PageCount += ExtraPageCount;
888  PointerPte -= ExtraPageCount;
889  ASSERT(PointerPte >= MmSystemPtesStart[SystemPteSpace]);
890  ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
891 
892  //
893  // Get the new base address
894  //
896  (ExtraPageCount << PAGE_SHIFT));
897  }
898 
899  //
900  // Remove flags
901  //
902  Mdl->MdlFlags &= ~(MDL_MAPPED_TO_SYSTEM_VA |
905 
906  //
907  // Release the system PTEs
908  //
909  MiReleaseSystemPtes(PointerPte, PageCount, SystemPteSpace);
910  }
911  else
912  {
914  }
915 }
#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:285
#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
union _MMPTE::@2275 u
#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

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

1637 {
1638  UNIMPLEMENTED;
1639 }
#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.