ReactOS  0.4.15-dev-2537-g99d7768
pfnlist.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/pfnlist.c
5  * PURPOSE: ARM Memory Manager PFN List Manipulation
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 #if DBG
19 #define ASSERT_LIST_INVARIANT(x) \
20 do { \
21  ASSERT(((x)->Total == 0 && \
22  (x)->Flink == LIST_HEAD && \
23  (x)->Blink == LIST_HEAD) || \
24  ((x)->Total != 0 && \
25  (x)->Flink != LIST_HEAD && \
26  (x)->Blink != LIST_HEAD)); \
27 } while (0)
28 #else
29 #define ASSERT_LIST_INVARIANT(x)
30 #endif
31 
32 /* GLOBALS ********************************************************************/
33 
37 
40 
50 
52 {
59  NULL,
60  NULL
61 };
62 
65 
66 /* FUNCTIONS ******************************************************************/
67 static
68 VOID
70  VOID)
71 {
72  /* Increment available pages */
74 
75  /* Check if we've reached the configured low memory threshold */
77  {
78  /* Clear the event, because now we're ABOVE the threshold */
80  }
82  {
83  /* Otherwise check if we reached the high threshold and signal the event */
85  }
86 }
87 
88 static
89 VOID
91  VOID)
92 {
94 
95  /* See if we hit any thresholds */
97  {
98  /* Clear the high memory event */
100  }
102  {
103  /* Signal the low memory event */
105  }
106 
107  /* One less page */
110  {
111  /* FIXME: Should wake up the MPW and working set manager, if we had one */
112 
113  DPRINT1("Running low on pages: %lu remaining\n", MmAvailablePages);
114 
115  /* Call RosMm and see if it can release any pages for us */
117  }
118 }
119 
120 VOID
121 NTAPI
123 {
124  KIRQL OldIrql;
127 
128  /* Map in hyperspace, then wipe it using XMMI or MEMSET */
133 }
134 
135 VOID
136 NTAPI
138 {
139  PFN_NUMBER OldFlink, OldBlink;
140  PMMPFNLIST ListHead;
141  MMLISTS ListName;
142  ULONG Color;
143  PMMCOLOR_TABLES ColorTable;
144  PMMPFN Pfn1;
145 
146  /* Make sure the PFN lock is held */
148 
149  /* Make sure the PFN entry isn't in-use */
150  ASSERT(Entry->u3.e1.WriteInProgress == 0);
151  ASSERT(Entry->u3.e1.ReadInProgress == 0);
152 
153  /* Find the list for this entry, make sure it's the free or zero list */
154  ListHead = MmPageLocationList[Entry->u3.e1.PageLocation];
155  ListName = ListHead->ListName;
156  ASSERT(ListHead != NULL);
157  ASSERT(ListName <= FreePageList);
158  ASSERT_LIST_INVARIANT(ListHead);
159 
160  /* Remove one count */
161  ASSERT(ListHead->Total != 0);
162  ListHead->Total--;
163 
164  /* Get the forward and back pointers */
165  OldFlink = Entry->u1.Flink;
166  OldBlink = Entry->u2.Blink;
167 
168  /* Check if the next entry is the list head */
169  if (OldFlink != LIST_HEAD)
170  {
171  /* It is not, so set the backlink of the actual entry, to our backlink */
172  MI_PFN_ELEMENT(OldFlink)->u2.Blink = OldBlink;
173  }
174  else
175  {
176  /* Set the list head's backlink instead */
177  ListHead->Blink = OldBlink;
178  }
179 
180  /* Check if the back entry is the list head */
181  if (OldBlink != LIST_HEAD)
182  {
183  /* It is not, so set the backlink of the actual entry, to our backlink */
184  MI_PFN_ELEMENT(OldBlink)->u1.Flink = OldFlink;
185  }
186  else
187  {
188  /* Set the list head's backlink instead */
189  ListHead->Flink = OldFlink;
190  }
191 
192  /* Get the page color */
193  OldBlink = MiGetPfnEntryIndex(Entry);
194  Color = OldBlink & MmSecondaryColorMask;
195 
196  /* Get the first page on the color list */
197  ColorTable = &MmFreePagesByColor[ListName][Color];
198 
199  /* Check if this was was actually the head */
200  OldFlink = ColorTable->Flink;
201  if (OldFlink == OldBlink)
202  {
203  /* Make the table point to the next page this page was linking to */
204  ColorTable->Flink = Entry->OriginalPte.u.Long;
205  if (ColorTable->Flink != LIST_HEAD)
206  {
207  /* And make the previous link point to the head now */
208  MI_PFN_ELEMENT(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
209  }
210  else
211  {
212  /* And if that page was the head, loop the list back around */
213  ColorTable->Blink = (PVOID)LIST_HEAD;
214  }
215  }
216  else
217  {
218  /* This page shouldn't be pointing back to the head */
219  ASSERT(Entry->u4.PteFrame != COLORED_LIST_HEAD);
220 
221  /* Make the back link point to whoever the next page is */
222  Pfn1 = MI_PFN_ELEMENT(Entry->u4.PteFrame);
223  Pfn1->OriginalPte.u.Long = Entry->OriginalPte.u.Long;
224 
225  /* Check if this page was pointing to the head */
226  if (Entry->OriginalPte.u.Long != LIST_HEAD)
227  {
228  /* Make the back link point to the head */
229  Pfn1 = MI_PFN_ELEMENT(Entry->OriginalPte.u.Long);
230  Pfn1->u4.PteFrame = Entry->u4.PteFrame;
231  }
232  else
233  {
234  /* Then the table is directly back pointing to this page now */
235  ColorTable->Blink = Pfn1;
236  }
237  }
238 
239  /* One less colored page */
240  ASSERT(ColorTable->Count >= 1);
241  ColorTable->Count--;
242 
243  /* ReactOS Hack */
244  Entry->OriginalPte.u.Long = 0;
245 
246  /* We are not on a list anymore */
247  Entry->u1.Flink = Entry->u2.Blink = 0;
248  ASSERT_LIST_INVARIANT(ListHead);
249 
250  /* Decrement number of available pages */
252 
253 #if MI_TRACE_PFNS
255  Entry->PfnUsage = MI_PFN_CURRENT_USAGE;
256  memcpy(Entry->ProcessName, MI_PFN_CURRENT_PROCESS_NAME, 16);
258  MI_SET_PROCESS2("Not Set");
259 #endif
260 }
261 
262 VOID
263 NTAPI
265 {
266  PMMPFNLIST ListHead;
267  PFN_NUMBER OldFlink, OldBlink;
268 
269  /* Make sure the PFN lock is held */
271 
272  /* ARM3 should only call this for dead pages */
273  ASSERT(Pfn->u3.e2.ReferenceCount == 0);
274 
275  /* Transition pages are supposed to be standby/modified/nowrite */
276  ListHead = MmPageLocationList[Pfn->u3.e1.PageLocation];
277  ASSERT(ListHead->ListName >= StandbyPageList);
278 
279  /* Check if this was standby, or modified */
280  if (ListHead == &MmStandbyPageListHead)
281  {
282  /* Should not be a ROM page */
283  ASSERT(Pfn->u3.e1.Rom == 0);
284 
285  /* Get the exact list */
286  ListHead = &MmStandbyPageListByPriority[Pfn->u4.Priority];
287 
288  /* Decrement number of available pages */
290 
291  /* Decrease transition page counter */
292  ASSERT(Pfn->u3.e1.PrototypePte == 1); /* Only supported ARM3 case */
294  }
295  else if (ListHead == &MmModifiedPageListHead)
296  {
297  /* Only shared memory (page-file backed) modified pages are supported */
298  ASSERT(Pfn->OriginalPte.u.Soft.Prototype == 0);
299 
300  /* Decrement the counters */
301  ListHead->Total--;
303 
304  /* Pick the correct colored list */
305  ListHead = &MmModifiedPageListByColor[0];
306 
307  /* Decrease transition page counter */
309  }
310  else if (ListHead == &MmModifiedNoWritePageListHead)
311  {
312  /* List not yet supported */
313  ASSERT(FALSE);
314  }
315 
316  /* Nothing should be in progress and the list should not be empty */
317  ASSERT(Pfn->u3.e1.WriteInProgress == 0);
318  ASSERT(Pfn->u3.e1.ReadInProgress == 0);
319  ASSERT(ListHead->Total != 0);
320 
321  /* Get the forward and back pointers */
322  OldFlink = Pfn->u1.Flink;
323  OldBlink = Pfn->u2.Blink;
324 
325  /* Check if the next entry is the list head */
326  if (OldFlink != LIST_HEAD)
327  {
328  /* It is not, so set the backlink of the actual entry, to our backlink */
329  MI_PFN_ELEMENT(OldFlink)->u2.Blink = OldBlink;
330  }
331  else
332  {
333  /* Set the list head's backlink instead */
334  ListHead->Blink = OldBlink;
335  }
336 
337  /* Check if the back entry is the list head */
338  if (OldBlink != LIST_HEAD)
339  {
340  /* It is not, so set the backlink of the actual entry, to our backlink */
341  MI_PFN_ELEMENT(OldBlink)->u1.Flink = OldFlink;
342  }
343  else
344  {
345  /* Set the list head's backlink instead */
346  ListHead->Flink = OldFlink;
347  }
348 
349  /* ReactOS Hack */
350  Pfn->OriginalPte.u.Long = 0;
351 
352  /* We are not on a list anymore */
353  Pfn->u1.Flink = Pfn->u2.Blink = 0;
354 
355  /* Remove one entry from the list */
356  ListHead->Total--;
357 
358  ASSERT_LIST_INVARIANT(ListHead);
359 }
360 
362 NTAPI
364  IN ULONG Color)
365 {
366  PMMPFN Pfn1;
367  PMMPFNLIST ListHead;
368  MMLISTS ListName;
369  PFN_NUMBER OldFlink, OldBlink;
370  USHORT OldColor, OldCache;
371  PMMCOLOR_TABLES ColorTable;
372 
373  /* Make sure PFN lock is held */
376 
377  /* Get the PFN entry */
378  Pfn1 = MI_PFN_ELEMENT(PageIndex);
379  ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
380  ASSERT(Pfn1->u3.e1.Rom == 0);
381 
382  /* Capture data for later */
383  OldColor = Pfn1->u3.e1.PageColor;
384  OldCache = Pfn1->u3.e1.CacheAttribute;
385 
386  /* Could be either on free or zero list */
387  ListHead = MmPageLocationList[Pfn1->u3.e1.PageLocation];
388  ASSERT_LIST_INVARIANT(ListHead);
389  ListName = ListHead->ListName;
390  ASSERT(ListName <= FreePageList);
391 
392  /* Remove a page */
393  ListHead->Total--;
394 
395  /* Get the forward and back pointers */
396  OldFlink = Pfn1->u1.Flink;
397  OldBlink = Pfn1->u2.Blink;
398 
399  /* Check if the next entry is the list head */
400  if (OldFlink != LIST_HEAD)
401  {
402  /* It is not, so set the backlink of the actual entry, to our backlink */
403  MI_PFN_ELEMENT(OldFlink)->u2.Blink = OldBlink;
404  }
405  else
406  {
407  /* Set the list head's backlink instead */
408  ListHead->Blink = OldBlink;
409  }
410 
411  /* Check if the back entry is the list head */
412  if (OldBlink != LIST_HEAD)
413  {
414  /* It is not, so set the backlink of the actual entry, to our backlink */
415  MI_PFN_ELEMENT(OldBlink)->u1.Flink = OldFlink;
416  }
417  else
418  {
419  /* Set the list head's backlink instead */
420  ListHead->Flink = OldFlink;
421  }
422 
423  /* We are not on a list anymore */
424  ASSERT_LIST_INVARIANT(ListHead);
425  Pfn1->u1.Flink = Pfn1->u2.Blink = 0;
426 
427  /* Zero flags but restore color and cache */
428  Pfn1->u3.e2.ShortFlags = 0;
429  Pfn1->u3.e1.PageColor = OldColor;
430  Pfn1->u3.e1.CacheAttribute = OldCache;
431 
432  /* Get the first page on the color list */
434  ColorTable = &MmFreePagesByColor[ListName][Color];
435  ASSERT(ColorTable->Count >= 1);
436 
437  /* Set the forward link to whoever we were pointing to */
438  ColorTable->Flink = Pfn1->OriginalPte.u.Long;
439 
440  /* Get the first page on the color list */
441  if (ColorTable->Flink == LIST_HEAD)
442  {
443  /* This is the beginning of the list, so set the sentinel value */
444  ColorTable->Blink = (PVOID)LIST_HEAD;
445  }
446  else
447  {
448  /* The list is empty, so we are the first page */
449  MI_PFN_ELEMENT(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
450  }
451 
452  /* One less page */
453  ColorTable->Count--;
454 
455  /* ReactOS Hack */
456  Pfn1->OriginalPte.u.Long = 0;
457 
458  /* Decrement number of available pages */
460 
461 #if MI_TRACE_PFNS
463  Pfn1->PfnUsage = MI_PFN_CURRENT_USAGE;
464  memcpy(Pfn1->ProcessName, MI_PFN_CURRENT_PROCESS_NAME, 16);
466  MI_SET_PROCESS2("Not Set");
467 #endif
468 
469  /* Return the page */
470  return PageIndex;
471 }
472 
474 NTAPI
476 {
477  PFN_NUMBER PageIndex;
478  PMMPFN Pfn1;
479 
480  /* Make sure PFN lock is held and we have pages */
482  ASSERT(MmAvailablePages != 0);
484 
485  /* Check the colored free list */
487  if (PageIndex == LIST_HEAD)
488  {
489  /* Check the colored zero list */
491  if (PageIndex == LIST_HEAD)
492  {
493  /* Check the free list */
495  PageIndex = MmFreePageListHead.Flink;
496  Color = PageIndex & MmSecondaryColorMask;
497  if (PageIndex == LIST_HEAD)
498  {
499  /* Check the zero list */
501  PageIndex = MmZeroedPageListHead.Flink;
502  Color = PageIndex & MmSecondaryColorMask;
503  ASSERT(PageIndex != LIST_HEAD);
504  if (PageIndex == LIST_HEAD)
505  {
506  /* FIXME: Should check the standby list */
508  }
509  }
510  }
511  }
512 
513  /* Remove the page from its list */
514  PageIndex = MiRemovePageByColor(PageIndex, Color);
515 
516  /* Sanity checks */
517  Pfn1 = MI_PFN_ELEMENT(PageIndex);
518  ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) ||
519  (Pfn1->u3.e1.PageLocation == ZeroedPageList));
520  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
521  ASSERT(Pfn1->u2.ShareCount == 0);
524 
525  /* Return the page */
526  return PageIndex;
527 }
528 
530 NTAPI
532 {
533  PFN_NUMBER PageIndex;
534  PMMPFN Pfn1;
535  BOOLEAN Zero = FALSE;
536 
537  /* Make sure PFN lock is held and we have pages */
539  ASSERT(MmAvailablePages != 0);
541 
542  /* Check the colored zero list */
544  if (PageIndex == LIST_HEAD)
545  {
546  /* Check the zero list */
548  PageIndex = MmZeroedPageListHead.Flink;
549  if (PageIndex == LIST_HEAD)
550  {
551  /* This means there's no zero pages, we have to look for free ones */
553  Zero = TRUE;
554 
555  /* Check the colored free list */
557  if (PageIndex == LIST_HEAD)
558  {
559  /* Check the free list */
561  PageIndex = MmFreePageListHead.Flink;
562  Color = PageIndex & MmSecondaryColorMask;
563  ASSERT(PageIndex != LIST_HEAD);
564  if (PageIndex == LIST_HEAD)
565  {
566  /* FIXME: Should check the standby list */
568  }
569  }
570  }
571  else
572  {
573  Color = PageIndex & MmSecondaryColorMask;
574  }
575  }
576 
577  /* Sanity checks */
578  Pfn1 = MI_PFN_ELEMENT(PageIndex);
579  ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) ||
580  (Pfn1->u3.e1.PageLocation == ZeroedPageList));
581 
582  /* Remove the page from its list */
583  PageIndex = MiRemovePageByColor(PageIndex, Color);
584  ASSERT(Pfn1 == MI_PFN_ELEMENT(PageIndex));
585 
586  /* Zero it, if needed */
587  if (Zero) MiZeroPhysicalPage(PageIndex);
588 
589  /* Sanity checks */
590  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
591  ASSERT(Pfn1->u2.ShareCount == 0);
594 
595  /* Return the page */
596  return PageIndex;
597 }
598 
599 /* HACK for keeping legacy Mm alive */
600 extern BOOLEAN MmRosNotifyAvailablePage(PFN_NUMBER PageFrameIndex);
601 
602 VOID
603 NTAPI
605 {
606  PMMPFNLIST ListHead;
607  PFN_NUMBER LastPage;
608  PMMPFN Pfn1;
609  ULONG Color;
610  PMMPFN Blink;
611  PMMCOLOR_TABLES ColorTable;
612 
613  /* Make sure the page index is valid */
615  ASSERT((PageFrameIndex != 0) &&
616  (PageFrameIndex <= MmHighestPhysicalPage) &&
617  (PageFrameIndex >= MmLowestPhysicalPage));
618 
619  /* Get the PFN entry */
620  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
621 
622  /* Sanity checks that a right kind of page is being inserted here */
623  ASSERT(Pfn1->u4.MustBeCached == 0);
624  ASSERT(Pfn1->u3.e1.Rom != 1);
625  ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
626  ASSERT(Pfn1->u4.VerifierAllocation == 0);
627  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
628 
629  /* HACK HACK HACK : Feed the page to legacy Mm */
630  if (MmRosNotifyAvailablePage(PageFrameIndex))
631  {
632  DPRINT1("Legacy Mm eating ARM3 page!.\n");
633  return;
634  }
635 
636  /* Get the free page list and increment its count */
637  ListHead = &MmFreePageListHead;
638  ASSERT_LIST_INVARIANT(ListHead);
639  ListHead->Total++;
640 
641  /* Get the last page on the list */
642  LastPage = ListHead->Blink;
643  if (LastPage != LIST_HEAD)
644  {
645  /* Link us with the previous page, so we're at the end now */
646  MI_PFN_ELEMENT(LastPage)->u1.Flink = PageFrameIndex;
647  }
648  else
649  {
650  /* The list is empty, so we are the first page */
651  ListHead->Flink = PageFrameIndex;
652  }
653 
654  /* Now make the list head point back to us (since we go at the end) */
655  ListHead->Blink = PageFrameIndex;
656  ASSERT_LIST_INVARIANT(ListHead);
657 
658  /* And initialize our own list pointers */
659  Pfn1->u1.Flink = LIST_HEAD;
660  Pfn1->u2.Blink = LastPage;
661 
662  /* Set the list name and default priority */
663  Pfn1->u3.e1.PageLocation = FreePageList;
664  Pfn1->u4.Priority = 3;
665 
666  /* Clear some status fields */
667  Pfn1->u4.InPageError = 0;
668  Pfn1->u4.AweAllocation = 0;
669 
670  /* Increment number of available pages */
672 
673  /* Get the page color */
674  Color = PageFrameIndex & MmSecondaryColorMask;
675 
676  /* Get the first page on the color list */
677  ColorTable = &MmFreePagesByColor[FreePageList][Color];
678  if (ColorTable->Flink == LIST_HEAD)
679  {
680  /* The list is empty, so we are the first page */
681  Pfn1->u4.PteFrame = COLORED_LIST_HEAD;
682  ColorTable->Flink = PageFrameIndex;
683  }
684  else
685  {
686  /* Get the previous page */
687  Blink = (PMMPFN)ColorTable->Blink;
688 
689  /* Make it link to us, and link back to it */
690  Blink->OriginalPte.u.Long = PageFrameIndex;
691  Pfn1->u4.PteFrame = MiGetPfnEntryIndex(Blink);
692  }
693 
694  /* Now initialize our own list pointers */
695  ColorTable->Blink = Pfn1;
696 
697  /* This page is now the last */
698  Pfn1->OriginalPte.u.Long = LIST_HEAD;
699 
700  /* And increase the count in the colored list */
701  ColorTable->Count++;
702 
703  /* Notify zero page thread if enough pages are on the free list now */
704  if (ListHead->Total >= 8)
705  {
706  /* Set the event */
708  }
709 
710 #if MI_TRACE_PFNS
711  Pfn1->PfnUsage = MI_USAGE_FREE_PAGE;
712  RtlZeroMemory(Pfn1->ProcessName, 16);
713 #endif
714 }
715 
716 VOID
717 FASTCALL
719 {
720  PMMPFNLIST ListHead;
721  PFN_NUMBER Flink;
722  PMMPFN Pfn1, Pfn2;
723 
724  /* Make sure the lock is held */
725  DPRINT("Inserting page: %lx into standby list !\n", PageFrameIndex);
727 
728  /* Make sure the PFN is valid */
729  ASSERT((PageFrameIndex != 0) &&
730  (PageFrameIndex <= MmHighestPhysicalPage) &&
731  (PageFrameIndex >= MmLowestPhysicalPage));
732 
733  /* Grab the PFN and validate it is the right kind of PFN being inserted */
734  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
735  ASSERT(Pfn1->u4.MustBeCached == 0);
736  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
737  ASSERT(Pfn1->u3.e1.PrototypePte == 1);
738  ASSERT(Pfn1->u3.e1.Rom != 1);
739 
740  /* One more transition page on a list */
742 
743  /* Get the standby page list and increment its count */
744  ListHead = &MmStandbyPageListByPriority [Pfn1->u4.Priority];
745  ASSERT_LIST_INVARIANT(ListHead);
746  ListHead->Total++;
747 
748  /* Make the head of the list point to this page now */
749  Flink = ListHead->Flink;
750  ListHead->Flink = PageFrameIndex;
751 
752  /* Make the page point to the previous head, and back to the list */
753  Pfn1->u1.Flink = Flink;
754  Pfn1->u2.Blink = LIST_HEAD;
755 
756  /* Was the list empty? */
757  if (Flink != LIST_HEAD)
758  {
759  /* It wasn't, so update the backlink of the previous head page */
760  Pfn2 = MI_PFN_ELEMENT(Flink);
761  Pfn2->u2.Blink = PageFrameIndex;
762  }
763  else
764  {
765  /* It was empty, so have it loop back around to this new page */
766  ListHead->Blink = PageFrameIndex;
767  }
768 
769  /* Move the page onto its new location */
771 
772  /* Increment number of available pages */
774 }
775 
776 VOID
777 NTAPI
779  IN PFN_NUMBER PageFrameIndex)
780 {
781  PFN_NUMBER Flink, LastPage;
782  PMMPFN Pfn1, Pfn2;
783  MMLISTS ListName;
784  PMMCOLOR_TABLES ColorHead;
785  ULONG Color;
786 
787  /* For free pages, use MiInsertPageInFreeList */
788  ASSERT(ListHead != &MmFreePageListHead);
789 
790  /* Make sure the lock is held */
792 
793  /* Make sure the PFN is valid */
794  ASSERT((PageFrameIndex) &&
795  (PageFrameIndex <= MmHighestPhysicalPage) &&
796  (PageFrameIndex >= MmLowestPhysicalPage));
797 
798  /* Page should be unused */
799  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
800  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
801  ASSERT(Pfn1->u3.e1.Rom != 1);
802 
803  /* Is a standby or modified page being inserted? */
804  ListName = ListHead->ListName;
805  if ((ListName == StandbyPageList) || (ListName == ModifiedPageList))
806  {
807  /* If the page is in transition, it must also be a prototype page */
808  if ((Pfn1->OriginalPte.u.Soft.Prototype == 0) &&
809  (Pfn1->OriginalPte.u.Soft.Transition == 1))
810  {
811  /* Crash the system on inconsistency */
812  KeBugCheckEx(MEMORY_MANAGEMENT, 0x8888, 0, 0, 0);
813  }
814  }
815 
816  /* Standby pages are prioritized, so we need to get the real head */
817  if (ListHead == &MmStandbyPageListHead)
818  {
819  /* Obviously the prioritized list should still have the same name */
820  ListHead = &MmStandbyPageListByPriority[Pfn1->u4.Priority];
821  ASSERT(ListHead->ListName == ListName);
822  }
823 
824  /* Increment the list count */
825  ListHead->Total++;
826 
827  /* Is a modified page being inserted? */
828  if (ListHead == &MmModifiedPageListHead)
829  {
830  /* For now, only single-prototype pages should end up in this path */
831  DPRINT("Modified page being added: %lx\n", PageFrameIndex);
832  ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
833 
834  /* Modified pages are colored when they are selected for page file */
835  ListHead = &MmModifiedPageListByColor[0];
836  ASSERT (ListHead->ListName == ListName);
837  ListHead->Total++;
838 
839  /* Increment the number of paging file modified pages */
841  }
842 
843  /* Don't handle bad pages yet yet */
844  ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
845 
846  /* Zero pages go to the head, all other pages go to the end */
847  if (ListName == ZeroedPageList)
848  {
849  /* Make the head of the list point to this page now */
850  Flink = ListHead->Flink;
851  ListHead->Flink = PageFrameIndex;
852 
853  /* Make the page point to the previous head, and back to the list */
854  Pfn1->u1.Flink = Flink;
855  Pfn1->u2.Blink = LIST_HEAD;
856 
857  /* Was the list empty? */
858  if (Flink != LIST_HEAD)
859  {
860  /* It wasn't, so update the backlink of the previous head page */
861  Pfn2 = MI_PFN_ELEMENT(Flink);
862  Pfn2->u2.Blink = PageFrameIndex;
863  }
864  else
865  {
866  /* It was empty, so have it loop back around to this new page */
867  ListHead->Blink = PageFrameIndex;
868  }
869  }
870  else
871  {
872  /* Get the last page on the list */
873  LastPage = ListHead->Blink;
874  if (LastPage != LIST_HEAD)
875  {
876  /* Link us with the previous page, so we're at the end now */
877  MI_PFN_ELEMENT(LastPage)->u1.Flink = PageFrameIndex;
878  }
879  else
880  {
881  /* The list is empty, so we are the first page */
882  ListHead->Flink = PageFrameIndex;
883  }
884 
885  /* Now make the list head point back to us (since we go at the end) */
886  ListHead->Blink = PageFrameIndex;
887  ASSERT_LIST_INVARIANT(ListHead);
888 
889  /* And initialize our own list pointers */
890  Pfn1->u1.Flink = LIST_HEAD;
891  Pfn1->u2.Blink = LastPage;
892  }
893 
894  /* Move the page onto its new location */
895  Pfn1->u3.e1.PageLocation = ListName;
896 
897  /* For zero/free pages, we also have to handle the colored lists */
898  if (ListName <= StandbyPageList)
899  {
900  /* Increment number of available pages */
902 
903  /* Sanity checks */
904  ASSERT(ListName == ZeroedPageList);
905  ASSERT(Pfn1->u4.InPageError == 0);
906 
907  /* Get the page color */
908  Color = PageFrameIndex & MmSecondaryColorMask;
909 
910  /* Get the list for this color */
911  ColorHead = &MmFreePagesByColor[ZeroedPageList][Color];
912 
913  /* Get the old head */
914  Flink = ColorHead->Flink;
915 
916  /* Make this page point back to the list, and point forwards to the old head */
917  Pfn1->OriginalPte.u.Long = Flink;
918  Pfn1->u4.PteFrame = COLORED_LIST_HEAD;
919 
920  /* Set the new head */
921  ColorHead->Flink = PageFrameIndex;
922 
923  /* Was the head empty? */
924  if (Flink != LIST_HEAD)
925  {
926  /* No, so make the old head point to this page */
927  Pfn2 = MI_PFN_ELEMENT(Flink);
928  Pfn2->u4.PteFrame = PageFrameIndex;
929  }
930  else
931  {
932  /* Yes, make it loop back to this page */
933  ColorHead->Blink = (PVOID)Pfn1;
934  }
935 
936  /* One more paged on the colored list */
937  ColorHead->Count++;
938 
939 #if MI_TRACE_PFNS
941  Pfn1->PfnUsage = MI_USAGE_FREE_PAGE;
942  RtlZeroMemory(Pfn1->ProcessName, 16);
943 #endif
944  }
945  else if (ListName == ModifiedPageList)
946  {
947  /* In ARM3, page must be destined for page file, and not yet written out */
948  ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
949  ASSERT(Pfn1->OriginalPte.u.Soft.PageFileHigh == 0);
950 
951  /* One more transition page */
953 
954  /* Increment the number of per-process modified pages */
955  PsGetCurrentProcess()->ModifiedPageCount++;
956 
957  /* FIXME: Wake up modified page writer if there are not enough free pages */
958  }
959  else if (ListName == ModifiedNoWritePageList)
960  {
961  /* This list is not yet implemented */
962  ASSERT(FALSE);
963  }
964 }
965 
966 VOID
967 NTAPI
969  IN PMMPTE PointerPte,
970  IN BOOLEAN Modified)
971 {
972  PMMPFN Pfn1;
974  PMMPTE PointerPtePte;
976 
977  /* Setup the PTE */
978  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
979  Pfn1->PteAddress = PointerPte;
980 
981  /* Check if this PFN is part of a valid address space */
982  if (PointerPte->u.Hard.Valid == 1)
983  {
984  /* Only valid from MmCreateProcessAddressSpace path */
986 
987  /* Make this a demand zero PTE */
989  }
990  else
991  {
992  /* Copy the PTE data */
993  Pfn1->OriginalPte = *PointerPte;
994  ASSERT(!((Pfn1->OriginalPte.u.Soft.Prototype == 0) &&
995  (Pfn1->OriginalPte.u.Soft.Transition == 1)));
996  }
997 
998  /* Otherwise this is a fresh page -- set it up */
999  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
1000  Pfn1->u3.e2.ReferenceCount = 1;
1001  Pfn1->u2.ShareCount = 1;
1002  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1003  ASSERT(Pfn1->u3.e1.Rom == 0);
1004  Pfn1->u3.e1.Modified = Modified;
1005 
1006  /* Get the page table for the PTE */
1007  PointerPtePte = MiAddressToPte(PointerPte);
1008  if (PointerPtePte->u.Hard.Valid == 0)
1009  {
1010  /* Make sure the PDE gets paged in properly */
1011  Status = MiCheckPdeForPagedPool(PointerPte);
1012  if (!NT_SUCCESS(Status))
1013  {
1014  /* Crash */
1015  KeBugCheckEx(MEMORY_MANAGEMENT,
1016  0x61940,
1017  (ULONG_PTR)PointerPte,
1018  (ULONG_PTR)PointerPtePte->u.Long,
1019  (ULONG_PTR)MiPteToAddress(PointerPte));
1020  }
1021  }
1022 
1023  /* Get the PFN for the page table */
1024  PageFrameIndex = PFN_FROM_PTE(PointerPtePte);
1025  ASSERT(PageFrameIndex != 0);
1026  Pfn1->u4.PteFrame = PageFrameIndex;
1027 
1028  /* Increase its share count so we don't get rid of it */
1029  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
1030  Pfn1->u2.ShareCount++;
1031 }
1032 
1033 VOID
1034 NTAPI
1036  IN PMMPTE PointerPte,
1037  IN MMPTE TempPte)
1038 {
1039  PMMPFN Pfn1;
1040  NTSTATUS Status;
1041  PMMPTE PointerPtePte;
1043 
1044  /* PTE must be invalid */
1045  ASSERT(PointerPte->u.Hard.Valid == 0);
1046 
1047  /* Setup the PTE */
1048  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
1049  Pfn1->PteAddress = PointerPte;
1050  Pfn1->OriginalPte = DemandZeroPte;
1051 
1052  /* Otherwise this is a fresh page -- set it up */
1053  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
1054  Pfn1->u3.e2.ReferenceCount++;
1055  Pfn1->u2.ShareCount++;
1056  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1057  ASSERT(Pfn1->u3.e1.Rom == 0);
1058  Pfn1->u3.e1.Modified = 1;
1059 
1060  /* Get the page table for the PTE */
1061  PointerPtePte = MiAddressToPte(PointerPte);
1062  if (PointerPtePte->u.Hard.Valid == 0)
1063  {
1064  /* Make sure the PDE gets paged in properly */
1065  Status = MiCheckPdeForPagedPool(PointerPte);
1066  if (!NT_SUCCESS(Status))
1067  {
1068  /* Crash */
1069  KeBugCheckEx(MEMORY_MANAGEMENT,
1070  0x61940,
1071  (ULONG_PTR)PointerPte,
1072  (ULONG_PTR)PointerPtePte->u.Long,
1073  (ULONG_PTR)MiPteToAddress(PointerPte));
1074  }
1075  }
1076 
1077  /* Get the PFN for the page table */
1078  PageFrameIndex = PFN_FROM_PTE(PointerPtePte);
1079  ASSERT(PageFrameIndex != 0);
1080  Pfn1->u4.PteFrame = PageFrameIndex;
1081 
1082  /* Increase its share count so we don't get rid of it */
1083  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
1084  Pfn1->u2.ShareCount++;
1085 
1086  /* Write valid PTE */
1087  MI_WRITE_VALID_PTE(PointerPte, TempPte);
1088 }
1089 
1090 NTSTATUS
1091 NTAPI
1093  IN PMMPDE PointerPde,
1094  IN PFN_NUMBER ContainingPageFrame,
1095  IN BOOLEAN SessionAllocation)
1096 {
1097  MMPDE TempPde;
1098  KIRQL OldIrql;
1099 
1100  /* Use either a global or local PDE */
1101  TempPde = SessionAllocation ? ValidKernelPdeLocal : ValidKernelPde;
1102 
1103  /* Lock the PFN database */
1105 
1106  /* Make sure nobody is racing us */
1107  if (PointerPde->u.Hard.Valid == 1)
1108  {
1109  /* Return special error if that was the case */
1111  return STATUS_RETRY;
1112  }
1113 
1114  /* Grab a zero page and set the PFN, then make it valid */
1115  *PageFrameIndex = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
1116  TempPde.u.Hard.PageFrameNumber = *PageFrameIndex;
1117  MI_WRITE_VALID_PDE(PointerPde, TempPde);
1118 
1119  /* Initialize the PFN */
1120  MiInitializePfnForOtherProcess(*PageFrameIndex,
1121  PointerPde,
1122  ContainingPageFrame);
1123  ASSERT(MI_PFN_ELEMENT(*PageFrameIndex)->u1.WsIndex == 0);
1124 
1125  /* Release the lock and return success */
1127  return STATUS_SUCCESS;
1128 }
1129 
1130 VOID
1131 NTAPI
1133  IN PFN_NUMBER PageFrameIndex)
1134 {
1135  PMMPTE PointerPte;
1136  MMPTE TempPte;
1137 
1138  ASSERT(PageFrameIndex > 0);
1139  ASSERT(MI_PFN_ELEMENT(PageFrameIndex) != NULL);
1140  ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
1141  ASSERT(MI_IS_ROS_PFN(Pfn1) == FALSE);
1142 
1143  /* Page must be in-use */
1144  if ((Pfn1->u3.e1.PageLocation != ActiveAndValid) &&
1145  (Pfn1->u3.e1.PageLocation != StandbyPageList))
1146  {
1147  /* Otherwise we have PFN corruption */
1148  KeBugCheckEx(PFN_LIST_CORRUPT,
1149  0x99,
1150  PageFrameIndex,
1151  Pfn1->u3.e1.PageLocation,
1152  0);
1153  }
1154 
1155  /* Page should at least have one reference */
1156  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
1157 
1158  /* Check if the share count is now 0 */
1159  ASSERT(Pfn1->u2.ShareCount < 0xF000000);
1160  if (!--Pfn1->u2.ShareCount)
1161  {
1162  /* Was this a prototype PTE? */
1163  if (Pfn1->u3.e1.PrototypePte)
1164  {
1165  /* Grab the PTE address and make sure it's in prototype pool */
1166  PointerPte = Pfn1->PteAddress;
1167  ASSERT((PointerPte >= (PMMPTE)MmPagedPoolStart) && (PointerPte <= (PMMPTE)MmPagedPoolEnd));
1168 
1169  /* The PTE that backs it should also be valdi */
1170  PointerPte = MiAddressToPte(PointerPte);
1171  ASSERT(PointerPte->u.Hard.Valid == 1);
1172 
1173  /* Get the original prototype PTE and turn it into a transition PTE */
1174  PointerPte = Pfn1->PteAddress;
1175  TempPte = *PointerPte;
1176  TempPte.u.Soft.Transition = 1;
1177  TempPte.u.Soft.Valid = 0;
1178  TempPte.u.Soft.Prototype = 0;
1179  TempPte.u.Soft.Protection = Pfn1->OriginalPte.u.Soft.Protection;
1180  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1181  DPRINT("Marking PTE: %p as transition (%p - %lx)\n", PointerPte, Pfn1, MiGetPfnEntryIndex(Pfn1));
1182  }
1183 
1184  /* Put the page in transition */
1185  Pfn1->u3.e1.PageLocation = TransitionPage;
1186 
1187  /* PFN lock must be held */
1189 
1190  if (Pfn1->u3.e2.ReferenceCount == 1)
1191  {
1192  /* Is there still a PFN for this page? */
1193  if (MI_IS_PFN_DELETED(Pfn1))
1194  {
1195  /* Clear the last reference */
1196  Pfn1->u3.e2.ReferenceCount = 0;
1197  ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
1198 
1199  /* Mark the page temporarily as valid, we're going to make it free soon */
1200  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1201 
1202  /* Bring it back into the free list */
1203  MiInsertPageInFreeList(PageFrameIndex);
1204  }
1205  else
1206  {
1207  /* PFN not yet deleted, drop a ref count */
1208  MiDecrementReferenceCount(Pfn1, PageFrameIndex);
1209  }
1210  }
1211  else
1212  {
1213  /* Otherwise, just drop the reference count */
1214  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
1215  }
1216  }
1217 }
1218 
1219 VOID
1220 NTAPI
1222  IN PFN_NUMBER PageFrameIndex)
1223 {
1224  /* PFN lock must be held */
1226 
1227  /* Sanity checks on the page */
1228  if (PageFrameIndex > MmHighestPhysicalPage ||
1229  Pfn1 != MI_PFN_ELEMENT(PageFrameIndex) ||
1230  Pfn1->u3.e2.ReferenceCount == 0 ||
1231  Pfn1->u3.e2.ReferenceCount >= 2500)
1232  {
1233  DPRINT1("PageFrameIndex=0x%lx, MmHighestPhysicalPage=0x%lx\n", PageFrameIndex, MmHighestPhysicalPage);
1234  DPRINT1("Pfn1=%p, Element=%p, RefCount=%u\n", Pfn1, MI_PFN_ELEMENT(PageFrameIndex), Pfn1->u3.e2.ReferenceCount);
1235  ASSERT(PageFrameIndex <= MmHighestPhysicalPage);
1236  ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
1237  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
1238  ASSERT(Pfn1->u3.e2.ReferenceCount < 2500);
1239  }
1240 
1241  /* Dereference the page, bail out if it's still alive */
1242  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
1243  if (Pfn1->u3.e2.ReferenceCount) return;
1244 
1245  /* Nobody should still have reference to this page */
1246  if (Pfn1->u2.ShareCount != 0)
1247  {
1248  /* Otherwise something's really wrong */
1249  KeBugCheckEx(PFN_LIST_CORRUPT, 7, PageFrameIndex, Pfn1->u2.ShareCount, 0);
1250  }
1251 
1252  /* And it should be lying on some page list */
1253  ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
1254 
1255  /* Did someone set the delete flag? */
1256  if (MI_IS_PFN_DELETED(Pfn1))
1257  {
1258  /* Insert it into the free list, there's nothing left to do */
1259  MiInsertPageInFreeList(PageFrameIndex);
1260  return;
1261  }
1262 
1263  /* Check to see which list this page should go into */
1264  if (Pfn1->u3.e1.Modified == 1)
1265  {
1266  /* Push it into the modified page list */
1267  MiInsertPageInList(&MmModifiedPageListHead, PageFrameIndex);
1268  }
1269  else
1270  {
1271  /* Otherwise, insert this page into the standby list */
1272  ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
1273  MiInsertStandbyListAtFront(PageFrameIndex);
1274  }
1275 }
1276 
1277 VOID
1278 NTAPI
1280  IN PVOID PteAddress,
1281  IN PFN_NUMBER PteFrame)
1282 {
1283  PMMPFN Pfn1;
1284 
1285  /* Setup the PTE */
1286  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
1287  Pfn1->PteAddress = PteAddress;
1288 
1289  /* Make this a software PTE */
1291 
1292  /* Setup the page */
1293  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
1294  Pfn1->u3.e2.ReferenceCount = 1;
1295  Pfn1->u2.ShareCount = 1;
1296  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1297  Pfn1->u3.e1.Modified = TRUE;
1298  Pfn1->u4.InPageError = FALSE;
1299 
1300  /* Did we get a PFN for the page table */
1301  if (PteFrame)
1302  {
1303  /* Store it */
1304  Pfn1->u4.PteFrame = PteFrame;
1305 
1306  /* Increase its share count so we don't get rid of it */
1307  Pfn1 = MI_PFN_ELEMENT(PteFrame);
1308  Pfn1->u2.ShareCount++;
1309  }
1310 }
1311 
1312 /* EOF */
#define MI_MAKE_SOFTWARE_PTE(p, x)
Definition: miarm.h:189
MMSUPPORT Vm
Definition: miarm.h:510
VOID FASTCALL MiInsertStandbyListAtFront(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:718
#define IN
Definition: typedefs.h:39
VOID NTAPI MiInitializePfn(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
Definition: pfnlist.c:968
VOID NTAPI MiUnlinkPageFromList(IN PMMPFN Pfn)
Definition: pfnlist.c:264
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:531
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1035
PVOID Blink
Definition: miarm.h:442
NTSTATUS NTAPI MiInitializeAndChargePfn(OUT PPFN_NUMBER PageFrameIndex, IN PMMPDE PointerPde, IN PFN_NUMBER ContainingPageFrame, IN BOOLEAN SessionAllocation)
Definition: pfnlist.c:1092
ULONG MI_PFN_CURRENT_USAGE
Definition: pfnlist.c:63
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:965
PFN_NUMBER MmMinimumFreePages
Definition: mminit.c:314
union _MMPTE::@2304 u
signed short * PSHORT
Definition: retypes.h:6
MMPFNLIST MmBadPageListHead
Definition: pfnlist.c:48
#define TRUE
Definition: types.h:120
ULONG_PTR AweAllocation
Definition: mm.h:393
MMPFNLIST MmStandbyPageListHead
Definition: pfnlist.c:43
ULONG MmTotalPagesForPagingFile
Definition: pfnlist.c:39
struct _MMPFN::@1778::@1784 e2
PFN_NUMBER NTAPI MiRemovePageByColor(IN PFN_NUMBER PageIndex, IN ULONG Color)
Definition: pfnlist.c:363
MMLISTS ListName
Definition: mm.h:415
char CHAR
Definition: xmlstorage.h:175
VOID NTAPI MiInsertPageInList(IN PMMPFNLIST ListHead, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:778
LONG NTSTATUS
Definition: precomp.h:26
PFN_NUMBER MmHighMemoryThreshold
Definition: mminit.c:301
PFN_NUMBER Flink
Definition: mm.h:349
#define ASSERT_LIST_INVARIANT(x)
Definition: pfnlist.c:29
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:242
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:930
USHORT Modified
Definition: mm.h:332
PVOID MmPagedPoolEnd
Definition: init.c:26
PFN_NUMBER MmLowestPhysicalPage
Definition: meminit.c:30
USHORT RemovalRequested
Definition: mm.h:338
MMPFNLIST MmFreePageListHead
Definition: pfnlist.c:42
NTSTATUS FASTCALL MiCheckPdeForPagedPool(IN PVOID Address)
Definition: pagfault.c:475
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FASTCALL
Definition: nt_native.h:50
union _MMPFN::@1781 u4
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:937
union _MMPFN::@1778 u3
USHORT PageLocation
Definition: mm.h:337
struct Color Color
PFN_NUMBER Flink
Definition: mm.h:416
enum _MMLISTS MMLISTS
uint32_t ULONG_PTR
Definition: typedefs.h:65
USHORT PrototypePte
Definition: mm.h:335
PMMPFNLIST MmPageLocationList[]
Definition: pfnlist.c:51
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:369
ULONG * PPFN_NUMBER
Definition: ke.h:9
USHORT CacheAttribute
Definition: mm.h:339
#define MiAddressToPte(x)
Definition: mmx86.c:19
union _MMPFN::@1776 u1
ULONG PFN_NUMBER
Definition: ke.h:9
ULONG_PTR MustBeCached
Definition: mm.h:395
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:951
ULONG_PTR ShareCount
Definition: mm.h:362
ULONG MmTransitionSharedPages
Definition: pfnlist.c:38
VOID NTAPI MmRebalanceMemoryConsumers(VOID)
Definition: balance.c:266
PFN_NUMBER Blink
Definition: mm.h:417
PFN_NUMBER Flink
Definition: miarm.h:441
#define MI_SET_PROCESS2(x)
Definition: mm.h:291
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:28
BOOLEAN MmMirroring
Definition: pfnlist.c:35
unsigned char BOOLEAN
ULONG_PTR VerifierAllocation
Definition: mm.h:392
MMPFNLIST MmRomPageListHead
Definition: pfnlist.c:49
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
KEVENT MmZeroingPageEvent
Definition: zeropage.c:20
ULONG MmSecondaryColorMask
Definition: mminit.c:257
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1010
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
void * PVOID
Definition: retypes.h:9
PMMCOLOR_TABLES MmFreePagesByColor[FreePageList+1]
Definition: mminit.c:286
MMPFNLIST MmModifiedPageListHead
Definition: pfnlist.c:45
MMPFNLIST MmModifiedNoWritePageListHead
Definition: pfnlist.c:47
Status
Definition: gdiplustypes.h:24
ULONG PageFrameNumber
Definition: mmtypes.h:74
static VOID MiDecrementAvailablePages(VOID)
Definition: pfnlist.c:90
VOID FASTCALL KeZeroPages(IN PVOID Address, IN ULONG Size)
Definition: stubs.c:91
#define ASSERT(a)
Definition: mode.c:45
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG64 Valid
Definition: mmtypes.h:150
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:195
VOID NTAPI MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
Definition: pfnlist.c:137
BOOLEAN MmRosNotifyAvailablePage(PFN_NUMBER PageFrameIndex)
Definition: balance.c:380
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
ULONG MmSystemPageColor
Definition: pfnlist.c:36
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:91
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1557
PFN_NUMBER MmLowMemoryThreshold
Definition: mminit.c:300
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define MM_READWRITE
Definition: inbv.c:12
ULONG64 PageFileHigh
Definition: mmtypes.h:93
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:604
Definition: mm.h:345
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
MMPFNLIST MmModifiedPageListByColor[1]
Definition: pfnlist.c:46
ULONG64 Prototype
Definition: mmtypes.h:89
#define PAGE_SIZE
Definition: env_spec_w32.h:49
static VOID MiIncrementAvailablePages(VOID)
Definition: pfnlist.c:69
ULONG MmSecondaryColors
Definition: mminit.c:256
LIST_HEAD(acpi_bus_event_list)
ULONG_PTR Priority
Definition: mm.h:394
MMPTE ValidKernelPdeLocal
Definition: init.c:32
MMPTE ValidKernelPde
Definition: init.c:28
#define InterlockedDecrement16
Definition: interlocked.h:139
ULONG_PTR Long
Definition: mmtypes.h:215
PVOID MmPagedPoolStart
Definition: miarm.h:584
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:984
USHORT PageColor
Definition: mm.h:336
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1279
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1221
unsigned short USHORT
Definition: pedump.c:61
MMPFNLIST MmZeroedPageListHead
Definition: pfnlist.c:41
ULONG_PTR PteFrame
Definition: mm.h:390
ULONG64 Transition
Definition: mmtypes.h:90
PFN_NUMBER Total
Definition: mm.h:414
struct _MMPFN * PMMPFN
#define MI_IS_ROS_PFN(x)
Definition: miarm.h:1086
USHORT Rom
Definition: mm.h:340
PMMPTE PteAddress
Definition: mm.h:358
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
#define NULL
Definition: types.h:112
MMPTE OriginalPte
Definition: mm.h:379
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:411
#define DPRINT1
Definition: precomp.h:8
#define STATUS_RETRY
Definition: udferr_usr.h:182
ULONG WsIndex
Definition: mm.h:350
PFN_NUMBER Blink
Definition: mm.h:361
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:989
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
union _MMPFN::@1777 u2
MMPFNLIST MmStandbyPageListByPriority[8]
Definition: pfnlist.c:44
MMPTE DemandZeroPte
Definition: init.c:37
PFN_NUMBER Count
Definition: miarm.h:443
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
ULONG_PTR InPageError
Definition: mm.h:391
#define STATUS_SUCCESS
Definition: shellext.h:65
PKEVENT MiLowMemoryEvent
Definition: mminit.c:292
#define DPRINT
Definition: sndvol32.h:71
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
ULONG WorkingSetSize
Definition: mmtypes.h:943
BOOLEAN MmDynamicPfn
Definition: pfnlist.c:34
PKEVENT MiHighMemoryEvent
Definition: mminit.c:293
#define PFN_FROM_PTE(v)
Definition: mm.h:92
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1132
base of all file and directory entries
Definition: entries.h:82
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
CHAR MI_PFN_CURRENT_PROCESS_NAME[16]
Definition: pfnlist.c:64
Definition: mm.h:412