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

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 

Functions

VOID NTAPI MiProtectFreeNonPagedPool (IN PVOID VirtualAddress, IN ULONG PageCount)
 
BOOLEAN NTAPI MiUnProtectFreeNonPagedPool (IN PVOID VirtualAddress, IN ULONG PageCount)
 
FORCEINLINE VOID MiProtectedPoolUnProtectLinks (IN PLIST_ENTRY Links, OUT PVOID *PoolFlink, OUT PVOID *PoolBlink)
 
FORCEINLINE VOID MiProtectedPoolProtectLinks (IN PVOID PoolFlink, IN PVOID PoolBlink)
 
VOID NTAPI MiProtectedPoolInsertList (IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry, IN BOOLEAN Critical)
 
VOID NTAPI MiProtectedPoolRemoveEntryList (IN PLIST_ENTRY Entry)
 
VOID NTAPI MiInitializeNonPagedPoolThresholds (VOID)
 
VOID NTAPI MiInitializePoolEvents (VOID)
 
VOID NTAPI MiInitializeNonPagedPool (VOID)
 
POOL_TYPE NTAPI MmDeterminePoolType (IN PVOID PoolAddress)
 
PVOID NTAPI MiAllocatePoolPages (IN POOL_TYPE PoolType, IN SIZE_T SizeInBytes)
 
ULONG NTAPI MiFreePoolPages (IN PVOID StartingVa)
 
BOOLEAN NTAPI MiRaisePoolQuota (IN POOL_TYPE PoolType, IN ULONG CurrentMaxQuota, OUT PULONG NewMaxQuota)
 
NTSTATUS NTAPI MiInitializeSessionPool (VOID)
 
PVOID NTAPI MmAllocateMappingAddress (IN SIZE_T NumberOfBytes, IN ULONG PoolTag)
 
VOID NTAPI MmFreeMappingAddress (IN PVOID BaseAddress, IN ULONG PoolTag)
 

Variables

LIST_ENTRY MmNonPagedPoolFreeListHead [MI_MAX_FREE_PAGE_LISTS]
 
PFN_COUNT MmNumberOfFreeNonPagedPool
 
PFN_COUNT MiExpansionPoolPagesInitialCharge
 
PVOID MmNonPagedPoolEnd0
 
PFN_NUMBER MiStartOfInitialPoolFrame
 
PFN_NUMBER MiEndOfInitialPoolFrame
 
KGUARDED_MUTEX MmPagedPoolMutex
 
MM_PAGED_POOL_INFO MmPagedPoolInfo
 
SIZE_T MmAllocatedNonPagedPool
 
ULONG MmSpecialPoolTag
 
ULONG MmConsumedPoolPercentage
 
BOOLEAN MmProtectFreedNonPagedPool
 
SLIST_HEADER MiNonPagedPoolSListHead
 
ULONG MiNonPagedPoolSListMaximum = 4
 
SLIST_HEADER MiPagedPoolSListHead
 
ULONG MiPagedPoolSListMaximum = 8
 

Macro Definition Documentation

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 15 of file pool.c.

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file pool.c.

Function Documentation

◆ MiAllocatePoolPages()

PVOID NTAPI MiAllocatePoolPages ( IN POOL_TYPE  PoolType,
IN SIZE_T  SizeInBytes 
)

Definition at line 420 of file pool.c.

