reactos/ntoskrnl/include/internal/mm.h

1534 lines
29 KiB
C
Raw Normal View History

#pragma once
#include <internal/arch/mm.h>
/* TYPES *********************************************************************/
struct _EPROCESS;
extern PMMSUPPORT MmKernelAddressSpace;
extern PFN_COUNT MiFreeSwapPages;
extern PFN_COUNT MiUsedSwapPages;
extern PFN_COUNT MmNumberOfPhysicalPages;
extern UCHAR MmDisablePagingExecutive;
extern PFN_NUMBER MmLowestPhysicalPage;
extern PFN_NUMBER MmHighestPhysicalPage;
extern PFN_NUMBER MmAvailablePages;
extern PFN_NUMBER MmResidentAvailablePages;
extern ULONG MmThrottleTop;
extern ULONG MmThrottleBottom;
extern LIST_ENTRY MmLoadedUserImageList;
extern KMUTANT MmSystemLoadLock;
extern ULONG MmNumberOfPagingFiles;
extern PVOID MmUnloadedDrivers;
extern PVOID MmLastUnloadedDrivers;
extern PVOID MmTriageActionTaken;
extern PVOID KernelVerifier;
extern MM_DRIVER_VERIFIER_DATA MmVerifierData;
extern SIZE_T MmTotalCommitLimit;
extern SIZE_T MmTotalCommittedPages;
extern SIZE_T MmSharedCommit;
extern SIZE_T MmDriverCommit;
extern SIZE_T MmProcessCommit;
extern SIZE_T MmPagedPoolCommit;
extern SIZE_T MmPeakCommitment;
extern SIZE_T MmtotalCommitLimitMaximum;
extern PVOID MiDebugMapping; // internal
extern PMMPTE MmDebugPte; // internal
- 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
struct _KTRAP_FRAME;
struct _EPROCESS;
struct _MM_RMAP_ENTRY;
typedef ULONG_PTR SWAPENTRY;
//
// MmDbgCopyMemory Flags
//
#define MMDBG_COPY_WRITE 0x00000001
#define MMDBG_COPY_PHYSICAL 0x00000002
#define MMDBG_COPY_UNSAFE 0x00000004
#define MMDBG_COPY_CACHED 0x00000008
#define MMDBG_COPY_UNCACHED 0x00000010
#define MMDBG_COPY_WRITE_COMBINED 0x00000020
//
// Maximum chunk size per copy
//
#define MMDBG_COPY_MAX_SIZE 0x8
#if defined(_X86_) // intenal for marea.c
- 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_STATIC_MEMORY_AREAS (14)
#else
#define MI_STATIC_MEMORY_AREAS (13)
#endif
#define MEMORY_AREA_SECTION_VIEW (1)
#define MEMORY_AREA_CACHE (2)
#define MEMORY_AREA_OWNED_BY_ARM3 (15)
#define MEMORY_AREA_STATIC (0x80000000)
/* Although Microsoft says this isn't hardcoded anymore,
they won't be able to change it. Stuff depends on it */
#define MM_VIRTMEM_GRANULARITY (64 * 1024)
#define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001)
/*
* Additional flags for protection attributes
*/
#define PAGE_WRITETHROUGH (1024)
#define PAGE_SYSTEM (2048)
#define SEC_PHYSICALMEMORY (0x80000000)
#define MM_PAGEFILE_SEGMENT (0x1)
#define MM_DATAFILE_SEGMENT (0x2)
#define MC_CACHE (0)
#define MC_USER (1)
#define MC_SYSTEM (2)
#define MC_MAXIMUM (3)
#define PAGED_POOL_MASK 1
#define MUST_SUCCEED_POOL_MASK 2
#define CACHE_ALIGNED_POOL_MASK 4
#define QUOTA_POOL_MASK 8
#define SESSION_POOL_MASK 32
#define VERIFIER_POOL_MASK 64
#define MAX_PAGING_FILES (16)
// FIXME: use ALIGN_UP_BY
#define MM_ROUND_UP(x,s) \
((PVOID)(((ULONG_PTR)(x)+(s)-1) & ~((ULONG_PTR)(s)-1)))
#define MM_ROUND_DOWN(x,s) \
((PVOID)(((ULONG_PTR)(x)) & ~((ULONG_PTR)(s)-1)))
#define PAGE_FLAGS_VALID_FOR_SECTION \
(PAGE_READONLY | \
PAGE_READWRITE | \
PAGE_WRITECOPY | \
PAGE_EXECUTE | \
PAGE_EXECUTE_READ | \
PAGE_EXECUTE_READWRITE | \
PAGE_EXECUTE_WRITECOPY | \
PAGE_NOACCESS | \
PAGE_NOCACHE)
#define PAGE_IS_READABLE \
(PAGE_READONLY | \
PAGE_READWRITE | \
PAGE_WRITECOPY | \
PAGE_EXECUTE_READ | \
PAGE_EXECUTE_READWRITE | \
PAGE_EXECUTE_WRITECOPY)
#define PAGE_IS_WRITABLE \
(PAGE_READWRITE | \
PAGE_WRITECOPY | \
PAGE_EXECUTE_READWRITE | \
PAGE_EXECUTE_WRITECOPY)
#define PAGE_IS_EXECUTABLE \
(PAGE_EXECUTE | \
PAGE_EXECUTE_READ | \
PAGE_EXECUTE_READWRITE | \
PAGE_EXECUTE_WRITECOPY)
#define PAGE_IS_WRITECOPY \
(PAGE_WRITECOPY | \
PAGE_EXECUTE_WRITECOPY)
//
// Wait entry for marking pages that are being serviced
//
#define MM_WAIT_ENTRY 0x7ffffc00
#define InterlockedCompareExchangePte(PointerPte, Exchange, Comperand) \
InterlockedCompareExchange((PLONG)(PointerPte), Exchange, Comperand)
#define InterlockedExchangePte(PointerPte, Value) \
InterlockedExchange((PLONG)(PointerPte), Value)
typedef struct _MM_SECTION_SEGMENT
{
FAST_MUTEX Lock; /* lock which protects the page directory */
[NEWCC] A reintegration checkpoint for the NewCC branch, brought to you by Team NewCC. Differences with current ReactOS trunk: * A new memory area type, MEMORY_AREA_CACHE, is added, which represents a mapped region of a file. In NEWCC mode, user sections are MEMORY_AREA_CACHE type as well, and obey new semantics. In non-NEWCC mode, they aren't used. * A way of claiming a page entry for a specific thread's work is added. Placing the special SWAPENTRY value MM_WAIT_ENTRY in a page table, or in a section page table should indicate that memory management code is intended to wait for another thread to make some status change before checking the state of the page entry again. In code that uses this convention, a return value of STATUS_SUCCESS + 1 is used to indicate that the caller should use the MiWaitForPageEvent macro to wait until somebody has change the state of a wait entry before checking again. This is a lighter weight mechanism than PAGEOPs. * A way of asking the caller to perform some blocking operation without locks held is provided. This replaces some spaghettified code in which locks are repeatedly taken and broken by code that performs various blocking operations. Using this mechanism, it is possible to do a small amount of non-blocking work, fill in a request, then return STATUS_MORE_PROCESSING_REQUIRED to request that locks be dropped and the blocking operation be carried out. A MM_REQUIRED_RESOURCES structure is provided to consumers of this contract to use to accumulate state across many blocking operations. Several functions wrapping blocking operations are provided in ntoskrnl/cache/reqtools.c. * Image section pages are no longer direct mapped. This is done to simplify consolidation of ownership of pages under the data section system. At a later time, it may be possible to make data pages directly available to image sections for the same file. This is likely the only direct performance impact this code makes on non-NEWCC mode. RMAPs: * A new type of RMAP entry is introduced, distinguished by RMAP_IS_SEGMENT(Address) of the rmap entry. This kind of entry contains a pointer to a section page table node in the Process pointer, which in turn links back to the MM_SECTION_SEGMENT it belongs to. Therefore, a page belonging only to a segment (that is, a segment page that isn't mapped) can exist and be evicted using the normal page eviction mechanism in balance.c. Each of the rmap function has been modified to deal with segment rmaps. * The low 8 bits of the Address field in a segment rmap denote the entry number in the generic table node pointed to by Process that points to the page the rmap belongs to. By combining them, you can determine the file offset the page belongs to. * In NEWCC mode, MmSharePageEntry/UnsharePageEntry are not used, and instead the page reference count is used to keep track of the number of mappings of a page, allowing the last reference expiring to allow the page to be recycled without much intervention. These are still used in non-NEWCC mode. One change has been made, the count fields have been narrowed by 1 bit to make room for a dirty bit in SSE entries, needed when a page is present but unmapped. Section page tables: * The section page tables are now implemented using RtlGenericTables. This enables a fairly compact representation of section page tables without having the existence of a section object imply 4k of fake PDEs. In addition, each node in the generic table has a wide file offset that is a multiple of 256 pages, or 1 megabyte total. Besides needing wide file offsets, the only other visible change caused by the switch to generic tables for section page tables is the need to lock the section segment before interacting with the section page table. Eviction: * Page eviction in cache sections is accomplished by MmpPageOutPhysicalAddress. In the case of a shared page, it tries to remove all mappings of the indicated page. If this process fails at any point, the page will simply be drawn back into the target address spaces. After succeeding at this, if TRUE has been accumulated into the page's dirty bit in the section page table, it is written back, and then permanently removed. NewCC mode: * NEWCC mode is introduced, which rewrites the file cache to a set of cache stripes actively mapped, along with unmapped section data. * NewCC is more authentic in its interpretation of the external interface to the windows cache than the current cache manager, implementing each of the cache manager functions according to the documented interface with no preconceived ideas about how anything should be implemented internally. Cache stripes are implemented on top of section objects, using the same memory manager paths, and therefore economizing code and complexity. This replaces a rather complicated system in which pages can be owned by the cache manager and the memory manager simultaneously and they must cooperate in a fairly sophisticated way to manage them. Since they're quite interdependent in the current code, modifying either is very difficult. In NEWCC, they have a clear division of labor and thus can be worked on independently. * Several third party filesystems that use the kernel Cc interface work properly using NEWCC, including matt wu's ext3 driver. * In contrast with code that tries to make CcInitializeCacheMap and CcUninitializeCacheMap into a pair that supports reference counting, NEWCC lazily initializes the shared and private cache maps as needed and uses the presence of a PrivateCacheMap on at least one file pointing to the SharedCacheMap as an indication that the FILE_OBJECT reference in the SharedCacheMap should still be held. When the last PrivateCacheMap is discarded, that's the appropriate time to tear down caching for a specific file, as the SharedCacheMap data is allowed to be saved and reused. We honor this by making the SharedCacheMap into a depot for keeping track of the PrivateCacheMap objects associated with views of a file. svn path=/trunk/; revision=55833
2012-02-23 12:03:06 +00:00
PFILE_OBJECT FileObject;
LARGE_INTEGER RawLength; /* length of the segment which is part of the mapped file */
LARGE_INTEGER Length; /* absolute length of the segment */
ULONG ReferenceCount;
[NEWCC] A reintegration checkpoint for the NewCC branch, brought to you by Team NewCC. Differences with current ReactOS trunk: * A new memory area type, MEMORY_AREA_CACHE, is added, which represents a mapped region of a file. In NEWCC mode, user sections are MEMORY_AREA_CACHE type as well, and obey new semantics. In non-NEWCC mode, they aren't used. * A way of claiming a page entry for a specific thread's work is added. Placing the special SWAPENTRY value MM_WAIT_ENTRY in a page table, or in a section page table should indicate that memory management code is intended to wait for another thread to make some status change before checking the state of the page entry again. In code that uses this convention, a return value of STATUS_SUCCESS + 1 is used to indicate that the caller should use the MiWaitForPageEvent macro to wait until somebody has change the state of a wait entry before checking again. This is a lighter weight mechanism than PAGEOPs. * A way of asking the caller to perform some blocking operation without locks held is provided. This replaces some spaghettified code in which locks are repeatedly taken and broken by code that performs various blocking operations. Using this mechanism, it is possible to do a small amount of non-blocking work, fill in a request, then return STATUS_MORE_PROCESSING_REQUIRED to request that locks be dropped and the blocking operation be carried out. A MM_REQUIRED_RESOURCES structure is provided to consumers of this contract to use to accumulate state across many blocking operations. Several functions wrapping blocking operations are provided in ntoskrnl/cache/reqtools.c. * Image section pages are no longer direct mapped. This is done to simplify consolidation of ownership of pages under the data section system. At a later time, it may be possible to make data pages directly available to image sections for the same file. This is likely the only direct performance impact this code makes on non-NEWCC mode. RMAPs: * A new type of RMAP entry is introduced, distinguished by RMAP_IS_SEGMENT(Address) of the rmap entry. This kind of entry contains a pointer to a section page table node in the Process pointer, which in turn links back to the MM_SECTION_SEGMENT it belongs to. Therefore, a page belonging only to a segment (that is, a segment page that isn't mapped) can exist and be evicted using the normal page eviction mechanism in balance.c. Each of the rmap function has been modified to deal with segment rmaps. * The low 8 bits of the Address field in a segment rmap denote the entry number in the generic table node pointed to by Process that points to the page the rmap belongs to. By combining them, you can determine the file offset the page belongs to. * In NEWCC mode, MmSharePageEntry/UnsharePageEntry are not used, and instead the page reference count is used to keep track of the number of mappings of a page, allowing the last reference expiring to allow the page to be recycled without much intervention. These are still used in non-NEWCC mode. One change has been made, the count fields have been narrowed by 1 bit to make room for a dirty bit in SSE entries, needed when a page is present but unmapped. Section page tables: * The section page tables are now implemented using RtlGenericTables. This enables a fairly compact representation of section page tables without having the existence of a section object imply 4k of fake PDEs. In addition, each node in the generic table has a wide file offset that is a multiple of 256 pages, or 1 megabyte total. Besides needing wide file offsets, the only other visible change caused by the switch to generic tables for section page tables is the need to lock the section segment before interacting with the section page table. Eviction: * Page eviction in cache sections is accomplished by MmpPageOutPhysicalAddress. In the case of a shared page, it tries to remove all mappings of the indicated page. If this process fails at any point, the page will simply be drawn back into the target address spaces. After succeeding at this, if TRUE has been accumulated into the page's dirty bit in the section page table, it is written back, and then permanently removed. NewCC mode: * NEWCC mode is introduced, which rewrites the file cache to a set of cache stripes actively mapped, along with unmapped section data. * NewCC is more authentic in its interpretation of the external interface to the windows cache than the current cache manager, implementing each of the cache manager functions according to the documented interface with no preconceived ideas about how anything should be implemented internally. Cache stripes are implemented on top of section objects, using the same memory manager paths, and therefore economizing code and complexity. This replaces a rather complicated system in which pages can be owned by the cache manager and the memory manager simultaneously and they must cooperate in a fairly sophisticated way to manage them. Since they're quite interdependent in the current code, modifying either is very difficult. In NEWCC, they have a clear division of labor and thus can be worked on independently. * Several third party filesystems that use the kernel Cc interface work properly using NEWCC, including matt wu's ext3 driver. * In contrast with code that tries to make CcInitializeCacheMap and CcUninitializeCacheMap into a pair that supports reference counting, NEWCC lazily initializes the shared and private cache maps as needed and uses the presence of a PrivateCacheMap on at least one file pointing to the SharedCacheMap as an indication that the FILE_OBJECT reference in the SharedCacheMap should still be held. When the last PrivateCacheMap is discarded, that's the appropriate time to tear down caching for a specific file, as the SharedCacheMap data is allowed to be saved and reused. We honor this by making the SharedCacheMap into a depot for keeping track of the PrivateCacheMap objects associated with views of a file. svn path=/trunk/; revision=55833
2012-02-23 12:03:06 +00:00
ULONG CacheCount;
ULONG Protection;
ULONG Flags;
BOOLEAN WriteCopy;
[NEWCC] A reintegration checkpoint for the NewCC branch, brought to you by Team NewCC. Differences with current ReactOS trunk: * A new memory area type, MEMORY_AREA_CACHE, is added, which represents a mapped region of a file. In NEWCC mode, user sections are MEMORY_AREA_CACHE type as well, and obey new semantics. In non-NEWCC mode, they aren't used. * A way of claiming a page entry for a specific thread's work is added. Placing the special SWAPENTRY value MM_WAIT_ENTRY in a page table, or in a section page table should indicate that memory management code is intended to wait for another thread to make some status change before checking the state of the page entry again. In code that uses this convention, a return value of STATUS_SUCCESS + 1 is used to indicate that the caller should use the MiWaitForPageEvent macro to wait until somebody has change the state of a wait entry before checking again. This is a lighter weight mechanism than PAGEOPs. * A way of asking the caller to perform some blocking operation without locks held is provided. This replaces some spaghettified code in which locks are repeatedly taken and broken by code that performs various blocking operations. Using this mechanism, it is possible to do a small amount of non-blocking work, fill in a request, then return STATUS_MORE_PROCESSING_REQUIRED to request that locks be dropped and the blocking operation be carried out. A MM_REQUIRED_RESOURCES structure is provided to consumers of this contract to use to accumulate state across many blocking operations. Several functions wrapping blocking operations are provided in ntoskrnl/cache/reqtools.c. * Image section pages are no longer direct mapped. This is done to simplify consolidation of ownership of pages under the data section system. At a later time, it may be possible to make data pages directly available to image sections for the same file. This is likely the only direct performance impact this code makes on non-NEWCC mode. RMAPs: * A new type of RMAP entry is introduced, distinguished by RMAP_IS_SEGMENT(Address) of the rmap entry. This kind of entry contains a pointer to a section page table node in the Process pointer, which in turn links back to the MM_SECTION_SEGMENT it belongs to. Therefore, a page belonging only to a segment (that is, a segment page that isn't mapped) can exist and be evicted using the normal page eviction mechanism in balance.c. Each of the rmap function has been modified to deal with segment rmaps. * The low 8 bits of the Address field in a segment rmap denote the entry number in the generic table node pointed to by Process that points to the page the rmap belongs to. By combining them, you can determine the file offset the page belongs to. * In NEWCC mode, MmSharePageEntry/UnsharePageEntry are not used, and instead the page reference count is used to keep track of the number of mappings of a page, allowing the last reference expiring to allow the page to be recycled without much intervention. These are still used in non-NEWCC mode. One change has been made, the count fields have been narrowed by 1 bit to make room for a dirty bit in SSE entries, needed when a page is present but unmapped. Section page tables: * The section page tables are now implemented using RtlGenericTables. This enables a fairly compact representation of section page tables without having the existence of a section object imply 4k of fake PDEs. In addition, each node in the generic table has a wide file offset that is a multiple of 256 pages, or 1 megabyte total. Besides needing wide file offsets, the only other visible change caused by the switch to generic tables for section page tables is the need to lock the section segment before interacting with the section page table. Eviction: * Page eviction in cache sections is accomplished by MmpPageOutPhysicalAddress. In the case of a shared page, it tries to remove all mappings of the indicated page. If this process fails at any point, the page will simply be drawn back into the target address spaces. After succeeding at this, if TRUE has been accumulated into the page's dirty bit in the section page table, it is written back, and then permanently removed. NewCC mode: * NEWCC mode is introduced, which rewrites the file cache to a set of cache stripes actively mapped, along with unmapped section data. * NewCC is more authentic in its interpretation of the external interface to the windows cache than the current cache manager, implementing each of the cache manager functions according to the documented interface with no preconceived ideas about how anything should be implemented internally. Cache stripes are implemented on top of section objects, using the same memory manager paths, and therefore economizing code and complexity. This replaces a rather complicated system in which pages can be owned by the cache manager and the memory manager simultaneously and they must cooperate in a fairly sophisticated way to manage them. Since they're quite interdependent in the current code, modifying either is very difficult. In NEWCC, they have a clear division of labor and thus can be worked on independently. * Several third party filesystems that use the kernel Cc interface work properly using NEWCC, including matt wu's ext3 driver. * In contrast with code that tries to make CcInitializeCacheMap and CcUninitializeCacheMap into a pair that supports reference counting, NEWCC lazily initializes the shared and private cache maps as needed and uses the presence of a PrivateCacheMap on at least one file pointing to the SharedCacheMap as an indication that the FILE_OBJECT reference in the SharedCacheMap should still be held. When the last PrivateCacheMap is discarded, that's the appropriate time to tear down caching for a specific file, as the SharedCacheMap data is allowed to be saved and reused. We honor this by making the SharedCacheMap into a depot for keeping track of the PrivateCacheMap objects associated with views of a file. svn path=/trunk/; revision=55833
2012-02-23 12:03:06 +00:00
BOOLEAN Locked;
struct
[NEWCC] A reintegration checkpoint for the NewCC branch, brought to you by Team NewCC. Differences with current ReactOS trunk: * A new memory area type, MEMORY_AREA_CACHE, is added, which represents a mapped region of a file. In NEWCC mode, user sections are MEMORY_AREA_CACHE type as well, and obey new semantics. In non-NEWCC mode, they aren't used. * A way of claiming a page entry for a specific thread's work is added. Placing the special SWAPENTRY value MM_WAIT_ENTRY in a page table, or in a section page table should indicate that memory management code is intended to wait for another thread to make some status change before checking the state of the page entry again. In code that uses this convention, a return value of STATUS_SUCCESS + 1 is used to indicate that the caller should use the MiWaitForPageEvent macro to wait until somebody has change the state of a wait entry before checking again. This is a lighter weight mechanism than PAGEOPs. * A way of asking the caller to perform some blocking operation without locks held is provided. This replaces some spaghettified code in which locks are repeatedly taken and broken by code that performs various blocking operations. Using this mechanism, it is possible to do a small amount of non-blocking work, fill in a request, then return STATUS_MORE_PROCESSING_REQUIRED to request that locks be dropped and the blocking operation be carried out. A MM_REQUIRED_RESOURCES structure is provided to consumers of this contract to use to accumulate state across many blocking operations. Several functions wrapping blocking operations are provided in ntoskrnl/cache/reqtools.c. * Image section pages are no longer direct mapped. This is done to simplify consolidation of ownership of pages under the data section system. At a later time, it may be possible to make data pages directly available to image sections for the same file. This is likely the only direct performance impact this code makes on non-NEWCC mode. RMAPs: * A new type of RMAP entry is introduced, distinguished by RMAP_IS_SEGMENT(Address) of the rmap entry. This kind of entry contains a pointer to a section page table node in the Process pointer, which in turn links back to the MM_SECTION_SEGMENT it belongs to. Therefore, a page belonging only to a segment (that is, a segment page that isn't mapped) can exist and be evicted using the normal page eviction mechanism in balance.c. Each of the rmap function has been modified to deal with segment rmaps. * The low 8 bits of the Address field in a segment rmap denote the entry number in the generic table node pointed to by Process that points to the page the rmap belongs to. By combining them, you can determine the file offset the page belongs to. * In NEWCC mode, MmSharePageEntry/UnsharePageEntry are not used, and instead the page reference count is used to keep track of the number of mappings of a page, allowing the last reference expiring to allow the page to be recycled without much intervention. These are still used in non-NEWCC mode. One change has been made, the count fields have been narrowed by 1 bit to make room for a dirty bit in SSE entries, needed when a page is present but unmapped. Section page tables: * The section page tables are now implemented using RtlGenericTables. This enables a fairly compact representation of section page tables without having the existence of a section object imply 4k of fake PDEs. In addition, each node in the generic table has a wide file offset that is a multiple of 256 pages, or 1 megabyte total. Besides needing wide file offsets, the only other visible change caused by the switch to generic tables for section page tables is the need to lock the section segment before interacting with the section page table. Eviction: * Page eviction in cache sections is accomplished by MmpPageOutPhysicalAddress. In the case of a shared page, it tries to remove all mappings of the indicated page. If this process fails at any point, the page will simply be drawn back into the target address spaces. After succeeding at this, if TRUE has been accumulated into the page's dirty bit in the section page table, it is written back, and then permanently removed. NewCC mode: * NEWCC mode is introduced, which rewrites the file cache to a set of cache stripes actively mapped, along with unmapped section data. * NewCC is more authentic in its interpretation of the external interface to the windows cache than the current cache manager, implementing each of the cache manager functions according to the documented interface with no preconceived ideas about how anything should be implemented internally. Cache stripes are implemented on top of section objects, using the same memory manager paths, and therefore economizing code and complexity. This replaces a rather complicated system in which pages can be owned by the cache manager and the memory manager simultaneously and they must cooperate in a fairly sophisticated way to manage them. Since they're quite interdependent in the current code, modifying either is very difficult. In NEWCC, they have a clear division of labor and thus can be worked on independently. * Several third party filesystems that use the kernel Cc interface work properly using NEWCC, including matt wu's ext3 driver. * In contrast with code that tries to make CcInitializeCacheMap and CcUninitializeCacheMap into a pair that supports reference counting, NEWCC lazily initializes the shared and private cache maps as needed and uses the presence of a PrivateCacheMap on at least one file pointing to the SharedCacheMap as an indication that the FILE_OBJECT reference in the SharedCacheMap should still be held. When the last PrivateCacheMap is discarded, that's the appropriate time to tear down caching for a specific file, as the SharedCacheMap data is allowed to be saved and reused. We honor this by making the SharedCacheMap into a depot for keeping track of the PrivateCacheMap objects associated with views of a file. svn path=/trunk/; revision=55833
2012-02-23 12:03:06 +00:00
{
ULONGLONG FileOffset; /* start offset into the file for image sections */
ULONG_PTR VirtualAddress; /* start offset into the address range for image sections */
[NEWCC] A reintegration checkpoint for the NewCC branch, brought to you by Team NewCC. Differences with current ReactOS trunk: * A new memory area type, MEMORY_AREA_CACHE, is added, which represents a mapped region of a file. In NEWCC mode, user sections are MEMORY_AREA_CACHE type as well, and obey new semantics. In non-NEWCC mode, they aren't used. * A way of claiming a page entry for a specific thread's work is added. Placing the special SWAPENTRY value MM_WAIT_ENTRY in a page table, or in a section page table should indicate that memory management code is intended to wait for another thread to make some status change before checking the state of the page entry again. In code that uses this convention, a return value of STATUS_SUCCESS + 1 is used to indicate that the caller should use the MiWaitForPageEvent macro to wait until somebody has change the state of a wait entry before checking again. This is a lighter weight mechanism than PAGEOPs. * A way of asking the caller to perform some blocking operation without locks held is provided. This replaces some spaghettified code in which locks are repeatedly taken and broken by code that performs various blocking operations. Using this mechanism, it is possible to do a small amount of non-blocking work, fill in a request, then return STATUS_MORE_PROCESSING_REQUIRED to request that locks be dropped and the blocking operation be carried out. A MM_REQUIRED_RESOURCES structure is provided to consumers of this contract to use to accumulate state across many blocking operations. Several functions wrapping blocking operations are provided in ntoskrnl/cache/reqtools.c. * Image section pages are no longer direct mapped. This is done to simplify consolidation of ownership of pages under the data section system. At a later time, it may be possible to make data pages directly available to image sections for the same file. This is likely the only direct performance impact this code makes on non-NEWCC mode. RMAPs: * A new type of RMAP entry is introduced, distinguished by RMAP_IS_SEGMENT(Address) of the rmap entry. This kind of entry contains a pointer to a section page table node in the Process pointer, which in turn links back to the MM_SECTION_SEGMENT it belongs to. Therefore, a page belonging only to a segment (that is, a segment page that isn't mapped) can exist and be evicted using the normal page eviction mechanism in balance.c. Each of the rmap function has been modified to deal with segment rmaps. * The low 8 bits of the Address field in a segment rmap denote the entry number in the generic table node pointed to by Process that points to the page the rmap belongs to. By combining them, you can determine the file offset the page belongs to. * In NEWCC mode, MmSharePageEntry/UnsharePageEntry are not used, and instead the page reference count is used to keep track of the number of mappings of a page, allowing the last reference expiring to allow the page to be recycled without much intervention. These are still used in non-NEWCC mode. One change has been made, the count fields have been narrowed by 1 bit to make room for a dirty bit in SSE entries, needed when a page is present but unmapped. Section page tables: * The section page tables are now implemented using RtlGenericTables. This enables a fairly compact representation of section page tables without having the existence of a section object imply 4k of fake PDEs. In addition, each node in the generic table has a wide file offset that is a multiple of 256 pages, or 1 megabyte total. Besides needing wide file offsets, the only other visible change caused by the switch to generic tables for section page tables is the need to lock the section segment before interacting with the section page table. Eviction: * Page eviction in cache sections is accomplished by MmpPageOutPhysicalAddress. In the case of a shared page, it tries to remove all mappings of the indicated page. If this process fails at any point, the page will simply be drawn back into the target address spaces. After succeeding at this, if TRUE has been accumulated into the page's dirty bit in the section page table, it is written back, and then permanently removed. NewCC mode: * NEWCC mode is introduced, which rewrites the file cache to a set of cache stripes actively mapped, along with unmapped section data. * NewCC is more authentic in its interpretation of the external interface to the windows cache than the current cache manager, implementing each of the cache manager functions according to the documented interface with no preconceived ideas about how anything should be implemented internally. Cache stripes are implemented on top of section objects, using the same memory manager paths, and therefore economizing code and complexity. This replaces a rather complicated system in which pages can be owned by the cache manager and the memory manager simultaneously and they must cooperate in a fairly sophisticated way to manage them. Since they're quite interdependent in the current code, modifying either is very difficult. In NEWCC, they have a clear division of labor and thus can be worked on independently. * Several third party filesystems that use the kernel Cc interface work properly using NEWCC, including matt wu's ext3 driver. * In contrast with code that tries to make CcInitializeCacheMap and CcUninitializeCacheMap into a pair that supports reference counting, NEWCC lazily initializes the shared and private cache maps as needed and uses the presence of a PrivateCacheMap on at least one file pointing to the SharedCacheMap as an indication that the FILE_OBJECT reference in the SharedCacheMap should still be held. When the last PrivateCacheMap is discarded, that's the appropriate time to tear down caching for a specific file, as the SharedCacheMap data is allowed to be saved and reused. We honor this by making the SharedCacheMap into a depot for keeping track of the PrivateCacheMap objects associated with views of a file. svn path=/trunk/; revision=55833
2012-02-23 12:03:06 +00:00
ULONG Characteristics;
} Image;
LIST_ENTRY ListOfSegments;
RTL_GENERIC_TABLE PageTable;
} MM_SECTION_SEGMENT, *PMM_SECTION_SEGMENT;
typedef struct _MM_IMAGE_SECTION_OBJECT
{
SECTION_IMAGE_INFORMATION ImageInformation;
PVOID BasedAddress;
ULONG NrSegments;
PMM_SECTION_SEGMENT Segments;
} MM_IMAGE_SECTION_OBJECT, *PMM_IMAGE_SECTION_OBJECT;
typedef struct _ROS_SECTION_OBJECT
{
CSHORT Type;
CSHORT Size;
LARGE_INTEGER MaximumSize;
ULONG SectionPageProtection;
ULONG AllocationAttributes;
PFILE_OBJECT FileObject;
union
{
PMM_IMAGE_SECTION_OBJECT ImageSection;
PMM_SECTION_SEGMENT Segment;
};
} ROS_SECTION_OBJECT, *PROS_SECTION_OBJECT;
#define MA_GetStartingAddress(_MemoryArea) ((_MemoryArea)->VadNode.StartingVpn << PAGE_SHIFT)
#define MA_GetEndingAddress(_MemoryArea) (((_MemoryArea)->VadNode.EndingVpn + 1) << PAGE_SHIFT)
typedef struct _MEMORY_AREA
{
MMVAD VadNode;
ULONG Type;
ULONG Protect;
ULONG Flags;
BOOLEAN DeleteInProgress;
ULONG Magic;
PVOID Vad;
union
2002-06-11 David Welch <welch@whitehall1-5.seh.ox.ac.uk> * subsys/system/winlogon/winlogon.c (WinMain): Check for failure when creating a window system. 2002-06-11 David Welch <welch@whitehall1-5.seh.ox.ac.uk> * ntoskrnl/ob/handle.c (ObDuplicateObject): Added this internal function for duplicating objects. * ntoskrnl/ps/process.c (NtCreateProcess): Duplicate the parent process's window station to the child process. * ntoskrnl/ps/process.c (PsInitProcessManagement): Initialize the first process's window station. 2002-06-11 David Welch <welch@whitehall1-5.seh.ox.ac.uk> * ntoskrnl/mm/marea.c (MmCreateMemoryArea): Initialise page operation structure members. * ntoskrnl/mm/pageop.c (MmReleasePageOp, MmGetPageOp): Increment or decrement the page operation count in the memory area. * ntoskrnl/mm/virtual.c (MmNotPresentFaultVirtualMemory, MmPageOutVirtualMemory): Check for a deleted memory area before handling the fault. * ntoskrnl/mm/virtual.c (MmFreeVirtualMemory): Wait for all page operations to finish before freeing the memory area. 2002-06-11 David Welch <welch@whitehall1-5.seh.ox.ac.uk> * ntoskrnl/ke/i386/syscall.S (interrupt_handler2e): Corrected test for previous mode, upper 16-bit of CS on the stack after an interrupt are arbitary. 2002-06-11 David Welch <welch@whitehall1-5.seh.ox.ac.uk> * lib/user32/misc/winsta.c: Cleaned up indentation. 2002-06-11 David Welch <welch@whitehall1-5.seh.ox.ac.uk> * apps/tests/winhello/winhello.c (WinMain, MainWndProc): Cleaned up formatting, some more error checks. 2002-06-04 David Welch <welch@whitehall1-5.seh.ox.ac.uk> * ntoskrnl/mm/virtual.c (MmSecureVirtualMemory, MmUnsecureVirtualMemory, NtQueryVirtualMemory): Corrected indentation. svn path=/trunk/; revision=3050
2002-06-11 22:09:03 +00:00
{
struct
{
ROS_SECTION_OBJECT* Section;
[NEWCC] A reintegration checkpoint for the NewCC branch, brought to you by Team NewCC. Differences with current ReactOS trunk: * A new memory area type, MEMORY_AREA_CACHE, is added, which represents a mapped region of a file. In NEWCC mode, user sections are MEMORY_AREA_CACHE type as well, and obey new semantics. In non-NEWCC mode, they aren't used. * A way of claiming a page entry for a specific thread's work is added. Placing the special SWAPENTRY value MM_WAIT_ENTRY in a page table, or in a section page table should indicate that memory management code is intended to wait for another thread to make some status change before checking the state of the page entry again. In code that uses this convention, a return value of STATUS_SUCCESS + 1 is used to indicate that the caller should use the MiWaitForPageEvent macro to wait until somebody has change the state of a wait entry before checking again. This is a lighter weight mechanism than PAGEOPs. * A way of asking the caller to perform some blocking operation without locks held is provided. This replaces some spaghettified code in which locks are repeatedly taken and broken by code that performs various blocking operations. Using this mechanism, it is possible to do a small amount of non-blocking work, fill in a request, then return STATUS_MORE_PROCESSING_REQUIRED to request that locks be dropped and the blocking operation be carried out. A MM_REQUIRED_RESOURCES structure is provided to consumers of this contract to use to accumulate state across many blocking operations. Several functions wrapping blocking operations are provided in ntoskrnl/cache/reqtools.c. * Image section pages are no longer direct mapped. This is done to simplify consolidation of ownership of pages under the data section system. At a later time, it may be possible to make data pages directly available to image sections for the same file. This is likely the only direct performance impact this code makes on non-NEWCC mode. RMAPs: * A new type of RMAP entry is introduced, distinguished by RMAP_IS_SEGMENT(Address) of the rmap entry. This kind of entry contains a pointer to a section page table node in the Process pointer, which in turn links back to the MM_SECTION_SEGMENT it belongs to. Therefore, a page belonging only to a segment (that is, a segment page that isn't mapped) can exist and be evicted using the normal page eviction mechanism in balance.c. Each of the rmap function has been modified to deal with segment rmaps. * The low 8 bits of the Address field in a segment rmap denote the entry number in the generic table node pointed to by Process that points to the page the rmap belongs to. By combining them, you can determine the file offset the page belongs to. * In NEWCC mode, MmSharePageEntry/UnsharePageEntry are not used, and instead the page reference count is used to keep track of the number of mappings of a page, allowing the last reference expiring to allow the page to be recycled without much intervention. These are still used in non-NEWCC mode. One change has been made, the count fields have been narrowed by 1 bit to make room for a dirty bit in SSE entries, needed when a page is present but unmapped. Section page tables: * The section page tables are now implemented using RtlGenericTables. This enables a fairly compact representation of section page tables without having the existence of a section object imply 4k of fake PDEs. In addition, each node in the generic table has a wide file offset that is a multiple of 256 pages, or 1 megabyte total. Besides needing wide file offsets, the only other visible change caused by the switch to generic tables for section page tables is the need to lock the section segment before interacting with the section page table. Eviction: * Page eviction in cache sections is accomplished by MmpPageOutPhysicalAddress. In the case of a shared page, it tries to remove all mappings of the indicated page. If this process fails at any point, the page will simply be drawn back into the target address spaces. After succeeding at this, if TRUE has been accumulated into the page's dirty bit in the section page table, it is written back, and then permanently removed. NewCC mode: * NEWCC mode is introduced, which rewrites the file cache to a set of cache stripes actively mapped, along with unmapped section data. * NewCC is more authentic in its interpretation of the external interface to the windows cache than the current cache manager, implementing each of the cache manager functions according to the documented interface with no preconceived ideas about how anything should be implemented internally. Cache stripes are implemented on top of section objects, using the same memory manager paths, and therefore economizing code and complexity. This replaces a rather complicated system in which pages can be owned by the cache manager and the memory manager simultaneously and they must cooperate in a fairly sophisticated way to manage them. Since they're quite interdependent in the current code, modifying either is very difficult. In NEWCC, they have a clear division of labor and thus can be worked on independently. * Several third party filesystems that use the kernel Cc interface work properly using NEWCC, including matt wu's ext3 driver. * In contrast with code that tries to make CcInitializeCacheMap and CcUninitializeCacheMap into a pair that supports reference counting, NEWCC lazily initializes the shared and private cache maps as needed and uses the presence of a PrivateCacheMap on at least one file pointing to the SharedCacheMap as an indication that the FILE_OBJECT reference in the SharedCacheMap should still be held. When the last PrivateCacheMap is discarded, that's the appropriate time to tear down caching for a specific file, as the SharedCacheMap data is allowed to be saved and reused. We honor this by making the SharedCacheMap into a depot for keeping track of the PrivateCacheMap objects associated with views of a file. svn path=/trunk/; revision=55833
2012-02-23 12:03:06 +00:00
LARGE_INTEGER ViewOffset;
PMM_SECTION_SEGMENT Segment;
LIST_ENTRY RegionListHead;
} SectionData;
struct
{
LIST_ENTRY RegionListHead;
} VirtualMemoryData;
} Data;
} MEMORY_AREA, *PMEMORY_AREA;
typedef struct _MM_RMAP_ENTRY
{
struct _MM_RMAP_ENTRY* Next;
PEPROCESS Process;
PVOID Address;
#if DBG
PVOID Caller;
#endif
}
MM_RMAP_ENTRY, *PMM_RMAP_ENTRY;
#if MI_TRACE_PFNS
extern ULONG MI_PFN_CURRENT_USAGE;
extern CHAR MI_PFN_CURRENT_PROCESS_NAME[16];
#define MI_SET_USAGE(x) MI_PFN_CURRENT_USAGE = x
#define MI_SET_PROCESS2(x) memcpy(MI_PFN_CURRENT_PROCESS_NAME, x, 16)
#else
#define MI_SET_USAGE(x)
#define MI_SET_PROCESS2(x)
#endif
typedef enum _MI_PFN_USAGES
{
MI_USAGE_NOT_SET = 0,
MI_USAGE_PAGED_POOL,
MI_USAGE_NONPAGED_POOL,
MI_USAGE_NONPAGED_POOL_EXPANSION,
MI_USAGE_KERNEL_STACK,
MI_USAGE_KERNEL_STACK_EXPANSION,
MI_USAGE_SYSTEM_PTE,
MI_USAGE_VAD,
MI_USAGE_PEB_TEB,
MI_USAGE_SECTION,
MI_USAGE_PAGE_TABLE,
MI_USAGE_PAGE_DIRECTORY,
MI_USAGE_LEGACY_PAGE_DIRECTORY,
MI_USAGE_DRIVER_PAGE,
MI_USAGE_CONTINOUS_ALLOCATION,
MI_USAGE_MDL,
MI_USAGE_DEMAND_ZERO,
MI_USAGE_ZERO_LOOP,
MI_USAGE_CACHE,
MI_USAGE_PFN_DATABASE,
MI_USAGE_BOOT_DRIVER,
MI_USAGE_INIT_MEMORY,
MI_USAGE_FREE_PAGE
} MI_PFN_USAGES;
//
// These two mappings are actually used by Windows itself, based on the ASSERTS
//
#define StartOfAllocation ReadInProgress
#define EndOfAllocation WriteInProgress
typedef struct _MMPFNENTRY
{
USHORT Modified:1;
USHORT ReadInProgress:1; // StartOfAllocation
USHORT WriteInProgress:1; // EndOfAllocation
USHORT PrototypePte:1;
USHORT PageColor:4;
USHORT PageLocation:3;
USHORT RemovalRequested:1;
USHORT CacheAttribute:2;
USHORT Rom:1;
USHORT ParityError:1;
} MMPFNENTRY;
// Mm internal
typedef struct _MMPFN
{
union
{
PFN_NUMBER Flink;
ULONG WsIndex;
PKEVENT Event;
NTSTATUS ReadStatus;
SINGLE_LIST_ENTRY NextStackPfn;
// HACK for ROSPFN
SWAPENTRY SwapEntry;
} u1;
PMMPTE PteAddress;
union
{
PFN_NUMBER Blink;
ULONG_PTR ShareCount;
} u2;
union
{
struct
{
USHORT ReferenceCount;
MMPFNENTRY e1;
};
struct
{
USHORT ReferenceCount;
USHORT ShortFlags;
} e2;
} u3;
union
{
MMPTE OriginalPte;
LONG AweReferenceCount;
// HACK for ROSPFN
PMM_RMAP_ENTRY RmapListHead;
};
union
{
ULONG_PTR EntireFrame;
struct
{
ULONG_PTR PteFrame:25;
ULONG_PTR InPageError:1;
ULONG_PTR VerifierAllocation:1;
ULONG_PTR AweAllocation:1;
ULONG_PTR Priority:3;
ULONG_PTR MustBeCached:1;
};
} u4;
#if MI_TRACE_PFNS
MI_PFN_USAGES PfnUsage;
CHAR ProcessName[16];
#endif
// HACK until WS lists are supported
MMWSLE Wsle;
} MMPFN, *PMMPFN;
extern PMMPFN MmPfnDatabase;
typedef struct _MMPFNLIST
{
PFN_NUMBER Total;
MMLISTS ListName;
PFN_NUMBER Flink;
PFN_NUMBER Blink;
} MMPFNLIST, *PMMPFNLIST;
extern MMPFNLIST MmZeroedPageListHead;
extern MMPFNLIST MmFreePageListHead;
extern MMPFNLIST MmStandbyPageListHead;
extern MMPFNLIST MmModifiedPageListHead;
extern MMPFNLIST MmModifiedNoWritePageListHead;
typedef struct _MM_MEMORY_CONSUMER
{
ULONG PagesUsed;
ULONG PagesTarget;
NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed);
} MM_MEMORY_CONSUMER, *PMM_MEMORY_CONSUMER;
typedef struct _MM_REGION
{
ULONG Type;
ULONG Protect;
SIZE_T Length;
LIST_ENTRY RegionListEntry;
} MM_REGION, *PMM_REGION;
// Mm internal
/* Entry describing free pool memory */
typedef struct _MMFREE_POOL_ENTRY
{
LIST_ENTRY List;
PFN_COUNT Size;
ULONG Signature;
struct _MMFREE_POOL_ENTRY *Owner;
} MMFREE_POOL_ENTRY, *PMMFREE_POOL_ENTRY;
/* Signature of a freed block */
#define MM_FREE_POOL_SIGNATURE 'ARM3'
/* Paged pool information */
typedef struct _MM_PAGED_POOL_INFO
modified include/reactos/probe.h Workaround for gcc 4.1.3. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 modified ntoskrnl/include/internal/mm.h gcc 4.3.2 doesn't like to be told to inline MmAcquirePageListLock modified ntoskrnl/include/internal/probe.h Cleaning up after TSVN's buggy "apply patch" modified subsystems/win32/win32k/ntuser/message.c Silence a gcc 4.3.2 warning (possibly incorrectly) modified dll/directx/ddraw/ddraw.rbuild modified dll/win32/gdi32/gdi32.rbuild modified dll/win32/kernel32/kernel32.rbuild modified dll/win32/psapi/psapi.rbuild modified dll/win32/setupapi/setupapi.rbuild modified dll/win32/syssetup/syssetup.rbuild modified dll/win32/user32/user32.rbuild modified drivers/input/kbdclass/kbdclass.rbuild modified drivers/input/mouclass/mouclass.rbuild modified drivers/network/afd/afd.rbuild modified drivers/network/tcpip/tcpip.rbuild modified lib/rtl/rtl.rbuild modified subsystems/win32/win32k/win32k.rbuild modified subsystems/win32/win32k/objects/gdiobj.c gcc 4.1.3 workarounds. See embedded comments modified base/services/eventlog/eventlog.h modified dll/win32/advapi32/advapi32.h Removed superfluous includes of pseh/pseh.h modified dll/directx/ddraw/Ddraw/ddraw_displaymode.c modified dll/directx/ddraw/Ddraw/ddraw_main.c modified dll/directx/ddraw/Ddraw/ddraw_setcooperativelevel.c modified dll/directx/ddraw/Ddraw/GetCaps.c modified dll/directx/ddraw/Ddraw/GetDeviceIdentifier.c modified dll/directx/ddraw/main.c modified dll/directx/ddraw/rosdraw.h modified dll/directx/ddraw/Surface/surface_main.c ddraw migrated to PSEH 2.0 modified dll/win32/gdi32/include/precomp.h modified dll/win32/gdi32/misc/misc.c modified dll/win32/gdi32/objects/bitmap.c gdi32 migrated to PSEH 2.0 modified dll/win32/kernel32/except/except.c modified dll/win32/kernel32/file/find.c modified dll/win32/kernel32/k32.h modified dll/win32/kernel32/mem/isbad.c modified dll/win32/kernel32/misc/console.c modified dll/win32/kernel32/process/procsup.c modified dll/win32/kernel32/string/lstring.c modified dll/win32/kernel32/thread/thread.c kernel32 migrated to PSEH 2.0 modified dll/win32/psapi/precomp.h modified dll/win32/psapi/psapi.c psapi migrated to PSEH 2.0 modified dll/win32/setupapi/cfgmgr.c modified dll/win32/setupapi/setupapi_private.h setupapi migrated to PSEH 2.0 modified dll/win32/syssetup/wizard.c syssetup migrated to PSEH 2.0 modified dll/win32/user32/include/user32.h modified dll/win32/user32/windows/class.c modified dll/win32/user32/windows/text.c modified dll/win32/user32/windows/window.c user32 migrated to PSEH 2.0 modified drivers/input/kbdclass/kbdclass.c modified drivers/input/kbdclass/kbdclass.h kbdclass migrated to PSEH 2.0 modified drivers/input/mouclass/mouclass.c modified drivers/input/mouclass/mouclass.h mouclass migrated to PSEH 2.0 modified drivers/network/afd/afd/info.c modified drivers/network/afd/afd/lock.c modified drivers/network/afd/afd/tdi.c modified drivers/network/afd/afd/tdiconn.c afd migrated to PSEH 2.0 modified drivers/network/lan/lan/lan.c lan migrated to PSEH 2.0 modified drivers/network/tcpip/tcpip/dispatch.c tcpip migrated to PSEH 2.0 modified lib/rtl/debug.c modified lib/rtl/res.c modified lib/rtl/rtl.h modified lib/rtl/unicode.c modified lib/rtl/workitem.c rtl migrated to PSEH 2.0 modified ntoskrnl/include/precomp.h ntoskrnl migrated to PSEH 2.0 modified subsystems/csr/csrsrv/api.c csrsrv migrated to PSEH 2.0 modified subsystems/win32/win32k/eng/bitblt.c modified subsystems/win32/win32k/eng/mem.c modified subsystems/win32/win32k/include/mmcopy.h modified subsystems/win32/win32k/misc/copy.c modified subsystems/win32/win32k/ntuser/callback.c modified subsystems/win32/win32k/ntuser/class.c modified subsystems/win32/win32k/ntuser/clipboard.c modified subsystems/win32/win32k/ntuser/cursoricon.c modified subsystems/win32/win32k/ntuser/display.c modified subsystems/win32/win32k/ntuser/hook.c modified subsystems/win32/win32k/ntuser/input.c modified subsystems/win32/win32k/ntuser/kbdlayout.c modified subsystems/win32/win32k/ntuser/menu.c modified subsystems/win32/win32k/ntuser/misc.c modified subsystems/win32/win32k/ntuser/ntstubs.c modified subsystems/win32/win32k/ntuser/painting.c modified subsystems/win32/win32k/ntuser/simplecall.c modified subsystems/win32/win32k/ntuser/sysparams.c modified subsystems/win32/win32k/ntuser/window.c modified subsystems/win32/win32k/objects/bitblt.c modified subsystems/win32/win32k/objects/bitmaps.c modified subsystems/win32/win32k/objects/brush.c modified subsystems/win32/win32k/objects/cliprgn.c modified subsystems/win32/win32k/objects/color.c modified subsystems/win32/win32k/objects/coord.c modified subsystems/win32/win32k/objects/dc.c modified subsystems/win32/win32k/objects/dcutil.c modified subsystems/win32/win32k/objects/dibobj.c modified subsystems/win32/win32k/objects/fillshap.c modified subsystems/win32/win32k/objects/font.c modified subsystems/win32/win32k/objects/freetype.c modified subsystems/win32/win32k/objects/icm.c modified subsystems/win32/win32k/objects/line.c modified subsystems/win32/win32k/objects/path.c modified subsystems/win32/win32k/objects/pen.c modified subsystems/win32/win32k/objects/print.c modified subsystems/win32/win32k/objects/region.c modified subsystems/win32/win32k/objects/text.c modified subsystems/win32/win32k/pch.h win32k migrated to PSEH 2.0 svn path=/trunk/; revision=37776
2008-11-30 19:28:11 +00:00
{
PRTL_BITMAP PagedPoolAllocationMap;
PRTL_BITMAP EndOfPagedPoolBitmap;
PMMPTE FirstPteForPagedPool;
PMMPTE LastPteForPagedPool;
PMMPDE NextPdeForPagedPoolExpansion;
ULONG PagedPoolHint;
SIZE_T PagedPoolCommit;
SIZE_T AllocatedPagedPool;
} MM_PAGED_POOL_INFO, *PMM_PAGED_POOL_INFO;
extern MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM];
/* Page file information */
typedef struct _MMPAGING_FILE
{
PFN_NUMBER Size;
PFN_NUMBER MaximumSize;
PFN_NUMBER MinimumSize;
PFN_NUMBER FreeSpace;
PFN_NUMBER CurrentUsage;
PFILE_OBJECT FileObject;
UNICODE_STRING PageFileName;
PRTL_BITMAP Bitmap;
HANDLE FileHandle;
}
MMPAGING_FILE, *PMMPAGING_FILE;
extern PMMPAGING_FILE MmPagingFile[MAX_PAGING_FILES];
typedef VOID
(*PMM_ALTER_REGION_FUNC)(
PMMSUPPORT AddressSpace,
PVOID BaseAddress,
SIZE_T Length,
ULONG OldType,
ULONG OldProtect,
ULONG NewType,
ULONG NewProtect
);
typedef VOID
(*PMM_FREE_PAGE_FUNC)(
PVOID Context,
PMEMORY_AREA MemoryArea,
PVOID Address,
PFN_NUMBER Page,
SWAPENTRY SwapEntry,
BOOLEAN Dirty
);
//
// Mm copy support for Kd
//
NTSTATUS
NTAPI
MmDbgCopyMemory(
IN ULONG64 Address,
IN PVOID Buffer,
IN ULONG Size,
IN ULONG Flags
);
- Disable the MiCacheImageSymbols call in MmLoadSystemImage for KD too as this hack is required for rossym rather than KDBG. Fixes detection of non-boot driver images by WinDbg. - Add another hack to freeldr.c to make sure that HAL is the second entry in the Load Order list -- detect if it isn't and insert it as the second entry manually if it isn't. - KdbInitialize can now assume that the 2nd entry in the Load Order list is HAL, just like ExpLoadBootSymbols and KD does, so get the Loader Entry directly instead of searching for it. - Move KiBootTss and KiBootGdt to freeldr.c as this is where they belong -- they are not required for NTLDR/WINLDR boot style and are only used directly in freeldr.c. - Get rid of the AcpiTableDetected variable from freeldr.c. Instead, set the AcpiTable entry to something and make PoInitSystem check for that instead to preserve the old behavior. - Implement KdpGetFirstParameter and KdpGetSecondParameter for ARM too -- just retrieve R3/R4 here. Also rename those macros to clarify what parameters we are retrieving. - Add MmIsSessionAddress stub and use it from KD handle session space properly in the Memory Query API, and ASSERT that we are not trying to do a copy to/from session space in MmDbgCopyMemory as we don't handle it properly. Put this in mmdbg.c for now as we don't implement session space, and it is only called from KD right now. - Rename the 3 kdsup.c files to kdx86.c, kdx64.c and kdarm.c to differ them from each other. - Implement KdpAllowDisable -- just check if any processor breakpoints are set on any processor in the system and disallow the disable if so. The routine is now architecture dependant, so move it to the appropriate files. - Get rid of the MmFreeLdr* variables too. These have been deprecated for some time now. - The ModuleObject and ImageBaseAddress parameters of MmLoadSystemImage are not optional so don't treat them as such, and don't zero initialize them as callers shouldn't rely on this. - Set LDRP_ENTRY_NATIVE instead of LDRP_COMPAT_DATABASE_PROCESSED to mark the image as a native image. Also fix the value of LDRP_ENTRY_NATIVE. - Fix definition of LDR_DATA_TABLE_ENTRY -- the Checksum member should be in the union too. - Remove some unnecessary externs for stuff we now define globally in the kernel headers. - Rename some variables in KD to better match the logic. - Move some x86 only stuff from global ke.h and ke_x.h to the x86 dependent ke.h. Remove DR_ACTIVE_MASK as it has been deprecated/unused for a while now. svn path=/trunk/; revision=44023
2009-11-08 01:13:49 +00:00
//
// Determines if a given address is a session address
//
BOOLEAN
NTAPI
MmIsSessionAddress(
IN PVOID Address
);
ULONG
NTAPI
MmGetSessionId(
IN PEPROCESS Process
);
ULONG
NTAPI
MmGetSessionIdEx(
IN PEPROCESS Process
);
/* marea.c *******************************************************************/
NTSTATUS
NTAPI
MmCreateMemoryArea(
PMMSUPPORT AddressSpace,
ULONG Type,
PVOID *BaseAddress,
SIZE_T Length,
ULONG Protection,
PMEMORY_AREA *Result,
ULONG AllocationFlags,
ULONG AllocationGranularity
);
PMEMORY_AREA
NTAPI
MmLocateMemoryAreaByAddress(
PMMSUPPORT AddressSpace,
PVOID Address
);
NTSTATUS
NTAPI
MmFreeMemoryArea(
PMMSUPPORT AddressSpace,
PMEMORY_AREA MemoryArea,
PMM_FREE_PAGE_FUNC FreePage,
PVOID FreePageContext
);
VOID
NTAPI
MiRosCleanupMemoryArea(
PEPROCESS Process,
PMMVAD Vad);
PMEMORY_AREA
NTAPI
MmLocateMemoryAreaByRegion(
PMMSUPPORT AddressSpace,
PVOID Address,
SIZE_T Length
);
PVOID
NTAPI
MmFindGap(
PMMSUPPORT AddressSpace,
SIZE_T Length,
ULONG_PTR Granularity,
BOOLEAN TopDown
);
VOID
NTAPI
MiRosCheckMemoryAreas(
PMMSUPPORT AddressSpace);
VOID
NTAPI
MiCheckAllProcessMemoryAreas(VOID);
/* npool.c *******************************************************************/
INIT_FUNCTION
VOID
NTAPI
MiInitializeNonPagedPool(VOID);
PVOID
NTAPI
MiAllocatePoolPages(
IN POOL_TYPE PoolType,
IN SIZE_T SizeInBytes
);
POOL_TYPE
NTAPI
MmDeterminePoolType(
IN PVOID VirtualAddress
);
ULONG
NTAPI
MiFreePoolPages(
IN PVOID StartingAddress
);
/* pool.c *******************************************************************/
BOOLEAN
NTAPI
MiRaisePoolQuota(
IN POOL_TYPE PoolType,
IN ULONG CurrentMaxQuota,
OUT PULONG NewMaxQuota
);
/* mdl.c *********************************************************************/
VOID
NTAPI
MmBuildMdlFromPages(
PMDL Mdl,
PPFN_NUMBER Pages
);
/* mminit.c ******************************************************************/
VOID
NTAPI
MmInit1(
VOID
);
INIT_FUNCTION
BOOLEAN
NTAPI
MmInitSystem(IN ULONG Phase,
IN PLOADER_PARAMETER_BLOCK LoaderBlock);
/* pagefile.c ****************************************************************/
SWAPENTRY
NTAPI
MmAllocSwapPage(VOID);
VOID
NTAPI
MmFreeSwapPage(SWAPENTRY Entry);
INIT_FUNCTION
VOID
NTAPI
MmInitPagingFile(VOID);
BOOLEAN
NTAPI
MmIsFileObjectAPagingFile(PFILE_OBJECT FileObject);
NTSTATUS
NTAPI
MmReadFromSwapPage(
SWAPENTRY SwapEntry,
PFN_NUMBER Page
);
NTSTATUS
NTAPI
MmWriteToSwapPage(
SWAPENTRY SwapEntry,
PFN_NUMBER Page
);
VOID
NTAPI
MmShowOutOfSpaceMessagePagingFile(VOID);
NTSTATUS
NTAPI
MiReadPageFile(
_In_ PFN_NUMBER Page,
_In_ ULONG PageFileIndex,
_In_ ULONG_PTR PageFileOffset);
/* process.c ****************************************************************/
NTSTATUS
NTAPI
MmInitializeProcessAddressSpace(
IN PEPROCESS Process,
IN PEPROCESS Clone OPTIONAL,
IN PVOID Section OPTIONAL,
IN OUT PULONG Flags,
IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL
);
NTSTATUS
NTAPI
MmCreatePeb(
IN PEPROCESS Process,
IN PINITIAL_PEB InitialPeb,
OUT PPEB *BasePeb
);
NTSTATUS
NTAPI
MmCreateTeb(
IN PEPROCESS Process,
IN PCLIENT_ID ClientId,
IN PINITIAL_TEB InitialTeb,
OUT PTEB* BaseTeb
);
VOID
NTAPI
MmDeleteTeb(
struct _EPROCESS *Process,
PTEB Teb
);
VOID
NTAPI
MmCleanProcessAddressSpace(IN PEPROCESS Process);
NTSTATUS
NTAPI
MmDeleteProcessAddressSpace(IN PEPROCESS Process);
ULONG
NTAPI
MmGetSessionLocaleId(VOID);
NTSTATUS
NTAPI
MmSetMemoryPriorityProcess(
IN PEPROCESS Process,
IN UCHAR MemoryPriority
);
/* i386/pfault.c *************************************************************/
NTSTATUS
NTAPI
MmPageFault(
ULONG Cs,
PULONG Eip,
PULONG Eax,
ULONG Cr2,
ULONG ErrorCode
);
/* special.c *****************************************************************/
VOID
NTAPI
MiInitializeSpecialPool(VOID);
BOOLEAN
NTAPI
MmUseSpecialPool(
IN SIZE_T NumberOfBytes,
IN ULONG Tag);
BOOLEAN
NTAPI
MmIsSpecialPoolAddress(
IN PVOID P);
BOOLEAN
NTAPI
MmIsSpecialPoolAddressFree(
IN PVOID P);
PVOID
NTAPI
MmAllocateSpecialPool(
IN SIZE_T NumberOfBytes,
IN ULONG Tag,
IN POOL_TYPE PoolType,
IN ULONG SpecialType);
VOID
NTAPI
MmFreeSpecialPool(
IN PVOID P);
/* mm.c **********************************************************************/
NTSTATUS
NTAPI
MmAccessFault(
IN ULONG FaultCode,
- Fix critical bugs in exception handling: Unwinding was completely broken, using the wrong SEH protector to detect collided unwinding. The correct protector itself also had a broken check. - Fix architectural bug in the entire TrapFrame<->Context conversion system and Ring Privilege Transitions (Inter-ring and intra-ring) which was lacking proper sanitation and validation of segments, flags and debug registers. Among other things, IOPL is now respected, CS is not KGDT_R0_CODE | RPL_MASK anymore, and the GPF code is now properly being called. This completely fixes exception handling being totally broken and crashing firefox installer, mirc, and other applications. - Rewrite the page fault handler base code in assembly instead of relying on a broken C routine. Detect VDM, V8086, detecting expected/normal fault in ExpInterlockedPopEntrySList and faults in the system handler code. Rewrite MmAccessFault to be the main function that calls out to other sub-fault functions, and use the same prototype as NT. - Fix the KGDT boot table to have proper granularity and big flags, and extend it to 256 entries. - Create proper thread context in RtlInitializeContext and cleanup Rtl Thread routines. - Remove all int3 and breakpoints from trap handlers, and replace them with a much better "UNHANDLED_PATH" macro which freezes the system, beeps, and displays a message with the line of code that's unhandled. This is to clearly tell the user that something is unhandled, instead of nesting infinite exceptions due to the int3. - Fix a bug in INT_PROLOG. - Sanitize EFLAGS and Code Segments in KeContextToTrapFrame and KeTrapFrameToContext. - Implement KiUpdateDr7 and KiRecordDr7 as well as DR_MASK and other DR-validation macros and functions to protect against DR-vulnerabilites as well as to properly account for each active hardware breakpoint in a per-thread fashion by using the dispatcher header. - Allow CR0_EM when running in a VDM. - Fix FPU/NPX Register handling in KeContextToTrapFrame and KeTrapFrameToContext, and also speed it up by manual copying instead of a memory move. - Properly give IOPL 3 to user-mode threads if they requested it. - Detect GPF during GPF. - Detect pagefault with a trap-frame spread over two or more pages and nested. - Properly sanitize and set correct trap frame in KiInitailizeUserApc. - Return STATUS_ACCESS_VIOLATION during page faults instead of STATUS_UNSUCESSFUL. - Fix assert in VdmSwapContext, as well as Code Selector check which was broken. - Fix delayed object deletion (ObDeferDeleteObject) and the Ob Repear Routine and list. - Update Kernel Fun. - BUGBUG: Temporaily hack VMWare to detection to always detect VMWare. svn path=/trunk/; revision=25238
2006-12-29 18:49:00 +00:00
IN PVOID Address,
IN KPROCESSOR_MODE Mode,
IN PVOID TrapInformation
);
/* kmap.c ********************************************************************/
NTSTATUS
NTAPI
MiCopyFromUserPage(
PFN_NUMBER DestPage,
const VOID *SrcAddress
);
/* process.c *****************************************************************/
PVOID
NTAPI
MmCreateKernelStack(BOOLEAN GuiStack, UCHAR Node);
VOID
NTAPI
MmDeleteKernelStack(PVOID Stack,
BOOLEAN GuiStack);
/* balance.c *****************************************************************/
INIT_FUNCTION
VOID
NTAPI
MmInitializeMemoryConsumer(
ULONG Consumer,
NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed)
);
INIT_FUNCTION
VOID
NTAPI
MmInitializeBalancer(
ULONG NrAvailablePages,
ULONG NrSystemPages
);
NTSTATUS
NTAPI
MmReleasePageMemoryConsumer(
ULONG Consumer,
PFN_NUMBER Page
);
NTSTATUS
NTAPI
MmRequestPageMemoryConsumer(
ULONG Consumer,
BOOLEAN MyWait,
PPFN_NUMBER AllocatedPage
);
INIT_FUNCTION
VOID
NTAPI
MiInitBalancerThread(VOID);
VOID
NTAPI
MmRebalanceMemoryConsumers(VOID);
/* rmap.c **************************************************************/
VOID
NTAPI
MmSetRmapListHeadPage(
PFN_NUMBER Page,
struct _MM_RMAP_ENTRY* ListHead
);
struct _MM_RMAP_ENTRY*
NTAPI
MmGetRmapListHeadPage(PFN_NUMBER Page);
VOID
NTAPI
MmInsertRmap(
PFN_NUMBER Page,
struct _EPROCESS *Process,
PVOID Address
);
VOID
NTAPI
MmDeleteAllRmaps(
PFN_NUMBER Page,
PVOID Context,
VOID (*DeleteMapping)(PVOID Context, struct _EPROCESS *Process, PVOID Address)
);
VOID
NTAPI
MmDeleteRmap(
PFN_NUMBER Page,
struct _EPROCESS *Process,
PVOID Address
);
INIT_FUNCTION
VOID
NTAPI
MmInitializeRmapList(VOID);
VOID
NTAPI
MmSetCleanAllRmaps(PFN_NUMBER Page);
VOID
NTAPI
MmSetDirtyAllRmaps(PFN_NUMBER Page);
BOOLEAN
NTAPI
MmIsDirtyPageRmap(PFN_NUMBER Page);
NTSTATUS
NTAPI
MmPageOutPhysicalAddress(PFN_NUMBER Page);
/* freelist.c **********************************************************/
FORCEINLINE
KIRQL
MiAcquirePfnLock(VOID)
{
return KeAcquireQueuedSpinLock(LockQueuePfnLock);
}
FORCEINLINE
VOID
MiReleasePfnLock(
_In_ KIRQL OldIrql)
{
KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
}
FORCEINLINE
VOID
MiAcquirePfnLockAtDpcLevel(VOID)
{
PKSPIN_LOCK_QUEUE LockQueue;
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock];
KeAcquireQueuedSpinLockAtDpcLevel(LockQueue);
}
FORCEINLINE
VOID
MiReleasePfnLockFromDpcLevel(VOID)
{
PKSPIN_LOCK_QUEUE LockQueue;
LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueuePfnLock];
KeReleaseQueuedSpinLockFromDpcLevel(LockQueue);
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
}
#define MI_ASSERT_PFN_LOCK_HELD() ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL)
FORCEINLINE
PMMPFN
MiGetPfnEntry(IN PFN_NUMBER Pfn)
{
PMMPFN Page;
- 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;
/* Make sure the PFN number is valid */
if (Pfn > MmHighestPhysicalPage) return NULL;
- 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
/* Make sure this page actually has a PFN entry */
if ((MiPfnBitMap.Buffer) && !(RtlTestBit(&MiPfnBitMap, (ULONG)Pfn))) return NULL;
/* Get the entry */
Page = &MmPfnDatabase[Pfn];
/* Return it */
return Page;
};
FORCEINLINE
PFN_NUMBER
MiGetPfnEntryIndex(IN PMMPFN Pfn1)
{
//
// This will return the Page Frame Number (PFN) from the MMPFN
//
return Pfn1 - MmPfnDatabase;
}
PFN_NUMBER
NTAPI
MmGetLRUNextUserPage(PFN_NUMBER PreviousPage);
PFN_NUMBER
NTAPI
MmGetLRUFirstUserPage(VOID);
VOID
NTAPI
MmInsertLRULastUserPage(PFN_NUMBER Page);
VOID
NTAPI
MmRemoveLRUUserPage(PFN_NUMBER Page);
VOID
NTAPI
MmDumpArmPfnDatabase(
IN BOOLEAN StatusOnly
);
VOID
NTAPI
MmZeroPageThread(
VOID
);
/* hypermap.c *****************************************************************/
extern PEPROCESS HyperProcess;
extern KIRQL HyperIrql;
PVOID
NTAPI
MiMapPageInHyperSpace(IN PEPROCESS Process,
IN PFN_NUMBER Page,
IN PKIRQL OldIrql);
VOID
NTAPI
MiUnmapPageInHyperSpace(IN PEPROCESS Process,
IN PVOID Address,
IN KIRQL OldIrql);
PVOID
NTAPI
MiMapPagesInZeroSpace(IN PMMPFN Pfn1,
IN PFN_NUMBER NumberOfPages);
VOID
NTAPI
MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress,
IN PFN_NUMBER NumberOfPages);
//
// ReactOS Compatibility Layer
//
FORCEINLINE
PVOID
MmCreateHyperspaceMapping(IN PFN_NUMBER Page)
{
HyperProcess = (PEPROCESS)KeGetCurrentThread()->ApcState.Process;
return MiMapPageInHyperSpace(HyperProcess, Page, &HyperIrql);
}
#define MmDeleteHyperspaceMapping(x) MiUnmapPageInHyperSpace(HyperProcess, x, HyperIrql);
/* i386/page.c *********************************************************/
NTSTATUS
NTAPI
MmCreateVirtualMapping(
struct _EPROCESS* Process,
PVOID Address,
ULONG flProtect,
PPFN_NUMBER Pages,
ULONG PageCount
);
NTSTATUS
NTAPI
MmCreateVirtualMappingUnsafe(
struct _EPROCESS* Process,
PVOID Address,
ULONG flProtect,
PPFN_NUMBER Pages,
ULONG PageCount
);
ULONG
NTAPI
MmGetPageProtect(
struct _EPROCESS* Process,
PVOID Address);
VOID
NTAPI
MmSetPageProtect(
struct _EPROCESS* Process,
PVOID Address,
ULONG flProtect
);
BOOLEAN
NTAPI
MmIsPagePresent(
struct _EPROCESS* Process,
PVOID Address
);
BOOLEAN
NTAPI
MmIsDisabledPage(
struct _EPROCESS* Process,
PVOID Address
);
INIT_FUNCTION
VOID
NTAPI
MmInitGlobalKernelPageDirectory(VOID);
[CACHE] The cache manager rewrite I started years ago has finally appeared in ReactOS' trunk and although at this point it's not quite perfectly integrated, it's enough to boot up the bootcd or livecd. To check out the more mature original, check out arty-newcc-reactos, branch arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit to not give up on it, and was able to reach out and be an advocate when i really wasn't able to. Others agree that the time has come to begin removing the old cache manager. I expect the remaining problems in the version going to trunk will be taken care of relatively quickly. The motivation for this effort lies in the particularly hairy relationship between ReactOS' cache manager and data sections. This code completely removes page sharing between cache manager and section and reimagines cache manager as being a facility layered on the memory manager, not really caring about individual pages, but simply managing data section objects where caching might occur. It took me about 2 years to do the first pass of this rewrite and most of this year to fix some lingering issues, properly implement demand paging in ReactOS (code which didn't come with this patch in a recognizable form), and finish getting the PrivateCacheMap and SharedCacheMap relationship correct. Currently, the new ntoskrnl/cache directory contains an own implementation of data file sections. After things have settled down, we can begin to deprecate and remove the parts of ReactOS' section implementation that depend on a close relationship with cache manager. Eventually, I think that the extra code added to ntoskrnl/cache/section will be removed and ReactOS' own sections will replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache path. Note also, that this makes all cache manager (and new section parts) use wide file offsets. If my section code were to take over other parts of the ReactOS memory manager, they would also benefit from these improvements. I invite anyone who wants to to peek at this code and fix whatever bugs can be found. svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
VOID
NTAPI
MmGetPageFileMapping(
struct _EPROCESS *Process,
[CACHE] The cache manager rewrite I started years ago has finally appeared in ReactOS' trunk and although at this point it's not quite perfectly integrated, it's enough to boot up the bootcd or livecd. To check out the more mature original, check out arty-newcc-reactos, branch arty-newcc on bitbucket.org . Amine Khaldi encouraged me quite a bit to not give up on it, and was able to reach out and be an advocate when i really wasn't able to. Others agree that the time has come to begin removing the old cache manager. I expect the remaining problems in the version going to trunk will be taken care of relatively quickly. The motivation for this effort lies in the particularly hairy relationship between ReactOS' cache manager and data sections. This code completely removes page sharing between cache manager and section and reimagines cache manager as being a facility layered on the memory manager, not really caring about individual pages, but simply managing data section objects where caching might occur. It took me about 2 years to do the first pass of this rewrite and most of this year to fix some lingering issues, properly implement demand paging in ReactOS (code which didn't come with this patch in a recognizable form), and finish getting the PrivateCacheMap and SharedCacheMap relationship correct. Currently, the new ntoskrnl/cache directory contains an own implementation of data file sections. After things have settled down, we can begin to deprecate and remove the parts of ReactOS' section implementation that depend on a close relationship with cache manager. Eventually, I think that the extra code added to ntoskrnl/cache/section will be removed and ReactOS' own sections will replace the use of the special MM_CACHE_SECTION_SEGMENT in the cache path. Note also, that this makes all cache manager (and new section parts) use wide file offsets. If my section code were to take over other parts of the ReactOS memory manager, they would also benefit from these improvements. I invite anyone who wants to to peek at this code and fix whatever bugs can be found. svn path=/trunk/; revision=49423
2010-11-02 02:32:39 +00:00
PVOID Address,
SWAPENTRY* SwapEntry);
VOID
NTAPI
MmDeletePageFileMapping(
struct _EPROCESS *Process,
PVOID Address,
SWAPENTRY* SwapEntry
);
NTSTATUS
NTAPI
MmCreatePageFileMapping(
struct _EPROCESS *Process,
PVOID Address,
SWAPENTRY SwapEntry
);
BOOLEAN
NTAPI
MmIsPageSwapEntry(
struct _EPROCESS *Process,
PVOID Address
);
VOID
NTAPI
MmSetDirtyPage(
struct _EPROCESS *Process,
PVOID Address
);
PFN_NUMBER
NTAPI
MmAllocPage(
ULONG Consumer
);
VOID
NTAPI
MmDereferencePage(PFN_NUMBER Page);
VOID
NTAPI
MmReferencePage(PFN_NUMBER Page);
ULONG
NTAPI
MmGetReferenceCountPage(PFN_NUMBER Page);
BOOLEAN
NTAPI
MmIsPageInUse(PFN_NUMBER Page);
VOID
NTAPI
MmSetSavedSwapEntryPage(
PFN_NUMBER Page,
SWAPENTRY SavedSwapEntry);
SWAPENTRY
NTAPI
MmGetSavedSwapEntryPage(PFN_NUMBER Page);
VOID
NTAPI
MmSetCleanPage(
struct _EPROCESS *Process,
PVOID Address
);
VOID
NTAPI
MmDeletePageTable(
struct _EPROCESS *Process,
PVOID Address
);
PFN_NUMBER
NTAPI
MmGetPfnForProcess(
struct _EPROCESS *Process,
PVOID Address
);
BOOLEAN
NTAPI
MmCreateProcessAddressSpace(
IN ULONG MinWs,
IN PEPROCESS Dest,
IN PULONG_PTR DirectoryTableBase
);
INIT_FUNCTION
NTSTATUS
NTAPI
MmInitializeHandBuiltProcess(
IN PEPROCESS Process,
IN PULONG_PTR DirectoryTableBase
);
INIT_FUNCTION
NTSTATUS
NTAPI
MmInitializeHandBuiltProcess2(
IN PEPROCESS Process
);
NTSTATUS
NTAPI
MmSetExecuteOptions(IN ULONG ExecuteOptions);
NTSTATUS
NTAPI
MmGetExecuteOptions(IN PULONG ExecuteOptions);
VOID
NTAPI
MmDeleteVirtualMapping(
struct _EPROCESS *Process,
PVOID Address,
BOOLEAN* WasDirty,
PPFN_NUMBER Page
);
BOOLEAN
NTAPI
MmIsDirtyPage(
struct _EPROCESS *Process,
PVOID Address
);
/* wset.c ********************************************************************/
NTSTATUS
MmTrimUserMemory(
ULONG Target,
ULONG Priority,
PULONG NrFreedPages
);
/* region.c ************************************************************/
NTSTATUS
NTAPI
MmAlterRegion(
PMMSUPPORT AddressSpace,
PVOID BaseAddress,
PLIST_ENTRY RegionListHead,
PVOID StartAddress,
SIZE_T Length,
ULONG NewType,
ULONG NewProtect,
PMM_ALTER_REGION_FUNC AlterFunc
);
VOID
NTAPI
MmInitializeRegion(
PLIST_ENTRY RegionListHead,
SIZE_T Length,
ULONG Type,
ULONG Protect
);
PMM_REGION
NTAPI
MmFindRegion(
PVOID BaseAddress,
PLIST_ENTRY RegionListHead,
PVOID Address,
PVOID* RegionBaseAddress
);
/* section.c *****************************************************************/
VOID
NTAPI
MmGetImageInformation(
OUT PSECTION_IMAGE_INFORMATION ImageInformation
);
PFILE_OBJECT
NTAPI
MmGetFileObjectForSection(
IN PVOID Section
);
NTSTATUS
NTAPI
MmGetFileNameForAddress(
IN PVOID Address,
OUT PUNICODE_STRING ModuleName
);
NTSTATUS
NTAPI
MmGetFileNameForSection(
IN PVOID Section,
OUT POBJECT_NAME_INFORMATION *ModuleName
);
NTSTATUS
NTAPI
MmQuerySectionView(
PMEMORY_AREA MemoryArea,
PVOID Address,
PMEMORY_BASIC_INFORMATION Info,
PSIZE_T ResultLength
);
NTSTATUS
NTAPI
MmProtectSectionView(
PMMSUPPORT AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID BaseAddress,
SIZE_T Length,
ULONG Protect,
PULONG OldProtect
);
INIT_FUNCTION
NTSTATUS
NTAPI
MmInitSectionImplementation(VOID);
NTSTATUS
NTAPI
MmNotPresentFaultSectionView(
PMMSUPPORT AddressSpace,
MEMORY_AREA* MemoryArea,
[NEWCC] A reintegration checkpoint for the NewCC branch, brought to you by Team NewCC. Differences with current ReactOS trunk: * A new memory area type, MEMORY_AREA_CACHE, is added, which represents a mapped region of a file. In NEWCC mode, user sections are MEMORY_AREA_CACHE type as well, and obey new semantics. In non-NEWCC mode, they aren't used. * A way of claiming a page entry for a specific thread's work is added. Placing the special SWAPENTRY value MM_WAIT_ENTRY in a page table, or in a section page table should indicate that memory management code is intended to wait for another thread to make some status change before checking the state of the page entry again. In code that uses this convention, a return value of STATUS_SUCCESS + 1 is used to indicate that the caller should use the MiWaitForPageEvent macro to wait until somebody has change the state of a wait entry before checking again. This is a lighter weight mechanism than PAGEOPs. * A way of asking the caller to perform some blocking operation without locks held is provided. This replaces some spaghettified code in which locks are repeatedly taken and broken by code that performs various blocking operations. Using this mechanism, it is possible to do a small amount of non-blocking work, fill in a request, then return STATUS_MORE_PROCESSING_REQUIRED to request that locks be dropped and the blocking operation be carried out. A MM_REQUIRED_RESOURCES structure is provided to consumers of this contract to use to accumulate state across many blocking operations. Several functions wrapping blocking operations are provided in ntoskrnl/cache/reqtools.c. * Image section pages are no longer direct mapped. This is done to simplify consolidation of ownership of pages under the data section system. At a later time, it may be possible to make data pages directly available to image sections for the same file. This is likely the only direct performance impact this code makes on non-NEWCC mode. RMAPs: * A new type of RMAP entry is introduced, distinguished by RMAP_IS_SEGMENT(Address) of the rmap entry. This kind of entry contains a pointer to a section page table node in the Process pointer, which in turn links back to the MM_SECTION_SEGMENT it belongs to. Therefore, a page belonging only to a segment (that is, a segment page that isn't mapped) can exist and be evicted using the normal page eviction mechanism in balance.c. Each of the rmap function has been modified to deal with segment rmaps. * The low 8 bits of the Address field in a segment rmap denote the entry number in the generic table node pointed to by Process that points to the page the rmap belongs to. By combining them, you can determine the file offset the page belongs to. * In NEWCC mode, MmSharePageEntry/UnsharePageEntry are not used, and instead the page reference count is used to keep track of the number of mappings of a page, allowing the last reference expiring to allow the page to be recycled without much intervention. These are still used in non-NEWCC mode. One change has been made, the count fields have been narrowed by 1 bit to make room for a dirty bit in SSE entries, needed when a page is present but unmapped. Section page tables: * The section page tables are now implemented using RtlGenericTables. This enables a fairly compact representation of section page tables without having the existence of a section object imply 4k of fake PDEs. In addition, each node in the generic table has a wide file offset that is a multiple of 256 pages, or 1 megabyte total. Besides needing wide file offsets, the only other visible change caused by the switch to generic tables for section page tables is the need to lock the section segment before interacting with the section page table. Eviction: * Page eviction in cache sections is accomplished by MmpPageOutPhysicalAddress. In the case of a shared page, it tries to remove all mappings of the indicated page. If this process fails at any point, the page will simply be drawn back into the target address spaces. After succeeding at this, if TRUE has been accumulated into the page's dirty bit in the section page table, it is written back, and then permanently removed. NewCC mode: * NEWCC mode is introduced, which rewrites the file cache to a set of cache stripes actively mapped, along with unmapped section data. * NewCC is more authentic in its interpretation of the external interface to the windows cache than the current cache manager, implementing each of the cache manager functions according to the documented interface with no preconceived ideas about how anything should be implemented internally. Cache stripes are implemented on top of section objects, using the same memory manager paths, and therefore economizing code and complexity. This replaces a rather complicated system in which pages can be owned by the cache manager and the memory manager simultaneously and they must cooperate in a fairly sophisticated way to manage them. Since they're quite interdependent in the current code, modifying either is very difficult. In NEWCC, they have a clear division of labor and thus can be worked on independently. * Several third party filesystems that use the kernel Cc interface work properly using NEWCC, including matt wu's ext3 driver. * In contrast with code that tries to make CcInitializeCacheMap and CcUninitializeCacheMap into a pair that supports reference counting, NEWCC lazily initializes the shared and private cache maps as needed and uses the presence of a PrivateCacheMap on at least one file pointing to the SharedCacheMap as an indication that the FILE_OBJECT reference in the SharedCacheMap should still be held. When the last PrivateCacheMap is discarded, that's the appropriate time to tear down caching for a specific file, as the SharedCacheMap data is allowed to be saved and reused. We honor this by making the SharedCacheMap into a depot for keeping track of the PrivateCacheMap objects associated with views of a file. svn path=/trunk/; revision=55833
2012-02-23 12:03:06 +00:00
PVOID Address,
BOOLEAN Locked
);
NTSTATUS
NTAPI
MmPageOutSectionView(
PMMSUPPORT AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID Address,
ULONG_PTR Entry
);
INIT_FUNCTION
NTSTATUS
NTAPI
MmCreatePhysicalMemorySection(VOID);
NTSTATUS
NTAPI
MmAccessFaultSectionView(
PMMSUPPORT AddressSpace,
MEMORY_AREA* MemoryArea,
PVOID Address
);
2002-08-14 David Welch <welch@computer2.darkstar.org> * subsys/smss/init.c (SmPagingFilesQueryRoutine): If possible take the size of the paging file from the registry. 2002-08-14 David Welch <welch@computer2.darkstar.org> * ntoskrnl/mm/section.c (MmCreateDataFileSection): Extend the section if necessary. 2002-08-14 David Welch <welch@computer2.darkstar.org> * ntoskrnl/mm/pagefile.c (NtCreatePagingFile): Set the file size using the FileAllocationInformation class. 2002-08-14 David Welch <welch@computer2.darkstar.org> * ntoskrnl/mm/anonmem.c (MmWritePageVirtualMemory): Implemented function to write anonymous memory pages to the swap file. * ntoskrnl/mm/anonmem.c (MmFreeVirtualMemoryPage): Free any swap page associated with the page. * ntoskrnl/mm/mpw.c (MmWriteDirtyPages): New function to find pages to write to disk. * ntoskrnl/mm/mpw.c (MmMpwThreadMain): Implemented MPW functionality. * ntoskrnl/mm/rmap.c (MmWritePagePhysicalAddress): New function to write a single page back to disk. * ntoskrnl/mm/rmap.c (MmSetCleanAllRmaps, MmSetDirtyAllRmaps, MmIsDirtyPageRmap): New rmap function to support the MPW thread. * ntoskrnl/mm/section.c (MmWritePageSectionView): Implemented function to write back section pages. * ntoskrnl/mm/section.c (MmFreeSectionPage): Free any swap entry associated with the page; mark pages shared with the cache as dirty if necessary. 2002-08-14 David Welch <welch@computer2.darkstar.org> * ntoskrnl/ldr/loader.c (LdrPEProcessModule): Set name of the module into the module text structure. 2002-08-14 David Welch <welch@computer2.darkstar.org> * ntoskrnl/io/rw.c (NtReadFile, NtWriteFile): Use the correct test for whether to wait for the completion of i/o. 2002-08-14 David Welch <welch@computer2.darkstar.org> * ntoskrnl/cm/ntfunc.c (NtFlushKey): Request synchronous i/o from NtOpenFile. * ntoskrnl/cm/regfile (CmiInitPermanentRegistryHive): Request synchronous i/o from NtCreateFile. * ntoskrnl/dbg/kdb_stabs.c (LdrpLoadModuleSymbols): Request synchronous i/o from NtOpenFile. * ntoskrnl/ldr/sysdll.c (LdrpMapSystemDll): Request synchronous i/o from NtOpenFile. 2002-08-14 David Welch <welch@computer2.darkstar.org> * ntoskrnl/cc/view.c (CcRosSuggestFreeCacheSegment): Maintain the correct reference count. 2002-08-14 David Welch <welch@computer2.darkstar.org> * ntoskrnl/cc/view.c (CcRosFlushCacheSegment): New function to write back a modified cache segment. * ntoskrnl/cc/view.c (CcRosFlushDirtyPages): New function to flush some dirty pages from the cache. * ntoskrnl/cc/view.c (CcRosMarkDirtyCacheSegment): New function to mark a cache segment modified while mapped into memory as dirty. 2002-08-14 David Welch <welch@computer2.darkstar.org> * ntoskrnl/cc/pin.c (CcMapData, CcUnpinData, CcSetDirtyPinnedData): Store the dirty status in the BCB; don't write back dirty data immediately. 2002-08-14 David Welch <welch@computer2.darkstar.org> * include/ntos/mm.h: Added SEC_XXXX defines from 'Windows NT/2000 Native API Reference' 2002-08-14 David Welch <welch@computer2.darkstar.org> * drivers/fs/vfat/ea.c (VfatSetExtendedAttributes): Empty placeholder for extended attribute functions. 2002-08-14 David Welch <welch@computer2.darkstar.org> * drivers/fs/vfat/finfo.c (VfatSetAllocationSizeInformation): Added function to set allocation size. 2002-08-14 David Welch <welch@computer2.darkstar.org> * drivers/fs/vfat/fcb.c (vfatFCBInitializeCache): Renamed to vfatFCBInitializeCacheFromVolume. * drivers/fs/vfat/fcb.c (vfatMakeFCBFromDirEntry): Don't initialise the cache with a file object representing the volume unless the FCB is for a directory. 2002-08-14 David Welch <welch@computer2.darkstar.org> * drivers/fs/vfat/create.c (VfatPagingFileCreate): Added a new function for handling paging file only code. * drivers/fs/vfat/create.c (VfatSupersedeFile): Added a new function for doing a file supersede. * drivers/fs/vfat/create.c (VfatCreateFile): Reformatted and adjusted control flow. Set allocation size and extended attributes on create. * drivers/fs/vfat/create.c (VfatCreate): Removed goto. 2002-08-14 David Welch <welch@computer2.darkstar.org> * drivers/fs/vfat/cleanup.c (VfatCleanupFile): Renamed updEntry to VfatUpdateEntry. * drivers/fs/vfat/close.c (VfatCloseFile): Renamed updEntry to VfatUpdateEntry. * drivers/fs/vfat/dirwr.c (updEntry): Renamed to VfatUpdateEntry. * drivers/fs/vfat/dirwr.c (addEntry): Renamed to VfatAddEntry. 2002-08-14 David Welch <welch@computer2.darkstar.org> * apps/tests/sectest/sectest.c (main): Fixed formatting. svn path=/trunk/; revision=3331
2002-08-14 20:58:39 +00:00
VOID
NTAPI
MmFreeSectionSegments(PFILE_OBJECT FileObject);
/* sysldr.c ******************************************************************/
INIT_FUNCTION
VOID
NTAPI
MiReloadBootLoadedDrivers(
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
INIT_FUNCTION
BOOLEAN
NTAPI
MiInitializeLoadedModuleList(
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
BOOLEAN
NTAPI
MmChangeKernelResourceSectionProtection(IN ULONG_PTR ProtectionMask);
VOID
NTAPI
MmMakeKernelResourceSectionWritable(VOID);
NTSTATUS
NTAPI
MmLoadSystemImage(
IN PUNICODE_STRING FileName,
IN PUNICODE_STRING NamePrefix OPTIONAL,
IN PUNICODE_STRING LoadedName OPTIONAL,
IN ULONG Flags,
OUT PVOID *ModuleObject,
OUT PVOID *ImageBaseAddress
);
NTSTATUS
NTAPI
MmUnloadSystemImage(
IN PVOID ImageHandle
);
NTSTATUS
NTAPI
MmCheckSystemImage(
IN HANDLE ImageHandle,
IN BOOLEAN PurgeSection
);
NTSTATUS
NTAPI
MmCallDllInitialize(
IN PLDR_DATA_TABLE_ENTRY LdrEntry,
IN PLIST_ENTRY ListHead
);
/* procsup.c *****************************************************************/
NTSTATUS
NTAPI
MmGrowKernelStack(
IN PVOID StackPointer
);
FORCEINLINE
VOID
MmLockAddressSpace(PMMSUPPORT AddressSpace)
{
KeAcquireGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock);
}
FORCEINLINE
VOID
MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
{
KeReleaseGuardedMutex(&CONTAINING_RECORD(AddressSpace, EPROCESS, Vm)->AddressCreationLock);
}
FORCEINLINE
PEPROCESS
MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
{
Looks like this address space nonsense made even less sense than originally understood. The kernel address space was something created very early-on, and associated with a global variable that actually contained the address space itself (so it wasn't part of any process). Its locks however, were associated to the "current process", which, when this function is called, is the idle process (which later is cloned into the initial system process). Shortly thereafter, the address space of the "current process" (still, at this point, the idle process) was initialized with the function reserved for real processes (MmInitializeProcessAddressSpace), which among other things, performed a couple of user-mode mappings (which are irrelevant and should not be part of the system process address space). This created a weird schism: the kernel address space was actually a global variable associated with no process at all, while the kernel process had its own address space as well (which was not the kernel address space). It's a miracle this didn't screw anything up especially since whether or not the address space has an owner determined the lowest address (which means that if the kernel process allocated a memory with its *own* address space, the code would think it was a user-mode process). This patch gets rid of the kernel address space as a static structure, and instead makes it a pointer into the idle/system process' address space. It also gets rid of MmInitializeKernelAddresSpace and instead makes use of the existing MmInitializeHandBuiltProcess, cleaning up the user-mode allocations previously made. Even though all address spaces now have an owner and are part of a process, MmGetAddressSpaceOwner will still return NULL for now, to remain backwards compatible with legacy code. svn path=/trunk/; revision=34876
2008-07-28 00:43:57 +00:00
if (AddressSpace == MmKernelAddressSpace) return NULL;
return CONTAINING_RECORD(AddressSpace, EPROCESS, Vm);
}
FORCEINLINE
PMMSUPPORT
MmGetCurrentAddressSpace(VOID)
{
return &((PEPROCESS)KeGetCurrentThread()->ApcState.Process)->Vm;
}
FORCEINLINE
PMMSUPPORT
MmGetKernelAddressSpace(VOID)
{
Looks like this address space nonsense made even less sense than originally understood. The kernel address space was something created very early-on, and associated with a global variable that actually contained the address space itself (so it wasn't part of any process). Its locks however, were associated to the "current process", which, when this function is called, is the idle process (which later is cloned into the initial system process). Shortly thereafter, the address space of the "current process" (still, at this point, the idle process) was initialized with the function reserved for real processes (MmInitializeProcessAddressSpace), which among other things, performed a couple of user-mode mappings (which are irrelevant and should not be part of the system process address space). This created a weird schism: the kernel address space was actually a global variable associated with no process at all, while the kernel process had its own address space as well (which was not the kernel address space). It's a miracle this didn't screw anything up especially since whether or not the address space has an owner determined the lowest address (which means that if the kernel process allocated a memory with its *own* address space, the code would think it was a user-mode process). This patch gets rid of the kernel address space as a static structure, and instead makes it a pointer into the idle/system process' address space. It also gets rid of MmInitializeKernelAddresSpace and instead makes use of the existing MmInitializeHandBuiltProcess, cleaning up the user-mode allocations previously made. Even though all address spaces now have an owner and are part of a process, MmGetAddressSpaceOwner will still return NULL for now, to remain backwards compatible with legacy code. svn path=/trunk/; revision=34876
2008-07-28 00:43:57 +00:00
return MmKernelAddressSpace;
}
/* expool.c ******************************************************************/
VOID
NTAPI
ExpCheckPoolAllocation(
PVOID P,
POOL_TYPE PoolType,
ULONG Tag);
VOID
NTAPI
ExReturnPoolQuota(
IN PVOID P);
/* mmsup.c *****************************************************************/
NTSTATUS
NTAPI
MmAdjustWorkingSetSize(
IN SIZE_T WorkingSetMinimumInBytes,
IN SIZE_T WorkingSetMaximumInBytes,
IN ULONG SystemCache,
IN BOOLEAN IncreaseOkay);
/* session.c *****************************************************************/
_IRQL_requires_max_(APC_LEVEL)
NTSTATUS
NTAPI
MmAttachSession(
_Inout_ PVOID SessionEntry,
_Out_ PKAPC_STATE ApcState);
_IRQL_requires_max_(APC_LEVEL)
VOID
NTAPI
MmDetachSession(
_Inout_ PVOID SessionEntry,
_Out_ PKAPC_STATE ApcState);
VOID
NTAPI
MmQuitNextSession(
_Inout_ PVOID SessionEntry);
PVOID
NTAPI
MmGetSessionById(
_In_ ULONG SessionId);
_IRQL_requires_max_(APC_LEVEL)
VOID
NTAPI
MmSetSessionLocaleId(
_In_ LCID LocaleId);
2018-08-13 05:42:57 +00:00
/* shutdown.c *****************************************************************/
VOID
MmShutdownSystem(IN ULONG Phase);
/* virtual.c *****************************************************************/
NTSTATUS
NTAPI
MmCopyVirtualMemory(IN PEPROCESS SourceProcess,
IN PVOID SourceAddress,
IN PEPROCESS TargetProcess,
OUT PVOID TargetAddress,
IN SIZE_T BufferSize,
IN KPROCESSOR_MODE PreviousMode,
OUT PSIZE_T ReturnSize);