ReactOS  0.4.10-dev-348-gbcec1fd
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 PDE_MAPPED_VA   (PTE_COUNT * PAGE_SIZE)
 
#define PT_SIZE   (PTE_COUNT * sizeof(MMPTE))
 
#define PD_SIZE   (PDE_COUNT * sizeof(MMPDE))
 
#define PD_COUNT   PPE_PER_PAGE
 
#define PDE_COUNT   PDE_PER_PAGE
 
#define PTE_COUNT   PTE_PER_PAGE
 
#define SYSTEM_PD_SIZE   (PD_COUNT * 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 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_TABLE
PPOOL_TRACKER_TABLE
 
typedef struct
_POOL_TRACKER_BIG_PAGES 
POOL_TRACKER_BIG_PAGES
 
typedef struct
_POOL_TRACKER_BIG_PAGES
PPOOL_TRACKER_BIG_PAGES
 
typedef struct
_MI_LARGE_PAGE_DRIVER_ENTRY 
MI_LARGE_PAGE_DRIVER_ENTRY
 
typedef struct
_MI_LARGE_PAGE_DRIVER_ENTRY
PMI_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_ATTRIBUTE
PMI_PFN_CACHE_ATTRIBUTE
 
typedef struct _PHYSICAL_MEMORY_RUN PHYSICAL_MEMORY_RUN
 
typedef struct
_PHYSICAL_MEMORY_RUN
PPHYSICAL_MEMORY_RUN
 
typedef struct
_PHYSICAL_MEMORY_DESCRIPTOR 
PHYSICAL_MEMORY_DESCRIPTOR
 
typedef struct
_PHYSICAL_MEMORY_DESCRIPTOR
PPHYSICAL_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_RANGES
PMI_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 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 MI_WS_OWNER (IN PEPROCESS Process)
 
FORCEINLINE BOOLEAN MiIsRosSectionObject (IN PVOID 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 MiUnlockWorkingSet (IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
 
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)
 
FORCEINLINE VOID MiIncrementPageTableReferences (IN PVOID Address)
 
FORCEINLINE VOID MiDecrementPageTableReferences (IN PVOID Address)
 
FORCEINLINE USHORT MiQueryPageTableReferences (IN PVOID Address)
 
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 MiInitializeNonPagedPool (VOID)
 
VOID NTAPI MiInitializeNonPagedPoolThresholds (VOID)
 
VOID NTAPI MiInitializePoolEvents (VOID)
 
VOID NTAPI InitializePool (IN POOL_TYPE PoolType, IN ULONG Threshold)
 
VOID NTAPI INIT_FUNCTION 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)
 
POOL_TYPE NTAPI MmDeterminePoolType (IN PVOID PoolAddress)
 
VOID NTAPI MiMakePdeExistAndMakeValid (IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
 
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe (IN ULONG Color)
 

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
 
RTL_BITMAP MiPfnBitMap
 
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 MmResidentAvailablePages
 
PFN_NUMBER MmResidentAvailableAtInit
 
ULONG MmTotalFreeSystemPtes [MaximumPtePoolTypes]
 
PFN_NUMBER MmTotalSystemDriverPages
 
ULONG MmCritsectTimeoutSeconds
 
PVOID MiSessionImageStart
 
PVOID MiSessionImageEnd
 
PMMPTE MiHighestUserPte
 
PMMPDE MiHighestUserPde
 
PFN_NUMBER MmSystemPageDirectory [PD_COUNT]
 
PMMPTE MmSharedUserDataPte
 
LIST_ENTRY MmProcessList
 
BOOLEAN MmZeroingPageThreadActive
 
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

#define _1GB   (1024 * _1MB)

Definition at line 16 of file miarm.h.

Referenced by MiInitializeNonPagedPool(), and MmArmInitSystem().

#define _1KB   (1024u)

Definition at line 14 of file miarm.h.

Referenced by FsRtlTest_StartTest(), and MmArmInitSystem().

#define BASE_POOL_TYPE_MASK   1

Definition at line 251 of file miarm.h.

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

Definition at line 210 of file miarm.h.

Referenced by MmZeroPageThread().

#define MI_INITIAL_SESSION_IDS   64

Definition at line 181 of file miarm.h.

Referenced by MiInitializeSessionIds().

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

Definition at line 146 of file miarm.h.

Referenced by MiCheckVirtualAddress(), and MiResolveDemandZeroFault().

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

Definition at line 152 of file miarm.h.

Referenced by MmArmAccessFault().

#define MI_IS_PFN_DELETED (   x)    ((ULONG_PTR)((x)->PteAddress) & 1)
#define MI_IS_ROS_PFN (   x)    ((x)->u4.AweAllocation == TRUE)
#define MI_IS_SESSION_IMAGE_ADDRESS (   Address)    (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd))
#define MI_IS_SESSION_PTE (   Pte)    ((((PMMPTE)Pte) >= MiSessionBasePte) && (((PMMPTE)Pte) < MiSessionLastPte))

Definition at line 143 of file miarm.h.

Referenced by MI_MAKE_HARDWARE_PTE_KERNEL(), and MmArmAccessFault().

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

Definition at line 149 of file miarm.h.

Referenced by MmArmAccessFault().

#define MI_MAKE_SOFTWARE_PTE (   p,
  x 
)    ((p)->u.Long = (x << MM_PTE_SOFTWARE_PROTECTION_BITS))
#define MI_SESSION_DATA_PAGES_MAXIMUM   (MM_ALLOCATION_GRANULARITY / PAGE_SIZE)
#define MI_SESSION_TAG_PAGES_MAXIMUM   (MM_ALLOCATION_GRANULARITY / PAGE_SIZE)

Definition at line 227 of file miarm.h.

Referenced by MiInitializeSessionIds(), and MiSessionCreateInternal().

#define MI_SYSTEM_VIEW_BUCKET_SIZE   _64K
#define MM_DELETE_CHECK   85

Definition at line 235 of file miarm.h.

Referenced by MiCheckSecuredVad(), and MiUnmapViewOfSection().

#define MM_EXECUTE   2

Definition at line 49 of file miarm.h.

Referenced by MiComputeDriverProtection().

#define MM_EXECUTE_READ   3

Definition at line 50 of file miarm.h.

#define MM_EXECUTE_READWRITE   6

Definition at line 53 of file miarm.h.

Referenced by MiComputeDriverProtection().

#define MM_EXECUTE_WRITECOPY   7

Definition at line 54 of file miarm.h.

#define MM_GUARDPAGE   0x10

Definition at line 61 of file miarm.h.

Referenced by MiAccessCheck(), MiMakeProtectionMask(), and MmArmAccessFault().

#define MM_INVALID_PROTECTION   0xFFFFFFFF
#define MM_NO_ACCESS_ALLOWED   01

Definition at line 234 of file miarm.h.

#define MM_NOCACHE   0x08

Definition at line 60 of file miarm.h.

Referenced by MiFlushTbAndCapture(), and MiMakeProtectionMask().

#define MM_OUTSWAPPED_KSTACK   (MM_EXECUTE_WRITECOPY | MM_WRITECOMBINE)

Definition at line 70 of file miarm.h.

#define MM_PROTECT_ACCESS   7

Definition at line 55 of file miarm.h.

Referenced by MiIsAccessAllowed().

#define MM_PROTECT_SPECIAL   0x18

Definition at line 63 of file miarm.h.

Referenced by MiAccessCheck(), MiCompleteProtoPteFault(), and MmArmAccessFault().

#define MM_READ_ONLY_ALLOWED   10

Definition at line 233 of file miarm.h.

#define MM_READ_WRITE_ALLOWED   11

Definition at line 232 of file miarm.h.

Referenced by MiCheckSecuredVad().

#define MM_SYSLDR_BOOT_LOADED   (PVOID)0xFFFFFFFF
#define MM_SYSLDR_NO_IMPORTS   (PVOID)0xFFFFFFFE
#define MM_SYSLDR_SINGLE_ENTRY   0x1
#define MM_WRITECOMBINE   0x18

Definition at line 62 of file miarm.h.

#define MM_WRITECOPY   5

Definition at line 52 of file miarm.h.

Referenced by MiCompleteProtoPteFault(), and MiResolveProtoPteFault().

#define MM_ZERO_ACCESS   0

Definition at line 47 of file miarm.h.

Referenced by MiCompleteProtoPteFault(), MiComputeDriverProtection(), and MmArmAccessFault().

#define PD_COUNT   PPE_PER_PAGE

Definition at line 31 of file miarm.h.

Referenced by MiBuildPagedPool(), and MiBuildPfnDatabaseFromPages().

#define PD_SIZE   (PDE_COUNT * sizeof(MMPDE))

Definition at line 28 of file miarm.h.

Referenced by MiSegmentDelete().

#define POOL_ALLOC_IRQL_INVALID   8

Definition at line 283 of file miarm.h.

Referenced by ExpCheckPoolIrqlLevel().

#define POOL_BILLED_PROCESS_INVALID   13

Definition at line 285 of file miarm.h.

#define POOL_BLOCK_SIZE   8
#define POOL_CORRUPTED_LIST   3

Definition at line 269 of file miarm.h.

#define POOL_ENTRIES_NOT_ALIGNED_NEXT   9

Definition at line 274 of file miarm.h.

#define POOL_ENTRIES_NOT_ALIGNED_PREVIOUS   6

Definition at line 271 of file miarm.h.

#define POOL_ENTRY_ALREADY_FREE   6

Definition at line 281 of file miarm.h.

#define POOL_ENTRY_CORRUPTED   1

Definition at line 280 of file miarm.h.

#define POOL_ENTRY_NOT_ALLOCATED   7

Definition at line 282 of file miarm.h.

#define POOL_ENTRY_NOT_FOUND   10

Definition at line 275 of file miarm.h.

#define POOL_FLAG_CHECK_DEADLOCK   0x10

Definition at line 261 of file miarm.h.

Referenced by ExFreePoolWithTag().

#define POOL_FLAG_CHECK_RESOURCES   0x4

Definition at line 259 of file miarm.h.

Referenced by ExFreePoolWithTag().

#define POOL_FLAG_CHECK_TIMERS   0x1

Definition at line 257 of file miarm.h.

Referenced by ExFreePoolWithTag().

#define POOL_FLAG_CHECK_WORKERS   0x2

Definition at line 258 of file miarm.h.

Referenced by ExFreePoolWithTag().

#define POOL_FLAG_CRASH_ON_FAILURE   0x80

Definition at line 264 of file miarm.h.

Referenced by ExAllocatePoolWithTag().

#define POOL_FLAG_DBGPRINT_ON_FAILURE   0x40

Definition at line 263 of file miarm.h.

Referenced by ExAllocatePoolWithTag().

#define POOL_FLAG_SPECIAL_POOL   0x20
#define POOL_FLAG_VERIFIER   0x8

