ReactOS  0.4.15-dev-5499-g1341c38
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

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 1437 of file sysldr.c.

1439 {
1440  ULONG Size, SectionCount, Alignment;
1441  PLDR_DATA_TABLE_ENTRY LdrEntry;
1442  ULONG_PTR DllBase, InitStart, InitEnd, ImageEnd, InitCode;
1443  PLIST_ENTRY NextEntry;
1444  PIMAGE_NT_HEADERS NtHeader;
1445  PIMAGE_SECTION_HEADER Section, LastSection, InitSection;
1446  BOOLEAN InitFound;
1447  DBG_UNREFERENCED_LOCAL_VARIABLE(InitSection);
1448 
1449  /* So we don't free our own code yet */
1450  InitCode = (ULONG_PTR)&MiFindInitializationCode;
1451 
1452  /* Assume failure */
1453  *StartVa = NULL;
1454 
1455  /* Acquire the necessary locks while we loop the list */
1459  KernelMode,
1460  FALSE,
1461  NULL);
1463 
1464  /* Loop all loaded modules */
1465  NextEntry = PsLoadedModuleList.Flink;
1466  while (NextEntry != &PsLoadedModuleList)
1467  {
1468  /* Get the loader entry and its DLL base */
1469  LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);
1470  DllBase = (ULONG_PTR)LdrEntry->DllBase;
1471 
1472  /* Only process boot loaded images. Other drivers are processed by
1473  MmFreeDriverInitialization */
1474  if (LdrEntry->Flags & LDRP_MM_LOADED)
1475  {
1476  /* Keep going */
1477  NextEntry = NextEntry->Flink;
1478  continue;
1479  }
1480 
1481  /* Get the NT header */
1482  NtHeader = RtlImageNtHeader((PVOID)DllBase);
1483  if (!NtHeader)
1484  {
1485  /* Keep going */
1486  NextEntry = NextEntry->Flink;
1487  continue;
1488  }
1489 
1490  /* Get the first section, the section count, and scan them all */
1491  Section = IMAGE_FIRST_SECTION(NtHeader);
1492  SectionCount = NtHeader->FileHeader.NumberOfSections;
1493  InitStart = 0;
1494  while (SectionCount > 0)
1495  {
1496  /* Assume failure */
1497  InitFound = FALSE;
1498 
1499  /* Is this the INIT section or a discardable section? */
1500  if ((strncmp((PCCH)Section->Name, "INIT", 5) == 0) ||
1502  {
1503  /* Remember this */
1504  InitFound = TRUE;
1505  InitSection = Section;
1506  }
1507 
1508  if (InitFound)
1509  {
1510  /* Pick the biggest size -- either raw or virtual */
1511  Size = max(Section->SizeOfRawData, Section->Misc.VirtualSize);
1512 
1513  /* Read the section alignment */
1515 
1516  /* Get the start and end addresses */
1517  InitStart = DllBase + Section->VirtualAddress;
1518  InitEnd = ALIGN_UP_BY(InitStart + Size, Alignment);
1519 
1520  /* Align the addresses to PAGE_SIZE */
1521  InitStart = ALIGN_UP_BY(InitStart, PAGE_SIZE);
1522  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1523 
1524  /* Have we reached the last section? */
1525  if (SectionCount == 1)
1526  {
1527  /* Remember this */
1528  LastSection = Section;
1529  }
1530  else
1531  {
1532  /* We have not, loop all the sections */
1533  LastSection = NULL;
1534  do
1535  {
1536  /* Keep going until we find a non-discardable section range */
1537  SectionCount--;
1538  Section++;
1540  {
1541  /* Discardable, so record it, then keep going */
1542  LastSection = Section;
1543  }
1544  else
1545  {
1546  /* Non-contigous discard flag, or no flag, break out */
1547  break;
1548  }
1549  }
1550  while (SectionCount > 1);
1551  }
1552 
1553  /* Have we found a discardable or init section? */
1554  if (LastSection)
1555  {
1556  /* Pick the biggest size -- either raw or virtual */
1557  Size = max(LastSection->SizeOfRawData, LastSection->Misc.VirtualSize);
1558 
1559  /* Use this as the end of the section address */
1560  InitEnd = DllBase + LastSection->VirtualAddress + Size;
1561 
1562  /* Have we reached the last section yet? */
1563  if (SectionCount != 1)
1564  {
1565  /* Then align this accross the session boundary */
1566  InitEnd = ALIGN_UP_BY(InitEnd, Alignment);
1567  InitEnd = ALIGN_DOWN_BY(InitEnd, PAGE_SIZE);
1568  }
1569  }
1570 
1571  /* Make sure we don't let the init section go past the image */
1572  ImageEnd = DllBase + LdrEntry->SizeOfImage;
1573  if (InitEnd > ImageEnd) InitEnd = ALIGN_UP_BY(ImageEnd, PAGE_SIZE);
1574 
1575  /* Make sure we have a valid, non-zero init section */
1576  if (InitStart < InitEnd)
1577  {
1578  /* Make sure we are not within this code itself */
1579  if ((InitCode >= InitStart) && (InitCode < InitEnd))
1580  {
1581  /* Return it, we can't free ourselves now */
1582  ASSERT(*StartVa == 0);
1583  *StartVa = (PVOID)InitStart;
1584  *EndVa = (PVOID)InitEnd;
1585  }
1586  else
1587  {
1588  /* This isn't us -- go ahead and free it */
1589  ASSERT(MI_IS_PHYSICAL_ADDRESS((PVOID)InitStart) == FALSE);
1590  DPRINT("Freeing init code: %p-%p ('%wZ' @%p : '%s')\n",
1591  (PVOID)InitStart,
1592  (PVOID)InitEnd,
1593  &LdrEntry->BaseDllName,
1594  LdrEntry->DllBase,
1595  InitSection->Name);
1596  MiFreeInitializationCode((PVOID)InitStart, (PVOID)InitEnd);
1597  }
1598  }
1599  }
1600 
1601  /* Move to the next section */
1602  SectionCount--;
1603  Section++;
1604  }
1605 
1606  /* Move to the next module */
1607  NextEntry = NextEntry->Flink;
1608  }
1609 
1610  /* Release the locks and return */
1614 }
ERESOURCE PsLoadedModuleResource
Definition: sysldr.c:24
#define max(a, b)
Definition: svc.c:63
#define TRUE
Definition: types.h:120
LIST_ENTRY PsLoadedModuleList
Definition: sysldr.c:21
union _IMAGE_SECTION_HEADER::@1517 Misc
ULONG SizeOfImage
Definition: ldrtypes.h:143
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
if(dx==0 &&dy==0)
Definition: linetemp.h:174
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
uint32_t ULONG_PTR
Definition: typedefs.h:65
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
PVOID DllBase
Definition: btrfs_drv.h:1880
VOID NTAPI MiFreeInitializationCode(IN PVOID InitStart, IN PVOID InitEnd)
Definition: sysldr.c:1414
#define FALSE
Definition: types.h:117
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
union Alignment_ Alignment
unsigned char BOOLEAN
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:319
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
CONST CHAR * PCCH
Definition: ntbasedef.h:392
#define ASSERT(a)
Definition: mode.c:44
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
KMUTANT MmSystemLoadLock
Definition: sysldr.c:26
#define MUTANT_INCREMENT
Definition: extypes.h:84
LONG NTAPI KeReleaseMutant(IN PKMUTANT Mutant, IN KPRIORITY Increment, IN BOOLEAN Abandon, IN BOOLEAN Wait)
Definition: mutex.c:98
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
Definition: btrfs_drv.h:1876
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:119
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define ALIGN_DOWN_BY(size, align)
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
UNICODE_STRING BaseDllName
Definition: ldrtypes.h:145
#define NULL
Definition: types.h:112
BYTE Name[IMAGE_SIZEOF_SHORT_NAME]
Definition: pedump.c:281
#define RtlImageNtHeader
Definition: compat.h:806
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)
#define DPRINT
Definition: sndvol32.h:71
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1437
#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 1414 of file sysldr.c.