422 {
423  PFN_NUMBER PageFrameNumber;
424  PFN_COUNT SizeInPages, PageTableCount;
425  ULONG i;
426  KIRQL OldIrql;
427  PLIST_ENTRY NextEntry, NextHead, LastHead;
428  PMMPTE PointerPte, StartPte;
429  PMMPDE PointerPde;
430  ULONG EndAllocation;
431  MMPTE TempPte;
432  MMPDE TempPde;
433  PMMPFN Pfn1;
434  PVOID BaseVa, BaseVaStart;
435  PMMFREE_POOL_ENTRY FreeEntry;
436 
437  //
438  // Figure out how big the allocation is in pages
439  //
440  SizeInPages = (PFN_COUNT)BYTES_TO_PAGES(SizeInBytes);
441 
442  //
443  // Check for overflow
444  //
445  if (SizeInPages == 0)
446  {
447  //
448  // Fail
449  //
450  return NULL;
451  }
452 
453  //
454  // Handle paged pool
455  //
457  {
458  //
459  // If only one page is being requested, try to grab it from the S-LIST
460  //
461  if ((SizeInPages == 1) && (ExQueryDepthSList(&MiPagedPoolSListHead)))
462  {
464  if (BaseVa) return BaseVa;
465  }
466 
467  //
468  // Lock the paged pool mutex
469  //
471 
472  //
473  // Find some empty allocation space
474  //
476  SizeInPages,
478  if (i == 0xFFFFFFFF)
479  {
480  //
481  // Get the page bit count
482  //
483  i = ((SizeInPages - 1) / PTE_PER_PAGE) + 1;
484  DPRINT("Paged pool expansion: %lu %x\n", i, SizeInPages);
485 
486  //
487  // Check if there is enougn paged pool expansion space left
488  //
491  {
492  //
493  // Out of memory!
494  //
495  DPRINT1("FAILED to allocate %Iu bytes from paged pool\n", SizeInBytes);
497  return NULL;
498  }
499 
500  //
501  // Check if we'll have to expand past the last PTE we have available
502  //
505  {
506  //
507  // We can only support this much then
508  //
510  PageTableCount = (PFN_COUNT)(PointerPde + 1 -
512  ASSERT(PageTableCount < i);
513  i = PageTableCount;
514  }
515  else
516  {
517  //
518  // Otherwise, there is plenty of space left for this expansion
519  //
520  PageTableCount = i;
521  }
522 
523  //
524  // Get the template PDE we'll use to expand
525  //
527 
528  //
529  // Get the first PTE in expansion space
530  //
532  BaseVa = MiPdeToPte(PointerPde);
533  BaseVaStart = BaseVa;
534 
535  //
536  // Lock the PFN database and loop pages
537  //
538  OldIrql = MiAcquirePfnLock();
539  do
540  {
541  //
542  // It should not already be valid
543  //
544  ASSERT(PointerPde->u.Hard.Valid == 0);
545 
546  /* Request a page */
548  MI_SET_PROCESS2("Kernel");
549  PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
550  TempPde.u.Hard.PageFrameNumber = PageFrameNumber;
551 #if (_MI_PAGING_LEVELS >= 3)
552  /* On PAE/x64 systems, there's no double-buffering */
553  /* Initialize the PFN entry for it */
554  MiInitializePfnForOtherProcess(PageFrameNumber,
555  (PMMPTE)PointerPde,
556  PFN_FROM_PTE(MiAddressToPte(PointerPde)));
557 
558  /* Write the actual PDE now */
559  MI_WRITE_VALID_PDE(PointerPde, TempPde);
560 #else
561  //
562  // Save it into our double-buffered system page directory
563  //
564  MmSystemPagePtes[((ULONG_PTR)PointerPde & (SYSTEM_PD_SIZE - 1)) / sizeof(MMPTE)] = TempPde;
565 
566  /* Initialize the PFN */
567  MiInitializePfnForOtherProcess(PageFrameNumber,
568  (PMMPTE)PointerPde,
570 #endif
571 
572  //
573  // Move on to the next expansion address
574  //
575  PointerPde++;
576  BaseVa = (PVOID)((ULONG_PTR)BaseVa + PAGE_SIZE);
577  i--;
578  } while (i > 0);
579 
580  //
581  // Release the PFN database lock
582  //
583  MiReleasePfnLock(OldIrql);
584 
585  //
586  // These pages are now available, clear their availablity bits
587  //
590  PTE_PER_PAGE;
592  EndAllocation,
593  PageTableCount * PTE_PER_PAGE);
594 
595  //
596  // Update the next expansion location
597  //
599 
600  //
601  // Zero out the newly available memory
602  //
603  RtlZeroMemory(BaseVaStart, PageTableCount * PAGE_SIZE);
604 
605  //
606  // Now try consuming the pages again
607  //
609  SizeInPages,
610  0);
611  if (i == 0xFFFFFFFF)
612  {
613  //
614  // Out of memory!
615  //
616  DPRINT1("FAILED to allocate %Iu bytes from paged pool\n", SizeInBytes);
618  return NULL;
619  }
620  }
621 
622  //
623  // Update the pool hint if the request was just one page
624  //
625  if (SizeInPages == 1) MmPagedPoolInfo.PagedPoolHint = i + 1;
626 
627  //
628  // Update the end bitmap so we know the bounds of this allocation when
629  // the time comes to free it
630  //
631  EndAllocation = i + SizeInPages - 1;
633 
634  //
635  // Now we can release the lock (it mainly protects the bitmap)
636  //
638 
639  //
640  // Now figure out where this allocation starts
641  //
642  BaseVa = (PVOID)((ULONG_PTR)MmPagedPoolStart + (i << PAGE_SHIFT));
643 
644  //
645  // Flush the TLB
646  //
648 
649  /* Setup a demand-zero writable PTE */
651 
652  //
653  // Find the first and last PTE, then loop them all
654  //
655  PointerPte = MiAddressToPte(BaseVa);
656  StartPte = PointerPte + SizeInPages;
657  do
658  {
659  //
660  // Write the demand zero PTE and keep going
661  //
662  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
663  } while (++PointerPte < StartPte);
664 
665  //
666  // Return the allocation address to the caller
667  //
668  return BaseVa;
669  }
670 
671  //
672  // If only one page is being requested, try to grab it from the S-LIST
673  //
674  if ((SizeInPages == 1) && (ExQueryDepthSList(&MiNonPagedPoolSListHead)))
675  {
677  if (BaseVa) return BaseVa;
678  }
679 
680  //
681  // Allocations of less than 4 pages go into their individual buckets
682  //
683  i = min(SizeInPages, MI_MAX_FREE_PAGE_LISTS) - 1;
684 
685  //
686  // Loop through all the free page lists based on the page index
687  //
688  NextHead = &MmNonPagedPoolFreeListHead[i];
690 
691  //
692  // Acquire the nonpaged pool lock
693  //
695  do
696  {
697  //
698  // Now loop through all the free page entries in this given list
699  //
700  NextEntry = NextHead->Flink;
701  while (NextEntry != NextHead)
702  {
703  /* Is freed non paged pool enabled */
705  {
706  /* We need to be able to touch this page, unprotect it */
707  MiUnProtectFreeNonPagedPool(NextEntry, 0);
708  }
709 
710  //
711  // Grab the entry and see if it can handle our allocation
712  //
713  FreeEntry = CONTAINING_RECORD(NextEntry, MMFREE_POOL_ENTRY, List);
714  ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE);
715  if (FreeEntry->Size >= SizeInPages)
716  {
717  //
718  // It does, so consume the pages from here
719  //
720  FreeEntry->Size -= SizeInPages;
721 
722  //
723  // The allocation will begin in this free page area
724  //
725  BaseVa = (PVOID)((ULONG_PTR)FreeEntry +
726  (FreeEntry->Size << PAGE_SHIFT));
727 
728  /* Remove the item from the list, depending if pool is protected */
731  else
732  RemoveEntryList(&FreeEntry->List);
733 
734  //
735  // However, check if its' still got space left
736  //
737  if (FreeEntry->Size != 0)
738  {
739  /* Check which list to insert this entry into */
740  i = min(FreeEntry->Size, MI_MAX_FREE_PAGE_LISTS) - 1;
741 
742  /* Insert the entry into the free list head, check for prot. pool */
745  else
747 
748  /* Is freed non paged pool protected? */
750  {
751  /* Protect the freed pool! */
752  MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size);
753  }
754  }
755 
756  //
757  // Grab the PTE for this allocation
758  //
759  PointerPte = MiAddressToPte(BaseVa);
760  ASSERT(PointerPte->u.Hard.Valid == 1);
761 
762  //
763  // Grab the PFN NextEntry and index
764  //
765  Pfn1 = MiGetPfnEntry(PFN_FROM_PTE(PointerPte));
766 
767  //
768  // Now mark it as the beginning of an allocation
769  //
770  ASSERT(Pfn1->u3.e1.StartOfAllocation == 0);
771  Pfn1->u3.e1.StartOfAllocation = 1;
772 
773  /* Mark it as special pool if needed */
774  ASSERT(Pfn1->u4.VerifierAllocation == 0);
776  {
777  Pfn1->u4.VerifierAllocation = 1;
778  }
779 
780  //
781  // Check if the allocation is larger than one page
782  //
783  if (SizeInPages != 1)
784  {
785  //
786  // Navigate to the last PFN entry and PTE
787  //
788  PointerPte += SizeInPages - 1;
789  ASSERT(PointerPte->u.Hard.Valid == 1);
790  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
791  }
792 
793  //
794  // Mark this PFN as the last (might be the same as the first)
795  //
796  ASSERT(Pfn1->u3.e1.EndOfAllocation == 0);
797  Pfn1->u3.e1.EndOfAllocation = 1;
798 
799  //
800  // Release the nonpaged pool lock, and return the allocation
801  //
803  return BaseVa;
804  }
805 
806  //
807  // Try the next free page entry
808  //
809  NextEntry = FreeEntry->List.Flink;
810 
811  /* Is freed non paged pool protected? */
813  {
814  /* Protect the freed pool! */
815  MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size);
816  }
817  }
818  } while (++NextHead < LastHead);
819 
820  //
821  // If we got here, we're out of space.
822  // Start by releasing the lock
823  //
825 
826  //
827  // Allocate some system PTEs
828  //
829  StartPte = MiReserveSystemPtes(SizeInPages, NonPagedPoolExpansion);
830  PointerPte = StartPte;
831  if (StartPte == NULL)
832  {
833  //
834  // Ran out of memory
835  //
836  DPRINT("Out of NP Expansion Pool\n");
837  return NULL;
838  }
839 
840  //
841  // Acquire the pool lock now
842  //
844 
845  //
846  // Lock the PFN database too
847  //
848  MiAcquirePfnLockAtDpcLevel();
849 
850  /* Check that we have enough available pages for this request */
851  if (MmAvailablePages < SizeInPages)
852  {
853  MiReleasePfnLockFromDpcLevel();
855 
856  MiReleaseSystemPtes(StartPte, SizeInPages, NonPagedPoolExpansion);
857 
858  DPRINT1("OUT OF AVAILABLE PAGES! Required %lu, Available %lu\n", SizeInPages, MmAvailablePages);
859 
860  return NULL;
861  }
862 
863  //
864  // Loop the pages
865  //
867  do
868  {
869  /* Allocate a page */
871  MI_SET_PROCESS2("Kernel");
872  PageFrameNumber = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
873 
874  /* Get the PFN entry for it and fill it out */
875  Pfn1 = MiGetPfnEntry(PageFrameNumber);
876  Pfn1->u3.e2.ReferenceCount = 1;
877  Pfn1->u2.ShareCount = 1;
878  Pfn1->PteAddress = PointerPte;
880  Pfn1->u4.VerifierAllocation = 0;
881 
882  /* Write the PTE for it */
883  TempPte.u.Hard.PageFrameNumber = PageFrameNumber;
884  MI_WRITE_VALID_PTE(PointerPte++, TempPte);
885  } while (--SizeInPages > 0);
886 
887  //
888  // This is the last page
889  //
890  Pfn1->u3.e1.EndOfAllocation = 1;
891 
892  //
893  // Get the first page and mark it as such
894  //
895  Pfn1 = MiGetPfnEntry(StartPte->u.Hard.PageFrameNumber);
896  Pfn1->u3.e1.StartOfAllocation = 1;
897 
898  /* Mark it as a verifier allocation if needed */
899  ASSERT(Pfn1->u4.VerifierAllocation == 0);
901 
902  //
903  // Release the PFN and nonpaged pool lock
904  //
905  MiReleasePfnLockFromDpcLevel();
907 
908  //
909  // Return the address
910  //
911  return MiPteToAddress(StartPte);
912 }
#define MI_MAKE_SOFTWARE_PTE(p, x)
Definition: miarm.h:189
PRTL_BITMAP PagedPoolAllocationMap
Definition: mm.h:475
#define PDE_PER_PAGE
Definition: mm.h:21
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
BOOLEAN NTAPI MiUnProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:68
#define MiAddressToPde(x)
Definition: mmx86.c:20
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define TRUE
Definition: types.h:120
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
ULONG Signature
Definition: mm.h:465
#define VERIFIER_POOL_MASK
Definition: mm.h:112
NTSYSAPI VOID NTAPI RtlSetBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:304
union _MMPFN::@1761 u3
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:237
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1292
#define InsertTailList(ListHead, Entry)
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
FORCEINLINE PMMPDE MiPteToPde(PMMPTE PointerPte)
Definition: mm.h:261
USHORT PageLocation
Definition: mm.h:354
PSLIST_ENTRY WINAPI InterlockedPopEntrySList(PSLIST_HEADER ListHead)
Definition: interlocked.c:55
SLIST_HEADER MiNonPagedPoolSListHead
Definition: pool.c:30
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:386
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
PMMPTE LastPteForPagedPool
Definition: mm.h:478
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
ULONG_PTR ShareCount
Definition: mm.h:379
VOID NTAPI MiProtectedPoolRemoveEntryList(IN PLIST_ENTRY Entry)
Definition: pool.c:166
#define MI_SET_PROCESS2(x)
Definition: mm.h:308
LIST_ENTRY List
Definition: mm.h:463
PFN_NUMBER MmSystemPageDirectory[PPE_PER_PAGE]
Definition: init.c:40
#define MI_MAX_FREE_PAGE_LISTS
Definition: mm.h:80
FORCEINLINE PMMPTE MiPdeToPte(PMMPDE PointerPde)
Definition: mm.h:237
ULONG_PTR VerifierAllocation
Definition: mm.h:409
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
#define BASE_POOL_TYPE_MASK
Definition: ExPools.c:15
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1023
#define MI_SET_USAGE(x)
Definition: mm.h:306
void * PVOID
Definition: retypes.h:9
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:264
union _MMPFN::@1760 u2
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
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:403
KIRQL OldIrql
Definition: mm.h:1502
PMMPDE MmSystemPagePtes
Definition: init.c:41
KGUARDED_MUTEX MmPagedPoolMutex
Definition: pool.c:24
PFN_COUNT Size
Definition: mm.h:464
ULONG PageFrameNumber
Definition: mmtypes.h:74
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:470
#define ASSERT(a)
Definition: mode.c:44
Definition: mm.h:461
ULONG64 Valid
Definition: mmtypes.h:150
MM_PAGED_POOL_INFO MmPagedPoolInfo
Definition: pool.c:25
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
#define PTE_PER_PAGE
Definition: mm.h:20
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
FORCEINLINE USHORT ExQueryDepthSList(_In_ PSLIST_HEADER SListHead)
Definition: exfuncs.h:153
MMPTE ValidKernelPte
Definition: init.c:29
VOID NTAPI MiProtectedPoolInsertList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry, IN BOOLEAN Critical)
Definition: pool.c:148
#define BYTES_TO_PAGES(Size)
#define MM_READWRITE
Definition: inbv.c:12
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: mm.h:362
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:119
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1000
MMPTE ValidKernelPde
Definition: init.c:28
PVOID MmPagedPoolStart
Definition: miarm.h:579
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define SYSTEM_PD_SIZE
Definition: miarm.h:32
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:997
BOOLEAN MmProtectFreedNonPagedPool
Definition: pool.c:29
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PRTL_BITMAP EndOfPagedPoolBitmap
Definition: mm.h:476
struct _MMPFN::@1761::@1767 e2
PMMPTE PteAddress
Definition: mm.h:375
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
SLIST_HEADER MiPagedPoolSListHead
Definition: pool.c:32
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3810
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
VOID NTAPI MiProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:39
ULONG PagedPoolHint
Definition: mm.h:480
#define DPRINT
Definition: sndvol32.h:71
PMMPTE FirstPteForPagedPool
Definition: mm.h:477
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]
Definition: pool.c:20
union _MMPTE::@2287 u
#define PFN_FROM_PTE(v)
Definition: mm.h:92
ULONG PageFrameNumber
Definition: mmtypes.h:109
PMMPDE NextPdeForPagedPoolExpansion
Definition: mm.h:479
union _MMPFN::@1764 u4

