ReactOS  0.4.15-dev-3326-ga91f5e8
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);
257  Entry->CallSite = _ReturnAddress();
259  MI_SET_PROCESS2("Not Set");
260 #endif
261 }
262 
263 VOID
264 NTAPI
266 {
267  PMMPFNLIST ListHead;
268  PFN_NUMBER OldFlink, OldBlink;
269 
270  /* Make sure the PFN lock is held */
272 
273  /* ARM3 should only call this for dead pages */
274  ASSERT(Pfn->u3.e2.ReferenceCount == 0);
275 
276  /* Transition pages are supposed to be standby/modified/nowrite */
277  ListHead = MmPageLocationList[Pfn->u3.e1.PageLocation];
278  ASSERT(ListHead->ListName >= StandbyPageList);
279 
280  /* Check if this was standby, or modified */
281  if (ListHead == &MmStandbyPageListHead)
282  {
283  /* Should not be a ROM page */
284  ASSERT(Pfn->u3.e1.Rom == 0);
285 
286  /* Get the exact list */
287  ListHead = &MmStandbyPageListByPriority[Pfn->u4.Priority];
288 
289  /* Decrement number of available pages */
291 
292  /* Decrease transition page counter */
293  ASSERT(Pfn->u3.e1.PrototypePte == 1); /* Only supported ARM3 case */
295  }
296  else if (ListHead == &MmModifiedPageListHead)
297  {
298  /* Only shared memory (page-file backed) modified pages are supported */
299  ASSERT(Pfn->OriginalPte.u.Soft.Prototype == 0);
300 
301  /* Decrement the counters */
302  ListHead->Total--;
304 
305  /* Pick the correct colored list */
306  ListHead = &MmModifiedPageListByColor[0];
307 
308  /* Decrease transition page counter */
310  }
311  else if (ListHead == &MmModifiedNoWritePageListHead)
312  {
313  /* List not yet supported */
314  ASSERT(FALSE);
315  }
316 
317  /* Nothing should be in progress and the list should not be empty */
318  ASSERT(Pfn->u3.e1.WriteInProgress == 0);
319  ASSERT(Pfn->u3.e1.ReadInProgress == 0);
320  ASSERT(ListHead->Total != 0);
321 
322  /* Get the forward and back pointers */
323  OldFlink = Pfn->u1.Flink;
324  OldBlink = Pfn->u2.Blink;
325 
326  /* Check if the next entry is the list head */
327  if (OldFlink != LIST_HEAD)
328  {
329  /* It is not, so set the backlink of the actual entry, to our backlink */
330  MI_PFN_ELEMENT(OldFlink)->u2.Blink = OldBlink;
331  }
332  else
333  {
334  /* Set the list head's backlink instead */
335  ListHead->Blink = OldBlink;
336  }
337 
338  /* Check if the back entry is the list head */
339  if (OldBlink != LIST_HEAD)
340  {
341  /* It is not, so set the backlink of the actual entry, to our backlink */
342  MI_PFN_ELEMENT(OldBlink)->u1.Flink = OldFlink;
343  }
344  else
345  {
346  /* Set the list head's backlink instead */
347  ListHead->Flink = OldFlink;
348  }
349 
350  /* ReactOS Hack */
351  Pfn->OriginalPte.u.Long = 0;
352 
353  /* We are not on a list anymore */
354  Pfn->u1.Flink = Pfn->u2.Blink = 0;
355 
356  /* Remove one entry from the list */
357  ListHead->Total--;
358 
359  ASSERT_LIST_INVARIANT(ListHead);
360 }
361 
363 NTAPI
365  IN ULONG Color)
366 {
367  PMMPFN Pfn1;
368  PMMPFNLIST ListHead;
369  MMLISTS ListName;
370  PFN_NUMBER OldFlink, OldBlink;
371  USHORT OldColor, OldCache;
372  PMMCOLOR_TABLES ColorTable;
373 
374  /* Make sure PFN lock is held */
377 
378  /* Get the PFN entry */
379  Pfn1 = MI_PFN_ELEMENT(PageIndex);
380  ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
381  ASSERT(Pfn1->u3.e1.Rom == 0);
382 
383  /* Capture data for later */
384  OldColor = Pfn1->u3.e1.PageColor;
385  OldCache = Pfn1->u3.e1.CacheAttribute;
386 
387  /* Could be either on free or zero list */
388  ListHead = MmPageLocationList[Pfn1->u3.e1.PageLocation];
389  ASSERT_LIST_INVARIANT(ListHead);
390  ListName = ListHead->ListName;
391  ASSERT(ListName <= FreePageList);
392 
393  /* Remove a page */
394  ListHead->Total--;
395 
396  /* Get the forward and back pointers */
397  OldFlink = Pfn1->u1.Flink;
398  OldBlink = Pfn1->u2.Blink;
399 
400  /* Check if the next entry is the list head */
401  if (OldFlink != LIST_HEAD)
402  {
403  /* It is not, so set the backlink of the actual entry, to our backlink */
404  MI_PFN_ELEMENT(OldFlink)->u2.Blink = OldBlink;
405  }
406  else
407  {
408  /* Set the list head's backlink instead */
409  ListHead->Blink = OldBlink;
410  }
411 
412  /* Check if the back entry is the list head */
413  if (OldBlink != LIST_HEAD)
414  {
415  /* It is not, so set the backlink of the actual entry, to our backlink */
416  MI_PFN_ELEMENT(OldBlink)->u1.Flink = OldFlink;
417  }
418  else
419  {
420  /* Set the list head's backlink instead */
421  ListHead->Flink = OldFlink;
422  }
423 
424  /* We are not on a list anymore */
425  ASSERT_LIST_INVARIANT(ListHead);
426  Pfn1->u1.Flink = Pfn1->u2.Blink = 0;
427 
428  /* Zero flags but restore color and cache */
429  Pfn1->u3.e2.ShortFlags = 0;
430  Pfn1->u3.e1.PageColor = OldColor;
431  Pfn1->u3.e1.CacheAttribute = OldCache;
432 
433  /* Get the first page on the color list */
435  ColorTable = &MmFreePagesByColor[ListName][Color];
436  ASSERT(ColorTable->Count >= 1);
437 
438  /* Set the forward link to whoever we were pointing to */
439  ColorTable->Flink = Pfn1->OriginalPte.u.Long;
440 
441  /* Get the first page on the color list */
442  if (ColorTable->Flink == LIST_HEAD)
443  {
444  /* This is the beginning of the list, so set the sentinel value */
445  ColorTable->Blink = (PVOID)LIST_HEAD;
446  }
447  else
448  {
449  /* The list is empty, so we are the first page */
450  MI_PFN_ELEMENT(ColorTable->Flink)->u4.PteFrame = COLORED_LIST_HEAD;
451  }
452 
453  /* One less page */
454  ColorTable->Count--;
455 
456  /* ReactOS Hack */
457  Pfn1->OriginalPte.u.Long = 0;
458 
459  /* Decrement number of available pages */
461 
462 #if MI_TRACE_PFNS
464  Pfn1->PfnUsage = MI_PFN_CURRENT_USAGE;
465  memcpy(Pfn1->ProcessName, MI_PFN_CURRENT_PROCESS_NAME, 16);
466  Pfn1->CallSite = _ReturnAddress();
468  MI_SET_PROCESS2("Not Set");
469 #endif
470 
471  /* Return the page */
472  return PageIndex;
473 }
474 
476 NTAPI
478 {
479  PFN_NUMBER PageIndex;
480  PMMPFN Pfn1;
481 
482  /* Make sure PFN lock is held and we have pages */
484  ASSERT(MmAvailablePages != 0);
486 
487  /* Check the colored free list */
489  if (PageIndex == LIST_HEAD)
490  {
491  /* Check the colored zero list */
493  if (PageIndex == LIST_HEAD)
494  {
495  /* Check the free list */
497  PageIndex = MmFreePageListHead.Flink;
498  Color = PageIndex & MmSecondaryColorMask;
499  if (PageIndex == LIST_HEAD)
500  {
501  /* Check the zero list */
503  PageIndex = MmZeroedPageListHead.Flink;
504  Color = PageIndex & MmSecondaryColorMask;
505  ASSERT(PageIndex != LIST_HEAD);
506  if (PageIndex == LIST_HEAD)
507  {
508  /* FIXME: Should check the standby list */
510  }
511  }
512  }
513  }
514 
515  /* Remove the page from its list */
516  PageIndex = MiRemovePageByColor(PageIndex, Color);
517 
518  /* Sanity checks */
519  Pfn1 = MI_PFN_ELEMENT(PageIndex);
520  ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) ||
521  (Pfn1->u3.e1.PageLocation == ZeroedPageList));
522  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
523  ASSERT(Pfn1->u2.ShareCount == 0);
526 
527  /* Return the page */
528  return PageIndex;
529 }
530 
532 NTAPI
534 {
535  PFN_NUMBER PageIndex;
536  PMMPFN Pfn1;
537  BOOLEAN Zero = FALSE;
538 
539  /* Make sure PFN lock is held and we have pages */
541  ASSERT(MmAvailablePages != 0);
543 
544  /* Check the colored zero list */
546  if (PageIndex == LIST_HEAD)
547  {
548  /* Check the zero list */
550  PageIndex = MmZeroedPageListHead.Flink;
551  if (PageIndex == LIST_HEAD)
552  {
553  /* This means there's no zero pages, we have to look for free ones */
555  Zero = TRUE;
556 
557  /* Check the colored free list */
559  if (PageIndex == LIST_HEAD)
560  {
561  /* Check the free list */
563  PageIndex = MmFreePageListHead.Flink;
564  Color = PageIndex & MmSecondaryColorMask;
565  ASSERT(PageIndex != LIST_HEAD);
566  if (PageIndex == LIST_HEAD)
567  {
568  /* FIXME: Should check the standby list */
570  }
571  }
572  }
573  else
574  {
575  Color = PageIndex & MmSecondaryColorMask;
576  }
577  }
578 
579  /* Sanity checks */
580  Pfn1 = MI_PFN_ELEMENT(PageIndex);
581  ASSERT((Pfn1->u3.e1.PageLocation == FreePageList) ||
582  (Pfn1->u3.e1.PageLocation == ZeroedPageList));
583 
584  /* Remove the page from its list */
585  PageIndex = MiRemovePageByColor(PageIndex, Color);
586  ASSERT(Pfn1 == MI_PFN_ELEMENT(PageIndex));
587 
588  /* Zero it, if needed */
589  if (Zero) MiZeroPhysicalPage(PageIndex);
590 
591  /* Sanity checks */
592  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
593  ASSERT(Pfn1->u2.ShareCount == 0);
596 
597  /* Return the page */
598  return PageIndex;
599 }
600 
601 VOID
602 NTAPI
604 {
605  PMMPFNLIST ListHead;
606  PFN_NUMBER LastPage;
607  PMMPFN Pfn1;
608  ULONG Color;
609  PMMPFN Blink;
610  PMMCOLOR_TABLES ColorTable;
611 
612  /* Make sure the page index is valid */
614  ASSERT((PageFrameIndex != 0) &&
615  (PageFrameIndex <= MmHighestPhysicalPage) &&
616  (PageFrameIndex >= MmLowestPhysicalPage));
617 
618  /* Get the PFN entry */
619  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
620 
621  /* Sanity checks that a right kind of page is being inserted here */
622  ASSERT(Pfn1->u4.MustBeCached == 0);
623  ASSERT(Pfn1->u3.e1.Rom != 1);
624  ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
625  ASSERT(Pfn1->u4.VerifierAllocation == 0);
626  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
627 
628  /* Get the free page list and increment its count */
629  ListHead = &MmFreePageListHead;
630  ASSERT_LIST_INVARIANT(ListHead);
631  ListHead->Total++;
632 
633  /* Get the last page on the list */
634  LastPage = ListHead->Blink;
635  if (LastPage != LIST_HEAD)
636  {
637  /* Link us with the previous page, so we're at the end now */
638  MI_PFN_ELEMENT(LastPage)->u1.Flink = PageFrameIndex;
639  }
640  else
641  {
642  /* The list is empty, so we are the first page */
643  ListHead->Flink = PageFrameIndex;
644  }
645 
646  /* Now make the list head point back to us (since we go at the end) */
647  ListHead->Blink = PageFrameIndex;
648  ASSERT_LIST_INVARIANT(ListHead);
649 
650  /* And initialize our own list pointers */
651  Pfn1->u1.Flink = LIST_HEAD;
652  Pfn1->u2.Blink = LastPage;
653 
654  /* Set the list name and default priority */
655  Pfn1->u3.e1.PageLocation = FreePageList;
656  Pfn1->u4.Priority = 3;
657 
658  /* Clear some status fields */
659  Pfn1->u4.InPageError = 0;
660  Pfn1->u4.AweAllocation = 0;
661 
662  /* Increment number of available pages */
664 
665  /* Get the page color */
666  Color = PageFrameIndex & MmSecondaryColorMask;
667 
668  /* Get the first page on the color list */
669  ColorTable = &MmFreePagesByColor[FreePageList][Color];
670  if (ColorTable->Flink == LIST_HEAD)
671  {
672  /* The list is empty, so we are the first page */
673  Pfn1->u4.PteFrame = COLORED_LIST_HEAD;
674  ColorTable->Flink = PageFrameIndex;
675  }
676  else
677  {
678  /* Get the previous page */
679  Blink = (PMMPFN)ColorTable->Blink;
680 
681  /* Make it link to us, and link back to it */
682  Blink->OriginalPte.u.Long = PageFrameIndex;
683  Pfn1->u4.PteFrame = MiGetPfnEntryIndex(Blink);
684  }
685 
686  /* Now initialize our own list pointers */
687  ColorTable->Blink = Pfn1;
688 
689  /* This page is now the last */
690  Pfn1->OriginalPte.u.Long = LIST_HEAD;
691 
692  /* And increase the count in the colored list */
693  ColorTable->Count++;
694 
695  /* Notify zero page thread if enough pages are on the free list now */
696  if (ListHead->Total >= 8)
697  {
698  /* Set the event */
700  }
701 
702 #if MI_TRACE_PFNS
703  Pfn1->PfnUsage = MI_USAGE_FREE_PAGE;
704  RtlZeroMemory(Pfn1->ProcessName, 16);
705  Pfn1->CallSite = NULL;
706 #endif
707 }
708 
709 VOID
710 FASTCALL
712 {
713  PMMPFNLIST ListHead;
714  PFN_NUMBER Flink;
715  PMMPFN Pfn1, Pfn2;
716 
717  /* Make sure the lock is held */
718  DPRINT("Inserting page: %lx into standby list !\n", PageFrameIndex);
720 
721  /* Make sure the PFN is valid */
722  ASSERT((PageFrameIndex != 0) &&
723  (PageFrameIndex <= MmHighestPhysicalPage) &&
724  (PageFrameIndex >= MmLowestPhysicalPage));
725 
726  /* Grab the PFN and validate it is the right kind of PFN being inserted */
727  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
728  ASSERT(Pfn1->u4.MustBeCached == 0);
729  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
730  ASSERT(Pfn1->u3.e1.PrototypePte == 1);
731  ASSERT(Pfn1->u3.e1.Rom != 1);
732 
733  /* One more transition page on a list */
735 
736  /* Get the standby page list and increment its count */
737  ListHead = &MmStandbyPageListByPriority [Pfn1->u4.Priority];
738  ASSERT_LIST_INVARIANT(ListHead);
739  ListHead->Total++;
740 
741  /* Make the head of the list point to this page now */
742  Flink = ListHead->Flink;
743  ListHead->Flink = PageFrameIndex;
744 
745  /* Make the page point to the previous head, and back to the list */
746  Pfn1->u1.Flink = Flink;
747  Pfn1->u2.Blink = LIST_HEAD;
748 
749  /* Was the list empty? */
750  if (Flink != LIST_HEAD)
751  {
752  /* It wasn't, so update the backlink of the previous head page */
753  Pfn2 = MI_PFN_ELEMENT(Flink);
754  Pfn2->u2.Blink = PageFrameIndex;
755  }
756  else
757  {
758  /* It was empty, so have it loop back around to this new page */
759  ListHead->Blink = PageFrameIndex;
760  }
761 
762  /* Move the page onto its new location */
764 
765  /* Increment number of available pages */
767 }
768 
769 VOID
770 NTAPI
772  IN PFN_NUMBER PageFrameIndex)
773 {
774  PFN_NUMBER Flink, LastPage;
775  PMMPFN Pfn1, Pfn2;
776  MMLISTS ListName;
777  PMMCOLOR_TABLES ColorHead;
778  ULONG Color;
779 
780  /* For free pages, use MiInsertPageInFreeList */
781  ASSERT(ListHead != &MmFreePageListHead);
782 
783  /* Make sure the lock is held */
785 
786  /* Make sure the PFN is valid */
787  ASSERT((PageFrameIndex) &&
788  (PageFrameIndex <= MmHighestPhysicalPage) &&
789  (PageFrameIndex >= MmLowestPhysicalPage));
790 
791  /* Page should be unused */
792  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
793  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
794  ASSERT(Pfn1->u3.e1.Rom != 1);
795 
796  /* Is a standby or modified page being inserted? */
797  ListName = ListHead->ListName;
798  if ((ListName == StandbyPageList) || (ListName == ModifiedPageList))
799  {
800  /* If the page is in transition, it must also be a prototype page */
801  if ((Pfn1->OriginalPte.u.Soft.Prototype == 0) &&
802  (Pfn1->OriginalPte.u.Soft.Transition == 1))
803  {
804  /* Crash the system on inconsistency */
805  KeBugCheckEx(MEMORY_MANAGEMENT, 0x8888, 0, 0, 0);
806  }
807  }
808 
809  /* Standby pages are prioritized, so we need to get the real head */
810  if (ListHead == &MmStandbyPageListHead)
811  {
812  /* Obviously the prioritized list should still have the same name */
813  ListHead = &MmStandbyPageListByPriority[Pfn1->u4.Priority];
814  ASSERT(ListHead->ListName == ListName);
815  }
816 
817  /* Increment the list count */
818  ListHead->Total++;
819 
820  /* Is a modified page being inserted? */
821  if (ListHead == &MmModifiedPageListHead)
822  {
823  /* For now, only single-prototype pages should end up in this path */
824  DPRINT("Modified page being added: %lx\n", PageFrameIndex);
825  ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
826 
827  /* Modified pages are colored when they are selected for page file */
828  ListHead = &MmModifiedPageListByColor[0];
829  ASSERT (ListHead->ListName == ListName);
830  ListHead->Total++;
831 
832  /* Increment the number of paging file modified pages */
834  }
835 
836  /* Don't handle bad pages yet yet */
837  ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
838 
839  /* Zero pages go to the head, all other pages go to the end */
840  if (ListName == ZeroedPageList)
841  {
842  /* Make the head of the list point to this page now */
843  Flink = ListHead->Flink;
844  ListHead->Flink = PageFrameIndex;
845 
846  /* Make the page point to the previous head, and back to the list */
847  Pfn1->u1.Flink = Flink;
848  Pfn1->u2.Blink = LIST_HEAD;
849 
850  /* Was the list empty? */
851  if (Flink != LIST_HEAD)
852  {
853  /* It wasn't, so update the backlink of the previous head page */
854  Pfn2 = MI_PFN_ELEMENT(Flink);
855  Pfn2->u2.Blink = PageFrameIndex;
856  }
857  else
858  {
859  /* It was empty, so have it loop back around to this new page */
860  ListHead->Blink = PageFrameIndex;
861  }
862  }
863  else
864  {
865  /* Get the last page on the list */
866  LastPage = ListHead->Blink;
867  if (LastPage != LIST_HEAD)
868  {
869  /* Link us with the previous page, so we're at the end now */
870  MI_PFN_ELEMENT(LastPage)->u1.Flink = PageFrameIndex;
871  }
872  else
873  {
874  /* The list is empty, so we are the first page */
875  ListHead->Flink = PageFrameIndex;
876  }
877 
878  /* Now make the list head point back to us (since we go at the end) */
879  ListHead->Blink = PageFrameIndex;
880  ASSERT_LIST_INVARIANT(ListHead);
881 
882  /* And initialize our own list pointers */
883  Pfn1->u1.Flink = LIST_HEAD;
884  Pfn1->u2.Blink = LastPage;
885  }
886 
887  /* Move the page onto its new location */
888  Pfn1->u3.e1.PageLocation = ListName;
889 
890  /* For zero/free pages, we also have to handle the colored lists */
891  if (ListName <= StandbyPageList)
892  {
893  /* Increment number of available pages */
895 
896  /* Sanity checks */
897  ASSERT(ListName == ZeroedPageList);
898  ASSERT(Pfn1->u4.InPageError == 0);
899 
900  /* Get the page color */
901  Color = PageFrameIndex & MmSecondaryColorMask;
902 
903  /* Get the list for this color */
904  ColorHead = &MmFreePagesByColor[ZeroedPageList][Color];
905 
906  /* Get the old head */
907  Flink = ColorHead->Flink;
908 
909  /* Make this page point back to the list, and point forwards to the old head */
910  Pfn1->OriginalPte.u.Long = Flink;
911  Pfn1->u4.PteFrame = COLORED_LIST_HEAD;
912 
913  /* Set the new head */
914  ColorHead->Flink = PageFrameIndex;
915 
916  /* Was the head empty? */
917  if (Flink != LIST_HEAD)
918  {
919  /* No, so make the old head point to this page */
920  Pfn2 = MI_PFN_ELEMENT(Flink);
921  Pfn2->u4.PteFrame = PageFrameIndex;
922  }
923  else
924  {
925  /* Yes, make it loop back to this page */
926  ColorHead->Blink = (PVOID)Pfn1;
927  }
928 
929  /* One more paged on the colored list */
930  ColorHead->Count++;
931 
932 #if MI_TRACE_PFNS
934  Pfn1->PfnUsage = MI_USAGE_FREE_PAGE;
935  RtlZeroMemory(Pfn1->ProcessName, 16);
936  Pfn1->CallSite = NULL;
937 #endif
938  }
939  else if (ListName == ModifiedPageList)
940  {
941  /* In ARM3, page must be destined for page file, and not yet written out */
942  ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
943  ASSERT(Pfn1->OriginalPte.u.Soft.PageFileHigh == 0);
944 
945  /* One more transition page */
947 
948  /* Increment the number of per-process modified pages */
949  PsGetCurrentProcess()->ModifiedPageCount++;
950 
951  /* FIXME: Wake up modified page writer if there are not enough free pages */
952  }
953  else if (ListName == ModifiedNoWritePageList)
954  {
955  /* This list is not yet implemented */
956  ASSERT(FALSE);
957  }
958 }
959 
960 VOID
961 NTAPI
963  IN PMMPTE PointerPte,
964  IN BOOLEAN Modified)
965 {
966  PMMPFN Pfn1;
968  PMMPTE PointerPtePte;
970 
971  /* Setup the PTE */
972  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
973  Pfn1->PteAddress = PointerPte;
974 
975  DPRINT("Called for %p from %p\n", Pfn1, _ReturnAddress());
976 
977  /* Check if this PFN is part of a valid address space */
978  if (PointerPte->u.Hard.Valid == 1)
979  {
980  /* Only valid from MmCreateProcessAddressSpace path */
982 
983  /* Make this a demand zero PTE */
985  }
986  else
987  {
988  /* Copy the PTE data */
989  Pfn1->OriginalPte = *PointerPte;
990  ASSERT(!((Pfn1->OriginalPte.u.Soft.Prototype == 0) &&
991  (Pfn1->OriginalPte.u.Soft.Transition == 1)));
992  }
993 
994  /* Otherwise this is a fresh page -- set it up */
995  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
996  Pfn1->u3.e2.ReferenceCount = 1;
997  Pfn1->u2.ShareCount = 1;
999  ASSERT(Pfn1->u3.e1.Rom == 0);
1000  Pfn1->u3.e1.Modified = Modified;
1001 
1002  /* Get the page table for the PTE */
1003  PointerPtePte = MiAddressToPte(PointerPte);
1004  if (PointerPtePte->u.Hard.Valid == 0)
1005  {
1006  /* Make sure the PDE gets paged in properly */
1007  Status = MiCheckPdeForPagedPool(PointerPte);
1008  if (!NT_SUCCESS(Status))
1009  {
1010  /* Crash */
1011  KeBugCheckEx(MEMORY_MANAGEMENT,
1012  0x61940,
1013  (ULONG_PTR)PointerPte,
1014  (ULONG_PTR)PointerPtePte->u.Long,
1015  (ULONG_PTR)MiPteToAddress(PointerPte));
1016  }
1017  }
1018 
1019  /* Get the PFN for the page table */
1020  PageFrameIndex = PFN_FROM_PTE(PointerPtePte);
1021  ASSERT(PageFrameIndex != 0);
1022  Pfn1->u4.PteFrame = PageFrameIndex;
1023 
1024  DPRINT("Incrementing share count of %lp from %p\n", PageFrameIndex, _ReturnAddress());
1025 
1026  /* Increase its share count so we don't get rid of it */
1027  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
1028  Pfn1->u2.ShareCount++;
1029 }
1030 
1031 VOID
1032 NTAPI
1034  IN PMMPTE PointerPte,
1035  IN MMPTE TempPte)
1036 {
1037  PMMPFN Pfn1;
1038  NTSTATUS Status;
1039  PMMPTE PointerPtePte;
1041 
1042  /* PTE must be invalid */
1043  ASSERT(PointerPte->u.Hard.Valid == 0);
1044 
1045  /* Setup the PTE */
1046  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
1047  Pfn1->PteAddress = PointerPte;
1048  Pfn1->OriginalPte = DemandZeroPte;
1049 
1050  DPRINT("Incrementing %p from %p\n", Pfn1, _ReturnAddress());
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  DPRINT("Incrementing %p from %p\n", Pfn1, _ReturnAddress());
1086 
1087  /* Write valid PTE */
1088  MI_WRITE_VALID_PTE(PointerPte, TempPte);
1089 }
1090 
1091 NTSTATUS
1092 NTAPI
1094  IN PMMPDE PointerPde,
1095  IN PFN_NUMBER ContainingPageFrame,
1096  IN BOOLEAN SessionAllocation)
1097 {
1098  MMPDE TempPde;
1099  KIRQL OldIrql;
1100 
1101  /* Use either a global or local PDE */
1102  TempPde = SessionAllocation ? ValidKernelPdeLocal : ValidKernelPde;
1103 
1104  /* Lock the PFN database */
1105  OldIrql = MiAcquirePfnLock();
1106 
1107  /* Make sure nobody is racing us */
1108  if (PointerPde->u.Hard.Valid == 1)
1109  {
1110  /* Return special error if that was the case */
1111  MiReleasePfnLock(OldIrql);
1112  return STATUS_RETRY;
1113  }
1114 
1115  /* Grab a zero page and set the PFN, then make it valid */
1116  *PageFrameIndex = MiRemoveZeroPage(MI_GET_NEXT_COLOR());
1117  TempPde.u.Hard.PageFrameNumber = *PageFrameIndex;
1118  MI_WRITE_VALID_PDE(PointerPde, TempPde);
1119 
1120  /* Initialize the PFN */
1121  MiInitializePfnForOtherProcess(*PageFrameIndex,
1122  PointerPde,
1123  ContainingPageFrame);
1124  ASSERT(MI_PFN_ELEMENT(*PageFrameIndex)->u1.WsIndex == 0);
1125 
1126  /* Release the lock and return success */
1127  MiReleasePfnLock(OldIrql);
1128  return STATUS_SUCCESS;
1129 }
1130 
1131 VOID
1132 NTAPI
1134  IN PFN_NUMBER PageFrameIndex)
1135 {
1136  PMMPTE PointerPte;
1137  MMPTE TempPte;
1138 
1139  ASSERT(PageFrameIndex > 0);
1140  ASSERT(MI_PFN_ELEMENT(PageFrameIndex) != NULL);
1141  ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
1142  ASSERT(MI_IS_ROS_PFN(Pfn1) == FALSE);
1143 
1144  DPRINT("Decrementing %p from %p\n", Pfn1, _ReturnAddress());
1145 
1146  /* Page must be in-use */
1147  if ((Pfn1->u3.e1.PageLocation != ActiveAndValid) &&
1148  (Pfn1->u3.e1.PageLocation != StandbyPageList))
1149  {
1150  /* Otherwise we have PFN corruption */
1151  KeBugCheckEx(PFN_LIST_CORRUPT,
1152  0x99,
1153  PageFrameIndex,
1154  Pfn1->u3.e1.PageLocation,
1155  0);
1156  }
1157 
1158  /* Page should at least have one reference */
1159  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
1160 
1161  /* Check if the share count is now 0 */
1162  ASSERT(Pfn1->u2.ShareCount < 0xF000000);
1163  if (!--Pfn1->u2.ShareCount)
1164  {
1165  /* Was this a prototype PTE? */
1166  if (Pfn1->u3.e1.PrototypePte)
1167  {
1168  /* Grab the PTE address and make sure it's in prototype pool */
1169  PointerPte = Pfn1->PteAddress;
1170  ASSERT((PointerPte >= (PMMPTE)MmPagedPoolStart) && (PointerPte <= (PMMPTE)MmPagedPoolEnd));
1171 
1172  /* The PTE that backs it should also be valdi */
1173  PointerPte = MiAddressToPte(PointerPte);
1174  ASSERT(PointerPte->u.Hard.Valid == 1);
1175 
1176  /* Get the original prototype PTE and turn it into a transition PTE */
1177  PointerPte = Pfn1->PteAddress;
1178  TempPte = *PointerPte;
1179  TempPte.u.Soft.Transition = 1;
1180  TempPte.u.Soft.Valid = 0;
1181  TempPte.u.Soft.Prototype = 0;
1182  TempPte.u.Soft.Protection = Pfn1->OriginalPte.u.Soft.Protection;
1183  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1184  DPRINT("Marking PTE: %p as transition (%p - %lx)\n", PointerPte, Pfn1, MiGetPfnEntryIndex(Pfn1));
1185  }
1186 
1187  /* Put the page in transition */
1188  Pfn1->u3.e1.PageLocation = TransitionPage;
1189 
1190  /* PFN lock must be held */
1192 
1193  if (Pfn1->u3.e2.ReferenceCount == 1)
1194  {
1195  /* Is there still a PFN for this page? */
1196  if (MI_IS_PFN_DELETED(Pfn1))
1197  {
1198  /* Clear the last reference */
1199  Pfn1->u3.e2.ReferenceCount = 0;
1200  ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
1201 
1202  /* Mark the page temporarily as valid, we're going to make it free soon */
1203  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1204 
1205  /* Bring it back into the free list */
1206  MiInsertPageInFreeList(PageFrameIndex);
1207  }
1208  else
1209  {
1210  /* PFN not yet deleted, drop a ref count */
1211  MiDecrementReferenceCount(Pfn1, PageFrameIndex);
1212  }
1213  }
1214  else
1215  {
1216  /* Otherwise, just drop the reference count */
1217  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
1218  }
1219  }
1220 }
1221 
1222 VOID
1223 NTAPI
1225  IN PFN_NUMBER PageFrameIndex)
1226 {
1227  /* PFN lock must be held */
1229 
1230  /* Sanity checks on the page */
1231  if (PageFrameIndex > MmHighestPhysicalPage ||
1232  Pfn1 != MI_PFN_ELEMENT(PageFrameIndex) ||
1233  Pfn1->u3.e2.ReferenceCount == 0 ||
1234  Pfn1->u3.e2.ReferenceCount >= 2500)
1235  {
1236  DPRINT1("PageFrameIndex=0x%lx, MmHighestPhysicalPage=0x%lx\n", PageFrameIndex, MmHighestPhysicalPage);
1237  DPRINT1("Pfn1=%p, Element=%p, RefCount=%u\n", Pfn1, MI_PFN_ELEMENT(PageFrameIndex), Pfn1->u3.e2.ReferenceCount);
1238  ASSERT(PageFrameIndex <= MmHighestPhysicalPage);
1239  ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
1240  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
1241  ASSERT(Pfn1->u3.e2.ReferenceCount < 2500);
1242  }
1243 
1244  /* Dereference the page, bail out if it's still alive */
1245  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
1246  if (Pfn1->u3.e2.ReferenceCount) return;
1247 
1248  /* Nobody should still have reference to this page */
1249  if (Pfn1->u2.ShareCount != 0)
1250  {
1251  /* Otherwise something's really wrong */
1252  KeBugCheckEx(PFN_LIST_CORRUPT, 7, PageFrameIndex, Pfn1->u2.ShareCount, 0);
1253  }
1254 
1255  /* And it should be lying on some page list */
1256  ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
1257 
1258  /* Did someone set the delete flag? */
1259  if (MI_IS_PFN_DELETED(Pfn1))
1260  {
1261  /* Insert it into the free list, there's nothing left to do */
1262  MiInsertPageInFreeList(PageFrameIndex);
1263  return;
1264  }
1265 
1266  /* Check to see which list this page should go into */
1267  if (Pfn1->u3.e1.Modified == 1)
1268  {
1269  /* Push it into the modified page list */
1270  MiInsertPageInList(&MmModifiedPageListHead, PageFrameIndex);
1271  }
1272  else
1273  {
1274  /* Otherwise, insert this page into the standby list */
1275  ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
1276  MiInsertStandbyListAtFront(PageFrameIndex);
1277  }
1278 }
1279 
1280 VOID
1281 NTAPI
1283  IN PVOID PteAddress,
1284  IN PFN_NUMBER PteFrame)
1285 {
1286  PMMPFN Pfn1;
1287 
1288  /* Setup the PTE */
1289  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
1290  Pfn1->PteAddress = PteAddress;
1291 
1292  /* Make this a software PTE */
1294 
1295  DPRINT("Called for %p from %p\n", Pfn1, _ReturnAddress());
1296 
1297  /* Setup the page */
1298  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
1299  Pfn1->u3.e2.ReferenceCount = 1;
1300  Pfn1->u2.ShareCount = 1;
1301  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1302  Pfn1->u3.e1.Modified = TRUE;
1303  Pfn1->u4.InPageError = FALSE;
1304 
1305  /* Did we get a PFN for the page table */
1306  if (PteFrame)
1307  {
1308  /* Store it */
1309  Pfn1->u4.PteFrame = PteFrame;
1310 
1311  /* Increase its share count so we don't get rid of it */
1312  Pfn1 = MI_PFN_ELEMENT(PteFrame);
1313 
1314  DPRINT("Incrementing %p from %p\n", Pfn1, _ReturnAddress());
1315  Pfn1->u2.ShareCount++;
1316  }
1317 }
1318 
1319 /* EOF */
#define MI_MAKE_SOFTWARE_PTE(p, x)
Definition: miarm.h:189
MMSUPPORT Vm
Definition: miarm.h:505
VOID FASTCALL MiInsertStandbyListAtFront(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:711
#define IN
Definition: typedefs.h:39
VOID NTAPI MiInitializePfn(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
Definition: pfnlist.c:962
VOID NTAPI MiUnlinkPageFromList(IN PMMPFN Pfn)
Definition: pfnlist.c:265
union _MMPFN::@1747 u1
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:533
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1033
PVOID Blink
Definition: miarm.h:437
NTSTATUS NTAPI MiInitializeAndChargePfn(OUT PPFN_NUMBER PageFrameIndex, IN PMMPDE PointerPde, IN PFN_NUMBER ContainingPageFrame, IN BOOLEAN SessionAllocation)
Definition: pfnlist.c:1093
ULONG MI_PFN_CURRENT_USAGE
Definition: pfnlist.c:63
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:996
PFN_NUMBER MmMinimumFreePages
Definition: mminit.c:314
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:410
MMPFNLIST MmStandbyPageListHead
Definition: pfnlist.c:43
ULONG MmTotalPagesForPagingFile
Definition: pfnlist.c:39
PFN_NUMBER NTAPI MiRemovePageByColor(IN PFN_NUMBER PageIndex, IN ULONG Color)
Definition: pfnlist.c:364
MMLISTS ListName
Definition: mm.h:433
char CHAR
Definition: xmlstorage.h:175
VOID NTAPI MiInsertPageInList(IN PMMPFNLIST ListHead, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:771
LONG NTSTATUS
Definition: precomp.h:26
PFN_NUMBER MmHighMemoryThreshold
Definition: mminit.c:301
PFN_NUMBER Flink
Definition: mm.h:366
#define ASSERT_LIST_INVARIANT(x)
Definition: pfnlist.c:29
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:237
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
USHORT Modified
Definition: mm.h:349
union _MMPFN::@1749 u3
PVOID MmPagedPoolEnd
Definition: init.c:26
PFN_NUMBER MmLowestPhysicalPage
Definition: meminit.c:30
USHORT RemovalRequested
Definition: mm.h:355
MMPFNLIST MmFreePageListHead
Definition: pfnlist.c:42
struct _MMPFN::@1749::@1755 e2
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
USHORT PageLocation
Definition: mm.h:354
struct Color Color
PFN_NUMBER Flink
Definition: mm.h:434
enum _MMLISTS MMLISTS
uint32_t ULONG_PTR
Definition: typedefs.h:65
USHORT PrototypePte
Definition: mm.h:352
PMMPFNLIST MmPageLocationList[]
Definition: pfnlist.c:51
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:386
ULONG * PPFN_NUMBER
Definition: ke.h:9
USHORT CacheAttribute
Definition: mm.h:356
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
ULONG_PTR MustBeCached
Definition: mm.h:412
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:379
ULONG MmTransitionSharedPages
Definition: pfnlist.c:38
VOID NTAPI MmRebalanceMemoryConsumers(VOID)
Definition: balance.c:270
PFN_NUMBER Blink
Definition: mm.h:435
PFN_NUMBER Flink
Definition: miarm.h:436
#define MI_SET_PROCESS2(x)
Definition: mm.h:308
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:409
MMPFNLIST MmRomPageListHead
Definition: pfnlist.c:49
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
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:1023
_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
KIRQL OldIrql
Definition: mm.h:1502
MMPFNLIST MmModifiedNoWritePageListHead
Definition: pfnlist.c:47
union _MMPFN::@1752 u4
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: cpu.c:56
#define ASSERT(a)
Definition: mode.c:44
#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
union _MMPTE::@2275 u
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:1579
PFN_NUMBER MmLowMemoryThreshold
Definition: mminit.c:300
#define MM_READWRITE
Definition: inbv.c:12
ULONG64 PageFileHigh
Definition: mmtypes.h:93
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:603
Definition: mm.h:362
#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:411
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:579
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:997
USHORT PageColor
Definition: mm.h:353
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1282
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1224
unsigned short USHORT
Definition: pedump.c:61
MMPFNLIST MmZeroedPageListHead
Definition: pfnlist.c:41
ULONG_PTR PteFrame
Definition: mm.h:407
ULONG64 Transition
Definition: mmtypes.h:90
PFN_NUMBER Total
Definition: mm.h:432
struct _MMPFN * PMMPFN
#define MI_IS_ROS_PFN(x)
Definition: miarm.h:1108
USHORT Rom
Definition: mm.h:357
PMMPTE PteAddress
Definition: mm.h:375
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
#define NULL
Definition: types.h:112
MMPTE OriginalPte
Definition: mm.h:396
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
union _MMPFN::@1748 u2
ULONG WsIndex
Definition: mm.h:367
PFN_NUMBER Blink
Definition: mm.h:378
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
void * _ReturnAddress(void)
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:1020
#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
MMPFNLIST MmStandbyPageListByPriority[8]
Definition: pfnlist.c:44
MMPTE DemandZeroPte
Definition: init.c:37
PFN_NUMBER Count
Definition: miarm.h:438
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
ULONG_PTR InPageError
Definition: mm.h:408
#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:954
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:1133
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:430