ReactOS  0.4.15-dev-1177-g6cb3b62
pfnlist.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for pfnlist.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 
#define ASSERT_LIST_INVARIANT(x)
 

Functions

static VOID MiIncrementAvailablePages (VOID)
 
static VOID MiDecrementAvailablePages (VOID)
 
VOID NTAPI MiZeroPhysicalPage (IN PFN_NUMBER PageFrameIndex)
 
VOID NTAPI MiUnlinkFreeOrZeroedPage (IN PMMPFN Entry)
 
VOID NTAPI MiUnlinkPageFromList (IN PMMPFN Pfn)
 
PFN_NUMBER NTAPI MiRemovePageByColor (IN PFN_NUMBER PageIndex, IN ULONG Color)
 
PFN_NUMBER NTAPI MiRemoveAnyPage (IN ULONG Color)
 
PFN_NUMBER NTAPI MiRemoveZeroPage (IN ULONG Color)
 
BOOLEAN MmRosNotifyAvailablePage (PFN_NUMBER PageFrameIndex)
 
VOID NTAPI MiInsertPageInFreeList (IN PFN_NUMBER PageFrameIndex)
 
VOID FASTCALL MiInsertStandbyListAtFront (IN PFN_NUMBER PageFrameIndex)
 
VOID NTAPI MiInsertPageInList (IN PMMPFNLIST ListHead, IN PFN_NUMBER PageFrameIndex)
 