Referenced by _IRQL_requires_(), ExAllocatePoolWithTag(), and InitializePool().

◆ MiFreePoolPages()

ULONG NTAPI MiFreePoolPages ( IN PVOID  StartingVa)

Definition at line 916 of file pool.c.

917 {
918  PMMPTE PointerPte, StartPte;
919  PMMPFN Pfn1, StartPfn;
920  PFN_COUNT FreePages, NumberOfPages;
921  KIRQL OldIrql;
922  PMMFREE_POOL_ENTRY FreeEntry, NextEntry, LastEntry;
923  ULONG i, End;
925 
926  //
927  // Handle paged pool
928  //
929  if ((StartingVa >= MmPagedPoolStart) && (StartingVa <= MmPagedPoolEnd))
930  {
931  //
932  // Calculate the offset from the beginning of paged pool, and convert it
933  // into pages
934  //
935  Offset = (ULONG_PTR)StartingVa - (ULONG_PTR)MmPagedPoolStart;
936  i = (ULONG)(Offset >> PAGE_SHIFT);
937  End = i;
938 
939  //
940  // Now use the end bitmap to scan until we find a set bit, meaning that
941  // this allocation finishes here
942  //
943  while (!RtlTestBit(MmPagedPoolInfo.EndOfPagedPoolBitmap, End)) End++;
944 
945  //
946  // Now calculate the total number of pages this allocation spans. If it's
947  // only one page, add it to the S-LIST instead of freeing it
948  //
949  NumberOfPages = End - i + 1;
950  if ((NumberOfPages == 1) &&
952  {
954  return 1;
955  }
956 
957  /* Delete the actual pages */
958  PointerPte = MmPagedPoolInfo.FirstPteForPagedPool + i;
959  FreePages = MiDeleteSystemPageableVm(PointerPte, NumberOfPages, 0, NULL);
960  ASSERT(FreePages == NumberOfPages);
961 
962  //
963  // Acquire the paged pool lock
964  //
966 
967  //
968  // Clear the allocation and free bits
969  //
972 
973  //
974  // Update the hint if we need to
975  //
977 
978  //
979  // Release the lock protecting the bitmaps
980  //
982 
983  //
984  // And finally return the number of pages freed
985  //
986  return NumberOfPages;
987  }
988 
989  //
990  // Get the first PTE and its corresponding PFN entry. If this is also the
991  // last PTE, meaning that this allocation was only for one page, push it into
992  // the S-LIST instead of freeing it
993  //
994  StartPte = PointerPte = MiAddressToPte(StartingVa);
995  StartPfn = Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
996  if ((Pfn1->u3.e1.EndOfAllocation == 1) &&
998  {
1000  return 1;
1001  }
1002 
1003  //
1004  // Loop until we find the last PTE
1005  //
1006  while (Pfn1->u3.e1.EndOfAllocation == 0)
1007  {
1008  //
1009  // Keep going
1010  //
1011  PointerPte++;
1012  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
1013  }
1014 
1015  //
1016  // Now we know how many pages we have
1017  //
1018  NumberOfPages = (PFN_COUNT)(PointerPte - StartPte + 1);
1019 
1020  //
1021  // Acquire the nonpaged pool lock
1022  //
1024 
1025  //
1026  // Mark the first and last PTEs as not part of an allocation anymore
1027  //
1028  StartPfn->u3.e1.StartOfAllocation = 0;
1029  Pfn1->u3.e1.EndOfAllocation = 0;
1030 
1031  //
1032  // Assume we will free as many pages as the allocation was
1033  //
1034  FreePages = NumberOfPages;
1035 
1036  //
1037  // Peek one page past the end of the allocation
1038  //
1039  PointerPte++;
1040 
1041  //
1042  // Guard against going past initial nonpaged pool
1043  //
1045  {
1046  //
1047  // This page is on the outskirts of initial nonpaged pool, so ignore it
1048  //
1049  Pfn1 = NULL;
1050  }
1051  else
1052  {
1053  /* Sanity check */
1054  ASSERT((ULONG_PTR)StartingVa + NumberOfPages <= (ULONG_PTR)MmNonPagedPoolEnd);
1055 
1056  /* Check if protected pool is enabled */
1058  {
1059  /* The freed block will be merged, it must be made accessible */
1061  }
1062 
1063  //
1064  // Otherwise, our entire allocation must've fit within the initial non
1065  // paged pool, or the expansion nonpaged pool, so get the PFN entry of
1066  // the next allocation
1067  //
1068  if (PointerPte->u.Hard.Valid == 1)
1069  {
1070  //
1071  // It's either expansion or initial: get the PFN entry
1072  //
1073  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
1074  }
1075  else
1076  {
1077  //
1078  // This means we've reached the guard page that protects the end of
1079  // the expansion nonpaged pool
1080  //
1081  Pfn1 = NULL;
1082  }
1083 
1084  }
1085 
1086  //
1087  // Check if this allocation actually exists
1088  //
1089  if ((Pfn1) && (Pfn1->u3.e1.StartOfAllocation == 0))
1090  {
1091  //
1092  // It doesn't, so we should actually locate a free entry descriptor
1093  //
1094  FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)StartingVa +
1095  (NumberOfPages << PAGE_SHIFT));
1096  ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE);
1097  ASSERT(FreeEntry->Owner == FreeEntry);
1098 
1099  /* Consume this entry's pages */
1100  FreePages += FreeEntry->Size;
1101 
1102  /* Remove the item from the list, depending if pool is protected */
1104  MiProtectedPoolRemoveEntryList(&FreeEntry->List);
1105  else
1106  RemoveEntryList(&FreeEntry->List);
1107  }
1108 
1109  //
1110  // Now get the official free entry we'll create for the caller's allocation
1111  //
1112  FreeEntry = StartingVa;
1113 
1114  //
1115  // Check if the our allocation is the very first page
1116  //
1118  {
1119  //
1120  // Then we can't do anything or we'll risk underflowing
1121  //
1122  Pfn1 = NULL;
1123  }
1124  else
1125  {
1126  //
1127  // Otherwise, get the PTE for the page right before our allocation
1128  //
1129  PointerPte -= NumberOfPages + 1;
1130 
1131  /* Check if protected pool is enabled */
1133  {
1134  /* The freed block will be merged, it must be made accessible */
1136  }
1137 
1138  /* Check if this is valid pool, or a guard page */
1139  if (PointerPte->u.Hard.Valid == 1)
1140  {
1141  //
1142  // It's either expansion or initial nonpaged pool, get the PFN entry
1143  //
1144  Pfn1 = MiGetPfnEntry(PointerPte->u.Hard.PageFrameNumber);
1145  }
1146  else
1147  {
1148  //
1149  // We must've reached the guard page, so don't risk touching it
1150  //
1151  Pfn1 = NULL;
1152  }
1153  }
1154 
1155  //
1156  // Check if there is a valid PFN entry for the page before the allocation
1157  // and then check if this page was actually the end of an allocation.
1158  // If it wasn't, then we know for sure it's a free page
1159  //
1160  if ((Pfn1) && (Pfn1->u3.e1.EndOfAllocation == 0))
1161  {
1162  //
1163  // Get the free entry descriptor for that given page range
1164  //
1165  FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)StartingVa - PAGE_SIZE);
1166  ASSERT(FreeEntry->Signature == MM_FREE_POOL_SIGNATURE);
1167  FreeEntry = FreeEntry->Owner;
1168 
1169  /* Check if protected pool is enabled */
1171  {
1172  /* The freed block will be merged, it must be made accessible */
1173  MiUnProtectFreeNonPagedPool(FreeEntry, 0);
1174  }
1175 
1176  //
1177  // Check if the entry is small enough (1-3 pages) to be indexed on a free list
1178  // If it is, we'll want to re-insert it, since we're about to
1179  // collapse our pages on top of it, which will change its count
1180  //
1181  if (FreeEntry->Size < MI_MAX_FREE_PAGE_LISTS)
1182  {
1183  /* Remove the item from the list, depending if pool is protected */
1185  MiProtectedPoolRemoveEntryList(&FreeEntry->List);
1186  else
1187  RemoveEntryList(&FreeEntry->List);
1188 
1189  //
1190  // Update its size
1191  //
1192  FreeEntry->Size += FreePages;
1193 
1194  //
1195  // And now find the new appropriate list to place it in
1196  //
1197  i = min(FreeEntry->Size, MI_MAX_FREE_PAGE_LISTS) - 1;
1198 
1199  /* Insert the entry into the free list head, check for prot. pool */
1202  else
1204  }
1205  else
1206  {
1207  //
1208  // Otherwise, just combine our free pages into this entry
1209  //
1210  FreeEntry->Size += FreePages;
1211  }
1212  }
1213 
1214  //
1215  // Check if we were unable to do any compaction, and we'll stick with this
1216  //
1217  if (FreeEntry == StartingVa)
1218  {
1219  //
1220  // Well, now we are a free entry. At worse we just have our newly freed
1221  // pages, at best we have our pages plus whatever entry came after us
1222  //
1223  FreeEntry->Size = FreePages;
1224 
1225  //
1226  // Find the appropriate list we should be on
1227  //
1228  i = min(FreeEntry->Size, MI_MAX_FREE_PAGE_LISTS) - 1;
1229 
1230  /* Insert the entry into the free list head, check for prot. pool */
1233  else
1235  }
1236 
1237  //
1238  // Just a sanity check
1239  //
1240  ASSERT(FreePages != 0);
1241 
1242  //
1243  // Get all the pages between our allocation and its end. These will all now
1244  // become free page chunks.
1245  //
1246  NextEntry = StartingVa;
1247  LastEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)NextEntry + (FreePages << PAGE_SHIFT));
1248  do
1249  {
1250  //
1251  // Link back to the parent free entry, and keep going
1252  //
1253  NextEntry->Owner = FreeEntry;
1254  NextEntry->Signature = MM_FREE_POOL_SIGNATURE;
1255  NextEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)NextEntry + PAGE_SIZE);
1256  } while (NextEntry != LastEntry);
1257 
1258  /* Is freed non paged pool protected? */
1260  {
1261  /* Protect the freed pool! */
1262  MiProtectFreeNonPagedPool(FreeEntry, FreeEntry->Size);
1263  }
1264 
1265  //
1266  // We're done, release the lock and let the caller know how much we freed
1267  //
1269  return NumberOfPages;
1270 }
PRTL_BITMAP PagedPoolAllocationMap
Definition: mm.h:475
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
BOOLEAN NTAPI MiUnProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:68
PFN_NUMBER MiEndOfInitialPoolFrame
Definition: pool.c:23
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define TRUE
Definition: types.h:120
ULONG Signature
Definition: mm.h:465
union _MMPFN::@1761 u3
PVOID MmPagedPoolEnd
Definition: init.c:26
#define InsertTailList(ListHead, Entry)
SLIST_HEADER MiNonPagedPoolSListHead
Definition: pool.c:30
PVOID MmNonPagedPoolEnd
Definition: mminit.c:99
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:386
#define MiAddressToPte(x)
Definition: mmx86.c:19
VOID NTAPI MiProtectedPoolRemoveEntryList(IN PLIST_ENTRY Entry)
Definition: pool.c:166
PFN_NUMBER MiStartOfInitialPoolFrame
Definition: pool.c:23
LIST_ENTRY List
Definition: mm.h:463
#define MI_MAX_FREE_PAGE_LISTS
Definition: mm.h:80
KIRQL OldIrql
Definition: mm.h:1502
KGUARDED_MUTEX MmPagedPoolMutex
Definition: pool.c:24
PFN_COUNT Size
Definition: mm.h:464
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:470
#define ASSERT(a)
Definition: mode.c:44
Definition: mm.h:461
ULONG64 Valid
Definition: mmtypes.h:150
MM_PAGED_POOL_INFO MmPagedPoolInfo
Definition: pool.c:25
VOID NTAPI RtlClearBit(_In_ PRTL_BITMAP BitMapHeader, _In_ BITMAP_INDEX BitNumber)
Definition: bitmap.c:294
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
FORCEINLINE USHORT ExQueryDepthSList(_In_ PSLIST_HEADER SListHead)
Definition: exfuncs.h:153
_Must_inspect_result_ NTSYSAPI BOOLEAN NTAPI RtlTestBit(_In_ PRTL_BITMAP BitMapHeader, _In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber)
Definition: bitmap.c:434
ULONG MiNonPagedPoolSListMaximum
Definition: pool.c:31
VOID NTAPI MiProtectedPoolInsertList(IN PLIST_ENTRY ListHead, IN PLIST_ENTRY Entry, IN BOOLEAN Critical)
Definition: pool.c:148
struct _MMFREE_POOL_ENTRY * Owner
Definition: mm.h:466
ULONG MiPagedPoolSListMaximum
Definition: pool.c:33
Definition: mm.h:362
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTKERNELAPI PSLIST_ENTRY FASTCALL InterlockedPushEntrySList(IN PSLIST_HEADER ListHead, IN PSLIST_ENTRY ListEntry)
Definition: interlocked.c:82
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1000
PVOID MmPagedPoolStart
Definition: miarm.h:579
PFN_COUNT NTAPI MiDeleteSystemPageableVm(IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
Definition: virtual.c:275
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
BOOLEAN MmProtectFreedNonPagedPool
Definition: pool.c:29
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _MMFREE_POOL_ENTRY * PMMFREE_POOL_ENTRY
PRTL_BITMAP EndOfPagedPoolBitmap
Definition: mm.h:476
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
SLIST_HEADER MiPagedPoolSListHead
Definition: pool.c:32
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:1020
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
VOID NTAPI MiProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:39
ULONG PagedPoolHint
Definition: mm.h:480
PMMPTE FirstPteForPagedPool
Definition: mm.h:477
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]
Definition: pool.c:20
union _MMPTE::@2287 u

