ReactOS  0.4.14-dev-293-g2b39b42
zeropage.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for zeropage.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 

Functions

VOID NTAPI MiFindInitializationCode (OUT PVOID *StartVa, OUT PVOID *EndVa)
 
VOID NTAPI MiFreeInitializationCode (IN PVOID StartVa, IN PVOID EndVa)
 
VOID NTAPI MmZeroPageThread (VOID)
 

Variables

BOOLEAN MmZeroingPageThreadActive
 
KEVENT MmZeroingPageEvent
 

Macro Definition Documentation

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 15 of file zeropage.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file zeropage.c.

Function Documentation

◆ MiFindInitializationCode()

VOID NTAPI MiFindInitializationCode ( OUT PVOID StartVa,
OUT PVOID EndVa 
)

Definition at line 1451 of file sysldr.c.

1453 {
1454  ULONG Size, SectionCount, Alignment;
1455  PLDR_DATA_TABLE_ENTRY LdrEntry;
1456  ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode;
1457  PLIST_ENTRY NextEntry;
1458  PIMAGE_NT_HEADERS NtHeader;
1459  PIMAGE_SECTION_HEADER Section, LastSection, InitSection;
1460  BOOLEAN InitFound;
1461  DBG_UNREFERENCED_LOCAL_VARIABLE(InitSection);
1462 
1463  /* So we don't free our own code yet */
1464  InitCode = (ULONG_PTR)&MiFindInitializationCode;
1465 
1466  /* Assume failure */
1467  *StartVa = NULL;
1468 
1469  /* Enter a critical region while we loop the list */
1471 
1472  /* Loop all loaded modules */
1473  NextEntry = PsLoadedModuleList.Flink;
1474  while (NextEntry != &PsLoadedModuleList)
1475  {
1476  /* Get the loader entry and its DLL base */
1477  LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1478  DllBase = (ULONG_PTR)LdrEntry->DllBase;
1479 
1480  /* Only process boot loaded images. Other drivers are processed by
1481  MmFreeDriverInitialization */
1482  if (LdrEntry->Flags & LDRP_MM_LOADED)
1483  {
1484  /* Keep going */
1485  NextEntry = NextEntry->Flink;
1486  continue;
1487  }
1488 
1489  /* Get the NT header */
1490  NtHeader = RtlImageNtHeader((PVOID)DllBase);
1491  if (!NtHeader)
1492  {
1493  /* Keep going */
1494  NextEntry = NextEntry->Flink;
1495  continue;
1496  }
1497 
1498  /* Get the first section, the section count, and scan them all */
1499  Section = IMAGE_FIRST_SECTION(NtHeader);
1500  SectionCount = NtHeader->FileHeader.NumberOfSections;
1501  InitStart = 0;
1502  while (SectionCount > 0)
1503  {
1504  /* Assume failure */
1505  InitFound = FALSE;
1506 
1507  /* Is this the INIT section or a discardable section? */
1508  if ((strncmp((PCCH)Section->Name, "INIT", 5) == 0) ||
1510  {
1511  /* Remember this */
1512  InitFound = TRUE;
1513  InitSection = Section;
1514  }
1515 
1516  if (InitFound)
1517  {
1518  /* Pick the biggest size -- either raw or virtual */
1519  Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
1520 
1521  /* Read the section alignment */
1523 
1524  /* Get the start and end addresses */
1525  InitStart = DllBase + Section->VirtualAddress;
1526  InitEnd = ALIGN_UP_BY(InitStart + Size, Alignment);
1527 
1528  /* Align the addresses to PAGE_SIZE */
1529  InitStart = ALIGN_UP_BY(InitStart, PAGE_SIZE);
1530  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1531 
1532  /* Have we reached the last section? */
1533  if (SectionCount == 1)
1534  {
1535  /* Remember this */
1536  LastSection = Section;
1537  }
1538  else
1539  {
1540  /* We have not, loop all the sections */
1541  LastSection = NULL;
1542  do
1543  {
1544  /* Keep going until we find a non-discardable section range */
1545  SectionCount--;
1546  Section++;
1548  {
1549  /* Discardable, so record it, then keep going */
1550  LastSection = Section;
1551  }
1552  else
1553  {
1554  /* Non-contigous discard flag, or no flag, break out */
1555  break;
1556  }
1557  }
1558  while (SectionCount > 1);
1559  }
1560 
1561  /* Have we found a discardable or init section? */
1562  if (LastSection)
1563  {
1564  /* Pick the biggest size -- either raw or virtual */
1565  Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize);
1566 
1567  /* Use this as the end of the section address */
1568  InitEnd = DllBase + LastSection->VirtualAddress + Size;
1569 
1570  /* Have we reached the last section yet? */
1571  if (SectionCount != 1)
1572  {
1573  /* Then align this accross the session boundary */
1574  InitEnd = ALIGN_UP_BY(InitEnd, Alignment);
1575  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1576  }
1577  }
1578 
1579  /* Make sure we don't let the init section go past the image */
1580  ImageEnd = DllBase + LdrEntry->SizeOfImage;
1581  if (InitEnd > ImageEnd) InitEnd = ALIGN_UP_BY(ImageEnd, PAGE_SIZE);
1582 
1583  /* Make sure we have a valid, non-zero init section */
1584  if (InitStart < InitEnd)
1585  {
1586  /* Make sure we are not within this code itself */
1587  if ((InitCode >= InitStart) && (InitCode < InitEnd))
1588  {
1589  /* Return it, we can't free ourselves now */
1590  ASSERT(*StartVa == 0);
1591  *StartVa = (PVOID)InitStart;
1592  *EndVa = (PVOID)InitEnd;
1593  }
1594  else
1595  {
1596  /* This isn't us -- go ahead and free it */
1597  ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE);
1598  DPRINT("Freeing init code: %p-%p ('%wZ' @%p : '%s')\n",
1599  (PVOID)InitStart,
1600  (PVOID)InitEnd,
1601  &LdrEntry->BaseDllName,
1602  LdrEntry->DllBase,
1603  InitSection->Name);
1604  MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd);
1605  }
1606  }
1607  }
1608 
1609  /* Move to the next section */
1610  SectionCount--;
1611  Section++;
1612  }
1613 
1614  /* Move to the next module */
1615  NextEntry = NextEntry->Flink;
1616  }
1617 
1618  /* Leave the critical region and return */
1620 }
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:34
ULONG SizeOfImage
Definition: ldrtypes.h:143
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
uint32_t ULONG_PTR
Definition: typedefs.h:63
PVOID DllBase
Definition: btrfs_drv.h:1784
VOID NTAPI MiFreeInitializationCode(IN PVOID InitStart, IN PVOID InitEnd)
Definition: sysldr.c:1428
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
union Alignment_ Alignment
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
void * PVOID
Definition: retypes.h:9
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
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
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:326
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
CONST CHAR * PCCH
Definition: ntbasedef.h:399
if(!(yy_init))
Definition: macro.lex.yy.c:714
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: btrfs_drv.h:1780
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:117
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define ALIGN_DOWN_BY(size, align)
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
#define RtlImageNtHeader
Definition: compat.h:457
ULONG Flags
Definition: ntddk_ex.h:207
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
#define ALIGN_UP_BY(size, align)
INIT_FUNCTION VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1451
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:937
union _IMAGE_SECTION_HEADER::@1543 Misc
#define LDRP_MM_LOADED
Definition: ldrtypes.h:60
#define IMAGE_SCN_MEM_DISCARDABLE
Definition: ntimage.h:235

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MiFreeInitializationCode()