VOID NTAPI MiInitializePfn (IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
 
VOID NTAPI MiInitializePfnAndMakePteValid (IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
 
NTSTATUS NTAPI MiInitializeAndChargePfn (OUT PPFN_NUMBER PageFrameIndex, IN PMMPDE PointerPde, IN PFN_NUMBER ContainingPageFrame, IN BOOLEAN SessionAllocation)
 
VOID NTAPI MiDecrementShareCount (IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
 
VOID NTAPI MiDecrementReferenceCount (IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
 
VOID NTAPI MiInitializePfnForOtherProcess (IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
 

Variables

BOOLEAN MmDynamicPfn
 
BOOLEAN MmMirroring
 
ULONG MmSystemPageColor
 
ULONG MmTransitionSharedPages
 
ULONG MmTotalPagesForPagingFile
 
MMPFNLIST MmZeroedPageListHead = {0, ZeroedPageList, LIST_HEAD, LIST_HEAD}
 
MMPFNLIST MmFreePageListHead = {0, FreePageList, LIST_HEAD, LIST_HEAD}
 
MMPFNLIST MmStandbyPageListHead = {0, StandbyPageList, LIST_HEAD, LIST_HEAD}
 
MMPFNLIST MmStandbyPageListByPriority [8]
 
MMPFNLIST MmModifiedPageListHead = {0, ModifiedPageList, LIST_HEAD, LIST_HEAD}
 
MMPFNLIST MmModifiedPageListByColor [1] = {{0, ModifiedPageList, LIST_HEAD, LIST_HEAD}}
 
MMPFNLIST MmModifiedNoWritePageListHead = {0, ModifiedNoWritePageList, LIST_HEAD, LIST_HEAD}
 
MMPFNLIST MmBadPageListHead = {0, BadPageList, LIST_HEAD, LIST_HEAD}
 
MMPFNLIST MmRomPageListHead = {0, StandbyPageList, LIST_HEAD, LIST_HEAD}
 
PMMPFNLIST MmPageLocationList []
 
ULONG MI_PFN_CURRENT_USAGE
 
CHAR MI_PFN_CURRENT_PROCESS_NAME [16] = "None yet"
 

Macro Definition Documentation

◆ ASSERT_LIST_INVARIANT

#define ASSERT_LIST_INVARIANT (   x)

Definition at line 29 of file pfnlist.c.

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 15 of file pfnlist.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file pfnlist.c.

Function Documentation

◆ MiDecrementAvailablePages()

static VOID MiDecrementAvailablePages ( VOID  )
static

Definition at line 90 of file pfnlist.c.

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 }
PFN_NUMBER MmMinimumFreePages
Definition: mminit.c:314
PFN_NUMBER MmHighMemoryThreshold
Definition: mminit.c:301
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FALSE
Definition: types.h:117
VOID NTAPI MmRebalanceMemoryConsumers(VOID)
Definition: balance.c:218
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PFN_NUMBER MmLowMemoryThreshold
Definition: mminit.c:300
#define DPRINT1
Definition: precomp.h:8
PKEVENT MiLowMemoryEvent
Definition: mminit.c:292
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
PKEVENT MiHighMemoryEvent
Definition: mminit.c:293

Referenced by MiRemovePageByColor(), MiUnlinkFreeOrZeroedPage(), and MiUnlinkPageFromList().

◆ MiDecrementReferenceCount()

VOID NTAPI MiDecrementReferenceCount ( IN PMMPFN  Pfn1,
IN PFN_NUMBER  PageFrameIndex 
)

Definition at line 1222 of file pfnlist.c.

1224 {
1225  /* PFN lock must be held */
1227 
1228  /* Sanity checks on the page */
1229  if (PageFrameIndex > MmHighestPhysicalPage ||
1230  Pfn1 != MI_PFN_ELEMENT(PageFrameIndex) ||
1231  Pfn1->u3.e2.ReferenceCount == 0 ||
1232  Pfn1->u3.e2.ReferenceCount >= 2500)
1233  {
1234  DPRINT1("PageFrameIndex=0x%lx, MmHighestPhysicalPage=0x%lx\n", PageFrameIndex, MmHighestPhysicalPage);
1235  DPRINT1("Pfn1=%p, Element=%p, RefCount=%u\n", Pfn1, MI_PFN_ELEMENT(PageFrameIndex), Pfn1->u3.e2.ReferenceCount);
1236  ASSERT(PageFrameIndex <= MmHighestPhysicalPage);
1237  ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
1238  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
1239  ASSERT(Pfn1->u3.e2.ReferenceCount < 2500);
1240  }
1241 
1242  /* Dereference the page, bail out if it's still alive */
1243  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
1244  if (Pfn1->u3.e2.ReferenceCount) return;
1245 
1246  /* Nobody should still have reference to this page */
1247  if (Pfn1->u2.ShareCount != 0)
1248  {
1249  /* Otherwise something's really wrong */
1250  KeBugCheckEx(PFN_LIST_CORRUPT, 7, PageFrameIndex, Pfn1->u2.ShareCount, 0);
1251  }
1252 
1253  /* And it should be lying on some page list */
1254  ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
1255 
1256  /* Did someone set the delete flag? */
1257  if (MI_IS_PFN_DELETED(Pfn1))
1258  {
1259  /* Insert it into the free list, there's nothing left to do */
1260  MiInsertPageInFreeList(PageFrameIndex);
1261  return;
1262  }
1263 
1264  /* Check to see which list this page should go into */
1265  if (Pfn1->u3.e1.Modified == 1)
1266  {
1267  /* Push it into the modified page list */
1268  MiInsertPageInList(&MmModifiedPageListHead, PageFrameIndex);
1269  }
1270  else
1271  {
1272  /* Otherwise, insert this page into the standby list */
1273  ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
1274  MiInsertStandbyListAtFront(PageFrameIndex);
1275  }
1276 }
VOID FASTCALL MiInsertStandbyListAtFront(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:718
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
signed short * PSHORT
Definition: retypes.h:6
VOID NTAPI MiInsertPageInList(IN PMMPFNLIST ListHead, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:778
struct _MMPFN::@1776::@1782 e2
MMPFNLIST MmModifiedPageListHead
Definition: pfnlist.c:45
union _MMPFN::@1776 u3
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:191
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:604
#define InterlockedDecrement16
Definition: interlocked.h:139
#define DPRINT1
Definition: precomp.h:8
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108

Referenced by MiDecrementShareCount(), MiDeletePte(), MiDereferencePfnAndDropLockCount(), and MmFreePagesFromMdl().

◆ MiDecrementShareCount()

VOID NTAPI MiDecrementShareCount ( IN PMMPFN  Pfn1,
IN PFN_NUMBER  PageFrameIndex 
)

Definition at line 1133 of file pfnlist.c.

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  /* Page must be in-use */
1145  if ((Pfn1->u3.e1.PageLocation != ActiveAndValid) &&
1146  (Pfn1->u3.e1.PageLocation != StandbyPageList))
1147  {
1148  /* Otherwise we have PFN corruption */
1149  KeBugCheckEx(PFN_LIST_CORRUPT,
1150  0x99,
1151  PageFrameIndex,
1152  Pfn1->u3.e1.PageLocation,
1153  0);
1154  }
1155 
1156  /* Page should at least have one reference */
1157  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
1158 
1159  /* Check if the share count is now 0 */
1160  ASSERT(Pfn1->u2.ShareCount < 0xF000000);
1161  if (!--Pfn1->u2.ShareCount)
1162  {
1163  /* Was this a prototype PTE? */
1164  if (Pfn1->u3.e1.PrototypePte)
1165  {
1166  /* Grab the PTE address and make sure it's in prototype pool */
1167  PointerPte = Pfn1->PteAddress;
1168  ASSERT((PointerPte >= (PMMPTE)MmPagedPoolStart) && (PointerPte <= (PMMPTE)MmPagedPoolEnd));
1169 
1170  /* The PTE that backs it should also be valdi */
1171  PointerPte = MiAddressToPte(PointerPte);
1172  ASSERT(PointerPte->u.Hard.Valid == 1);
1173 
1174  /* Get the original prototype PTE and turn it into a transition PTE */
1175  PointerPte = Pfn1->PteAddress;
1176  TempPte = *PointerPte;
1177  TempPte.u.Soft.Transition = 1;
1178  TempPte.u.Soft.Valid = 0;
1179  TempPte.u.Soft.Prototype = 0;
1180  TempPte.u.Soft.Protection = Pfn1->OriginalPte.u.Soft.Protection;
1181  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1182  DPRINT("Marking PTE: %p as transition (%p - %lx)\n", PointerPte, Pfn1, MiGetPfnEntryIndex(Pfn1));
1183  }
1184 
1185  /* Put the page in transition */
1186  Pfn1->u3.e1.PageLocation = TransitionPage;
1187 
1188  /* PFN lock must be held */
1190 
1191  if (Pfn1->u3.e2.ReferenceCount == 1)
1192  {
1193  /* Is there still a PFN for this page? */
1194  if (MI_IS_PFN_DELETED(Pfn1))
1195  {
1196  /* Clear the last reference */
1197  Pfn1->u3.e2.ReferenceCount = 0;
1198  ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
1199 
1200  /* Mark the page temporarily as valid, we're going to make it free soon */
1201  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1202 
1203  /* Bring it back into the free list */
1204  MiInsertPageInFreeList(PageFrameIndex);
1205  }
1206  else
1207  {
1208  /* PFN not yet deleted, drop a ref count */
1209  MiDecrementReferenceCount(Pfn1, PageFrameIndex);
1210  }
1211  }
1212  else
1213  {
1214  /* Otherwise, just drop the reference count */
1215  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
1216  }
1217  }
1218 }
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
signed short * PSHORT
Definition: retypes.h:6
PVOID MmPagedPoolEnd
Definition: init.c:26
union _MMPTE::@2302 u
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
ULONG64 Valid
Definition: mmtypes.h:150
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:191
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:604
#define InterlockedDecrement16
Definition: interlocked.h:139
PVOID MmPagedPoolStart
Definition: miarm.h:581
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:971
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1222
#define MI_IS_ROS_PFN(x)
Definition: miarm.h:1069
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:960
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108

Referenced by MiDeletePte(), MiDeleteSystemPageableVm(), MiFreeContiguousMemory(), MiProcessValidPteList(), MiProtectVirtualMemory(), MiReleaseProcessReferenceToSessionDataPage(), MiRemoveMappedPtes(), MiUnmapLockedPagesInUserSpace(), MmDeleteKernelStack(), MmDeleteProcessAddressSpace2(), MmFreeLoaderBlock(), and MmFreeSpecialPool().

◆ MiIncrementAvailablePages()

static VOID MiIncrementAvailablePages ( VOID  )
static

Definition at line 69 of file pfnlist.c.

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 }
PFN_NUMBER MmHighMemoryThreshold
Definition: mminit.c:301
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FALSE
Definition: types.h:117
PFN_NUMBER MmLowMemoryThreshold
Definition: mminit.c:300
PKEVENT MiLowMemoryEvent
Definition: mminit.c:292
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
PKEVENT MiHighMemoryEvent
Definition: mminit.c:293

Referenced by MiInsertPageInFreeList(), MiInsertPageInList(), and MiInsertStandbyListAtFront().

◆ MiInitializeAndChargePfn()

NTSTATUS NTAPI MiInitializeAndChargePfn ( OUT PPFN_NUMBER  PageFrameIndex,
IN PMMPDE  PointerPde,
IN PFN_NUMBER  ContainingPageFrame,
IN BOOLEAN  SessionAllocation 
)

Definition at line 1093 of file pfnlist.c.

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 */
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 */
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 */
1128  return STATUS_SUCCESS;
1129 }
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:531
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:238
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
UCHAR KIRQL
Definition: env_spec_w32.h:591
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:997
ULONG PageFrameNumber
Definition: mmtypes.h:74
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
union _MMPFN::@1774 u1
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
MMPTE ValidKernelPdeLocal
Definition: init.c:32
MMPTE ValidKernelPde
Definition: init.c:28
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1280
#define STATUS_RETRY
Definition: udferr_usr.h:182
ULONG WsIndex
Definition: mm.h:310
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by MiInitializeSessionPool().

◆ MiInitializePfn()

VOID NTAPI MiInitializePfn ( IN PFN_NUMBER  PageFrameIndex,
IN PMMPTE  PointerPte,
IN BOOLEAN  Modified 
)

Definition at line 969 of file pfnlist.c.

972 {
973  PMMPFN Pfn1;
975  PMMPTE PointerPtePte;
977 
978  /* Setup the PTE */
979  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
980  Pfn1->PteAddress = PointerPte;
981 
982  /* Check if this PFN is part of a valid address space */
983  if (PointerPte->u.Hard.Valid == 1)
984  {
985  /* Only valid from MmCreateProcessAddressSpace path */
986  ASSERT(PsGetCurrentProcess()->Vm.WorkingSetSize == 0);
987 
988  /* Make this a demand zero PTE */
990  }
991  else
992  {
993  /* Copy the PTE data */
994  Pfn1->OriginalPte = *PointerPte;
995  ASSERT(!((Pfn1->OriginalPte.u.Soft.Prototype == 0) &&
996  (Pfn1->OriginalPte.u.Soft.Transition == 1)));
997  }
998 
999  /* Otherwise this is a fresh page -- set it up */
1000  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
1001  Pfn1->u3.e2.ReferenceCount = 1;
1002  Pfn1->u2.ShareCount = 1;
1003  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1004  ASSERT(Pfn1->u3.e1.Rom == 0);
1005  Pfn1->u3.e1.Modified = Modified;
1006 
1007  /* Get the page table for the PTE */
1008  PointerPtePte = MiAddressToPte(PointerPte);
1009  if (PointerPtePte->u.Hard.Valid == 0)
1010  {
1011  /* Make sure the PDE gets paged in properly */
1012  Status = MiCheckPdeForPagedPool(PointerPte);
1013  if (!NT_SUCCESS(Status))
1014  {
1015  /* Crash */
1016  KeBugCheckEx(MEMORY_MANAGEMENT,
1017  0x61940,
1018  (ULONG_PTR)PointerPte,
1019  (ULONG_PTR)PointerPtePte->u.Long,
1020  (ULONG_PTR)MiPteToAddress(PointerPte));
1021  }
1022  }
1023 
1024  /* Get the PFN for the page table */
1025  PageFrameIndex = PFN_FROM_PTE(PointerPtePte);
1026  ASSERT(PageFrameIndex != 0);
1027  Pfn1->u4.PteFrame = PageFrameIndex;
1028 
1029  /* Increase its share count so we don't get rid of it */
1030  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
1031  Pfn1->u2.ShareCount++;
1032 }
#define MI_MAKE_SOFTWARE_PTE(p, x)
Definition: miarm.h:185
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
LONG NTSTATUS
Definition: precomp.h:26
union _MMPFN::@1779 u4
USHORT Modified
Definition: mm.h:292
NTSTATUS FASTCALL MiCheckPdeForPagedPool(IN PVOID Address)
Definition: pagfault.c:475
USHORT PageLocation
Definition: mm.h:297
uint32_t ULONG_PTR
Definition: typedefs.h:65
MMPFNENTRY e1
Definition: mm.h:329
union _MMPTE::@2302 u
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG_PTR ShareCount
Definition: mm.h:322
#define PsGetCurrentProcess
Definition: psfuncs.h:17
union _MMPFN::@1775 u2
struct _MMPFN::@1776::@1782 e2
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
union _MMPFN::@1776 u3
ULONG64 Valid
Definition: mmtypes.h:150
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
#define MM_READWRITE
Definition: inbv.c:12
Definition: mm.h:305
ULONG64 Prototype
Definition: mmtypes.h:89
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG_PTR PteFrame
Definition: mm.h:350
ULONG64 Transition
Definition: mmtypes.h:90
USHORT Rom
Definition: mm.h:300
PMMPTE PteAddress
Definition: mm.h:318
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
MMPTE OriginalPte
Definition: mm.h:339
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
#define PFN_FROM_PTE(v)
Definition: mm.h:92
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108

Referenced by MiLoadImageSection(), MiResolveDemandZeroFault(), MiResolvePageFileFault(), MiResolveProtoPteFault(), MmArmAccessFault(), MmCreateKernelStack(), MmGrowKernelStackEx(), and MmInitializeProcessAddressSpace().

◆ MiInitializePfnAndMakePteValid()

VOID NTAPI MiInitializePfnAndMakePteValid ( IN PFN_NUMBER  PageFrameIndex,
IN PMMPTE  PointerPte,
IN MMPTE  TempPte 
)

Definition at line 1036 of file pfnlist.c.

1039 {
1040  PMMPFN Pfn1;
1041  NTSTATUS Status;
1042  PMMPTE PointerPtePte;
1044 
1045  /* PTE must be invalid */
1046  ASSERT(PointerPte->u.Hard.Valid == 0);
1047 
1048  /* Setup the PTE */
1049  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
1050  Pfn1->PteAddress = PointerPte;
1051  Pfn1->OriginalPte = DemandZeroPte;
1052 
1053  /* Otherwise this is a fresh page -- set it up */
1054  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
1055  Pfn1->u3.e2.ReferenceCount++;
1056  Pfn1->u2.ShareCount++;
1057  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1058  ASSERT(Pfn1->u3.e1.Rom == 0);
1059  Pfn1->u3.e1.Modified = 1;
1060 
1061  /* Get the page table for the PTE */
1062  PointerPtePte = MiAddressToPte(PointerPte);
1063  if (PointerPtePte->u.Hard.Valid == 0)
1064  {
1065  /* Make sure the PDE gets paged in properly */
1066  Status = MiCheckPdeForPagedPool(PointerPte);
1067  if (!NT_SUCCESS(Status))
1068  {
1069  /* Crash */
1070  KeBugCheckEx(MEMORY_MANAGEMENT,
1071  0x61940,
1072  (ULONG_PTR)PointerPte,
1073  (ULONG_PTR)PointerPtePte->u.Long,
1074  (ULONG_PTR)MiPteToAddress(PointerPte));
1075  }
1076  }
1077 
1078  /* Get the PFN for the page table */
1079  PageFrameIndex = PFN_FROM_PTE(PointerPtePte);
1080  ASSERT(PageFrameIndex != 0);
1081  Pfn1->u4.PteFrame = PageFrameIndex;
1082 
1083  /* Increase its share count so we don't get rid of it */
1084  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
1085  Pfn1->u2.ShareCount++;
1086 
1087  /* Write valid PTE */
1088  MI_WRITE_VALID_PTE(PointerPte, TempPte);
1089 }
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
LONG NTSTATUS
Definition: precomp.h:26
union _MMPFN::@1779 u4
USHORT Modified
Definition: mm.h:292
NTSTATUS FASTCALL MiCheckPdeForPagedPool(IN PVOID Address)
Definition: pagfault.c:475
USHORT PageLocation
Definition: mm.h:297
uint32_t ULONG_PTR
Definition: typedefs.h:65
MMPFNENTRY e1
Definition: mm.h:329
union _MMPTE::@2302 u
#define MiAddressToPte(x)
Definition: mmx86.c:19
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:942
ULONG_PTR ShareCount
Definition: mm.h:322
union _MMPFN::@1775 u2
struct _MMPFN::@1776::@1782 e2
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
union _MMPFN::@1776 u3
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
Definition: mm.h:305
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG_PTR PteFrame
Definition: mm.h:350
USHORT Rom
Definition: mm.h:300
PMMPTE PteAddress
Definition: mm.h:318
MMPTE OriginalPte
Definition: mm.h:339
MMPTE DemandZeroPte
Definition: init.c:37
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
#define PFN_FROM_PTE(v)
Definition: mm.h:92
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108

Referenced by MiSessionCreateInternal(), MiSessionInitializeWorkingSetList(), and MmAllocateSpecialPool().

◆ MiInitializePfnForOtherProcess()

VOID NTAPI MiInitializePfnForOtherProcess ( IN PFN_NUMBER  PageFrameIndex,
IN PVOID  PteAddress,
IN PFN_NUMBER  PteFrame 
)

Definition at line 1280 of file pfnlist.c.

1283 {
1284  PMMPFN Pfn1;
1285 
1286  /* Setup the PTE */
1287  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex);
1288  Pfn1->PteAddress = PteAddress;
1289 
1290  /* Make this a software PTE */
1292 
1293  /* Setup the page */
1294  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
1295  Pfn1->u3.e2.ReferenceCount = 1;
1296  Pfn1->u2.ShareCount = 1;
1297  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1298  Pfn1->u3.e1.Modified = TRUE;
1299  Pfn1->u4.InPageError = FALSE;
1300 
1301  /* Did we get a PFN for the page table */
1302  if (PteFrame)
1303  {
1304  /* Store it */
1305  Pfn1->u4.PteFrame = PteFrame;
1306 
1307  /* Increase its share count so we don't get rid of it */
1308  Pfn1 = MI_PFN_ELEMENT(PteFrame);
1309  Pfn1->u2.ShareCount++;
1310  }
1311 }
#define MI_MAKE_SOFTWARE_PTE(p, x)
Definition: miarm.h:185
#define TRUE
Definition: types.h:120
union _MMPFN::@1779 u4
USHORT Modified
Definition: mm.h:292
USHORT PageLocation
Definition: mm.h:297
MMPFNENTRY e1
Definition: mm.h:329
#define FALSE
Definition: types.h:117
ULONG_PTR ShareCount
Definition: mm.h:322
union _MMPFN::@1775 u2
struct _MMPFN::@1776::@1782 e2
union _MMPFN::@1776 u3
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
#define MM_READWRITE
Definition: inbv.c:12
Definition: mm.h:305
ULONG_PTR PteFrame
Definition: mm.h:350
PMMPTE PteAddress
Definition: mm.h:318
MMPTE OriginalPte
Definition: mm.h:339
ULONG_PTR InPageError
Definition: mm.h:351

Referenced by MiAllocatePoolPages(), MiBuildPagedPool(), MiFillSystemPageDirectory(), MiInitializeAndChargePfn(), MiSessionCommitPageTables(), MiSessionCreateInternal(), and MiSessionInitializeWorkingSetList().

◆ MiInsertPageInFreeList()

VOID NTAPI MiInsertPageInFreeList ( IN PFN_NUMBER  PageFrameIndex)

Definition at line 604 of file pfnlist.c.

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 }
PVOID Blink
Definition: miarm.h:438
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
ULONG_PTR AweAllocation
Definition: mm.h:353
PFN_NUMBER Flink
Definition: mm.h:309
union _MMPFN::@1779 u4
#define ASSERT_LIST_INVARIANT(x)
Definition: pfnlist.c:29
PFN_NUMBER MmLowestPhysicalPage
Definition: meminit.c:30
USHORT RemovalRequested
Definition: mm.h:298
MMPFNLIST MmFreePageListHead
Definition: pfnlist.c:42
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
USHORT PageLocation
Definition: mm.h:297
struct Color Color
PFN_NUMBER Flink
Definition: mm.h:373
MMPFNENTRY e1
Definition: mm.h:329
union _MMPTE::@2302 u
ULONG PFN_NUMBER
Definition: ke.h:8
ULONG_PTR MustBeCached
Definition: mm.h:355
#define FALSE
Definition: types.h:117
PFN_NUMBER Blink
Definition: mm.h:374
PFN_NUMBER Flink
Definition: miarm.h:437
ULONG_PTR VerifierAllocation
Definition: mm.h:352
KEVENT MmZeroingPageEvent
Definition: zeropage.c:20
ULONG MmSecondaryColorMask
Definition: mminit.c:257
union _MMPFN::@1775 u2
struct _MMPFN::@1776::@1782 e2
PMMCOLOR_TABLES MmFreePagesByColor[FreePageList+1]
Definition: mminit.c:286
union _MMPFN::@1776 u3
BOOLEAN MmRosNotifyAvailablePage(PFN_NUMBER PageFrameIndex)
Definition: balance.c:406
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
union _MMPFN::@1774 u1
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
Definition: mm.h:305
static VOID MiIncrementAvailablePages(VOID)
Definition: pfnlist.c:69
LIST_HEAD(acpi_bus_event_list)
ULONG_PTR Priority
Definition: mm.h:354
ULONG_PTR Long
Definition: mmtypes.h:215
ULONG_PTR PteFrame
Definition: mm.h:350
PFN_NUMBER Total
Definition: mm.h:371
struct _MMPFN * PMMPFN
USHORT Rom
Definition: mm.h:300
MMPTE OriginalPte
Definition: mm.h:339
#define DPRINT1
Definition: precomp.h:8
PFN_NUMBER Blink
Definition: mm.h:321
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:960
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
PFN_NUMBER Count
Definition: miarm.h:439
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
ULONG_PTR InPageError
Definition: mm.h:351
Definition: mm.h:369

Referenced by MiAddDescriptorToDatabase(), MiBuildPfnDatabaseFromLoaderBlock(), MiDecrementReferenceCount(), MiDecrementShareCount(), MiSegmentDelete(), MmDereferencePage(), and MmFreeLoaderBlock().

◆ MiInsertPageInList()

VOID NTAPI MiInsertPageInList ( IN PMMPFNLIST  ListHead,
IN PFN_NUMBER  PageFrameIndex 
)

Definition at line 778 of file pfnlist.c.

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
940  //ASSERT(MI_PFN_CURRENT_USAGE == MI_USAGE_NOT_SET);
941  Pfn1->PfnUsage = MI_USAGE_FREE_PAGE;
943  RtlZeroMemory(Pfn1->ProcessName, 16);
944 #endif
945  }
946  else if (ListName == ModifiedPageList)
947  {
948  /* In ARM3, page must be destined for page file, and not yet written out */
949  ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
950  ASSERT(Pfn1->OriginalPte.u.Soft.PageFileHigh == 0);
951 
952  /* One more transition page */
954 
955  /* Increment the number of per-process modified pages */
956  PsGetCurrentProcess()->ModifiedPageCount++;
957 
958  /* FIXME: Wake up modified page writer if there are not enough free pages */
959  }
960  else if (ListName == ModifiedNoWritePageList)
961  {
962  /* This list is not yet implemented */
963  ASSERT(FALSE);
964  }
965 }
PVOID Blink
Definition: miarm.h:438
ULONG MI_PFN_CURRENT_USAGE
Definition: pfnlist.c:63
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
MMPFNLIST MmStandbyPageListHead
Definition: pfnlist.c:43
ULONG MmTotalPagesForPagingFile
Definition: pfnlist.c:39
PFN_NUMBER Flink
Definition: mm.h:309
union _MMPFN::@1779 u4
#define ASSERT_LIST_INVARIANT(x)
Definition: pfnlist.c:29
PFN_NUMBER MmLowestPhysicalPage
Definition: meminit.c:30
USHORT RemovalRequested
Definition: mm.h:298
MMPFNLIST MmFreePageListHead
Definition: pfnlist.c:42
USHORT PageLocation
Definition: mm.h:297
struct Color Color
enum _MMLISTS MMLISTS
MMPFNENTRY e1
Definition: mm.h:329
union _MMPTE::@2302 u
ULONG PFN_NUMBER
Definition: ke.h:8
#define FALSE
Definition: types.h:117
ULONG MmTransitionSharedPages
Definition: pfnlist.c:38
PFN_NUMBER Flink
Definition: miarm.h:437
#define PsGetCurrentProcess
Definition: psfuncs.h:17
ULONG MmSecondaryColorMask
Definition: mminit.c:257
void DPRINT(...)
Definition: polytest.cpp:61
union _MMPFN::@1775 u2
struct _MMPFN::@1776::@1782 e2
void * PVOID
Definition: retypes.h:9
PMMCOLOR_TABLES MmFreePagesByColor[FreePageList+1]
Definition: mminit.c:286
MMPFNLIST MmModifiedPageListHead
Definition: pfnlist.c:45
union _MMPFN::@1776 u3
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
union _MMPFN::@1774 u1
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
ULONG64 PageFileHigh
Definition: mmtypes.h:93
Definition: mm.h:305
MMPFNLIST MmModifiedPageListByColor[1]
Definition: pfnlist.c:46
ULONG64 Prototype
Definition: mmtypes.h:89
static VOID MiIncrementAvailablePages(VOID)
Definition: pfnlist.c:69
LIST_HEAD(acpi_bus_event_list)
ULONG_PTR Priority
Definition: mm.h:354
ULONG_PTR Long
Definition: mmtypes.h:215
ULONG_PTR PteFrame
Definition: mm.h:350
ULONG64 Transition
Definition: mmtypes.h:90
USHORT Rom
Definition: mm.h:300
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
MMPTE OriginalPte
Definition: mm.h:339
PFN_NUMBER Blink
Definition: mm.h:321
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
MMPFNLIST MmStandbyPageListByPriority[8]
Definition: pfnlist.c:44
PFN_NUMBER Count
Definition: miarm.h:439
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
ULONG_PTR InPageError
Definition: mm.h:351
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108