Referenced by _IRQL_requires_(), and ExFreePoolWithTag().

◆ MiInitializeNonPagedPool()

VOID NTAPI MiInitializeNonPagedPool ( VOID  )

Definition at line 276 of file pool.c.

277 {
278  ULONG i;
279  PFN_COUNT PoolPages;
280  PMMFREE_POOL_ENTRY FreeEntry, FirstEntry;
281  PMMPTE PointerPte;
282  PAGED_CODE();
283 
284  //
285  // Initialize the pool S-LISTs as well as their maximum count. In general,
286  // we'll allow 8 times the default on a 2GB system, and two times the default
287  // on a 1GB system.
288  //
291  if (MmNumberOfPhysicalPages >= ((2 * _1GB) /PAGE_SIZE))
292  {
295  }
296  else if (MmNumberOfPhysicalPages >= (_1GB /PAGE_SIZE))
297  {
300  }
301 
302  //
303  // However if debugging options for the pool are enabled, turn off the S-LIST
304  // to reduce the risk of messing things up even more
305  //
307  {
310  }
311 
312  //
313  // We keep 4 lists of free pages (4 lists help avoid contention)
314  //
315  for (i = 0; i < MI_MAX_FREE_PAGE_LISTS; i++)
316  {
317  //
318  // Initialize each of them
319  //
321  }
322 
323  //
324  // Calculate how many pages the initial nonpaged pool has
325  //
327  MmNumberOfFreeNonPagedPool = PoolPages;
328 
329  //
330  // Initialize the first free entry
331  //
332  FreeEntry = MmNonPagedPoolStart;
333  FirstEntry = FreeEntry;
334  FreeEntry->Size = PoolPages;
335  FreeEntry->Signature = MM_FREE_POOL_SIGNATURE;
336  FreeEntry->Owner = FirstEntry;
337 
338  //
339  // Insert it into the last list
340  //
342  &FreeEntry->List);
343 
344  //
345  // Now create free entries for every single other page
346  //
347  while (PoolPages-- > 1)
348  {
349  //
350  // Link them all back to the original entry
351  //
352  FreeEntry = (PMMFREE_POOL_ENTRY)((ULONG_PTR)FreeEntry + PAGE_SIZE);
353  FreeEntry->Owner = FirstEntry;
354  FreeEntry->Signature = MM_FREE_POOL_SIGNATURE;
355  }
356 
357  //
358  // Validate and remember first allocated pool page
359  //
360  PointerPte = MiAddressToPte(MmNonPagedPoolStart);
361  ASSERT(PointerPte->u.Hard.Valid == 1);
363 
364  //
365  // Keep track of where initial nonpaged pool ends
366  //
369 
370  //
371  // Validate and remember last allocated pool page
372  //
373  PointerPte = MiAddressToPte((PVOID)((ULONG_PTR)MmNonPagedPoolEnd0 - 1));
374  ASSERT(PointerPte->u.Hard.Valid == 1);
376 
377  //
378  // Validate the first nonpaged pool expansion page (which is a guard page)
379  //
381  ASSERT(PointerPte->u.Hard.Valid == 0);
382 
383  //
384  // Calculate the size of the expansion region alone
385  //
388 
389  //
390  // Remove 2 pages, since there's a guard page on top and on the bottom
391  //
393 
394  //
395  // Now initialize the nonpaged pool expansion PTE space. Remember there's a
396  // guard page on top so make sure to skip it. The bottom guard page will be
397  // guaranteed by the fact our size is off by one.
398  //
399  MiInitializeSystemPtes(PointerPte + 1,
402 }
PFN_NUMBER MiEndOfInitialPoolFrame
Definition: pool.c:23
ULONG PFN_COUNT
Definition: mmtypes.h:102
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
ULONG Signature
Definition: mm.h:465
PVOID MmNonPagedPoolExpansionStart
Definition: init.c:25
SLIST_HEADER MiNonPagedPoolSListHead
Definition: pool.c:30
uint32_t ULONG_PTR
Definition: typedefs.h:65
PFN_COUNT MmNumberOfFreeNonPagedPool
Definition: pool.c:21
#define MiAddressToPte(x)
Definition: mmx86.c:19
VOID NTAPI MiInitializeSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE PoolType)
Definition: syspte.c:388
PFN_NUMBER MiStartOfInitialPoolFrame
Definition: pool.c:23
LIST_ENTRY List
Definition: mm.h:463
#define MI_MAX_FREE_PAGE_LISTS
Definition: mm.h:80
PVOID MmNonPagedPoolEnd0
Definition: pool.c:22
PFN_COUNT MiExpansionPoolPagesInitialCharge
Definition: pool.c:21
void * PVOID
Definition: retypes.h:9
FORCEINLINE VOID InitializeSListHead(_Out_ PSLIST_HEADER SListHead)
Definition: rtlfuncs.h:3351
PFN_COUNT Size
Definition: mm.h:464
#define MM_FREE_POOL_SIGNATURE
Definition: mm.h:470
#define ASSERT(a)
Definition: mode.c:44
Definition: mm.h:461
ULONG64 Valid
Definition: mmtypes.h:150
ULONG MiNonPagedPoolSListMaximum
Definition: pool.c:31
struct _MMFREE_POOL_ENTRY * Owner
Definition: mm.h:466
#define BYTES_TO_PAGES(Size)
ULONG MiPagedPoolSListMaximum
Definition: pool.c:33
#define PAGE_SIZE
Definition: env_spec_w32.h:49
PVOID MmNonPagedPoolStart
Definition: init.c:24
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
BOOLEAN MmProtectFreedNonPagedPool
Definition: pool.c:29
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct _MMFREE_POOL_ENTRY * PMMFREE_POOL_ENTRY
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
ULONG MmMaximumNonPagedPoolInBytes
Definition: init.c:22
SLIST_HEADER MiPagedPoolSListHead
Definition: pool.c:32
unsigned int ULONG
Definition: retypes.h:1
ULONG MmSizeOfNonPagedPoolInBytes
Definition: init.c:21
LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]
Definition: pool.c:20
union _MMPTE::@2287 u
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define _1GB
Definition: miarm.h:20
#define PAGED_CODE()