Definition at line 260 of file miarm.h.

Referenced by ExAllocatePoolWithTag(), and ExFreePoolWithTag().

#define POOL_FREE_IRQL_INVALID   9

Definition at line 284 of file miarm.h.

Referenced by ExpCheckPoolIrqlLevel().

#define POOL_HEADER_IS_ZERO   8

Definition at line 273 of file miarm.h.

#define POOL_HEADER_NOT_ALIGNED   7

Definition at line 272 of file miarm.h.

#define POOL_HEADER_SIZE_INVALID   32

Definition at line 286 of file miarm.h.

#define POOL_LISTS_PER_PAGE   (PAGE_SIZE / POOL_BLOCK_SIZE)

Definition at line 250 of file miarm.h.

Referenced by ExAllocatePoolWithTag(), and ExInitializePoolDescriptor().

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

Definition at line 252 of file miarm.h.

Referenced by ExAllocatePoolWithTag().

#define POOL_SIZE_OR_INDEX_MISMATCH   5

Definition at line 270 of file miarm.h.

#define PT_SIZE   (PTE_COUNT * sizeof(MMPTE))

Definition at line 25 of file miarm.h.

#define SYSTEM_PD_SIZE   (PD_COUNT * PD_SIZE)

Typedef Documentation

typedef struct _MMVIEW * PMMVIEW

Enumeration Type Documentation

Enumerator
MiNonCached 
MiCached 
MiWriteCombined 
MiNotMapped 

Definition at line 387 of file miarm.h.