Referenced by MiDecrementReferenceCount(), and MmZeroPageThread().

◆ MiInsertStandbyListAtFront()

VOID FASTCALL MiInsertStandbyListAtFront ( IN PFN_NUMBER  PageFrameIndex)

Definition at line 718 of file pfnlist.c.

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 }
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
PFN_NUMBER Flink
Definition: mm.h:309
union _MMPFN::@1779 u4
#define ASSERT_LIST_INVARIANT(x)
Definition: pfnlist.c:29
PFN_NUMBER MmLowestPhysicalPage
Definition: meminit.c:30
USHORT PageLocation
Definition: mm.h:297
PFN_NUMBER Flink
Definition: mm.h:373
USHORT PrototypePte
Definition: mm.h:295
MMPFNENTRY e1
Definition: mm.h:329
ULONG PFN_NUMBER
Definition: ke.h:8
ULONG_PTR MustBeCached
Definition: mm.h:355
ULONG MmTransitionSharedPages
Definition: pfnlist.c:38
PFN_NUMBER Blink
Definition: mm.h:374
void DPRINT(...)
Definition: polytest.cpp:61
union _MMPFN::@1775 u2
struct _MMPFN::@1776::@1782 e2
union _MMPFN::@1776 u3
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
union _MMPFN::@1774 u1
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
Definition: mm.h:305
static VOID MiIncrementAvailablePages(VOID)
Definition: pfnlist.c:69
LIST_HEAD(acpi_bus_event_list)
ULONG_PTR Priority
Definition: mm.h:354
PFN_NUMBER Total
Definition: mm.h:371
USHORT Rom
Definition: mm.h:300
PFN_NUMBER Blink
Definition: mm.h:321
MMPFNLIST MmStandbyPageListByPriority[8]
Definition: pfnlist.c:44
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
Definition: mm.h:369

