ReactOS  0.4.15-dev-5130-gc1c1279
mdlsup.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: ntoskrnl/mm/ARM3/mdlsup.c
5  * PURPOSE: ARM Memory Manager Memory Descriptor List (MDL) Management
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 #define MODULE_INVOLVED_IN_ARM3
16 #include <mm/ARM3/miarm.h>
17 
18 /* GLOBALS ********************************************************************/
19 
23 
25 
26 /* INTERNAL FUNCTIONS *********************************************************/
27 static
28 PVOID
29 NTAPI
31  _In_ PMDL Mdl,
32  _In_ PVOID StartVa,
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 
78  if (!NT_SUCCESS(Status))
79  {
80  Vad = NULL;
81  goto Error;
82  }
83 
84  /* Allocate a VAD for our mapped region */
85  Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
86  if (Vad == NULL)
87  {
90  goto Error;
91  }
92 
93  /* Initialize PhysicalMemory VAD */
94  RtlZeroMemory(Vad, sizeof(*Vad));
95  Vad->u2.VadFlags2.LongVad = 1;
98  Vad->u.VadFlags.PrivateMemory = 1;
99 
100  /* Did the caller specify an address? */
101  if (BaseAddress == NULL)
102  {
103  /* We get to pick the address */
105  AddressSpaceLocked = TRUE;
106  if (Process->VmDeleted)
107  {
109  goto Error;
110  }
111 
114  &Process->VadRoot,
115  &Parent,
116  &StartingVa);
117  if (Result == TableFoundNode)
118  {
120  goto Error;
121  }
122  EndingVa = StartingVa + NumberOfPages * PAGE_SIZE - 1;
123  BaseAddress = (PVOID)StartingVa;
124  }
125  else
126  {
127  /* Caller specified a base address */
128  StartingVa = (ULONG_PTR)BaseAddress;
129  EndingVa = StartingVa + NumberOfPages * PAGE_SIZE - 1;
130 
131  /* Make sure it's valid */
132  if (BYTE_OFFSET(StartingVa) != 0 ||
133  EndingVa <= StartingVa ||
134  EndingVa > (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS)
135  {
137  goto Error;
138  }
139 
141  AddressSpaceLocked = TRUE;
142  if (Process->VmDeleted)
143  {
145  goto Error;
146  }
147 
148  /* Check if it's already in use */
150  EndingVa >> PAGE_SHIFT,
151  &Process->VadRoot,
152  &Parent);
153  if (Result == TableFoundNode)
154  {
156  goto Error;
157  }
158  }
159 
160  Vad->StartingVpn = StartingVa >> PAGE_SHIFT;
161  Vad->EndingVpn = EndingVa >> PAGE_SHIFT;
162 
164 
165  ASSERT(Vad->EndingVpn >= Vad->StartingVpn);
166  MiInsertVad((PMMVAD)Vad, &Process->VadRoot);
167 
168  /* Check if this is uncached */
169  if (CacheAttribute != MiCached)
170  {
171  /* Flush all caches */
174  }
175 
176  PointerPte = MiAddressToPte(BaseAddress);
177  while (NumberOfPages != 0 &&
178  *MdlPages != LIST_HEAD)
179  {
180  PointerPde = MiPteToPde(PointerPte);
182  ASSERT(PointerPte->u.Hard.Valid == 0);
183 
184  /* Add a PDE reference for each page */
186 
187  /* Set up our basic user PTE */
189  PointerPte,
190  MM_READWRITE,
191  *MdlPages);
192 
193  EffectiveCacheAttribute = CacheAttribute;
194 
195  /* We need to respect the PFN's caching information in some cases */
196  Pfn2 = MiGetPfnEntry(*MdlPages);
197  if (Pfn2 != NULL)
198  {
199  ASSERT(Pfn2->u3.e2.ReferenceCount != 0);
200 
201  switch (Pfn2->u3.e1.CacheAttribute)
202  {
203  case MiNonCached:
204  if (CacheAttribute != MiNonCached)
205  {
206  MiCacheOverride[1]++;
207  EffectiveCacheAttribute = MiNonCached;
208  }
209  break;
210 
211  case MiCached:
212  if (CacheAttribute != MiCached)
213  {
214  MiCacheOverride[0]++;
215  EffectiveCacheAttribute = MiCached;
216  }
217  break;
218 
219  case MiWriteCombined:
220  if (CacheAttribute != MiWriteCombined)
221  {
222  MiCacheOverride[2]++;
223  EffectiveCacheAttribute = MiWriteCombined;
224  }
225  break;
226 
227  default:
228  /* We don't support AWE magic (MiNotMapped) */
229  DPRINT1("FIXME: MiNotMapped is not supported\n");
230  ASSERT(FALSE);
231  break;
232  }
233  }
234 
235  /* Configure caching */
236  switch (EffectiveCacheAttribute)
237  {
238  case MiNonCached:
241  break;
242  case MiCached:
243  break;
244  case MiWriteCombined:
247  break;
248  default:
249  ASSERT(FALSE);
250  break;
251  }
252 
253  /* Make the page valid */
254  MI_WRITE_VALID_PTE(PointerPte, TempPte);
255 
256  /* Acquire a share count */
257  Pfn1 = MI_PFN_ELEMENT(PointerPde->u.Hard.PageFrameNumber);
258  DPRINT("Incrementing %p from %p\n", Pfn1, _ReturnAddress());
259  OldIrql = MiAcquirePfnLock();
260  Pfn1->u2.ShareCount++;
261  MiReleasePfnLock(OldIrql);
262 
263  /* Next page */
264  MdlPages++;
265  PointerPte++;
266  NumberOfPages--;
268  }
269 
271  ASSERT(AddressSpaceLocked);
273 
274  ASSERT(StartingVa != 0);
275  return (PVOID)((ULONG_PTR)StartingVa + MmGetMdlByteOffset(Mdl));
276 
277 Error:
278  if (AddressSpaceLocked)
279  {
281  }
282  if (Vad != NULL)
283  {
284  ExFreePoolWithTag(Vad, 'ldaV');
286  }
288 }
289 
290 static
291 VOID
292 NTAPI
295  _In_ PMDL Mdl)
296 {
299  PMMVAD Vad;
300  PMMPTE PointerPte;
301  PMMPDE PointerPde;
302  KIRQL OldIrql;
303  ULONG NumberOfPages;
304  PPFN_NUMBER MdlPages;
305  PFN_NUMBER PageTablePage;
306 
307  DPRINT("MiUnmapLockedPagesInUserSpace(%p, %p)\n", BaseAddress, Mdl);
308 
311  ASSERT(NumberOfPages != 0);
312  MdlPages = MmGetMdlPfnArray(Mdl);
313 
314  /* Find the VAD */
317  if (!Vad ||
319  {
320  DPRINT1("MiUnmapLockedPagesInUserSpace invalid for %p\n", BaseAddress);
322  return;
323  }
324 
326 
327  /* Remove it from the process VAD tree */
328  ASSERT(Process->VadRoot.NumberGenericTableElements >= 1);
329  MiRemoveNode((PMMADDRESS_NODE)Vad, &Process->VadRoot);
331 
332  /* MiRemoveNode should have removed us if we were the hint */
333  ASSERT(Process->VadRoot.NodeHint != Vad);
334 
335  PointerPte = MiAddressToPte(BaseAddress);
336  OldIrql = MiAcquirePfnLock();
337  while (NumberOfPages != 0 &&
338  *MdlPages != LIST_HEAD)
339  {
340  ASSERT(MiAddressToPte(PointerPte)->u.Hard.Valid == 1);
341  ASSERT(PointerPte->u.Hard.Valid == 1);
342 
343  /* Invalidate it */
344  MI_ERASE_PTE(PointerPte);
345 
346  /* We invalidated this PTE, so dereference the PDE */
347  PointerPde = MiAddressToPde(BaseAddress);
348  PageTablePage = PointerPde->u.Hard.PageFrameNumber;
349  MiDecrementShareCount(MiGetPfnEntry(PageTablePage), PageTablePage);
350 
352  {
353  ASSERT(MiIsPteOnPdeBoundary(PointerPte + 1) || (NumberOfPages == 1));
354  MiDeletePde(PointerPde, Process);
355  }
356 
357  /* Next page */
358  PointerPte++;
359  NumberOfPages--;
361  MdlPages++;
362  }
363 
365  MiReleasePfnLock(OldIrql);
368  ExFreePoolWithTag(Vad, 'ldaV');
369 }
370 
371 /* PUBLIC FUNCTIONS ***********************************************************/
372 
373 /*
374  * @implemented
375  */
376 PMDL
377 NTAPI
379  IN PVOID Base,
380  IN SIZE_T Length)
381 {
382  SIZE_T Size;
383 
384  //
385  // Check if we don't have an MDL built
386  //
387  if (!Mdl)
388  {
389  //
390  // Calculate the size we'll need and allocate the MDL
391  //
394  if (!Mdl) return NULL;
395  }
396 
397  //
398  // Initialize it
399  //
401  return Mdl;
402 }
403 
404 /*
405  * @implemented
406  */
407 SIZE_T
408 NTAPI
410  IN SIZE_T Length)
411 {
412  //
413  // Return the MDL size
414  //
415  return sizeof(MDL) +
417 }
418 
419 /*
420  * @implemented
421  */
422 VOID
423 NTAPI
425 {
426  PPFN_NUMBER MdlPages, EndPage;
427  PFN_NUMBER Pfn, PageCount;
428  PVOID Base;
429  PMMPTE PointerPte;
430 
431  //
432  // Sanity checks
433  //
434  ASSERT(Mdl->ByteCount != 0);
435  ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED |
438  MDL_PARTIAL)) == 0);
439 
440  //
441  // We know the MDL isn't associated to a process now
442  //
443  Mdl->Process = NULL;
444 
445  //
446  // Get page and VA information
447  //
448  MdlPages = (PPFN_NUMBER)(Mdl + 1);
449  Base = Mdl->StartVa;
450 
451  //
452  // Set the system address and now get the page count
453  //
454  Mdl->MappedSystemVa = (PVOID)((ULONG_PTR)Base + Mdl->ByteOffset);
455  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Mdl->MappedSystemVa,
456  Mdl->ByteCount);
457  ASSERT(PageCount != 0);
458  EndPage = MdlPages + PageCount;
459 
460  //
461  // Loop the PTEs
462  //
463  PointerPte = MiAddressToPte(Base);
464  do
465  {
466  //
467  // Write the PFN
468  //
469  Pfn = PFN_FROM_PTE(PointerPte++);
470  *MdlPages++ = Pfn;
471  } while (MdlPages < EndPage);
472 
473  //
474  // Set the nonpaged pool flag
475  //
476  Mdl->MdlFlags |= MDL_SOURCE_IS_NONPAGED_POOL;
477 
478  //
479  // Check if this is an I/O mapping
480  //
481  if (!MiGetPfnEntry(Pfn)) Mdl->MdlFlags |= MDL_IO_SPACE;
482 }
483 
484 /*
485  * @implemented
486  */
487 PMDL
488 NTAPI
493 {
494  //
495  // Call the internal routine
496  //
497  return MiAllocatePagesForMdl(LowAddress,
498  HighAddress,
499  SkipBytes,
500  TotalBytes,
501  MiNotMapped,
502  0);
503 }
504 
505 /*
506  * @implemented
507  */
508 PMDL
509 NTAPI
515  IN ULONG Flags)
516 {
517  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
518 
519  //
520  // Check for invalid cache type
521  //
523  {
524  //
525  // Normalize to default
526  //
527  CacheAttribute = MiNotMapped;
528  }
529  else
530  {
531  //
532  // Conver to internal caching attribute
533  //
534  CacheAttribute = MiPlatformCacheAttributes[FALSE][CacheType];
535  }
536 
537  //
538  // Only these flags are allowed
539  //
541  {
542  //
543  // Silently fail
544  //
545  return NULL;
546  }
547 
548  //
549  // Call the internal routine
550  //
551  return MiAllocatePagesForMdl(LowAddress,
552  HighAddress,
553  SkipBytes,
554  TotalBytes,
555  CacheAttribute,
556  Flags);
557 }
558 
559 /*
560  * @implemented
561  */
562 VOID
563 NTAPI
565 {
566  PVOID Base;
567  PPFN_NUMBER Pages;
568  LONG NumberOfPages;
569  PMMPFN Pfn1;
570  KIRQL OldIrql;
571  DPRINT("Freeing MDL: %p\n", Mdl);
572 
573  //
574  // Sanity checks
575  //
577  ASSERT((Mdl->MdlFlags & MDL_IO_SPACE) == 0);
578  ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0);
579 
580  //
581  // Get address and page information
582  //
583  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
584  NumberOfPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
585 
586  //
587  // Acquire PFN lock
588  //
589  OldIrql = MiAcquirePfnLock();
590 
591  //
592  // Loop all the MDL pages
593  //
594  Pages = (PPFN_NUMBER)(Mdl + 1);
595  do
596  {
597  //
598  // Reached the last page
599  //
600  if (*Pages == LIST_HEAD) break;
601 
602  //
603  // Get the page entry
604  //
605  Pfn1 = MiGetPfnEntry(*Pages);
606  ASSERT(Pfn1);
607  ASSERT(Pfn1->u2.ShareCount == 1);
608  ASSERT(MI_IS_PFN_DELETED(Pfn1) == TRUE);
609  if (Pfn1->u4.PteFrame != 0x1FFEDCB)
610  {
611  /* Corrupted PFN entry or invalid free */
612  KeBugCheckEx(MEMORY_MANAGEMENT, 0x1236, (ULONG_PTR)Mdl, (ULONG_PTR)Pages, *Pages);
613  }
614 
615  //
616  // Clear it
617  //
618  Pfn1->u3.e1.StartOfAllocation = 0;
619  Pfn1->u3.e1.EndOfAllocation = 0;
621  Pfn1->u2.ShareCount = 0;
622 
623  //
624  // Dereference it
625  //
626  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
627  if (Pfn1->u3.e2.ReferenceCount != 1)
628  {
629  /* Just take off one reference */
630  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
631  }
632  else
633  {
634  /* We'll be nuking the whole page */
635  MiDecrementReferenceCount(Pfn1, *Pages);
636  }
637 
638  //
639  // Clear this page and move on
640  //
641  *Pages++ = LIST_HEAD;
642  } while (--NumberOfPages != 0);
643 
644  //
645  // Release the lock
646  //
647  MiReleasePfnLock(OldIrql);
648 
649  //
650  // Remove the pages locked flag
651  //
652  Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
653 }
654 
655 /*
656  * @implemented
657  */
658 PVOID
659 NTAPI
664  IN ULONG BugCheckOnFailure,
665  IN ULONG Priority) // MM_PAGE_PRIORITY
666 {
667  PVOID Base;
668  PPFN_NUMBER MdlPages, LastPage;
669  PFN_COUNT PageCount;
670  BOOLEAN IsIoMapping;
671  MI_PFN_CACHE_ATTRIBUTE CacheAttribute;
672  PMMPTE PointerPte;
673  MMPTE TempPte;
674 
675  //
676  // Sanity check
677  //
678  ASSERT(Mdl->ByteCount != 0);
679 
680  //
681  // Get the base
682  //
683  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
684 
685  //
686  // Handle kernel case first
687  //
688  if (AccessMode == KernelMode)
689  {
690  //
691  // Get the list of pages and count
692  //
693  MdlPages = (PPFN_NUMBER)(Mdl + 1);
694  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
695  LastPage = MdlPages + PageCount;
696 
697  //
698  // Sanity checks
699  //
700  ASSERT((Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
703  ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED | MDL_PARTIAL)) != 0);
704 
705  //
706  // Get the correct cache type
707  //
708  IsIoMapping = (Mdl->MdlFlags & MDL_IO_SPACE) != 0;
709  CacheAttribute = MiPlatformCacheAttributes[IsIoMapping][CacheType];
710 
711  //
712  // Reserve the PTEs
713  //
714  PointerPte = MiReserveSystemPtes(PageCount, SystemPteSpace);
715  if (!PointerPte)
716  {
717  //
718  // If it can fail, return NULL
719  //
720  if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL) return NULL;
721 
722  //
723  // Should we bugcheck?
724  //
725  if (!BugCheckOnFailure) return NULL;
726 
727  //
728  // Yes, crash the system
729  //
730  KeBugCheckEx(NO_MORE_SYSTEM_PTES, 0, PageCount, 0, 0);
731  }
732 
733  //
734  // Get the mapped address
735  //
736  Base = (PVOID)((ULONG_PTR)MiPteToAddress(PointerPte) + Mdl->ByteOffset);
737 
738  //
739  // Get the template
740  //
742  switch (CacheAttribute)
743  {
744  case MiNonCached:
745 
746  //
747  // Disable caching
748  //
751  break;
752 
753  case MiWriteCombined:
754 
755  //
756  // Enable write combining
757  //
760  break;
761 
762  default:
763  //
764  // Nothing to do
765  //
766  break;
767  }
768 
769  //
770  // Loop all PTEs
771  //
772  do
773  {
774  //
775  // We're done here
776  //
777  if (*MdlPages == LIST_HEAD) break;
778 
779  //
780  // Write the PTE
781  //
782  TempPte.u.Hard.PageFrameNumber = *MdlPages;
783  MI_WRITE_VALID_PTE(PointerPte++, TempPte);
784  } while (++MdlPages < LastPage);
785 
786  //
787  // Mark it as mapped
788  //
789  ASSERT((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA) == 0);
790  Mdl->MappedSystemVa = Base;
791  Mdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;
792 
793  //
794  // Check if it was partial
795  //
796  if (Mdl->MdlFlags & MDL_PARTIAL)
797  {
798  //
799  // Write the appropriate flag here too
800  //
801  Mdl->MdlFlags |= MDL_PARTIAL_HAS_BEEN_MAPPED;
802  }
803 
804  //
805  // Return the mapped address
806  //
807  return Base;
808  }
809 
811 }
812 
813 /*
814  * @implemented
815  */
816 PVOID
817 NTAPI
820 {
821  //
822  // Call the extended version
823  //
825  AccessMode,
826  MmCached,
827  NULL,
828  TRUE,
830 }
831 
832 /*
833  * @implemented
834  */
835 VOID
836 NTAPI
838  IN PMDL Mdl)
839 {
840  PVOID Base;
841  PFN_COUNT PageCount, ExtraPageCount;
842  PPFN_NUMBER MdlPages;
843  PMMPTE PointerPte;
844 
845  //
846  // Sanity check
847  //
848  ASSERT(Mdl->ByteCount != 0);
849 
850  //
851  // Check if this is a kernel request
852  //
854  {
855  //
856  // Get base and count information
857  //
858  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
859  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
860 
861  //
862  // Sanity checks
863  //
864  ASSERT((Mdl->MdlFlags & MDL_PARENT_MAPPED_SYSTEM_VA) == 0);
865  ASSERT(PageCount != 0);
866  ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
867 
868  //
869  // Get the PTE
870  //
871  PointerPte = MiAddressToPte(BaseAddress);
872 
873  //
874  // This should be a resident system PTE
875  //
876  ASSERT(PointerPte >= MmSystemPtesStart[SystemPteSpace]);
877  ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
878  ASSERT(PointerPte->u.Hard.Valid == 1);
879 
880  //
881  // Check if the caller wants us to free advanced pages
882  //
883  if (Mdl->MdlFlags & MDL_FREE_EXTRA_PTES)
884  {
885  //
886  // Get the MDL page array
887  //
888  MdlPages = MmGetMdlPfnArray(Mdl);
889 
890  /* Number of extra pages stored after the PFN array */
891  ExtraPageCount = (PFN_COUNT)*(MdlPages + PageCount);
892 
893  //
894  // Do the math
895  //
896  PageCount += ExtraPageCount;
897  PointerPte -= ExtraPageCount;
898  ASSERT(PointerPte >= MmSystemPtesStart[SystemPteSpace]);
899  ASSERT(PointerPte <= MmSystemPtesEnd[SystemPteSpace]);
900 
901  //
902  // Get the new base address
903  //
905  (ExtraPageCount << PAGE_SHIFT));
906  }
907 
908  //
909  // Remove flags
910  //
911  Mdl->MdlFlags &= ~(MDL_MAPPED_TO_SYSTEM_VA |
914 
915  //
916  // Release the system PTEs
917  //
918  MiReleaseSystemPtes(PointerPte, PageCount, SystemPteSpace);
919  }
920  else
921  {
923  }
924 }
925 
926 /*
927  * @implemented
928  */
929 VOID
930 NTAPI
934 {
935  PPFN_NUMBER MdlPages;
936  PVOID Base, Address, LastAddress, StartAddress;
937  ULONG LockPages, TotalPages;
940  NTSTATUS ProbeStatus;
941  PMMPTE PointerPte, LastPte;
942  PMMPDE PointerPde;
943 #if (_MI_PAGING_LEVELS >= 3)
944  PMMPDE PointerPpe;
945 #endif
946 #if (_MI_PAGING_LEVELS == 4)
947  PMMPDE PointerPxe;
948 #endif
949  PFN_NUMBER PageFrameIndex;
950  BOOLEAN UsePfnLock;
951  KIRQL OldIrql;
952  PMMPFN Pfn1;
953  DPRINT("Probing MDL: %p\n", Mdl);
954 
955  //
956  // Sanity checks
957  //
958  ASSERT(Mdl->ByteCount != 0);
959  ASSERT(((ULONG)Mdl->ByteOffset & ~(PAGE_SIZE - 1)) == 0);
960  ASSERT(((ULONG_PTR)Mdl->StartVa & (PAGE_SIZE - 1)) == 0);
961  ASSERT((Mdl->MdlFlags & (MDL_PAGES_LOCKED |
964  MDL_PARTIAL |
965  MDL_IO_SPACE)) == 0);
966 
967  //
968  // Get page and base information
969  //
970  MdlPages = (PPFN_NUMBER)(Mdl + 1);
971  Base = Mdl->StartVa;
972 
973  //
974  // Get the addresses and how many pages we span (and need to lock)
975  //
976  Address = (PVOID)((ULONG_PTR)Base + Mdl->ByteOffset);
977  LastAddress = (PVOID)((ULONG_PTR)Address + Mdl->ByteCount);
978  LockPages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Address, Mdl->ByteCount);
979  ASSERT(LockPages != 0);
980 
981  /* Block invalid access */
982  if ((AccessMode != KernelMode) &&
983  ((LastAddress > (PVOID)MM_USER_PROBE_ADDRESS) || (Address >= LastAddress)))
984  {
985  /* Caller should be in SEH, raise the error */
986  *MdlPages = LIST_HEAD;
988  }
989 
990  //
991  // Get the process
992  //
994  {
995  //
996  // Get the process
997  //
999  }
1000  else
1001  {
1002  //
1003  // No process
1004  //
1005  CurrentProcess = NULL;
1006  }
1007 
1008  //
1009  // Save the number of pages we'll have to lock, and the start address
1010  //
1011  TotalPages = LockPages;
1012  StartAddress = Address;
1013 
1014  /* Large pages not supported */
1016 
1017  //
1018  // Now probe them
1019  //
1020  ProbeStatus = STATUS_SUCCESS;
1021  _SEH2_TRY
1022  {
1023  //
1024  // Enter probe loop
1025  //
1026  do
1027  {
1028  //
1029  // Assume failure
1030  //
1031  *MdlPages = LIST_HEAD;
1032 
1033  //
1034  // Read
1035  //
1036  *(volatile CHAR*)Address;
1037 
1038  //
1039  // Check if this is write access (only probe for user-mode)
1040  //
1041  if ((Operation != IoReadAccess) &&
1043  {
1044  //
1045  // Probe for write too
1046  //
1048  }
1049 
1050  //
1051  // Next address...
1052  //
1054 
1055  //
1056  // Next page...
1057  //
1058  LockPages--;
1059  MdlPages++;
1060  } while (Address < LastAddress);
1061 
1062  //
1063  // Reset back to the original page
1064  //
1065  ASSERT(LockPages == 0);
1066  MdlPages = (PPFN_NUMBER)(Mdl + 1);
1067  }
1069  {
1070  //
1071  // Oops :(
1072  //
1073  ProbeStatus = _SEH2_GetExceptionCode();
1074  }
1075  _SEH2_END;
1076 
1077  //
1078  // So how did that go?
1079  //
1080  if (ProbeStatus != STATUS_SUCCESS)
1081  {
1082  //
1083  // Fail
1084  //
1085  DPRINT1("MDL PROBE FAILED!\n");
1086  Mdl->Process = NULL;
1087  ExRaiseStatus(ProbeStatus);
1088  }
1089 
1090  //
1091  // Get the PTE and PDE
1092  //
1093  PointerPte = MiAddressToPte(StartAddress);
1094  PointerPde = MiAddressToPde(StartAddress);
1095 #if (_MI_PAGING_LEVELS >= 3)
1096  PointerPpe = MiAddressToPpe(StartAddress);
1097 #endif
1098 #if (_MI_PAGING_LEVELS == 4)
1099  PointerPxe = MiAddressToPxe(StartAddress);
1100 #endif
1101 
1102  //
1103  // Sanity check
1104  //
1105  ASSERT(MdlPages == (PPFN_NUMBER)(Mdl + 1));
1106 
1107  //
1108  // Check what kind of operation this is
1109  //
1110  if (Operation != IoReadAccess)
1111  {
1112  //
1113  // Set the write flag
1114  //
1115  Mdl->MdlFlags |= MDL_WRITE_OPERATION;
1116  }
1117  else
1118  {
1119  //
1120  // Remove the write flag
1121  //
1122  Mdl->MdlFlags &= ~(MDL_WRITE_OPERATION);
1123  }
1124 
1125  //
1126  // Mark the MDL as locked *now*
1127  //
1128  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
1129 
1130  //
1131  // Check if this came from kernel mode
1132  //
1134  {
1135  //
1136  // We should not have a process
1137  //
1139  Mdl->Process = NULL;
1140 
1141  //
1142  // In kernel mode, we don't need to check for write access
1143  //
1145 
1146  //
1147  // Use the PFN lock
1148  //
1149  UsePfnLock = TRUE;
1150  OldIrql = MiAcquirePfnLock();
1151  }
1152  else
1153  {
1154  //
1155  // Sanity checks
1156  //
1157  ASSERT(TotalPages != 0);
1159 
1160  //
1161  // Track locked pages
1162  //
1163  InterlockedExchangeAddSizeT(&CurrentProcess->NumberOfLockedPages,
1164  TotalPages);
1165 
1166  //
1167  // Save the process
1168  //
1169  Mdl->Process = CurrentProcess;
1170 
1171  /* Lock the process working set */
1173  UsePfnLock = FALSE;
1174  OldIrql = MM_NOIRQL;
1175  }
1176 
1177  //
1178  // Get the last PTE
1179  //
1180  LastPte = MiAddressToPte((PVOID)((ULONG_PTR)LastAddress - 1));
1181 
1182  //
1183  // Loop the pages
1184  //
1185  do
1186  {
1187  //
1188  // Assume failure and check for non-mapped pages
1189  //
1190  *MdlPages = LIST_HEAD;
1191  while (
1192 #if (_MI_PAGING_LEVELS == 4)
1193  (PointerPxe->u.Hard.Valid == 0) ||
1194 #endif
1195 #if (_MI_PAGING_LEVELS >= 3)
1196  (PointerPpe->u.Hard.Valid == 0) ||
1197 #endif
1198  (PointerPde->u.Hard.Valid == 0) ||
1199  (PointerPte->u.Hard.Valid == 0))
1200  {
1201  //
1202  // What kind of lock were we using?
1203  //
1204  if (UsePfnLock)
1205  {
1206  //
1207  // Release PFN lock
1208  //
1209  MiReleasePfnLock(OldIrql);
1210  }
1211  else
1212  {
1213  /* Release process working set */
1215  }
1216 
1217  //
1218  // Access the page
1219  //
1220  Address = MiPteToAddress(PointerPte);
1221 
1222  //HACK: Pass a placeholder TrapInformation so the fault handler knows we're unlocked
1223  Status = MmAccessFault(FALSE, Address, KernelMode, (PVOID)(ULONG_PTR)0xBADBADA3BADBADA3ULL);
1224  if (!NT_SUCCESS(Status))
1225  {
1226  //
1227  // Fail
1228  //
1229  DPRINT1("Access fault failed\n");
1230  goto Cleanup;
1231  }
1232 
1233  //
1234  // What lock should we use?
1235  //
1236  if (UsePfnLock)
1237  {
1238  //
1239  // Grab the PFN lock
1240  //
1241  OldIrql = MiAcquirePfnLock();
1242  }
1243  else
1244  {
1245  /* Lock the process working set */
1247  }
1248  }
1249 
1250  //
1251  // Check if this was a write or modify
1252  //
1253  if (Operation != IoReadAccess)
1254  {
1255  //
1256  // Check if the PTE is not writable
1257  //
1258  if (MI_IS_PAGE_WRITEABLE(PointerPte) == FALSE)
1259  {
1260  //
1261  // Check if it's copy on write
1262  //
1263  if (MI_IS_PAGE_COPY_ON_WRITE(PointerPte))
1264  {
1265  //
1266  // Get the base address and allow a change for user-mode
1267  //
1268  Address = MiPteToAddress(PointerPte);
1270  {
1271  //
1272  // What kind of lock were we using?
1273  //
1274  if (UsePfnLock)
1275  {
1276  //
1277  // Release PFN lock
1278  //
1279  MiReleasePfnLock(OldIrql);
1280  }
1281  else
1282  {
1283  /* Release process working set */
1285  }
1286 
1287  //
1288  // Access the page
1289  //
1290 
1291  //HACK: Pass a placeholder TrapInformation so the fault handler knows we're unlocked
1292  Status = MmAccessFault(TRUE, Address, KernelMode, (PVOID)(ULONG_PTR)0xBADBADA3BADBADA3ULL);
1293  if (!NT_SUCCESS(Status))
1294  {
1295  //
1296  // Fail
1297  //
1298  DPRINT1("Access fault failed\n");
1299  goto Cleanup;
1300  }
1301 
1302  //
1303  // Re-acquire the lock
1304  //
1305  if (UsePfnLock)
1306  {
1307  //
1308  // Grab the PFN lock
1309  //
1310  OldIrql = MiAcquirePfnLock();
1311  }
1312  else
1313  {
1314  /* Lock the process working set */
1316  }
1317 
1318  //
1319  // Start over
1320  //
1321  continue;
1322  }
1323  }
1324 
1325  //
1326  // Fail, since we won't allow this
1327  //
1329  goto CleanupWithLock;
1330  }
1331  }
1332 
1333  //
1334  // Grab the PFN
1335  //
1336  PageFrameIndex = PFN_FROM_PTE(PointerPte);
1337  Pfn1 = MiGetPfnEntry(PageFrameIndex);
1338  if (Pfn1)
1339  {
1340  /* Either this is for kernel-mode, or the working set is held */
1341  ASSERT((CurrentProcess == NULL) || (UsePfnLock == FALSE));
1342 
1343  /* No Physical VADs supported yet */
1344  if (CurrentProcess) ASSERT(CurrentProcess->PhysicalVadRoot == NULL);
1345 
1346  /* This address should already exist and be fully valid */
1348  }
1349  else
1350  {
1351  //
1352  // For I/O addresses, just remember this
1353  //
1354  Mdl->MdlFlags |= MDL_IO_SPACE;
1355  }
1356 
1357  //
1358  // Write the page and move on
1359  //
1360  *MdlPages++ = PageFrameIndex;
1361  PointerPte++;
1362 
1363  /* Check if we're on a PDE boundary */
1364  if (MiIsPteOnPdeBoundary(PointerPte)) PointerPde++;
1365 #if (_MI_PAGING_LEVELS >= 3)
1366  if (MiIsPteOnPpeBoundary(PointerPte)) PointerPpe++;
1367 #endif
1368 #if (_MI_PAGING_LEVELS == 4)
1369  if (MiIsPteOnPxeBoundary(PointerPte)) PointerPxe++;
1370 #endif
1371 
1372  } while (PointerPte <= LastPte);
1373 
1374  //
1375  // What kind of lock were we using?
1376  //
1377  if (UsePfnLock)
1378  {
1379  //
1380  // Release PFN lock
1381  //
1382  MiReleasePfnLock(OldIrql);
1383  }
1384  else
1385  {
1386  /* Release process working set */
1388  }
1389 
1390  //
1391  // Sanity check
1392  //
1393  ASSERT((Mdl->MdlFlags & MDL_DESCRIBES_AWE) == 0);
1394  return;
1395 
1396 CleanupWithLock:
1397  //
1398  // This is the failure path
1399  //
1401 
1402  //
1403  // What kind of lock were we using?
1404  //
1405  if (UsePfnLock)
1406  {
1407  //
1408  // Release PFN lock
1409  //
1410  MiReleasePfnLock(OldIrql);
1411  }
1412  else
1413  {
1414  /* Release process working set */
1416  }
1417 Cleanup:
1418  //
1419  // Pages must be locked so MmUnlock can work
1420  //
1421  ASSERT(Mdl->MdlFlags & MDL_PAGES_LOCKED);
1422  MmUnlockPages(Mdl);
1423 
1424  //
1425  // Raise the error
1426  //
1428 }
1429 
1430 /*
1431  * @implemented
1432  */
1433 VOID
1434 NTAPI
1436 {
1437  PPFN_NUMBER MdlPages, LastPage;
1439  PVOID Base;
1440  ULONG Flags, PageCount;
1441  KIRQL OldIrql;
1442  PMMPFN Pfn1;
1443  DPRINT("Unlocking MDL: %p\n", Mdl);
1444 
1445  //
1446  // Sanity checks
1447  //
1448  ASSERT((Mdl->MdlFlags & MDL_PAGES_LOCKED) != 0);
1449  ASSERT((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0);
1450  ASSERT((Mdl->MdlFlags & MDL_PARTIAL) == 0);
1451  ASSERT(Mdl->ByteCount != 0);
1452 
1453  //
1454  // Get the process associated and capture the flags which are volatile
1455  //
1456  Process = Mdl->Process;
1457  Flags = Mdl->MdlFlags;
1458 
1459  //
1460  // Automagically undo any calls to MmGetSystemAddressForMdl's for this MDL
1461  //
1462  if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
1463  {
1464  //
1465  // Unmap the pages from system space
1466  //
1467  MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
1468  }
1469 
1470  //
1471  // Get the page count
1472  //
1473  MdlPages = (PPFN_NUMBER)(Mdl + 1);
1474  Base = (PVOID)((ULONG_PTR)Mdl->StartVa + Mdl->ByteOffset);
1475  PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base, Mdl->ByteCount);
1476  ASSERT(PageCount != 0);
1477 
1478  //
1479  // We don't support AWE
1480  //
1482 
1483  //
1484  // Check if the buffer is mapped I/O space
1485  //
1486  if (Flags & MDL_IO_SPACE)
1487  {
1488  //
1489  // Acquire PFN lock
1490  //
1491  OldIrql = MiAcquirePfnLock();
1492 
1493  //
1494  // Loop every page
1495  //
1496  LastPage = MdlPages + PageCount;
1497  do
1498  {
1499  //
1500  // Last page, break out
1501  //
1502  if (*MdlPages == LIST_HEAD) break;
1503 
1504  //
1505  // Check if this page is in the PFN database
1506  //
1507  Pfn1 = MiGetPfnEntry(*MdlPages);
1508  if (Pfn1) MiDereferencePfnAndDropLockCount(Pfn1);
1509  } while (++MdlPages < LastPage);
1510 
1511  //
1512  // Release the lock
1513  //
1514  MiReleasePfnLock(OldIrql);
1515 
1516  //
1517  // Check if we have a process
1518  //
1519  if (Process)
1520  {
1521  //
1522  // Handle the accounting of locked pages
1523  //
1524  ASSERT(Process->NumberOfLockedPages > 0);
1525  InterlockedExchangeAddSizeT(&Process->NumberOfLockedPages,
1526  -(LONG_PTR)PageCount);
1527  }
1528 
1529  //
1530  // We're done
1531  //
1532  Mdl->MdlFlags &= ~MDL_IO_SPACE;
1533  Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1534  return;
1535  }
1536 
1537  //
1538  // Check if we have a process
1539  //
1540  if (Process)
1541  {
1542  //
1543  // Handle the accounting of locked pages
1544  //
1545  ASSERT(Process->NumberOfLockedPages > 0);
1546  InterlockedExchangeAddSizeT(&Process->NumberOfLockedPages,
1547  -(LONG_PTR)PageCount);
1548  }
1549 
1550  //
1551  // Loop every page
1552  //
1553  LastPage = MdlPages + PageCount;
1554  do
1555  {
1556  //
1557  // Last page reached
1558  //
1559  if (*MdlPages == LIST_HEAD)
1560  {
1561  //
1562  // Were there no pages at all?
1563  //
1564  if (MdlPages == (PPFN_NUMBER)(Mdl + 1))
1565  {
1566  //
1567  // We're already done
1568  //
1569  Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1570  return;
1571  }
1572 
1573  //
1574  // Otherwise, stop here
1575  //
1576  LastPage = MdlPages;
1577  break;
1578  }
1579 
1580  /* Save the PFN entry instead for the secondary loop */
1581  *MdlPages = (PFN_NUMBER)MiGetPfnEntry(*MdlPages);
1582  ASSERT(*MdlPages != 0);
1583  } while (++MdlPages < LastPage);
1584 
1585  //
1586  // Reset pointer
1587  //
1588  MdlPages = (PPFN_NUMBER)(Mdl + 1);
1589 
1590  //
1591  // Now grab the PFN lock for the actual unlock and dereference
1592  //
1593  OldIrql = MiAcquirePfnLock();
1594  do
1595  {
1596  /* Get the current entry and reference count */
1597  Pfn1 = (PMMPFN)*MdlPages;
1599  } while (++MdlPages < LastPage);
1600 
1601  //
1602  // Release the lock
1603  //
1604  MiReleasePfnLock(OldIrql);
1605 
1606  //
1607  // We're done
1608  //
1609  Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
1610 }
1611 
1612 /*
1613  * @unimplemented
1614  */
1615 NTSTATUS
1616 NTAPI
1619 {
1620  UNIMPLEMENTED;
1621  return STATUS_NOT_IMPLEMENTED;
1622 }
1623 
1624 /*
1625  * @unimplemented
1626  */
1627 PVOID
1628 NTAPI
1630  IN ULONG PoolTag,
1633 {
1634  UNIMPLEMENTED;
1635  return 0;
1636 }
1637 
1638 /*
1639  * @unimplemented
1640  */
1641 VOID
1642 NTAPI
1644  IN ULONG PoolTag,
1646 {
1647  UNIMPLEMENTED;
1648 }
1649 
1650 /*
1651  * @unimplemented
1652  */
1653 NTSTATUS
1654 NTAPI
1655 MmPrefetchPages(IN ULONG NumberOfLists,
1656  IN PREAD_LIST *ReadLists)
1657 {
1658  UNIMPLEMENTED;
1659  return STATUS_NOT_IMPLEMENTED;
1660 }
1661 
1662 /*
1663  * @unimplemented
1664  */
1665 NTSTATUS
1666 NTAPI
1669 {
1670  UNIMPLEMENTED;
1671  return STATUS_NOT_IMPLEMENTED;
1672 }
1673 
1674 /*
1675  * @unimplemented
1676  */
1677 VOID
1678 NTAPI
1683 {
1684  UNIMPLEMENTED;
1685 }
1686 
1687 
1688 /*
1689  * @unimplemented
1690  */
1691 VOID
1692 NTAPI
1694  IN LARGE_INTEGER PageList[],
1697 {
1698  UNIMPLEMENTED;
1699 }
1700 
1701 /*
1702  * @unimplemented
1703  */
1704 VOID
1705 NTAPI
1707 {
1708  UNIMPLEMENTED;
1709 }
1710 
1711 /* EOF */
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
ULONG_PTR EndingVpn
Definition: mmtypes.h:756
_SEH2_TRY
Definition: create.c:4226
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
BOOLEAN MmTrackPtes
Definition: mdlsup.c:20
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:1011
#define MM_HIGHEST_USER_ADDRESS
Definition: armddk.h:17
#define MDL_WRITE_OPERATION
Definition: mmtypes.h:25
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:39
#define MM_VIRTMEM_GRANULARITY
Definition: mm.h:102
#define _MI_PAGING_LEVELS
Definition: mm.h:6
union _MMPTE::@2285 u
static VOID NTAPI MiUnmapLockedPagesInUserSpace(_In_ PVOID BaseAddress, _In_ PMDL Mdl)
Definition: mdlsup.c:293
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define _In_opt_
Definition: ms_sal.h:309
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 MiAddressToPde(x)
Definition: mmx86.c:20
#define MmInitializeMdl(_MemoryDescriptorList, _BaseVa, _Length)
FORCEINLINE VOID MiDereferencePfnAndDropLockCount(IN PMMPFN Pfn1)
Definition: miarm.h:1620
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
union _MMPFN::@1753 u2
NTSTATUS NTAPI MmAccessFault(IN ULONG FaultCode, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
Definition: mmfault.c:205
signed short * PSHORT
Definition: retypes.h:6
#define MmGetMdlVirtualAddress(_Mdl)
PMMPTE MmSystemPtesEnd[MaximumPtePoolTypes]
Definition: syspte.c:23
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define TRUE
Definition: types.h:120
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
SIZE_T MmSystemLockPagesCount
Definition: mdlsup.c:22
char CHAR
Definition: xmlstorage.h:175
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1666
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:424
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:760
enum _TABLE_SEARCH_RESULT TABLE_SEARCH_RESULT
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:161
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2413
FORCEINLINE USHORT MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2512
#define MM_READWRITE
Definition: bootanim.c:19
#define ExRaiseStatus
Definition: ntoskrnl.h:108
FORCEINLINE VOID MiLockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1129
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
VOID NTAPI MmProbeAndLockSelectedPages(IN OUT PMDL MemoryDescriptorList, IN LARGE_INTEGER PageList[], IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:1693
ULONG_PTR Protection
Definition: mmtypes.h:693
ULONG LongVad
Definition: mmtypes.h:708
#define MI_IS_PAGE_COPY_ON_WRITE(x)
Definition: mm.h:110
VOID NTAPI MmMapMemoryDumpMdl(IN PMDL Mdl)
Definition: mdlsup.c:1706
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
_SEH2_END
Definition: create.c:4400
union _MMVAD_LONG::@2570 u2
if(dx==0 &&dy==0)
Definition: linetemp.h:174
FORCEINLINE PMMPDE MiPteToPde(PMMPTE PointerPte)
Definition: mm.h:268
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:731
#define MDL_MAPPED_TO_SYSTEM_VA
Definition: mmtypes.h:18
PVOID NTAPI MmMapLockedPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode)
Definition: mdlsup.c:818
int WINAPI EndPage(_In_ HDC)
USHORT PageLocation
Definition: mm.h:365
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: mdlsup.c:510
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
ULONG * PPFN_NUMBER
Definition: ke.h:9
return STATUS_NOT_IMPLEMENTED
PVOID NTAPI MmMapLockedPagesSpecifyCache(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN MEMORY_CACHING_TYPE CacheType, IN PVOID BaseAddress, IN ULONG BugCheckOnFailure, IN ULONG Priority)
Definition: mdlsup.c:660
USHORT CacheAttribute
Definition: mm.h:367
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MM_NOIRQL
Definition: mm.h:70
ULONG PFN_NUMBER
Definition: ke.h:9
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#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
_Inout_ PMDL MemoryDescriptorList
Definition: mmfuncs.h:405
long LONG
Definition: pedump.c:60
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:837
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType]
Definition: iosup.c:27
VOID NTAPI MmFreePagesFromMdl(IN PMDL Mdl)
Definition: mdlsup.c:564
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:395
#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
#define MDL_MAPPING_CAN_FAIL
Definition: mmtypes.h:31
unsigned char BOOLEAN
VOID NTAPI MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
Definition: virtual.c:2475
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS _In_ MEMORY_CACHING_TYPE CacheType
Definition: mmfuncs.h:214
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:48
static WCHAR Address[46]
Definition: ping.c:68
#define MDL_FREE_EXTRA_PTES
Definition: mmtypes.h:27
#define MDL_PARENT_MAPPED_SYSTEM_VA
Definition: mmtypes.h:26
_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
#define _In_
Definition: ms_sal.h:308
#define MDL_SOURCE_IS_NONPAGED_POOL
Definition: mmtypes.h:20
union _MMVAD::@2566 u
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1133
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
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
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
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
PMMPTE MmSystemPtesStart[MaximumPtePoolTypes]
Definition: syspte.c:22
BOOLEAN NTAPI KeInvalidateAllCaches(VOID)
Definition: cpu.c:484
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:171
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 CurrentProcess
Definition: shell.c:125
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
static PVOID NTAPI MiMapLockedPagesInUserSpace(_In_ PMDL Mdl, _In_ PVOID StartVa, _In_ MEMORY_CACHING_TYPE CacheType, _In_opt_ PVOID BaseAddress)
Definition: mdlsup.c:30
ULONG_PTR PrivateMemory
Definition: mmtypes.h:695
#define MDL_DESCRIBES_AWE
Definition: mmtypes.h:28
#define ASSERT(a)
Definition: mode.c:44
ULONG MiCacheOverride[MiNotMapped+1]
Definition: mdlsup.c:24
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
FP_OP Operation
Definition: fpcontrol.c:150
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define TAG_MDL
Definition: tag.h:86
ULONG64 Valid
Definition: mmtypes.h:150
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:195
ULONG_PTR StartingVpn
Definition: mmtypes.h:755
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
#define MM_USER_PROBE_ADDRESS
Definition: armddk.h:19
#define MiIsPteOnPpeBoundary(PointerPte)
Definition: mm.h:308
#define PAGE_ALIGN(Va)
_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
MMPTE ValidKernelPte
Definition: init.c:29
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define MI_PAGE_WRITE_THROUGH(x)
Definition: mm.h:102
_Must_inspect_result_ _In_opt_ PWDF_OBJECT_ATTRIBUTES _In_ _Strict_type_match_ POOL_TYPE _In_opt_ ULONG PoolTag
Definition: wdfmemory.h:159
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define MM_ALLOCATE_FROM_LOCAL_NODE_ONLY
Definition: mmtypes.h:12
_In_ WDFINTERRUPT _In_ WDF_INTERRUPT_POLICY _In_ WDF_INTERRUPT_PRIORITY Priority
Definition: wdfinterrupt.h:651
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1224
struct _MMPFN::@1754::@1760 e2
FORCEINLINE USHORT MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2486
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
MDL
Definition: mmtypes.h:117
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 MI_IS_PAGE_WRITEABLE(x)
Definition: mm.h:106
SIZE_T NTAPI MmSizeOfMdl(IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:409
union _MMPFN::@1754 u3
#define PAGE_SIZE
Definition: env_spec_w32.h:49
FORCEINLINE VOID MiDeletePde(_In_ PMMPDE PointerPde, _In_ PEPROCESS CurrentProcess)
Definition: miarm.h:2546
static const WCHAR Cleanup[]
Definition: register.c:80
LIST_HEAD(acpi_bus_event_list)
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:360
#define InterlockedDecrement16
Definition: interlocked.h:139
#define MDL_PARTIAL_HAS_BEEN_MAPPED
Definition: mmtypes.h:23
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
ULONG_PTR SIZE_T
Definition: typedefs.h:80
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
union _MMPFN::@1757 u4
NTSTATUS NTAPI MmProtectMdlSystemAddress(IN PMDL MemoryDescriptorList, IN ULONG NewProtect)
Definition: mdlsup.c:1667
#define MiIsPteOnPdeBoundary(PointerPte)
Definition: mm.h:306
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
enum _LOCK_OPERATION LOCK_OPERATION
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242
ULONG_PTR PteFrame
Definition: mm.h:418
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:557
PMDL NTAPI MmCreateMdl(IN PMDL Mdl, IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:378
struct _MMPFN * PMMPFN
PVOID NTAPI MmMapLockedPagesWithReservedMapping(IN PVOID MappingAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList, IN MEMORY_CACHING_TYPE CacheType)
Definition: mdlsup.c:1629
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
_Must_inspect_result_ _In_ ULONG NewProtect
Definition: mmfuncs.h:682
#define MmGetMdlByteCount(_Mdl)
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
NTSTATUS NTAPI MmAdvanceMdl(IN PMDL Mdl, IN ULONG NumberOfBytes)
Definition: mdlsup.c:1617
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1035
#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 MM_DONT_ZERO_ALLOCATION
Definition: mmtypes.h:11
#define DPRINT1
Definition: precomp.h:8
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:46
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
void * _ReturnAddress(void)
BOOLEAN MmTrackLockedPages
Definition: mdlsup.c:21
#define OUT
Definition: typedefs.h:40
#define MDL_PARTIAL
Definition: mmtypes.h:22
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:115
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
union _MMVAD_LONG::@2569 u
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define MmGetMdlByteOffset(_Mdl)
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
VOID NTAPI MiInsertVad(_Inout_ PMMVAD Vad, _Inout_ PMM_AVL_TABLE VadRoot)
#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
VOID NTAPI MmUnmapReservedMapping(IN PVOID BaseAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList)
Definition: mdlsup.c:1643
#define DPRINT
Definition: sndvol32.h:71
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:208
enum _MEMORY_CACHING_TYPE MEMORY_CACHING_TYPE
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
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
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define ProbeForWriteChar(Ptr)
Definition: probe.h:33
#define APC_LEVEL
Definition: env_spec_w32.h:695
PMDL NTAPI MmAllocatePagesForMdl(IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes)
Definition: mdlsup.c:489
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1659
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define BYTE_OFFSET(Va)
ULONG_PTR VadType
Definition: mmtypes.h:691
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
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
NTSTATUS NTAPI MmPrefetchPages(IN ULONG NumberOfLists, IN PREAD_LIST *ReadLists)
Definition: mdlsup.c:1655
VOID NTAPI MmProbeAndLockProcessPages(IN OUT PMDL MemoryDescriptorList, IN PEPROCESS Process, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:1679
#define MiIsPteOnPxeBoundary(PointerPte)
Definition: mm.h:310
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_ SIZE_T TotalBytes
Definition: mmfuncs.h:226
FORCEINLINE VOID MiUnlockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1199
ULONG PageFrameNumber
Definition: mmtypes.h:109
#define PAGED_CODE()