reactos/ntoskrnl/mm/ARM3/miarm.h

461 lines
11 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Kernel
* LICENSE: BSD - See COPYING.ARM in the top level directory
* FILE: ntoskrnl/mm/ARM3/miarm.h
* PURPOSE: ARM Memory Manager Header
* PROGRAMMERS: ReactOS Portable Systems Group
*/
#define MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING ((255*1024*1024) >> PAGE_SHIFT)
#define MI_MIN_PAGES_FOR_SYSPTE_TUNING ((19*1024*1024) >> PAGE_SHIFT)
#define MI_MIN_PAGES_FOR_SYSPTE_BOOST ((32*1024*1024) >> PAGE_SHIFT)
#define MI_MAX_INIT_NONPAGED_POOL_SIZE (128 * 1024 * 1024)
#define MI_MAX_NONPAGED_POOL_SIZE (128 * 1024 * 1024)
#define MI_MAX_FREE_PAGE_LISTS 4
- Initialize the value of MmBootImageSize in ARM3 now. - Also fix its value such that it's PDE aligned -- this makes sure that we don't step on any of the boot loader's PDE mappings and can blow everything away later. - Initialize the MmSystem/User/Probe Addresses in ARM3 as well (no functional change). - Print out a lot more of the VA ranges in ARM3's Phase 2 initialization. Most of the VA space is now dumped out. - Write out the code to initialize session space VA ranges - Image space, view space, working set space and pool space values are all calculated properly. - NT default sizes are used, without support for registry overrides (yet). - Also system view space is initialized and sized. - Code is heavily commented and explained for inquisitive minds. - Define the paged pool start address, minimum/default size, and add some extra pool header asserts/definitions. - Define MmPagedPoolInfo to keep track of all paged pool related information (start/end PTEs, VA ranges, allocation/free bitmaps, etc). - Fixed a lot of comments and added some new ones to provide extra clarity. - Implement MiBuildPagedPool. It has two jobs: - Build and create the shadow system page directory, which double-maps the System process' PDE. - More explenations are in the comments. - Define the paged pool region and size, and initialize MmPagedPoolInfo accordingly. - Create and setup the paged pool allocation and free bitmaps (again explained in the comments). - There shouldn't be any real functional change yet due to this commit. - We need to create memory areas for session space and system view space otherwise the VA regions could get used by ReactOS instead. svn path=/trunk/; revision=42148
2009-07-22 22:46:29 +00:00
#define MI_MIN_INIT_PAGED_POOLSIZE (32 * 1024 * 1024)
#define MI_SESSION_VIEW_SIZE (20 * 1024 * 1024)
#define MI_SESSION_POOL_SIZE (16 * 1024 * 1024)
#define MI_SESSION_IMAGE_SIZE (8 * 1024 * 1024)
#define MI_SESSION_WORKING_SET_SIZE (4 * 1024 * 1024)
#define MI_SESSION_SIZE (MI_SESSION_VIEW_SIZE + \
MI_SESSION_POOL_SIZE + \
MI_SESSION_IMAGE_SIZE + \
MI_SESSION_WORKING_SET_SIZE)
#define MI_SYSTEM_VIEW_SIZE (16 * 1024 * 1024)
#define MI_SYSTEM_CACHE_WS_START (PVOID)0xC0C00000
- Initialize the value of MmBootImageSize in ARM3 now. - Also fix its value such that it's PDE aligned -- this makes sure that we don't step on any of the boot loader's PDE mappings and can blow everything away later. - Initialize the MmSystem/User/Probe Addresses in ARM3 as well (no functional change). - Print out a lot more of the VA ranges in ARM3's Phase 2 initialization. Most of the VA space is now dumped out. - Write out the code to initialize session space VA ranges - Image space, view space, working set space and pool space values are all calculated properly. - NT default sizes are used, without support for registry overrides (yet). - Also system view space is initialized and sized. - Code is heavily commented and explained for inquisitive minds. - Define the paged pool start address, minimum/default size, and add some extra pool header asserts/definitions. - Define MmPagedPoolInfo to keep track of all paged pool related information (start/end PTEs, VA ranges, allocation/free bitmaps, etc). - Fixed a lot of comments and added some new ones to provide extra clarity. - Implement MiBuildPagedPool. It has two jobs: - Build and create the shadow system page directory, which double-maps the System process' PDE. - More explenations are in the comments. - Define the paged pool region and size, and initialize MmPagedPoolInfo accordingly. - Create and setup the paged pool allocation and free bitmaps (again explained in the comments). - There shouldn't be any real functional change yet due to this commit. - We need to create memory areas for session space and system view space otherwise the VA regions could get used by ReactOS instead. svn path=/trunk/; revision=42148
2009-07-22 22:46:29 +00:00
#define MI_PAGED_POOL_START (PVOID)0xE1000000
#define MI_NONPAGED_POOL_END (PVOID)0xFFBE0000
- Implement support for reading and writing physical memory for KD. The implementation uses a reserved mapping page to map the target physical address to. On x86 this page is located at virtual address 0xFFBFF000, and the PTE for this page is the last PTE of the nonpaged pool's PDE. Other architectures may need to reserve the PTE elsewhere. - The physical memory support relies on several Mm variables and structures to be properly set up. Add a new flag, MiDbgReadyForPhysical, and set it when the debugger support can handle physical memory requests. - Protect this page with a Memory Area to make the old Mm keep its dirty hands off it. - Does not support I/O space or cache flags yet. - Add generic KeInvalidateTlbEntry to invalidate a single TLB entry for a given address instead of flushing the whole TLB. Used by the debugger physical memory support as invalidating the whole TLB for every map and unmap of its debug PTE would incur significant overhead for large copies. Replace direct usage of __invlpg() with this in x86 code too. - Fix incorrect cache flag check and set in KdpRead/WritePhysicalmemory for write combined requests. The debugger's Uncached flag was checked instead of the Write Combined flag, and the debuggers Write Combine number (0x3) was set instead of Mm's flag (0x20). - Fix implementation of MmIsAddressValid (at least for x86; other architectures will need more checks). Just check the Address' PDE and PTE valid bits instead of using Memory Areas. - Add missing ASSERTs to ensure the Memory Areas for paged pool, the PCR page, and the Shared User Data page are created. - Add missing Memory Area for the 2 pages HAL currently uses for its own mappings on x86 -- previously, those pages could have been allocated by other parts of the OS, which would have resulted in serious corruptions. svn path=/trunk/; revision=43960
2009-11-04 22:40:18 +00:00
#define MI_DEBUG_MAPPING (PVOID)0xFFBFF000
- Initialize the value of MmBootImageSize in ARM3 now. - Also fix its value such that it's PDE aligned -- this makes sure that we don't step on any of the boot loader's PDE mappings and can blow everything away later. - Initialize the MmSystem/User/Probe Addresses in ARM3 as well (no functional change). - Print out a lot more of the VA ranges in ARM3's Phase 2 initialization. Most of the VA space is now dumped out. - Write out the code to initialize session space VA ranges - Image space, view space, working set space and pool space values are all calculated properly. - NT default sizes are used, without support for registry overrides (yet). - Also system view space is initialized and sized. - Code is heavily commented and explained for inquisitive minds. - Define the paged pool start address, minimum/default size, and add some extra pool header asserts/definitions. - Define MmPagedPoolInfo to keep track of all paged pool related information (start/end PTEs, VA ranges, allocation/free bitmaps, etc). - Fixed a lot of comments and added some new ones to provide extra clarity. - Implement MiBuildPagedPool. It has two jobs: - Build and create the shadow system page directory, which double-maps the System process' PDE. - More explenations are in the comments. - Define the paged pool region and size, and initialize MmPagedPoolInfo accordingly. - Create and setup the paged pool allocation and free bitmaps (again explained in the comments). - There shouldn't be any real functional change yet due to this commit. - We need to create memory areas for session space and system view space otherwise the VA regions could get used by ReactOS instead. svn path=/trunk/; revision=42148
2009-07-22 22:46:29 +00:00
#define MI_MIN_SECONDARY_COLORS 8
#define MI_SECONDARY_COLORS 64
#define MI_MAX_SECONDARY_COLORS 1024
#define MM_HIGHEST_VAD_ADDRESS \
(PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
/* Make the code cleaner with some definitions for size multiples */
#define _1KB (1024)
#define _1MB (1024 * _1KB)
/* Size of a PDE directory, and size of a page table */
#define PDE_SIZE (PDE_COUNT * sizeof(MMPDE))
#define PT_SIZE (PTE_COUNT * sizeof(MMPTE))
/* Architecture specific count of PDEs in a directory, and count of PTEs in a PT */
#ifdef _M_IX86
#define PD_COUNT 1
#define PDE_COUNT 1024
#define PTE_COUNT 1024
#elif _M_ARM
#define PD_COUNT 1
#define PDE_COUNT 4096
#define PTE_COUNT 256
#else
#error Define these please!
#endif
//
// PFN List Sentinel
//
#define LIST_HEAD 0xFFFFFFFF
//
// FIXFIX: These should go in ex.h after the pool merge
//
- Initialize the value of MmBootImageSize in ARM3 now. - Also fix its value such that it's PDE aligned -- this makes sure that we don't step on any of the boot loader's PDE mappings and can blow everything away later. - Initialize the MmSystem/User/Probe Addresses in ARM3 as well (no functional change). - Print out a lot more of the VA ranges in ARM3's Phase 2 initialization. Most of the VA space is now dumped out. - Write out the code to initialize session space VA ranges - Image space, view space, working set space and pool space values are all calculated properly. - NT default sizes are used, without support for registry overrides (yet). - Also system view space is initialized and sized. - Code is heavily commented and explained for inquisitive minds. - Define the paged pool start address, minimum/default size, and add some extra pool header asserts/definitions. - Define MmPagedPoolInfo to keep track of all paged pool related information (start/end PTEs, VA ranges, allocation/free bitmaps, etc). - Fixed a lot of comments and added some new ones to provide extra clarity. - Implement MiBuildPagedPool. It has two jobs: - Build and create the shadow system page directory, which double-maps the System process' PDE. - More explenations are in the comments. - Define the paged pool region and size, and initialize MmPagedPoolInfo accordingly. - Create and setup the paged pool allocation and free bitmaps (again explained in the comments). - There shouldn't be any real functional change yet due to this commit. - We need to create memory areas for session space and system view space otherwise the VA regions could get used by ReactOS instead. svn path=/trunk/; revision=42148
2009-07-22 22:46:29 +00:00
#define POOL_LISTS_PER_PAGE (PAGE_SIZE / sizeof(LIST_ENTRY))
#define BASE_POOL_TYPE_MASK 1
#define POOL_MAX_ALLOC (PAGE_SIZE - (sizeof(POOL_HEADER) + sizeof(LIST_ENTRY)))
typedef struct _POOL_DESCRIPTOR
{
POOL_TYPE PoolType;
ULONG PoolIndex;
ULONG RunningAllocs;
ULONG RunningDeAllocs;
ULONG TotalPages;
ULONG TotalBigPages;
ULONG Threshold;
PVOID LockAddress;
PVOID PendingFrees;
LONG PendingFreeDepth;
SIZE_T TotalBytes;
SIZE_T Spare0;
LIST_ENTRY ListHeads[POOL_LISTS_PER_PAGE];
} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
typedef struct _POOL_HEADER
{
union
{
struct
{
USHORT PreviousSize:9;
USHORT PoolIndex:7;
USHORT BlockSize:9;
USHORT PoolType:7;
};
ULONG Ulong1;
};
union
{
ULONG PoolTag;
struct
{
USHORT AllocatorBackTraceIndex;
USHORT PoolTagHash;
};
};
} POOL_HEADER, *PPOOL_HEADER;
- Initialize the value of MmBootImageSize in ARM3 now. - Also fix its value such that it's PDE aligned -- this makes sure that we don't step on any of the boot loader's PDE mappings and can blow everything away later. - Initialize the MmSystem/User/Probe Addresses in ARM3 as well (no functional change). - Print out a lot more of the VA ranges in ARM3's Phase 2 initialization. Most of the VA space is now dumped out. - Write out the code to initialize session space VA ranges - Image space, view space, working set space and pool space values are all calculated properly. - NT default sizes are used, without support for registry overrides (yet). - Also system view space is initialized and sized. - Code is heavily commented and explained for inquisitive minds. - Define the paged pool start address, minimum/default size, and add some extra pool header asserts/definitions. - Define MmPagedPoolInfo to keep track of all paged pool related information (start/end PTEs, VA ranges, allocation/free bitmaps, etc). - Fixed a lot of comments and added some new ones to provide extra clarity. - Implement MiBuildPagedPool. It has two jobs: - Build and create the shadow system page directory, which double-maps the System process' PDE. - More explenations are in the comments. - Define the paged pool region and size, and initialize MmPagedPoolInfo accordingly. - Create and setup the paged pool allocation and free bitmaps (again explained in the comments). - There shouldn't be any real functional change yet due to this commit. - We need to create memory areas for session space and system view space otherwise the VA regions could get used by ReactOS instead. svn path=/trunk/; revision=42148
2009-07-22 22:46:29 +00:00
//
// Everything depends on this
//
C_ASSERT(sizeof(POOL_HEADER) == 8);
C_ASSERT(sizeof(POOL_HEADER) == sizeof(LIST_ENTRY));
extern ULONG ExpNumberOfPagedPools;
extern POOL_DESCRIPTOR NonPagedPoolDescriptor;
extern PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
extern PVOID PoolTrackTable;
//
// END FIXFIX
//
typedef struct _MI_LARGE_PAGE_DRIVER_ENTRY
{
LIST_ENTRY Links;
UNICODE_STRING BaseName;
} MI_LARGE_PAGE_DRIVER_ENTRY, *PMI_LARGE_PAGE_DRIVER_ENTRY;
typedef enum _MMSYSTEM_PTE_POOL_TYPE
{
SystemPteSpace,
NonPagedPoolExpansion,
MaximumPtePoolTypes
} MMSYSTEM_PTE_POOL_TYPE;
typedef enum _MI_PFN_CACHE_ATTRIBUTE
{
MiNonCached,
MiCached,
MiWriteCombined,
MiNotMapped
} MI_PFN_CACHE_ATTRIBUTE, *PMI_PFN_CACHE_ATTRIBUTE;
typedef struct _PHYSICAL_MEMORY_RUN
{
ULONG BasePage;
ULONG PageCount;
} PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
typedef struct _PHYSICAL_MEMORY_DESCRIPTOR
{
ULONG NumberOfRuns;
ULONG NumberOfPages;
PHYSICAL_MEMORY_RUN Run[1];
} PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
typedef struct _MMCOLOR_TABLES
{
PFN_NUMBER Flink;
PVOID Blink;
PFN_NUMBER Count;
} MMCOLOR_TABLES, *PMMCOLOR_TABLES;
extern MMPTE HyperTemplatePte;
extern MMPTE ValidKernelPde;
extern MMPTE ValidKernelPte;
extern ULONG MmSizeOfNonPagedPoolInBytes;
extern ULONG MmMaximumNonPagedPoolInBytes;
extern PFN_NUMBER MmMaximumNonPagedPoolInPages;
extern PFN_NUMBER MmSizeOfPagedPoolInPages;
extern PVOID MmNonPagedSystemStart;
extern PVOID MmNonPagedPoolStart;
extern PVOID MmNonPagedPoolExpansionStart;
- Reimplement MmAllocateContiguousMemory, MmAllocateContiguousMemorySpecifyCache, MmFreeContiguousMemory, MmFreeContiguousMemorySpecifyCache: - Use a smarter algorithm (as described here: http://www.microsoft.com/whdc/Driver/tips/ContigMem.mspx) to first try to satisfy the allocation by a simple nonpaged pool allocation (for cached requests only). - This range is then checked for physical continuity, since it's not guaranteed for non-initial-pool allocations (and right now in ReactOS, it never is). - As a fallback, Windows NT then attempts to scan free nonpaged pool pages. This is not yet implemented since the ReactOS nonpaged pool is not usually contiguous (to the level that NT's is). - When the ARM pool is implemented and replaces nonpaged pool, this code path will have to be implemented. - As a last resort, the actual PFN database is scanned for contiguous free pages. - ReactOS used MmGetContiguousPages for this, which blindly scanned the PFN database. New MiFindContinuousPages will scan the physical memory descriptor block recently implemented, which avoids going over pages we already know are going to be unusable. - The ReactOS function also held the PFN lock for the entire duration of the scan, which is significant on systems with large memory. Instead, we make an initial unsafe scan first, and only lock when we think we've found a correct range (and we'll then reconfirm the ranges). - Finally, the older function actually did a double-scan to try to avoid using memory ranges under 16MB, which was useless on today's systems and also rather inefficient. - Other than that, the actual setup of the PFN entry is copy-pasted from the old ReactOS function, so nothing's changed there -- the page still looks the same, but the selection algorithm is faster and more accurate. - Once the pages are found, we piggyback on the new I/O mapping mechanism (which uses System PTEs) instead of doing it all over by hand as before. - Since the underlying support is still System PTEs, once again, optimizations to that component will yield significant improvements here too. svn path=/trunk/; revision=41657
2009-06-28 05:43:12 +00:00
extern PVOID MmNonPagedPoolEnd;
extern ULONG MmSizeOfPagedPoolInBytes;
extern PVOID MmPagedPoolStart;
extern PVOID MmPagedPoolEnd;
extern PVOID MmSessionBase;
extern ULONG MmSessionSize;
extern PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte;
extern PMMPTE MiFirstReservedZeroingPte;
- Reimplement MmAllocateContiguousMemory, MmAllocateContiguousMemorySpecifyCache, MmFreeContiguousMemory, MmFreeContiguousMemorySpecifyCache: - Use a smarter algorithm (as described here: http://www.microsoft.com/whdc/Driver/tips/ContigMem.mspx) to first try to satisfy the allocation by a simple nonpaged pool allocation (for cached requests only). - This range is then checked for physical continuity, since it's not guaranteed for non-initial-pool allocations (and right now in ReactOS, it never is). - As a fallback, Windows NT then attempts to scan free nonpaged pool pages. This is not yet implemented since the ReactOS nonpaged pool is not usually contiguous (to the level that NT's is). - When the ARM pool is implemented and replaces nonpaged pool, this code path will have to be implemented. - As a last resort, the actual PFN database is scanned for contiguous free pages. - ReactOS used MmGetContiguousPages for this, which blindly scanned the PFN database. New MiFindContinuousPages will scan the physical memory descriptor block recently implemented, which avoids going over pages we already know are going to be unusable. - The ReactOS function also held the PFN lock for the entire duration of the scan, which is significant on systems with large memory. Instead, we make an initial unsafe scan first, and only lock when we think we've found a correct range (and we'll then reconfirm the ranges). - Finally, the older function actually did a double-scan to try to avoid using memory ranges under 16MB, which was useless on today's systems and also rather inefficient. - Other than that, the actual setup of the PFN entry is copy-pasted from the old ReactOS function, so nothing's changed there -- the page still looks the same, but the selection algorithm is faster and more accurate. - Once the pages are found, we piggyback on the new I/O mapping mechanism (which uses System PTEs) instead of doing it all over by hand as before. - Since the underlying support is still System PTEs, once again, optimizations to that component will yield significant improvements here too. svn path=/trunk/; revision=41657
2009-06-28 05:43:12 +00:00
extern MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType];
extern PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;
extern ULONG MmBootImageSize;
- Major rewrite of Memory Descriptor List (MDL) implementation (moving it towards using System PTEs). - MmCreateMdl, MmSizeOfMdl: No Change. - MmBuildMdlForNonPagedPool: Do not use MmGetPfnForProcess, just normal PMMPTE manipulation. - This seems to cause issues in certain scenarios, because in ReactOS, nonpaged pool, a resident and guaranteed resources, does not always have its PDEs mapped! - By calling MmGetPfnForProcess, this wound up in the annals of ReactOS mm code, which lazy-remapped the PDE. We detected this issue specifically in the cache manager, and fixed it there. It should not appear anywhere else. - MmAllocatePagesForMdl, MmAllocatePagesForMdlEx, MmFreePagesFromMdl: - The *Ex function is now implemented. - Allocating pages now uses MiAllocatePagesForMdl, which is based on the older MmAllocPagesSpecifyRange. - The code is cleaner, better commented, and better handles partial MDLs. - Cache flags are still ignored (so the Ex functionality isn't really there). - MmMapLockedPages, MmMapLockedPagesSpecifyCache, MmUnmapLockedPages: - These functions now use System PTEs for the mappings, instead of the hacked-up "MDL Mapping Space". - This frees up 256MB of Kernel Virtual Address Space. - Takes advantage of all System PTE functionality. - Once again, optimizations in the System PTE code will be felt here. - For user-space mappings however, the old code is still kept and used. - MiMapLockedPagesInUserSpace and MiUnMapLockedPagesInUserSpace are now in virtual.c and provide this. - MmProbeAndLockPages, MmUnlockPages: - The pages are actually probed now, in SEH. This did not seem to happen before (did someone misread the function's name?) - Probe for write is only done for write access to user pages (as documented). - We do not probe/check for write access for kernel requests (force Operation to be IoReadAccess). - Proper locking is used now: Address Space lock for user mappings, PFN lock for kernel mappings. - Faulting in pages (to make them available before locking) is now done outside the address space/PFN lock. - You don't want to be holding a spinlock/mutex while doing disk I/O! - For write/modify access, if the PTE is not writable, fail the request since the PTE protection overrides. - However, if the PTE is writable but also copy on write, then we'll fault the page in for write access, which is a legitimate operation for certain user-mode scenarios. - The old version always provided the CopyOnWrite behavior, even for non-CopyOnWrite pages! - Reference and lock every valid page that has a PFN entry (non-I/O Pages). - The older code did not seem to lock pages that had to be faulted in (weren't already valid). - Cleanup the cleanup code (no pun intended). Because we now mark the pages as locked early-on, and because of changes in MmUnlockPages, we can simply use MmUnlockPages in case of error, since it will be able to fully back-out and references/locks that we did. - Previous code attempted to do this on its own, in a pretty inconsistent manner, which would leave page leaks (both in references and lock count). - In MmUnlockPages, not as many changes, but we now: - Still make sure that an I/O Mapping MDL doesn't have valid PFN database pages (non-I/O). - An MDL can cover pages that are both I/O mapped and RAM mapped, so we have to unlock/dereference the latter instead of skipping them as the old code did. - Use the PFN lock when checking pages and unlocking/dereferencing them. - Overall, non-complete MDLs are now marked by having a -1 PFN, and the MDL code has been updated to early-break out of page-scanning loops and/or ignore such pages, which can happen in a sparse MDL. - Implementation has been tested on VMWare and QEMU for a variety of tasks and was found to be reliable and stable. svn path=/trunk/; revision=41707
2009-06-30 08:29:22 +00:00
extern PMMPTE MmSystemPtesStart[MaximumPtePoolTypes];
extern PMMPTE MmSystemPtesEnd[MaximumPtePoolTypes];
extern PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
extern MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
extern ULONG MxPfnAllocation;
- Initialize the value of MmBootImageSize in ARM3 now. - Also fix its value such that it's PDE aligned -- this makes sure that we don't step on any of the boot loader's PDE mappings and can blow everything away later. - Initialize the MmSystem/User/Probe Addresses in ARM3 as well (no functional change). - Print out a lot more of the VA ranges in ARM3's Phase 2 initialization. Most of the VA space is now dumped out. - Write out the code to initialize session space VA ranges - Image space, view space, working set space and pool space values are all calculated properly. - NT default sizes are used, without support for registry overrides (yet). - Also system view space is initialized and sized. - Code is heavily commented and explained for inquisitive minds. - Define the paged pool start address, minimum/default size, and add some extra pool header asserts/definitions. - Define MmPagedPoolInfo to keep track of all paged pool related information (start/end PTEs, VA ranges, allocation/free bitmaps, etc). - Fixed a lot of comments and added some new ones to provide extra clarity. - Implement MiBuildPagedPool. It has two jobs: - Build and create the shadow system page directory, which double-maps the System process' PDE. - More explenations are in the comments. - Define the paged pool region and size, and initialize MmPagedPoolInfo accordingly. - Create and setup the paged pool allocation and free bitmaps (again explained in the comments). - There shouldn't be any real functional change yet due to this commit. - We need to create memory areas for session space and system view space otherwise the VA regions could get used by ReactOS instead. svn path=/trunk/; revision=42148
2009-07-22 22:46:29 +00:00
extern MM_PAGED_POOL_INFO MmPagedPoolInfo;
- This is a HIGH RISK patch. It has been tested on multiple emulators and configurations but requires broader input. - Implement several changes to PFN database management: - The PTEs for the PFN Database are now created by ARM3. Unlike the old code which create PTE for every page on the machine, ARM3 only creates PTEs to account for pages that should be in the PFN database. - A second related change is what "pages should be in the PFN database". Previously, reserved or otherwise non-existing (ie: holes) memory regions would get a PFN entry created and marked as "BIOS". This is wasteful and not compatible with Windows: there should not be PFN entries created at all. - So we removed BIOS PFN entries, and now only create PTEs for valid pages as listed in the physical memory ranges. - This allows machines with "holes" in their physical address space not to waste dozens of MBs of nonpaged pool - Also saves memory on regular machines too, since 1-4MB worth of memory will now not be in the DB anymore - To keep track of pages that are invalid/unknown/ignored, there is now a "PFN Bitmap". This bitmap has one bit set for each valid PFN in the database. - And so, MiGetPfnEntry now also validates that, if there is a PFN Bitmap, the requested PFN is actually present in the database. - This introduces a major functional change: device pages, reserved pages, and other BIOS pages cannot be referenced, shared, or managed in any meaningful way. - We have attempted to fix parts of the OS that depended on this, but there may still be bugs. - A known issue may be an assertion during reboot and/or shutdown in the hyperspace mapping function. It is currently safe to simply "cont" in the debugger a couple of times. - We are working on a fix. svn path=/trunk/; revision=42220
2009-07-25 21:35:31 +00:00
extern RTL_BITMAP MiPfnBitMap;
extern KGUARDED_MUTEX MmPagedPoolMutex;
extern PVOID MmPagedPoolStart;
extern PVOID MmPagedPoolEnd;
extern PVOID MmNonPagedSystemStart;
extern PVOID MiSystemViewStart;
extern ULONG MmSystemViewSize;
extern PVOID MmSessionBase;
extern PVOID MiSessionSpaceEnd;
extern ULONG MmSizeOfPagedPoolInBytes;
extern PMMPTE MmSystemPagePtes;
extern PVOID MmSystemCacheStart;
extern PVOID MmSystemCacheEnd;
extern MMSUPPORT MmSystemCacheWs;
extern SIZE_T MmAllocatedNonPagedPool;
extern ULONG_PTR MmSubsectionBase;
extern ULONG MmSpecialPoolTag;
extern PVOID MmHyperSpaceEnd;
extern PMMWSL MmSystemCacheWorkingSetList;
extern ULONG MmMinimumNonPagedPoolSize;
extern ULONG MmMinAdditionNonPagedPoolPerMb;
extern ULONG MmDefaultMaximumNonPagedPool;
extern ULONG MmMaxAdditionNonPagedPoolPerMb;
extern ULONG MmSecondaryColors;
extern ULONG MmSecondaryColorMask;
extern ULONG MmNumberOfSystemPtes;
extern ULONG MmMaximumNonPagedPoolPercent;
extern ULONG MmLargeStackSize;
extern PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
extern ULONG MmProductType;
extern MM_SYSTEMSIZE MmSystemSize;
extern PKEVENT MiLowMemoryEvent;
extern PKEVENT MiHighMemoryEvent;
extern PKEVENT MiLowPagedPoolEvent;
extern PKEVENT MiHighPagedPoolEvent;
extern PKEVENT MiLowNonPagedPoolEvent;
extern PKEVENT MiHighNonPagedPoolEvent;
extern PFN_NUMBER MmLowMemoryThreshold;
extern PFN_NUMBER MmHighMemoryThreshold;
extern PFN_NUMBER MiLowPagedPoolThreshold;
extern PFN_NUMBER MiHighPagedPoolThreshold;
extern PFN_NUMBER MiLowNonPagedPoolThreshold;
extern PFN_NUMBER MiHighNonPagedPoolThreshold;
extern PFN_NUMBER MmMinimumFreePages;
extern PFN_NUMBER MmPlentyFreePages;
extern PFN_NUMBER MiExpansionPoolPagesInitialCharge;
extern PFN_NUMBER MmResidentAvailablePages;
extern PFN_NUMBER MmResidentAvailablePagesAtInit;
#define MI_PFN_TO_PFNENTRY(x) (&MmPfnDatabase[1][x])
#define MI_PFNENTRY_TO_PFN(x) (x - MmPfnDatabase[1])
NTSTATUS
NTAPI
MmArmInitSystem(
IN ULONG Phase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
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
);
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
MmArmAccessFault(
IN BOOLEAN StoreInstruction,
IN PVOID Address,
IN KPROCESSOR_MODE Mode,
IN PVOID TrapInformation
);
VOID
NTAPI
MiInitializeNonPagedPool(
VOID
);
VOID
NTAPI
MiInitializeNonPagedPoolThresholds(
VOID
);
VOID
NTAPI
MiInitializePoolEvents(
VOID
);
VOID //
NTAPI //
InitializePool( //
IN POOL_TYPE PoolType,// FIXFIX: This should go in ex.h after the pool merge
IN ULONG Threshold //
); //
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
);
- Reimplement MmAllocateContiguousMemory, MmAllocateContiguousMemorySpecifyCache, MmFreeContiguousMemory, MmFreeContiguousMemorySpecifyCache: - Use a smarter algorithm (as described here: http://www.microsoft.com/whdc/Driver/tips/ContigMem.mspx) to first try to satisfy the allocation by a simple nonpaged pool allocation (for cached requests only). - This range is then checked for physical continuity, since it's not guaranteed for non-initial-pool allocations (and right now in ReactOS, it never is). - As a fallback, Windows NT then attempts to scan free nonpaged pool pages. This is not yet implemented since the ReactOS nonpaged pool is not usually contiguous (to the level that NT's is). - When the ARM pool is implemented and replaces nonpaged pool, this code path will have to be implemented. - As a last resort, the actual PFN database is scanned for contiguous free pages. - ReactOS used MmGetContiguousPages for this, which blindly scanned the PFN database. New MiFindContinuousPages will scan the physical memory descriptor block recently implemented, which avoids going over pages we already know are going to be unusable. - The ReactOS function also held the PFN lock for the entire duration of the scan, which is significant on systems with large memory. Instead, we make an initial unsafe scan first, and only lock when we think we've found a correct range (and we'll then reconfirm the ranges). - Finally, the older function actually did a double-scan to try to avoid using memory ranges under 16MB, which was useless on today's systems and also rather inefficient. - Other than that, the actual setup of the PFN entry is copy-pasted from the old ReactOS function, so nothing's changed there -- the page still looks the same, but the selection algorithm is faster and more accurate. - Once the pages are found, we piggyback on the new I/O mapping mechanism (which uses System PTEs) instead of doing it all over by hand as before. - Since the underlying support is still System PTEs, once again, optimizations to that component will yield significant improvements here too. svn path=/trunk/; revision=41657
2009-06-28 05:43:12 +00:00
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
);
- Major rewrite of Memory Descriptor List (MDL) implementation (moving it towards using System PTEs). - MmCreateMdl, MmSizeOfMdl: No Change. - MmBuildMdlForNonPagedPool: Do not use MmGetPfnForProcess, just normal PMMPTE manipulation. - This seems to cause issues in certain scenarios, because in ReactOS, nonpaged pool, a resident and guaranteed resources, does not always have its PDEs mapped! - By calling MmGetPfnForProcess, this wound up in the annals of ReactOS mm code, which lazy-remapped the PDE. We detected this issue specifically in the cache manager, and fixed it there. It should not appear anywhere else. - MmAllocatePagesForMdl, MmAllocatePagesForMdlEx, MmFreePagesFromMdl: - The *Ex function is now implemented. - Allocating pages now uses MiAllocatePagesForMdl, which is based on the older MmAllocPagesSpecifyRange. - The code is cleaner, better commented, and better handles partial MDLs. - Cache flags are still ignored (so the Ex functionality isn't really there). - MmMapLockedPages, MmMapLockedPagesSpecifyCache, MmUnmapLockedPages: - These functions now use System PTEs for the mappings, instead of the hacked-up "MDL Mapping Space". - This frees up 256MB of Kernel Virtual Address Space. - Takes advantage of all System PTE functionality. - Once again, optimizations in the System PTE code will be felt here. - For user-space mappings however, the old code is still kept and used. - MiMapLockedPagesInUserSpace and MiUnMapLockedPagesInUserSpace are now in virtual.c and provide this. - MmProbeAndLockPages, MmUnlockPages: - The pages are actually probed now, in SEH. This did not seem to happen before (did someone misread the function's name?) - Probe for write is only done for write access to user pages (as documented). - We do not probe/check for write access for kernel requests (force Operation to be IoReadAccess). - Proper locking is used now: Address Space lock for user mappings, PFN lock for kernel mappings. - Faulting in pages (to make them available before locking) is now done outside the address space/PFN lock. - You don't want to be holding a spinlock/mutex while doing disk I/O! - For write/modify access, if the PTE is not writable, fail the request since the PTE protection overrides. - However, if the PTE is writable but also copy on write, then we'll fault the page in for write access, which is a legitimate operation for certain user-mode scenarios. - The old version always provided the CopyOnWrite behavior, even for non-CopyOnWrite pages! - Reference and lock every valid page that has a PFN entry (non-I/O Pages). - The older code did not seem to lock pages that had to be faulted in (weren't already valid). - Cleanup the cleanup code (no pun intended). Because we now mark the pages as locked early-on, and because of changes in MmUnlockPages, we can simply use MmUnlockPages in case of error, since it will be able to fully back-out and references/locks that we did. - Previous code attempted to do this on its own, in a pretty inconsistent manner, which would leave page leaks (both in references and lock count). - In MmUnlockPages, not as many changes, but we now: - Still make sure that an I/O Mapping MDL doesn't have valid PFN database pages (non-I/O). - An MDL can cover pages that are both I/O mapped and RAM mapped, so we have to unlock/dereference the latter instead of skipping them as the old code did. - Use the PFN lock when checking pages and unlocking/dereferencing them. - Overall, non-complete MDLs are now marked by having a -1 PFN, and the MDL code has been updated to early-break out of page-scanning loops and/or ignore such pages, which can happen in a sparse MDL. - Implementation has been tested on VMWare and QEMU for a variety of tasks and was found to be reliable and stable. svn path=/trunk/; revision=41707
2009-06-30 08:29:22 +00:00
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
);
PVOID
NTAPI
MiMapLockedPagesInUserSpace(
IN PMDL Mdl,
IN PVOID BaseVa,
IN MEMORY_CACHING_TYPE CacheType,
IN PVOID BaseAddress
);
VOID
NTAPI
MiUnmapLockedPagesInUserSpace(
IN PVOID BaseAddress,
IN PMDL Mdl
);
VOID
NTAPI
MiInsertInListTail(
IN PMMPFNLIST ListHead,
IN PMMPFN Entry
);
VOID
NTAPI
MiInsertZeroListAtBack(
IN PFN_NUMBER PageIndex
);
VOID
NTAPI
MiUnlinkFreeOrZeroedPage(
IN PMMPFN Entry
);
PMMPFN
NTAPI
MiRemoveHeadList(
IN PMMPFNLIST ListHead
);
VOID
NTAPI
MiInsertPageInFreeList(
IN PFN_NUMBER PageFrameIndex
);
/* EOF */