Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

989 lines
24 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. miglobal.c
  5. Abstract:
  6. This module contains the private global storage for the memory
  7. management subsystem.
  8. Author:
  9. Lou Perazzoli (loup) 6-Apr-1989
  10. Landy Wang (landyw) 02-June-1997
  11. Revision History:
  12. --*/
  13. #include "mi.h"
  14. //
  15. // Highest user address;
  16. //
  17. PVOID MmHighestUserAddress;
  18. //
  19. // Start of system address range.
  20. //
  21. PVOID MmSystemRangeStart;
  22. //
  23. // User probe address;
  24. //
  25. ULONG_PTR MmUserProbeAddress;
  26. #if !defined(_WIN64)
  27. //
  28. // Virtual bias applied during the loading of the kernel image.
  29. //
  30. ULONG_PTR MmVirtualBias;
  31. #endif
  32. //
  33. // Number of secondary colors, based on level 2 d cache size.
  34. //
  35. ULONG MmSecondaryColors;
  36. //
  37. // The starting color index seed, incremented at each process creation.
  38. //
  39. ULONG MmProcessColorSeed = 0x12345678;
  40. //
  41. // Total number of physical pages available on the system.
  42. //
  43. PFN_COUNT MmNumberOfPhysicalPages;
  44. //
  45. // Lowest physical page number in the system.
  46. //
  47. PFN_NUMBER MmLowestPhysicalPage = (PFN_NUMBER)-1;
  48. //
  49. // Highest physical page number in the system.
  50. //
  51. PFN_NUMBER MmHighestPhysicalPage;
  52. //
  53. // Highest possible physical page number in the system.
  54. //
  55. PFN_NUMBER MmHighestPossiblePhysicalPage;
  56. //
  57. // Total number of available pages in the system. This
  58. // is the sum of the pages on the zeroed, free and standby lists.
  59. //
  60. PFN_COUNT MmAvailablePages;
  61. PFN_NUMBER MmThrottleTop;
  62. PFN_NUMBER MmThrottleBottom;
  63. //
  64. // Highest VAD index used to create bitmaps.
  65. //
  66. ULONG MiLastVadBit = 1;
  67. //
  68. // System wide memory management statistics block.
  69. //
  70. MMINFO_COUNTERS MmInfoCounters;
  71. //
  72. // Total number of physical pages which would be usable if every process
  73. // was at its minimum working set size. This value is initialized
  74. // at system initialization to MmAvailablePages - MM_FLUID_PHYSICAL_PAGES.
  75. // Every time a thread is created, the kernel stack is subtracted from
  76. // this and every time a process is created, the minimum working set
  77. // is subtracted from this. If the value would become negative, the
  78. // operation (create process/kernel stack/ adjust working set) fails.
  79. // The PFN LOCK must be owned to manipulate this value.
  80. //
  81. SPFN_NUMBER MmResidentAvailablePages;
  82. //
  83. // The total number of pages which would be removed from working sets
  84. // if every working set was at its minimum.
  85. //
  86. PFN_NUMBER MmPagesAboveWsMinimum;
  87. //
  88. // The total number of pages which would be removed from working sets
  89. // if every working set above its maximum was at its maximum.
  90. //
  91. PFN_NUMBER MmPagesAboveWsMaximum;
  92. //
  93. // The number of pages to add to a working set if there are ample
  94. // available pages and the working set is below its maximum.
  95. //
  96. //
  97. // If memory is becoming short and MmPagesAboveWsMinimum is
  98. // greater than MmPagesAboveWsThreshold, trim working sets.
  99. //
  100. PFN_NUMBER MmPagesAboveWsThreshold = 37;
  101. PFN_NUMBER MmWorkingSetSizeIncrement = 6;
  102. //
  103. // The number of pages to extend the maximum working set size by
  104. // if the working set at its maximum and there are ample available pages.
  105. PFN_NUMBER MmWorkingSetSizeExpansion = 20;
  106. //
  107. // The number of pages required to be freed by working set reduction
  108. // before working set reduction is attempted.
  109. //
  110. PFN_NUMBER MmWsAdjustThreshold = 45;
  111. //
  112. // The number of pages available to allow the working set to be
  113. // expanded above its maximum.
  114. //
  115. PFN_NUMBER MmWsExpandThreshold = 90;
  116. //
  117. // The total number of pages to reduce by working set trimming.
  118. //
  119. PFN_NUMBER MmWsTrimReductionGoal = 29;
  120. //
  121. // The total number of pages needed for the loader to successfully hibernate.
  122. //
  123. PFN_NUMBER MmHiberPages = 768;
  124. //
  125. // The following values are frequently used together. They tend
  126. // not to be modified once the system has initialized so should
  127. // not be grouped with data whose values change frequently to
  128. // eliminate false sharing.
  129. //
  130. ULONG MmSecondaryColorMask;
  131. UCHAR MmSecondaryColorNodeShift;
  132. //
  133. // Registry-settable threshold for using large pages. x86 only.
  134. //
  135. ULONG MmLargePageMinimum;
  136. PMMPFN MmPfnDatabase;
  137. MMPFNLIST MmZeroedPageListHead = {
  138. 0, // Total
  139. ZeroedPageList, // ListName
  140. MM_EMPTY_LIST, //Flink
  141. MM_EMPTY_LIST // Blink
  142. };
  143. MMPFNLIST MmFreePageListHead = {
  144. 0, // Total
  145. FreePageList, // ListName
  146. MM_EMPTY_LIST, //Flink
  147. MM_EMPTY_LIST // Blink
  148. };
  149. MMPFNLIST MmStandbyPageListHead = {
  150. 0, // Total
  151. StandbyPageList, // ListName
  152. MM_EMPTY_LIST, //Flink
  153. MM_EMPTY_LIST // Blink
  154. };
  155. MMPFNLIST MmModifiedPageListHead = {
  156. 0, // Total
  157. ModifiedPageList, // ListName
  158. MM_EMPTY_LIST, //Flink
  159. MM_EMPTY_LIST // Blink
  160. };
  161. MMPFNLIST MmModifiedNoWritePageListHead = {
  162. 0, // Total
  163. ModifiedNoWritePageList, // ListName
  164. MM_EMPTY_LIST, //Flink
  165. MM_EMPTY_LIST // Blink
  166. };
  167. MMPFNLIST MmBadPageListHead = {
  168. 0, // Total
  169. BadPageList, // ListName
  170. MM_EMPTY_LIST, //Flink
  171. MM_EMPTY_LIST // Blink
  172. };
  173. //
  174. // Note the ROM page listhead is deliberately not in the set
  175. // of MmPageLocationList ranges.
  176. //
  177. MMPFNLIST MmRomPageListHead = {
  178. 0, // Total
  179. StandbyPageList, // ListName
  180. MM_EMPTY_LIST, //Flink
  181. MM_EMPTY_LIST // Blink
  182. };
  183. PMMPFNLIST MmPageLocationList[NUMBER_OF_PAGE_LISTS] = {
  184. &MmZeroedPageListHead,
  185. &MmFreePageListHead,
  186. &MmStandbyPageListHead,
  187. &MmModifiedPageListHead,
  188. &MmModifiedNoWritePageListHead,
  189. &MmBadPageListHead,
  190. NULL,
  191. NULL };
  192. PMMPTE MiHighestUserPte;
  193. PMMPTE MiHighestUserPde;
  194. #if (_MI_PAGING_LEVELS >= 4)
  195. PMMPTE MiHighestUserPpe;
  196. PMMPTE MiHighestUserPxe;
  197. #endif
  198. PMMPTE MiSessionBasePte;
  199. PMMPTE MiSessionLastPte;
  200. //
  201. // Hyper space items.
  202. //
  203. PMMPTE MmFirstReservedMappingPte;
  204. PMMPTE MmLastReservedMappingPte;
  205. //
  206. // Event for available pages, set means pages are available.
  207. //
  208. KEVENT MmAvailablePagesEvent;
  209. //
  210. // Event for the zeroing page thread.
  211. //
  212. KEVENT MmZeroingPageEvent;
  213. //
  214. // Boolean to indicate if the zeroing page thread is currently
  215. // active. This is set to true when the zeroing page event is
  216. // set and set to false when the zeroing page thread is done
  217. // zeroing all the pages on the free list.
  218. //
  219. BOOLEAN MmZeroingPageThreadActive;
  220. //
  221. // Minimum number of free pages before zeroing page thread starts.
  222. //
  223. PFN_NUMBER MmMinimumFreePagesToZero = 8;
  224. //
  225. // System space sizes - MmNonPagedSystemStart to MM_NON_PAGED_SYSTEM_END
  226. // defines the ranges of PDEs which must be copied into a new process's
  227. // address space.
  228. //
  229. PVOID MmNonPagedSystemStart;
  230. LOGICAL MmProtectFreedNonPagedPool;
  231. //
  232. // This is set in the registry to the maximum number of gigabytes of RAM
  233. // that can be added to this machine (ie: #of DIMM slots times maximum
  234. // supported DIMM size). This lets configurations that won't use the absolute
  235. // maximum indicate that a smaller (virtually) PFN database size can be used
  236. // thus leaving more virtual address space for things like system PTEs, etc.
  237. //
  238. PFN_NUMBER MmDynamicPfn;
  239. #ifdef MM_BUMP_COUNTER_MAX
  240. SIZE_T MmResTrack[MM_BUMP_COUNTER_MAX];
  241. #endif
  242. #ifdef MM_COMMIT_COUNTER_MAX
  243. SIZE_T MmTrackCommit[MM_COMMIT_COUNTER_MAX];
  244. #endif
  245. //
  246. // Set via the registry to identify which drivers are leaking locked pages.
  247. //
  248. LOGICAL MmTrackLockedPages;
  249. KSPIN_LOCK MiTrackLockedPagesLock;
  250. //
  251. // Set via the registry to identify drivers which unload without releasing
  252. // resources or still have active timers, etc.
  253. //
  254. LOGICAL MmSnapUnloads = TRUE;
  255. #if DBG
  256. PETHREAD MiExpansionLockOwner;
  257. #endif
  258. //
  259. // Pool sizes.
  260. //
  261. SIZE_T MmSizeOfNonPagedPoolInBytes;
  262. SIZE_T MmMaximumNonPagedPoolInBytes;
  263. ULONG MmMaximumNonPagedPoolPercent;
  264. SIZE_T MmMinimumNonPagedPoolSize = 256 * 1024; // 256k
  265. ULONG MmMinAdditionNonPagedPoolPerMb = 32 * 1024; // 32k
  266. SIZE_T MmDefaultMaximumNonPagedPool = 1024 * 1024; // 1mb
  267. ULONG MmMaxAdditionNonPagedPoolPerMb = 400 * 1024; //400k
  268. SIZE_T MmSizeOfPagedPoolInBytes = 32 * 1024 * 1024; // 32 MB.
  269. ULONG MmNumberOfSystemPtes;
  270. ULONG MiRequestedSystemPtes;
  271. PMMPTE MmFirstPteForPagedPool;
  272. PMMPTE MmLastPteForPagedPool;
  273. //
  274. // Pool bit maps and other related structures.
  275. //
  276. PVOID MmPageAlignedPoolBase[2];
  277. ULONG MmExpandedPoolBitPosition;
  278. PFN_NUMBER MmNumberOfFreeNonPagedPool;
  279. //
  280. // MmFirstFreeSystemPte contains the offset from the
  281. // Nonpaged system base to the first free system PTE.
  282. // Note that an offset of -1 indicates an empty list.
  283. //
  284. MMPTE MmFirstFreeSystemPte[MaximumPtePoolTypes];
  285. //
  286. // System cache sizes.
  287. //
  288. PMMWSL MmSystemCacheWorkingSetList = (PMMWSL)MM_SYSTEM_CACHE_WORKING_SET;
  289. MMSUPPORT MmSystemCacheWs;
  290. PMMWSLE MmSystemCacheWsle;
  291. PVOID MmSystemCacheStart = (PVOID)MM_SYSTEM_CACHE_START;
  292. PVOID MmSystemCacheEnd;
  293. PRTL_BITMAP MmSystemCacheAllocationMap;
  294. PRTL_BITMAP MmSystemCacheEndingMap;
  295. //
  296. // This value should not be greater than 256MB in a system with 1GB of
  297. // system space.
  298. //
  299. ULONG_PTR MmSizeOfSystemCacheInPages = 64 * 256; //64MB.
  300. //
  301. // Default sizes for the system cache.
  302. //
  303. PFN_NUMBER MmSystemCacheWsMinimum = 288;
  304. PFN_NUMBER MmSystemCacheWsMaximum = 350;
  305. //
  306. // Cells to track unused thread kernel stacks to avoid TB flushes
  307. // every time a thread terminates.
  308. //
  309. ULONG MmMaximumDeadKernelStacks = 5;
  310. SLIST_HEADER MmDeadStackSListHead;
  311. //
  312. // Cells to track control area synchronization.
  313. //
  314. SLIST_HEADER MmEventCountSListHead;
  315. SLIST_HEADER MmInPageSupportSListHead;
  316. //
  317. // MmSystemPteBase contains the address of 1 PTE before
  318. // the first free system PTE (zero indicates an empty list).
  319. // The value of this field does not change once set.
  320. //
  321. PMMPTE MmSystemPteBase;
  322. PMMADDRESS_NODE MmSectionBasedRoot;
  323. PVOID MmHighSectionBase;
  324. //
  325. // Section object type.
  326. //
  327. POBJECT_TYPE MmSectionObjectType;
  328. //
  329. // Section commit mutex.
  330. //
  331. FAST_MUTEX MmSectionCommitMutex;
  332. //
  333. // Section base address mutex.
  334. //
  335. FAST_MUTEX MmSectionBasedMutex;
  336. //
  337. // Resource for section extension.
  338. //
  339. ERESOURCE MmSectionExtendResource;
  340. ERESOURCE MmSectionExtendSetResource;
  341. //
  342. // Pagefile creation lock.
  343. //
  344. FAST_MUTEX MmPageFileCreationLock;
  345. MMDEREFERENCE_SEGMENT_HEADER MmDereferenceSegmentHeader;
  346. LIST_ENTRY MmUnusedSegmentList;
  347. LIST_ENTRY MmUnusedSubsectionList;
  348. KEVENT MmUnusedSegmentCleanup;
  349. ULONG MmUnusedSegmentCount;
  350. ULONG MmUnusedSubsectionCount;
  351. ULONG MmUnusedSubsectionCountPeak;
  352. SIZE_T MiUnusedSubsectionPagedPool;
  353. SIZE_T MiUnusedSubsectionPagedPoolPeak;
  354. //
  355. // If more than this percentage of pool is consumed and pool allocations
  356. // might fail, then trim unused segments & subsections to get back to
  357. // this percentage.
  358. //
  359. ULONG MmConsumedPoolPercentage;
  360. MMWORKING_SET_EXPANSION_HEAD MmWorkingSetExpansionHead;
  361. MMPAGE_FILE_EXPANSION MmAttemptForCantExtend;
  362. //
  363. // Paging files
  364. //
  365. MMMOD_WRITER_LISTHEAD MmPagingFileHeader;
  366. MMMOD_WRITER_LISTHEAD MmMappedFileHeader;
  367. LIST_ENTRY MmFreePagingSpaceLow;
  368. ULONG MmNumberOfActiveMdlEntries;
  369. PMMPAGING_FILE MmPagingFile[MAX_PAGE_FILES];
  370. ULONG MmNumberOfPagingFiles;
  371. KEVENT MmModifiedPageWriterEvent;
  372. KEVENT MmWorkingSetManagerEvent;
  373. KEVENT MmCollidedFlushEvent;
  374. //
  375. // Total number of committed pages.
  376. //
  377. SIZE_T MmTotalCommittedPages;
  378. //
  379. // Limit on committed pages. When MmTotalCommittedPages would become
  380. // greater than or equal to this number the paging files must be expanded.
  381. //
  382. SIZE_T MmTotalCommitLimit;
  383. SIZE_T MmTotalCommitLimitMaximum;
  384. //
  385. // Number of pages to overcommit without expanding the paging file.
  386. // MmTotalCommitLimit = (total paging file space) + MmOverCommit.
  387. //
  388. SIZE_T MmOverCommit;
  389. //
  390. // Modified page writer.
  391. //
  392. //
  393. // Minimum number of free pages before working set trimming and
  394. // aggressive modified page writing is started.
  395. //
  396. PFN_NUMBER MmMinimumFreePages = 26;
  397. //
  398. // Stop writing modified pages when MmFreeGoal pages exist.
  399. //
  400. PFN_NUMBER MmFreeGoal = 100;
  401. //
  402. // Start writing pages if more than this number of pages
  403. // is on the modified page list.
  404. //
  405. PFN_NUMBER MmModifiedPageMaximum;
  406. //
  407. // Minimum number of modified pages required before the modified
  408. // page writer is started.
  409. //
  410. PFN_NUMBER MmModifiedPageMinimum;
  411. //
  412. // Amount of disk space that must be free after the paging file is
  413. // extended.
  414. //
  415. ULONG MmMinimumFreeDiskSpace = 1024 * 1024;
  416. //
  417. // Minimum size in pages to extend the paging file by.
  418. //
  419. ULONG MmPageFileExtension = 256;
  420. //
  421. // Size to reduce the paging file by.
  422. //
  423. ULONG MmMinimumPageFileReduction = 256; //256 pages (1mb)
  424. //
  425. // Number of pages to write in a single I/O.
  426. //
  427. ULONG MmModifiedWriteClusterSize = MM_MAXIMUM_WRITE_CLUSTER;
  428. //
  429. // Number of pages to read in a single I/O if possible.
  430. //
  431. ULONG MmReadClusterSize = 7;
  432. const ULONG MMSECT = 'tSmM'; // This is exported to special pool.
  433. //
  434. // This resource guards the working set list for the system shared
  435. // address space (paged pool, system cache, pagable drivers).
  436. //
  437. ERESOURCE MmSystemWsLock;
  438. PETHREAD MmSystemLockOwner;
  439. //
  440. // Spin lock for allowing working set expansion.
  441. //
  442. KSPIN_LOCK MmExpansionLock;
  443. //
  444. // System process working set sizes.
  445. //
  446. PFN_NUMBER MmSystemProcessWorkingSetMin = 50;
  447. PFN_NUMBER MmSystemProcessWorkingSetMax = 450;
  448. WSLE_NUMBER MmMaximumWorkingSetSize;
  449. PFN_NUMBER MmMinimumWorkingSetSize = 20;
  450. //
  451. // Page color for system working set.
  452. //
  453. ULONG MmSystemPageColor;
  454. //
  455. // Time constants
  456. //
  457. const LARGE_INTEGER MmSevenMinutes = {0, -1};
  458. //
  459. // Note that the following constant is initialized to five seconds,
  460. // but is set to 3 on very small workstations.
  461. //
  462. LARGE_INTEGER MmWorkingSetProtectionTime = {5 * 1000 * 1000 * 10, 0};
  463. const LARGE_INTEGER MmOneSecond = {(ULONG)(-1 * 1000 * 1000 * 10), -1};
  464. const LARGE_INTEGER MmTwentySeconds = {(ULONG)(-20 * 1000 * 1000 * 10), -1};
  465. const LARGE_INTEGER MmShortTime = {(ULONG)(-10 * 1000 * 10), -1}; // 10 milliseconds
  466. const LARGE_INTEGER MmHalfSecond = {(ULONG)(-5 * 100 * 1000 * 10), -1};
  467. const LARGE_INTEGER Mm30Milliseconds = {(ULONG)(-30 * 1000 * 10), -1};
  468. //
  469. // Parameters for user mode passed up via PEB in MmCreatePeb.
  470. //
  471. LARGE_INTEGER MmCriticalSectionTimeout; // Filled in by mminit.c
  472. SIZE_T MmHeapSegmentReserve = 1024 * 1024;
  473. SIZE_T MmHeapSegmentCommit = PAGE_SIZE * 2;
  474. SIZE_T MmHeapDeCommitTotalFreeThreshold = 64 * 1024;
  475. SIZE_T MmHeapDeCommitFreeBlockThreshold = PAGE_SIZE;
  476. //
  477. // Set from ntos\config\CMDAT3.C Used by customers to disable paging
  478. // of executive on machines with lots of memory. Worth a few TPS on a
  479. // database server.
  480. //
  481. ULONG MmDisablePagingExecutive;
  482. BOOLEAN Mm64BitPhysicalAddress;
  483. #if DBG
  484. ULONG MmDebug;
  485. #endif
  486. //
  487. // Map a page protection from the Pte.Protect field into a protection mask.
  488. //
  489. ULONG MmProtectToValue[32] = {
  490. PAGE_NOACCESS,
  491. PAGE_READONLY,
  492. PAGE_EXECUTE,
  493. PAGE_EXECUTE_READ,
  494. PAGE_READWRITE,
  495. PAGE_WRITECOPY,
  496. PAGE_EXECUTE_READWRITE,
  497. PAGE_EXECUTE_WRITECOPY,
  498. PAGE_NOACCESS,
  499. PAGE_NOCACHE | PAGE_READONLY,
  500. PAGE_NOCACHE | PAGE_EXECUTE,
  501. PAGE_NOCACHE | PAGE_EXECUTE_READ,
  502. PAGE_NOCACHE | PAGE_READWRITE,
  503. PAGE_NOCACHE | PAGE_WRITECOPY,
  504. PAGE_NOCACHE | PAGE_EXECUTE_READWRITE,
  505. PAGE_NOCACHE | PAGE_EXECUTE_WRITECOPY,
  506. PAGE_NOACCESS,
  507. PAGE_GUARD | PAGE_READONLY,
  508. PAGE_GUARD | PAGE_EXECUTE,
  509. PAGE_GUARD | PAGE_EXECUTE_READ,
  510. PAGE_GUARD | PAGE_READWRITE,
  511. PAGE_GUARD | PAGE_WRITECOPY,
  512. PAGE_GUARD | PAGE_EXECUTE_READWRITE,
  513. PAGE_GUARD | PAGE_EXECUTE_WRITECOPY,
  514. PAGE_NOACCESS,
  515. PAGE_NOCACHE | PAGE_GUARD | PAGE_READONLY,
  516. PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE,
  517. PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE_READ,
  518. PAGE_NOCACHE | PAGE_GUARD | PAGE_READWRITE,
  519. PAGE_NOCACHE | PAGE_GUARD | PAGE_WRITECOPY,
  520. PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE_READWRITE,
  521. PAGE_NOCACHE | PAGE_GUARD | PAGE_EXECUTE_WRITECOPY
  522. };
  523. #if (defined(_WIN64) || defined(_X86PAE_))
  524. ULONGLONG
  525. #else
  526. ULONG
  527. #endif
  528. MmProtectToPteMask[32] = {
  529. MM_PTE_NOACCESS,
  530. MM_PTE_READONLY | MM_PTE_CACHE,
  531. MM_PTE_EXECUTE | MM_PTE_CACHE,
  532. MM_PTE_EXECUTE_READ | MM_PTE_CACHE,
  533. MM_PTE_READWRITE | MM_PTE_CACHE,
  534. MM_PTE_WRITECOPY | MM_PTE_CACHE,
  535. MM_PTE_EXECUTE_READWRITE | MM_PTE_CACHE,
  536. MM_PTE_EXECUTE_WRITECOPY | MM_PTE_CACHE,
  537. MM_PTE_NOACCESS,
  538. MM_PTE_NOCACHE | MM_PTE_READONLY,
  539. MM_PTE_NOCACHE | MM_PTE_EXECUTE,
  540. MM_PTE_NOCACHE | MM_PTE_EXECUTE_READ,
  541. MM_PTE_NOCACHE | MM_PTE_READWRITE,
  542. MM_PTE_NOCACHE | MM_PTE_WRITECOPY,
  543. MM_PTE_NOCACHE | MM_PTE_EXECUTE_READWRITE,
  544. MM_PTE_NOCACHE | MM_PTE_EXECUTE_WRITECOPY,
  545. MM_PTE_NOACCESS,
  546. MM_PTE_GUARD | MM_PTE_READONLY | MM_PTE_CACHE,
  547. MM_PTE_GUARD | MM_PTE_EXECUTE | MM_PTE_CACHE,
  548. MM_PTE_GUARD | MM_PTE_EXECUTE_READ | MM_PTE_CACHE,
  549. MM_PTE_GUARD | MM_PTE_READWRITE | MM_PTE_CACHE,
  550. MM_PTE_GUARD | MM_PTE_WRITECOPY | MM_PTE_CACHE,
  551. MM_PTE_GUARD | MM_PTE_EXECUTE_READWRITE | MM_PTE_CACHE,
  552. MM_PTE_GUARD | MM_PTE_EXECUTE_WRITECOPY | MM_PTE_CACHE,
  553. MM_PTE_NOACCESS,
  554. MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_READONLY,
  555. MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE,
  556. MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE_READ,
  557. MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_READWRITE,
  558. MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_WRITECOPY,
  559. MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE_READWRITE,
  560. MM_PTE_NOCACHE | MM_PTE_GUARD | MM_PTE_EXECUTE_WRITECOPY
  561. };
  562. //
  563. // Conversion which takes a Pte.Protect and builds a new Pte.Protect which
  564. // is not copy-on-write.
  565. //
  566. ULONG MmMakeProtectNotWriteCopy[32] = {
  567. MM_NOACCESS,
  568. MM_READONLY,
  569. MM_EXECUTE,
  570. MM_EXECUTE_READ,
  571. MM_READWRITE,
  572. MM_READWRITE, //not copy
  573. MM_EXECUTE_READWRITE,
  574. MM_EXECUTE_READWRITE,
  575. MM_NOACCESS,
  576. MM_NOCACHE | MM_READONLY,
  577. MM_NOCACHE | MM_EXECUTE,
  578. MM_NOCACHE | MM_EXECUTE_READ,
  579. MM_NOCACHE | MM_READWRITE,
  580. MM_NOCACHE | MM_READWRITE,
  581. MM_NOCACHE | MM_EXECUTE_READWRITE,
  582. MM_NOCACHE | MM_EXECUTE_READWRITE,
  583. MM_NOACCESS,
  584. MM_GUARD_PAGE | MM_READONLY,
  585. MM_GUARD_PAGE | MM_EXECUTE,
  586. MM_GUARD_PAGE | MM_EXECUTE_READ,
  587. MM_GUARD_PAGE | MM_READWRITE,
  588. MM_GUARD_PAGE | MM_READWRITE,
  589. MM_GUARD_PAGE | MM_EXECUTE_READWRITE,
  590. MM_GUARD_PAGE | MM_EXECUTE_READWRITE,
  591. MM_NOACCESS,
  592. MM_NOCACHE | MM_GUARD_PAGE | MM_READONLY,
  593. MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE,
  594. MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE_READ,
  595. MM_NOCACHE | MM_GUARD_PAGE | MM_READWRITE,
  596. MM_NOCACHE | MM_GUARD_PAGE | MM_READWRITE,
  597. MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE_READWRITE,
  598. MM_NOCACHE | MM_GUARD_PAGE | MM_EXECUTE_READWRITE
  599. };
  600. //
  601. // Converts a protection code to an access right for section access.
  602. // This uses only the lower 3 bits of the 5 bit protection code.
  603. //
  604. ACCESS_MASK MmMakeSectionAccess[8] = { SECTION_MAP_READ,
  605. SECTION_MAP_READ,
  606. SECTION_MAP_EXECUTE,
  607. SECTION_MAP_EXECUTE | SECTION_MAP_READ,
  608. SECTION_MAP_WRITE,
  609. SECTION_MAP_READ,
  610. SECTION_MAP_EXECUTE | SECTION_MAP_WRITE,
  611. SECTION_MAP_EXECUTE | SECTION_MAP_READ };
  612. //
  613. // Converts a protection code to an access right for file access.
  614. // This uses only the lower 3 bits of the 5 bit protection code.
  615. //
  616. ACCESS_MASK MmMakeFileAccess[8] = { FILE_READ_DATA,
  617. FILE_READ_DATA,
  618. FILE_EXECUTE,
  619. FILE_EXECUTE | FILE_READ_DATA,
  620. FILE_WRITE_DATA | FILE_READ_DATA,
  621. FILE_READ_DATA,
  622. FILE_EXECUTE | FILE_WRITE_DATA | FILE_READ_DATA,
  623. FILE_EXECUTE | FILE_READ_DATA };
  624. MM_PAGED_POOL_INFO MmPagedPoolInfo;
  625. //
  626. // Some Hydra variables.
  627. //
  628. ULONG_PTR MmSessionBase;
  629. PMM_SESSION_SPACE MmSessionSpace;
  630. ULONG_PTR MiSessionSpaceWs;
  631. SIZE_T MmSessionSize;
  632. LIST_ENTRY MiSessionWsList;
  633. ULONG_PTR MiSystemViewStart;
  634. SIZE_T MmSystemViewSize;
  635. ULONG_PTR MiSessionPoolStart;
  636. ULONG_PTR MiSessionPoolEnd;
  637. ULONG_PTR MiSessionSpaceEnd;
  638. ULONG_PTR MiSessionViewStart;
  639. ULONG MiSessionSpacePageTables;
  640. SIZE_T MmSessionViewSize;
  641. SIZE_T MmSessionPoolSize;
  642. ULONG_PTR MiSessionImageStart;
  643. ULONG_PTR MiSessionImageEnd;
  644. PMMPTE MiSessionImagePteStart;
  645. PMMPTE MiSessionImagePteEnd;
  646. SIZE_T MmSessionImageSize;
  647. //
  648. // Cache control stuff. Note this may be overridden by deficient hardware
  649. // platforms at startup.
  650. //
  651. MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2 * MmMaximumCacheType] =
  652. {
  653. //
  654. // Memory space
  655. //
  656. MiNonCached,
  657. MiCached,
  658. MiWriteCombined,
  659. MiCached,
  660. MiNonCached,
  661. MiWriteCombined,
  662. //
  663. // I/O space
  664. //
  665. MiNonCached,
  666. MiCached,
  667. MiWriteCombined,
  668. MiCached,
  669. MiNonCached,
  670. MiWriteCombined
  671. };
  672. //
  673. // Note the Driver Verifier can reinitialize the mask values.
  674. //
  675. ULONG MiIoRetryMask = 0x1f;
  676. ULONG MiFaultRetryMask = 0x1f;
  677. ULONG MiUserFaultRetryMask = 0xF;
  678. #if defined (_MI_INSTRUMENT_PFN)
  679. //
  680. // Instrumentation code to track PFN lock duration.
  681. //
  682. ULONG MiPfnTimings;
  683. ULONG_PTR MiPfnAcquiredAddress;
  684. LARGE_INTEGER MiPfnAcquired;
  685. LARGE_INTEGER MiPfnThreshold;
  686. MMPFNTIMINGS MiPfnSorted[MI_MAX_PFN_CALLERS];
  687. ULONG MiMaxPfnTimings = MI_MAX_PFN_CALLERS;
  688. ULONG_PTR
  689. MiGetExecutionAddress(
  690. VOID
  691. )
  692. {
  693. #if defined(_X86_)
  694. _asm {
  695. push dword ptr [esp]
  696. pop eax
  697. }
  698. #else
  699. PVOID CallingAddress;
  700. PVOID CallersCaller;
  701. RtlGetCallersAddress (&CallingAddress, &CallersCaller);
  702. return (ULONG_PTR) CallingAddress;
  703. #endif
  704. }
  705. #endif
  706. #ifdef ALLOC_DATA_PRAGMA
  707. #pragma data_seg("INIT")
  708. #endif
  709. WCHAR MmVerifyDriverBuffer[MI_SUSPECT_DRIVER_BUFFER_LENGTH] = {0};
  710. ULONG MmVerifyDriverBufferType = REG_NONE;
  711. ULONG MmVerifyDriverLevel = (ULONG)-1;
  712. ULONG MmCritsectTimeoutSeconds = 2592000;
  713. #ifdef ALLOC_DATA_PRAGMA
  714. #pragma data_seg()
  715. #endif
  716. ULONG MmVerifyDriverBufferLength = sizeof(MmVerifyDriverBuffer);