ReactOS  0.4.15-dev-2704-gd5265b0
miarm.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _POOL_DESCRIPTOR
 
struct  _POOL_HEADER
 
struct  _POOL_TRACKER_TABLE
 
struct  _POOL_TRACKER_BIG_PAGES
 
struct  _MI_LARGE_PAGE_DRIVER_ENTRY
 
struct  _PHYSICAL_MEMORY_RUN
 
struct  _PHYSICAL_MEMORY_DESCRIPTOR
 
struct  _MMCOLOR_TABLES
 
struct  _MI_LARGE_PAGE_RANGES
 
struct  _MMVIEW
 
struct  _MMSESSION
 
struct  _MM_SESSION_SPACE_FLAGS
 
struct  _MM_SESSION_SPACE
 

Macros

#define MI_LOWEST_VAD_ADDRESS   (PVOID)MM_LOWEST_USER_ADDRESS
 
#define _1KB   (1024u)
 
#define _1MB   (1024 * _1KB)
 
#define _1GB   (1024 * _1MB)
 
#define _64K   (64 * _1KB)
 
#define PT_SIZE   (PTE_PER_PAGE * sizeof(MMPTE))
 
#define PD_SIZE   (PDE_PER_PAGE * sizeof(MMPDE))
 
#define SYSTEM_PD_SIZE   (PPE_PER_PAGE * PD_SIZE)
 
#define MM_ZERO_ACCESS   0
 
#define MM_READONLY   1
 
#define MM_EXECUTE   2
 
#define MM_EXECUTE_READ   3
 
#define MM_READWRITE   4
 
#define MM_WRITECOPY   5
 
#define MM_EXECUTE_READWRITE   6
 
#define MM_EXECUTE_WRITECOPY   7
 
#define MM_PROTECT_ACCESS   7
 
#define MM_NOCACHE   0x08
 
#define MM_GUARDPAGE   0x10
 
#define MM_WRITECOMBINE   0x18
 
#define MM_PROTECT_SPECIAL   0x18
 
#define MM_DECOMMIT   (MM_ZERO_ACCESS | MM_GUARDPAGE)
 
#define MM_NOACCESS   (MM_ZERO_ACCESS | MM_WRITECOMBINE)
 
#define MM_OUTSWAPPED_KSTACK   (MM_EXECUTE_WRITECOPY | MM_WRITECOMBINE)
 
#define MM_INVALID_PROTECTION   0xFFFFFFFF
 
#define IMAGE_SCN_PROTECTION_MASK   (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE)
 
#define MI_IS_SESSION_IMAGE_ADDRESS(Address)   (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd))
 
#define MI_IS_SESSION_ADDRESS(Address)   (((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd))
 
#define MI_IS_SESSION_PTE(Pte)   ((((PMMPTE)Pte) >= MiSessionBasePte) && (((PMMPTE)Pte) < MiSessionLastPte))
 
#define MI_IS_PAGE_TABLE_ADDRESS(Address)   (((PVOID)(Address) >= (PVOID)PTE_BASE) && ((PVOID)(Address) <= (PVOID)PTE_TOP))
 
#define MI_IS_SYSTEM_PAGE_TABLE_ADDRESS(Address)   (((Address) >= (PVOID)MiAddressToPte(MmSystemRangeStart)) && ((Address) <= (PVOID)PTE_TOP))
 
#define MI_IS_PAGE_TABLE_OR_HYPER_ADDRESS(Address)   (((PVOID)(Address) >= (PVOID)PTE_BASE) && ((PVOID)(Address) <= (PVOID)MmHyperSpaceEnd))
 
#define MI_MAKE_SOFTWARE_PTE(p, x)   ((p)->u.Long = (x << MM_PTE_SOFTWARE_PROTECTION_BITS))
 
#define MI_SET_PFN_DELETED(x)   ((x)->PteAddress = (PMMPTE)((ULONG_PTR)(x)->PteAddress | 1))
 
#define MI_IS_PFN_DELETED(x)   ((ULONG_PTR)((x)->PteAddress) & 1)
 
#define MM_SYSLDR_NO_IMPORTS   (PVOID)0xFFFFFFFE
 
#define MM_SYSLDR_BOOT_LOADED   (PVOID)0xFFFFFFFF
 
#define MM_SYSLDR_SINGLE_ENTRY   0x1
 
#define MI_INITIAL_SESSION_IDS   64
 
#define MM_NOIRQL   (KIRQL)0xFFFFFFFF
 
#define MI_GET_PAGE_COLOR(x)   ((x) & MmSecondaryColorMask)
 
#define MI_GET_NEXT_COLOR()   (MI_GET_PAGE_COLOR(++MmSystemPageColor))
 
#define MI_GET_NEXT_PROCESS_COLOR(x)   (MI_GET_PAGE_COLOR(++(x)->NextPageColor))
 
#define MI_PTE_LOOKUP_NEEDED   0xFFFFF
 
#define MI_SESSION_DATA_PAGES_MAXIMUM   (MM_ALLOCATION_GRANULARITY / PAGE_SIZE)
 
#define MI_SESSION_TAG_PAGES_MAXIMUM   (MM_ALLOCATION_GRANULARITY / PAGE_SIZE)
 
#define MM_READ_WRITE_ALLOWED   11
 
#define MM_READ_ONLY_ALLOWED   10
 
#define MM_NO_ACCESS_ALLOWED   01
 
#define MM_DELETE_CHECK   85
 
#define MI_SYSTEM_VIEW_BUCKET_SIZE   _64K
 
#define POOL_BLOCK_SIZE   8
 
#define POOL_LISTS_PER_PAGE   (PAGE_SIZE / POOL_BLOCK_SIZE)
 
#define BASE_POOL_TYPE_MASK   1
 
#define POOL_MAX_ALLOC   (PAGE_SIZE - (sizeof(POOL_HEADER) + POOL_BLOCK_SIZE))
 
#define POOL_FLAG_CHECK_TIMERS   0x1
 
#define POOL_FLAG_CHECK_WORKERS   0x2
 
#define POOL_FLAG_CHECK_RESOURCES   0x4
 
#define POOL_FLAG_VERIFIER   0x8
 
#define POOL_FLAG_CHECK_DEADLOCK   0x10
 
#define POOL_FLAG_SPECIAL_POOL   0x20
 
#define POOL_FLAG_DBGPRINT_ON_FAILURE   0x40
 
#define POOL_FLAG_CRASH_ON_FAILURE   0x80
 
#define POOL_CORRUPTED_LIST   3
 
#define POOL_SIZE_OR_INDEX_MISMATCH   5
 
#define POOL_ENTRIES_NOT_ALIGNED_PREVIOUS   6
 
#define POOL_HEADER_NOT_ALIGNED   7
 
#define POOL_HEADER_IS_ZERO   8
 
#define POOL_ENTRIES_NOT_ALIGNED_NEXT   9
 
#define POOL_ENTRY_NOT_FOUND   10
 
#define POOL_ENTRY_CORRUPTED   1
 
#define POOL_ENTRY_ALREADY_FREE   6
 
#define POOL_ENTRY_NOT_ALLOCATED   7
 
#define POOL_ALLOC_IRQL_INVALID   8
 
#define POOL_FREE_IRQL_INVALID   9
 
#define POOL_BILLED_PROCESS_INVALID   13
 
#define POOL_HEADER_SIZE_INVALID   32
 
#define MI_IS_ROS_PFN(x)   ((x)->u4.AweAllocation == TRUE)
 

Typedefs

typedef struct _POOL_DESCRIPTOR POOL_DESCRIPTOR
 
typedef struct _POOL_DESCRIPTORPPOOL_DESCRIPTOR
 
typedef struct _POOL_HEADER POOL_HEADER
 
typedef struct _POOL_HEADERPPOOL_HEADER
 
typedef struct _POOL_TRACKER_TABLE POOL_TRACKER_TABLE
 
typedef struct _POOL_TRACKER_TABLEPPOOL_TRACKER_TABLE
 
typedef struct _POOL_TRACKER_BIG_PAGES POOL_TRACKER_BIG_PAGES
 
typedef struct _POOL_TRACKER_BIG_PAGESPPOOL_TRACKER_BIG_PAGES
 
typedef struct _MI_LARGE_PAGE_DRIVER_ENTRY MI_LARGE_PAGE_DRIVER_ENTRY
 
typedef struct _MI_LARGE_PAGE_DRIVER_ENTRYPMI_LARGE_PAGE_DRIVER_ENTRY
 
typedef enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE
 
typedef enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
 
typedef enum _MI_PFN_CACHE_ATTRIBUTEPMI_PFN_CACHE_ATTRIBUTE
 
typedef struct _PHYSICAL_MEMORY_RUN PHYSICAL_MEMORY_RUN
 
typedef struct _PHYSICAL_MEMORY_RUNPPHYSICAL_MEMORY_RUN
 
typedef struct _PHYSICAL_MEMORY_DESCRIPTOR PHYSICAL_MEMORY_DESCRIPTOR
 
typedef struct _PHYSICAL_MEMORY_DESCRIPTORPPHYSICAL_MEMORY_DESCRIPTOR
 
typedef struct _MMCOLOR_TABLES MMCOLOR_TABLES
 
typedef struct _MMCOLOR_TABLESPMMCOLOR_TABLES
 
typedef struct _MI_LARGE_PAGE_RANGES MI_LARGE_PAGE_RANGES
 
typedef struct _MI_LARGE_PAGE_RANGESPMI_LARGE_PAGE_RANGES
 
typedef struct _MMVIEW MMVIEW
 
typedef struct _MMVIEWPMMVIEW
 
typedef struct _MMSESSION MMSESSION
 
typedef struct _MMSESSIONPMMSESSION
 
typedef struct _MM_SESSION_SPACE_FLAGS MM_SESSION_SPACE_FLAGS
 
typedef struct _MM_SESSION_SPACE MM_SESSION_SPACE
 
typedef struct _MM_SESSION_SPACEPMM_SESSION_SPACE
 

Enumerations

enum  _MMSYSTEM_PTE_POOL_TYPE { SystemPteSpace, NonPagedPoolExpansion, MaximumPtePoolTypes }
 
enum  _MI_PFN_CACHE_ATTRIBUTE { MiNonCached, MiCached, MiWriteCombined, MiNotMapped }
 

Functions

 C_ASSERT (sizeof(POOL_HEADER)==POOL_BLOCK_SIZE)
 
 C_ASSERT (POOL_BLOCK_SIZE==sizeof(LIST_ENTRY))
 
FORCEINLINE BOOLEAN MI_IS_PROCESS_WORKING_SET (PMMSUPPORT WorkingSet)
 
FORCEINLINE BOOLEAN MiIsMemoryTypeFree (TYPE_OF_MEMORY MemoryType)
 
FORCEINLINE BOOLEAN MiIsMemoryTypeInvisible (TYPE_OF_MEMORY MemoryType)
 
FORCEINLINE BOOLEAN MiIsUserPde (PVOID Address)
 
FORCEINLINE BOOLEAN MiIsUserPte (PVOID Address)
 