VOID NTAPI MiFreeInitializationCode ( IN PVOID  StartVa,
IN PVOID  EndVa 
)

Definition at line 1428 of file sysldr.c.

1430 {
1431  PMMPTE PointerPte;
1432  PFN_NUMBER PagesFreed;
1433 
1434  /* Get the start PTE */
1435  PointerPte = MiAddressToPte(InitStart);
1436  ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1437 
1438  /* Compute the number of pages we expect to free */
1439  PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1440 
1441  /* Try to actually free them */
1442  PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1443  PagesFreed,
1444  0,
1445  NULL);
1446 }
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
smooth NULL
Definition: ftsmooth.c:416
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:297
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:937

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MmZeroPageThread()

VOID NTAPI MmZeroPageThread ( VOID  )

Definition at line 37 of file zeropage.c.

38 {
40  PVOID StartAddress, EndAddress;
41  PVOID WaitObjects[2];
42  KIRQL OldIrql;
43  PVOID ZeroAddress;
44  PFN_NUMBER PageIndex, FreePage;
45  PMMPFN Pfn1;
46 
47  /* Get the discardable sections to free them */
48  MiFindInitializationCode(&StartAddress, &EndAddress);
49  if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress);
50  DPRINT("Free non-cache pages: %lx\n", MmAvailablePages + MiMemoryConsumers[MC_CACHE].PagesUsed);
51 
52  /* Set our priority to 0 */
53  Thread->BasePriority = 0;
55 
56  /* Setup the wait objects */
57  WaitObjects[0] = &MmZeroingPageEvent;
58 // WaitObjects[1] = &PoSystemIdleTimer; FIXME: Implement idle timer
59 
60  while (TRUE)
61  {
63  WaitObjects,
64  WaitAny,
65  WrFreePage,
66  KernelMode,
67  FALSE,
68  NULL,
69  NULL);
72 
73  while (TRUE)
74  {
76  {
79  break;
80  }
81 
82  PageIndex = MmFreePageListHead.Flink;
83  ASSERT(PageIndex != LIST_HEAD);
84  Pfn1 = MiGetPfnEntry(PageIndex);
86  MI_SET_PROCESS2("Kernel 0 Loop");
88 
89  /* The first global free page should also be the first on its own list */
90  if (FreePage != PageIndex)
91  {
92  KeBugCheckEx(PFN_LIST_CORRUPT,
93  0x8F,
94  FreePage,
95  PageIndex,
96  0);
97  }
98 
99  Pfn1->u1.Flink = LIST_HEAD;
101 
102  ZeroAddress = MiMapPagesInZeroSpace(Pfn1, 1);
103  ASSERT(ZeroAddress);
104  RtlZeroMemory(ZeroAddress, PAGE_SIZE);
105  MiUnmapPagesInZeroSpace(ZeroAddress, 1);
106 
108 
110  }
111  }
112 }
union _MMPFN::@1746 u1
#define TRUE
Definition: types.h:120
KEVENT MmZeroingPageEvent
Definition: zeropage.c:21
MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM]
Definition: balance.c:36
BOOLEAN MmZeroingPageThreadActive
Definition: zeropage.c:20
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1451
PFN_NUMBER Flink
Definition: mm.h:309
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
MMPFNLIST MmZeroedPageListHead
Definition: pfnlist.c:41
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
PFN_NUMBER Flink
Definition: mm.h:373
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PFN_NUMBER
Definition: ke.h:8
#define MI_SET_PROCESS2(x)
Definition: mm.h:254
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI MiInsertPageInList(IN PMMPFNLIST ListHead, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:778
#define MI_SET_USAGE(x)
Definition: mm.h:253
VOID NTAPI MiFreeInitializationCode(IN PVOID StartVa, IN PVOID EndVa)
Definition: sysldr.c:1428
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
NTSTATUS NTAPI KeWaitForMultipleObjects(IN ULONG Count, IN PVOID Object[], IN WAIT_TYPE WaitType, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL, OUT PKWAIT_BLOCK WaitBlockArray OPTIONAL)
Definition: wait.c:586
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PVOID NTAPI MiMapPagesInZeroSpace(IN PMMPFN Pfn1, IN PFN_NUMBER NumberOfPages)
Definition: hypermap.c:113
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: mm.h:305
#define PAGE_SIZE
Definition: env_spec_w32.h:49
LIST_HEAD(acpi_bus_event_list)
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
#define MI_GET_PAGE_COLOR(x)
Definition: miarm.h:245
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
VOID NTAPI MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress, IN PFN_NUMBER NumberOfPages)
Definition: hypermap.c:185
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1327
PFN_NUMBER Total
Definition: mm.h:371
#define MC_CACHE
Definition: mm.h:93
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define KeGetCurrentThread
Definition: hal.h:44
MMPFNLIST MmFreePageListHead
Definition: pfnlist.c:42
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:107

Referenced by Phase1Initialization().

Variable Documentation

◆ MmZeroingPageEvent

KEVENT MmZeroingPageEvent

Definition at line 21 of file zeropage.c.

Referenced by MiInsertPageInFreeList(), MmArmInitSystem(), and MmZeroPageThread().

◆ MmZeroingPageThreadActive

BOOLEAN MmZeroingPageThreadActive

Definition at line 20 of file zeropage.c.

Referenced by MiInsertPageInFreeList(), MmArmInitSystem(), and MmZeroPageThread().