Referenced by MiDecrementReferenceCount().

◆ MiRemoveAnyPage()

PFN_NUMBER NTAPI MiRemoveAnyPage ( IN ULONG  Color)

Definition at line 475 of file pfnlist.c.

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 }
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
PFN_NUMBER NTAPI MiRemovePageByColor(IN PFN_NUMBER PageIndex, IN ULONG Color)
Definition: pfnlist.c:363
#define ASSERT_LIST_INVARIANT(x)
Definition: pfnlist.c:29
MMPFNLIST MmFreePageListHead
Definition: pfnlist.c:42
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
USHORT PageLocation
Definition: mm.h:297
struct Color Color
PFN_NUMBER Flink
Definition: mm.h:373
MMPFNENTRY e1
Definition: mm.h:329
ULONG PFN_NUMBER
Definition: ke.h:8
ULONG_PTR ShareCount
Definition: mm.h:322
PFN_NUMBER Flink
Definition: miarm.h:437
ULONG MmSecondaryColorMask
Definition: mminit.c:257
union _MMPFN::@1775 u2
struct _MMPFN::@1776::@1782 e2
PMMCOLOR_TABLES MmFreePagesByColor[FreePageList+1]
Definition: mminit.c:286
union _MMPFN::@1776 u3
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
Definition: mm.h:305
ULONG MmSecondaryColors
Definition: mminit.c:256
LIST_HEAD(acpi_bus_event_list)
MMPFNLIST MmZeroedPageListHead
Definition: pfnlist.c:41
PFN_NUMBER Total
Definition: mm.h:371