FORCEINLINE ULONG_PTR MiDetermineUserGlobalPteMask (IN PVOID PointerPte)
 
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL (IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
 
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE (IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
 
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER (IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
 
FORCEINLINE VOID MI_MAKE_PROTOTYPE_PTE (IN PMMPTE NewPte, IN PMMPTE PointerPte)
 
FORCEINLINE VOID MI_MAKE_SUBSECTION_PTE (IN PMMPTE NewPte, IN PVOID Segment)
 
FORCEINLINE BOOLEAN MI_IS_MAPPED_PTE (PMMPTE PointerPte)
 
FORCEINLINE VOID MI_MAKE_TRANSITION_PTE (_Out_ PMMPTE NewPte, _In_ PFN_NUMBER Page, _In_ ULONG Protection)
 
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS (IN PVOID Address)
 
FORCEINLINE VOID MI_WRITE_VALID_PTE (IN PMMPTE PointerPte, IN MMPTE TempPte)
 
FORCEINLINE VOID MI_UPDATE_VALID_PTE (IN PMMPTE PointerPte, IN MMPTE TempPte)
 
FORCEINLINE VOID MI_WRITE_INVALID_PTE (IN PMMPTE PointerPte, IN MMPTE InvalidPte)
 
FORCEINLINE VOID MI_ERASE_PTE (IN PMMPTE PointerPte)
 
FORCEINLINE VOID MI_WRITE_VALID_PDE (IN PMMPDE PointerPde, IN MMPDE TempPde)
 
FORCEINLINE VOID MI_WRITE_INVALID_PDE (IN PMMPDE PointerPde, IN MMPDE InvalidPde)
 
FORCEINLINE BOOLEAN MM_ANY_WS_LOCK_HELD (IN PETHREAD Thread)
 
FORCEINLINE BOOLEAN MM_ANY_WS_LOCK_HELD_EXCLUSIVE (_In_ PETHREAD Thread)
 
FORCEINLINE BOOLEAN MI_WS_OWNER (IN PEPROCESS Process)
 
FORCEINLINE BOOLEAN MiIsRosSectionObject (IN PSECTION Section)
 
VOID NTAPI MiDecrementReferenceCount (IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
 
FORCEINLINE BOOLEAN MI_IS_WS_UNSAFE (IN PEPROCESS Process)
 
FORCEINLINE VOID MiLockProcessWorkingSet (IN PEPROCESS Process, IN PETHREAD Thread)
 
FORCEINLINE VOID MiLockProcessWorkingSetShared (IN PEPROCESS Process, IN PETHREAD Thread)
 
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe (IN PEPROCESS Process, IN PETHREAD Thread)
 
FORCEINLINE VOID MiUnlockProcessWorkingSet (IN PEPROCESS Process, IN PETHREAD Thread)
 
FORCEINLINE VOID MiUnlockProcessWorkingSetShared (IN PEPROCESS Process, IN PETHREAD Thread)
 
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe (IN PEPROCESS Process, IN PETHREAD Thread)
 
FORCEINLINE VOID MiLockWorkingSet (IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
 
FORCEINLINE VOID MiLockWorkingSetShared (_In_ PETHREAD Thread, _In_ PMMSUPPORT WorkingSet)
 
FORCEINLINE VOID MiUnlockWorkingSet (IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
 
FORCEINLINE VOID MiUnlockWorkingSetShared (_In_ PETHREAD Thread, _In_ PMMSUPPORT WorkingSet)
 
FORCEINLINE BOOLEAN MiConvertSharedWorkingSetLockToExclusive (_In_ PETHREAD Thread, _In_ PMMSUPPORT Vm)
 
FORCEINLINE VOID MiUnlockProcessWorkingSetForFault (IN PEPROCESS Process, IN PETHREAD Thread, OUT PBOOLEAN Safe, OUT PBOOLEAN Shared)
 
FORCEINLINE VOID MiLockProcessWorkingSetForFault (IN PEPROCESS Process, IN PETHREAD Thread, IN BOOLEAN Safe, IN BOOLEAN Shared)
 
FORCEINLINE KIRQL MiAcquireExpansionLock (VOID)
 
FORCEINLINE VOID MiReleaseExpansionLock (KIRQL OldIrql)
 
FORCEINLINE PMMPTE MI_GET_PROTOTYPE_PTE_FOR_VPN (IN PMMVAD Vad, IN ULONG_PTR Vpn)
 
FORCEINLINE PMMPFN MI_PFN_ELEMENT (IN PFN_NUMBER Pfn)
 
FORCEINLINE VOID MiDropLockCount (IN PMMPFN Pfn1)
 
FORCEINLINE VOID MiDereferencePfnAndDropLockCount (IN PMMPFN Pfn1)
 
FORCEINLINE VOID MiReferenceProbedPageAndBumpLockCount (IN PMMPFN Pfn1)
 
FORCEINLINE VOID MiReferenceUsedPageAndBumpLockCount (IN PMMPFN Pfn1)
 
FORCEINLINE VOID MiReferenceUnusedPageAndBumpLockCount (IN PMMPFN Pfn1)
 
BOOLEAN NTAPI MmArmInitSystem (IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
VOID NTAPI MiInitializeSessionSpaceLayout (VOID)
 
NTSTATUS NTAPI MiInitMachineDependent (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
VOID NTAPI MiComputeColorInformation (VOID)
 
VOID NTAPI MiMapPfnDatabase (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
VOID NTAPI MiInitializeColorTables (VOID)
 
VOID NTAPI MiInitializePfnDatabase (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
 
VOID NTAPI MiInitializeSessionWsSupport (VOID)
 
VOID NTAPI MiInitializeSessionIds (VOID)
 
BOOLEAN NTAPI MiInitializeMemoryEvents (VOID)
 
PFN_NUMBER NTAPI MxGetNextPage (IN PFN_NUMBER PageCount)
 
PPHYSICAL_MEMORY_DESCRIPTOR NTAPI MmInitializeMemoryLimits (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PBOOLEAN IncludeType)
 
PFN_NUMBER NTAPI MiPagesInLoaderBlock (IN PLOADER_PARAMETER_BLOCK LoaderBlock, IN PBOOLEAN IncludeType)
 
VOID FASTCALL MiSyncARM3WithROS (IN PVOID AddressStart, IN PVOID AddressEnd)
 
NTSTATUS NTAPI MiRosProtectVirtualMemory (IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN OUT PSIZE_T NumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG OldAccessProtection OPTIONAL)
 
NTSTATUS NTAPI MmArmAccessFault (IN ULONG FaultCode, IN PVOID Address, IN KPROCESSOR_MODE Mode, IN PVOID TrapInformation)
 
NTSTATUS FASTCALL MiCheckPdeForPagedPool (IN PVOID Address)
 
VOID NTAPI MiInitializeNonPagedPoolThresholds (VOID)
 
VOID NTAPI MiInitializePoolEvents (VOID)
 
VOID NTAPI InitializePool (IN POOL_TYPE PoolType, IN ULONG Threshold)
 
VOID NTAPI ExInitializePoolDescriptor (IN PPOOL_DESCRIPTOR PoolDescriptor, IN POOL_TYPE PoolType, IN ULONG PoolIndex, IN ULONG Threshold, IN PVOID PoolLock)
 
NTSTATUS NTAPI MiInitializeSessionPool (VOID)
 
VOID NTAPI MiInitializeSystemPtes (IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE PoolType)
 
PMMPTE NTAPI MiReserveSystemPtes (IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
 
VOID NTAPI MiReleaseSystemPtes (IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
 
PFN_NUMBER NTAPI MiFindContiguousPages (IN PFN_NUMBER LowestPfn, IN PFN_NUMBER HighestPfn, IN PFN_NUMBER BoundaryPfn, IN PFN_NUMBER SizeInPages, IN MEMORY_CACHING_TYPE CacheType)
 
PVOID NTAPI MiCheckForContiguousMemory (IN PVOID BaseAddress, IN PFN_NUMBER BaseAddressPages, IN PFN_NUMBER SizeInPages, IN PFN_NUMBER LowestPfn, IN PFN_NUMBER HighestPfn, IN PFN_NUMBER BoundaryPfn, IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute)
 
PMDL NTAPI MiAllocatePagesForMdl (IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS SkipBytes, IN SIZE_T TotalBytes, IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute, IN ULONG Flags)
 
VOID NTAPI MiInsertPageInList (IN PMMPFNLIST ListHead, IN PFN_NUMBER PageFrameIndex)
 
VOID NTAPI MiUnlinkFreeOrZeroedPage (IN PMMPFN Entry)
 
VOID NTAPI MiUnlinkPageFromList (IN PMMPFN Pfn)
 
VOID NTAPI MiInitializePfn (IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
 
NTSTATUS NTAPI MiInitializeAndChargePfn (OUT PPFN_NUMBER PageFrameIndex, IN PMMPDE PointerPde, IN PFN_NUMBER ContainingPageFrame, IN BOOLEAN SessionAllocation)
 
VOID NTAPI MiInitializePfnAndMakePteValid (IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
 
VOID NTAPI MiInitializePfnForOtherProcess (IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
 
VOID NTAPI MiDecrementShareCount (IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
 
PFN_NUMBER NTAPI MiRemoveAnyPage (IN ULONG Color)
 
PFN_NUMBER NTAPI MiRemoveZeroPage (IN ULONG Color)
 
VOID NTAPI MiZeroPhysicalPage (IN PFN_NUMBER PageFrameIndex)
 
VOID NTAPI MiInsertPageInFreeList (IN PFN_NUMBER PageFrameIndex)
 
PFN_COUNT NTAPI MiDeleteSystemPageableVm (IN PMMPTE PointerPte, IN PFN_NUMBER PageCount, IN ULONG Flags, OUT PPFN_NUMBER ValidPages)
 
ULONG NTAPI MiGetPageProtection (IN PMMPTE PointerPte)
 
PLDR_DATA_TABLE_ENTRY NTAPI MiLookupDataTableEntry (IN PVOID Address)
 
VOID NTAPI MiInitializeDriverLargePageList (VOID)
 
VOID NTAPI MiInitializeLargePageSupport (VOID)
 
VOID NTAPI MiSyncCachedRanges (VOID)
 
BOOLEAN NTAPI MiIsPfnInUse (IN PMMPFN Pfn1)
 
PMMVAD NTAPI MiLocateAddress (IN PVOID VirtualAddress)
 
TABLE_SEARCH_RESULT NTAPI MiCheckForConflictingNode (IN ULONG_PTR StartVpn, IN ULONG_PTR EndVpn, IN PMM_AVL_TABLE Table, OUT PMMADDRESS_NODE *NodeOrParent)
 
TABLE_SEARCH_RESULT NTAPI MiFindEmptyAddressRangeDownTree (IN SIZE_T Length, IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PULONG_PTR Base, OUT PMMADDRESS_NODE *Parent)
 
NTSTATUS NTAPI MiFindEmptyAddressRangeDownBasedTree (IN SIZE_T Length, IN ULONG_PTR BoundaryAddress, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PULONG_PTR Base)
 
TABLE_SEARCH_RESULT NTAPI MiFindEmptyAddressRangeInTree (IN SIZE_T Length, IN ULONG_PTR Alignment, IN PMM_AVL_TABLE Table, OUT PMMADDRESS_NODE *PreviousVad, OUT PULONG_PTR Base)
 
NTSTATUS NTAPI MiCheckSecuredVad (IN PMMVAD Vad, IN PVOID Base, IN SIZE_T Size, IN ULONG ProtectionMask)
 
VOID NTAPI MiInsertVad (_Inout_ PMMVAD Vad, _Inout_ PMM_AVL_TABLE VadRoot)
 
NTSTATUS NTAPI MiInsertVadEx (_Inout_ PMMVAD Vad, _In_ ULONG_PTR *BaseAddress, _In_ SIZE_T ViewSize, _In_ ULONG_PTR HighestAddress, _In_ ULONG_PTR Alignment, _In_ ULONG AllocationType)
 
VOID NTAPI MiInsertBasedSection (IN PSECTION Section)
 
NTSTATUS NTAPI MiUnmapViewOfSection (IN PEPROCESS Process, IN PVOID BaseAddress, IN ULONG Flags)
 
NTSTATUS NTAPI MiRosUnmapViewOfSection (IN PEPROCESS Process, IN PVOID BaseAddress, IN BOOLEAN SkipDebuggerNotify)
 
VOID NTAPI MiInsertNode (IN PMM_AVL_TABLE Table, IN PMMADDRESS_NODE NewNode, PMMADDRESS_NODE Parent, TABLE_SEARCH_RESULT Result)
 
VOID NTAPI MiRemoveNode (IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
 
PMMADDRESS_NODE NTAPI MiGetPreviousNode (IN PMMADDRESS_NODE Node)
 
PMMADDRESS_NODE NTAPI MiGetNextNode (IN PMMADDRESS_NODE Node)
 
BOOLEAN NTAPI MiInitializeSystemSpaceMap (IN PMMSESSION InputSession OPTIONAL)
 
VOID NTAPI MiSessionRemoveProcess (VOID)
 
VOID NTAPI MiReleaseProcessReferenceToSessionDataPage (IN PMM_SESSION_SPACE SessionGlobal)
 
VOID NTAPI MiSessionAddProcess (IN PEPROCESS NewProcess)
 
NTSTATUS NTAPI MiSessionCommitPageTables (IN PVOID StartVa, IN PVOID EndVa)
 
ULONG NTAPI MiMakeProtectionMask (IN ULONG Protect)
 
VOID NTAPI MiDeleteVirtualAddresses (IN ULONG_PTR Va, IN ULONG_PTR EndingAddress, IN PMMVAD Vad)
 
VOID NTAPI MiDeletePte (IN PMMPTE PointerPte, IN PVOID VirtualAddress, IN PEPROCESS CurrentProcess, IN PMMPTE PrototypePte)
 
ULONG NTAPI MiMakeSystemAddressValid (IN PVOID PageTableVirtualAddress, IN PEPROCESS CurrentProcess)
 
ULONG NTAPI MiMakeSystemAddressValidPfn (IN PVOID VirtualAddress, IN KIRQL OldIrql)
 
VOID NTAPI MiRemoveMappedView (IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
 
PSUBSECTION NTAPI MiLocateSubsection (IN PMMVAD Vad, IN ULONG_PTR Vpn)
 
VOID NTAPI MiDeleteARM3Section (PVOID ObjectBody)
 
NTSTATUS NTAPI MiQueryMemorySectionName (IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID MemoryInformation, IN SIZE_T MemoryInformationLength, OUT PSIZE_T ReturnLength)
 
NTSTATUS NTAPI MiRosUnmapViewInSystemSpace (IN PVOID MappedBase)
 
VOID NTAPI MiMakePdeExistAndMakeValid (IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
 
VOID NTAPI MiWriteProtectSystemImage (_In_ PVOID ImageBase)
 
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe (IN ULONG Color)
 
FORCEINLINE USHORT MiIncrementPageTableReferences (IN PVOID Address)
 
FORCEINLINE USHORT MiDecrementPageTableReferences (IN PVOID Address)
 
FORCEINLINE VOID MiDeletePde (_In_ PMMPDE PointerPde, _In_ PEPROCESS CurrentProcess)
 

Variables

const ULONG_PTR MmProtectToPteMask [32]
 
const ULONG MmProtectToValue [32]
 
ULONG ExpNumberOfPagedPools
 
POOL_DESCRIPTOR NonPagedPoolDescriptor
 
PPOOL_DESCRIPTOR ExpPagedPoolDescriptor [16+1]
 
PPOOL_TRACKER_TABLE PoolTrackTable
 
PMM_SESSION_SPACE MmSessionSpace
 
MMPTE HyperTemplatePte
 
MMPDE ValidKernelPde
 
MMPTE ValidKernelPte
 
MMPDE ValidKernelPdeLocal
 
MMPTE ValidKernelPteLocal
 
MMPDE DemandZeroPde
 
MMPTE DemandZeroPte
 
MMPTE PrototypePte
 
MMPTE MmDecommittedPte
 
BOOLEAN MmLargeSystemCache
 
BOOLEAN MmZeroPageFile
 
BOOLEAN MmProtectFreedNonPagedPool
 
BOOLEAN MmTrackLockedPages
 
BOOLEAN MmTrackPtes
 
BOOLEAN MmDynamicPfn
 
BOOLEAN MmMirroring
 
BOOLEAN MmMakeLowMemory
 
BOOLEAN MmEnforceWriteProtection
 
SIZE_T MmAllocationFragment
 
ULONG MmConsumedPoolPercentage
 
ULONG MmVerifyDriverBufferType
 
ULONG MmVerifyDriverLevel
 
WCHAR MmVerifyDriverBuffer [512]
 
WCHAR MmLargePageDriverBuffer [512]
 
LIST_ENTRY MiLargePageDriverList
 
BOOLEAN MiLargePageAllDrivers
 
ULONG MmVerifyDriverBufferLength
 
ULONG MmLargePageDriverBufferLength
 
SIZE_T MmSizeOfNonPagedPoolInBytes
 
SIZE_T MmMaximumNonPagedPoolInBytes
 
PFN_NUMBER MmMaximumNonPagedPoolInPages
 
PFN_NUMBER MmSizeOfPagedPoolInPages
 
PVOID MmNonPagedSystemStart
 
PVOID MmNonPagedPoolStart
 
PVOID MmNonPagedPoolExpansionStart
 
PVOID MmNonPagedPoolEnd
 
SIZE_T MmSizeOfPagedPoolInBytes
 
PVOID MmPagedPoolStart
 
PVOID MmPagedPoolEnd
 
PVOID MmSessionBase
 
SIZE_T MmSessionSize
 
PMMPTE MmFirstReservedMappingPte
 
PMMPTE MmLastReservedMappingPte
 
PMMPTE MiFirstReservedZeroingPte
 
MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes [2][MmMaximumCacheType]
 
PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock
 
SIZE_T MmBootImageSize
 
PMMPTE MmSystemPtesStart [MaximumPtePoolTypes]
 
PMMPTE MmSystemPtesEnd [MaximumPtePoolTypes]
 
PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor
 
MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor
 
ULONG_PTR MxPfnAllocation
 
MM_PAGED_POOL_INFO MmPagedPoolInfo
 
KGUARDED_MUTEX MmPagedPoolMutex
 
KGUARDED_MUTEX MmSectionCommitMutex
 
PVOID MiSystemViewStart
 
SIZE_T MmSystemViewSize
 
PVOID MiSessionSpaceEnd
 
PMMPTE MiSessionImagePteStart
 
PMMPTE MiSessionImagePteEnd
 
PMMPTE MiSessionBasePte
 
PMMPTE MiSessionLastPte
 
PMMPDE MmSystemPagePtes
 
PVOID MmSystemCacheStart
 
PVOID MmSystemCacheEnd
 
MMSUPPORT MmSystemCacheWs
 
SIZE_T MmAllocatedNonPagedPool
 
ULONG MmSpecialPoolTag
 
PVOID MmHyperSpaceEnd
 
PMMWSL MmSystemCacheWorkingSetList
 
SIZE_T MmMinimumNonPagedPoolSize
 
ULONG MmMinAdditionNonPagedPoolPerMb
 
SIZE_T MmDefaultMaximumNonPagedPool
 
ULONG MmMaxAdditionNonPagedPoolPerMb
 
ULONG MmSecondaryColors
 
ULONG MmSecondaryColorMask
 
ULONG MmNumberOfSystemPtes
 
ULONG MmMaximumNonPagedPoolPercent
 
ULONG MmLargeStackSize
 
PMMCOLOR_TABLES MmFreePagesByColor [FreePageList+1]
 
MMPFNLIST MmStandbyPageListByPriority [8]
 
ULONG MmProductType
 
MM_SYSTEMSIZE MmSystemSize
 
PKEVENT MiLowMemoryEvent
 
PKEVENT MiHighMemoryEvent
 
PKEVENT MiLowPagedPoolEvent
 
PKEVENT MiHighPagedPoolEvent
 
PKEVENT MiLowNonPagedPoolEvent
 
PKEVENT MiHighNonPagedPoolEvent
 
PFN_NUMBER MmLowMemoryThreshold
 
PFN_NUMBER MmHighMemoryThreshold
 
PFN_NUMBER MiLowPagedPoolThreshold
 
PFN_NUMBER MiHighPagedPoolThreshold
 
PFN_NUMBER MiLowNonPagedPoolThreshold
 
PFN_NUMBER MiHighNonPagedPoolThreshold
 
PFN_NUMBER MmMinimumFreePages
 
PFN_NUMBER MmPlentyFreePages
 
SIZE_T MmMinimumStackCommitInBytes
 
PFN_COUNT MiExpansionPoolPagesInitialCharge
 
PFN_NUMBER MmResidentAvailableAtInit
 
ULONG MmTotalFreeSystemPtes [MaximumPtePoolTypes]
 
PFN_NUMBER MmTotalSystemDriverPages
 
ULONG MmCritsectTimeoutSeconds
 
PVOID MiSessionImageStart
 
PVOID MiSessionImageEnd
 
PMMPTE MiHighestUserPte
 
PMMPDE MiHighestUserPde
 
PFN_NUMBER MmSystemPageDirectory [PPE_PER_PAGE]
 
PMMPTE MmSharedUserDataPte
 
LIST_ENTRY MmProcessList
 
KEVENT MmZeroingPageEvent
 
ULONG MmSystemPageColor
 
ULONG MmProcessColorSeed
 
PMMWSL MmWorkingSetList
 
PFN_NUMBER MiNumberOfFreePages
 
SIZE_T MmSessionViewSize
 
SIZE_T MmSessionPoolSize
 
SIZE_T MmSessionImageSize
 
PVOID MiSessionPoolEnd
 
PVOID MiSessionPoolStart
 
PVOID MiSessionViewStart
 
PVOID MiSessionSpaceWs
 
ULONG MmMaximumDeadKernelStacks
 
SLIST_HEADER MmDeadStackSListHead
 
MM_AVL_TABLE MmSectionBasedRoot
 
KGUARDED_MUTEX MmSectionBasedMutex
 
PVOID MmHighSectionBase
 
SIZE_T MmSystemLockPagesCount
 
ULONG_PTR MmSubsectionBase
 
LARGE_INTEGER MmCriticalSectionTimeout
 
LIST_ENTRY MmWorkingSetExpansionHead
 
KSPIN_LOCK MmExpansionLock
 
PETHREAD MiExpansionLockOwner
 

Macro Definition Documentation

◆ _1GB

#define _1GB   (1024 * _1MB)

Definition at line 20 of file miarm.h.

◆ _1KB

#define _1KB   (1024u)

Definition at line 18 of file miarm.h.

◆ _1MB

#define _1MB   (1024 * _1KB)

Definition at line 19 of file miarm.h.

◆ _64K

#define _64K   (64 * _1KB)

Definition at line 23 of file miarm.h.

◆ BASE_POOL_TYPE_MASK

#define BASE_POOL_TYPE_MASK   1

Definition at line 282 of file miarm.h.

◆ IMAGE_SCN_PROTECTION_MASK

#define IMAGE_SCN_PROTECTION_MASK   (IMAGE_SCN_MEM_WRITE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_EXECUTE)

Definition at line 160 of file miarm.h.

◆ MI_GET_NEXT_COLOR

#define MI_GET_NEXT_COLOR ( )    (MI_GET_PAGE_COLOR(++MmSystemPageColor))

Definition at line 242 of file miarm.h.

◆ MI_GET_NEXT_PROCESS_COLOR

#define MI_GET_NEXT_PROCESS_COLOR (   x)    (MI_GET_PAGE_COLOR(++(x)->NextPageColor))

Definition at line 243 of file miarm.h.

◆ MI_GET_PAGE_COLOR

#define MI_GET_PAGE_COLOR (   x)    ((x) & MmSecondaryColorMask)

Definition at line 241 of file miarm.h.

◆ MI_INITIAL_SESSION_IDS

#define MI_INITIAL_SESSION_IDS   64

Definition at line 212 of file miarm.h.

◆ MI_IS_PAGE_TABLE_ADDRESS

#define MI_IS_PAGE_TABLE_ADDRESS (   Address)    (((PVOID)(Address) >= (PVOID)PTE_BASE) && ((PVOID)(Address) <= (PVOID)PTE_TOP))

Definition at line 177 of file miarm.h.

◆ MI_IS_PAGE_TABLE_OR_HYPER_ADDRESS

#define MI_IS_PAGE_TABLE_OR_HYPER_ADDRESS (   Address)    (((PVOID)(Address) >= (PVOID)PTE_BASE) && ((PVOID)(Address) <= (PVOID)MmHyperSpaceEnd))

Definition at line 183 of file miarm.h.

◆ MI_IS_PFN_DELETED

#define MI_IS_PFN_DELETED (   x)    ((ULONG_PTR)((x)->PteAddress) & 1)

Definition at line 195 of file miarm.h.

◆ MI_IS_ROS_PFN

#define MI_IS_ROS_PFN (   x)    ((x)->u4.AweAllocation == TRUE)

Definition at line 1113 of file miarm.h.

◆ MI_IS_SESSION_ADDRESS

#define MI_IS_SESSION_ADDRESS (   Address)    (((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd))

Definition at line 171 of file miarm.h.

◆ MI_IS_SESSION_IMAGE_ADDRESS

#define MI_IS_SESSION_IMAGE_ADDRESS (   Address)    (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd))

Definition at line 168 of file miarm.h.

◆ MI_IS_SESSION_PTE

#define MI_IS_SESSION_PTE (   Pte)    ((((PMMPTE)Pte) >= MiSessionBasePte) && (((PMMPTE)Pte) < MiSessionLastPte))

Definition at line 174 of file miarm.h.

◆ MI_IS_SYSTEM_PAGE_TABLE_ADDRESS

#define MI_IS_SYSTEM_PAGE_TABLE_ADDRESS (   Address)    (((Address) >= (PVOID)MiAddressToPte(MmSystemRangeStart)) && ((Address) <= (PVOID)PTE_TOP))

Definition at line 180 of file miarm.h.

◆ MI_LOWEST_VAD_ADDRESS

#define MI_LOWEST_VAD_ADDRESS   (PVOID)MM_LOWEST_USER_ADDRESS

Definition at line 15 of file miarm.h.

◆ MI_MAKE_SOFTWARE_PTE

#define MI_MAKE_SOFTWARE_PTE (   p,
  x 
)    ((p)->u.Long = (x << MM_PTE_SOFTWARE_PROTECTION_BITS))

Definition at line 189 of file miarm.h.

◆ MI_PTE_LOOKUP_NEEDED

#define MI_PTE_LOOKUP_NEEDED   0xFFFFF

Definition at line 251 of file miarm.h.

◆ MI_SESSION_DATA_PAGES_MAXIMUM

#define MI_SESSION_DATA_PAGES_MAXIMUM   (MM_ALLOCATION_GRANULARITY / PAGE_SIZE)

Definition at line 257 of file miarm.h.

◆ MI_SESSION_TAG_PAGES_MAXIMUM

#define MI_SESSION_TAG_PAGES_MAXIMUM   (MM_ALLOCATION_GRANULARITY / PAGE_SIZE)

Definition at line 258 of file miarm.h.

◆ MI_SET_PFN_DELETED

#define MI_SET_PFN_DELETED (   x)    ((x)->PteAddress = (PMMPTE)((ULONG_PTR)(x)->PteAddress | 1))

Definition at line 194 of file miarm.h.

◆ MI_SYSTEM_VIEW_BUCKET_SIZE

#define MI_SYSTEM_VIEW_BUCKET_SIZE   _64K

Definition at line 271 of file miarm.h.

◆ MM_DECOMMIT

#define MM_DECOMMIT   (MM_ZERO_ACCESS | MM_GUARDPAGE)

Definition at line 64 of file miarm.h.

◆ MM_DELETE_CHECK

#define MM_DELETE_CHECK   85

Definition at line 266 of file miarm.h.

◆ MM_EXECUTE

#define MM_EXECUTE   2

Definition at line 45 of file miarm.h.

◆ MM_EXECUTE_READ

#define MM_EXECUTE_READ   3

Definition at line 46 of file miarm.h.

◆ MM_EXECUTE_READWRITE

#define MM_EXECUTE_READWRITE   6

Definition at line 49 of file miarm.h.

◆ MM_EXECUTE_WRITECOPY

#define MM_EXECUTE_WRITECOPY   7

Definition at line 50 of file miarm.h.

◆ MM_GUARDPAGE

#define MM_GUARDPAGE   0x10

Definition at line 57 of file miarm.h.

◆ MM_INVALID_PROTECTION

#define MM_INVALID_PROTECTION   0xFFFFFFFF

Definition at line 67 of file miarm.h.

◆ MM_NO_ACCESS_ALLOWED

#define MM_NO_ACCESS_ALLOWED   01

Definition at line 265 of file miarm.h.

◆ MM_NOACCESS

#define MM_NOACCESS   (MM_ZERO_ACCESS | MM_WRITECOMBINE)

Definition at line 65 of file miarm.h.

◆ MM_NOCACHE

#define MM_NOCACHE   0x08

Definition at line 56 of file miarm.h.

◆ MM_NOIRQL

#define MM_NOIRQL   (KIRQL)0xFFFFFFFF

Definition at line 236 of file miarm.h.

◆ MM_OUTSWAPPED_KSTACK

#define MM_OUTSWAPPED_KSTACK   (MM_EXECUTE_WRITECOPY | MM_WRITECOMBINE)

Definition at line 66 of file miarm.h.

◆ MM_PROTECT_ACCESS

#define MM_PROTECT_ACCESS   7

Definition at line 51 of file miarm.h.

◆ MM_PROTECT_SPECIAL

#define MM_PROTECT_SPECIAL   0x18

Definition at line 59 of file miarm.h.

◆ MM_READ_ONLY_ALLOWED

#define MM_READ_ONLY_ALLOWED   10

Definition at line 264 of file miarm.h.

◆ MM_READ_WRITE_ALLOWED

#define MM_READ_WRITE_ALLOWED   11

Definition at line 263 of file miarm.h.

◆ MM_READONLY

#define MM_READONLY   1

Definition at line 44 of file miarm.h.

◆ MM_READWRITE

#define MM_READWRITE   4

Definition at line 47 of file miarm.h.

◆ MM_SYSLDR_BOOT_LOADED

#define MM_SYSLDR_BOOT_LOADED   (PVOID)0xFFFFFFFF

Definition at line 205 of file miarm.h.

◆ MM_SYSLDR_NO_IMPORTS

#define MM_SYSLDR_NO_IMPORTS   (PVOID)0xFFFFFFFE

Definition at line 204 of file miarm.h.

◆ MM_SYSLDR_SINGLE_ENTRY

#define MM_SYSLDR_SINGLE_ENTRY   0x1

Definition at line 207 of file miarm.h.

◆ MM_WRITECOMBINE

#define MM_WRITECOMBINE   0x18

Definition at line 58 of file miarm.h.

◆ MM_WRITECOPY

#define MM_WRITECOPY   5

Definition at line 48 of file miarm.h.

◆ MM_ZERO_ACCESS

#define MM_ZERO_ACCESS   0

Definition at line 43 of file miarm.h.

◆ PD_SIZE

#define PD_SIZE   (PDE_PER_PAGE * sizeof(MMPDE))

Definition at line 29 of file miarm.h.

◆ POOL_ALLOC_IRQL_INVALID

#define POOL_ALLOC_IRQL_INVALID   8

Definition at line 314 of file miarm.h.

◆ POOL_BILLED_PROCESS_INVALID

#define POOL_BILLED_PROCESS_INVALID   13

Definition at line 316 of file miarm.h.

◆ POOL_BLOCK_SIZE

#define POOL_BLOCK_SIZE   8

Definition at line 279 of file miarm.h.

◆ POOL_CORRUPTED_LIST

#define POOL_CORRUPTED_LIST   3

Definition at line 300 of file miarm.h.

◆ POOL_ENTRIES_NOT_ALIGNED_NEXT

#define POOL_ENTRIES_NOT_ALIGNED_NEXT   9

Definition at line 305 of file miarm.h.

◆ POOL_ENTRIES_NOT_ALIGNED_PREVIOUS

#define POOL_ENTRIES_NOT_ALIGNED_PREVIOUS   6

Definition at line 302 of file miarm.h.

◆ POOL_ENTRY_ALREADY_FREE

#define POOL_ENTRY_ALREADY_FREE   6

Definition at line 312 of file miarm.h.

◆ POOL_ENTRY_CORRUPTED

#define POOL_ENTRY_CORRUPTED   1

Definition at line 311 of file miarm.h.

◆ POOL_ENTRY_NOT_ALLOCATED

#define POOL_ENTRY_NOT_ALLOCATED   7

Definition at line 313 of file miarm.h.

◆ POOL_ENTRY_NOT_FOUND

#define POOL_ENTRY_NOT_FOUND   10

Definition at line 306 of file miarm.h.

◆ POOL_FLAG_CHECK_DEADLOCK

#define POOL_FLAG_CHECK_DEADLOCK   0x10

Definition at line 292 of file miarm.h.

◆ POOL_FLAG_CHECK_RESOURCES

#define POOL_FLAG_CHECK_RESOURCES   0x4

Definition at line 290 of file miarm.h.

◆ POOL_FLAG_CHECK_TIMERS

#define POOL_FLAG_CHECK_TIMERS   0x1

Definition at line 288 of file miarm.h.

◆ POOL_FLAG_CHECK_WORKERS

#define POOL_FLAG_CHECK_WORKERS   0x2

Definition at line 289 of file miarm.h.

◆ POOL_FLAG_CRASH_ON_FAILURE

#define POOL_FLAG_CRASH_ON_FAILURE   0x80

Definition at line 295 of file miarm.h.

◆ POOL_FLAG_DBGPRINT_ON_FAILURE

#define POOL_FLAG_DBGPRINT_ON_FAILURE   0x40

Definition at line 294 of file miarm.h.

◆ POOL_FLAG_SPECIAL_POOL

#define POOL_FLAG_SPECIAL_POOL   0x20

Definition at line 293 of file miarm.h.

◆ POOL_FLAG_VERIFIER

#define POOL_FLAG_VERIFIER   0x8

Definition at line 291 of file miarm.h.

◆ POOL_FREE_IRQL_INVALID

#define POOL_FREE_IRQL_INVALID   9

Definition at line 315 of file miarm.h.

◆ POOL_HEADER_IS_ZERO

#define POOL_HEADER_IS_ZERO   8

Definition at line 304 of file miarm.h.

◆ POOL_HEADER_NOT_ALIGNED

#define POOL_HEADER_NOT_ALIGNED   7

Definition at line 303 of file miarm.h.

◆ POOL_HEADER_SIZE_INVALID

#define POOL_HEADER_SIZE_INVALID   32

Definition at line 317 of file miarm.h.

◆ POOL_LISTS_PER_PAGE

#define POOL_LISTS_PER_PAGE   (PAGE_SIZE / POOL_BLOCK_SIZE)

Definition at line 281 of file miarm.h.

◆ POOL_MAX_ALLOC

#define POOL_MAX_ALLOC   (PAGE_SIZE - (sizeof(POOL_HEADER) + POOL_BLOCK_SIZE))

Definition at line 283 of file miarm.h.

◆ POOL_SIZE_OR_INDEX_MISMATCH

#define POOL_SIZE_OR_INDEX_MISMATCH   5

Definition at line 301 of file miarm.h.

◆ PT_SIZE

#define PT_SIZE   (PTE_PER_PAGE * sizeof(MMPTE))

Definition at line 26 of file miarm.h.

◆ SYSTEM_PD_SIZE

#define SYSTEM_PD_SIZE   (PPE_PER_PAGE * PD_SIZE)

Definition at line 32 of file miarm.h.

Typedef Documentation

◆ MI_LARGE_PAGE_DRIVER_ENTRY

◆ MI_LARGE_PAGE_RANGES

◆ MI_PFN_CACHE_ATTRIBUTE

◆ MM_SESSION_SPACE

◆ MM_SESSION_SPACE_FLAGS

◆ MMCOLOR_TABLES

◆ MMSESSION

◆ MMSYSTEM_PTE_POOL_TYPE

◆ MMVIEW

◆ PHYSICAL_MEMORY_DESCRIPTOR

◆ PHYSICAL_MEMORY_RUN

◆ PMI_LARGE_PAGE_DRIVER_ENTRY

◆ PMI_LARGE_PAGE_RANGES

◆ PMI_PFN_CACHE_ATTRIBUTE

◆ PMM_SESSION_SPACE

◆ PMMCOLOR_TABLES

◆ PMMSESSION

◆ PMMVIEW

typedef struct _MMVIEW * PMMVIEW

◆ POOL_DESCRIPTOR

◆ POOL_HEADER

◆ POOL_TRACKER_BIG_PAGES

◆ POOL_TRACKER_TABLE

◆ PPHYSICAL_MEMORY_DESCRIPTOR

◆ PPHYSICAL_MEMORY_RUN

◆ PPOOL_DESCRIPTOR

◆ PPOOL_HEADER

◆ PPOOL_TRACKER_BIG_PAGES

◆ PPOOL_TRACKER_TABLE

Enumeration Type Documentation

◆ _MI_PFN_CACHE_ATTRIBUTE

Enumerator
MiNonCached 
MiCached 
MiWriteCombined 
MiNotMapped 

Definition at line 418 of file miarm.h.

419 {
420  MiNonCached,
421  MiCached,
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
enum _MI_PFN_CACHE_ATTRIBUTE * PMI_PFN_CACHE_ATTRIBUTE

◆ _MMSYSTEM_PTE_POOL_TYPE

Enumerator
SystemPteSpace 
NonPagedPoolExpansion 
MaximumPtePoolTypes 

Definition at line 411 of file miarm.h.

412 {
enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE

Function Documentation

◆ C_ASSERT() [1/2]

C_ASSERT ( sizeof(POOL_HEADER = =POOL_BLOCK_SIZE)

◆ C_ASSERT() [2/2]

C_ASSERT ( POOL_BLOCK_SIZE  = =sizeof(LIST_ENTRY))

◆ ExInitializePoolDescriptor()

VOID NTAPI ExInitializePoolDescriptor ( IN PPOOL_DESCRIPTOR  PoolDescriptor,
IN POOL_TYPE  PoolType,
IN ULONG  PoolIndex,
IN ULONG  Threshold,
IN PVOID  PoolLock 
)

Definition at line 966 of file expool.c.

971 {
972  PLIST_ENTRY NextEntry, LastEntry;
973 
974  //
975  // Setup the descriptor based on the caller's request
976  //
977  PoolDescriptor->PoolType = PoolType;
978  PoolDescriptor->PoolIndex = PoolIndex;
979  PoolDescriptor->Threshold = Threshold;
980  PoolDescriptor->LockAddress = PoolLock;
981 
982  //
983  // Initialize accounting data
984  //
985  PoolDescriptor->RunningAllocs = 0;
986  PoolDescriptor->RunningDeAllocs = 0;
987  PoolDescriptor->TotalPages = 0;
988  PoolDescriptor->TotalBytes = 0;
989  PoolDescriptor->TotalBigPages = 0;
990 
991  //
992  // Nothing pending for now
993  //
994  PoolDescriptor->PendingFrees = NULL;
995  PoolDescriptor->PendingFreeDepth = 0;
996 
997  //
998  // Loop all the descriptor's allocation lists and initialize them
999  //
1000  NextEntry = PoolDescriptor->ListHeads;
1001  LastEntry = NextEntry + POOL_LISTS_PER_PAGE;
1002  while (NextEntry < LastEntry)
1003  {
1004  ExpInitializePoolListHead(NextEntry);
1005  NextEntry++;
1006  }
1007 
1008  //
1009  // Note that ReactOS does not support Session Pool Yet
1010  //
1012 }
VOID NTAPI ExpInitializePoolListHead(IN PLIST_ENTRY ListHead)
Definition: expool.c:114
#define ASSERT(a)
Definition: mode.c:44
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
#define POOL_LISTS_PER_PAGE
Definition: miarm.h:281
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3810

Referenced by InitializePool(), and MiInitializeSessionPool().

◆ InitializePool()

VOID NTAPI InitializePool ( IN POOL_TYPE  PoolType,
IN ULONG  Threshold 
)

Definition at line 1017 of file expool.c.

1019 {
1021  SIZE_T TableSize;
1022  ULONG i;
1023 
1024  //
1025  // Check what kind of pool this is
1026  //
1027  if (PoolType == NonPagedPool)
1028  {
1029  //
1030  // Compute the track table size and convert it from a power of two to an
1031  // actual byte size
1032  //
1033  // NOTE: On checked builds, we'll assert if the registry table size was
1034  // invalid, while on retail builds we'll just break out of the loop at
1035  // that point.
1036  //
1038  for (i = 0; i < 32; i++)
1039  {
1040  if (TableSize & 1)
1041  {
1042  ASSERT((TableSize & ~1) == 0);
1043  if (!(TableSize & ~1)) break;
1044  }
1045  TableSize >>= 1;
1046  }
1047 
1048  //
1049  // If we hit bit 32, than no size was defined in the registry, so
1050  // we'll use the default size of 2048 entries.
1051  //
1052  // Otherwise, use the size from the registry, as long as it's not
1053  // smaller than 64 entries.
1054  //
1055  if (i == 32)
1056  {
1057  PoolTrackTableSize = 2048;
1058  }
1059  else
1060  {
1061  PoolTrackTableSize = max(1 << i, 64);
1062  }
1063 
1064  //
1065  // Loop trying with the biggest specified size first, and cut it down
1066  // by a power of two each iteration in case not enough memory exist
1067  //
1068  while (TRUE)
1069  {
1070  //
1071  // Do not allow overflow
1072  //
1073  if ((PoolTrackTableSize + 1) > (MAXULONG_PTR / sizeof(POOL_TRACKER_TABLE)))
1074  {
1075  PoolTrackTableSize >>= 1;
1076  continue;
1077  }
1078 
1079  //
1080  // Allocate the tracker table and exit the loop if this worked
1081  //
1083  (PoolTrackTableSize + 1) *
1084  sizeof(POOL_TRACKER_TABLE));
1085  if (PoolTrackTable) break;
1086 
1087  //
1088  // Otherwise, as long as we're not down to the last bit, keep
1089  // iterating
1090  //
1091  if (PoolTrackTableSize == 1)
1092  {
1093  KeBugCheckEx(MUST_SUCCEED_POOL_EMPTY,
1094  TableSize,
1095  0xFFFFFFFF,
1096  0xFFFFFFFF,
1097  0xFFFFFFFF);
1098  }
1099  PoolTrackTableSize >>= 1;
1100  }
1101 
1102  //
1103  // Add one entry, compute the hash, and zero the table
1104  //
1107 
1110 
1111  //
1112  // Finally, add the most used tags to speed up those allocations
1113  //
1114  ExpSeedHotTags();
1115 
1116  //
1117  // We now do the exact same thing with the tracker table for big pages
1118  //
1120  for (i = 0; i < 32; i++)
1121  {
1122  if (TableSize & 1)
1123  {
1124  ASSERT((TableSize & ~1) == 0);
1125  if (!(TableSize & ~1)) break;
1126  }
1127  TableSize >>= 1;
1128  }
1129 
1130  //
1131  // For big pages, the default tracker table is 4096 entries, while the
1132  // minimum is still 64
1133  //
1134  if (i == 32)
1135  {
1136  PoolBigPageTableSize = 4096;
1137  }
1138  else
1139  {
1140  PoolBigPageTableSize = max(1 << i, 64);
1141  }
1142 
1143  //
1144  // Again, run the exact same loop we ran earlier, but this time for the
1145  // big pool tracker instead
1146  //
1147  while (TRUE)
1148  {
1150  {
1151  PoolBigPageTableSize >>= 1;
1152  continue;
1153  }
1154 
1157  sizeof(POOL_TRACKER_BIG_PAGES));
1158  if (PoolBigPageTable) break;
1159 
1160  if (PoolBigPageTableSize == 1)
1161  {
1162  KeBugCheckEx(MUST_SUCCEED_POOL_EMPTY,
1163  TableSize,
1164  0xFFFFFFFF,
1165  0xFFFFFFFF,
1166  0xFFFFFFFF);
1167  }
1168 
1169  PoolBigPageTableSize >>= 1;
1170  }
1171 
1172  //
1173  // An extra entry is not needed for for the big pool tracker, so just
1174  // compute the hash and zero it
1175  //
1179  for (i = 0; i < PoolBigPageTableSize; i++)
1180  {
1182  }
1183 
1184  //
1185  // During development, print this out so we can see what's happening
1186  //
1187  DPRINT("EXPOOL: Pool Tracker Table at: 0x%p with 0x%lx bytes\n",
1189  DPRINT("EXPOOL: Big Pool Tracker Table at: 0x%p with 0x%lx bytes\n",
1191 
1192  //
1193  // Insert the generic tracker for all of big pool
1194  //
1195  ExpInsertPoolTracker('looP',
1197  sizeof(POOL_TRACKER_BIG_PAGES)),
1198  NonPagedPool);
1199 
1200  //
1201  // No support for NUMA systems at this time
1202  //
1203  ASSERT(KeNumberNodes == 1);
1204 
1205  //
1206  // Initialize the tag spinlock
1207  //
1209 
1210  //
1211  // Initialize the nonpaged pool descriptor
1212  //
1215  NonPagedPool,
1216  0,
1217  Threshold,
1218  NULL);
1219  }
1220  else
1221  {
1222  //
1223  // No support for NUMA systems at this time
1224  //
1225  ASSERT(KeNumberNodes == 1);
1226 
1227  //
1228  // Allocate the pool descriptor
1229  //
1231  sizeof(KGUARDED_MUTEX) +
1232  sizeof(POOL_DESCRIPTOR),
1233  'looP');
1234  if (!Descriptor)
1235  {
1236  //
1237  // This is really bad...
1238  //
1239  KeBugCheckEx(MUST_SUCCEED_POOL_EMPTY,
1240  0,
1241  -1,
1242  -1,
1243  -1);
1244  }
1245 
1246  //
1247  // Setup the vector and guarded mutex for paged pool
1248  //
1254  PagedPool,
1255  0,
1256  Threshold,
1258 
1259  //
1260  // Insert the generic tracker for all of nonpaged pool
1261  //
1262  ExpInsertPoolTracker('looP',
1264  NonPagedPool);
1265  }
1266 }
PVOID NTAPI ExAllocatePoolWithTag(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: expool.c:1901
VOID NTAPI ExpSeedHotTags(VOID)
Definition: expool.c:636
#define max(a, b)
Definition: svc.c:63
SIZE_T PoolTrackTableMask
Definition: expool.c:46
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:339
struct _KGUARDED_MUTEX * PKGUARDED_MUTEX
#define TRUE
Definition: types.h:120
SIZE_T PoolTrackTableSize
Definition: expool.c:46
#define MAXULONG_PTR
Definition: basetsd.h:103
PKGUARDED_MUTEX ExpPagedPoolMutex
Definition: expool.c:45
PPOOL_DESCRIPTOR PoolVector[2]
Definition: expool.c:44
VOID NTAPI ExInitializePoolDescriptor(IN PPOOL_DESCRIPTOR PoolDescriptor, IN POOL_TYPE PoolType, IN ULONG PoolIndex, IN ULONG Threshold, IN PVOID PoolLock)
Definition: expool.c:966
SIZE_T PoolBigPageTableSize
Definition: expool.c:47
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
void * PVOID
Definition: retypes.h:9
#define ASSERT(a)
Definition: mode.c:44
PPOOL_TRACKER_TABLE PoolTrackTable
Definition: expool.c:49
PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16+1]
Definition: expool.c:43
POOL_DESCRIPTOR NonPagedPoolDescriptor
Definition: expool.c:42
PVOID NTAPI MiAllocatePoolPages(IN POOL_TYPE PoolType, IN SIZE_T SizeInBytes)
Definition: pool.c:420
UCHAR KeNumberNodes
Definition: krnlinit.c:40
ULONG_PTR SIZE_T
Definition: typedefs.h:80
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
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
#define ROUND_TO_PAGES(Size)
VOID NTAPI ExpInsertPoolTracker(IN ULONG Key, IN SIZE_T NumberOfBytes, IN POOL_TYPE PoolType)
Definition: expool.c:847
#define min(a, b)
Definition: monoChain.cc:55
#define NULL
Definition: types.h:112
PPOOL_TRACKER_BIG_PAGES PoolBigPageTable
Definition: expool.c:50
SIZE_T PoolBigPageTableHash
Definition: expool.c:47
#define POOL_BIG_TABLE_ENTRY_FREE
Definition: expool.c:23
_Must_inspect_result_ typedef _Out_ PULONG TableSize
Definition: iotypes.h:4327
_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
ULONG MmSizeOfNonPagedPoolInBytes
Definition: init.c:21
#define DPRINT
Definition: sndvol32.h:71
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
KSPIN_LOCK ExpTaggedPoolLock
Definition: expool.c:51

Referenced by MiBuildPagedPool(), and MiInitMachineDependent().

◆ MI_ERASE_PTE()

FORCEINLINE VOID MI_ERASE_PTE ( IN PMMPTE  PointerPte)

Definition at line 1016 of file miarm.h.

1017 {
1018  /* Zero out the PTE */
1019  ASSERT(PointerPte->u.Long != 0);
1020  PointerPte->u.Long = 0;
1021 }
#define ASSERT(a)
Definition: mode.c:44

Referenced by MiDeletePte(), MiDeleteSystemPageableVm(), MiDeleteVirtualAddresses(), MiUnmapLockedPagesInUserSpace(), and MmFreeSpecialPool().

◆ MI_GET_PROTOTYPE_PTE_FOR_VPN()

FORCEINLINE PMMPTE MI_GET_PROTOTYPE_PTE_FOR_VPN ( IN PMMVAD  Vad,
IN ULONG_PTR  Vpn 
)

Definition at line 1567 of file miarm.h.

1569 {
1570  PMMPTE ProtoPte;
1571 
1572  /* Find the offset within the VAD's prototype PTEs */
1573  ProtoPte = Vad->FirstPrototypePte + (Vpn - Vad->StartingVpn);
1574  ASSERT(ProtoPte <= Vad->LastContiguousPte);
1575  return ProtoPte;
1576 }
#define ASSERT(a)
Definition: mode.c:44

Referenced by MiDeleteVirtualAddresses(), MiQueryAddressState(), and NtAllocateVirtualMemory().

◆ MI_IS_MAPPED_PTE()

FORCEINLINE BOOLEAN MI_IS_MAPPED_PTE ( PMMPTE  PointerPte)
Todo:
Make this reasonable code, this is UGLY!

Definition at line 929 of file miarm.h.

930 {
932  return ((PointerPte->u.Long & 0xFFFFFC01) != 0);
933 }
union _MMPTE::@2311 u
ULONG_PTR Long
Definition: mmtypes.h:215

◆ MI_IS_PHYSICAL_ADDRESS()

FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS ( IN PVOID  Address)

Definition at line 955 of file miarm.h.

956 {
957  PMMPDE PointerPde;
958 
959  /* Large pages are never paged out, always physically resident */
960  PointerPde = MiAddressToPde(Address);
961  return ((PointerPde->u.Hard.LargePage) && (PointerPde->u.Hard.Valid));
962 }
#define MiAddressToPde(x)
Definition: mmx86.c:20
union _MMPTE::@2311 u
static WCHAR Address[46]
Definition: ping.c:68
ULONG64 Valid
Definition: mmtypes.h:150
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG64 LargePage
Definition: mmtypes.h:165

Referenced by MiDispatchFault(), MiFindInitializationCode(), MiFreeInitializationCode(), MiProtectFreeNonPagedPool(), MiReleaseProcessReferenceToSessionDataPage(), MiSetPagingOfDriver(), MiUnProtectFreeNonPagedPool(), MiWriteProtectSystemImage(), MmChangeKernelResourceSectionProtection(), MmFreeDriverInitialization(), MmFreeLoaderBlock(), MmMakeKernelResourceSectionWritable(), and MmProbeAndLockPages().

◆ MI_IS_PROCESS_WORKING_SET()

FORCEINLINE BOOLEAN MI_IS_PROCESS_WORKING_SET ( PMMSUPPORT  WorkingSet)

Definition at line 671 of file miarm.h.

672 {
673  return (WorkingSet != &MmSystemCacheWs) && !WorkingSet->Flags.SessionSpace;
674 }
ULONG SessionSpace
Definition: mmtypes.h:902
MMSUPPORT_FLAGS Flags
Definition: mmtypes.h:930
MMSUPPORT MmSystemCacheWs
Definition: init.c:55

Referenced by MiInitializeWorkingSetList(), and MmWorkingSetManager().

◆ MI_IS_WS_UNSAFE()

FORCEINLINE BOOLEAN MI_IS_WS_UNSAFE ( IN PEPROCESS  Process)

Definition at line 1124 of file miarm.h.

1125 {
1126  return (Process->Vm.Flags.AcquiredUnsafe == TRUE);
1127 }
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

Referenced by MiLockProcessWorkingSet(), MiLockProcessWorkingSetShared(), MiLockProcessWorkingSetUnsafe(), MiUnlockProcessWorkingSet(), MiUnlockProcessWorkingSetForFault(), MiUnlockProcessWorkingSetShared(), and MiUnlockProcessWorkingSetUnsafe().

◆ MI_MAKE_HARDWARE_PTE()

FORCEINLINE VOID MI_MAKE_HARDWARE_PTE ( IN PMMPTE  NewPte,
IN PMMPTE  MappingPte,
IN ULONG_PTR  ProtectionMask,
IN PFN_NUMBER  PageFrameNumber 
)

Definition at line 817 of file miarm.h.

821 {
822  /* Check that we are not setting valid a page that should not be */
823  ASSERT(ProtectionMask & MM_PROTECT_ACCESS);
824  ASSERT((ProtectionMask & MM_GUARDPAGE) == 0);
825 
826  /* Set the protection and page */
827  NewPte->u.Long = MiDetermineUserGlobalPteMask(MappingPte);
828  NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
829  NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
830 }
const ULONG_PTR MmProtectToPteMask[32]
Definition: page.c:22
FORCEINLINE ULONG_PTR MiDetermineUserGlobalPteMask(IN PVOID PointerPte)
Definition: miarm.h:746
#define ASSERT(a)
Definition: mode.c:44
#define MM_PROTECT_ACCESS
Definition: miarm.h:51
#define MM_GUARDPAGE
Definition: miarm.h:57

Referenced by MiCompleteProtoPteFault(), MiResolveDemandZeroFault(), MiResolvePageFileFault(), MiResolveProtoPteFault(), MmArmAccessFault(), and MmCreateVirtualMappingUnsafe().

◆ MI_MAKE_HARDWARE_PTE_KERNEL()

FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL ( IN PMMPTE  NewPte,
IN PMMPTE  MappingPte,
IN ULONG_PTR  ProtectionMask,
IN PFN_NUMBER  PageFrameNumber 
)

Definition at line 783 of file miarm.h.

787 {
788  /* Only valid for kernel, non-session PTEs */
789  ASSERT(MappingPte > MiHighestUserPte);
790  ASSERT(!MI_IS_SESSION_PTE(MappingPte));
791  ASSERT((MappingPte < (PMMPTE)PDE_BASE) || (MappingPte > (PMMPTE)PDE_TOP));
792 
793  /* Check that we are not setting valid a page that should not be */
794  ASSERT(ProtectionMask & MM_PROTECT_ACCESS);
795  ASSERT((ProtectionMask & MM_GUARDPAGE) == 0);
796 
797  /* Start fresh */
798  NewPte->u.Long = 0;
799 
800  /* Set the protection and page */
801  NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
802  NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
803 
804  /* Make this valid & global */
805 #ifdef _GLOBAL_PAGES_ARE_AWESOME_
807  NewPte->u.Hard.Global = 1;
808 #endif
809  NewPte->u.Hard.Valid = 1;
810 }
ULONG KeFeatureBits
Definition: krnlinit.c:22
#define PDE_BASE
Definition: winldr.c:21
const ULONG_PTR MmProtectToPteMask[32]
Definition: page.c:22
#define ASSERT(a)
Definition: mode.c:44
#define MI_IS_SESSION_PTE(Pte)
Definition: miarm.h:174
#define MM_PROTECT_ACCESS
Definition: miarm.h:51
#define PDE_TOP
Definition: mm.h:161
#define MM_GUARDPAGE
Definition: miarm.h:57
#define KF_GLOBAL_PAGE
Definition: ketypes.h:147
PMMPTE MiHighestUserPte
Definition: mminit.c:233

Referenced by MiArchCreateProcessAddressSpace(), MmChangeKernelResourceSectionProtection(), MmCreateKernelStack(), MmGrowKernelStackEx(), and MmInitSystem().

◆ MI_MAKE_HARDWARE_PTE_USER()

FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER ( IN PMMPTE  NewPte,
IN PMMPTE  MappingPte,
IN ULONG_PTR  ProtectionMask,
IN PFN_NUMBER  PageFrameNumber 
)

Definition at line 837 of file miarm.h.

841 {
842  /* Only valid for kernel, non-session PTEs */
843  ASSERT(MappingPte <= MiHighestUserPte);
844 
845  /* Start fresh */
846  NewPte->u.Long = 0;
847 
848  /* Check that we are not setting valid a page that should not be */
849  ASSERT(ProtectionMask & MM_PROTECT_ACCESS);
850  ASSERT((ProtectionMask & MM_GUARDPAGE) == 0);
851 
852  NewPte->u.Hard.Valid = TRUE;
853  NewPte->u.Hard.Owner = TRUE;
854  NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
855  NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
856 }
#define TRUE
Definition: types.h:120
const ULONG_PTR MmProtectToPteMask[32]
Definition: page.c:22
#define ASSERT(a)
Definition: mode.c:44
#define MM_PROTECT_ACCESS
Definition: miarm.h:51
#define MM_GUARDPAGE
Definition: miarm.h:57
PMMPTE MiHighestUserPte
Definition: mminit.c:233

Referenced by MiCompleteProtoPteFault(), MiFlushTbAndCapture(), MiMapLockedPagesInUserSpace(), MiResolveDemandZeroFault(), MiResolveProtoPteFault(), and MmArmAccessFault().

◆ MI_MAKE_PROTOTYPE_PTE()

FORCEINLINE VOID MI_MAKE_PROTOTYPE_PTE ( IN PMMPTE  NewPte,
IN PMMPTE  PointerPte 
)

Definition at line 864 of file miarm.h.

866 {
868 
869  /* Mark this as a prototype */
870  NewPte->u.Long = 0;
871  NewPte->u.Proto.Prototype = 1;
872 
873  /*
874  * Prototype PTEs are only valid in paged pool by design, this little trick
875  * lets us only use 30 bits for the adress of the PTE, as long as the area
876  * stays 1024MB At most.
877  */
878  Offset = (ULONG_PTR)PointerPte - (ULONG_PTR)MmPagedPoolStart;
879 
880  /*
881  * 7 bits go in the "low" (but we assume the bottom 2 are zero)
882  * and the other 21 bits go in the "high"
883  */
884  NewPte->u.Proto.ProtoAddressLow = (Offset & 0x1FC) >> 2;
885  NewPte->u.Proto.ProtoAddressHigh = (Offset & 0x3FFFFE00) >> 9;
886 }
uint32_t ULONG_PTR
Definition: typedefs.h:65
PVOID MmPagedPoolStart
Definition: miarm.h:584
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define ULONG_PTR
Definition: config.h:101

◆ MI_MAKE_SUBSECTION_PTE()

FORCEINLINE VOID MI_MAKE_SUBSECTION_PTE ( IN PMMPTE  NewPte,
IN PVOID  Segment 
)

Definition at line 893 of file miarm.h.

895 {
897 
898  /* Mark this as a prototype */
899  NewPte->u.Long = 0;
900  NewPte->u.Subsect.Prototype = 1;
901 
902  /*
903  * Segments are only valid either in nonpaged pool. We store the 20 bit
904  * difference either from the top or bottom of nonpaged pool, giving a
905  * maximum of 128MB to each delta, meaning nonpaged pool cannot exceed
906  * 256MB.
907  */
908  if ((ULONG_PTR)Segment < ((ULONG_PTR)MmSubsectionBase + (128 * _1MB)))
909  {
911  NewPte->u.Subsect.WhichPool = PagedPool;
912  }
913  else
914  {
916  NewPte->u.Subsect.WhichPool = NonPagedPool;
917  }
918 
919  /*
920  * 4 bits go in the "low" (but we assume the bottom 3 are zero)
921  * and the other 20 bits go in the "high"
922  */
923  NewPte->u.Subsect.SubsectionAddressLow = (Offset & 0x78) >> 3;
924  NewPte->u.Subsect.SubsectionAddressHigh = (Offset & 0xFFFFF80) >> 7;
925 }
ULONG_PTR MmSubsectionBase
Definition: section.c:197
PVOID MmNonPagedPoolEnd
Definition: mminit.c:99
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
#define _1MB
Definition: miarm.h:19
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define ULONG_PTR
Definition: config.h:101

◆ MI_MAKE_TRANSITION_PTE()

FORCEINLINE VOID MI_MAKE_TRANSITION_PTE ( _Out_ PMMPTE  NewPte,
_In_ PFN_NUMBER  Page,
_In_ ULONG  Protection 
)

Definition at line 939 of file miarm.h.

942 {
943  NewPte->u.Long = 0;
944  NewPte->u.Trans.Transition = 1;
945  NewPte->u.Trans.Protection = Protection;
946  NewPte->u.Trans.PageFrameNumber = Page;
947 }
PFN_NUMBER Page
Definition: section.c:4757

Referenced by MiResolvePageFileFault(), and TrimWsList().

◆ MI_PFN_ELEMENT()

◆ MI_UPDATE_VALID_PTE()

FORCEINLINE VOID MI_UPDATE_VALID_PTE ( IN PMMPTE  PointerPte,
IN MMPTE  TempPte 
)

Definition at line 987 of file miarm.h.

989 {
990  /* Write the valid PTE */
991  ASSERT(PointerPte->u.Hard.Valid == 1);
992  ASSERT(TempPte.u.Hard.Valid == 1);
993  ASSERT(PointerPte->u.Hard.PageFrameNumber == TempPte.u.Hard.PageFrameNumber);
994  *PointerPte = TempPte;
995 }
#define ASSERT(a)
Definition: mode.c:44
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
ULONG PageFrameNumber
Definition: mmtypes.h:109

Referenced by MiFlushTbAndCapture(), MiSetSystemCodeProtection(), and MmChangeKernelResourceSectionProtection().

◆ MI_WRITE_INVALID_PDE()

FORCEINLINE VOID MI_WRITE_INVALID_PDE ( IN PMMPDE  PointerPde,
IN MMPDE  InvalidPde 
)

Definition at line 1045 of file miarm.h.

1047 {
1048  /* Write the invalid PDE */
1049  ASSERT(InvalidPde.u.Hard.Valid == 0);
1050  ASSERT(InvalidPde.u.Long != 0);
1051 #ifdef _M_AMD64
1052  ASSERT(InvalidPde.u.Soft.Protection == MM_EXECUTE_READWRITE);
1053 #endif
1054  *PointerPde = InvalidPde;
1055 }
#define ASSERT(a)
Definition: mode.c:44
#define MM_EXECUTE_READWRITE
Definition: miarm.h:49

Referenced by MmArmAccessFault().

◆ MI_WRITE_INVALID_PTE()

FORCEINLINE VOID MI_WRITE_INVALID_PTE ( IN PMMPTE  PointerPte,
IN MMPTE  InvalidPte 
)

Definition at line 1002 of file miarm.h.

1004 {
1005  /* Write the invalid PTE */
1006  ASSERT(InvalidPte.u.Hard.Valid == 0);
1007  ASSERT(InvalidPte.u.Long != 0);
1008  *PointerPte = InvalidPte;
1009 }
#define ASSERT(a)
Definition: mode.c:44

Referenced by MiAccessCheck(), MiAddMappedPtes(), MiAllocatePoolPages(), MiDecommitPages(), MiDecrementShareCount(), MiMapViewOfDataSection(), MiProcessValidPteList(), MiProtectFreeNonPagedPool(), MiProtectVirtualMemory(), MiResolvePageFileFault(), MiSetProtectionOnSection(), MmArmAccessFault(), MmCommitSessionMappedView(), MmCreateKernelStack(), MmGrowKernelStackEx(), and NtAllocateVirtualMemory().

◆ MI_WRITE_VALID_PDE()

FORCEINLINE VOID MI_WRITE_VALID_PDE ( IN PMMPDE  PointerPde,
IN MMPDE  TempPde 
)

Definition at line 1028 of file miarm.h.

1030 {
1031  /* Write the valid PDE */
1032  ASSERT(PointerPde->u.Hard.Valid == 0);
1033 #ifdef _M_AMD64
1034  ASSERT(PointerPde->u.Hard.NoExecute == 0);
1035 #endif
1036  ASSERT(TempPde.u.Hard.Valid == 1);
1037  *PointerPde = TempPde;
1038 }
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
#define ASSERT(a)
Definition: mode.c:44

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

◆ MI_WRITE_VALID_PTE()

FORCEINLINE VOID MI_WRITE_VALID_PTE ( IN PMMPTE  PointerPte,
IN MMPTE  TempPte 
)

Definition at line 969 of file miarm.h.

971 {
972  /* Write the valid PTE */
973  ASSERT(PointerPte->u.Hard.Valid == 0);
974  ASSERT(TempPte.u.Hard.Valid == 1);
975 #if _M_AMD64
977  (TempPte.u.Hard.NoExecute == 0));
978 #endif
979  *PointerPte = TempPte;
980 }
#define MI_IS_PAGE_TABLE_ADDRESS(Address)
Definition: miarm.h:177
#define ASSERT(a)
Definition: mode.c:44
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201

Referenced by MiAllocatePoolPages(), MiArchCreateProcessAddressSpace(), MiBuildPagedPool(), MiCompleteProtoPteFault(), MiCopyPfn(), MiDispatchFault(), MiInitializeColorTables(), MiInitializePfnAndMakePteValid(), MiInitMachineDependent(), MiLoadImageSection(), MiMapLockedPagesInUserSpace(), MiMapPageInHyperSpace(), MiMapPagesInZeroSpace(), MiMapPDEs(), MiMapPfnDatabase(), MiMapPPEs(), MiMapPTEs(), MiReloadBootLoadedDrivers(), MiResolveDemandZeroFault(), MiResolvePageFileFault(), MiResolveProtoPteFault(), MiResolveTransitionFault(), MiSessionCreateInternal(), MiUnProtectFreeNonPagedPool(), MiZeroPfn(), MmAllocateNonCachedMemory(), MmArmAccessFault(), MmCreateKernelStack(), MmGrowKernelStackEx(), MmMapIoSpace(), and MmMapLockedPagesSpecifyCache().

◆ MI_WS_OWNER()

FORCEINLINE BOOLEAN MI_WS_OWNER ( IN PEPROCESS  Process)

Definition at line 1087 of file miarm.h.

1088 {
1089  /* Check if this process is the owner, and that the thread owns the WS */
1090  if (PsGetCurrentThread()->OwnsProcessWorkingSetExclusive == 0)
1091  {
1092  DPRINT("Thread: %p is not an owner\n", PsGetCurrentThread());
1093  }
1094  if (KeGetCurrentThread()->ApcState.Process != &Process->Pcb)
1095  {
1096  DPRINT("Current thread %p is attached to another process %p\n", PsGetCurrentThread(), Process);
1097  }
1098  return ((KeGetCurrentThread()->ApcState.Process == &Process->Pcb) &&
1099  ((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) ||
1100  (PsGetCurrentThread()->OwnsProcessWorkingSetShared)));
1101 }
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1629
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define DPRINT
Definition: sndvol32.h:71
#define KeGetCurrentThread
Definition: hal.h:50

Referenced by MiUnlockProcessWorkingSet(), MiUnlockProcessWorkingSetForFault(), MiUnlockProcessWorkingSetShared(), and MiUnlockProcessWorkingSetUnsafe().

◆ MiAcquireExpansionLock()

FORCEINLINE KIRQL MiAcquireExpansionLock ( VOID  )

Definition at line 1541 of file miarm.h.

1542 {
1543  KIRQL OldIrql;
1544 
1549  return OldIrql;
1550 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
KSPIN_LOCK MmExpansionLock
Definition: session.c:32
UCHAR KIRQL
Definition: env_spec_w32.h:591
PETHREAD MiExpansionLockOwner
Definition: session.c:33
#define ASSERT(a)
Definition: mode.c:44
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define NULL
Definition: types.h:112
#define APC_LEVEL
Definition: env_spec_w32.h:695

Referenced by MiArchCreateProcessAddressSpace(), MiDereferenceSessionFinal(), MiSessionAddProcess(), MiSessionInitializeWorkingSetList(), MiSessionLeader(), MiSessionRemoveProcess(), MmDeleteProcessAddressSpace(), MmGetSessionById(), and MmWorkingSetManager().

◆ MiAllocatePagesForMdl()

PMDL NTAPI MiAllocatePagesForMdl ( IN PHYSICAL_ADDRESS  LowAddress,
IN PHYSICAL_ADDRESS  HighAddress,
IN PHYSICAL_ADDRESS  SkipBytes,
IN SIZE_T  TotalBytes,
IN MI_PFN_CACHE_ATTRIBUTE  CacheAttribute,
IN ULONG  Flags 
)

Definition at line 182 of file freelist.c.

188 {
189  PMDL Mdl;
190  PFN_NUMBER PageCount, LowPage, HighPage, SkipPages, PagesFound = 0, Page;
191  PPFN_NUMBER MdlPage, LastMdlPage;
192  KIRQL OldIrql;
193  PMMPFN Pfn1;
194  INT LookForZeroedPages;
196  DPRINT1("ARM3-DEBUG: Being called with %I64x %I64x %I64x %lx %d %lu\n", LowAddress, HighAddress, SkipBytes, TotalBytes, CacheAttribute, MdlFlags);
197 
198  //
199  // Convert the low address into a PFN
200  //
201  LowPage = (PFN_NUMBER)(LowAddress.QuadPart >> PAGE_SHIFT);
202 
203  //
204  // Convert, and normalize, the high address into a PFN
205  //
206  HighPage = (PFN_NUMBER)(HighAddress.QuadPart >> PAGE_SHIFT);
207  if (HighPage > MmHighestPhysicalPage) HighPage = MmHighestPhysicalPage;
208 
209  //
210  // Validate skipbytes and convert them into pages
211  //
212  if (BYTE_OFFSET(SkipBytes.LowPart)) return NULL;
213  SkipPages = (PFN_NUMBER)(SkipBytes.QuadPart >> PAGE_SHIFT);
214 
215  /* This isn't supported at all */
216  if (SkipPages) DPRINT1("WARNING: Caller requesting SkipBytes, MDL might be mismatched\n");
217 
218  //
219  // Now compute the number of pages the MDL will cover
220  //
222  do
223  {
224  //
225  // Try creating an MDL for these many pages
226  //
227  Mdl = MmCreateMdl(NULL, NULL, PageCount << PAGE_SHIFT);
228  if (Mdl) break;
229 
230  //
231  // This function is not required to return the amount of pages requested
232  // In fact, it can return as little as 1 page, and callers are supposed
233  // to deal with this scenario. So re-attempt the allocation with less
234  // pages than before, and see if it worked this time.
235  //
236  PageCount -= (PageCount >> 4);
237  } while (PageCount);
238 
239  //
240  // Wow, not even a single page was around!
241  //
242  if (!Mdl) return NULL;
243 
244  //
245  // This is where the page array starts....
246  //
247  MdlPage = (PPFN_NUMBER)(Mdl + 1);
248 
249  //
250  // Lock the PFN database
251  //
253 
254  //
255  // Are we looking for any pages, without discriminating?
256  //
257  if ((LowPage == 0) && (HighPage == MmHighestPhysicalPage))
258  {
259  //
260  // Well then, let's go shopping
261  //
262  while (PagesFound < PageCount)
263  {
264  /* Grab a page */
266  MI_SET_PROCESS2("Kernel");
267 
268  /* FIXME: This check should be smarter */
269  Page = 0;
270  if (MmAvailablePages != 0)
271  Page = MiRemoveAnyPage(0);
272 
273  if (Page == 0)
274  {
275  /* This is not good... hopefully we have at least SOME pages */
276  ASSERT(PagesFound);
277  break;
278  }
279 
280  /* Grab the page entry for it */
281  Pfn1 = MiGetPfnEntry(Page);
282 
283  //
284  // Make sure it's really free
285  //
286  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
287 
288  /* Now setup the page and mark it */
289  Pfn1->u3.e2.ReferenceCount = 1;
290  Pfn1->u2.ShareCount = 1;
291  MI_SET_PFN_DELETED(Pfn1);
292  Pfn1->u4.PteFrame = 0x1FFEDCB;
293  Pfn1->u3.e1.StartOfAllocation = 1;
294  Pfn1->u3.e1.EndOfAllocation = 1;
295  Pfn1->u4.VerifierAllocation = 0;
296 
297  //
298  // Save it into the MDL
299  //
300  *MdlPage++ = MiGetPfnEntryIndex(Pfn1);
301  PagesFound++;
302  }
303  }
304  else
305  {
306  //
307  // You want specific range of pages. We'll do this in two runs
308  //
309  for (LookForZeroedPages = 1; LookForZeroedPages >= 0; LookForZeroedPages--)
310  {
311  //
312  // Scan the range you specified
313  //
314  for (Page = LowPage; Page < HighPage; Page++)
315  {
316  //
317  // Get the PFN entry for this page
318  //
319  Pfn1 = MiGetPfnEntry(Page);
320  ASSERT(Pfn1);
321 
322  //
323  // Make sure it's free and if this is our first pass, zeroed
324  //
325  if (MiIsPfnInUse(Pfn1)) continue;
326  if ((Pfn1->u3.e1.PageLocation == ZeroedPageList) != LookForZeroedPages) continue;
327 
328  /* Remove the page from the free or zero list */
329  ASSERT(Pfn1->u3.e1.ReadInProgress == 0);
331  MI_SET_PROCESS2("Kernel");
333 
334  //
335  // Sanity checks
336  //
337  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
338 
339  //
340  // Now setup the page and mark it
341  //
342  Pfn1->u3.e2.ReferenceCount = 1;
343  Pfn1->u2.ShareCount = 1;
344  MI_SET_PFN_DELETED(Pfn1);
345  Pfn1->u4.PteFrame = 0x1FFEDCB;
346  Pfn1->u3.e1.StartOfAllocation = 1;
347  Pfn1->u3.e1.EndOfAllocation = 1;
348  Pfn1->u4.VerifierAllocation = 0;
349 
350  //
351  // Save this page into the MDL
352  //
353  *MdlPage++ = Page;
354  if (++PagesFound == PageCount) break;
355  }
356 
357  //
358  // If the first pass was enough, don't keep going, otherwise, go again
359  //
360  if (PagesFound == PageCount) break;
361  }
362  }
363 
364  //
365  // Now release the PFN count
366  //
368 
369  //
370  // We might've found less pages, but not more ;-)
371  //
372  if (PagesFound != PageCount) ASSERT(PagesFound < PageCount);
373  if (!PagesFound)
374  {
375  //
376  // If we didn' tfind any pages at all, fail
377  //
378  DPRINT1("NO MDL PAGES!\n");
380  return NULL;
381  }
382 
383  //
384  // Write out how many pages we found
385  //
386  Mdl->ByteCount = (ULONG)(PagesFound << PAGE_SHIFT);
387 
388  //
389  // Terminate the MDL array if there's certain missing pages
390  //
391  if (PagesFound != PageCount) *MdlPage = LIST_HEAD;
392 
393  //
394  // Now go back and loop over all the MDL pages
395  //
396  MdlPage = (PPFN_NUMBER)(Mdl + 1);
397  LastMdlPage = MdlPage + PagesFound;
398  while (MdlPage < LastMdlPage)
399  {
400  //
401  // Check if we've reached the end
402  //
403  Page = *MdlPage++;
404  if (Page == LIST_HEAD) break;
405 
406  //
407  // Get the PFN entry for the page and check if we should zero it out
408  //
409  Pfn1 = MiGetPfnEntry(Page);
410  ASSERT(Pfn1);
413  }
414 
415  //
416  // We're done, mark the pages as locked
417  //
418  Mdl->Process = NULL;
419  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
420  return Mdl;
421 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
union _MMPFN::@1784 u2
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
union _MMPFN::@1788 u4
USHORT ReadInProgress
Definition: mm.h:333
struct _MMPFN::@1785::@1791 e2
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:930
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
int32_t INT
Definition: typedefs.h:58
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:937
USHORT PageLocation
Definition: mm.h:337
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:369
ULONG * PPFN_NUMBER
Definition: ke.h:9
ULONG PFN_NUMBER
Definition: ke.h:9
ULONG_PTR ShareCount
Definition: mm.h:362
#define MI_SET_PROCESS2(x)
Definition: mm.h:291
ULONG_PTR VerifierAllocation
Definition: mm.h:392
PFN_NUMBER Page
Definition: section.c:4757
#define MI_SET_USAGE(x)
Definition: mm.h:289
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
#define ASSERT(a)
Definition: mode.c:44
#define MDL_PAGES_LOCKED
Definition: mmtypes.h:19
#define TAG_MDL
Definition: tag.h:86
PFN_NUMBER MmAvailablePages
Definition: freelist.c:26
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: mm.h:345
ULONG LowPart
Definition: typedefs.h:106
LIST_HEAD(acpi_bus_event_list)
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:969
BOOLEAN NTAPI MiIsPfnInUse(IN PMMPFN Pfn1)
Definition: freelist.c:174
union _MMPFN::@1785 u3
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:194
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
ULONG_PTR PteFrame
Definition: mm.h:390
PMDL NTAPI MmCreateMdl(IN PMDL Mdl, IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:369
#define NULL
Definition: types.h:112
_In_ WDFDEVICE _In_ PVOID _In_opt_ PMDL Mdl
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:989
unsigned int ULONG
Definition: retypes.h:1
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
VOID NTAPI MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
Definition: pfnlist.c:137
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define BYTE_OFFSET(Va)
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_ SIZE_T TotalBytes
Definition: mmfuncs.h:226
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by MmAllocateNonCachedMemory(), MmAllocatePagesForMdl(), and MmAllocatePagesForMdlEx().

◆ MiCheckForConflictingNode()

TABLE_SEARCH_RESULT NTAPI MiCheckForConflictingNode ( IN ULONG_PTR  StartVpn,
IN ULONG_PTR  EndVpn,
IN PMM_AVL_TABLE  Table,
OUT PMMADDRESS_NODE NodeOrParent 
)

Definition at line 78 of file vadnode.c.

82 {
83  PMMADDRESS_NODE ParentNode, CurrentNode;
84 
85  /* If the tree is empty, there is no conflict */
86  if (Table->NumberGenericTableElements == 0) return TableEmptyTree;
87 
88  /* Start looping from the root node */
89  CurrentNode = RtlRightChildAvl(&Table->BalancedRoot);
90  ASSERT(CurrentNode != NULL);
91  while (CurrentNode)
92  {
93  ParentNode = CurrentNode;
94 
95  /* This address comes after */
96  if (StartVpn > CurrentNode->EndingVpn)
97  {
98  /* Keep searching on the right */
99  CurrentNode = RtlRightChildAvl(CurrentNode);
100  }
101  else if (EndVpn < CurrentNode->StartingVpn)
102  {
103  /* This address ends before the node starts, search on the left */
104  CurrentNode = RtlLeftChildAvl(CurrentNode);
105  }
106  else
107  {
108  /* This address is part of this node, return it */
109  *NodeOrParent = ParentNode;
110  return TableFoundNode;
111  }
112  }
113 
114  /* There is no more child, save the current node as parent */
115  *NodeOrParent = ParentNode;
116  if (StartVpn > ParentNode->EndingVpn)
117  {
118  return TableInsertAsRight;
119  }
120  else
121  {
122  return TableInsertAsLeft;
123  }
124 }
ASMGENDATA Table[]
Definition: genincdata.c:61
#define RtlRightChildAvl
Definition: miavl.h:45
ULONG_PTR EndingVpn
Definition: mmtypes.h:651
#define ASSERT(a)
Definition: mode.c:44
#define RtlLeftChildAvl
Definition: miavl.h:46
#define NULL
Definition: types.h:112

Referenced by MiInsertVadEx(), MiMapLockedPagesInUserSpace(), MiProtectVirtualMemory(), MmLocateMemoryAreaByAddress(), MmLocateMemoryAreaByRegion(), and NtAllocateVirtualMemory().

◆ MiCheckForContiguousMemory()

PVOID NTAPI MiCheckForContiguousMemory ( IN PVOID  BaseAddress,
IN PFN_NUMBER  BaseAddressPages,
IN PFN_NUMBER  SizeInPages,
IN PFN_NUMBER  LowestPfn,
IN PFN_NUMBER  HighestPfn,
IN PFN_NUMBER  BoundaryPfn,
IN MI_PFN_CACHE_ATTRIBUTE  CacheAttribute 
)

Definition at line 214 of file contmem.c.

221 {
222  PMMPTE StartPte, EndPte;
223  PFN_NUMBER PreviousPage = 0, Page, HighPage, BoundaryMask, Pages = 0;
224 
225  //
226  // Okay, first of all check if the PFNs match our restrictions
227  //
228  if (LowestPfn > HighestPfn) return NULL;
229  if (LowestPfn + SizeInPages <= LowestPfn) return NULL;
230  if (LowestPfn + SizeInPages - 1 > HighestPfn) return NULL;
231  if (BaseAddressPages < SizeInPages) return NULL;
232 
233  //
234  // This is the last page we need to get to and the boundary requested
235  //
236  HighPage = HighestPfn + 1 - SizeInPages;
237  BoundaryMask = ~(BoundaryPfn - 1);
238 
239  //
240  // And here's the PTEs for this allocation. Let's go scan them.
241  //
242  StartPte = MiAddressToPte(BaseAddress);
243  EndPte = StartPte + BaseAddressPages;
244  while (StartPte < EndPte)
245  {
246  //
247  // Get this PTE's page number
248  //
249  ASSERT (StartPte->u.Hard.Valid == 1);
250  Page = PFN_FROM_PTE(StartPte);
251 
252  //
253  // Is this the beginning of our adventure?
254  //
255  if (!Pages)
256  {
257  //
258  // Check if this PFN is within our range
259  //
260  if ((Page >= LowestPfn) && (Page <= HighPage))
261  {
262  //
263  // It is! Do you care about boundary (alignment)?
264  //
265  if (!(BoundaryPfn) ||
266  (!((Page ^ (Page + SizeInPages - 1)) & BoundaryMask)))
267  {
268  //
269  // You don't care, or you do care but we deliver
270  //
271  Pages++;
272  }
273  }
274 
275  //
276  // Have we found all the pages we need by now?
277  // Incidently, this means you only wanted one page
278  //
279  if (Pages == SizeInPages)
280  {
281  //
282  // Mission complete
283  //
284  return MiPteToAddress(StartPte);
285  }
286  }
287  else
288  {
289  //
290  // Have we found a page that doesn't seem to be contiguous?
291  //
292  if (Page != (PreviousPage + 1))
293  {
294  //
295  // Ah crap, we have to start over
296  //
297  Pages = 0;
298  continue;
299  }
300 
301  //
302  // Otherwise, we're still in the game. Do we have all our pages?
303  //
304  if (++Pages == SizeInPages)
305  {
306  //
307  // We do! This entire range was contiguous, so we'll return it!
308  //
309  return MiPteToAddress(StartPte - Pages + 1);
310  }
311  }
312 
313  //
314  // Try with the next PTE, remember this PFN
315  //
316  PreviousPage = Page;
317  StartPte++;
318  continue;
319  }
320 
321  //
322  // All good returns are within the loop...
323  //
324  return NULL;
325 }
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:9
union _MMPTE::@2311 u
PFN_NUMBER Page
Definition: section.c:4757
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define ASSERT(a)
Definition: mode.c:44
ULONG64 Valid
Definition: mmtypes.h:150
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define NULL
Definition: types.h:112
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
#define PFN_FROM_PTE(v)
Definition: mm.h:92

Referenced by MiAllocateContiguousMemory().

◆ MiCheckPdeForPagedPool()

NTSTATUS FASTCALL MiCheckPdeForPagedPool ( IN PVOID  Address)

Definition at line 475 of file pagfault.c.

476 {
478 }
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:242

Referenced by MiDeletePte(), MiInitializePfn(), MiInitializePfnAndMakePteValid(), and MmArmAccessFault().

◆ MiCheckSecuredVad()

NTSTATUS NTAPI MiCheckSecuredVad ( IN PMMVAD  Vad,
IN PVOID  Base,
IN SIZE_T  Size,
IN ULONG  ProtectionMask 
)

Definition at line 815 of file vadnode.c.

819 {
820  ULONG_PTR StartAddress, EndAddress;
821 
822  /* Compute start and end address */
823  StartAddress = (ULONG_PTR)Base;
824  EndAddress = StartAddress + Size - 1;
825 
826  /* Are we deleting/unmapping, or changing? */
827  if (ProtectionMask < MM_DELETE_CHECK)
828  {
829  /* Changing... are we allowed to do so? */
830  if ((Vad->u.VadFlags.NoChange == 1) &&
831  (Vad->u2.VadFlags2.SecNoChange == 1) &&
832  (Vad->u.VadFlags.Protection != ProtectionMask))
833  {
834  /* Nope, bail out */
835  DPRINT1("Trying to mess with a no-change VAD!\n");
837  }
838  }
839  else
840  {
841  /* This is allowed */
842  ProtectionMask = 0;
843  }
844 
845  /* ARM3 doesn't support this yet */
846  ASSERT(Vad->u2.VadFlags2.MultipleSecured == 0);
847 
848  /* Is this a one-secured VAD, like a TEB or PEB? */
849  if (Vad->u2.VadFlags2.OneSecured)
850  {
851  /* Is this allocation being described by the VAD? */
852  if ((StartAddress <= ((PMMVAD_LONG)Vad)->u3.Secured.EndVpn) &&
853  (EndAddress >= ((PMMVAD_LONG)Vad)->u3.Secured.StartVpn))
854  {
855  /* Guard page? */
856  if (ProtectionMask & MM_DECOMMIT)
857  {
858  DPRINT1("Not allowed to change protection on guard page!\n");
860  }
861 
862  /* ARM3 doesn't have read-only VADs yet */
863  ASSERT(Vad->u2.VadFlags2.ReadOnly == 0);
864 
865  /* Check if read-write protections are allowed */
866  if (MmReadWrite[ProtectionMask] < MM_READ_WRITE_ALLOWED)
867  {
868  DPRINT1("Invalid protection mask for RW access!\n");
870  }
871  }
872  }
873 
874  /* All good, allow the change */
875  return STATUS_SUCCESS;
876 }
ULONG ReadOnly
Definition: mmtypes.h:707
#define MM_DECOMMIT
Definition: miarm.h:64
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
#define MM_DELETE_CHECK
Definition: miarm.h:266
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MM_READ_WRITE_ALLOWED
Definition: miarm.h:263
#define ASSERT(a)
Definition: mode.c:44
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:768
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:305
union _MMVAD_LONG::@2575 u2
#define DPRINT1
Definition: precomp.h:8
CHAR MmReadWrite[32]
Definition: vadnode.c:25
#define ULONG_PTR
Definition: config.h:101
#define STATUS_SUCCESS
Definition: shellext.h:65
static BYTE u3[]
Definition: msg.c:580

Referenced by MiUnmapViewOfSection(), and NtAllocateVirtualMemory().

◆ MiComputeColorInformation()

VOID NTAPI MiComputeColorInformation ( VOID  )

Definition at line 508 of file mminit.c.

509 {
510  ULONG L2Associativity;
511 
512  /* Check if no setting was provided already */
513  if (!MmSecondaryColors)
514  {
515  /* Get L2 cache information */
516  L2Associativity = KeGetPcr()->SecondLevelCacheAssociativity;
517 
518  /* The number of colors is the number of cache bytes by set/way */
519  MmSecondaryColors = KeGetPcr()->SecondLevelCacheSize;
520  if (L2Associativity) MmSecondaryColors /= L2Associativity;
521  }
522 
523  /* Now convert cache bytes into pages */
525  if (!MmSecondaryColors)
526  {
527  /* If there was no cache data from the KPCR, use the default colors */
529  }
530  else
531  {
532  /* Otherwise, make sure there aren't too many colors */
534  {
535  /* Set the maximum */
537  }
538 
539  /* Make sure there aren't too little colors */
541  {
542  /* Set the default */
544  }
545 
546  /* Finally make sure the colors are a power of two */
548  {
549  /* Set the default */
551  }
552  }
553 
554  /* Compute the mask and store it */
556  KeGetCurrentPrcb()->SecondaryColorMask = MmSecondaryColorMask;
557 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1079
#define MI_MAX_SECONDARY_COLORS
Definition: mm.h:78
#define KeGetPcr()
Definition: ke.h:26
#define MI_SECONDARY_COLORS
Definition: mm.h:77
ULONG MmSecondaryColorMask
Definition: mminit.c:257
#define MI_MIN_SECONDARY_COLORS
Definition: mm.h:76
unsigned int ULONG
Definition: retypes.h:1
ULONG MmSecondaryColors
Definition: mminit.c:256

Referenced by MmArmInitSystem().

◆ MiConvertSharedWorkingSetLockToExclusive()

FORCEINLINE BOOLEAN MiConvertSharedWorkingSetLockToExclusive ( _In_ PETHREAD  Thread,
_In_ PMMSUPPORT  Vm 
)

Definition at line 1438 of file miarm.h.

1441 {
1442  /* Sanity check: No exclusive lock. */
1446 
1447  /* And it should have one and only one shared lock */
1449 
1450  /* Try. */
1451  if (!ExConvertPushLockSharedToExclusive(&Vm->WorkingSetMutex))
1452  return FALSE;
1453 
1454  if (Vm == &MmSystemCacheWs)
1455  {
1459  }
1460  else if (Vm->Flags.SessionSpace)
1461  {
1465  }
1466  else
1467  {
1471  }
1472 
1473  return TRUE;
1474 }
ULONG OwnsSystemWorkingSetShared
Definition: pstypes.h:1224
#define TRUE
Definition: types.h:120
ULONG OwnsSessionWorkingSetShared
Definition: pstypes.h:1226
#define FALSE
Definition: types.h:117
ULONG OwnsSessionWorkingSetExclusive
Definition: pstypes.h:1225
#define ASSERT(a)
Definition: mode.c:44
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
ULONG OwnsSystemWorkingSetExclusive
Definition: pstypes.h:1223
FORCEINLINE BOOLEAN ExConvertPushLockSharedToExclusive(IN PEX_PUSH_LOCK PushLock)
Definition: ex.h:1137
ULONG OwnsProcessWorkingSetShared
Definition: pstypes.h:1222
MMSUPPORT MmSystemCacheWs
Definition: init.c:55
ULONG OwnsProcessWorkingSetExclusive
Definition: pstypes.h:1221

Referenced by MmWorkingSetManager().

◆ MiDecrementPageTableReferences()

FORCEINLINE USHORT MiDecrementPageTableReferences ( IN PVOID  Address)

Definition at line 2509 of file miarm.h.

2510 {
2511  PMMPDE PointerPde = MiAddressToPde(Address);
2512  PMMPFN Pfn;
2513 
2514  /* We should not tinker with this one. */
2515  ASSERT(PointerPde != (PMMPDE)PXE_SELFMAP);
2516 
2517  DPRINT("Decrementing %p from %p\n", PointerPde, _ReturnAddress());
2518 
2519  /* Make sure we're locked */
2520  ASSERT(PsGetCurrentThread()->OwnsProcessWorkingSetExclusive);
2521 
2522  /* If we're decreasing refcount, then it must be valid! */
2523  ASSERT(PointerPde->u.Hard.Valid == 1);
2524 
2525  /* This lies on the PFN */
2526  Pfn = MiGetPfnEntry(PFN_FROM_PDE(PointerPde));
2527 
2530 
2532 
2533  return Pfn->OriginalPte.u.Soft.UsedPageTableEntries;
2534 }
#define PFN_FROM_PDE(v)
Definition: mm.h:93
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
union _MMPTE::@2311 u
static WCHAR Address[46]
Definition: ping.c:68
#define PXE_SELFMAP
#define ASSERT(a)
Definition: mode.c:44
ULONG64 UsedPageTableEntries
Definition: mmtypes.h:91
ULONG64 Valid
Definition: mmtypes.h:150
#define PTE_PER_PAGE
Definition: mm.h:20
Definition: mm.h:345
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:969
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
MMPTE OriginalPte
Definition: mm.h:379
void * _ReturnAddress(void)
#define DPRINT
Definition: sndvol32.h:71

Referenced by MiDeletePde(), MiDeleteVirtualAddresses(), MiUnmapLockedPagesInUserSpace(), MmDeletePageFileMapping(), and MmDeleteVirtualMapping().

◆ MiDecrementReferenceCount()

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

Definition at line 1230 of file pfnlist.c.

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

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

◆ MiDecrementShareCount()

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

Definition at line 1139 of file pfnlist.c.

1141 {
1142  PMMPTE PointerPte;
1143  MMPTE TempPte;
1144 
1145  ASSERT(PageFrameIndex > 0);
1146  ASSERT(MI_PFN_ELEMENT(PageFrameIndex) != NULL);
1147  ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
1148  ASSERT(MI_IS_ROS_PFN(Pfn1) == FALSE);
1149 
1150  DPRINT("Decrementing %p from %p\n", Pfn1, _ReturnAddress());
1151 
1152  /* Page must be in-use */
1153  if ((Pfn1->u3.e1.PageLocation != ActiveAndValid) &&
1154  (Pfn1->u3.e1.PageLocation != StandbyPageList))
1155  {
1156  /* Otherwise we have PFN corruption */
1157  KeBugCheckEx(PFN_LIST_CORRUPT,
1158  0x99,
1159  PageFrameIndex,
1160  Pfn1->u3.e1.PageLocation,
1161  0);
1162  }
1163 
1164  /* Page should at least have one reference */
1165  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
1166 
1167  /* Check if the share count is now 0 */
1168  ASSERT(Pfn1->u2.ShareCount < 0xF000000);
1169  if (!--Pfn1->u2.ShareCount)
1170  {
1171  /* Was this a prototype PTE? */
1172  if (Pfn1->u3.e1.PrototypePte)
1173  {
1174  /* Grab the PTE address and make sure it's in prototype pool */
1175  PointerPte = Pfn1->PteAddress;
1176  ASSERT((PointerPte >= (PMMPTE)MmPagedPoolStart) && (PointerPte <= (PMMPTE)MmPagedPoolEnd));
1177 
1178  /* The PTE that backs it should also be valdi */
1179  PointerPte = MiAddressToPte(PointerPte);
1180  ASSERT(PointerPte->u.Hard.Valid == 1);
1181 
1182  /* Get the original prototype PTE and turn it into a transition PTE */
1183  PointerPte = Pfn1->PteAddress;
1184  TempPte = *PointerPte;
1185  TempPte.u.Soft.Transition = 1;
1186  TempPte.u.Soft.Valid = 0;
1187  TempPte.u.Soft.Prototype = 0;
1188  TempPte.u.Soft.Protection = Pfn1->OriginalPte.u.Soft.Protection;
1189  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1190  DPRINT("Marking PTE: %p as transition (%p - %lx)\n", PointerPte, Pfn1, MiGetPfnEntryIndex(Pfn1));
1191  }
1192 
1193  /* Put the page in transition */
1194  Pfn1->u3.e1.PageLocation = TransitionPage;
1195 
1196  /* PFN lock must be held */
1198 
1199  if (Pfn1->u3.e2.ReferenceCount == 1)
1200  {
1201  /* Is there still a PFN for this page? */
1202  if (MI_IS_PFN_DELETED(Pfn1))
1203  {
1204  /* Clear the last reference */
1205  Pfn1->u3.e2.ReferenceCount = 0;
1206  ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
1207 
1208  /* Mark the page temporarily as valid, we're going to make it free soon */
1209  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1210 
1211  /* Bring it back into the free list */
1212  MiInsertPageInFreeList(PageFrameIndex);
1213  }
1214  else
1215  {
1216  /* PFN not yet deleted, drop a ref count */
1217  MiDecrementReferenceCount(Pfn1, PageFrameIndex);
1218  }
1219  }
1220  else
1221  {
1222  /* Otherwise, just drop the reference count */
1223  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
1224  }
1225  }
1226 }
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:965
signed short * PSHORT
Definition: retypes.h:6
PVOID MmPagedPoolEnd
Definition: init.c:26
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define FALSE
Definition: types.h:117
union _MMPTE::@2311 u
#define ASSERT(a)
Definition: mode.c:44
ULONG64 Valid
Definition: mmtypes.h:150
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:195
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1584
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:604
#define InterlockedDecrement16
Definition: interlocked.h:139
PVOID MmPagedPoolStart
Definition: miarm.h:584
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:1002
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1230
#define MI_IS_ROS_PFN(x)
Definition: miarm.h:1113
#define NULL
Definition: types.h:112
void * _ReturnAddress(void)
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:989
#define DPRINT
Definition: sndvol32.h:71
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 FreeWsleIndex(), MiDeletePte(), MiDeleteSystemPageableVm(), MiFreeContiguousMemory(), MiProcessValidPteList(), MiProtectVirtualMemory(), MiReleaseProcessReferenceToSessionDataPage(), MiRemoveMappedPtes(), MiUnmapLockedPagesInUserSpace(), MmDeleteKernelStack(), MmDeleteProcessAddressSpace(), MmFreeLoaderBlock(), MmFreeSpecialPool(), and TrimWsList().

◆ MiDeleteARM3Section()

VOID NTAPI MiDeleteARM3Section ( PVOID  ObjectBody)

Definition at line 3306 of file section.c.

3307 {
3309  PCONTROL_AREA ControlArea;
3310  KIRQL OldIrql;
3311 
3312  SectionObject = (PSECTION)ObjectBody;
3313 
3314  if (SectionObject->u.Flags.Based == 1)
3315  {
3316  /* Remove the node from the global section address tree */
3320  }
3321 
3322  /* Lock the PFN database */
3324 
3325  ASSERT(SectionObject->Segment);
3326  ASSERT(SectionObject->Segment->ControlArea);
3327 
3328  ControlArea = SectionObject->Segment->ControlArea;
3329 
3330  /* Dereference */
3331  ControlArea->NumberOfSectionReferences--;
3332  ControlArea->NumberOfUserReferences--;
3333 
3334  ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
3335 
3336  /* Check it. It will delete it if there is no more reference to it */
3337  MiCheckControlArea(ControlArea, OldIrql);
3338 }
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
ULONG NumberOfSectionReferences
Definition: mmtypes.h:520
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:110
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:930
UCHAR KIRQL
Definition: env_spec_w32.h:591
ASSERT(Segment->Locked)
struct _SECTION * PSECTION
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:360
ULONG BeingDeleted
Definition: mmtypes.h:460
ULONG NumberOfUserReferences
Definition: mmtypes.h:524
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:732
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
MMSECTION_FLAGS Flags
Definition: mmtypes.h:528
union _CONTROL_AREA::@2564 u

Referenced by MmpDeleteSection().

◆ MiDeletePde()

FORCEINLINE VOID MiDeletePde ( _In_ PMMPDE  PointerPde,
_In_ PEPROCESS  CurrentProcess 
)

Definition at line 2543 of file miarm.h.

2546 {
2547  /* Only for user-mode ones */
2548  ASSERT(MiIsUserPde(PointerPde));
2549 
2550  /* Kill this one as a PTE */
2551  MiDeletePte((PMMPTE)PointerPde, MiPdeToPte(PointerPde), CurrentProcess, NULL);
2552 #if _MI_PAGING_LEVELS >= 3
2553  /* Cascade down */
2554  if (MiDecrementPageTableReferences(MiPdeToPte(PointerPde)) == 0)
2555  {
2556  MiDeletePte(MiPdeToPpe(PointerPde), PointerPde, CurrentProcess, NULL);
2557 #if _MI_PAGING_LEVELS == 4
2558  if (MiDecrementPageTableReferences(PointerPde) == 0)
2559  {
2560  MiDeletePte(MiPdeToPxe(PointerPde), MiPdeToPpe(PointerPde), CurrentProcess, NULL);
2561  }
2562 #endif
2563  }
2564 #endif
2565 }
FORCEINLINE USHORT MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2509
VOID NTAPI MiDeletePte(IN PMMPTE PointerPte, IN PVOID VirtualAddress, IN PEPROCESS CurrentProcess, IN PMMPTE PrototypePte)
Definition: virtual.c:369
FORCEINLINE BOOLEAN MiIsUserPde(PVOID Address)
Definition: miarm.h:727
FORCEINLINE PMMPTE MiPdeToPte(PMMPDE PointerPde)
Definition: mm.h:237
ULONG CurrentProcess
Definition: shell.c:125
#define ASSERT(a)
Definition: mode.c:44
FORCEINLINE PMMPDE MiPdeToPpe(PMMPDE PointerPde)
Definition: mm.h:285
FORCEINLINE PMMPXE MiPdeToPxe(PMMPDE PointerPde)
Definition: mm.h:293
#define NULL
Definition: types.h:112

Referenced by MiDeleteVirtualAddresses(), MiUnmapLockedPagesInUserSpace(), and MmDeleteVirtualMapping().

◆ MiDeletePte()

VOID NTAPI MiDeletePte ( IN PMMPTE  PointerPte,
IN PVOID  VirtualAddress,
IN PEPROCESS  CurrentProcess,
IN PMMPTE  PrototypePte 
)

Definition at line 369 of file virtual.c.

373 {
374  PMMPFN Pfn1;
375  MMPTE TempPte;
376  PFN_NUMBER PageFrameIndex;
377  PMMPDE PointerPde;
378 
379  /* PFN lock must be held */
381 
382  /* WorkingSet must be exclusively locked */
384 
385  /* This must be current process. */
387 
388  /* Capture the PTE */
389  TempPte = *PointerPte;
390 
391  /* See if the PTE is valid */
392  if (TempPte.u.Hard.Valid == 0)
393  {
394  /* Prototype and paged out PTEs not supported yet */
395  ASSERT(TempPte.u.Soft.Prototype == 0);
396  ASSERT((TempPte.u.Soft.PageFileHigh == 0) || (TempPte.u.Soft.Transition == 1));
397 
398  if (TempPte.u.Soft.Transition)
399  {
400  /* Get the PFN entry */
401  PageFrameIndex = PFN_FROM_PTE(&TempPte);
402  Pfn1 = MiGetPfnEntry(PageFrameIndex);
403 
404  DPRINT("Pte %p is transitional!\n", PointerPte);
405 
406  /* Make sure the saved PTE address is valid */
407  ASSERT((PMMPTE)((ULONG_PTR)Pfn1->PteAddress & ~0x1) == PointerPte);
408 
409  /* Destroy the PTE */
410  MI_ERASE_PTE(PointerPte);
411 
412  /* Drop the reference on the page table. */
414 
415  /* In case of shared page, the prototype PTE must be in transition, not the process one */
416  ASSERT(Pfn1->u3.e1.PrototypePte == 0);
417 
418  /* Delete the PFN */
419  MI_SET_PFN_DELETED(Pfn1);
420 
421  /* It must be either free (refcount == 0) or being written (refcount == 1) */
422  ASSERT(Pfn1->u3.e2.ReferenceCount == Pfn1->u3.e1.WriteInProgress);
423 
424  /* See if we must free it ourselves, or if it will be freed once I/O is over */
425  if (Pfn1->u3.e2.ReferenceCount == 0)
426  {
427  /* And it should be in standby or modified list */
429 
430  /* Unlink it and set its reference count to one */
431  MiUnlinkPageFromList(Pfn1);
432  Pfn1->u3.e2.ReferenceCount++;
433 
434  /* This will put it back in free list and clean properly up */
435  MiDecrementReferenceCount(Pfn1, PageFrameIndex);
436  }
437  return;
438  }
439  }
440 
441  /* Get the PFN entry */
442  PageFrameIndex = PFN_FROM_PTE(&TempPte);
443  Pfn1 = MiGetPfnEntry(PageFrameIndex);
444 
445  /* Check if this is a valid, prototype PTE */
446  if (Pfn1->u3.e1.PrototypePte == 1)
447  {
448  /* Get the PDE and make sure it's faulted in */
449  PointerPde = MiPteToPde(PointerPte);
450  if (PointerPde->u.Hard.Valid == 0)
451  {
452 #if (_MI_PAGING_LEVELS == 2)
453  /* Could be paged pool access from a new process -- synchronize the page directories */
455  {
456 #endif
457  /* The PDE must be valid at this point */
458  KeBugCheckEx(MEMORY_MANAGEMENT,
459  0x61940,
460  (ULONG_PTR)PointerPte,
461  PointerPte->u.Long,
463  }
464 #if (_MI_PAGING_LEVELS == 2)
465  }
466 #endif
467  /* Drop the share count on the page table */
468  PointerPde = MiPteToPde(PointerPte);
470  PointerPde->u.Hard.PageFrameNumber);
471 
472  /* Drop the share count */
473  MiDecrementShareCount(Pfn1, PageFrameIndex);
474 
475  /* Either a fork, or this is the shared user data page */
476  if ((PointerPte <= MiHighestUserPte) && (PrototypePte != Pfn1->PteAddress))
477  {
478  /* If it's not the shared user page, then crash, since there's no fork() yet */
481  {
482  /* Must be some sort of memory corruption */
483  KeBugCheckEx(MEMORY_MANAGEMENT,
484  0x400,
485  (ULONG_PTR)PointerPte,
487  (ULONG_PTR)Pfn1->PteAddress);
488  }
489  }
490 
491  /* Erase it */
492  MI_ERASE_PTE(PointerPte);
493  }
494  else
495  {
496  /* Make sure the saved PTE address is valid */
497  if ((PMMPTE)((ULONG_PTR)Pfn1->PteAddress & ~0x1) != PointerPte)
498  {
499  /* The PFN entry is illegal, or invalid */
500  KeBugCheckEx(MEMORY_MANAGEMENT,
501  0x401,
502  (ULONG_PTR)PointerPte,
503  PointerPte->u.Long,
504  (ULONG_PTR)Pfn1->PteAddress);
505  }
506 
507  /* Erase the PTE */
508  MI_ERASE_PTE(PointerPte);
509 
510  /* There should only be 1 shared reference count */
511  ASSERT(Pfn1->u2.ShareCount == 1);
512 
513  /* Drop the reference on the page table. */
515 
516  /* Mark the PFN for deletion and dereference what should be the last ref */
517  MI_SET_PFN_DELETED(Pfn1);
518  MiDecrementShareCount(Pfn1, PageFrameIndex);
519 
520  /* We should eventually do this */
521  //CurrentProcess->NumberOfPrivatePages--;
522  }
523 
524  /* Flush the TLB */
526 }
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:1016
union _MMPFN::@1784 u2
MMPTE PrototypePte
Definition: init.c:40
union _MMPFN::@1788 u4
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:965
VOID NTAPI MiUnlinkPageFromList(IN PMMPFN Pfn)
Definition: pfnlist.c:264
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
struct _MMPFN::@1785::@1791 e2
NTSTATUS FASTCALL MiCheckPdeForPagedPool(IN PVOID Address)
Definition: pagfault.c:475
FORCEINLINE PMMPDE MiPteToPde(PMMPTE PointerPte)
Definition: mm.h:261
USHORT PageLocation
Definition: mm.h:337
uint32_t ULONG_PTR
Definition: typedefs.h:65
USHORT PrototypePte
Definition: mm.h:335
MMPFNENTRY e1
Definition: mm.h:369
ULONG PFN_NUMBER
Definition: ke.h:9
ULONG_PTR ShareCount
Definition: mm.h:362
union _MMPTE::@2311 u
#define USER_SHARED_DATA
Definition: pstypes.h:51
#define PsGetCurrentProcess
Definition: psfuncs.h:17
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1139
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress
USHORT WriteInProgress
Definition: mm.h:334
ULONG CurrentProcess
Definition: shell.c:125
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG64 Valid
Definition: mmtypes.h:150
#define PAGE_ALIGN(Va)
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1230
Definition: mm.h:345
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:969
union _MMPFN::@1785 u3
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:194
ULONG_PTR PteFrame
Definition: mm.h:390
PMMPTE PteAddress
Definition: mm.h:358
PVOID MmHighestUserAddress
Definition: rtlcompat.c:29
FORCEINLINE BOOLEAN MM_ANY_WS_LOCK_HELD_EXCLUSIVE(_In_ PETHREAD Thread)
Definition: miarm.h:1075
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
PMMPTE MiHighestUserPte
Definition: mminit.c:233
#define DPRINT
Definition: sndvol32.h:71
#define PFN_FROM_PTE(v)
Definition: mm.h:92
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:316

Referenced by MiDeletePde(), MiDeleteVirtualAddresses(), MiResolveProtoPteFault(), MmArmAccessFault(), and MmDeletePageFileMapping().

◆ MiDeleteSystemPageableVm()

PFN_COUNT NTAPI MiDeleteSystemPageableVm ( IN PMMPTE  PointerPte,
IN PFN_NUMBER  PageCount,
IN ULONG  Flags,
OUT PPFN_NUMBER  ValidPages 
)

Definition at line 275 of file virtual.c.

279 {
280  PFN_COUNT ActualPages = 0;
281  PETHREAD CurrentThread = PsGetCurrentThread();
282  PMMPFN Pfn1, Pfn2;
283  PFN_NUMBER PageFrameIndex, PageTableIndex;
284  KIRQL OldIrql;
286 
287  /* Lock the system working set */
288  MiLockWorkingSet(CurrentThread, &MmSystemCacheWs);
289 
290  /* Loop all pages */
291  while (PageCount)
292  {
293  /* Make sure there's some data about the page */
294  if (PointerPte->u.Long)
295  {
296  /* Normally this is one possibility -- freeing a valid page */
297  if (PointerPte->u.Hard.Valid)
298  {
299  /* Get the page PFN */
300  PageFrameIndex = PFN_FROM_PTE(PointerPte);
301  Pfn1 = MiGetPfnEntry(PageFrameIndex);
302 
303  /* Should not have any working set data yet */
304  ASSERT(Pfn1->u1.WsIndex == 0);
305 
306  /* Actual valid, legitimate, pages */
307  if (ValidPages) (*ValidPages)++;
308 
309  /* Get the page table entry */
310  PageTableIndex = Pfn1->u4.PteFrame;
311  Pfn2 = MiGetPfnEntry(PageTableIndex);
312 
313  /* Lock the PFN database */
315 
316  /* Delete it the page */
317  MI_SET_PFN_DELETED(Pfn1);
318  MiDecrementShareCount(Pfn1, PageFrameIndex);
319 
320  /* Decrement the page table too */
321  MiDecrementShareCount(Pfn2, PageTableIndex);
322 
323  /* Release the PFN database */
325 
326  /* Destroy the PTE */
327  MI_ERASE_PTE(PointerPte);
328  }
329  else
330  {
331  /* As always, only handle current ARM3 scenarios */
332  ASSERT(PointerPte->u.Soft.Prototype == 0);
333  ASSERT(PointerPte->u.Soft.Transition == 0);
334 
335  /*
336  * The only other ARM3 possibility is a demand zero page, which would
337  * mean freeing some of the paged pool pages that haven't even been
338  * touched yet, as part of a larger allocation.
339  *
340  * Right now, we shouldn't expect any page file information in the PTE
341  */
342  ASSERT(PointerPte->u.Soft.PageFileHigh == 0);
343 
344  /* Destroy the PTE */
345  MI_ERASE_PTE(PointerPte);
346  }
347 
348  /* Actual legitimate pages */
349  ActualPages++;
350  }
351 
352  /* Keep going */
353  PointerPte++;
354  PageCount--;
355  }
356 
357  /* Release the working set */
358  MiUnlockWorkingSet(CurrentThread, &MmSystemCacheWs);
359 
360  /* Flush the entire TLB */
362 
363  /* Done */
364  return ActualPages;
365 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:1016
union _MMPFN::@1788 u4
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define TRUE
Definition: types.h:120
union _MMPFN::@1783 u1
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:930
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:937
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PFN_NUMBER
Definition: ke.h:9
MMSUPPORT MmSystemCacheWs
Definition: init.c:55
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1139
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1361
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:407
#define ASSERT(a)
Definition: mode.c:44
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: mm.h:345
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:969
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:194
ULONG_PTR PteFrame
Definition: mm.h:390
ULONG WsIndex
Definition: mm.h:350
FORCEINLINE VOID MiLockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1275
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PFN_FROM_PTE(v)
Definition: mm.h:92

Referenced by MiFreeInitializationCode(), MiFreePoolPages(), MmFreeDriverInitialization(), and MmFreeSpecialPool().

◆ MiDeleteVirtualAddresses()

VOID NTAPI MiDeleteVirtualAddresses ( IN ULONG_PTR  Va,
IN ULONG_PTR  EndingAddress,
IN PMMVAD  Vad 
)

Definition at line 530 of file virtual.c.

533 {
534  PMMPTE PointerPte, PrototypePte, LastPrototypePte;
535  PMMPDE PointerPde;
536 #if (_MI_PAGING_LEVELS >= 3)
537  PMMPPE PointerPpe;
538 #endif
539 #if (_MI_PAGING_LEVELS >= 4)
540  PMMPPE PointerPxe;
541 #endif
542  MMPTE TempPte;
544  KIRQL OldIrql;
545  BOOLEAN AddressGap = FALSE;
546  PSUBSECTION Subsection;
547 
548  /* Get out if this is a fake VAD, RosMm will free the marea pages */
549  if ((Vad) && (Vad->u.VadFlags.Spare == 1)) return;
550 
551  /* Get the current process */
553 
554  /* Check if this is a section VAD or a VM VAD */
555  if (!(Vad) || (Vad->u.VadFlags.PrivateMemory) || !(Vad->FirstPrototypePte))
556  {
557  /* Don't worry about prototypes */
558  PrototypePte = LastPrototypePte = NULL;
559  }
560  else
561  {
562  /* Get the prototype PTE */
563  PrototypePte = Vad->FirstPrototypePte;
564  LastPrototypePte = Vad->FirstPrototypePte + 1;
565  }
566 
567  /* In all cases, we don't support fork() yet */
568  ASSERT(CurrentProcess->CloneRoot == NULL);
569 
570  /* Loop the PTE for each VA (EndingAddress is inclusive!) */
571  while (Va <= EndingAddress)
572  {
573 #if (_MI_PAGING_LEVELS >= 4)
574  /* Get the PXE and check if it's valid */
575  PointerPxe = MiAddressToPxe((PVOID)Va);
576  if (!PointerPxe->u.Hard.Valid)
577  {
578  /* Check for unmapped range and skip it */
579  if (!PointerPxe->u.Long)
580  {
581  /* There are gaps in the address space */
582  AddressGap = TRUE;
583 
584  /* Update Va and continue looping */
585  Va = (ULONG_PTR)MiPxeToAddress(PointerPxe + 1);
586  continue;
587  }
588 
589  /* Make the PXE valid */
591  }
592 #endif
593 #if (_MI_PAGING_LEVELS >= 3)
594  /* Get the PPE and check if it's valid */
595  PointerPpe = MiAddressToPpe((PVOID)Va);
596  if (!PointerPpe->u.Hard.Valid)
597  {
598  /* Check for unmapped range and skip it */
599  if (!PointerPpe->u.Long)
600  {
601  /* There are gaps in the address space */
602  AddressGap = TRUE;
603 
604  /* Update Va and continue looping */
605  Va = (ULONG_PTR)MiPpeToAddress(PointerPpe + 1);
606  continue;
607  }
608 
609  /* Make the PPE valid */
611  }
612 #endif
613  /* Skip invalid PDEs */
614  PointerPde = MiAddressToPde((PVOID)Va);
615  if (!PointerPde->u.Long)
616  {
617  /* There are gaps in the address space */
618  AddressGap = TRUE;
619 
620  /* Check if all the PDEs are invalid, so there's nothing to free */
621  Va = (ULONG_PTR)MiPdeToAddress(PointerPde + 1);
622  continue;
623  }
624 
625  /* Now check if the PDE is mapped in */
626  if (!PointerPde->u.Hard.Valid)
627  {
628  /* It isn't, so map it in */
629  PointerPte = MiPteToAddress(PointerPde);
631  }
632 
633  /* Now we should have a valid PDE, mapped in, and still have some VA */
634  ASSERT(PointerPde->u.Hard.Valid == 1);
635  ASSERT(Va <= EndingAddress);
636 
637  /* Check if this is a section VAD with gaps in it */
638  if ((AddressGap) && (LastPrototypePte))
639  {
640  /* We need to skip to the next correct prototype PTE */
642 
643  /* And we need the subsection to skip to the next last prototype PTE */
644  Subsection = MiLocateSubsection(Vad, Va >> PAGE_SHIFT);
645  if (Subsection)
646  {
647  /* Found it! */
648  LastPrototypePte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
649  }
650  else
651  {
652  /* No more subsections, we are done with prototype PTEs */
653  PrototypePte = NULL;
654  }
655  }
656 
657  /* Lock the PFN Database while we delete the PTEs */
659  PointerPte = MiAddressToPte(Va);
660  do
661  {
662  /* Making sure the PDE is still valid */
663  ASSERT(PointerPde->u.Hard.Valid == 1);
664 
665  /* Capture the PDE and make sure it exists */
666  TempPte = *PointerPte;
667  if (TempPte.u.Long)
668  {
669  /* Check if the PTE is actually mapped in */
671  {
672  /* Are we dealing with section VAD? */
673  if ((LastPrototypePte) && (PrototypePte > LastPrototypePte))
674  {
675  /* We need to skip to the next correct prototype PTE */
677 
678  /* And we need the subsection to skip to the next last prototype PTE */
679  Subsection = MiLocateSubsection(Vad, Va >> PAGE_SHIFT);
680  if (Subsection)
681  {
682  /* Found it! */
683  LastPrototypePte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
684  }
685  else
686  {
687  /* No more subsections, we are done with prototype PTEs */
688  PrototypePte = NULL;
689  }
690  }
691 
692  /* Check for prototype PTE */
693  if ((TempPte.u.Hard.Valid == 0) &&
694  (TempPte.u.Soft.Prototype == 1))
695  {
696  /* Just nuke it */
697  MI_ERASE_PTE(PointerPte);
698  }
699  else
700  {
701  /* Delete the PTE proper */
702  MiDeletePte(PointerPte,
703  (PVOID)Va,
705  PrototypePte);
706  }
707  }
708  else
709  {
710  /* The PTE was never mapped, just nuke it here */
711  MI_ERASE_PTE(PointerPte);
712  }
713 
715  {
716  ASSERT(PointerPde->u.Long != 0);
717  /* Delete the PDE proper */
718  MiDeletePde(PointerPde, CurrentProcess);
719  /* Jump */
720  Va = (ULONG_PTR)MiPdeToAddress(PointerPde + 1);
721  break;
722  }
723  }
724 
725  /* Update the address and PTE for it */
726  Va += PAGE_SIZE;
727  PointerPte++;
728  PrototypePte++;
729  } while ((Va & (PDE_MAPPED_VA - 1)) && (Va <= EndingAddress));
730 
731  /* Release the lock */
733 
734  if (Va > EndingAddress) return;
735 
736  /* Otherwise, we exited because we hit a new PDE boundary, so start over */
737  AddressGap = FALSE;
738  }
739 }
ULONG NTAPI MiMakeSystemAddressValid(IN PVOID PageTableVirtualAddress, IN PEPROCESS CurrentProcess)
Definition: virtual.c:183
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:1016
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
MMPTE PrototypePte
Definition: init.c:40
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define TRUE
Definition: types.h:120
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:154
FORCEINLINE USHORT MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2509
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:930
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:937
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define FALSE
Definition: types.h:117
union _MMPTE::@2311 u
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:164
ULONG CurrentProcess
Definition: shell.c:125
#define ASSERT(a)
Definition: mode.c:44
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
FORCEINLINE PVOID MiPxeToAddress(PMMPTE PointerPxe)
Definition: mm.h:228
#define PAGE_SIZE
Definition: env_spec_w32.h:49
FORCEINLINE VOID MiDeletePde(_In_ PMMPDE PointerPde, _In_ PEPROCESS CurrentProcess)
Definition: miarm.h:2543
ULONG_PTR Long
Definition: mmtypes.h:215
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
PSUBSECTION NTAPI MiLocateSubsection(IN PMMVAD Vad, IN ULONG_PTR Vpn)
Definition: section.c:574
FORCEINLINE PVOID MiPdeToAddress(PMMPTE PointerPde)
Definition: mm.h:210
#define NULL
Definition: types.h:112
VOID NTAPI MiDeletePte(IN PMMPTE PointerPte, IN PVOID VirtualAddress, IN PEPROCESS CurrentProcess, IN PMMPTE PrototypePte)
Definition: virtual.c:369
FORCEINLINE PVOID MiPpeToAddress(PMMPTE PointerPpe)
Definition: mm.h:219
FORCEINLINE BOOLEAN MI_IS_MAPPED_PTE(PMMPTE PointerPte)
Definition: mm.h:349
#define PDE_MAPPED_VA
Definition: mm.h:39
#define ULONG_PTR
Definition: config.h:101
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
PMMPTE SubsectionBase
Definition: mmtypes.h:578
FORCEINLINE PMMPTE MI_GET_PROTOTYPE_PTE_FOR_VPN(IN PMMVAD Vad, IN ULONG_PTR Vpn)
Definition: miarm.h:1567
ULONG PtesInSubsection
Definition: mmtypes.h:580

Referenced by MiRemoveMappedView(), MmCleanProcessAddressSpace(), MmDeleteTeb(), and NtFreeVirtualMemory().

◆ MiDereferencePfnAndDropLockCount()

FORCEINLINE VOID MiDereferencePfnAndDropLockCount ( IN PMMPFN  Pfn1)

Definition at line 1625 of file miarm.h.

1626 {
1627  USHORT RefCount, OldRefCount;
1628  PFN_NUMBER PageFrameIndex;
1629 
1630  /* Loop while we decrement the page successfully */
1631  do
1632  {
1633  /* There should be at least one reference */
1634  OldRefCount = Pfn1->u3.e2.ReferenceCount;
1635  ASSERT(OldRefCount != 0);
1636 
1637  /* Are we the last one */
1638  if (OldRefCount == 1)
1639  {
1640  /* The page shoudln't be shared not active at this point */
1641  ASSERT(Pfn1->u3.e2.ReferenceCount == 1);
1642  ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
1643  ASSERT(Pfn1->u2.ShareCount == 0);
1644 
1645  /* Is it a prototype PTE? */
1646  if ((Pfn1->u3.e1.PrototypePte == 1) &&
1647  (Pfn1->OriginalPte.u.Soft.Prototype == 1))
1648  {
1649  /* FIXME: We should return commit */
1650  DPRINT1("Not returning commit for prototype PTE\n");
1651  }
1652 
1653  /* Update the counter, and drop a reference the long way */
1655  PageFrameIndex = MiGetPfnEntryIndex(Pfn1);
1656  MiDecrementReferenceCount(Pfn1, PageFrameIndex);
1657  return;
1658  }
1659 
1660  /* Drop a reference the short way, and that's it */
1661  RefCount = InterlockedCompareExchange16((PSHORT)&Pfn1->u3.e2.ReferenceCount,
1662  OldRefCount - 1,
1663  OldRefCount);
1664  ASSERT(RefCount != 0);
1665  } while (OldRefCount != RefCount);
1666 
1667  /* If we got here, there should be more than one reference */
1668  ASSERT(RefCount > 1);
1669  if (RefCount == 2)
1670  {
1671  /* Is it still being shared? */
1672  if (Pfn1->u2.ShareCount >= 1)
1673  {
1674  /* Then it should be valid */
1675  ASSERT(Pfn1->u3.e1.PageLocation == ActiveAndValid);
1676 
1677  /* Is it a prototype PTE? */
1678  if ((Pfn1->u3.e1.PrototypePte == 1) &&
1679  (Pfn1->OriginalPte.u.Soft.Prototype == 1))
1680  {
1681  /* We don't handle ethis */
1682  ASSERT(FALSE);
1683  }
1684 
1685  /* Update the counter */
1687  }
1688  }
1689 }
signed short * PSHORT
Definition: retypes.h:6
SIZE_T MmSystemLockPagesCount
Definition: mdlsup.c:22
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
#define ASSERT(a)
Definition: mode.c:44
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1230
unsigned short USHORT
Definition: pedump.c:61
#define InterlockedCompareExchange16
Definition: interlocked.h:109
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:989
#define InterlockedDecrementSizeT(a)
Definition: interlocked.h:153

Referenced by MI_UNLOCK_VA(), MiCompleteProtoPteFault(), MiDispatchFault(), and MmUnlockPages().

◆ MiDetermineUserGlobalPteMask()

FORCEINLINE ULONG_PTR MiDetermineUserGlobalPteMask ( IN PVOID  PointerPte)

Definition at line 746 of file miarm.h.

747 {
748  MMPTE TempPte;
749 
750  /* Start fresh */
751  TempPte.u.Long = 0;
752 
753  /* Make it valid and accessed */
754  TempPte.u.Hard.Valid = TRUE;
756 
757  /* Is this for user-mode? */
758  if (
759 #if (_MI_PAGING_LEVELS == 4)
760  MiIsUserPxe(PointerPte) ||
761 #endif
762 #if (_MI_PAGING_LEVELS >= 3)
763  MiIsUserPpe(PointerPte) ||
764 #endif
765  MiIsUserPde(PointerPte) ||
766  MiIsUserPte(PointerPte))
767  {
768  /* Set the owner bit */
770  }
771 
772  /* FIXME: We should also set the global bit */
773 
774  /* Return the protection */
775  return TempPte.u.Long;
776 }
#define _MI_PAGING_LEVELS
Definition: mm.h:6
#define MI_MAKE_ACCESSED_PAGE(x)
Definition: mm.h:100
#define TRUE
Definition: types.h:120
#define MI_MAKE_OWNER_PAGE(x)
Definition: mm.h:113
FORCEINLINE BOOLEAN MiIsUserPde(PVOID Address)
Definition: miarm.h:727
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
FORCEINLINE BOOLEAN MiIsUserPte(PVOID Address)
Definition: miarm.h:735

Referenced by MI_MAKE_HARDWARE_PTE(), and MiResolveTransitionFault().

◆ MiDropLockCount()

FORCEINLINE VOID MiDropLockCount ( IN PMMPFN  Pfn1)

Definition at line 1595 of file miarm.h.

1596 {
1597  /* This page shouldn't be locked, but it should be valid */
1598  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
1599  ASSERT(Pfn1->u2.ShareCount == 0);
1600 
1601  /* Is this the last reference to the page */
1602  if (Pfn1->u3.e2.ReferenceCount == 1)
1603  {
1604  /* It better not be valid */
1605  ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
1606 
1607  /* Is it a prototype PTE? */
1608  if ((Pfn1->u3.e1.PrototypePte == 1) &&
1609  (Pfn1->OriginalPte.u.Soft.Prototype == 1))
1610  {
1611  /* FIXME: We should return commit */
1612  DPRINT1("Not returning commit for prototype PTE\n");
1613  }
1614 
1615  /* Update the counter */
1617  }
1618 }
SIZE_T MmSystemLockPagesCount
Definition: mdlsup.c:22
#define ASSERT(a)
Definition: mode.c:44
#define DPRINT1
Definition: precomp.h:8
#define InterlockedDecrementSizeT(a)
Definition: interlocked.h:153

Referenced by MiResolveTransitionFault().

◆ MiFindContiguousPages()

PFN_NUMBER NTAPI MiFindContiguousPages ( IN PFN_NUMBER  LowestPfn,
IN PFN_NUMBER  HighestPfn,
IN PFN_NUMBER  BoundaryPfn,
IN PFN_NUMBER  SizeInPages,
IN MEMORY_CACHING_TYPE  CacheType 
)

Definition at line 22 of file contmem.c.

27 {
28  PFN_NUMBER Page, PageCount, LastPage, Length, BoundaryMask;
29  ULONG i = 0;
30  PMMPFN Pfn1, EndPfn;
31  KIRQL OldIrql;
32  PAGED_CODE();
33  ASSERT(SizeInPages != 0);
34 
35  //
36  // Convert the boundary PFN into an alignment mask
37  //
38  BoundaryMask = ~(BoundaryPfn - 1);
39 
40  /* Disable APCs */
42 
43  //
44  // Loop all the physical memory blocks
45  //
46  do
47  {
48  //
49  // Capture the base page and length of this memory block
50  //
52  PageCount = MmPhysicalMemoryBlock->Run[i].PageCount;
53 
54  //
55  // Check how far this memory block will go
56  //
57  LastPage = Page + PageCount;
58 
59  //
60  // Trim it down to only the PFNs we're actually interested in
61  //
62  if ((LastPage - 1) > HighestPfn) LastPage = HighestPfn + 1;
63  if (Page < LowestPfn) Page = LowestPfn;
64 
65  //
66  // Skip this run if it's empty or fails to contain all the pages we need
67  //
68  if (!(PageCount) || ((Page + SizeInPages) > LastPage)) continue;
69 
70  //
71  // Now scan all the relevant PFNs in this run
72  //
73  Length = 0;
74  for (Pfn1 = MI_PFN_ELEMENT(Page); Page < LastPage; Page++, Pfn1++)
75  {
76  //
77  // If this PFN is in use, ignore it
78  //
79  if (MiIsPfnInUse(Pfn1))
80  {
81  Length = 0;
82  continue;
83  }
84 
85  //
86  // If we haven't chosen a start PFN yet and the caller specified an
87  // alignment, make sure the page matches the alignment restriction
88  //
89  if ((!(Length) && (BoundaryPfn)) &&
90  (((Page ^ (Page + SizeInPages - 1)) & BoundaryMask)))
91  {
92  //
93  // It does not, so bail out
94  //
95  continue;
96  }
97 
98  //
99  // Increase the number of valid pages, and check if we have enough
100  //
101  if (++Length == SizeInPages)
102  {
103  //
104  // It appears we've amassed enough legitimate pages, rollback
105  //
106  Pfn1 -= (Length - 1);
107  Page -= (Length - 1);
108 
109  //
110  // Acquire the PFN lock
111  //
113  do
114  {
115  //
116  // Things might've changed for us. Is the page still free?
117  //
118  if (MiIsPfnInUse(Pfn1)) break;
119 
120  //
121  // So far so good. Is this the last confirmed valid page?
122  //
123  if (!--Length)
124  {
125  //
126  // Sanity check that we didn't go out of bounds
127  //
129 
130  //
131  // Loop until all PFN entries have been processed
132  //
133  EndPfn = Pfn1 - SizeInPages + 1;
134  do
135  {
136  //
137  // This PFN is now a used page, set it up
138  //
140  MI_SET_PROCESS2("Kernel Driver");
142  Pfn1->u3.e2.ReferenceCount = 1;
143  Pfn1->u2.ShareCount = 1;
145  Pfn1->u3.e1.StartOfAllocation = 0;
146  Pfn1->u3.e1.EndOfAllocation = 0;
147  Pfn1->u3.e1.PrototypePte = 0;
148  Pfn1->u4.VerifierAllocation = 0;
149  Pfn1->PteAddress = (PVOID)(ULONG_PTR)0xBAADF00DBAADF00DULL;
150 
151  //
152  // Check if this is the last PFN, otherwise go on
153  //
154  if (Pfn1 == EndPfn) break;
155  Pfn1--;
156  } while (TRUE);
157 
158  //
159  // Mark the first and last PFN so we can find them later
160  //
161  Pfn1->u3.e1.StartOfAllocation = 1;
162  (Pfn1 + SizeInPages - 1)->u3.e1.EndOfAllocation = 1;
163 
164  //
165  // Now it's safe to let go of the PFN lock
166  //
168 
169  //
170  // Quick sanity check that the last PFN is consistent
171  //
172  EndPfn = Pfn1 + SizeInPages;
173  ASSERT(EndPfn == MI_PFN_ELEMENT(Page + 1));
174 
175  //
176  // Compute the first page, and make sure it's consistent
177  //
178  Page = Page - SizeInPages + 1;
179  ASSERT(Pfn1 == MI_PFN_ELEMENT(Page));
180  ASSERT(Page != 0);
181 
182  /* Enable APCs and return the page */
184  return Page;
185  }
186 
187  //
188  // Keep going. The purpose of this loop is to reconfirm that
189  // after acquiring the PFN lock these pages are still usable
190  //
191  Pfn1++;
192  Page++;
193  } while (TRUE);
194 
195  //
196  // If we got here, something changed while we hadn't acquired
197  // the PFN lock yet, so we'll have to restart
198  //
200  Length = 0;
201  }
202  }
203  } while (++i != MmPhysicalMemoryBlock->NumberOfRuns);
204 
205  //
206  // And if we get here, it means no suitable physical memory runs were found
207  //
209  return 0;
210 }
union _MMPFN::@1784 u2
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
union _MMPFN::@1788 u4
#define TRUE
Definition: types.h:120
PFN_NUMBER PageCount
Definition: miarm.h:429
struct _MMPFN::@1785::@1791 e2
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:930
PHYSICAL_MEMORY_RUN Run[1]
Definition: miarm.h:436
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:937
USHORT PageLocation
Definition: mm.h:337
uint32_t ULONG_PTR
Definition: typedefs.h:65
USHORT PrototypePte
Definition: mm.h:335
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:369
ULONG PFN_NUMBER
Definition: ke.h:9
ULONG_PTR ShareCount
Definition: mm.h:362
PFN_NUMBER BasePage
Definition: miarm.h:428