Referenced by MiBuildNonPagedPool(), and MiInitMachineDependent().

◆ MiInitializeNonPagedPoolThresholds()

VOID NTAPI MiInitializeNonPagedPoolThresholds ( VOID  )

Definition at line 184 of file pool.c.

185 {
187 
188  /* Default low threshold of 8MB or one third of nonpaged pool */
191 
192  /* Default high threshold of 20MB or 50% */
196 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
ULONG PFN_NUMBER
Definition: ke.h:9
#define ASSERT(a)
Definition: mode.c:44
PFN_NUMBER MiHighNonPagedPoolThreshold
Definition: mminit.c:305
PFN_NUMBER MmMaximumNonPagedPoolInPages
Definition: mminit.c:30
#define _1MB
Definition: miarm.h:19
#define min(a, b)
Definition: monoChain.cc:55
PFN_NUMBER MiLowNonPagedPoolThreshold
Definition: mminit.c:304

Referenced by MiBuildNonPagedPool(), and MiInitMachineDependent().

◆ MiInitializePoolEvents()

VOID NTAPI MiInitializePoolEvents ( VOID  )

Definition at line 201 of file pool.c.

202 {
203  KIRQL OldIrql;
204  PFN_NUMBER FreePoolInPages;
205 
206  /* Lock paged pool */
208 
209  /* Total size of the paged pool minus the allocated size, is free */
211 
212  /* Check the initial state high state */
213  if (FreePoolInPages >= MiHighPagedPoolThreshold)
214  {
215  /* We have plenty of pool */
217  }
218  else
219  {
220  /* We don't */
222  }
223 
224  /* Check the initial low state */
225  if (FreePoolInPages <= MiLowPagedPoolThreshold)
226  {
227  /* We're very low in free pool memory */
229  }
230  else
231  {
232  /* We're not */
234  }
235 
236  /* Release the paged pool lock */
238 
239  /* Now it's time for the nonpaged pool lock */
241 
242  /* Free pages are the maximum minus what's been allocated */
244 
245  /* Check if we have plenty */
246  if (FreePoolInPages >= MiHighNonPagedPoolThreshold)
247  {
248  /* We do, set the event */
250  }
251  else
252  {
253  /* We don't, clear the event */
255  }
256 
257  /* Check if we have very little */
258  if (FreePoolInPages <= MiLowNonPagedPoolThreshold)
259  {
260  /* We do, set the event */
262  }
263  else
264  {
265  /* We don't, clear it */
267  }
268 
269  /* We're done, release the nonpaged pool lock */
271 }
SIZE_T MmAllocatedNonPagedPool
Definition: pool.c:26
PKEVENT MiHighNonPagedPoolEvent
Definition: mminit.c:297
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
PKEVENT MiLowNonPagedPoolEvent
Definition: mminit.c:296
SIZE_T AllocatedPagedPool
Definition: mm.h:482
PFN_NUMBER MiHighPagedPoolThreshold
Definition: mminit.c:303
KIRQL OldIrql
Definition: mm.h:1502
KGUARDED_MUTEX MmPagedPoolMutex
Definition: pool.c:24
MM_PAGED_POOL_INFO MmPagedPoolInfo
Definition: pool.c:25
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
PFN_NUMBER MiHighNonPagedPoolThreshold
Definition: mminit.c:305
PFN_NUMBER MmMaximumNonPagedPoolInPages
Definition: mminit.c:30
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
PFN_NUMBER MiLowPagedPoolThreshold
Definition: mminit.c:302
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
PKEVENT MiLowPagedPoolEvent
Definition: mminit.c:294
PKEVENT MiHighPagedPoolEvent
Definition: mminit.c:295
PFN_NUMBER MiLowNonPagedPoolThreshold
Definition: mminit.c:304
PFN_NUMBER MmSizeOfPagedPoolInPages
Definition: mminit.c:111
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22

Referenced by MiInitializeMemoryEvents().

◆ MiInitializeSessionPool()

NTSTATUS NTAPI MiInitializeSessionPool ( VOID  )

Definition at line 1289 of file pool.c.

1290 {
1291  PMMPTE PointerPte, LastPte;
1292  PMMPDE PointerPde, LastPde;
1293  PFN_NUMBER PageFrameIndex, PdeCount;
1294  PPOOL_DESCRIPTOR PoolDescriptor;
1295  PMM_SESSION_SPACE SessionGlobal;
1296  PMM_PAGED_POOL_INFO PagedPoolInfo;
1297  NTSTATUS Status;
1298  ULONG Index, PoolSize, BitmapSize;
1299  PAGED_CODE();
1300 
1301  /* Lock session pool */
1302  SessionGlobal = MmSessionSpace->GlobalVirtualAddress;
1303  KeInitializeGuardedMutex(&SessionGlobal->PagedPoolMutex);
1304 
1305  /* Setup a valid pool descriptor */
1306  PoolDescriptor = &MmSessionSpace->PagedPool;
1307  ExInitializePoolDescriptor(PoolDescriptor,
1309  0,
1310  0,
1311  &SessionGlobal->PagedPoolMutex);
1312 
1313  /* Setup the pool addresses */
1316  DPRINT1("Session Pool Start: 0x%p End: 0x%p\n",
1318 
1319  /* Reset all the counters */
1320  PagedPoolInfo = &MmSessionSpace->PagedPoolInfo;
1321  PagedPoolInfo->PagedPoolCommit = 0;
1322  PagedPoolInfo->PagedPoolHint = 0;
1323  PagedPoolInfo->AllocatedPagedPool = 0;
1324 
1325  /* Compute PDE and PTE addresses */
1330 
1331  /* Write them down */
1332  MmSessionSpace->PagedPoolBasePde = PointerPde;
1333  PagedPoolInfo->FirstPteForPagedPool = PointerPte;
1334  PagedPoolInfo->LastPteForPagedPool = LastPte;
1335  PagedPoolInfo->NextPdeForPagedPoolExpansion = PointerPde + 1;
1336 
1337  /* Zero the PDEs */
1338  PdeCount = LastPde - PointerPde;
1339  RtlZeroMemory(PointerPde, (PdeCount + 1) * sizeof(MMPTE));
1340 
1341  /* Initialize the PFN for the PDE */
1342  Status = MiInitializeAndChargePfn(&PageFrameIndex,
1343  PointerPde,
1345  TRUE);
1347 
1348  /* Initialize the first page table */
1350  Index >>= 22;
1351 #ifndef _M_AMD64 // FIXME
1353  MmSessionSpace->PageTables[Index] = *PointerPde;
1354 #endif
1355 
1356  /* Bump up counters */
1359 
1360  /* Compute the size of the pool in pages, and of the bitmap for it */
1361  PoolSize = MmSessionPoolSize >> PAGE_SHIFT;
1362  BitmapSize = sizeof(RTL_BITMAP) + ((PoolSize + 31) / 32) * sizeof(ULONG);
1363 
1364  /* Allocate and initialize the bitmap to track allocations */
1366  BitmapSize,
1367  TAG_MM);
1368  ASSERT(PagedPoolInfo->PagedPoolAllocationMap != NULL);
1370  (PULONG)(PagedPoolInfo->PagedPoolAllocationMap + 1),
1371  PoolSize);
1372 
1373  /* Set all bits, but clear the first page table's worth */
1374  RtlSetAllBits(PagedPoolInfo->PagedPoolAllocationMap);
1375  RtlClearBits(PagedPoolInfo->PagedPoolAllocationMap, 0, PTE_PER_PAGE);
1376 
1377  /* Allocate and initialize the bitmap to track free space */
1379  BitmapSize,
1380  TAG_MM);
1381  ASSERT(PagedPoolInfo->EndOfPagedPoolBitmap != NULL);
1383  (PULONG)(PagedPoolInfo->EndOfPagedPoolBitmap + 1),
1384  PoolSize);
1385 
1386  /* Clear all the bits and return success */
1387  RtlClearAllBits(PagedPoolInfo->EndOfPagedPoolBitmap);
1388  return STATUS_SUCCESS;
1389 }
PRTL_BITMAP PagedPoolAllocationMap
Definition: mm.h:475
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
SIZE_T NonPageablePages
Definition: miarm.h:486
PVOID PagedPoolStart
Definition: miarm.h:488
struct _RTL_BITMAP RTL_BITMAP
PVOID MiSessionPoolStart
Definition: init.c:32
#define MiAddressToPde(x)
Definition: mmx86.c:20
PMMPDE PageTables
Definition: miarm.h:512
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI MiInitializeAndChargePfn(OUT PPFN_NUMBER PageFrameIndex, IN PMMPDE PointerPde, IN PFN_NUMBER ContainingPageFrame, IN BOOLEAN SessionAllocation)
Definition: pfnlist.c:1103
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
LONG NTSTATUS
Definition: precomp.h:26
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
MM_PAGED_POOL_INFO PagedPoolInfo
Definition: miarm.h:504
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID MmSessionBase
Definition: init.c:33
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
#define TAG_MM
Definition: tag.h:136
PMMPTE LastPteForPagedPool
Definition: mm.h:478
#define InterlockedIncrementSizeT(a)
Definition: interlocked.h:220
VOID NTAPI ExInitializePoolDescriptor(IN PPOOL_DESCRIPTOR PoolDescriptor, IN POOL_TYPE PoolType, IN ULONG PoolIndex, IN ULONG Threshold, IN PVOID PoolLock)
Definition: expool.c:966
NTSYSAPI void WINAPI RtlSetAllBits(PRTL_BITMAP)
POOL_DESCRIPTOR PagedPool
Definition: miarm.h:508
SIZE_T AllocatedPagedPool
Definition: mm.h:482
void * PVOID
Definition: retypes.h:9
SIZE_T PagedPoolCommit
Definition: mm.h:481
Status
Definition: gdiplustypes.h:24
struct _MM_SESSION_SPACE * GlobalVirtualAddress
Definition: miarm.h:475
#define ASSERT(a)
Definition: mode.c:44
SIZE_T CommittedPages
Definition: miarm.h:487
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ WDFCOLLECTION _In_ ULONG Index
#define PTE_PER_PAGE
Definition: mm.h:20
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PVOID PagedPoolEnd
Definition: miarm.h:489
KGUARDED_MUTEX PagedPoolMutex
Definition: miarm.h:503
ULONG_PTR Long
Definition: mmtypes.h:215
ULONG MmSessionPoolSize
Definition: init.c:36
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
PRTL_BITMAP EndOfPagedPoolBitmap
Definition: mm.h:476
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
#define DPRINT1
Definition: precomp.h:8
PVOID MiSessionPoolEnd
Definition: init.c:31
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
ULONG PagedPoolHint
Definition: mm.h:480
#define STATUS_SUCCESS
Definition: shellext.h:65
PMMPTE FirstPteForPagedPool
Definition: mm.h:477
PMMPDE PagedPoolBasePde
Definition: miarm.h:490
union _MMPTE::@2287 u
PMMPDE NextPdeForPagedPoolExpansion
Definition: mm.h:479
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:485
#define PAGED_CODE()