Referenced by MiAllocatePagesForMdl(), MiAllocatePoolPages(), MiInitMachineDependent(), MiLoadImageSection(), MiResolveDemandZeroFault(), MiResolvePageFileFault(), MiResolveProtoPteFault(), MiSessionCreateInternal(), MiSessionInitializeWorkingSetList(), MmAllocateSpecialPool(), MmArmAccessFault(), MmCreateKernelStack(), MmCreateProcessAddressSpace(), MmGrowKernelStackEx(), and MmZeroPageThread().

◆ MiRemovePageByColor()

PFN_NUMBER NTAPI MiRemovePageByColor ( IN PFN_NUMBER  PageIndex,
IN ULONG  Color 
)

Definition at line 363 of file pfnlist.c.

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
462  //ASSERT(MI_PFN_CURRENT_USAGE != MI_USAGE_NOT_SET);
463  Pfn1->PfnUsage = MI_PFN_CURRENT_USAGE;
464  memcpy(Pfn1->ProcessName, MI_PFN_CURRENT_PROCESS_NAME, 16);
465  //MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET;
466  //memcpy(MI_PFN_CURRENT_PROCESS_NAME, "Not Set", 16);
467 #endif
468 
469  /* Return the page */
470  return PageIndex;
471 }
PVOID Blink
Definition: miarm.h:438
ULONG MI_PFN_CURRENT_USAGE
Definition: pfnlist.c:63
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
MMLISTS ListName
Definition: mm.h:372
PFN_NUMBER Flink
Definition: mm.h:309
union _MMPFN::@1779 u4
#define ASSERT_LIST_INVARIANT(x)
Definition: pfnlist.c:29
USHORT RemovalRequested
Definition: mm.h:298
USHORT PageLocation
Definition: mm.h:297
struct Color Color
PFN_NUMBER Flink
Definition: mm.h:373
enum _MMLISTS MMLISTS
PMMPFNLIST MmPageLocationList[]
Definition: pfnlist.c:51
MMPFNENTRY e1
Definition: mm.h:329
union _MMPTE::@2302 u
USHORT CacheAttribute
Definition: mm.h:299
ULONG PFN_NUMBER
Definition: ke.h:8
PFN_NUMBER Blink
Definition: mm.h:374
PFN_NUMBER Flink
Definition: miarm.h:437
union _MMPFN::@1775 u2
struct _MMPFN::@1776::@1782 e2
void * PVOID
Definition: retypes.h:9
PMMCOLOR_TABLES MmFreePagesByColor[FreePageList+1]
Definition: mminit.c:286
static VOID MiDecrementAvailablePages(VOID)
Definition: pfnlist.c:90
union _MMPFN::@1776 u3
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
union _MMPFN::@1774 u1
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
Definition: mm.h:305
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ULONG MmSecondaryColors
Definition: mminit.c:256
LIST_HEAD(acpi_bus_event_list)
ULONG_PTR Long
Definition: mmtypes.h:215
USHORT PageColor
Definition: mm.h:296
unsigned short USHORT
Definition: pedump.c:61
ULONG_PTR PteFrame
Definition: mm.h:350
PFN_NUMBER Total
Definition: mm.h:371
USHORT Rom
Definition: mm.h:300
MMPTE OriginalPte
Definition: mm.h:339
PFN_NUMBER Blink
Definition: mm.h:321
PFN_NUMBER Count
Definition: miarm.h:439
CHAR MI_PFN_CURRENT_PROCESS_NAME[16]
Definition: pfnlist.c:64
Definition: mm.h:369