1416 {
1417  PMMPTE PointerPte;
1418  PFN_NUMBER PagesFreed;
1419 
1420  /* Get the start PTE */
1421  PointerPte = MiAddressToPte(InitStart);
1422  ASSERT(MI_IS_PHYSICAL_ADDRESS(InitStart) == FALSE);
1423 
1424  /* Compute the number of pages we expect to free */
1425  PagesFreed = (PFN_NUMBER)(MiAddressToPte(InitEnd) - PointerPte);
1426 
1427  /* Try to actually free them */
1428  PagesFreed = MiDeleteSystemPageableVm(PointerPte,
1429  PagesFreed,
1430  0,
1431  NULL);
1432 }
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
#define NULL
Definition: types.h:112
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950

Referenced by MiFindInitializationCode(), and MmZeroPageThread().

◆ MmZeroPageThread()

VOID NTAPI MmZeroPageThread ( VOID  )

Definition at line 36 of file zeropage.c.

37 {
39  PVOID StartAddress, EndAddress;
40  PVOID WaitObjects[2];
41 
42  /* Get the discardable sections to free them */
43  MiFindInitializationCode(&StartAddress, &EndAddress);
44  if (StartAddress) MiFreeInitializationCode(StartAddress, EndAddress);
45  DPRINT("Free pages: %lx\n", MmAvailablePages);
46 
47  /* Set our priority to 0 */
48  Thread->BasePriority = 0;
50 
51  /* Setup the wait objects */
52  WaitObjects[0] = &MmZeroingPageEvent;
53 // WaitObjects[1] = &PoSystemIdleTimer; FIXME: Implement idle timer
54 
55  while (TRUE)
56  {
57  KIRQL OldIrql;
58 
60  WaitObjects,
61  WaitAny,
62  WrFreePage,
63  KernelMode,
64  FALSE,
65  NULL,
66  NULL);
67  OldIrql = MiAcquirePfnLock();
68 
69  while (TRUE)
70  {
71  ULONG PageCount = 0;
72  PMMPFN Pfn1 = (PMMPFN)LIST_HEAD;
73  PVOID ZeroAddress;
74  PFN_NUMBER PageIndex, FreePage;
75 
76  while (PageCount < MI_ZERO_PTES)
77  {
78  PMMPFN Pfn2;
79 
81  break;
82 
83  PageIndex = MmFreePageListHead.Flink;
84  ASSERT(PageIndex != LIST_HEAD);
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  Pfn2 = MiGetPfnEntry(PageIndex);
100  Pfn2->u1.Flink = (PFN_NUMBER)Pfn1;
101  Pfn1 = Pfn2;
102  PageCount++;
103  }
104  MiReleasePfnLock(OldIrql);
105 
106  if (PageCount == 0)
107  {
109  break;
110  }
111 
112  ZeroAddress = MiMapPagesInZeroSpace(Pfn1, PageCount);
113  ASSERT(ZeroAddress);
114  KeZeroPages(ZeroAddress, PageCount * PAGE_SIZE);
115  MiUnmapPagesInZeroSpace(ZeroAddress, PageCount);
116 
117  OldIrql = MiAcquirePfnLock();
118 
119  while (Pfn1 != (PMMPFN)LIST_HEAD)
120  {
121  PageIndex = MiGetPfnEntryIndex(Pfn1);
122  Pfn1 = (PMMPFN)Pfn1->u1.Flink;
124  }
125  }
126  }
127 }
KEVENT MmZeroingPageEvent
Definition: zeropage.c:20
#define TRUE
Definition: types.h:120
VOID NTAPI MiFindInitializationCode(OUT PVOID *StartVa, OUT PVOID *EndVa)
Definition: sysldr.c:1437
PFN_NUMBER Flink
Definition: mm.h:377
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
MMPFNLIST MmZeroedPageListHead
Definition: pfnlist.c:41
PFN_NUMBER Flink
Definition: mm.h:445
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
#define MI_SET_PROCESS2(x)
Definition: mm.h:319
VOID NTAPI MiInsertPageInList(IN PMMPFNLIST ListHead, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:771
#define MI_SET_USAGE(x)
Definition: mm.h:317
VOID FASTCALL KeZeroPages(IN PVOID Address, IN ULONG Size)
Definition: cpu.c:56
VOID NTAPI MiFreeInitializationCode(IN PVOID StartVa, IN PVOID EndVa)
Definition: sysldr.c:1414
#define ASSERT(a)
Definition: mode.c:44
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2652
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
PVOID NTAPI MiMapPagesInZeroSpace(IN PMMPFN Pfn1, IN PFN_NUMBER NumberOfPages)
Definition: hypermap.c:111
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
Definition: mm.h:373
#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:1047
#define MI_GET_PAGE_COLOR(x)
Definition: miarm.h:236
union _MMPFN::@1755 u1
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
VOID NTAPI MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress, IN PFN_NUMBER NumberOfPages)
Definition: hypermap.c:187
KPRIORITY NTAPI KeSetPriorityThread(IN PKTHREAD Thread, IN KPRIORITY Priority)
Definition: thrdobj.c:1327
PFN_NUMBER Total
Definition: mm.h:443
struct _MMPFN * PMMPFN
#define NULL
Definition: types.h:112
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:1067
unsigned int ULONG
Definition: retypes.h:1
#define DPRINT
Definition: sndvol32.h:71
#define KeGetCurrentThread
Definition: hal.h:55
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define MI_ZERO_PTES
Definition: mm.h:82
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:108

Referenced by Phase1Initialization().

Variable Documentation

◆ MmZeroingPageEvent

KEVENT MmZeroingPageEvent

Definition at line 20 of file zeropage.c.

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