◆ MiProtectedPoolInsertList()

VOID NTAPI MiProtectedPoolInsertList ( IN PLIST_ENTRY  ListHead,
IN PLIST_ENTRY  Entry,
IN BOOLEAN  Critical 
)

Definition at line 148 of file pool.c.

151 {
152  PVOID PoolFlink, PoolBlink;
153 
154  /* Make the list accessible */
155  MiProtectedPoolUnProtectLinks(ListHead, &PoolFlink, &PoolBlink);
156 
157  /* Now insert in the right position */
158  Critical ? InsertHeadList(ListHead, Entry) : InsertTailList(ListHead, Entry);
159 
160  /* And reprotect the pages containing the free links */
161  MiProtectedPoolProtectLinks(PoolFlink, PoolBlink);
162 }
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
#define InsertTailList(ListHead, Entry)
FORCEINLINE VOID MiProtectedPoolUnProtectLinks(IN PLIST_ENTRY Links, OUT PVOID *PoolFlink, OUT PVOID *PoolBlink)
Definition: pool.c:103
base of all file and directory entries
Definition: entries.h:82
FORCEINLINE VOID MiProtectedPoolProtectLinks(IN PVOID PoolFlink, IN PVOID PoolBlink)
Definition: pool.c:138

Referenced by MiAllocatePoolPages(), and MiFreePoolPages().