Referenced by MiRemoveAnyPage(), and MiRemoveZeroPage().

◆ MiRemoveZeroPage()

PFN_NUMBER NTAPI MiRemoveZeroPage ( IN ULONG  Color)

Definition at line 531 of file pfnlist.c.

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 }
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
#define TRUE
Definition: types.h:120
PFN_NUMBER NTAPI MiRemovePageByColor(IN PFN_NUMBER PageIndex, IN ULONG Color)
Definition: pfnlist.c:363
#define ASSERT_LIST_INVARIANT(x)
Definition: pfnlist.c:29
MMPFNLIST MmFreePageListHead
Definition: pfnlist.c:42
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
USHORT PageLocation
Definition: mm.h:297
struct Color Color
PFN_NUMBER Flink
Definition: mm.h:373
MMPFNENTRY e1
Definition: mm.h:329
ULONG PFN_NUMBER
Definition: ke.h:8
#define FALSE
Definition: types.h:117
ULONG_PTR ShareCount
Definition: mm.h:322
PFN_NUMBER Flink
Definition: miarm.h:437
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
unsigned char BOOLEAN
ULONG MmSecondaryColorMask
Definition: mminit.c:257
union _MMPFN::@1775 u2
struct _MMPFN::@1776::@1782 e2
PMMCOLOR_TABLES MmFreePagesByColor[FreePageList+1]
Definition: mminit.c:286
union _MMPFN::@1776 u3
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
Definition: mm.h:305
ULONG MmSecondaryColors
Definition: mminit.c:256
LIST_HEAD(acpi_bus_event_list)
MMPFNLIST MmZeroedPageListHead
Definition: pfnlist.c:41
PFN_NUMBER Total
Definition: mm.h:371
IN PVCB IN VBO IN ULONG OUT PBCB OUT PVOID IN BOOLEAN IN BOOLEAN Zero
Definition: fatprocs.h:411