388 {
389  MiNonCached,
390  MiCached,
enum _MI_PFN_CACHE_ATTRIBUTE MI_PFN_CACHE_ATTRIBUTE
enum _MI_PFN_CACHE_ATTRIBUTE * PMI_PFN_CACHE_ATTRIBUTE
Enumerator
SystemPteSpace 
NonPagedPoolExpansion 
MaximumPtePoolTypes 

Definition at line 380 of file miarm.h.

381 {
enum _MMSYSTEM_PTE_POOL_TYPE MMSYSTEM_PTE_POOL_TYPE

Function Documentation

C_ASSERT ( sizeof(POOL_HEADER = =POOL_BLOCK_SIZE)
C_ASSERT ( POOL_BLOCK_SIZE  = =sizeof(LIST_ENTRY))
VOID NTAPI INIT_FUNCTION ExInitializePoolDescriptor ( IN PPOOL_DESCRIPTOR  PoolDescriptor,
IN POOL_TYPE  PoolType,
IN ULONG  PoolIndex,
IN ULONG  Threshold,
IN PVOID  PoolLock 
)

Definition at line 964 of file expool.c.

Referenced by InitializePool(), and MiInitializeSessionPool().

969 {
970  PLIST_ENTRY NextEntry, LastEntry;
971 
972  //
973  // Setup the descriptor based on the caller's request
974  //
975  PoolDescriptor->PoolType = PoolType;
976  PoolDescriptor->PoolIndex = PoolIndex;
977  PoolDescriptor->Threshold = Threshold;
978  PoolDescriptor->LockAddress = PoolLock;
979 
980  //
981  // Initialize accounting data
982  //
983  PoolDescriptor->RunningAllocs = 0;
984  PoolDescriptor->RunningDeAllocs = 0;
985  PoolDescriptor->TotalPages = 0;
986  PoolDescriptor->TotalBytes = 0;
987  PoolDescriptor->TotalBigPages = 0;
988 
989  //
990  // Nothing pending for now
991  //
992  PoolDescriptor->PendingFrees = NULL;
993  PoolDescriptor->PendingFreeDepth = 0;
994 
995  //
996  // Loop all the descriptor's allocation lists and initialize them
997  //
998  NextEntry = PoolDescriptor->ListHeads;
999  LastEntry = NextEntry + POOL_LISTS_PER_PAGE;
1000  while (NextEntry < LastEntry)
1001  {
1002  ExpInitializePoolListHead(NextEntry);
1003  NextEntry++;
1004  }
1005 
1006  //
1007  // Note that ReactOS does not support Session Pool Yet
1008  //
1010 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
VOID NTAPI ExpInitializePoolListHead(IN PLIST_ENTRY ListHead)
Definition: expool.c:104
smooth NULL
Definition: ftsmooth.c:416
IN REFCLSID IN PUNKNOWN IN POOL_TYPE PoolType
Definition: unknown.h:68
Definition: typedefs.h:117
#define POOL_LISTS_PER_PAGE
Definition: miarm.h:250
VOID NTAPI InitializePool ( IN POOL_TYPE  PoolType,
IN ULONG  Threshold 
)

Definition at line 1015 of file expool.c.

Referenced by MiBuildPagedPool(), and MiInitMachineDependent().

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

Definition at line 959 of file miarm.h.

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

960 {
961  /* Zero out the PTE */
962  ASSERT(PointerPte->u.Long != 0);
963  PointerPte->u.Long = 0;
964 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE PMMPTE MI_GET_PROTOTYPE_PTE_FOR_VPN ( IN PMMVAD  Vad,
IN ULONG_PTR  Vpn 
)

Definition at line 1376 of file miarm.h.

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

1378 {
1379  PMMPTE ProtoPte;
1380 
1381  /* Find the offset within the VAD's prototype PTEs */
1382  ProtoPte = Vad->FirstPrototypePte + (Vpn - Vad->StartingVpn);
1383  ASSERT(ProtoPte <= Vad->LastContiguousPte);
1384  return ProtoPte;
1385 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE BOOLEAN MI_IS_MAPPED_PTE ( PMMPTE  PointerPte)
Todo:
Make this reasonable code, this is UGLY!

Definition at line 876 of file miarm.h.

877 {
879  return ((PointerPte->u.Long & 0xFFFFFC01) != 0);
880 }
ULONG_PTR Long
Definition: mmtypes.h:215
union _MMPTE::@2170 u
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS ( IN PVOID  Address)

Definition at line 902 of file miarm.h.

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

903 {
904  PMMPDE PointerPde;
905 
906  /* Large pages are never paged out, always physically resident */
907  PointerPde = MiAddressToPde(Address);
908  return ((PointerPde->u.Hard.LargePage) && (PointerPde->u.Hard.Valid));
909 }
PVOID ULONG Address
Definition: oprghdlr.h:14
#define MiAddressToPde(x)
Definition: mmx86.c:20
ULONG64 Valid
Definition: mmtypes.h:150
union _MMPTE::@2170 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG64 LargePage
Definition: mmtypes.h:165
FORCEINLINE BOOLEAN MI_IS_WS_UNSAFE ( IN PEPROCESS  Process)

Definition at line 1054 of file miarm.h.

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

1055 {
1056  return (Process->Vm.Flags.AcquiredUnsafe == TRUE);
1057 }
#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
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE ( IN PMMPTE  NewPte,
IN PMMPTE  MappingPte,
IN ULONG_PTR  ProtectionMask,
IN PFN_NUMBER  PageFrameNumber 
)

Definition at line 771 of file miarm.h.

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

775 {
776  /* Set the protection and page */
777  NewPte->u.Long = MiDetermineUserGlobalPteMask(MappingPte);
778  NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
779  NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
780 }
const ULONG_PTR MmProtectToPteMask[32]
Definition: page.c:32
FORCEINLINE ULONG_PTR MiDetermineUserGlobalPteMask(IN PVOID PointerPte)
Definition: miarm.h:711
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL ( IN PMMPTE  NewPte,
IN PMMPTE  MappingPte,
IN ULONG_PTR  ProtectionMask,
IN PFN_NUMBER  PageFrameNumber 
)

Definition at line 748 of file miarm.h.

Referenced by MiInitializeWorkingSetList(), MmCreateKernelStack(), MmGrowKernelStackEx(), and MmInitSystem().

752 {
753  /* Only valid for kernel, non-session PTEs */
754  ASSERT(MappingPte > MiHighestUserPte);
755  ASSERT(!MI_IS_SESSION_PTE(MappingPte));
756  ASSERT((MappingPte < (PMMPTE)PDE_BASE) || (MappingPte > (PMMPTE)PDE_TOP));
757 
758  /* Start fresh */
759  *NewPte = ValidKernelPte;
760 
761  /* Set the protection and page */
762  NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
763  NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
764 }
MMPTE ValidKernelPte
Definition: init.c:31
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define PDE_BASE
Definition: winldr.c:20
const ULONG_PTR MmProtectToPteMask[32]
Definition: page.c:32
#define MI_IS_SESSION_PTE(Pte)
Definition: miarm.h:143
#define PDE_TOP
Definition: mm.h:32
union _MMPTE::@2170 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
PMMPTE MiHighestUserPte
Definition: mminit.c:233
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_USER ( IN PMMPTE  NewPte,
IN PMMPTE  MappingPte,
IN ULONG_PTR  ProtectionMask,
IN PFN_NUMBER  PageFrameNumber 
)

Definition at line 787 of file miarm.h.

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

791 {
792  /* Only valid for kernel, non-session PTEs */
793  ASSERT(MappingPte <= MiHighestUserPte);
794 
795  /* Start fresh */
796  NewPte->u.Long = 0;
797 
798  /* Set the protection and page */
799  NewPte->u.Hard.Valid = TRUE;
800  NewPte->u.Hard.Owner = TRUE;
801  NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
802  NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
803 }
#define TRUE
Definition: types.h:120
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
const ULONG_PTR MmProtectToPteMask[32]
Definition: page.c:32
PMMPTE MiHighestUserPte
Definition: mminit.c:233
FORCEINLINE VOID MI_MAKE_PROTOTYPE_PTE ( IN PMMPTE  NewPte,
IN PMMPTE  PointerPte 
)

Definition at line 811 of file miarm.h.

813 {
815 
816  /* Mark this as a prototype */
817  NewPte->u.Long = 0;
818  NewPte->u.Proto.Prototype = 1;
819 
820  /*
821  * Prototype PTEs are only valid in paged pool by design, this little trick
822  * lets us only use 30 bits for the adress of the PTE, as long as the area
823  * stays 1024MB At most.
824  */
825  Offset = (ULONG_PTR)PointerPte - (ULONG_PTR)MmPagedPoolStart;
826 
827  /*
828  * 7 bits go in the "low" (but we assume the bottom 2 are zero)
829  * and the other 21 bits go in the "high"
830  */
831  NewPte->u.Proto.ProtoAddressLow = (Offset & 0x1FC) >> 2;
832  NewPte->u.Proto.ProtoAddressHigh = (Offset & 0x3FFFFE00) >> 9;
833 }
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
PVOID MmPagedPoolStart
Definition: miarm.h:554
#define ULONG_PTR
Definition: config.h:101
FORCEINLINE VOID MI_MAKE_SUBSECTION_PTE ( IN PMMPTE  NewPte,
IN PVOID  Segment 
)

Definition at line 840 of file miarm.h.

842 {
844 
845  /* Mark this as a prototype */
846  NewPte->u.Long = 0;
847  NewPte->u.Subsect.Prototype = 1;
848 
849  /*
850  * Segments are only valid either in nonpaged pool. We store the 20 bit
851  * difference either from the top or bottom of nonpaged pool, giving a
852  * maximum of 128MB to each delta, meaning nonpaged pool cannot exceed
853  * 256MB.
854  */
855  if ((ULONG_PTR)Segment < ((ULONG_PTR)MmSubsectionBase + (128 * _1MB)))
856  {
858  NewPte->u.Subsect.WhichPool = PagedPool;
859  }
860  else
861  {
863  NewPte->u.Subsect.WhichPool = NonPagedPool;
864  }
865 
866  /*
867  * 4 bits go in the "low" (but we assume the bottom 3 are zero)
868  * and the other 20 bits go in the "high"
869  */
870  NewPte->u.Subsect.SubsectionAddressLow = (Offset & 0x78) >> 3;
871  NewPte->u.Subsect.SubsectionAddressHigh = (Offset & 0xFFFFF80) >> 7;
872 }
ULONG_PTR MmSubsectionBase
Definition: section.c:138
PVOID MmNonPagedPoolEnd
Definition: mminit.c:99
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_Inout_ PVOID Segment
Definition: exfuncs.h:893
#define _1MB
Definition: miarm.h:15
#define ULONG_PTR
Definition: config.h:101
FORCEINLINE VOID MI_MAKE_TRANSITION_PTE ( _Out_ PMMPTE  NewPte,
_In_ PFN_NUMBER  Page,
_In_ ULONG  Protection 
)

Definition at line 886 of file miarm.h.

Referenced by MiResolvePageFileFault().

889 {
890  NewPte->u.Long = 0;
891  NewPte->u.Trans.Transition = 1;
892  NewPte->u.Trans.Protection = Protection;
893  NewPte->u.Trans.PageFrameNumber = Page;
894 }
FORCEINLINE VOID MI_UPDATE_VALID_PTE ( IN PMMPTE  PointerPte,
IN MMPTE  TempPte 
)

Definition at line 930 of file miarm.h.

Referenced by MiFlushTbAndCapture().

932 {
933  /* Write the valid PTE */
934  ASSERT(PointerPte->u.Hard.Valid == 1);
935  ASSERT(TempPte.u.Hard.Valid == 1);
936  ASSERT(PointerPte->u.Hard.PageFrameNumber == TempPte.u.Hard.PageFrameNumber);
937  *PointerPte = TempPte;
938 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
ULONG PageFrameNumber
Definition: mmtypes.h:109
FORCEINLINE VOID MI_WRITE_INVALID_PDE ( IN PMMPDE  PointerPde,
IN MMPDE  InvalidPde 
)

Definition at line 985 of file miarm.h.

Referenced by MmArmAccessFault().

987 {
988  /* Write the invalid PDE */
989  ASSERT(InvalidPde.u.Hard.Valid == 0);
990  ASSERT(InvalidPde.u.Long != 0);
991  *PointerPde = InvalidPde;
992 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE VOID MI_WRITE_INVALID_PTE ( IN PMMPTE  PointerPte,
IN MMPTE  InvalidPte 
)

Definition at line 945 of file miarm.h.

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

947 {
948  /* Write the invalid PTE */
949  ASSERT(InvalidPte.u.Hard.Valid == 0);
950  ASSERT(InvalidPte.u.Long != 0);
951  *PointerPte = InvalidPte;
952 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE VOID MI_WRITE_VALID_PDE ( IN PMMPDE  PointerPde,
IN MMPDE  TempPde 
)

Definition at line 971 of file miarm.h.

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

973 {
974  /* Write the valid PDE */
975  ASSERT(PointerPde->u.Hard.Valid == 0);
976  ASSERT(TempPde.u.Hard.Valid == 1);
977  *PointerPde = TempPde;
978 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:77
FORCEINLINE BOOLEAN MI_WS_OWNER ( IN PEPROCESS  Process)

Definition at line 1015 of file miarm.h.

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

1016 {
1017  /* Check if this process is the owner, and that the thread owns the WS */
1018  if (PsGetCurrentThread()->OwnsProcessWorkingSetExclusive == 0)
1019  {
1020  DPRINT("Thread: %p is not an owner\n", PsGetCurrentThread());
1021  }
1022  if (KeGetCurrentThread()->ApcState.Process != &Process->Pcb)
1023  {
1024  DPRINT("Current thread %p is attached to another process %p\n", PsGetCurrentThread(), Process);
1025  }
1026  return ((KeGetCurrentThread()->ApcState.Process == &Process->Pcb) &&
1027  ((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) ||
1028  (PsGetCurrentThread()->OwnsProcessWorkingSetShared)));
1029 }
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
void DPRINT(...)
Definition: polytest.cpp:61
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1452
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define KeGetCurrentThread
Definition: hal.h:44
FORCEINLINE KIRQL MiAcquireExpansionLock ( VOID  )

Definition at line 1350 of file miarm.h.

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

1351 {
1352  KIRQL OldIrql;
1353 
1355  KeAcquireSpinLock(&MmExpansionLock, &OldIrql);
1358  return OldIrql;
1359 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
KSPIN_LOCK MmExpansionLock
Definition: session.c:32
UCHAR KIRQL
Definition: env_spec_w32.h:591
PETHREAD MiExpansionLockOwner
Definition: session.c:33
smooth NULL
Definition: ftsmooth.c:416
#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:803
#define APC_LEVEL
Definition: env_spec_w32.h:695
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 150 of file freelist.c.

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

156 {
157  PMDL Mdl;
158  PFN_NUMBER PageCount, LowPage, HighPage, SkipPages, PagesFound = 0, Page;
159  PPFN_NUMBER MdlPage, LastMdlPage;
160  KIRQL OldIrql;
161  PMMPFN Pfn1;
162  INT LookForZeroedPages;
164  DPRINT1("ARM3-DEBUG: Being called with %I64x %I64x %I64x %lx %d %lu\n", LowAddress, HighAddress, SkipBytes, TotalBytes, CacheAttribute, MdlFlags);
165 
166  //
167  // Convert the low address into a PFN
168  //
169  LowPage = (PFN_NUMBER)(LowAddress.QuadPart >> PAGE_SHIFT);
170 
171  //
172  // Convert, and normalize, the high address into a PFN
173  //
174  HighPage = (PFN_NUMBER)(HighAddress.QuadPart >> PAGE_SHIFT);
175  if (HighPage > MmHighestPhysicalPage) HighPage = MmHighestPhysicalPage;
176 
177  //
178  // Validate skipbytes and convert them into pages
179  //
180  if (BYTE_OFFSET(SkipBytes.LowPart)) return NULL;
181  SkipPages = (PFN_NUMBER)(SkipBytes.QuadPart >> PAGE_SHIFT);
182 
183  /* This isn't supported at all */
184  if (SkipPages) DPRINT1("WARNING: Caller requesting SkipBytes, MDL might be mismatched\n");
185 
186  //
187  // Now compute the number of pages the MDL will cover
188  //
190  do
191  {
192  //
193  // Try creating an MDL for these many pages
194  //
195  Mdl = MmCreateMdl(NULL, NULL, PageCount << PAGE_SHIFT);
196  if (Mdl) break;
197 
198  //
199  // This function is not required to return the amount of pages requested
200  // In fact, it can return as little as 1 page, and callers are supposed
201  // to deal with this scenario. So re-attempt the allocation with less
202  // pages than before, and see if it worked this time.
203  //
204  PageCount -= (PageCount >> 4);
205  } while (PageCount);
206 
207  //
208  // Wow, not even a single page was around!
209  //
210  if (!Mdl) return NULL;
211 
212  //
213  // This is where the page array starts....
214  //
215  MdlPage = (PPFN_NUMBER)(Mdl + 1);
216 
217  //
218  // Lock the PFN database
219  //
220  OldIrql = MiAcquirePfnLock();
221 
222  //
223  // Are we looking for any pages, without discriminating?
224  //
225  if ((LowPage == 0) && (HighPage == MmHighestPhysicalPage))
226  {
227  //
228  // Well then, let's go shopping
229  //
230  while (PagesFound < PageCount)
231  {
232  /* Grab a page */
234  MI_SET_PROCESS2("Kernel");
235 
236  /* FIXME: This check should be smarter */
237  Page = 0;
238  if (MmAvailablePages != 0)
239  Page = MiRemoveAnyPage(0);
240 
241  if (Page == 0)
242  {
243  /* This is not good... hopefully we have at least SOME pages */
244  ASSERT(PagesFound);
245  break;
246  }
247 
248  /* Grab the page entry for it */
249  Pfn1 = MiGetPfnEntry(Page);
250 
251  //
252  // Make sure it's really free
253  //
254  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
255 
256  /* Now setup the page and mark it */
257  Pfn1->u3.e2.ReferenceCount = 1;
258  Pfn1->u2.ShareCount = 1;
259  MI_SET_PFN_DELETED(Pfn1);
260  Pfn1->u4.PteFrame = 0x1FFEDCB;
261  Pfn1->u3.e1.StartOfAllocation = 1;
262  Pfn1->u3.e1.EndOfAllocation = 1;
263  Pfn1->u4.VerifierAllocation = 0;
264 
265  //
266  // Save it into the MDL
267  //
268  *MdlPage++ = MiGetPfnEntryIndex(Pfn1);
269  PagesFound++;
270  }
271  }
272  else
273  {
274  //
275  // You want specific range of pages. We'll do this in two runs
276  //
277  for (LookForZeroedPages = 1; LookForZeroedPages >= 0; LookForZeroedPages--)
278  {
279  //
280  // Scan the range you specified
281  //
282  for (Page = LowPage; Page < HighPage; Page++)
283  {
284  //
285  // Get the PFN entry for this page
286  //
287  Pfn1 = MiGetPfnEntry(Page);
288  ASSERT(Pfn1);
289 
290  //
291  // Make sure it's free and if this is our first pass, zeroed
292  //
293  if (MiIsPfnInUse(Pfn1)) continue;
294  if ((Pfn1->u3.e1.PageLocation == ZeroedPageList) != LookForZeroedPages) continue;
295 
296  /* Remove the page from the free or zero list */
297  ASSERT(Pfn1->u3.e1.ReadInProgress == 0);
299  MI_SET_PROCESS2("Kernel");
301 
302  //
303  // Sanity checks
304  //
305  ASSERT(Pfn1->u3.e2.ReferenceCount == 0);
306 
307  //
308  // Now setup the page and mark it
309  //
310  Pfn1->u3.e2.ReferenceCount = 1;
311  Pfn1->u2.ShareCount = 1;
312  MI_SET_PFN_DELETED(Pfn1);
313  Pfn1->u4.PteFrame = 0x1FFEDCB;
314  Pfn1->u3.e1.StartOfAllocation = 1;
315  Pfn1->u3.e1.EndOfAllocation = 1;
316  Pfn1->u4.VerifierAllocation = 0;
317 
318  //
319  // Save this page into the MDL
320  //
321  *MdlPage++ = Page;
322  if (++PagesFound == PageCount) break;
323  }
324 
325  //
326  // If the first pass was enough, don't keep going, otherwise, go again
327  //
328  if (PagesFound == PageCount) break;
329  }
330  }
331 
332  //
333  // Now release the PFN count
334  //
335  MiReleasePfnLock(OldIrql);
336 
337  //
338  // We might've found less pages, but not more ;-)
339  //
340  if (PagesFound != PageCount) ASSERT(PagesFound < PageCount);
341  if (!PagesFound)
342  {
343  //
344  // If we didn' tfind any pages at all, fail
345  //
346  DPRINT1("NO MDL PAGES!\n");
348  return NULL;
349  }
350 
351  //
352  // Write out how many pages we found
353  //
354  Mdl->ByteCount = (ULONG)(PagesFound << PAGE_SHIFT);
355 
356  //
357  // Terminate the MDL array if there's certain missing pages
358  //
359  if (PagesFound != PageCount) *MdlPage = LIST_HEAD;
360 
361  //
362  // Now go back and loop over all the MDL pages
363  //
364  MdlPage = (PPFN_NUMBER)(Mdl + 1);
365  LastMdlPage = MdlPage + PagesFound;
366  while (MdlPage < LastMdlPage)
367  {
368  //
369  // Check if we've reached the end
370  //
371  Page = *MdlPage++;
372  if (Page == LIST_HEAD) break;
373 
374  //
375  // Get the PFN entry for the page and check if we should zero it out
376  //
377  Pfn1 = MiGetPfnEntry(Page);
378  ASSERT(Pfn1);
379  if (Pfn1->u3.e1.PageLocation != ZeroedPageList) MiZeroPhysicalPage(Page);
381  }
382 
383  //
384  // We're done, mark the pages as locked
385  //
386  Mdl->Process = NULL;
387  Mdl->MdlFlags |= MDL_PAGES_LOCKED;
388  return Mdl;
389 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
USHORT ReadInProgress
Definition: mm.h:291
union _MMPFN::@1663 u2
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:875
union _MMPFN::@1664 u3
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
PVOID PMDL
Definition: usb.h:39
struct _MMPFN::@1664::@1670 e2
int32_t INT
Definition: typedefs.h:56
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:882
USHORT PageLocation
Definition: mm.h:295
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:327
ULONG * PPFN_NUMBER
Definition: ke.h:8
ULONG PFN_NUMBER
Definition: ke.h:8
ULONG_PTR ShareCount
Definition: mm.h:320
#define MI_SET_PROCESS2(x)
Definition: mm.h:252
smooth NULL
Definition: ftsmooth.c:416
ULONG_PTR VerifierAllocation
Definition: mm.h:350
#define MI_SET_USAGE(x)
Definition: mm.h:251
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
#define ADDRESS_AND_SIZE_TO_SPAN_PAGES(_Va, _Size)
#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:803
Definition: mm.h:303
ULONG LowPart
Definition: typedefs.h:104
LIST_HEAD(acpi_bus_event_list)
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:914
BOOLEAN NTAPI MiIsPfnInUse(IN PMMPFN Pfn1)
Definition: freelist.c:142
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:163
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
ULONG_PTR PteFrame
Definition: mm.h:348
PMDL NTAPI MmCreateMdl(IN PMDL Mdl, IN PVOID Base, IN SIZE_T Length)
Definition: mdlsup.c:352
union _MMPFN::@1667 u4
#define DPRINT1
Definition: precomp.h:8
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:934
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:112
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.

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

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 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define RtlRightChildAvl
Definition: miavl.h:45
smooth NULL
Definition: ftsmooth.c:416
ULONG_PTR EndingVpn
Definition: mmtypes.h:655
#define RtlLeftChildAvl
Definition: miavl.h:46
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.

Referenced by MiAllocateContiguousMemory().

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 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
smooth NULL
Definition: ftsmooth.c:416
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:197
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG64 Valid
Definition: mmtypes.h:150
union _MMPTE::@2170 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define PFN_FROM_PTE(v)
Definition: mm.h:88
NTSTATUS FASTCALL MiCheckPdeForPagedPool ( IN PVOID  Address)

Definition at line 454 of file pagfault.c.

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

455 {
457 }
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
NTSTATUS NTAPI MiCheckSecuredVad ( IN PMMVAD  Vad,
IN PVOID  Base,
IN SIZE_T  Size,
IN ULONG  ProtectionMask 
)

Definition at line 815 of file vadnode.c.

Referenced by MiUnmapViewOfSection(), and NtAllocateVirtualMemory().

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:711
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
return STATUS_SUCCESS
Definition: btrfs.c:2690
#define MM_DECOMMIT
Definition: miarm.h:68
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
#define MM_DELETE_CHECK
Definition: miarm.h:235
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define MM_READ_WRITE_ALLOWED
Definition: miarm.h:232
UINTN Size
Definition: acefiex.h:555
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:772
union _MMVAD_LONG::@2434 u2
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:291
#define DPRINT1
Definition: precomp.h:8
CHAR MmReadWrite[32]
Definition: vadnode.c:25
#define ULONG_PTR
Definition: config.h:101
static BYTE u3[]
Definition: msg.c:580
VOID NTAPI MiComputeColorInformation ( VOID  )

Definition at line 508 of file mminit.c.

Referenced by MmArmInitSystem().

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:1062
#define MI_MAX_SECONDARY_COLORS
Definition: mm.h:74
#define KeGetPcr()
Definition: ke.h:25
#define MI_SECONDARY_COLORS
Definition: mm.h:73
ULONG MmSecondaryColorMask
Definition: mminit.c:257
#define MI_MIN_SECONDARY_COLORS
Definition: mm.h:72
unsigned int ULONG
Definition: retypes.h:1
ULONG MmSecondaryColors
Definition: mminit.c:256
FORCEINLINE VOID MiDecrementPageTableReferences ( IN PVOID  Address)

Definition at line 1649 of file miarm.h.

Referenced by MiDeleteVirtualAddresses(), and MiUnmapLockedPagesInUserSpace().

1650 {
1651  PUSHORT RefCount;
1652 
1654 
1655  *RefCount -= 1;
1656  ASSERT(*RefCount < PTE_PER_PAGE);
1657 }
PVOID ULONG Address
Definition: oprghdlr.h:14
USHORT UsedPageTableEntries[768]
Definition: mmtypes.h:870
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MiGetPdeOffset(x)
Definition: mm.h:184
unsigned short * PUSHORT
Definition: retypes.h:2
#define PTE_PER_PAGE
Definition: mm.h:19
PMMWSL MmWorkingSetList
Definition: procsup.c:21
VOID NTAPI MiDecrementReferenceCount ( IN PMMPFN  Pfn1,
IN PFN_NUMBER  PageFrameIndex 
)

Definition at line 1222 of file pfnlist.c.

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

1224 {
1225  /* PFN lock must be held */
1227 
1228  /* Sanity checks on the page */
1229  if (PageFrameIndex > MmHighestPhysicalPage ||
1230  Pfn1 != MI_PFN_ELEMENT(PageFrameIndex) ||
1231  Pfn1->u3.e2.ReferenceCount == 0 ||
1232  Pfn1->u3.e2.ReferenceCount >= 2500)
1233  {
1234  DPRINT1("PageFrameIndex=0x%lx, MmHighestPhysicalPage=0x%lx\n", PageFrameIndex, MmHighestPhysicalPage);
1235  DPRINT1("Pfn1=%p, Element=%p, RefCount=%u\n", Pfn1, MI_PFN_ELEMENT(PageFrameIndex), Pfn1->u3.e2.ReferenceCount);
1236  ASSERT(PageFrameIndex <= MmHighestPhysicalPage);
1237  ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
1238  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
1239  ASSERT(Pfn1->u3.e2.ReferenceCount < 2500);
1240  }
1241 
1242  /* Dereference the page, bail out if it's still alive */
1243  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
1244  if (Pfn1->u3.e2.ReferenceCount) return;
1245 
1246  /* Nobody should still have reference to this page */
1247  if (Pfn1->u2.ShareCount != 0)
1248  {
1249  /* Otherwise something's really wrong */
1250  KeBugCheckEx(PFN_LIST_CORRUPT, 7, PageFrameIndex, Pfn1->u2.ShareCount, 0);
1251  }
1252 
1253  /* And it should be lying on some page list */
1254  ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
1255 
1256  /* Did someone set the delete flag? */
1257  if (MI_IS_PFN_DELETED(Pfn1))
1258  {
1259  /* Insert it into the free list, there's nothing left to do */
1260  MiInsertPageInFreeList(PageFrameIndex);
1261  return;
1262  }
1263 
1264  /* Check to see which list this page should go into */
1265  if (Pfn1->u3.e1.Modified == 1)
1266  {
1267  /* Push it into the modified page list */
1268  MiInsertPageInList(&MmModifiedPageListHead, PageFrameIndex);
1269  }
1270  else
1271  {
1272  /* Otherwise, insert this page into the standby list */
1273  ASSERT(Pfn1->u3.e1.RemovalRequested == 0);
1274  MiInsertStandbyListAtFront(PageFrameIndex);
1275  }
1276 }
VOID FASTCALL MiInsertStandbyListAtFront(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:718
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:910
signed short * PSHORT
Definition: retypes.h:6
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
VOID NTAPI MiInsertPageInList(IN PMMPFNLIST ListHead, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:778
union _MMPFN::@1664 u3
struct _MMPFN::@1664::@1670 e2
MMPFNLIST MmModifiedPageListHead
Definition: pfnlist.c:45
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:164
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1393
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:604
#define InterlockedDecrement16
Definition: interlocked.h:139
#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:94
VOID NTAPI MiDecrementShareCount ( IN PMMPFN  Pfn1,
IN PFN_NUMBER  PageFrameIndex 
)

Definition at line 1133 of file pfnlist.c.

Referenced by MiDeletePte(), MiDeleteSystemPageableVm(), MiFreeContiguousMemory(), MiProcessValidPteList(), MiProtectVirtualMemory(), MiReleaseProcessReferenceToSessionDataPage(), MiRemoveMappedPtes(), MiUnmapLockedPagesInUserSpace(), MmDeleteKernelStack(), MmDeleteProcessAddressSpace2(), MmFreeLoaderBlock(), and MmFreeSpecialPool().

1135 {
1136  PMMPTE PointerPte;
1137  MMPTE TempPte;
1138 
1139  ASSERT(PageFrameIndex > 0);
1140  ASSERT(MI_PFN_ELEMENT(PageFrameIndex) != NULL);
1141  ASSERT(Pfn1 == MI_PFN_ELEMENT(PageFrameIndex));
1142  ASSERT(MI_IS_ROS_PFN(Pfn1) == FALSE);
1143 
1144  /* Page must be in-use */
1145  if ((Pfn1->u3.e1.PageLocation != ActiveAndValid) &&
1146  (Pfn1->u3.e1.PageLocation != StandbyPageList))
1147  {
1148  /* Otherwise we have PFN corruption */
1149  KeBugCheckEx(PFN_LIST_CORRUPT,
1150  0x99,
1151  PageFrameIndex,
1152  Pfn1->u3.e1.PageLocation,
1153  0);
1154  }
1155 
1156  /* Page should at least have one reference */
1157  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
1158 
1159  /* Check if the share count is now 0 */
1160  ASSERT(Pfn1->u2.ShareCount < 0xF000000);
1161  if (!--Pfn1->u2.ShareCount)
1162  {
1163  /* Was this a prototype PTE? */
1164  if (Pfn1->u3.e1.PrototypePte)
1165  {
1166  /* Grab the PTE address and make sure it's in prototype pool */
1167  PointerPte = Pfn1->PteAddress;
1168  ASSERT((PointerPte >= (PMMPTE)MmPagedPoolStart) && (PointerPte <= (PMMPTE)MmPagedPoolEnd));
1169 
1170  /* The PTE that backs it should also be valdi */
1171  PointerPte = MiAddressToPte(PointerPte);
1172  ASSERT(PointerPte->u.Hard.Valid == 1);
1173 
1174  /* Get the original prototype PTE and turn it into a transition PTE */
1175  PointerPte = Pfn1->PteAddress;
1176  TempPte = *PointerPte;
1177  TempPte.u.Soft.Transition = 1;
1178  TempPte.u.Soft.Valid = 0;
1179  TempPte.u.Soft.Prototype = 0;
1180  TempPte.u.Soft.Protection = Pfn1->OriginalPte.u.Soft.Protection;
1181  MI_WRITE_INVALID_PTE(PointerPte, TempPte);
1182  DPRINT("Marking PTE: %p as transition (%p - %lx)\n", PointerPte, Pfn1, MiGetPfnEntryIndex(Pfn1));
1183  }
1184 
1185  /* Put the page in transition */
1186  Pfn1->u3.e1.PageLocation = TransitionPage;
1187 
1188  /* PFN lock must be held */
1190 
1191  if (Pfn1->u3.e2.ReferenceCount == 1)
1192  {
1193  /* Is there still a PFN for this page? */
1194  if (MI_IS_PFN_DELETED(Pfn1))
1195  {
1196  /* Clear the last reference */
1197  Pfn1->u3.e2.ReferenceCount = 0;
1198  ASSERT(Pfn1->OriginalPte.u.Soft.Prototype == 0);
1199 
1200  /* Mark the page temporarily as valid, we're going to make it free soon */
1201  Pfn1->u3.e1.PageLocation = ActiveAndValid;
1202 
1203  /* Bring it back into the free list */
1204  MiInsertPageInFreeList(PageFrameIndex);
1205  }
1206  else
1207  {
1208  /* PFN not yet deleted, drop a ref count */
1209  MiDecrementReferenceCount(Pfn1, PageFrameIndex);
1210  }
1211  }
1212  else
1213  {
1214  /* Otherwise, just drop the reference count */
1215  InterlockedDecrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
1216  }
1217  }
1218 }
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:910
signed short * PSHORT
Definition: retypes.h:6
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
PVOID MmPagedPoolEnd
Definition: init.c:26
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
ULONG64 Protection
Definition: mmtypes.h:88
ULONG64 Valid
Definition: mmtypes.h:150
#define MI_IS_PFN_DELETED(x)
Definition: miarm.h:164
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1393
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:604
ULONG64 Prototype
Definition: mmtypes.h:89
ULONG64 Valid
Definition: mmtypes.h:86
#define InterlockedDecrement16
Definition: interlocked.h:139
PVOID MmPagedPoolStart
Definition: miarm.h:554
union _MMPTE::@2170 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:945
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1222
ULONG64 Transition
Definition: mmtypes.h:90
#define MI_IS_ROS_PFN(x)
Definition: miarm.h:1043
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:934
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:94
VOID NTAPI MiDeleteARM3Section ( PVOID  ObjectBody)

Definition at line 3244 of file section.c.

Referenced by MmpDeleteSection().

3245 {
3247  PCONTROL_AREA ControlArea;
3248  KIRQL OldIrql;
3249 
3250  SectionObject = (PSECTION)ObjectBody;
3251 
3252  if (SectionObject->u.Flags.Based == 1)
3253  {
3254  /* Remove the node from the global section address tree */
3256  MiRemoveNode(&SectionObject->Address, &MmSectionBasedRoot);
3258  }
3259 
3260  /* Lock the PFN database */
3261  OldIrql = MiAcquirePfnLock();
3262 
3263  ASSERT(SectionObject->Segment);
3264  ASSERT(SectionObject->Segment->ControlArea);
3265 
3266  ControlArea = SectionObject->Segment->ControlArea;
3267 
3268  /* Dereference */
3269  ControlArea->NumberOfSectionReferences--;
3270  ControlArea->NumberOfUserReferences--;
3271 
3272  ASSERT(ControlArea->u.Flags.BeingDeleted == 0);
3273 
3274  /* Check it. It will delete it if there is no more reference to it */
3275  MiCheckControlArea(ControlArea, OldIrql);
3276 }
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
ULONG NumberOfSectionReferences
Definition: mmtypes.h:515
union _CONTROL_AREA::@2423 u
PSEGMENT Segment
Definition: mmtypes.h:813
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
KGUARDED_MUTEX MmSectionBasedMutex
Definition: section.c:110
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:875
struct _CONTROL_AREA * ControlArea
Definition: mmtypes.h:401
UCHAR KIRQL
Definition: env_spec_w32.h:591
struct _SECTION * PSECTION
MMSECTION_FLAGS Flags
Definition: mmtypes.h:818
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
union _SECTION::@2439 u
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:360
ULONG BeingDeleted
Definition: mmtypes.h:455
MMADDRESS_NODE Address
Definition: mmtypes.h:812
ULONG NumberOfUserReferences
Definition: mmtypes.h:519
VOID NTAPI MiCheckControlArea(IN PCONTROL_AREA ControlArea, IN KIRQL OldIrql)
Definition: section.c:728
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
MMSECTION_FLAGS Flags
Definition: mmtypes.h:523
VOID NTAPI MiDeletePte ( IN PMMPTE  PointerPte,
IN PVOID  VirtualAddress,
IN PEPROCESS  CurrentProcess,
IN PMMPTE  PrototypePte 
)

Definition at line 391 of file virtual.c.

Referenced by MiBalancerThread(), MiDeleteVirtualAddresses(), MiResolveProtoPteFault(), MiUnmapLockedPagesInUserSpace(), MmArmAccessFault(), MmDeleteProcessAddressSpace(), and MmFreeMemoryArea().

395 {
396  PMMPFN Pfn1;
397  MMPTE TempPte;
398  PFN_NUMBER PageFrameIndex;
399  PMMPDE PointerPde;
400 
401  /* PFN lock must be held */
403 
404  /* Capture the PTE */
405  TempPte = *PointerPte;
406 
407  /* See if the PTE is valid */
408  if (TempPte.u.Hard.Valid == 0)
409  {
410  /* Prototype and paged out PTEs not supported yet */
411  ASSERT(TempPte.u.Soft.Prototype == 0);
412  ASSERT((TempPte.u.Soft.PageFileHigh == 0) || (TempPte.u.Soft.Transition == 1));
413 
414  if (TempPte.u.Soft.Transition)
415  {
416  /* Get the PFN entry */
417  PageFrameIndex = PFN_FROM_PTE(&TempPte);
418  Pfn1 = MiGetPfnEntry(PageFrameIndex);
419 
420  DPRINT("Pte %p is transitional!\n", PointerPte);
421 
422  /* Make sure the saved PTE address is valid */
423  ASSERT((PMMPTE)((ULONG_PTR)Pfn1->PteAddress & ~0x1) == PointerPte);
424 
425  /* Destroy the PTE */
426  MI_ERASE_PTE(PointerPte);
427 
428  /* Drop the reference on the page table. */
430 
431  ASSERT(Pfn1->u3.e1.PrototypePte == 0);
432 
433  /* Make the page free. For prototypes, it will be made free when deleting the section object */
434  if (Pfn1->u3.e2.ReferenceCount == 0)
435  {
436  /* And it should be in standby or modified list */
438 
439  /* Unlink it and set its reference count to one */
440  MiUnlinkPageFromList(Pfn1);
441  Pfn1->u3.e2.ReferenceCount++;
442 
443  /* This will put it back in free list and clean properly up */
444  MI_SET_PFN_DELETED(Pfn1);
445  MiDecrementReferenceCount(Pfn1, PageFrameIndex);
446  }
447  return;
448  }
449  }
450 
451  /* Get the PFN entry */
452  PageFrameIndex = PFN_FROM_PTE(&TempPte);
453  Pfn1 = MiGetPfnEntry(PageFrameIndex);
454 
455  /* Check if this is a valid, prototype PTE */
456  if (Pfn1->u3.e1.PrototypePte == 1)
457  {
458  /* Get the PDE and make sure it's faulted in */
459  PointerPde = MiPteToPde(PointerPte);
460  if (PointerPde->u.Hard.Valid == 0)
461  {
462 #if (_MI_PAGING_LEVELS == 2)
463  /* Could be paged pool access from a new process -- synchronize the page directories */
465  {
466 #endif
467  /* The PDE must be valid at this point */
468  KeBugCheckEx(MEMORY_MANAGEMENT,
469  0x61940,
470  (ULONG_PTR)PointerPte,
471  PointerPte->u.Long,
473  }
474 #if (_MI_PAGING_LEVELS == 2)
475  }
476 #endif
477  /* Drop the share count on the page table */
478  PointerPde = MiPteToPde(PointerPte);
480  PointerPde->u.Hard.PageFrameNumber);
481 
482  /* Drop the share count */
483  MiDecrementShareCount(Pfn1, PageFrameIndex);
484 
485  /* Either a fork, or this is the shared user data page */
486  if ((PointerPte <= MiHighestUserPte) && (PrototypePte != Pfn1->PteAddress))
487  {
488  /* If it's not the shared user page, then crash, since there's no fork() yet */
490  (MmHighestUserAddress <= (PVOID)USER_SHARED_DATA))
491  {
492  /* Must be some sort of memory corruption */
493  KeBugCheckEx(MEMORY_MANAGEMENT,
494  0x400,
495  (ULONG_PTR)PointerPte,
497  (ULONG_PTR)Pfn1->PteAddress);
498  }
499  }
500 
501  /* Erase it */
502  MI_ERASE_PTE(PointerPte);
503  }
504  else
505  {
506  /* Make sure the saved PTE address is valid */
507  if ((PMMPTE)((ULONG_PTR)Pfn1->PteAddress & ~0x1) != PointerPte)
508  {
509  /* The PFN entry is illegal, or invalid */
510  KeBugCheckEx(MEMORY_MANAGEMENT,
511  0x401,
512  (ULONG_PTR)PointerPte,
513  PointerPte->u.Long,
514  (ULONG_PTR)Pfn1->PteAddress);
515  }
516 
517  /* Erase the PTE */
518  MI_ERASE_PTE(PointerPte);
519 
520  /* There should only be 1 shared reference count */
521  ASSERT(Pfn1->u2.ShareCount == 1);
522 
523  /* Drop the reference on the page table. */
525 
526  /* Mark the PFN for deletion and dereference what should be the last ref */
527  MI_SET_PFN_DELETED(Pfn1);
528  MiDecrementShareCount(Pfn1, PageFrameIndex);
529 
530  /* We should eventually do this */
531  //CurrentProcess->NumberOfPrivatePages--;
532  }
533 
534  /* Flush the TLB */
536 }
DWORD *typedef PVOID
Definition: winlogon.h:52
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:959
MMPTE PrototypePte
Definition: init.c:42
#define MI_ASSERT_PFN_LOCK_HELD()
Definition: mm.h:910
VOID NTAPI MiUnlinkPageFromList(IN PMMPFN Pfn)
Definition: pfnlist.c:264
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
union _MMPFN::@1663 u2
union _MMPFN::@1664 u3
NTSTATUS FASTCALL MiCheckPdeForPagedPool(IN PVOID Address)
Definition: pagfault.c:454
struct _MMPFN::@1664::@1670 e2
USHORT PageLocation
Definition: mm.h:295
uint32_t ULONG_PTR
Definition: typedefs.h:63
USHORT PrototypePte
Definition: mm.h:293
MMPFNENTRY e1
Definition: mm.h:327
ULONG PFN_NUMBER
Definition: ke.h:8
ULONG_PTR ShareCount
Definition: mm.h:320
#define USER_SHARED_DATA
Definition: pstypes.h:51
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1133
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
ULONG64 Valid
Definition: mmtypes.h:150
#define PAGE_ALIGN(Va)
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1222
ULONG64 PageFileHigh
Definition: mmtypes.h:93
Definition: mm.h:303
ULONG64 Prototype
Definition: mmtypes.h:89
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3773
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:914
union _MMPTE::@2170 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:163
#define MiPteToPde(_Pte)
Definition: mm.h:232
ULONG_PTR PteFrame
Definition: mm.h:348
ULONG64 Transition
Definition: mmtypes.h:90
PMMPTE PteAddress
Definition: mm.h:316
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
union _MMPFN::@1667 u4
PVOID MmHighestUserAddress
Definition: rtlcompat.c:29
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
PMMPTE MiHighestUserPte
Definition: mminit.c:233
#define PFN_FROM_PTE(v)
Definition: mm.h:88
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:94
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:322
PFN_COUNT NTAPI MiDeleteSystemPageableVm ( IN PMMPTE  PointerPte,
IN PFN_NUMBER  PageCount,
IN ULONG  Flags,
OUT PPFN_NUMBER  ValidPages 
)

Definition at line 297 of file virtual.c.

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

301 {
302  PFN_COUNT ActualPages = 0;
303  PETHREAD CurrentThread = PsGetCurrentThread();
304  PMMPFN Pfn1, Pfn2;
305  PFN_NUMBER PageFrameIndex, PageTableIndex;
306  KIRQL OldIrql;
308 
309  /* Lock the system working set */
310  MiLockWorkingSet(CurrentThread, &MmSystemCacheWs);
311 
312  /* Loop all pages */
313  while (PageCount)
314  {
315  /* Make sure there's some data about the page */
316  if (PointerPte->u.Long)
317  {
318  /* As always, only handle current ARM3 scenarios */
319  ASSERT(PointerPte->u.Soft.Prototype == 0);
320  ASSERT(PointerPte->u.Soft.Transition == 0);
321 
322  /* Normally this is one possibility -- freeing a valid page */
323  if (PointerPte->u.Hard.Valid)
324  {
325  /* Get the page PFN */
326  PageFrameIndex = PFN_FROM_PTE(PointerPte);
327  Pfn1 = MiGetPfnEntry(PageFrameIndex);
328 
329  /* Should not have any working set data yet */
330  ASSERT(Pfn1->u1.WsIndex == 0);
331 
332  /* Actual valid, legitimate, pages */
333  if (ValidPages) (*ValidPages)++;
334 
335  /* Get the page table entry */
336  PageTableIndex = Pfn1->u4.PteFrame;
337  Pfn2 = MiGetPfnEntry(PageTableIndex);
338 
339  /* Lock the PFN database */
340  OldIrql = MiAcquirePfnLock();
341 
342  /* Delete it the page */
343  MI_SET_PFN_DELETED(Pfn1);
344  MiDecrementShareCount(Pfn1, PageFrameIndex);
345 
346  /* Decrement the page table too */
347  MiDecrementShareCount(Pfn2, PageTableIndex);
348 
349  /* Release the PFN database */
350  MiReleasePfnLock(OldIrql);
351 
352  /* Destroy the PTE */
353  MI_ERASE_PTE(PointerPte);
354  }
355  else
356  {
357  /*
358  * The only other ARM3 possibility is a demand zero page, which would
359  * mean freeing some of the paged pool pages that haven't even been
360  * touched yet, as part of a larger allocation.
361  *
362  * Right now, we shouldn't expect any page file information in the PTE
363  */
364  ASSERT(PointerPte->u.Soft.PageFileHigh == 0);
365 
366  /* Destroy the PTE */
367  MI_ERASE_PTE(PointerPte);
368  }
369 
370  /* Actual legitimate pages */
371  ActualPages++;
372  }
373 
374  /* Keep going */
375  PointerPte++;
376  PageCount--;
377  }
378 
379  /* Release the working set */
380  MiUnlockWorkingSet(CurrentThread, &MmSystemCacheWs);
381 
382  /* Flush the entire TLB */
384 
385  /* Done */
386  return ActualPages;
387 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:959
#define TRUE
Definition: types.h:120
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
ULONG PFN_COUNT
Definition: mmtypes.h:102
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:875
union _MMPFN::@1662 u1
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:882
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PFN_NUMBER
Definition: ke.h:8
MMSUPPORT MmSystemCacheWs
Definition: init.c:55
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1133
FORCEINLINE VOID MiUnlockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1249
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:413
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: mm.h:303
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:914
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:163
ULONG_PTR PteFrame
Definition: mm.h:348
union _MMPFN::@1667 u4
ULONG WsIndex
Definition: mm.h:308
FORCEINLINE VOID MiLockWorkingSet(IN PETHREAD Thread, IN PMMSUPPORT WorkingSet)
Definition: miarm.h:1205
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PFN_FROM_PTE(v)
Definition: mm.h:88
VOID NTAPI MiDeleteVirtualAddresses ( IN ULONG_PTR  Va,
IN ULONG_PTR  EndingAddress,
IN PMMVAD  Vad 
)

Definition at line 540 of file virtual.c.

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

543 {
544  PMMPTE PointerPte, PrototypePte, LastPrototypePte;
545  PMMPDE PointerPde;
546  MMPTE TempPte;
548  KIRQL OldIrql;
549  BOOLEAN AddressGap = FALSE;
550  PSUBSECTION Subsection;
551 
552  /* Get out if this is a fake VAD, RosMm will free the marea pages */
553  if ((Vad) && (Vad->u.VadFlags.Spare == 1)) return;
554 
555  /* Grab the process and PTE/PDE for the address being deleted */
556  CurrentProcess = PsGetCurrentProcess();
557  PointerPde = MiAddressToPde(Va);
558  PointerPte = MiAddressToPte(Va);
559 
560  /* Check if this is a section VAD or a VM VAD */
561  if (!(Vad) || (Vad->u.VadFlags.PrivateMemory) || !(Vad->FirstPrototypePte))
562  {
563  /* Don't worry about prototypes */
564  PrototypePte = LastPrototypePte = NULL;
565  }
566  else
567  {
568  /* Get the prototype PTE */
569  PrototypePte = Vad->FirstPrototypePte;
570  LastPrototypePte = Vad->FirstPrototypePte + 1;
571  }
572 
573  /* In all cases, we don't support fork() yet */
574  ASSERT(CurrentProcess->CloneRoot == NULL);
575 
576  /* Loop the PTE for each VA */
577  while (TRUE)
578  {
579  /* First keep going until we find a valid PDE */
580  while (!PointerPde->u.Long)
581  {
582  /* There are gaps in the address space */
583  AddressGap = TRUE;
584 
585  /* Still no valid PDE, try the next 4MB (or whatever) */
586  PointerPde++;
587 
588  /* Update the PTE on this new boundary */
589  PointerPte = MiPteToAddress(PointerPde);
590 
591  /* Check if all the PDEs are invalid, so there's nothing to free */
592  Va = (ULONG_PTR)MiPteToAddress(PointerPte);
593  if (Va > EndingAddress) return;
594  }
595 
596  /* Now check if the PDE is mapped in */
597  if (!PointerPde->u.Hard.Valid)
598  {
599  /* It isn't, so map it in */
600  PointerPte = MiPteToAddress(PointerPde);
601  MiMakeSystemAddressValid(PointerPte, CurrentProcess);
602  }
603 
604  /* Now we should have a valid PDE, mapped in, and still have some VA */
605  ASSERT(PointerPde->u.Hard.Valid == 1);
606  ASSERT(Va <= EndingAddress);
607 
608  /* Check if this is a section VAD with gaps in it */
609  if ((AddressGap) && (LastPrototypePte))
610  {
611  /* We need to skip to the next correct prototype PTE */
612  PrototypePte = MI_GET_PROTOTYPE_PTE_FOR_VPN(Vad, Va >> PAGE_SHIFT);
613 
614  /* And we need the subsection to skip to the next last prototype PTE */
615  Subsection = MiLocateSubsection(Vad, Va >> PAGE_SHIFT);
616  if (Subsection)
617  {
618  /* Found it! */
619  LastPrototypePte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
620  }
621  else
622  {
623  /* No more subsections, we are done with prototype PTEs */
624  PrototypePte = NULL;
625  }
626  }
627 
628  /* Lock the PFN Database while we delete the PTEs */
629  OldIrql = MiAcquirePfnLock();
630  do
631  {
632  /* Capture the PDE and make sure it exists */
633  TempPte = *PointerPte;
634  if (TempPte.u.Long)
635  {
637 
638  /* Check if the PTE is actually mapped in */
639  if (MI_IS_MAPPED_PTE(&TempPte))
640  {
641  /* Are we dealing with section VAD? */
642  if ((LastPrototypePte) && (PrototypePte > LastPrototypePte))
643  {
644  /* We need to skip to the next correct prototype PTE */
645  PrototypePte = MI_GET_PROTOTYPE_PTE_FOR_VPN(Vad, Va >> PAGE_SHIFT);
646 
647  /* And we need the subsection to skip to the next last prototype PTE */
648  Subsection = MiLocateSubsection(Vad, Va >> PAGE_SHIFT);
649  if (Subsection)
650  {
651  /* Found it! */
652  LastPrototypePte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
653  }
654  else
655  {
656  /* No more subsections, we are done with prototype PTEs */
657  PrototypePte = NULL;
658  }
659  }
660 
661  /* Check for prototype PTE */
662  if ((TempPte.u.Hard.Valid == 0) &&
663  (TempPte.u.Soft.Prototype == 1))
664  {
665  /* Just nuke it */
666  MI_ERASE_PTE(PointerPte);
667  }
668  else
669  {
670  /* Delete the PTE proper */
671  MiDeletePte(PointerPte,
672  (PVOID)Va,
673  CurrentProcess,
674  PrototypePte);
675  }
676  }
677  else
678  {
679  /* The PTE was never mapped, just nuke it here */
680  MI_ERASE_PTE(PointerPte);
681  }
682  }
683 
684  /* Update the address and PTE for it */
685  Va += PAGE_SIZE;
686  PointerPte++;
687  PrototypePte++;
688 
689  /* Making sure the PDE is still valid */
690  ASSERT(PointerPde->u.Hard.Valid == 1);
691  }
692  while ((Va & (PDE_MAPPED_VA - 1)) && (Va <= EndingAddress));
693 
694  /* The PDE should still be valid at this point */
695  ASSERT(PointerPde->u.Hard.Valid == 1);
696 
697  /* Check remaining PTE count (go back 1 page due to above loop) */
698  if (MiQueryPageTableReferences((PVOID)(Va - PAGE_SIZE)) == 0)
699  {
700  if (PointerPde->u.Long != 0)
701  {
702  /* Delete the PTE proper */
703  MiDeletePte(PointerPde,
704  MiPteToAddress(PointerPde),
705  CurrentProcess,
706  NULL);
707  }
708  }
709 
710  /* Release the lock and get out if we're done */
711  MiReleasePfnLock(OldIrql);
712  if (Va > EndingAddress) return;
713 
714  /* Otherwise, we exited because we hit a new PDE boundary, so start over */
715  PointerPde = MiAddressToPde(Va);
716  AddressGap = FALSE;
717  }
718 }
DWORD *typedef PVOID
Definition: winlogon.h:52
ULONG NTAPI MiMakeSystemAddressValid(IN PVOID PageTableVirtualAddress, IN PEPROCESS CurrentProcess)
Definition: virtual.c:205
FORCEINLINE VOID MI_ERASE_PTE(IN PMMPTE PointerPte)
Definition: miarm.h:959
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
MMPTE PrototypePte
Definition: init.c:42
#define TRUE
Definition: types.h:120
#define MiAddressToPde(x)
Definition: mmx86.c:20
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:875
FORCEINLINE USHORT MiQueryPageTableReferences(IN PVOID Address)
Definition: miarm.h:1661
PVOID CloneRoot
Definition: pstypes.h:1230
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:882
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define FALSE
Definition: types.h:117
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:197
#define PDE_MAPPED_VA
Definition: miarm.h:22
unsigned char BOOLEAN
FORCEINLINE VOID MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:1649
ULONG CurrentProcess
Definition: shell.c:125
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
ULONG64 Prototype
Definition: mmtypes.h:89
#define PAGE_SIZE
Definition: env_spec_w32.h:49
ULONG_PTR Long
Definition: mmtypes.h:215
union _MMPTE::@2170 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
PSUBSECTION NTAPI MiLocateSubsection(IN PMMVAD Vad, IN ULONG_PTR Vpn)
Definition: section.c:570
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
VOID NTAPI MiDeletePte(IN PMMPTE PointerPte, IN PVOID VirtualAddress, IN PEPROCESS CurrentProcess, IN PMMPTE PrototypePte)
Definition: virtual.c:391
FORCEINLINE BOOLEAN MI_IS_MAPPED_PTE(PMMPTE PointerPte)
Definition: mm.h:287
#define ULONG_PTR
Definition: config.h:101
PMMPTE SubsectionBase
Definition: mmtypes.h:571
FORCEINLINE PMMPTE MI_GET_PROTOTYPE_PTE_FOR_VPN(IN PMMVAD Vad, IN ULONG_PTR Vpn)
Definition: miarm.h:1376
ULONG PtesInSubsection
Definition: mmtypes.h:573
FORCEINLINE VOID MiDereferencePfnAndDropLockCount ( IN PMMPFN  Pfn1)

Definition at line 1434 of file miarm.h.

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

1435 {
1436  USHORT RefCount, OldRefCount;
1437  PFN_NUMBER PageFrameIndex;
1438 
1439  /* Loop while we decrement the page successfully */
1440  do
1441  {
1442  /* There should be at least one reference */
1443  OldRefCount = Pfn1->u3.e2.ReferenceCount;
1444  ASSERT(OldRefCount != 0);
1445 
1446  /* Are we the last one */
1447  if (OldRefCount == 1)
1448  {
1449  /* The page shoudln't be shared not active at this point */
1450  ASSERT(Pfn1->u3.e2.ReferenceCount == 1);
1451  ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
1452  ASSERT(Pfn1->u2.ShareCount == 0);
1453 
1454  /* Is it a prototype PTE? */
1455  if ((Pfn1->u3.e1.PrototypePte == 1) &&
1456  (Pfn1->OriginalPte.u.Soft.Prototype == 1))
1457  {
1458  /* FIXME: We should return commit */
1459  DPRINT1("Not returning commit for prototype PTE\n");
1460  }
1461 
1462  /* Update the counter, and drop a reference the long way */
1464  PageFrameIndex = MiGetPfnEntryIndex(Pfn1);
1465  MiDecrementReferenceCount(Pfn1, PageFrameIndex);
1466  return;
1467  }
1468 
1469  /* Drop a reference the short way, and that's it */
1470  RefCount = InterlockedCompareExchange16((PSHORT)&Pfn1->u3.e2.ReferenceCount,
1471  OldRefCount - 1,
1472  OldRefCount);
1473  ASSERT(RefCount != 0);
1474  } while (OldRefCount != RefCount);
1475 
1476  /* If we got here, there should be more than one reference */
1477  ASSERT(RefCount > 1);
1478  if (RefCount == 2)
1479  {
1480  /* Is it still being shared? */
1481  if (Pfn1->u2.ShareCount >= 1)
1482  {
1483  /* Then it should be valid */
1484  ASSERT(Pfn1->u3.e1.PageLocation == ActiveAndValid);
1485 
1486  /* Is it a prototype PTE? */
1487  if ((Pfn1->u3.e1.PrototypePte == 1) &&
1488  (Pfn1->OriginalPte.u.Soft.Prototype == 1))
1489  {
1490  /* We don't handle ethis */
1491  ASSERT(FALSE);
1492  }
1493 
1494  /* Update the counter */
1496  }
1497  }
1498 }
signed short * PSHORT
Definition: retypes.h:6
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
SIZE_T MmSystemLockPagesCount
Definition: mdlsup.c:22
ULONG PFN_NUMBER
Definition: ke.h:8
#define FALSE
Definition: types.h:117
VOID NTAPI MiDecrementReferenceCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1222
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:934
#define InterlockedDecrementSizeT(a)
Definition: interlocked.h:153
FORCEINLINE ULONG_PTR MiDetermineUserGlobalPteMask ( IN PVOID  PointerPte)

Definition at line 711 of file miarm.h.

Referenced by MI_MAKE_HARDWARE_PTE(), and MiResolveTransitionFault().

712 {
713  MMPTE TempPte;
714 
715  /* Start fresh */
716  TempPte.u.Long = 0;
717 
718  /* Make it valid and accessed */
719  TempPte.u.Hard.Valid = TRUE;
720  MI_MAKE_ACCESSED_PAGE(&TempPte);
721 
722  /* Is this for user-mode? */
723  if (
724 #if (_MI_PAGING_LEVELS == 4)
725  MiIsUserPxe(PointerPte) ||
726 #endif
727 #if (_MI_PAGING_LEVELS >= 3)
728  MiIsUserPpe(PointerPte) ||
729 #endif
730  MiIsUserPde(PointerPte) ||
731  MiIsUserPte(PointerPte))
732  {
733  /* Set the owner bit */
734  MI_MAKE_OWNER_PAGE(&TempPte);
735  }
736 
737  /* FIXME: We should also set the global bit */
738 
739  /* Return the protection */
740  return TempPte.u.Long;
741 }
#define _MI_PAGING_LEVELS
Definition: mm.h:6
#define TRUE
Definition: types.h:120
#define MI_MAKE_ACCESSED_PAGE(x)
Definition: mm.h:96
#define MI_MAKE_OWNER_PAGE(x)
Definition: mm.h:109
FORCEINLINE BOOLEAN MiIsUserPde(PVOID Address)
Definition: miarm.h:692
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
FORCEINLINE BOOLEAN MiIsUserPte(PVOID Address)
Definition: miarm.h:700
ULONG_PTR Long
Definition: mmtypes.h:215
union _MMPTE::@2170 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
FORCEINLINE VOID MiDropLockCount ( IN PMMPFN  Pfn1)

Definition at line 1404 of file miarm.h.

Referenced by MiResolveTransitionFault().

1405 {
1406  /* This page shouldn't be locked, but it should be valid */
1407  ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
1408  ASSERT(Pfn1->u2.ShareCount == 0);
1409 
1410  /* Is this the last reference to the page */
1411  if (Pfn1->u3.e2.ReferenceCount == 1)
1412  {
1413  /* It better not be valid */
1414  ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
1415 
1416  /* Is it a prototype PTE? */
1417  if ((Pfn1->u3.e1.PrototypePte == 1) &&
1418  (Pfn1->OriginalPte.u.Soft.Prototype == 1))
1419  {
1420  /* FIXME: We should return commit */
1421  DPRINT1("Not returning commit for prototype PTE\n");
1422  }
1423 
1424  /* Update the counter */
1426  }
1427 }
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
SIZE_T MmSystemLockPagesCount
Definition: mdlsup.c:22
#define DPRINT1
Definition: precomp.h:8
#define InterlockedDecrementSizeT(a)
Definition: interlocked.h:153
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.

Referenced by MiFindContiguousMemory().

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  //
112  OldIrql = MiAcquirePfnLock();
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  //
167  MiReleasePfnLock(OldIrql);
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  //
199  MiReleasePfnLock(OldIrql);
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 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define TRUE
Definition: types.h:120
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
union _MMPFN::@1663 u2
PFN_NUMBER PageCount
Definition: miarm.h:398
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:875
union _MMPFN::@1664 u3
PHYSICAL_MEMORY_RUN Run[1]
Definition: miarm.h:405
struct _MMPFN::@1664::@1670 e2
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:882
USHORT PageLocation
Definition: mm.h:295
#define PAGED_CODE()
Definition: video.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:63
USHORT PrototypePte
Definition: mm.h:293
UCHAR KIRQL
Definition: env_spec_w32.h:591
MMPFNENTRY e1
Definition: mm.h:327
GLenum GLclampf GLint i
Definition: glfuncs.h:14
ULONG PFN_NUMBER
Definition: ke.h:8
ULONG_PTR ShareCount
Definition: mm.h:320
PFN_NUMBER BasePage
Definition: miarm.h:397
#define MI_SET_PROCESS2(x)
Definition: mm.h:252
#define KeLeaveGuardedRegion()
Definition: ke_x.h:63
ULONG_PTR VerifierAllocation
Definition: mm.h:350
#define MI_SET_USAGE(x)
Definition: mm.h:251
#define ULL(a, b)
Definition: format_msg.c:27
PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock
Definition: init.c:45
#define KeEnterGuardedRegion()
Definition: ke_x.h:34
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1393
VOID UINTN Length
Definition: acefiex.h:744
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: mm.h:303
PMMPTE PteAddress
Definition: mm.h:316
union _MMPFN::@1667 u4
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN NTAPI MiIsPfnInUse(IN PMMPFN Pfn1)
Definition: freelist.c:142
static BYTE u3[]
Definition: msg.c:580
VOID NTAPI MiUnlinkFreeOrZeroedPage(IN PMMPFN Entry)
Definition: pfnlist.c:137
NTSTATUS NTAPI MiFindEmptyAddressRangeDownBasedTree ( IN SIZE_T  Length,
IN ULONG_PTR  BoundaryAddress,
IN ULONG_PTR  Alignment,
IN PMM_AVL_TABLE  Table,
OUT PULONG_PTR  Base 
)

Definition at line 713 of file vadnode.c.

Referenced by MmCreateArm3Section().

718 {
719  PMMADDRESS_NODE Node, LowestNode;
720  ULONG_PTR LowVpn, BestVpn;
721 
722  /* Sanity checks */
724  ASSERT(BoundaryAddress);
725  ASSERT(BoundaryAddress <= ((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1));
726 
727  /* Compute page length, make sure the boundary address is valid */
729  if ((BoundaryAddress + 1) < Length) return STATUS_NO_MEMORY;
730 
731  /* Check if the table is empty */
732  BestVpn = ROUND_DOWN(BoundaryAddress + 1 - Length, Alignment);
733  if (Table->NumberGenericTableElements == 0)
734  {
735  /* Tree is empty, the candidate address is already the best one */
736  *Base = BestVpn;
737  return STATUS_SUCCESS;
738  }
739 
740  /* Go to the right-most node which should be the biggest address */
741  Node = Table->BalancedRoot.RightChild;
742  while (RtlRightChildAvl(Node)) Node = RtlRightChildAvl(Node);
743 
744  /* Check if we can fit in here */
745  LowVpn = ROUND_UP(Node->EndingVpn + 1, Alignment);
746  if ((LowVpn < BoundaryAddress) && (Length <= (BoundaryAddress - LowVpn)))
747  {
748 #if (NTDDI_VERSION >= NTDDI_VISTA)
749  /* Return the address. */
750  *Base = BestVpn;
751 #else
752  /* Note: this is a compatibility hack that mimics a bug in the 2k3
753  kernel. It will can waste up to Alignment bytes of memory above
754  the allocation. This bug was fixed in Windows Vista */
755  *Base = ROUND_DOWN(BoundaryAddress - Length, Alignment);
756 #endif
757  return STATUS_SUCCESS;
758  }
759 
760  /* Now loop the Vad nodes */
761  do
762  {
763  /* Break out if we've reached the last node */
764  LowestNode = MiGetPreviousNode(Node);
765  if (!LowestNode) break;
766 
767  /* Check if this node could contain the requested address */
768  LowVpn = ROUND_UP(LowestNode->EndingVpn + 1, Alignment);
769  if ((LowestNode->EndingVpn < BestVpn) &&
770  (LowVpn < Node->StartingVpn) &&
771  (Length <= (Node->StartingVpn - LowVpn)))
772  {
773  /* Check if we need to take BoundaryAddress into account */
774  if (BoundaryAddress < Node->StartingVpn)
775  {
776  /* Return the optimal VPN address */
777  *Base = BestVpn;
778  return STATUS_SUCCESS;
779  }
780  else
781  {
782  /* The upper margin is given by the Node's starting address */
784  return STATUS_SUCCESS;
785  }
786  }
787 
788  /* Move to the next node */
789  Node = LowestNode;
790  } while (TRUE);
791 
792  /* Check if there's enough space before the lowest Vad */
794  ((Node->StartingVpn - (ULONG_PTR)MI_LOWEST_VAD_ADDRESS) >= Length))
795  {
796  /* Check if it fits in perfectly */
797  if (BoundaryAddress < Node->StartingVpn)
798  {
799  /* Return the optimal VPN address */
800  *Base = BestVpn;
801  return STATUS_SUCCESS;
802  }
803 
804  /* Return an aligned base address within this node */
806  return STATUS_SUCCESS;
807  }
808 
809  /* No address space left at all */
810  return STATUS_NO_MEMORY;
811 }
#define TRUE
Definition: types.h:120
MM_AVL_TABLE MmSectionBasedRoot
Definition: section.c:109
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MI_LOWEST_VAD_ADDRESS
Definition: miarm.h:11
return STATUS_SUCCESS
Definition: btrfs.c:2690
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
#define RtlRightChildAvl
Definition: miavl.h:45
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG_PTR StartingVpn
Definition: mmtypes.h:654
ULONG_PTR EndingVpn
Definition: mmtypes.h:655
VOID UINTN Length
Definition: acefiex.h:744
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:30
#define ROUND_TO_PAGES(Size)
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:42
PMMADDRESS_NODE NTAPI MiGetPreviousNode(IN PMMADDRESS_NODE Node)
Definition: vadnode.c:431
union gl_dlist_node Node
Definition: dlist.c:302
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 
)

Definition at line 597 of file vadnode.c.

Referenced by MiInsertVadEx(), and MmFindGap().

603 {
604  PMMADDRESS_NODE Node, OldNode = NULL, Child;
605  ULONG_PTR LowVpn, HighVpn, AlignmentVpn;
606  PFN_NUMBER PageCount;
607 
608  /* Sanity checks */
609  ASSERT(BoundaryAddress);
610  ASSERT(BoundaryAddress <= ((ULONG_PTR)MM_HIGHEST_VAD_ADDRESS));
611  ASSERT((Alignment & (PAGE_SIZE - 1)) == 0);
612 
613  /* Calculate page numbers for the length and alignment */
615  PageCount = Length >> PAGE_SHIFT;
616  AlignmentVpn = Alignment / PAGE_SIZE;
617 
618  /* Check for kernel mode table (memory areas) */
619  if (Table->Unused == 1)
620  {
621  LowVpn = ALIGN_UP_BY((ULONG_PTR)MmSystemRangeStart >> PAGE_SHIFT, AlignmentVpn);
622  }
623  else
624  {
626  }
627 
628  /* Check if there is enough space below the boundary */
629  if ((LowVpn + Length) > (BoundaryAddress + 1))
630  {
631  return TableFoundNode;
632  }
633 
634  /* Check if the table is empty */
635  if (Table->NumberGenericTableElements == 0)
636  {
637  /* Tree is empty, the candidate address is already the best one */
638  *Base = ALIGN_DOWN_BY(BoundaryAddress + 1 - Length, Alignment);
639  return TableEmptyTree;
640  }
641 
642  /* Calculate the initial upper margin */
643  HighVpn = (BoundaryAddress + 1) >> PAGE_SHIFT;
644 
645  /* Starting from the root, follow the right children until we found a node
646  that ends above the boundary */
647  Node = RtlRightChildAvl(&Table->BalancedRoot);
648  while ((Node->EndingVpn < HighVpn) &&
649  ((Child = RtlRightChildAvl(Node)) != NULL)) Node = Child;
650 
651  /* Now loop the Vad nodes */
652  while (Node)
653  {
654  /* Calculate the lower margin */
655  LowVpn = ALIGN_UP_BY(Node->EndingVpn + 1, AlignmentVpn);
656 
657  /* Check if the current bounds are suitable */
658  if ((HighVpn > LowVpn) && ((HighVpn - LowVpn) >= PageCount))
659  {
660  /* There is enough space to add our node */
661  LowVpn = ALIGN_DOWN_BY(HighVpn - PageCount, AlignmentVpn);
662  *Base = LowVpn << PAGE_SHIFT;
663 
664  /* Can we use the current node as parent? */
665  if (!RtlRightChildAvl(Node))
666  {
667  /* Node has no right child, so use it as parent */
668  *Parent = Node;
669  return TableInsertAsRight;
670  }
671  else
672  {
673  /* Node has a right child. This means we must have already
674  moved one node left from the right-most node we started
675  with, thus we already have an OldNode! */
676  ASSERT(OldNode != NULL);
677 
678  /* The node we had before is the most left grandchild of
679  that right child, use it as parent. */
680  ASSERT(RtlLeftChildAvl(OldNode) == NULL);
681  *Parent = OldNode;
682  return TableInsertAsLeft;
683  }
684  }
685 
686  /* Update the upper margin if necessary */
687  if (Node->StartingVpn < HighVpn) HighVpn = Node->StartingVpn;
688 
689  /* Remember the current node and go to the previous node */
690  OldNode = Node;
691  Node = MiGetPreviousNode(Node);
692  }
693 
694  /* Check if there's enough space before the lowest Vad */
696  if ((HighVpn > LowVpn) && ((HighVpn - LowVpn) >= PageCount))
697  {
698  /* There is enough space to add our address */
699  LowVpn = ALIGN_DOWN_BY(HighVpn - PageCount, Alignment >> PAGE_SHIFT);
700  *Base = LowVpn << PAGE_SHIFT;
701  *Parent = OldNode;
702  return TableInsertAsLeft;
703  }
704 
705  /* No address space left at all */
706  *Base = 0;
707  *Parent = NULL;
708  return TableFoundNode;
709 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
#define MI_LOWEST_VAD_ADDRESS
Definition: miarm.h:11
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2327
#define RtlRightChildAvl
Definition: miavl.h:45
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn BOOLEAN Physical UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:718