◆ MiProtectedPoolProtectLinks()

FORCEINLINE VOID MiProtectedPoolProtectLinks ( IN PVOID  PoolFlink,
IN PVOID  PoolBlink 
)

Definition at line 138 of file pool.c.

140 {
141  /* Reprotect the pages, if they got unprotected earlier */
142  if (PoolFlink) MiProtectFreeNonPagedPool(PoolFlink, 1);
143  if (PoolBlink) MiProtectFreeNonPagedPool(PoolBlink, 1);
144 }
VOID NTAPI MiProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:39

Referenced by MiProtectedPoolInsertList().

◆ MiProtectedPoolRemoveEntryList()

VOID NTAPI MiProtectedPoolRemoveEntryList ( IN PLIST_ENTRY  Entry)

Definition at line 166 of file pool.c.

167 {
168  PVOID PoolFlink, PoolBlink;
169 
170  /* Make the list accessible */
171  MiProtectedPoolUnProtectLinks(Entry, &PoolFlink, &PoolBlink);
172 
173  /* Now remove */
175 
176  /* And reprotect the pages containing the free links */
177  if (PoolFlink) MiProtectFreeNonPagedPool(PoolFlink, 1);
178  if (PoolBlink) MiProtectFreeNonPagedPool(PoolBlink, 1);
179 }
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
FORCEINLINE VOID MiProtectedPoolUnProtectLinks(IN PLIST_ENTRY Links, OUT PVOID *PoolFlink, OUT PVOID *PoolBlink)
Definition: pool.c:103
VOID NTAPI MiProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:39
base of all file and directory entries
Definition: entries.h:82

Referenced by MiAllocatePoolPages(), and MiFreePoolPages().

◆ MiProtectedPoolUnProtectLinks()

FORCEINLINE VOID MiProtectedPoolUnProtectLinks ( IN PLIST_ENTRY  Links,
OUT PVOID PoolFlink,
OUT PVOID PoolBlink 
)

Definition at line 103 of file pool.c.

106 {
107  BOOLEAN Safe;
108  PVOID PoolVa;
109 
110  /* Initialize variables */
111  *PoolFlink = *PoolBlink = NULL;
112 
113  /* Check if the list has entries */
114  if (IsListEmpty(Links) == FALSE)
115  {
116  /* We are going to need to forward link to do an insert */
117  PoolVa = Links->Flink;
118 
119  /* So make it safe to access */
120  Safe = MiUnProtectFreeNonPagedPool(PoolVa, 1);
121  if (Safe) *PoolFlink = PoolVa;
122  }
123 
124  /* Are we going to need a backward link too? */
125  if (Links != Links->Blink)
126  {
127  /* Get the head's backward link for the insert */
128  PoolVa = Links->Blink;
129 
130  /* Make it safe to access */
131  Safe = MiUnProtectFreeNonPagedPool(PoolVa, 1);
132  if (Safe) *PoolBlink = PoolVa;
133  }
134 }
BOOLEAN NTAPI MiUnProtectFreeNonPagedPool(IN PVOID VirtualAddress, IN ULONG PageCount)
Definition: pool.c:68
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define NULL
Definition: types.h:112

Referenced by MiProtectedPoolInsertList(), and MiProtectedPoolRemoveEntryList().

◆ MiProtectFreeNonPagedPool()

VOID NTAPI MiProtectFreeNonPagedPool ( IN PVOID  VirtualAddress,
IN ULONG  PageCount 
)