Referenced by MiBuildPagedPool(), MiFillSystemPageDirectory(), MiGetPteForProcess(), MiInitializeAndChargePfn(), MiRemoveZeroPageSafe(), MiResolveDemandZeroFault(), MiSessionCommitPageTables(), and MmAllocPage().

◆ MiUnlinkFreeOrZeroedPage()

VOID NTAPI MiUnlinkFreeOrZeroedPage ( IN PMMPFN  Entry)

Definition at line 137 of file pfnlist.c.

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 // MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET;
258 // memcpy(MI_PFN_CURRENT_PROCESS_NAME, "Not Set", 16);
259 #endif
260 }
PVOID Blink
Definition: miarm.h:438
ULONG MI_PFN_CURRENT_USAGE
Definition: pfnlist.c:63
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
MMLISTS ListName
Definition: mm.h:372
PFN_NUMBER Flink
Definition: mm.h:309
union _MMPFN::@1779 u4
#define ASSERT_LIST_INVARIANT(x)
Definition: pfnlist.c:29
struct Color Color
PFN_NUMBER Flink
Definition: mm.h:373
enum _MMLISTS MMLISTS
PMMPFNLIST MmPageLocationList[]
Definition: pfnlist.c:51
union _MMPTE::@2302 u
ULONG PFN_NUMBER
Definition: ke.h:8
PFN_NUMBER Blink
Definition: mm.h:374
PFN_NUMBER Flink
Definition: miarm.h:437
smooth NULL
Definition: ftsmooth.c:416
ULONG MmSecondaryColorMask
Definition: mminit.c:257
union _MMPFN::@1775 u2
void * PVOID
Definition: retypes.h:9
PMMCOLOR_TABLES MmFreePagesByColor[FreePageList+1]
Definition: mminit.c:286
static VOID MiDecrementAvailablePages(VOID)
Definition: pfnlist.c:90
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
union _MMPFN::@1774 u1
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
Definition: mm.h:305
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
LIST_HEAD(acpi_bus_event_list)
ULONG_PTR Long
Definition: mmtypes.h:215
ULONG_PTR PteFrame
Definition: mm.h:350
PFN_NUMBER Total
Definition: mm.h:371
MMPTE OriginalPte
Definition: mm.h:339
PFN_NUMBER Blink
Definition: mm.h:321
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:960
unsigned int ULONG
Definition: retypes.h:1
PFN_NUMBER Count
Definition: miarm.h:439
base of all file and directory entries
Definition: entries.h:82
CHAR MI_PFN_CURRENT_PROCESS_NAME[16]
Definition: pfnlist.c:64
Definition: mm.h:369

Referenced by MiAllocatePagesForMdl(), and MiFindContiguousPages().

◆ MiUnlinkPageFromList()

VOID NTAPI MiUnlinkPageFromList ( IN PMMPFN  Pfn)

Definition at line 264 of file pfnlist.c.

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 }
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
MMPFNLIST MmStandbyPageListHead
Definition: pfnlist.c:43
ULONG MmTotalPagesForPagingFile
Definition: pfnlist.c:39
MMLISTS ListName
Definition: mm.h:372
PFN_NUMBER Flink
Definition: mm.h:309
#define ASSERT_LIST_INVARIANT(x)
Definition: pfnlist.c:29
PFN_NUMBER Flink
Definition: mm.h:373
PMMPFNLIST MmPageLocationList[]
Definition: pfnlist.c:51
ULONG PFN_NUMBER
Definition: ke.h:8
#define FALSE
Definition: types.h:117
ULONG MmTransitionSharedPages
Definition: pfnlist.c:38
PFN_NUMBER Blink
Definition: mm.h:374
union _MMPFN::@1775 u2
MMPFNLIST MmModifiedPageListHead
Definition: pfnlist.c:45
MMPFNLIST MmModifiedNoWritePageListHead
Definition: pfnlist.c:47
static VOID MiDecrementAvailablePages(VOID)
Definition: pfnlist.c:90
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
union _MMPFN::@1774 u1
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1419
MMPFNLIST MmModifiedPageListByColor[1]
Definition: pfnlist.c:46
LIST_HEAD(acpi_bus_event_list)
PFN_NUMBER Total
Definition: mm.h:371
PFN_NUMBER Blink
Definition: mm.h:321
MMPFNLIST MmStandbyPageListByPriority[8]
Definition: pfnlist.c:44
Definition: mm.h:369

Referenced by MiDeletePte(), MiDispatchFault(), MiResolveTransitionFault(), and MiSegmentDelete().

◆ MiZeroPhysicalPage()

VOID NTAPI MiZeroPhysicalPage ( IN PFN_NUMBER  PageFrameIndex)

Definition at line 122 of file pfnlist.c.

123 {
124  KIRQL OldIrql;
127 
128  /* Map in hyperspace, then wipe it using XMMI or MEMSET */
133 }
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:30
VOID FASTCALL KeZeroPages(IN PVOID Address, IN ULONG Size)
Definition: stubs.c:82
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:93
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define PAGE_SIZE
Definition: env_spec_w32.h:49
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

Referenced by CcInitCacheZeroPage(), MiAllocatePagesForMdl(), MiRemoveZeroPage(), MiSessionCreateInternal(), MiSessionInitializeWorkingSetList(), MmCreateProcessAddressSpace(), and MmRosNotifyAvailablePage().