Definition at line 39 of file pool.c.

41 {
42  PMMPTE PointerPte, LastPte;
43  MMPTE TempPte;
44 
45  /* If pool is physical, can't protect PTEs */
47 
48  /* Get PTE pointers and loop */
49  PointerPte = MiAddressToPte(VirtualAddress);
50  LastPte = PointerPte + PageCount;
51  do
52  {
53  /* Capture the PTE for safety */
54  TempPte = *PointerPte;
55 
56  /* Mark it as an invalid PTE, set proto bit to recognize it as pool */
57  TempPte.u.Hard.Valid = 0;
58  TempPte.u.Soft.Prototype = 1;
59  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
60  } while (++PointerPte < LastPte);
61 
62  /* Flush the TLB */
64 }
#define TRUE
Definition: types.h:120
#define MiAddressToPte(x)
Definition: mmx86.c:19
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:403
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:997
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950

Referenced by MiAllocatePoolPages(), MiFreePoolPages(), MiProtectedPoolProtectLinks(), and MiProtectedPoolRemoveEntryList().

◆ MiRaisePoolQuota()

BOOLEAN NTAPI MiRaisePoolQuota ( IN POOL_TYPE  PoolType,
IN ULONG  CurrentMaxQuota,
OUT PULONG  NewMaxQuota 
)

Definition at line 1275 of file pool.c.

1278 {
1279  //
1280  // Not implemented
1281  //
1282  UNIMPLEMENTED;
1283  *NewMaxQuota = CurrentMaxQuota + 65536;
1284  return TRUE;
1285 }
#define TRUE
Definition: types.h:120
#define UNIMPLEMENTED
Definition: debug.h:115

◆ MiUnProtectFreeNonPagedPool()

BOOLEAN NTAPI MiUnProtectFreeNonPagedPool ( IN PVOID  VirtualAddress,
IN ULONG  PageCount 
)

Definition at line 68 of file pool.c.

70 {
71  PMMPTE PointerPte;
72  MMPTE TempPte;
73  PFN_NUMBER UnprotectedPages = 0;
74 
75  /* If pool is physical, can't protect PTEs */
77 
78  /* Get, and capture the PTE */
79  PointerPte = MiAddressToPte(VirtualAddress);
80  TempPte = *PointerPte;
81 
82  /* Loop protected PTEs */
83  while ((TempPte.u.Hard.Valid == 0) && (TempPte.u.Soft.Prototype == 1))
84  {
85  /* Unprotect the PTE */
86  TempPte.u.Hard.Valid = 1;
87  TempPte.u.Soft.Prototype = 0;
88  MI_WRITE_VALID_PTE(PointerPte, TempPte);
89 
90  /* One more page */
91  if (++UnprotectedPages == PageCount) break;
92 
93  /* Capture next PTE */
94  TempPte = *(++PointerPte);
95  }
96 
97  /* Return if any pages were unprotected */
98  return UnprotectedPages ? TRUE : FALSE;
99 }
#define TRUE
Definition: types.h:120
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:964
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:950

Referenced by MiAllocatePoolPages(), MiFreePoolPages(), and MiProtectedPoolUnProtectLinks().

◆ MmAllocateMappingAddress()

PVOID NTAPI MmAllocateMappingAddress ( IN SIZE_T  NumberOfBytes,
IN ULONG  PoolTag 
)

Definition at line 1398 of file pool.c.

1400 {
1401  UNIMPLEMENTED;
1402  return NULL;
1403 }
#define NULL
Definition: types.h:112
#define UNIMPLEMENTED
Definition: debug.h:115

Referenced by START_TEST().

◆ MmDeterminePoolType()

POOL_TYPE NTAPI MmDeterminePoolType ( IN PVOID  PoolAddress)

Definition at line 406 of file pool.c.

407 {
408  //
409  // Use a simple bounds check
410  //
411  if (PoolAddress >= MmPagedPoolStart && PoolAddress <= MmPagedPoolEnd)
412  return PagedPool;
413  else if (PoolAddress >= MmNonPagedPoolStart && PoolAddress <= MmNonPagedPoolEnd)
414  return NonPagedPool;
415  KeBugCheckEx(BAD_POOL_CALLER, 0x42, (ULONG_PTR)PoolAddress, 0, 0);
416 }
PVOID MmPagedPoolEnd
Definition: init.c:26
PVOID MmNonPagedPoolEnd
Definition: mminit.c:99
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID MmPagedPoolStart
Definition: miarm.h:579
PVOID MmNonPagedPoolStart
Definition: init.c:24
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 ExFreePoolWithTag(), and ExpCheckPoolAllocation().

◆ MmFreeMappingAddress()

VOID NTAPI MmFreeMappingAddress ( IN PVOID  BaseAddress,
IN ULONG  PoolTag 
)

Definition at line 1410 of file pool.c.

1412 {
1413  UNIMPLEMENTED;
1414 }
#define UNIMPLEMENTED
Definition: debug.h:115

Referenced by START_TEST().

Variable Documentation

◆ MiEndOfInitialPoolFrame

PFN_NUMBER MiEndOfInitialPoolFrame

Definition at line 23 of file pool.c.

Referenced by MiFreePoolPages(), and MiInitializeNonPagedPool().

◆ MiExpansionPoolPagesInitialCharge

PFN_COUNT MiExpansionPoolPagesInitialCharge

Definition at line 21 of file pool.c.

Referenced by MiInitializeNonPagedPool(), and MmArmInitSystem().

◆ MiNonPagedPoolSListHead

SLIST_HEADER MiNonPagedPoolSListHead

Definition at line 30 of file pool.c.

Referenced by MiAllocatePoolPages(), MiFreePoolPages(), and MiInitializeNonPagedPool().

◆ MiNonPagedPoolSListMaximum

ULONG MiNonPagedPoolSListMaximum = 4

Definition at line 31 of file pool.c.

Referenced by MiFreePoolPages(), and MiInitializeNonPagedPool().

◆ MiPagedPoolSListHead

SLIST_HEADER MiPagedPoolSListHead

Definition at line 32 of file pool.c.

Referenced by MiAllocatePoolPages(), MiFreePoolPages(), and MiInitializeNonPagedPool().

◆ MiPagedPoolSListMaximum

ULONG MiPagedPoolSListMaximum = 8

Definition at line 33 of file pool.c.

Referenced by MiFreePoolPages(), and MiInitializeNonPagedPool().

◆ MiStartOfInitialPoolFrame

PFN_NUMBER MiStartOfInitialPoolFrame

Definition at line 23 of file pool.c.

Referenced by MiFreePoolPages(), and MiInitializeNonPagedPool().

◆ MmAllocatedNonPagedPool

SIZE_T MmAllocatedNonPagedPool

Definition at line 26 of file pool.c.

Referenced by MiInitializePoolEvents().

◆ MmConsumedPoolPercentage

ULONG MmConsumedPoolPercentage

Definition at line 28 of file pool.c.

◆ MmNonPagedPoolEnd0

PVOID MmNonPagedPoolEnd0

Definition at line 22 of file pool.c.

Referenced by MiInitializeNonPagedPool().

◆ MmNonPagedPoolFreeListHead

LIST_ENTRY MmNonPagedPoolFreeListHead[MI_MAX_FREE_PAGE_LISTS]

Definition at line 20 of file pool.c.

Referenced by MiAllocatePoolPages(), MiFreePoolPages(), and MiInitializeNonPagedPool().

◆ MmNumberOfFreeNonPagedPool

PFN_COUNT MmNumberOfFreeNonPagedPool

Definition at line 21 of file pool.c.

Referenced by MiInitializeNonPagedPool().

◆ MmPagedPoolInfo

◆ MmPagedPoolMutex

KGUARDED_MUTEX MmPagedPoolMutex

◆ MmProtectFreedNonPagedPool

BOOLEAN MmProtectFreedNonPagedPool

◆ MmSpecialPoolTag

ULONG MmSpecialPoolTag

Definition at line 27 of file pool.c.

Referenced by MiInitializeSpecialPool(), MmArmInitSystem(), and MmUseSpecialPool().