◆ MmRosNotifyAvailablePage()

BOOLEAN MmRosNotifyAvailablePage ( PFN_NUMBER  PageFrameIndex)

Definition at line 406 of file balance.c.

407 {
410  PMMPFN Pfn1;
411 
412  /* Make sure the PFN lock is held */
414 
416  {
417  /* Dirty way to know if we were initialized. */
418  return FALSE;
419  }
420 
422  if (!Entry)
423  return FALSE;
424 
426  MiZeroPhysicalPage(Page);
427  Request->Page = Page;
428 
429  Pfn1 = MiGetPfnEntry(Page);
430  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
431  Pfn1->u3.e2.ReferenceCount = 1;
433 
434  /* This marks the PFN as a ReactOS PFN */
435  Pfn1->u4.AweAllocation = TRUE;
436 
437  /* Allocate the extra ReactOS Data and zero it out */
438  Pfn1->u1.SwapEntry = 0;
439  Pfn1->RmapListHead = NULL;
440 
442 
443  return TRUE;
444 }
static LIST_ENTRY AllocationListHead
Definition: balance.c:39
_In_ WDFREQUEST Request
Definition: cdrom.h:1234
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:936
struct _Entry Entry
Definition: kefuncs.h:627
#define TRUE
Definition: types.h:120
ULONG_PTR AweAllocation
Definition: mm.h:353
PMM_RMAP_ENTRY RmapListHead
Definition: mm.h:343
union _MMPFN::@1779 u4
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
USHORT PageLocation
Definition: mm.h:297
MMPFNENTRY e1
Definition: mm.h:329
#define FALSE
Definition: types.h:117
PLIST_ENTRY NTAPI ExInterlockedRemoveHeadList(IN OUT PLIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:166
smooth NULL
Definition: ftsmooth.c:416
struct _MMPFN::@1776::@1782 e2
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
union _MMPFN::@1776 u3
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
union _MMPFN::@1774 u1
static KSPIN_LOCK AllocationListLock
Definition: balance.c:40
Definition: mm.h:305
Definition: typedefs.h:119
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
SWAPENTRY SwapEntry
Definition: mm.h:316
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
#define IO_NO_INCREMENT
Definition: iotypes.h:581
static ULONG MiMinimumAvailablePages
Definition: balance.c:37
base of all file and directory entries
Definition: entries.h:82

Referenced by MiInsertPageInFreeList().

Variable Documentation

◆ MI_PFN_CURRENT_PROCESS_NAME

CHAR MI_PFN_CURRENT_PROCESS_NAME[16] = "None yet"

◆ MI_PFN_CURRENT_USAGE

ULONG MI_PFN_CURRENT_USAGE

Definition at line 63 of file pfnlist.c.

Referenced by MiInsertPageInList(), MiRemovePageByColor(), and MiUnlinkFreeOrZeroedPage().

◆ MmBadPageListHead

MMPFNLIST MmBadPageListHead = {0, BadPageList, LIST_HEAD, LIST_HEAD}

Definition at line 48 of file pfnlist.c.

◆ MmDynamicPfn

BOOLEAN MmDynamicPfn

Definition at line 34 of file pfnlist.c.

◆ MmFreePageListHead

◆ MmMirroring

BOOLEAN MmMirroring

Definition at line 35 of file pfnlist.c.

◆ MmModifiedNoWritePageListHead

MMPFNLIST MmModifiedNoWritePageListHead = {0, ModifiedNoWritePageList, LIST_HEAD, LIST_HEAD}

Definition at line 47 of file pfnlist.c.

Referenced by MiUnlinkPageFromList().

◆ MmModifiedPageListByColor

MMPFNLIST MmModifiedPageListByColor[1] = {{0, ModifiedPageList, LIST_HEAD, LIST_HEAD}}

Definition at line 46 of file pfnlist.c.

Referenced by MiInsertPageInList(), and MiUnlinkPageFromList().

◆ MmModifiedPageListHead

MMPFNLIST MmModifiedPageListHead = {0, ModifiedPageList, LIST_HEAD, LIST_HEAD}

◆ MmPageLocationList

PMMPFNLIST MmPageLocationList[]
Initial value:
=
{
}
MMPFNLIST MmBadPageListHead
Definition: pfnlist.c:48
MMPFNLIST MmStandbyPageListHead
Definition: pfnlist.c:43
MMPFNLIST MmFreePageListHead
Definition: pfnlist.c:42
smooth NULL
Definition: ftsmooth.c:416
MMPFNLIST MmModifiedPageListHead
Definition: pfnlist.c:45
MMPFNLIST MmModifiedNoWritePageListHead
Definition: pfnlist.c:47
MMPFNLIST MmZeroedPageListHead
Definition: pfnlist.c:41

Definition at line 51 of file pfnlist.c.

Referenced by MiRemovePageByColor(), MiUnlinkFreeOrZeroedPage(), and MiUnlinkPageFromList().

◆ MmRomPageListHead

MMPFNLIST MmRomPageListHead = {0, StandbyPageList, LIST_HEAD, LIST_HEAD}

Definition at line 49 of file pfnlist.c.

◆ MmStandbyPageListByPriority

MMPFNLIST MmStandbyPageListByPriority[8]

◆ MmStandbyPageListHead

MMPFNLIST MmStandbyPageListHead = {0, StandbyPageList, LIST_HEAD, LIST_HEAD}

Definition at line 43 of file pfnlist.c.

Referenced by MiInsertPageInList(), and MiUnlinkPageFromList().

◆ MmSystemPageColor

ULONG MmSystemPageColor

Definition at line 36 of file pfnlist.c.

◆ MmTotalPagesForPagingFile

ULONG MmTotalPagesForPagingFile

Definition at line 39 of file pfnlist.c.

Referenced by MiInsertPageInList(), and MiUnlinkPageFromList().

◆ MmTransitionSharedPages

ULONG MmTransitionSharedPages

Definition at line 38 of file pfnlist.c.

Referenced by MiInsertPageInList(), MiInsertStandbyListAtFront(), and MiUnlinkPageFromList().

◆ MmZeroedPageListHead

MMPFNLIST MmZeroedPageListHead = {0, ZeroedPageList, LIST_HEAD, LIST_HEAD}

Definition at line 41 of file pfnlist.c.

Referenced by MiRemoveAnyPage(), MiRemoveZeroPage(), and MmZeroPageThread().