mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 04:43:51 +00:00
- Changed all internal memory functions to use the page frame number instead of the physical address.
- Allowed MmCreateVirtualMapping to create mappings for more than one page. svn path=/trunk/; revision=10331
This commit is contained in:
parent
5f1aa6ff61
commit
fd411381da
26 changed files with 1029 additions and 1205 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: copy.c,v 1.27 2004/06/21 04:11:44 ion Exp $
|
/* $Id: copy.c,v 1.28 2004/08/01 07:24:57 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -26,11 +26,7 @@
|
||||||
|
|
||||||
#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
|
#define ROUND_DOWN(N, S) ((N) - ((N) % (S)))
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
static PFN_TYPE CcZeroPage = 0;
|
||||||
static PHYSICAL_ADDRESS CcZeroPage = (PHYSICAL_ADDRESS)0LL;
|
|
||||||
#else
|
|
||||||
static PHYSICAL_ADDRESS CcZeroPage = { 0 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAX_ZERO_LENGTH (256 * 1024)
|
#define MAX_ZERO_LENGTH (256 * 1024)
|
||||||
#define MAX_RW_LENGTH (64 * 1024)
|
#define MAX_RW_LENGTH (64 * 1024)
|
||||||
|
@ -54,7 +50,7 @@ CcInitCacheZeroPage(VOID)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &CcZeroPage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &CcZeroPage);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Can't allocate CcZeroPage.\n");
|
DbgPrint("Can't allocate CcZeroPage.\n");
|
||||||
|
@ -122,7 +118,7 @@ ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length,
|
||||||
PCACHE_SEGMENT current2;
|
PCACHE_SEGMENT current2;
|
||||||
ULONG current_size;
|
ULONG current_size;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG offset;
|
PPFN_TYPE MdlPages;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Count the maximum number of bytes we could read starting
|
* Count the maximum number of bytes we could read starting
|
||||||
|
@ -142,17 +138,13 @@ ReadCacheSegmentChain(PBCB Bcb, ULONG ReadOffset, ULONG Length,
|
||||||
MmInitializeMdl(Mdl, NULL, current_size);
|
MmInitializeMdl(Mdl, NULL, current_size);
|
||||||
Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
|
Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
|
||||||
current2 = current;
|
current2 = current;
|
||||||
offset = 0;
|
MdlPages = (PPFN_TYPE)(Mdl + 1);
|
||||||
while (current2 != NULL && !current2->Valid)
|
while (current2 != NULL && !current2->Valid)
|
||||||
{
|
{
|
||||||
for (i = 0; i < (Bcb->CacheSegmentSize / PAGE_SIZE); i++)
|
PVOID address = current2->BaseAddress;
|
||||||
|
for (i = 0; i < (Bcb->CacheSegmentSize / PAGE_SIZE); i++, address += PAGE_SIZE)
|
||||||
{
|
{
|
||||||
PVOID address;
|
*MdlPages++ = MmGetPfnForProcess(NULL, address);
|
||||||
PHYSICAL_ADDRESS page;
|
|
||||||
address = (char*)current2->BaseAddress + (i * PAGE_SIZE);
|
|
||||||
page = MmGetPhysicalAddressForProcess(NULL, address);
|
|
||||||
((PULONG)(Mdl + 1))[offset] = page.QuadPart >> PAGE_SHIFT;
|
|
||||||
offset++;
|
|
||||||
}
|
}
|
||||||
current2 = current2->NextInChain;
|
current2 = current2->NextInChain;
|
||||||
}
|
}
|
||||||
|
@ -649,7 +641,7 @@ CcZeroData (IN PFILE_OBJECT FileObject,
|
||||||
Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
|
Mdl->MdlFlags |= (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
|
||||||
for (i = 0; i < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); i++)
|
for (i = 0; i < ((Mdl->Size - sizeof(MDL)) / sizeof(ULONG)); i++)
|
||||||
{
|
{
|
||||||
((PULONG)(Mdl + 1))[i] = CcZeroPage.QuadPart >> PAGE_SHIFT;
|
((PPFN_TYPE)(Mdl + 1))[i] = CcZeroPage;
|
||||||
}
|
}
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
Status = IoPageWrite(FileObject, Mdl, &WriteOffset, &Event, &Iosb);
|
Status = IoPageWrite(FileObject, Mdl, &WriteOffset, &Event, &Iosb);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: view.c,v 1.72 2004/02/26 19:29:55 hbirr Exp $
|
/* $Id: view.c,v 1.73 2004/08/01 07:24:57 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/cc/view.c
|
* FILE: ntoskrnl/cc/view.c
|
||||||
|
@ -282,8 +282,8 @@ CcRosTrimCache(ULONG Target, ULONG Priority, PULONG NrFreed)
|
||||||
ExReleaseFastMutex(&ViewLock);
|
ExReleaseFastMutex(&ViewLock);
|
||||||
for (i = 0; i < current->Bcb->CacheSegmentSize / PAGE_SIZE; i++)
|
for (i = 0; i < current->Bcb->CacheSegmentSize / PAGE_SIZE; i++)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
Page = MmGetPhysicalAddress((char*)current->BaseAddress + i * PAGE_SIZE);
|
Page = MmGetPhysicalAddress((char*)current->BaseAddress + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT;
|
||||||
Status = MmPageOutPhysicalAddress(Page);
|
Status = MmPageOutPhysicalAddress(Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -488,8 +488,10 @@ CcRosCreateCacheSegment(PBCB Bcb,
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
PPFN_TYPE Pfn;
|
||||||
#ifdef CACHE_BITMAP
|
#ifdef CACHE_BITMAP
|
||||||
ULONG StartingOffset;
|
ULONG StartingOffset;
|
||||||
|
#else
|
||||||
#endif
|
#endif
|
||||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||||
|
|
||||||
|
@ -611,26 +613,24 @@ CcRosCreateCacheSegment(PBCB Bcb,
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Pfn = alloca(sizeof(PFN_TYPE) * (Bcb->CacheSegmentSize / PAGE_SIZE));
|
||||||
for (i = 0; i < (Bcb->CacheSegmentSize / PAGE_SIZE); i++)
|
for (i = 0; i < (Bcb->CacheSegmentSize / PAGE_SIZE); i++)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS Page;
|
Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Pfn[i]);
|
||||||
|
|
||||||
Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Page);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
KEBUGCHECK(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
|
||||||
(char*)current->BaseAddress + (i * PAGE_SIZE),
|
|
||||||
PAGE_READWRITE,
|
|
||||||
Page,
|
|
||||||
TRUE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
|
current->BaseAddress,
|
||||||
|
PAGE_READWRITE,
|
||||||
|
Pfn,
|
||||||
|
Bcb->CacheSegmentSize / PAGE_SIZE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,12 +770,12 @@ CcRosRequestCacheSegment(PBCB Bcb,
|
||||||
#else
|
#else
|
||||||
STATIC VOID
|
STATIC VOID
|
||||||
CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
assert(SwapEntry == 0);
|
assert(SwapEntry == 0);
|
||||||
if (PhysAddr.QuadPart != 0)
|
if (Page != 0)
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_CACHE, PhysAddr);
|
MmReleasePageMemoryConsumer(MC_CACHE, Page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -789,7 +789,7 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg)
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG RegionSize;
|
ULONG RegionSize;
|
||||||
ULONG Base;
|
ULONG Base;
|
||||||
PHYSICAL_ADDRESS PhysicalAddr;
|
PFN_TYPE Page;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
#endif
|
#endif
|
||||||
DPRINT("Freeing cache segment %x\n", CacheSeg);
|
DPRINT("Freeing cache segment %x\n", CacheSeg);
|
||||||
|
@ -803,8 +803,8 @@ CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg)
|
||||||
CacheSeg->BaseAddress + (i * PAGE_SIZE),
|
CacheSeg->BaseAddress + (i * PAGE_SIZE),
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL,
|
NULL,
|
||||||
&PhysicalAddr);
|
&Page);
|
||||||
MmReleasePageMemoryConsumer(MC_CACHE, PhysicalAddr);
|
MmReleasePageMemoryConsumer(MC_CACHE, Page);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql);
|
KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql);
|
||||||
|
|
|
@ -20,6 +20,8 @@ struct _MM_RMAP_ENTRY;
|
||||||
struct _MM_PAGEOP;
|
struct _MM_PAGEOP;
|
||||||
typedef ULONG SWAPENTRY;
|
typedef ULONG SWAPENTRY;
|
||||||
|
|
||||||
|
typedef ULONG PFN_TYPE, *PPFN_TYPE;
|
||||||
|
|
||||||
#define MEMORY_AREA_INVALID (0)
|
#define MEMORY_AREA_INVALID (0)
|
||||||
#define MEMORY_AREA_SECTION_VIEW (1)
|
#define MEMORY_AREA_SECTION_VIEW (1)
|
||||||
#define MEMORY_AREA_CONTINUOUS_MEMORY (2)
|
#define MEMORY_AREA_CONTINUOUS_MEMORY (2)
|
||||||
|
@ -42,6 +44,11 @@ typedef ULONG SWAPENTRY;
|
||||||
#define NR_SECTION_PAGE_TABLES (1024)
|
#define NR_SECTION_PAGE_TABLES (1024)
|
||||||
#define NR_SECTION_PAGE_ENTRIES (1024)
|
#define NR_SECTION_PAGE_ENTRIES (1024)
|
||||||
|
|
||||||
|
#ifndef __USE_W32API
|
||||||
|
#define MM_LOWEST_USER_ADDRESS (4096)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Additional flags for protection attributes
|
* Additional flags for protection attributes
|
||||||
|
@ -178,178 +185,6 @@ extern PVOID MmSystemRangeStart;
|
||||||
|
|
||||||
#endif /* __USE_W32API */
|
#endif /* __USE_W32API */
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS */
|
|
||||||
|
|
||||||
VOID MmLockAddressSpace(PMADDRESS_SPACE AddressSpace);
|
|
||||||
VOID MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace);
|
|
||||||
VOID MmInitializeKernelAddressSpace(VOID);
|
|
||||||
PMADDRESS_SPACE MmGetCurrentAddressSpace(VOID);
|
|
||||||
PMADDRESS_SPACE MmGetKernelAddressSpace(VOID);
|
|
||||||
NTSTATUS MmInitializeAddressSpace(struct _EPROCESS* Process,
|
|
||||||
PMADDRESS_SPACE AddressSpace);
|
|
||||||
NTSTATUS MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace);
|
|
||||||
PVOID STDCALL MmAllocateSection (IN ULONG Length);
|
|
||||||
NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process,
|
|
||||||
PMADDRESS_SPACE AddressSpace,
|
|
||||||
ULONG Type,
|
|
||||||
PVOID* BaseAddress,
|
|
||||||
ULONG Length,
|
|
||||||
ULONG Attributes,
|
|
||||||
MEMORY_AREA** Result,
|
|
||||||
BOOL FixedAddress,
|
|
||||||
BOOL TopDown,
|
|
||||||
PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL);
|
|
||||||
MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
|
|
||||||
PVOID Address);
|
|
||||||
ULONG MmFindGapAtAddress(PMADDRESS_SPACE AddressSpace,
|
|
||||||
PVOID Address);
|
|
||||||
NTSTATUS MmInitMemoryAreas(VOID);
|
|
||||||
VOID MiInitializeNonPagedPool(VOID);
|
|
||||||
NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
|
|
||||||
PVOID BaseAddress,
|
|
||||||
ULONG Length,
|
|
||||||
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea,
|
|
||||||
PVOID Address, PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry,
|
|
||||||
BOOLEAN Dirty),
|
|
||||||
PVOID FreePageContext);
|
|
||||||
VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
|
|
||||||
NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
|
|
||||||
NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
|
|
||||||
NTSTATUS MmInitSectionImplementation(VOID);
|
|
||||||
|
|
||||||
#ifndef __USE_W32API
|
|
||||||
#define MM_LOWEST_USER_ADDRESS (4096)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PMEMORY_AREA MmSplitMemoryArea(struct _EPROCESS* Process,
|
|
||||||
PMADDRESS_SPACE AddressSpace,
|
|
||||||
PMEMORY_AREA OriginalMemoryArea,
|
|
||||||
PVOID BaseAddress,
|
|
||||||
ULONG Length,
|
|
||||||
ULONG NewType,
|
|
||||||
ULONG NewAttributes);
|
|
||||||
PVOID
|
|
||||||
MmInitializePageList(PVOID FirstPhysKernelAddress,
|
|
||||||
PVOID LastPhysKernelAddress,
|
|
||||||
ULONG MemorySizeInPages,
|
|
||||||
ULONG LastKernelBase,
|
|
||||||
PADDRESS_RANGE BIOSMemoryMap,
|
|
||||||
ULONG AddressRangeCount);
|
|
||||||
PHYSICAL_ADDRESS
|
|
||||||
MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry);
|
|
||||||
VOID MmDereferencePage(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
VOID MmReferencePage(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
VOID MmDeletePageTable(struct _EPROCESS* Process,
|
|
||||||
PVOID Address);
|
|
||||||
NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src,
|
|
||||||
struct _EPROCESS* Dest);
|
|
||||||
NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
|
|
||||||
NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
|
|
||||||
VOID
|
|
||||||
MmDeleteVirtualMapping(struct _EPROCESS* Process,
|
|
||||||
PVOID Address,
|
|
||||||
BOOL FreePage,
|
|
||||||
BOOL* WasDirty,
|
|
||||||
PHYSICAL_ADDRESS* PhysicalPage);
|
|
||||||
VOID MmUpdateStackPageDir(PULONG LocalPageDir, struct _KTHREAD* KThread);
|
|
||||||
|
|
||||||
#define MM_PAGE_CLEAN (0)
|
|
||||||
#define MM_PAGE_DIRTY (1)
|
|
||||||
|
|
||||||
VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages);
|
|
||||||
PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset);
|
|
||||||
VOID MiShutdownMemoryManager(VOID);
|
|
||||||
PHYSICAL_ADDRESS
|
|
||||||
MmGetPhysicalAddressForProcess(struct _EPROCESS* Process,
|
|
||||||
PVOID Address);
|
|
||||||
NTSTATUS STDCALL
|
|
||||||
MmUnmapViewOfSection(struct _EPROCESS* Process, PVOID BaseAddress);
|
|
||||||
VOID MmInitPagingFile(VOID);
|
|
||||||
|
|
||||||
/* FIXME: it should be in ddk/mmfuncs.h */
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
MmCreateSection (
|
|
||||||
OUT PSECTION_OBJECT * SectionObject,
|
|
||||||
IN ACCESS_MASK DesiredAccess,
|
|
||||||
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
|
||||||
IN PLARGE_INTEGER MaximumSize,
|
|
||||||
IN ULONG SectionPageProtection,
|
|
||||||
IN ULONG AllocationAttributes,
|
|
||||||
IN HANDLE FileHandle OPTIONAL,
|
|
||||||
IN PFILE_OBJECT File OPTIONAL
|
|
||||||
);
|
|
||||||
|
|
||||||
NTSTATUS MmPageFault(ULONG Cs,
|
|
||||||
PULONG Eip,
|
|
||||||
PULONG Eax,
|
|
||||||
ULONG Cr2,
|
|
||||||
ULONG ErrorCode);
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
MmAccessFault(KPROCESSOR_MODE Mode,
|
|
||||||
ULONG Address,
|
|
||||||
BOOLEAN FromMdl);
|
|
||||||
NTSTATUS
|
|
||||||
MmNotPresentFault(KPROCESSOR_MODE Mode,
|
|
||||||
ULONG Address,
|
|
||||||
BOOLEAN FromMdl);
|
|
||||||
NTSTATUS
|
|
||||||
MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
|
||||||
MEMORY_AREA* MemoryArea,
|
|
||||||
PVOID Address,
|
|
||||||
BOOLEAN Locked);
|
|
||||||
NTSTATUS
|
|
||||||
MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|
||||||
MEMORY_AREA* MemoryArea,
|
|
||||||
PVOID Address,
|
|
||||||
BOOLEAN Locked);
|
|
||||||
NTSTATUS MmWaitForPage(PVOID Page);
|
|
||||||
VOID MmClearWaitPage(PVOID Page);
|
|
||||||
VOID MmSetWaitPage(PVOID Page);
|
|
||||||
BOOLEAN MmIsDirtyPage(struct _EPROCESS* Process, PVOID Address);
|
|
||||||
BOOLEAN MmIsPageTablePresent(PVOID PAddress);
|
|
||||||
NTSTATUS
|
|
||||||
MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
|
||||||
PMEMORY_AREA MemoryArea,
|
|
||||||
PVOID Address,
|
|
||||||
struct _MM_PAGEOP* PageOp);
|
|
||||||
NTSTATUS
|
|
||||||
MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
|
||||||
PMEMORY_AREA MemoryArea,
|
|
||||||
PVOID Address,
|
|
||||||
struct _MM_PAGEOP* PageOp);
|
|
||||||
MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
|
|
||||||
PVOID Address,
|
|
||||||
ULONG Length);
|
|
||||||
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, BOOL TopDown);
|
|
||||||
VOID ExUnmapPage(PVOID Addr);
|
|
||||||
PVOID ExAllocatePage(VOID);
|
|
||||||
|
|
||||||
BOOLEAN MmReserveSwapPages(ULONG Nr);
|
|
||||||
VOID MmDereserveSwapPages(ULONG Nr);
|
|
||||||
SWAPENTRY MmAllocSwapPage(VOID);
|
|
||||||
VOID MmFreeSwapPage(SWAPENTRY Entry);
|
|
||||||
|
|
||||||
VOID MmInit1(ULONG FirstKernelPhysAddress,
|
|
||||||
ULONG LastKernelPhysAddress,
|
|
||||||
ULONG LastKernelAddress,
|
|
||||||
PADDRESS_RANGE BIOSMemoryMap,
|
|
||||||
ULONG AddressRangeCount,
|
|
||||||
ULONG MaxMemInMeg);
|
|
||||||
VOID MmInit2(VOID);
|
|
||||||
VOID MmInit3(VOID);
|
|
||||||
VOID MiFreeInitMemory(VOID);
|
|
||||||
#if 0
|
|
||||||
NTSTATUS MmInitPagerThread(VOID);
|
|
||||||
#endif
|
|
||||||
VOID MiInitBalancerThread(VOID);
|
|
||||||
NTSTATUS MmInitZeroPageThread(VOID);
|
|
||||||
|
|
||||||
VOID MiInitKernelMap(VOID);
|
|
||||||
NTSTATUS MmCreatePageTable(PVOID PAddress);
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ULONG NrTotalPages;
|
ULONG NrTotalPages;
|
||||||
|
@ -366,50 +201,8 @@ typedef struct
|
||||||
|
|
||||||
extern MM_STATS MmStats;
|
extern MM_STATS MmStats;
|
||||||
|
|
||||||
PVOID
|
|
||||||
MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process);
|
|
||||||
NTSTATUS
|
|
||||||
MmWriteToSwapPage(SWAPENTRY SwapEntry, PHYSICAL_ADDRESS* Page);
|
|
||||||
NTSTATUS
|
|
||||||
MmReadFromSwapPage(SWAPENTRY SwapEntry, PHYSICAL_ADDRESS* Page);
|
|
||||||
VOID
|
|
||||||
MmSetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress, ULONG Flags);
|
|
||||||
ULONG
|
|
||||||
MmGetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
VOID MmSetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress,
|
|
||||||
SWAPENTRY SavedSwapEntry);
|
|
||||||
SWAPENTRY MmGetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
VOID MmSetCleanPage(struct _EPROCESS* Process, PVOID Address);
|
|
||||||
VOID MmLockPage(PHYSICAL_ADDRESS PhysicalPage);
|
|
||||||
VOID MmUnlockPage(PHYSICAL_ADDRESS PhysicalPage);
|
|
||||||
ULONG MmGetLockCountPage(PHYSICAL_ADDRESS PhysicalPage);
|
|
||||||
|
|
||||||
NTSTATUS MmSafeCopyFromUser(PVOID Dest, const VOID *Src, ULONG Count);
|
|
||||||
NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG Count);
|
|
||||||
NTSTATUS
|
|
||||||
MmCreatePhysicalMemorySection(VOID);
|
|
||||||
PHYSICAL_ADDRESS
|
|
||||||
MmGetContinuousPages(ULONG NumberOfBytes,
|
|
||||||
PHYSICAL_ADDRESS LowestAcceptableAddress,
|
|
||||||
PHYSICAL_ADDRESS HighestAcceptableAddress,
|
|
||||||
ULONG Alignment);
|
|
||||||
|
|
||||||
#define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
|
#define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
|
||||||
MEMORY_AREA* MemoryArea,
|
|
||||||
PVOID Address,
|
|
||||||
BOOLEAN Locked);
|
|
||||||
ULONG
|
|
||||||
MmGetPageProtect(struct _EPROCESS* Process, PVOID Address);
|
|
||||||
PVOID
|
|
||||||
ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage);
|
|
||||||
ULONG
|
|
||||||
MmGetReferenceCountPage(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
BOOLEAN
|
|
||||||
MmIsUsablePage(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
|
|
||||||
#define MM_PAGEOP_PAGEIN (1)
|
#define MM_PAGEOP_PAGEIN (1)
|
||||||
#define MM_PAGEOP_PAGEOUT (2)
|
#define MM_PAGEOP_PAGEOUT (2)
|
||||||
#define MM_PAGEOP_PAGESYNCH (3)
|
#define MM_PAGEOP_PAGESYNCH (3)
|
||||||
|
@ -446,86 +239,12 @@ typedef struct _MM_PAGEOP
|
||||||
ULONG Offset;
|
ULONG Offset;
|
||||||
} MM_PAGEOP, *PMM_PAGEOP;
|
} MM_PAGEOP, *PMM_PAGEOP;
|
||||||
|
|
||||||
VOID
|
|
||||||
MmReleasePageOp(PMM_PAGEOP PageOp);
|
|
||||||
|
|
||||||
PMM_PAGEOP
|
|
||||||
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
|
||||||
PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType, BOOL First);
|
|
||||||
PMM_PAGEOP
|
|
||||||
MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
|
||||||
PMM_SECTION_SEGMENT Segment, ULONG Offset);
|
|
||||||
VOID
|
|
||||||
MmInitializePageOp(VOID);
|
|
||||||
VOID
|
|
||||||
MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
|
|
||||||
VOID
|
|
||||||
MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly);
|
|
||||||
VOID
|
|
||||||
MmMarkPageMapped(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
VOID
|
|
||||||
MmMarkPageUnmapped(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
VOID
|
|
||||||
MmFreeSectionSegments(PFILE_OBJECT FileObject);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VOID
|
|
||||||
MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea);
|
|
||||||
NTSTATUS
|
|
||||||
MiCopyFromUserPage(PHYSICAL_ADDRESS DestPhysPage, PVOID SourceAddress);
|
|
||||||
NTSTATUS
|
|
||||||
MiZeroPage(PHYSICAL_ADDRESS PhysPage);
|
|
||||||
BOOLEAN
|
|
||||||
MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
|
|
||||||
|
|
||||||
#define STATUS_MM_RESTART_OPERATION ((NTSTATUS)0xD0000001)
|
|
||||||
|
|
||||||
NTSTATUS
|
|
||||||
MmCreateVirtualMappingForKernel(PVOID Address,
|
|
||||||
ULONG flProtect,
|
|
||||||
PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
NTSTATUS MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked);
|
|
||||||
NTSTATUS MmCreateVirtualMapping(struct _EPROCESS* Process,
|
|
||||||
PVOID Address,
|
|
||||||
ULONG flProtect,
|
|
||||||
PHYSICAL_ADDRESS PhysicalAddress,
|
|
||||||
BOOLEAN MayWait);
|
|
||||||
NTSTATUS
|
|
||||||
MmCreateVirtualMappingUnsafe(struct _EPROCESS* Process,
|
|
||||||
PVOID Address,
|
|
||||||
ULONG flProtect,
|
|
||||||
PHYSICAL_ADDRESS PhysicalAddress,
|
|
||||||
BOOLEAN MayWait);
|
|
||||||
|
|
||||||
VOID MmSetPageProtect(struct _EPROCESS* Process,
|
|
||||||
PVOID Address,
|
|
||||||
ULONG flProtect);
|
|
||||||
BOOLEAN MmIsPagePresent(struct _EPROCESS* Process,
|
|
||||||
PVOID Address);
|
|
||||||
|
|
||||||
VOID MmInitGlobalKernelPageDirectory(VOID);
|
|
||||||
|
|
||||||
/* Memory balancing. */
|
|
||||||
VOID
|
|
||||||
MmInitializeMemoryConsumer(ULONG Consumer,
|
|
||||||
NTSTATUS (*Trim)(ULONG Target, ULONG Priority,
|
|
||||||
PULONG NrFreed));
|
|
||||||
VOID
|
|
||||||
MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages);
|
|
||||||
NTSTATUS
|
|
||||||
MmReleasePageMemoryConsumer(ULONG Consumer, PHYSICAL_ADDRESS Page);
|
|
||||||
NTSTATUS
|
|
||||||
MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
|
|
||||||
PHYSICAL_ADDRESS* AllocatedPage);
|
|
||||||
|
|
||||||
#define MC_CACHE (0)
|
#define MC_CACHE (0)
|
||||||
#define MC_USER (1)
|
#define MC_USER (1)
|
||||||
#define MC_PPOOL (2)
|
#define MC_PPOOL (2)
|
||||||
#define MC_NPPOOL (3)
|
#define MC_NPPOOL (3)
|
||||||
#define MC_MAXIMUM (4)
|
#define MC_MAXIMUM (4)
|
||||||
|
|
||||||
|
|
||||||
typedef struct _MM_MEMORY_CONSUMER
|
typedef struct _MM_MEMORY_CONSUMER
|
||||||
{
|
{
|
||||||
ULONG PagesUsed;
|
ULONG PagesUsed;
|
||||||
|
@ -536,56 +255,8 @@ MM_MEMORY_CONSUMER, *PMM_MEMORY_CONSUMER;
|
||||||
|
|
||||||
extern MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM];
|
extern MM_MEMORY_CONSUMER MiMemoryConsumers[MC_MAXIMUM];
|
||||||
|
|
||||||
VOID
|
|
||||||
MmSetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress,
|
|
||||||
struct _MM_RMAP_ENTRY* ListHead);
|
|
||||||
struct _MM_RMAP_ENTRY*
|
|
||||||
MmGetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
VOID
|
|
||||||
MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process,
|
|
||||||
PVOID Address);
|
|
||||||
VOID
|
|
||||||
MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress, PVOID Context,
|
|
||||||
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, PVOID Address));
|
|
||||||
VOID
|
|
||||||
MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process,
|
|
||||||
PVOID Address);
|
|
||||||
VOID
|
|
||||||
MmInitializeRmapList(VOID);
|
|
||||||
PHYSICAL_ADDRESS
|
|
||||||
MmGetLRUNextUserPage(PHYSICAL_ADDRESS PreviousPhysicalAddress);
|
|
||||||
PHYSICAL_ADDRESS
|
|
||||||
MmGetLRUFirstUserPage(VOID);
|
|
||||||
NTSTATUS
|
|
||||||
MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
NTSTATUS
|
|
||||||
MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages);
|
|
||||||
|
|
||||||
VOID
|
|
||||||
MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, PHYSICAL_ADDRESS* PhysicalAddr);
|
|
||||||
VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address);
|
|
||||||
VOID
|
|
||||||
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
|
|
||||||
SWAPENTRY* SwapEntry);
|
|
||||||
NTSTATUS
|
|
||||||
MmCreatePageFileMapping(PEPROCESS Process,
|
|
||||||
PVOID Address,
|
|
||||||
SWAPENTRY SwapEntry);
|
|
||||||
BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address);
|
|
||||||
VOID
|
|
||||||
MmTransferOwnershipPage(PHYSICAL_ADDRESS PhysicalAddress, ULONG NewConsumer);
|
|
||||||
VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address);
|
|
||||||
VOID
|
|
||||||
MmInitializeMdlImplementation(VOID);
|
|
||||||
extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
|
extern PHYSICAL_ADDRESS MmSharedDataPagePhysicalAddress;
|
||||||
struct _KTRAP_FRAME;
|
struct _KTRAP_FRAME;
|
||||||
NTSTATUS STDCALL
|
|
||||||
MmDumpToPagingFile(ULONG BugCode,
|
|
||||||
ULONG BugCodeParameter1,
|
|
||||||
ULONG BugCodeParameter2,
|
|
||||||
ULONG BugCodeParameter3,
|
|
||||||
ULONG BugCodeParameter4,
|
|
||||||
struct _KTRAP_FRAME* TrapFrame);
|
|
||||||
|
|
||||||
typedef VOID (*PMM_ALTER_REGION_FUNC)(PMADDRESS_SPACE AddressSpace,
|
typedef VOID (*PMM_ALTER_REGION_FUNC)(PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID BaseAddress, ULONG Length,
|
PVOID BaseAddress, ULONG Length,
|
||||||
|
@ -600,75 +271,474 @@ typedef struct _MM_REGION
|
||||||
LIST_ENTRY RegionListEntry;
|
LIST_ENTRY RegionListEntry;
|
||||||
} MM_REGION, *PMM_REGION;
|
} MM_REGION, *PMM_REGION;
|
||||||
|
|
||||||
NTSTATUS
|
/* FUNCTIONS */
|
||||||
MmAlterRegion(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress,
|
|
||||||
PLIST_ENTRY RegionListHead, PVOID StartAddress, ULONG Length,
|
/* aspace.c ******************************************************************/
|
||||||
ULONG NewType, ULONG NewProtect,
|
|
||||||
PMM_ALTER_REGION_FUNC AlterFunc);
|
VOID MmLockAddressSpace(PMADDRESS_SPACE AddressSpace);
|
||||||
VOID
|
|
||||||
MmInitialiseRegion(PLIST_ENTRY RegionListHead, ULONG Length, ULONG Type,
|
VOID MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace);
|
||||||
ULONG Protect);
|
|
||||||
PMM_REGION
|
VOID MmInitializeKernelAddressSpace(VOID);
|
||||||
MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address,
|
|
||||||
PVOID* RegionBaseAddress);
|
PMADDRESS_SPACE MmGetCurrentAddressSpace(VOID);
|
||||||
|
|
||||||
|
PMADDRESS_SPACE MmGetKernelAddressSpace(VOID);
|
||||||
|
|
||||||
|
NTSTATUS MmInitializeAddressSpace(struct _EPROCESS* Process,
|
||||||
|
PMADDRESS_SPACE AddressSpace);
|
||||||
|
|
||||||
|
NTSTATUS MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace);
|
||||||
|
|
||||||
|
/* marea.c *******************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process,
|
||||||
|
PMADDRESS_SPACE AddressSpace,
|
||||||
|
ULONG Type,
|
||||||
|
PVOID* BaseAddress,
|
||||||
|
ULONG Length,
|
||||||
|
ULONG Attributes,
|
||||||
|
MEMORY_AREA** Result,
|
||||||
|
BOOL FixedAddress,
|
||||||
|
BOOL TopDown,
|
||||||
|
PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL);
|
||||||
|
|
||||||
|
MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PVOID Address);
|
||||||
|
|
||||||
|
ULONG MmFindGapAtAddress(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PVOID Address);
|
||||||
|
|
||||||
|
NTSTATUS MmInitMemoryAreas(VOID);
|
||||||
|
|
||||||
|
NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PVOID BaseAddress,
|
||||||
|
ULONG Length,
|
||||||
|
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea,
|
||||||
|
PVOID Address, PFN_TYPE Page, SWAPENTRY SwapEntry,
|
||||||
|
BOOLEAN Dirty),
|
||||||
|
PVOID FreePageContext);
|
||||||
|
|
||||||
|
VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
|
||||||
|
|
||||||
|
NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
|
||||||
|
|
||||||
|
NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
|
||||||
|
|
||||||
|
PMEMORY_AREA MmSplitMemoryArea(struct _EPROCESS* Process,
|
||||||
|
PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA OriginalMemoryArea,
|
||||||
|
PVOID BaseAddress,
|
||||||
|
ULONG Length,
|
||||||
|
ULONG NewType,
|
||||||
|
ULONG NewAttributes);
|
||||||
|
|
||||||
|
MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PVOID Address,
|
||||||
|
ULONG Length);
|
||||||
|
|
||||||
|
PVOID MmFindGap(PMADDRESS_SPACE AddressSpace, ULONG Length, BOOL TopDown);
|
||||||
|
|
||||||
|
/* npool.c *******************************************************************/
|
||||||
|
|
||||||
|
VOID MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
|
||||||
|
|
||||||
|
VOID MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly);
|
||||||
|
|
||||||
|
VOID MiInitializeNonPagedPool(VOID);
|
||||||
|
|
||||||
|
PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset);
|
||||||
|
|
||||||
|
/* mdl.c *********************************************************************/
|
||||||
|
|
||||||
|
VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages);
|
||||||
|
|
||||||
|
/* mminit.c ******************************************************************/
|
||||||
|
|
||||||
|
VOID MiShutdownMemoryManager(VOID);
|
||||||
|
|
||||||
|
VOID MmInit1(ULONG FirstKernelPhysAddress,
|
||||||
|
ULONG LastKernelPhysAddress,
|
||||||
|
ULONG LastKernelAddress,
|
||||||
|
PADDRESS_RANGE BIOSMemoryMap,
|
||||||
|
ULONG AddressRangeCount,
|
||||||
|
ULONG MaxMemInMeg);
|
||||||
|
|
||||||
|
VOID MmInit2(VOID);
|
||||||
|
|
||||||
|
VOID MmInit3(VOID);
|
||||||
|
|
||||||
|
VOID MiFreeInitMemory(VOID);
|
||||||
|
|
||||||
|
VOID MmInitializeMdlImplementation(VOID);
|
||||||
|
|
||||||
|
/* pagefile.c ****************************************************************/
|
||||||
|
|
||||||
|
SWAPENTRY MmAllocSwapPage(VOID);
|
||||||
|
|
||||||
|
VOID MmDereserveSwapPages(ULONG Nr);
|
||||||
|
|
||||||
|
VOID MmFreeSwapPage(SWAPENTRY Entry);
|
||||||
|
|
||||||
|
VOID MmInitPagingFile(VOID);
|
||||||
|
|
||||||
|
NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page);
|
||||||
|
|
||||||
|
BOOLEAN MmReserveSwapPages(ULONG Nr);
|
||||||
|
|
||||||
|
NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page);
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
MmDumpToPagingFile(ULONG BugCode,
|
||||||
|
ULONG BugCodeParameter1,
|
||||||
|
ULONG BugCodeParameter2,
|
||||||
|
ULONG BugCodeParameter3,
|
||||||
|
ULONG BugCodeParameter4,
|
||||||
|
struct _KTRAP_FRAME* TrapFrame);
|
||||||
|
|
||||||
|
BOOLEAN MmIsAvailableSwapPage(VOID);
|
||||||
|
|
||||||
|
VOID MmShowOutOfSpaceMessagePagingFile(VOID);
|
||||||
|
|
||||||
|
/* i386/pfault.c *************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS MmPageFault(ULONG Cs,
|
||||||
|
PULONG Eip,
|
||||||
|
PULONG Eax,
|
||||||
|
ULONG Cr2,
|
||||||
|
ULONG ErrorCode);
|
||||||
|
|
||||||
|
/* mm.c **********************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS MmAccessFault(KPROCESSOR_MODE Mode,
|
||||||
|
ULONG Address,
|
||||||
|
BOOLEAN FromMdl);
|
||||||
|
|
||||||
|
NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
|
||||||
|
ULONG Address,
|
||||||
|
BOOLEAN FromMdl);
|
||||||
|
|
||||||
|
/* anonmem.c *****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
|
MEMORY_AREA* MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
BOOLEAN Locked);
|
||||||
|
|
||||||
|
NTSTATUS MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
struct _MM_PAGEOP* PageOp);
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
MmQueryAnonMem(PMEMORY_AREA MemoryArea,
|
MmQueryAnonMem(PMEMORY_AREA MemoryArea,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
PMEMORY_BASIC_INFORMATION Info,
|
PMEMORY_BASIC_INFORMATION Info,
|
||||||
PULONG ResultLength);
|
PULONG ResultLength);
|
||||||
|
|
||||||
|
VOID MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea);
|
||||||
|
|
||||||
|
NTSTATUS MmProtectAnonMem(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID BaseAddress,
|
||||||
|
ULONG Length,
|
||||||
|
ULONG Protect,
|
||||||
|
PULONG OldProtect);
|
||||||
|
|
||||||
|
NTSTATUS MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA MArea,
|
||||||
|
PVOID Address,
|
||||||
|
PMM_PAGEOP PageOp);
|
||||||
|
|
||||||
|
/* kmap.c ********************************************************************/
|
||||||
|
|
||||||
|
PVOID ExAllocatePage(VOID);
|
||||||
|
|
||||||
|
VOID ExUnmapPage(PVOID Addr);
|
||||||
|
|
||||||
|
VOID MiInitKernelMap(VOID);
|
||||||
|
|
||||||
|
PVOID ExAllocatePageWithPhysPage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
NTSTATUS MiCopyFromUserPage(PFN_TYPE Page, PVOID SourceAddress);
|
||||||
|
|
||||||
|
NTSTATUS MiZeroPage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
/* memsafe.s *****************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS MmSafeCopyFromUser(PVOID Dest, const VOID *Src, ULONG Count);
|
||||||
|
|
||||||
|
NTSTATUS MmSafeCopyToUser(PVOID Dest, const VOID *Src, ULONG Count);
|
||||||
|
|
||||||
|
/* pageop.c ******************************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
MmReleasePageOp(PMM_PAGEOP PageOp);
|
||||||
|
|
||||||
|
PMM_PAGEOP
|
||||||
|
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
|
PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType, BOOL First);
|
||||||
|
PMM_PAGEOP
|
||||||
|
MmCheckForPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
|
||||||
|
PMM_SECTION_SEGMENT Segment, ULONG Offset);
|
||||||
|
VOID
|
||||||
|
MmInitializePageOp(VOID);
|
||||||
|
|
||||||
|
/* balace.c ******************************************************************/
|
||||||
|
|
||||||
|
VOID MmInitializeMemoryConsumer(ULONG Consumer,
|
||||||
|
NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed));
|
||||||
|
|
||||||
|
VOID MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages);
|
||||||
|
|
||||||
|
NTSTATUS MmReleasePageMemoryConsumer(ULONG Consumer, PFN_TYPE Page);
|
||||||
|
|
||||||
|
NTSTATUS MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_TYPE AllocatedPage);
|
||||||
|
|
||||||
|
VOID MiInitBalancerThread(VOID);
|
||||||
|
|
||||||
|
VOID MmRebalanceMemoryConsumers(VOID);
|
||||||
|
|
||||||
|
/* rmap.c **************************************************************/
|
||||||
|
|
||||||
|
VOID MmSetRmapListHeadPage(PFN_TYPE Page, struct _MM_RMAP_ENTRY* ListHead);
|
||||||
|
|
||||||
|
struct _MM_RMAP_ENTRY* MmGetRmapListHeadPage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
VOID MmInsertRmap(PFN_TYPE Page, PEPROCESS Process, PVOID Address);
|
||||||
|
|
||||||
|
VOID MmDeleteAllRmaps(PFN_TYPE Page, PVOID Context,
|
||||||
|
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, PVOID Address));
|
||||||
|
|
||||||
|
VOID MmDeleteRmap(PFN_TYPE Page, PEPROCESS Process, PVOID Address);
|
||||||
|
|
||||||
|
VOID MmInitializeRmapList(VOID);
|
||||||
|
|
||||||
|
VOID MmSetCleanAllRmaps(PFN_TYPE Page);
|
||||||
|
|
||||||
|
VOID MmSetDirtyAllRmaps(PFN_TYPE Page);
|
||||||
|
|
||||||
|
BOOL MmIsDirtyPageRmap(PFN_TYPE Page);
|
||||||
|
|
||||||
|
NTSTATUS MmWritePagePhysicalAddress(PFN_TYPE Page);
|
||||||
|
|
||||||
|
NTSTATUS MmPageOutPhysicalAddress(PFN_TYPE Page);
|
||||||
|
|
||||||
|
/* freelist.c **********************************************************/
|
||||||
|
|
||||||
|
PFN_TYPE MmGetLRUNextUserPage(PFN_TYPE PreviousPage);
|
||||||
|
|
||||||
|
PFN_TYPE MmGetLRUFirstUserPage(VOID);
|
||||||
|
|
||||||
|
VOID MmSetLRULastPage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
VOID MmLockPage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
VOID MmUnlockPage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
ULONG MmGetLockCountPage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
|
||||||
|
PVOID LastPhysKernelAddress,
|
||||||
|
ULONG MemorySizeInPages,
|
||||||
|
ULONG LastKernelBase,
|
||||||
|
PADDRESS_RANGE BIOSMemoryMap,
|
||||||
|
ULONG AddressRangeCount);
|
||||||
|
|
||||||
|
PFN_TYPE MmGetContinuousPages(ULONG NumberOfBytes,
|
||||||
|
PHYSICAL_ADDRESS LowestAcceptableAddress,
|
||||||
|
PHYSICAL_ADDRESS HighestAcceptableAddress,
|
||||||
|
ULONG Alignment);
|
||||||
|
|
||||||
|
NTSTATUS MmInitZeroPageThread(VOID);
|
||||||
|
|
||||||
|
/* i386/page.c *********************************************************/
|
||||||
|
|
||||||
|
NTSTATUS MmCreateVirtualMappingForKernel(PVOID Address,
|
||||||
|
ULONG flProtect,
|
||||||
|
PPFN_TYPE Pages,
|
||||||
|
ULONG PageCount);
|
||||||
|
|
||||||
|
NTSTATUS MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked);
|
||||||
|
|
||||||
|
NTSTATUS MmCreateVirtualMapping(struct _EPROCESS* Process,
|
||||||
|
PVOID Address,
|
||||||
|
ULONG flProtect,
|
||||||
|
PPFN_TYPE Pages,
|
||||||
|
ULONG PageCount);
|
||||||
|
|
||||||
|
NTSTATUS MmCreateVirtualMappingUnsafe(struct _EPROCESS* Process,
|
||||||
|
PVOID Address,
|
||||||
|
ULONG flProtect,
|
||||||
|
PPFN_TYPE Pages,
|
||||||
|
ULONG PageCount);
|
||||||
|
|
||||||
|
ULONG MmGetPageProtect(struct _EPROCESS* Process, PVOID Address);
|
||||||
|
|
||||||
|
VOID MmSetPageProtect(struct _EPROCESS* Process,
|
||||||
|
PVOID Address,
|
||||||
|
ULONG flProtect);
|
||||||
|
|
||||||
|
BOOLEAN MmIsPagePresent(struct _EPROCESS* Process,
|
||||||
|
PVOID Address);
|
||||||
|
|
||||||
|
VOID MmInitGlobalKernelPageDirectory(VOID);
|
||||||
|
|
||||||
|
VOID MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, PPFN_TYPE Page);
|
||||||
|
|
||||||
|
VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address);
|
||||||
|
|
||||||
|
VOID MmRawDeleteVirtualMapping(PVOID Address);
|
||||||
|
|
||||||
|
VOID MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY* SwapEntry);
|
||||||
|
|
||||||
|
NTSTATUS MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry);
|
||||||
|
|
||||||
|
BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address);
|
||||||
|
|
||||||
|
VOID MmTransferOwnershipPage(PFN_TYPE Page, ULONG NewConsumer);
|
||||||
|
|
||||||
|
VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address);
|
||||||
|
|
||||||
|
PFN_TYPE MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry);
|
||||||
|
|
||||||
|
VOID MmDereferencePage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
VOID MmReferencePage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
BOOLEAN MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
|
||||||
|
|
||||||
|
ULONG MmGetReferenceCountPage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
BOOLEAN MmIsUsablePage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
VOID MmSetFlagsPage(PFN_TYPE Page, ULONG Flags);
|
||||||
|
|
||||||
|
ULONG MmGetFlagsPage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
VOID MmSetSavedSwapEntryPage(PFN_TYPE Page, SWAPENTRY SavedSwapEntry);
|
||||||
|
|
||||||
|
SWAPENTRY MmGetSavedSwapEntryPage(PFN_TYPE Page);
|
||||||
|
|
||||||
|
VOID MmSetCleanPage(struct _EPROCESS* Process, PVOID Address);
|
||||||
|
|
||||||
|
NTSTATUS MmCreatePageTable(PVOID PAddress);
|
||||||
|
|
||||||
|
VOID MmDeletePageTable(struct _EPROCESS* Process, PVOID Address);
|
||||||
|
|
||||||
|
PFN_TYPE MmGetPfnForProcess(struct _EPROCESS* Process, PVOID Address);
|
||||||
|
|
||||||
|
NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src, struct _EPROCESS* Dest);
|
||||||
|
|
||||||
|
NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
|
||||||
|
|
||||||
|
NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
|
||||||
|
|
||||||
|
VOID MmDeleteVirtualMapping(struct _EPROCESS* Process,
|
||||||
|
PVOID Address,
|
||||||
|
BOOL FreePage,
|
||||||
|
BOOL* WasDirty,
|
||||||
|
PPFN_TYPE Page);
|
||||||
|
|
||||||
|
VOID MmUpdateStackPageDir(PULONG LocalPageDir, struct _KTHREAD* KThread);
|
||||||
|
|
||||||
|
BOOLEAN MmIsDirtyPage(struct _EPROCESS* Process, PVOID Address);
|
||||||
|
|
||||||
|
VOID MmMarkPageMapped(PFN_TYPE Page);
|
||||||
|
|
||||||
|
VOID MmMarkPageUnmapped(PFN_TYPE Page);
|
||||||
|
|
||||||
|
/* wset.c ********************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages);
|
||||||
|
|
||||||
|
/* region.c ************************************************************/
|
||||||
|
|
||||||
|
NTSTATUS MmAlterRegion(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress,
|
||||||
|
PLIST_ENTRY RegionListHead, PVOID StartAddress, ULONG Length,
|
||||||
|
ULONG NewType, ULONG NewProtect,
|
||||||
|
PMM_ALTER_REGION_FUNC AlterFunc);
|
||||||
|
|
||||||
|
VOID MmInitialiseRegion(PLIST_ENTRY RegionListHead, ULONG Length, ULONG Type,
|
||||||
|
ULONG Protect);
|
||||||
|
|
||||||
|
PMM_REGION MmFindRegion(PVOID BaseAddress, PLIST_ENTRY RegionListHead, PVOID Address,
|
||||||
|
PVOID* RegionBaseAddress);
|
||||||
|
|
||||||
|
/* section.c *****************************************************************/
|
||||||
|
|
||||||
|
PVOID STDCALL
|
||||||
|
MmAllocateSection (IN ULONG Length);
|
||||||
|
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
MmQuerySectionView(PMEMORY_AREA MemoryArea,
|
MmQuerySectionView(PMEMORY_AREA MemoryArea,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
PMEMORY_BASIC_INFORMATION Info,
|
PMEMORY_BASIC_INFORMATION Info,
|
||||||
PULONG ResultLength);
|
PULONG ResultLength);
|
||||||
NTSTATUS
|
|
||||||
MmProtectAnonMem(PMADDRESS_SPACE AddressSpace,
|
NTSTATUS
|
||||||
PMEMORY_AREA MemoryArea,
|
|
||||||
PVOID BaseAddress,
|
|
||||||
ULONG Length,
|
|
||||||
ULONG Protect,
|
|
||||||
PULONG OldProtect);
|
|
||||||
NTSTATUS
|
|
||||||
MmProtectSectionView(PMADDRESS_SPACE AddressSpace,
|
MmProtectSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
PMEMORY_AREA MemoryArea,
|
PMEMORY_AREA MemoryArea,
|
||||||
PVOID BaseAddress,
|
PVOID BaseAddress,
|
||||||
ULONG Length,
|
ULONG Length,
|
||||||
ULONG Protect,
|
ULONG Protect,
|
||||||
PULONG OldProtect);
|
PULONG OldProtect);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
PMEMORY_AREA MArea,
|
PMEMORY_AREA MArea,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
PMM_PAGEOP PageOp);
|
PMM_PAGEOP PageOp);
|
||||||
|
|
||||||
|
NTSTATUS MmInitSectionImplementation(VOID);
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
MmUnmapViewOfSection(struct _EPROCESS* Process, PVOID BaseAddress);
|
||||||
|
|
||||||
|
/* FIXME: it should be in ddk/mmfuncs.h */
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
MmCreateSection (OUT PSECTION_OBJECT * SectionObject,
|
||||||
|
IN ACCESS_MASK DesiredAccess,
|
||||||
|
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
|
||||||
|
IN PLARGE_INTEGER MaximumSize,
|
||||||
|
IN ULONG SectionPageProtection,
|
||||||
|
IN ULONG AllocationAttributes,
|
||||||
|
IN HANDLE FileHandle OPTIONAL,
|
||||||
|
IN PFILE_OBJECT File OPTIONAL);
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
PMEMORY_AREA MArea,
|
MEMORY_AREA* MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
BOOLEAN Locked);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
|
PMEMORY_AREA MemoryArea,
|
||||||
|
PVOID Address,
|
||||||
|
struct _MM_PAGEOP* PageOp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmCreatePhysicalMemorySection(VOID);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
|
MEMORY_AREA* MemoryArea,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
PMM_PAGEOP PageOp);
|
BOOLEAN Locked);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmSetCleanAllRmaps(PHYSICAL_ADDRESS PhysicalAddress);
|
MmFreeSectionSegments(PFILE_OBJECT FileObject);
|
||||||
VOID
|
|
||||||
MmSetDirtyAllRmaps(PHYSICAL_ADDRESS PhysicalAddress);
|
/* mpw.c *********************************************************************/
|
||||||
NTSTATUS
|
|
||||||
MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
BOOL
|
|
||||||
MmIsDirtyPageRmap(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
NTSTATUS MmInitMpwThread(VOID);
|
NTSTATUS MmInitMpwThread(VOID);
|
||||||
BOOLEAN
|
|
||||||
MmIsAvailableSwapPage(VOID);
|
/* pager.c *******************************************************************/
|
||||||
VOID
|
|
||||||
MmShowOutOfSpaceMessagePagingFile(VOID);
|
BOOLEAN MiIsPagerThread(VOID);
|
||||||
VOID
|
|
||||||
MmRebalanceMemoryConsumers(VOID);
|
VOID MiStartPagerThread(VOID);
|
||||||
BOOLEAN
|
|
||||||
MiIsPagerThread(VOID);
|
VOID MiStopPagerThread(VOID);
|
||||||
VOID
|
|
||||||
MiStartPagerThread(VOID);
|
|
||||||
VOID
|
|
||||||
MmSetLRULastPage(PHYSICAL_ADDRESS PhysicalAddress);
|
|
||||||
VOID
|
|
||||||
MmRawDeleteVirtualMapping(PVOID Address);
|
|
||||||
VOID
|
|
||||||
MiStopPagerThread(VOID);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: mdl.c,v 1.15 2004/05/15 22:51:38 hbirr Exp $
|
/* $Id: mdl.c,v 1.16 2004/08/01 07:24:57 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <internal/pool.h>
|
#include <internal/pool.h>
|
||||||
|
#include <internal/mm.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
@ -91,8 +92,8 @@ IoBuildPartialMdl(PMDL SourceMdl,
|
||||||
PVOID VirtualAddress,
|
PVOID VirtualAddress,
|
||||||
ULONG Length)
|
ULONG Length)
|
||||||
{
|
{
|
||||||
PULONG TargetPages = (PULONG)(TargetMdl + 1);
|
PPFN_TYPE TargetPages = (PPFN_TYPE)(TargetMdl + 1);
|
||||||
PULONG SourcePages = (PULONG)(SourceMdl + 1);
|
PPFN_TYPE SourcePages = (PPFN_TYPE)(SourceMdl + 1);
|
||||||
ULONG Count;
|
ULONG Count;
|
||||||
ULONG Delta;
|
ULONG Delta;
|
||||||
|
|
||||||
|
@ -116,7 +117,7 @@ IoBuildPartialMdl(PMDL SourceMdl,
|
||||||
|
|
||||||
DPRINT("Delta %d, Count %d\n", Delta, Count);
|
DPRINT("Delta %d, Count %d\n", Delta, Count);
|
||||||
|
|
||||||
memcpy(TargetPages, SourcePages, Count * sizeof(ULONG));
|
memcpy(TargetPages, SourcePages, Count * sizeof(PFN_TYPE));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
ULONG KiPcrInitDone = 0;
|
ULONG KiPcrInitDone = 0;
|
||||||
static ULONG PcrsAllocated = 0;
|
static ULONG PcrsAllocated = 0;
|
||||||
static PHYSICAL_ADDRESS PcrPages[MAXIMUM_PROCESSORS];
|
static PFN_TYPE PcrPages[MAXIMUM_PROCESSORS];
|
||||||
ULONG Ke386CpuidFlags, Ke386CpuidFlags2, Ke386CpuidExFlags;
|
ULONG Ke386CpuidFlags, Ke386CpuidFlags2, Ke386CpuidExFlags;
|
||||||
ULONG Ke386Cpuid = 300;
|
ULONG Ke386Cpuid = 300;
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ Ki386GetCpuId(VOID)
|
||||||
VOID INIT_FUNCTION
|
VOID INIT_FUNCTION
|
||||||
KePrepareForApplicationProcessorInit(ULONG Id)
|
KePrepareForApplicationProcessorInit(ULONG Id)
|
||||||
{
|
{
|
||||||
MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &PcrPages[Id]);
|
MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &PcrPages[Id]);
|
||||||
KiGdtPrepareForApplicationProcessorInit(Id);
|
KiGdtPrepareForApplicationProcessorInit(Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,8 @@ KeApplicationProcessorInit(VOID)
|
||||||
KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGE_SIZE));
|
KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGE_SIZE));
|
||||||
MmCreateVirtualMappingForKernel((PVOID)KPCR,
|
MmCreateVirtualMappingForKernel((PVOID)KPCR,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
PcrPages[Offset]);
|
&PcrPages[Offset],
|
||||||
|
1);
|
||||||
memset(KPCR, 0, PAGE_SIZE);
|
memset(KPCR, 0, PAGE_SIZE);
|
||||||
KPCR->ProcessorNumber = (UCHAR)Offset;
|
KPCR->ProcessorNumber = (UCHAR)Offset;
|
||||||
KPCR->Self = KPCR;
|
KPCR->Self = KPCR;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: kthread.c,v 1.47 2004/06/23 22:31:51 ion Exp $
|
/* $Id: kthread.c,v 1.48 2004/08/01 07:24:59 hbirr Exp $
|
||||||
*
|
*
|
||||||
* FILE: ntoskrnl/ke/kthread.c
|
* FILE: ntoskrnl/ke/kthread.c
|
||||||
* PURPOSE: Microkernel thread support
|
* PURPOSE: Microkernel thread support
|
||||||
|
@ -58,12 +58,12 @@ KeCapturePersistentThreadState(
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
KeFreeStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
KeFreeStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
assert(SwapEntry == 0);
|
assert(SwapEntry == 0);
|
||||||
if (PhysAddr.QuadPart != 0)
|
if (Page != 0)
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysAddr);
|
MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +143,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
||||||
InitializeListHead(&Thread->MutantListHead);
|
InitializeListHead(&Thread->MutantListHead);
|
||||||
if (!First)
|
if (!First)
|
||||||
{
|
{
|
||||||
|
PFN_TYPE Page[MM_STACK_SIZE / PAGE_SIZE];
|
||||||
KernelStack = NULL;
|
KernelStack = NULL;
|
||||||
|
|
||||||
MmLockAddressSpace(MmGetKernelAddressSpace());
|
MmLockAddressSpace(MmGetKernelAddressSpace());
|
||||||
|
@ -165,17 +166,20 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
|
||||||
}
|
}
|
||||||
for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++)
|
for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS Page;
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page[i]);
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
}
|
||||||
(char*)KernelStack + (i * PAGE_SIZE),
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
PAGE_EXECUTE_READWRITE,
|
KernelStack,
|
||||||
Page,
|
PAGE_READWRITE,
|
||||||
TRUE);
|
Page,
|
||||||
|
MM_STACK_SIZE / PAGE_SIZE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
Thread->InitialStack = (char*)KernelStack + MM_STACK_SIZE;
|
Thread->InitialStack = (char*)KernelStack + MM_STACK_SIZE;
|
||||||
Thread->StackBase = (char*)KernelStack + MM_STACK_SIZE;
|
Thread->StackBase = (char*)KernelStack + MM_STACK_SIZE;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: process.c,v 1.20 2004/06/23 22:31:51 ion Exp $
|
/* $Id: process.c,v 1.21 2004/08/01 07:24:59 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/ke/process.c
|
* FILE: ntoskrnl/ke/process.c
|
||||||
|
@ -73,7 +73,7 @@ KeAttachProcess (PEPROCESS Process)
|
||||||
To prevent this, make sure the page directory of the process we're
|
To prevent this, make sure the page directory of the process we're
|
||||||
attaching to is up-to-date. */
|
attaching to is up-to-date. */
|
||||||
|
|
||||||
AttachedProcessPageDir = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase);
|
AttachedProcessPageDir = ExAllocatePageWithPhysPage(Process->Pcb.DirectoryTableBase.QuadPart >> PAGE_SHIFT);
|
||||||
MmUpdateStackPageDir(AttachedProcessPageDir, &CurrentThread->Tcb);
|
MmUpdateStackPageDir(AttachedProcessPageDir, &CurrentThread->Tcb);
|
||||||
ExUnmapPage(AttachedProcessPageDir);
|
ExUnmapPage(AttachedProcessPageDir);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: anonmem.c,v 1.29 2004/07/10 17:01:03 hbirr Exp $
|
/* $Id: anonmem.c,v 1.30 2004/08/01 07:24:57 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/anonmem.c
|
* FILE: ntoskrnl/mm/anonmem.c
|
||||||
|
@ -45,7 +45,7 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
PMM_PAGEOP PageOp)
|
PMM_PAGEOP PageOp)
|
||||||
{
|
{
|
||||||
SWAPENTRY SwapEntry;
|
SWAPENTRY SwapEntry;
|
||||||
LARGE_INTEGER PhysicalAddress;
|
PFN_TYPE Page;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -59,8 +59,7 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
|
|
||||||
PhysicalAddress =
|
Page = MmGetPfnForProcess(AddressSpace->Process, Address);
|
||||||
MmGetPhysicalAddressForProcess(AddressSpace->Process, Address);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get that the page actually is dirty.
|
* Get that the page actually is dirty.
|
||||||
|
@ -81,7 +80,7 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* If necessary, allocate an entry in the paging file for this page
|
* If necessary, allocate an entry in the paging file for this page
|
||||||
*/
|
*/
|
||||||
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
SwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||||
if (SwapEntry == 0)
|
if (SwapEntry == 0)
|
||||||
{
|
{
|
||||||
SwapEntry = MmAllocSwapPage();
|
SwapEntry = MmAllocSwapPage();
|
||||||
|
@ -98,7 +97,7 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Write the page to the pagefile
|
* Write the page to the pagefile
|
||||||
*/
|
*/
|
||||||
Status = MmWriteToSwapPage(SwapEntry, &PhysicalAddress);
|
Status = MmWriteToSwapPage(SwapEntry, Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
|
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
|
||||||
|
@ -113,7 +112,7 @@ MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Otherwise we have succeeded.
|
* Otherwise we have succeeded.
|
||||||
*/
|
*/
|
||||||
MmSetSavedSwapEntryPage(PhysicalAddress, SwapEntry);
|
MmSetSavedSwapEntryPage(Page, SwapEntry);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
|
@ -126,7 +125,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
PMM_PAGEOP PageOp)
|
PMM_PAGEOP PageOp)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS PhysicalAddress;
|
PFN_TYPE Page;
|
||||||
BOOL WasDirty;
|
BOOL WasDirty;
|
||||||
SWAPENTRY SwapEntry;
|
SWAPENTRY SwapEntry;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -149,9 +148,9 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
* Disable the virtual mapping.
|
* Disable the virtual mapping.
|
||||||
*/
|
*/
|
||||||
MmDisableVirtualMapping(MemoryArea->Process, Address,
|
MmDisableVirtualMapping(MemoryArea->Process, Address,
|
||||||
&WasDirty, &PhysicalAddress);
|
&WasDirty, &Page);
|
||||||
|
|
||||||
if (PhysicalAddress.QuadPart == 0)
|
if (Page == 0)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
@ -162,13 +161,13 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
if (!WasDirty)
|
if (!WasDirty)
|
||||||
{
|
{
|
||||||
MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL);
|
MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL);
|
||||||
MmDeleteAllRmaps(PhysicalAddress, NULL, NULL);
|
MmDeleteAllRmaps(Page, NULL, NULL);
|
||||||
if ((SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress)) != 0)
|
if ((SwapEntry = MmGetSavedSwapEntryPage(Page)) != 0)
|
||||||
{
|
{
|
||||||
MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry);
|
MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry);
|
||||||
MmSetSavedSwapEntryPage(PhysicalAddress, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
}
|
}
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
|
@ -178,7 +177,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* If necessary, allocate an entry in the paging file for this page
|
* If necessary, allocate an entry in the paging file for this page
|
||||||
*/
|
*/
|
||||||
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
SwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||||
if (SwapEntry == 0)
|
if (SwapEntry == 0)
|
||||||
{
|
{
|
||||||
SwapEntry = MmAllocSwapPage();
|
SwapEntry = MmAllocSwapPage();
|
||||||
|
@ -196,7 +195,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Write the page to the pagefile
|
* Write the page to the pagefile
|
||||||
*/
|
*/
|
||||||
Status = MmWriteToSwapPage(SwapEntry, &PhysicalAddress);
|
Status = MmWriteToSwapPage(SwapEntry, Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
|
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
|
||||||
|
@ -211,12 +210,12 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Otherwise we have succeeded, free the page
|
* Otherwise we have succeeded, free the page
|
||||||
*/
|
*/
|
||||||
DPRINT("MM: Swapped out virtual memory page 0x%.8X!\n", PhysicalAddress);
|
DPRINT("MM: Swapped out virtual memory page 0x%.8X!\n", Page << PAGE_SHIFT);
|
||||||
MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL);
|
MmDeleteVirtualMapping(MemoryArea->Process, Address, FALSE, NULL, NULL);
|
||||||
MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry);
|
MmCreatePageFileMapping(MemoryArea->Process, Address, SwapEntry);
|
||||||
MmDeleteAllRmaps(PhysicalAddress, NULL, NULL);
|
MmDeleteAllRmaps(Page, NULL, NULL);
|
||||||
MmSetSavedSwapEntryPage(PhysicalAddress, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
|
@ -238,7 +237,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
* NOTES: This function is called with the address space lock held.
|
* NOTES: This function is called with the address space lock held.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PMM_REGION Region;
|
PMM_REGION Region;
|
||||||
PMM_PAGEOP PageOp;
|
PMM_PAGEOP PageOp;
|
||||||
|
@ -252,7 +251,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPfnForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -337,7 +336,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPfnForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
MmReleasePageOp(PageOp);
|
MmReleasePageOp(PageOp);
|
||||||
|
@ -368,7 +367,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
SWAPENTRY SwapEntry;
|
SWAPENTRY SwapEntry;
|
||||||
|
|
||||||
MmDeletePageFileMapping(MemoryArea->Process, Address, &SwapEntry);
|
MmDeletePageFileMapping(MemoryArea->Process, Address, &SwapEntry);
|
||||||
Status = MmReadFromSwapPage(SwapEntry, &Page);
|
Status = MmReadFromSwapPage(SwapEntry, Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
|
@ -383,16 +382,16 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
||||||
(PVOID)PAGE_ROUND_DOWN(Address),
|
(PVOID)PAGE_ROUND_DOWN(Address),
|
||||||
Region->Protect,
|
Region->Protect,
|
||||||
Page,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
while (Status == STATUS_NO_MEMORY)
|
while (Status == STATUS_NO_MEMORY)
|
||||||
{
|
{
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
||||||
Address,
|
Address,
|
||||||
Region->Protect,
|
Region->Protect,
|
||||||
Page,
|
&Page,
|
||||||
TRUE);
|
1);
|
||||||
MmLockAddressSpace(AddressSpace);
|
MmLockAddressSpace(AddressSpace);
|
||||||
}
|
}
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -412,7 +411,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(Page);
|
||||||
}
|
}
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
@ -442,7 +441,7 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
|
||||||
|
|
||||||
for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
|
for (i=0; i < PAGE_ROUND_UP(RegionSize)/PAGE_SIZE; i++)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER PhysicalAddr;
|
PFN_TYPE Page;
|
||||||
|
|
||||||
if (MmIsPageSwapEntry(AddressSpace->Process,
|
if (MmIsPageSwapEntry(AddressSpace->Process,
|
||||||
(char*)BaseAddress + (i * PAGE_SIZE)))
|
(char*)BaseAddress + (i * PAGE_SIZE)))
|
||||||
|
@ -458,19 +457,19 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
MmDeleteVirtualMapping(AddressSpace->Process,
|
MmDeleteVirtualMapping(AddressSpace->Process,
|
||||||
(char*)BaseAddress + (i*PAGE_SIZE),
|
(char*)BaseAddress + (i*PAGE_SIZE),
|
||||||
FALSE, NULL, &PhysicalAddr);
|
FALSE, NULL, &Page);
|
||||||
if (PhysicalAddr.QuadPart != 0)
|
if (Page != 0)
|
||||||
{
|
{
|
||||||
SWAPENTRY SavedSwapEntry;
|
SWAPENTRY SavedSwapEntry;
|
||||||
SavedSwapEntry = MmGetSavedSwapEntryPage(PhysicalAddr);
|
SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||||
if (SavedSwapEntry != 0)
|
if (SavedSwapEntry != 0)
|
||||||
{
|
{
|
||||||
MmFreeSwapPage(SavedSwapEntry);
|
MmFreeSwapPage(SavedSwapEntry);
|
||||||
MmSetSavedSwapEntryPage(PhysicalAddr, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
}
|
}
|
||||||
MmDeleteRmap(PhysicalAddr, AddressSpace->Process,
|
MmDeleteRmap(Page, AddressSpace->Process,
|
||||||
(char*)BaseAddress + (i * PAGE_SIZE));
|
(char*)BaseAddress + (i * PAGE_SIZE));
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddr);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -481,7 +480,7 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
|
||||||
* alter the attributes for any allocated pages within the region
|
* alter the attributes for any allocated pages within the region
|
||||||
*/
|
*/
|
||||||
if (NewType == MEM_COMMIT && OldType == MEM_COMMIT &&
|
if (NewType == MEM_COMMIT && OldType == MEM_COMMIT &&
|
||||||
OldProtect != NewProtect)
|
OldProtect != NewProtect)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
|
@ -665,23 +664,23 @@ VOID STATIC
|
||||||
MmFreeVirtualMemoryPage(PVOID Context,
|
MmFreeVirtualMemoryPage(PVOID Context,
|
||||||
MEMORY_AREA* MemoryArea,
|
MEMORY_AREA* MemoryArea,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
PHYSICAL_ADDRESS PhysicalAddr,
|
PFN_TYPE Page,
|
||||||
SWAPENTRY SwapEntry,
|
SWAPENTRY SwapEntry,
|
||||||
BOOLEAN Dirty)
|
BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
PEPROCESS Process = (PEPROCESS)Context;
|
PEPROCESS Process = (PEPROCESS)Context;
|
||||||
|
|
||||||
if (PhysicalAddr.QuadPart != 0)
|
if (Page != 0)
|
||||||
{
|
{
|
||||||
SWAPENTRY SavedSwapEntry;
|
SWAPENTRY SavedSwapEntry;
|
||||||
SavedSwapEntry = MmGetSavedSwapEntryPage(PhysicalAddr);
|
SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||||
if (SavedSwapEntry != 0)
|
if (SavedSwapEntry != 0)
|
||||||
{
|
{
|
||||||
MmFreeSwapPage(SavedSwapEntry);
|
MmFreeSwapPage(SavedSwapEntry);
|
||||||
MmSetSavedSwapEntryPage(PhysicalAddr, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
}
|
}
|
||||||
MmDeleteRmap(PhysicalAddr, Process, Address);
|
MmDeleteRmap(Page, Process, Address);
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddr);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
}
|
}
|
||||||
else if (SwapEntry != 0)
|
else if (SwapEntry != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: balance.c,v 1.30 2004/07/31 09:44:35 hbirr Exp $
|
/* $Id: balance.c,v 1.31 2004/08/01 07:24:57 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/balance.c
|
* FILE: ntoskrnl/mm/balance.c
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
/* TYPES ********************************************************************/
|
/* TYPES ********************************************************************/
|
||||||
typedef struct _MM_ALLOCATION_REQUEST
|
typedef struct _MM_ALLOCATION_REQUEST
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
}
|
}
|
||||||
|
@ -98,19 +98,13 @@ MmInitializeMemoryConsumer(ULONG Consumer,
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmReleasePageMemoryConsumer(ULONG Consumer, PHYSICAL_ADDRESS Page)
|
MmReleasePageMemoryConsumer(ULONG Consumer, PFN_TYPE Page)
|
||||||
{
|
{
|
||||||
PMM_ALLOCATION_REQUEST Request;
|
PMM_ALLOCATION_REQUEST Request;
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
if (Page == 0)
|
||||||
|
|
||||||
if (Page.QuadPart == 0LL)
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (Page.QuadPart == 0)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
DPRINT1("Tried to release page zero.\n");
|
DPRINT1("Tried to release page zero.\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
|
@ -196,10 +190,10 @@ MiIsBalancerThread(VOID)
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
|
MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
|
||||||
PHYSICAL_ADDRESS* AllocatedPage)
|
PPFN_TYPE AllocatedPage)
|
||||||
{
|
{
|
||||||
ULONG OldUsed;
|
ULONG OldUsed;
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -223,14 +217,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
|
||||||
if (Consumer == MC_NPPOOL || MiIsBalancerThread())
|
if (Consumer == MC_NPPOOL || MiIsBalancerThread())
|
||||||
{
|
{
|
||||||
Page = MmAllocPage(Consumer, 0);
|
Page = MmAllocPage(Consumer, 0);
|
||||||
#if defined(__GNUC__)
|
if (Page == 0)
|
||||||
|
|
||||||
if (Page.QuadPart == 0LL)
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (Page.QuadPart == 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
@ -257,12 +244,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Insert an allocation request. */
|
/* Insert an allocation request. */
|
||||||
#if defined(__GNUC__)
|
Request.Page = 0;
|
||||||
Request.Page.QuadPart = 0LL;
|
|
||||||
#else
|
|
||||||
|
|
||||||
Request.Page.QuadPart = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KeInitializeEvent(&Request.Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Request.Event, NotificationEvent, FALSE);
|
||||||
InterlockedIncrement((LONG *)&MiPagesRequired);
|
InterlockedIncrement((LONG *)&MiPagesRequired);
|
||||||
|
@ -283,14 +265,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
Page = Request.Page;
|
Page = Request.Page;
|
||||||
#if defined(__GNUC__)
|
if (Page == 0)
|
||||||
|
|
||||||
if (Page.QuadPart == 0LL)
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (Page.QuadPart == 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
@ -304,14 +279,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait,
|
||||||
* Actually allocate the page.
|
* Actually allocate the page.
|
||||||
*/
|
*/
|
||||||
Page = MmAllocPage(Consumer, 0);
|
Page = MmAllocPage(Consumer, 0);
|
||||||
#if defined(__GNUC__)
|
if (Page == 0)
|
||||||
|
|
||||||
if (Page.QuadPart == 0LL)
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (Page.QuadPart == 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: cont.c,v 1.31 2004/04/10 22:35:25 gdalsnes Exp $
|
/* $Id: cont.c,v 1.32 2004/08/01 07:24:57 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -21,13 +21,13 @@
|
||||||
|
|
||||||
VOID STATIC
|
VOID STATIC
|
||||||
MmFreeContinuousPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
MmFreeContinuousPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry,
|
PFN_TYPE Page, SWAPENTRY SwapEntry,
|
||||||
BOOLEAN Dirty)
|
BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
assert(SwapEntry == 0);
|
assert(SwapEntry == 0);
|
||||||
if (PhysAddr.QuadPart != 0)
|
if (Page != 0)
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysAddr);
|
MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
|
||||||
PMEMORY_AREA MArea;
|
PMEMORY_AREA MArea;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PVOID BaseAddress = 0;
|
PVOID BaseAddress = 0;
|
||||||
PHYSICAL_ADDRESS PBase;
|
PFN_TYPE PBase;
|
||||||
ULONG Attributes;
|
ULONG Attributes;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
|
@ -78,14 +78,7 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
|
||||||
LowestAcceptableAddress,
|
LowestAcceptableAddress,
|
||||||
HighestAcceptableAddress,
|
HighestAcceptableAddress,
|
||||||
Alignment);
|
Alignment);
|
||||||
#if defined(__GNUC__)
|
if (PBase == 0)
|
||||||
|
|
||||||
if (PBase.QuadPart == 0LL)
|
|
||||||
#else
|
|
||||||
|
|
||||||
if (PBase.QuadPart == 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
MmLockAddressSpace(MmGetKernelAddressSpace());
|
MmLockAddressSpace(MmGetKernelAddressSpace());
|
||||||
MmFreeMemoryArea(MmGetKernelAddressSpace(),
|
MmFreeMemoryArea(MmGetKernelAddressSpace(),
|
||||||
|
@ -96,22 +89,13 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
|
||||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / 4096); i++)
|
for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE); i++, PBase++)
|
||||||
{
|
{
|
||||||
#if !defined(__GNUC__)
|
|
||||||
LARGE_INTEGER dummyJunkNeeded;
|
|
||||||
dummyJunkNeeded.QuadPart = PBase.QuadPart + (i * 4096);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
MmCreateVirtualMapping(NULL,
|
MmCreateVirtualMapping(NULL,
|
||||||
(char*)BaseAddress + (i * 4096),
|
(char*)BaseAddress + (i * 4096),
|
||||||
Attributes,
|
Attributes,
|
||||||
#if defined(__GNUC__)
|
&PBase,
|
||||||
(LARGE_INTEGER)(PBase.QuadPart + (i * 4096)),
|
1);
|
||||||
#else
|
|
||||||
dummyJunkNeeded,
|
|
||||||
#endif
|
|
||||||
TRUE);
|
|
||||||
}
|
}
|
||||||
return(BaseAddress);
|
return(BaseAddress);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,30 +68,38 @@ static ULONG UnzeroedPageCount = 0;
|
||||||
/* FUNCTIONS *************************************************************/
|
/* FUNCTIONS *************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmTransferOwnershipPage(PHYSICAL_ADDRESS PhysicalAddress, ULONG NewConsumer)
|
MmTransferOwnershipPage(PFN_TYPE Pfn, ULONG NewConsumer)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
if (MmPageArray[Start].MapCount != 0)
|
if (MmPageArray[Pfn].MapCount != 0)
|
||||||
{
|
{
|
||||||
DbgPrint("Transfering mapped page.\n");
|
DbgPrint("Transfering mapped page.\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
RemoveEntryList(&MmPageArray[Start].ListEntry);
|
if (MmPageArray[Pfn].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
||||||
|
{
|
||||||
|
DPRINT1("Type: %d\n", MmPageArray[Pfn].Flags.Type);
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
if (MmPageArray[Pfn].ReferenceCount != 1)
|
||||||
|
{
|
||||||
|
DPRINT1("ReferenceCount: %d\n", MmPageArray[Pfn].ReferenceCount);
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
RemoveEntryList(&MmPageArray[Pfn].ListEntry);
|
||||||
InsertTailList(&UsedPageListHeads[NewConsumer],
|
InsertTailList(&UsedPageListHeads[NewConsumer],
|
||||||
&MmPageArray[Start].ListEntry);
|
&MmPageArray[Pfn].ListEntry);
|
||||||
MmPageArray[Start].Flags.Consumer = NewConsumer;
|
MmPageArray[Pfn].Flags.Consumer = NewConsumer;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
MiZeroPage(PhysicalAddress);
|
MiZeroPage(Pfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
PHYSICAL_ADDRESS
|
PFN_TYPE
|
||||||
MmGetLRUFirstUserPage(VOID)
|
MmGetLRUFirstUserPage(VOID)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY NextListEntry;
|
PLIST_ENTRY NextListEntry;
|
||||||
PHYSICAL_ADDRESS Next;
|
|
||||||
PHYSICAL_PAGE* PageDescriptor;
|
PHYSICAL_PAGE* PageDescriptor;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
@ -100,90 +108,58 @@ MmGetLRUFirstUserPage(VOID)
|
||||||
if (NextListEntry == &UsedPageListHeads[MC_USER])
|
if (NextListEntry == &UsedPageListHeads[MC_USER])
|
||||||
{
|
{
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
#if defined(__GNUC__)
|
return 0;
|
||||||
|
|
||||||
return((PHYSICAL_ADDRESS)0LL);
|
|
||||||
#else
|
|
||||||
|
|
||||||
{
|
|
||||||
const PHYSICAL_ADDRESS dummyJunkNeeded =
|
|
||||||
{
|
|
||||||
0
|
|
||||||
};
|
|
||||||
return dummyJunkNeeded;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
|
PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
|
||||||
Next.QuadPart = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray);
|
|
||||||
Next.QuadPart = (Next.QuadPart / sizeof(PHYSICAL_PAGE)) * PAGE_SIZE;
|
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
return(Next);
|
return PageDescriptor - MmPageArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmSetLRULastPage(PHYSICAL_ADDRESS PhysicalAddress)
|
MmSetLRULastPage(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
assert (Pfn < MmPageArraySize);
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
if (MmPageArray[Start].Flags.Type == MM_PHYSICAL_PAGE_USED &&
|
if (MmPageArray[Pfn].Flags.Type == MM_PHYSICAL_PAGE_USED &&
|
||||||
MmPageArray[Start].Flags.Consumer == MC_USER)
|
MmPageArray[Pfn].Flags.Consumer == MC_USER)
|
||||||
{
|
{
|
||||||
RemoveEntryList(&MmPageArray[Start].ListEntry);
|
RemoveEntryList(&MmPageArray[Pfn].ListEntry);
|
||||||
InsertTailList(&UsedPageListHeads[MC_USER],
|
InsertTailList(&UsedPageListHeads[MC_USER],
|
||||||
&MmPageArray[Start].ListEntry);
|
&MmPageArray[Pfn].ListEntry);
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
PHYSICAL_ADDRESS
|
PFN_TYPE
|
||||||
MmGetLRUNextUserPage(PHYSICAL_ADDRESS PreviousPhysicalAddress)
|
MmGetLRUNextUserPage(PFN_TYPE PreviousPfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PreviousPhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
PLIST_ENTRY NextListEntry;
|
PLIST_ENTRY NextListEntry;
|
||||||
PHYSICAL_ADDRESS Next;
|
|
||||||
PHYSICAL_PAGE* PageDescriptor;
|
PHYSICAL_PAGE* PageDescriptor;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED ||
|
if (MmPageArray[PreviousPfn].Flags.Type != MM_PHYSICAL_PAGE_USED ||
|
||||||
MmPageArray[Start].Flags.Consumer != MC_USER)
|
MmPageArray[PreviousPfn].Flags.Consumer != MC_USER)
|
||||||
{
|
{
|
||||||
NextListEntry = UsedPageListHeads[MC_USER].Flink;
|
NextListEntry = UsedPageListHeads[MC_USER].Flink;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NextListEntry = MmPageArray[Start].ListEntry.Flink;
|
NextListEntry = MmPageArray[PreviousPfn].ListEntry.Flink;
|
||||||
}
|
}
|
||||||
if (NextListEntry == &UsedPageListHeads[MC_USER])
|
if (NextListEntry == &UsedPageListHeads[MC_USER])
|
||||||
{
|
{
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
#if defined(__GNUC__)
|
return 0;
|
||||||
|
|
||||||
return((PHYSICAL_ADDRESS)0LL);
|
|
||||||
#else
|
|
||||||
|
|
||||||
{
|
|
||||||
const PHYSICAL_ADDRESS dummyJunkNeeded =
|
|
||||||
{
|
|
||||||
0
|
|
||||||
};
|
|
||||||
return dummyJunkNeeded;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
|
PageDescriptor = CONTAINING_RECORD(NextListEntry, PHYSICAL_PAGE, ListEntry);
|
||||||
Next.QuadPart = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray);
|
|
||||||
Next.QuadPart = (Next.QuadPart / sizeof(PHYSICAL_PAGE)) * PAGE_SIZE;
|
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
return(Next);
|
return PageDescriptor - MmPageArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
PHYSICAL_ADDRESS
|
PFN_TYPE
|
||||||
MmGetContinuousPages(ULONG NumberOfBytes,
|
MmGetContinuousPages(ULONG NumberOfBytes,
|
||||||
PHYSICAL_ADDRESS LowestAcceptableAddress,
|
PHYSICAL_ADDRESS LowestAcceptableAddress,
|
||||||
PHYSICAL_ADDRESS HighestAcceptableAddress,
|
PHYSICAL_ADDRESS HighestAcceptableAddress,
|
||||||
|
@ -191,7 +167,7 @@ MmGetContinuousPages(ULONG NumberOfBytes,
|
||||||
{
|
{
|
||||||
ULONG NrPages;
|
ULONG NrPages;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
LONG start;
|
ULONG start;
|
||||||
ULONG length;
|
ULONG length;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
@ -232,20 +208,7 @@ MmGetContinuousPages(ULONG NumberOfBytes,
|
||||||
if (start == -1 || length != NrPages)
|
if (start == -1 || length != NrPages)
|
||||||
{
|
{
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
#if defined(__GNUC__)
|
return 0;
|
||||||
|
|
||||||
return((PHYSICAL_ADDRESS)(LONGLONG)0);
|
|
||||||
#else
|
|
||||||
|
|
||||||
{
|
|
||||||
const PHYSICAL_ADDRESS dummyJunkNeeded =
|
|
||||||
{
|
|
||||||
0
|
|
||||||
};
|
|
||||||
return dummyJunkNeeded;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
for (i = start; i < (start + length); i++)
|
for (i = start; i < (start + length); i++)
|
||||||
{
|
{
|
||||||
|
@ -270,29 +233,15 @@ MmGetContinuousPages(ULONG NumberOfBytes,
|
||||||
{
|
{
|
||||||
if (MmPageArray[i].Flags.Zero == 0)
|
if (MmPageArray[i].Flags.Zero == 0)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS Page;
|
MiZeroPage(i);
|
||||||
Page.QuadPart = i * PAGE_SIZE;
|
|
||||||
MiZeroPage(Page);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MmPageArray[i].Flags.Zero = 0;
|
MmPageArray[i].Flags.Zero = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
#if defined(__GNUC__)
|
|
||||||
|
return start;
|
||||||
return((PHYSICAL_ADDRESS)((LONGLONG)start * PAGE_SIZE));
|
|
||||||
#else
|
|
||||||
|
|
||||||
{
|
|
||||||
const PHYSICAL_ADDRESS dummyJunkNeeded =
|
|
||||||
{
|
|
||||||
start * PAGE_SIZE
|
|
||||||
};
|
|
||||||
return dummyJunkNeeded;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID INIT_FUNCTION
|
VOID INIT_FUNCTION
|
||||||
|
@ -445,26 +394,13 @@ MmInitializePageList(PVOID FirstPhysKernelAddress,
|
||||||
PVOID Address = (char*)(ULONG)MmPageArray + (i * PAGE_SIZE);
|
PVOID Address = (char*)(ULONG)MmPageArray + (i * PAGE_SIZE);
|
||||||
if (!MmIsPagePresent(NULL, Address))
|
if (!MmIsPagePresent(NULL, Address))
|
||||||
{
|
{
|
||||||
#if !defined(__GNUC__)
|
ULONG Pfn = ((ULONG_PTR)LastPhysKernelAddress >> PAGE_SHIFT) - Reserved + i;
|
||||||
const PHYSICAL_ADDRESS dummyJunkNeeded =
|
|
||||||
{
|
|
||||||
(ULONG)LastPhysKernelAddress -
|
|
||||||
(Reserved * PAGE_SIZE) + (i * PAGE_SIZE)
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ULONG PhysicalAddress = (ULONG)LastPhysKernelAddress -
|
|
||||||
(Reserved * PAGE_SIZE) + (i * PAGE_SIZE);
|
|
||||||
Status =
|
Status =
|
||||||
MmCreateVirtualMappingUnsafe(NULL,
|
MmCreateVirtualMappingUnsafe(NULL,
|
||||||
Address,
|
Address,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
#if defined(__GNUC__)
|
&Pfn,
|
||||||
(PHYSICAL_ADDRESS)(LONGLONG)PhysicalAddress,
|
1);
|
||||||
#else
|
|
||||||
dummyJunkNeeded,
|
|
||||||
#endif
|
|
||||||
FALSE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
@ -614,85 +550,78 @@ MmInitializePageList(PVOID FirstPhysKernelAddress,
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmSetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress, ULONG Flags)
|
MmSetFlagsPage(PFN_TYPE Pfn, ULONG Flags)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
assert (Pfn < MmPageArraySize);
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
MmPageArray[Start].AllFlags = Flags;
|
MmPageArray[Pfn].AllFlags = Flags;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmSetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress,
|
MmSetRmapListHeadPage(PFN_TYPE Pfn, struct _MM_RMAP_ENTRY* ListHead)
|
||||||
struct _MM_RMAP_ENTRY* ListHead)
|
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
MmPageArray[Pfn].RmapListHead = ListHead;
|
||||||
|
|
||||||
MmPageArray[Start].RmapListHead = ListHead;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct _MM_RMAP_ENTRY*
|
struct _MM_RMAP_ENTRY*
|
||||||
MmGetRmapListHeadPage(PHYSICAL_ADDRESS PhysicalAddress)
|
MmGetRmapListHeadPage(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
return(MmPageArray[Pfn].RmapListHead);
|
||||||
|
|
||||||
return(MmPageArray[Start].RmapListHead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmMarkPageMapped(PHYSICAL_ADDRESS PhysicalAddress)
|
MmMarkPageMapped(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
if (Start < MmPageArraySize)
|
if (Pfn < MmPageArraySize)
|
||||||
{
|
{
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
if (MmPageArray[Start].Flags.Type == MM_PHYSICAL_PAGE_FREE)
|
if (MmPageArray[Pfn].Flags.Type == MM_PHYSICAL_PAGE_FREE)
|
||||||
{
|
{
|
||||||
DbgPrint("Mapping non-used page\n");
|
DbgPrint("Mapping non-used page\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
MmPageArray[Start].MapCount++;
|
MmPageArray[Pfn].MapCount++;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmMarkPageUnmapped(PHYSICAL_ADDRESS PhysicalAddress)
|
MmMarkPageUnmapped(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
if (Start < MmPageArraySize)
|
if (Pfn < MmPageArraySize)
|
||||||
{
|
{
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
if (MmPageArray[Start].Flags.Type == MM_PHYSICAL_PAGE_FREE)
|
if (MmPageArray[Pfn].Flags.Type == MM_PHYSICAL_PAGE_FREE)
|
||||||
{
|
{
|
||||||
DbgPrint("Unmapping non-used page\n");
|
DbgPrint("Unmapping non-used page\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
if (MmPageArray[Start].MapCount == 0)
|
if (MmPageArray[Pfn].MapCount == 0)
|
||||||
{
|
{
|
||||||
DbgPrint("Unmapping not mapped page\n");
|
DbgPrint("Unmapping not mapped page\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
MmPageArray[Start].MapCount--;
|
MmPageArray[Pfn].MapCount--;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
MmGetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress)
|
MmGetFlagsPage(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
|
|
||||||
|
assert (Pfn < MmPageArraySize);
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
Flags = MmPageArray[Start].AllFlags;
|
Flags = MmPageArray[Pfn].AllFlags;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
|
|
||||||
return(Flags);
|
return(Flags);
|
||||||
|
@ -700,98 +629,94 @@ MmGetFlagsPage(PHYSICAL_ADDRESS PhysicalAddress)
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmSetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress,
|
MmSetSavedSwapEntryPage(PFN_TYPE Pfn, SWAPENTRY SavedSwapEntry)
|
||||||
SWAPENTRY SavedSwapEntry)
|
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
assert (Pfn < MmPageArraySize);
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
MmPageArray[Start].SavedSwapEntry = SavedSwapEntry;
|
MmPageArray[Pfn].SavedSwapEntry = SavedSwapEntry;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
SWAPENTRY
|
SWAPENTRY
|
||||||
MmGetSavedSwapEntryPage(PHYSICAL_ADDRESS PhysicalAddress)
|
MmGetSavedSwapEntryPage(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
SWAPENTRY SavedSwapEntry;
|
SWAPENTRY SavedSwapEntry;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
assert (Pfn < MmPageArraySize);
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
SavedSwapEntry = MmPageArray[Start].SavedSwapEntry;
|
SavedSwapEntry = MmPageArray[Pfn].SavedSwapEntry;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
|
|
||||||
return(SavedSwapEntry);
|
return(SavedSwapEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmReferencePage(PHYSICAL_ADDRESS PhysicalAddress)
|
MmReferencePage(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
DPRINT("MmReferencePage(PhysicalAddress %x)\n", PhysicalAddress);
|
DPRINT("MmReferencePage(PysicalAddress %x)\n", Pfn << PAGE_SHIFT);
|
||||||
|
|
||||||
if (PhysicalAddress.u.LowPart == 0)
|
if (Pfn == 0 || Pfn >= MmPageArraySize)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
|
|
||||||
if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
if (MmPageArray[Pfn].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
||||||
{
|
{
|
||||||
DbgPrint("Referencing non-used page\n");
|
DbgPrint("Referencing non-used page\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
MmPageArray[Start].ReferenceCount++;
|
MmPageArray[Pfn].ReferenceCount++;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
MmGetReferenceCountPage(PHYSICAL_ADDRESS PhysicalAddress)
|
MmGetReferenceCountPage(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
ULONG RCount;
|
ULONG RCount;
|
||||||
|
|
||||||
DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", PhysicalAddress);
|
DPRINT("MmGetReferenceCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
|
||||||
|
|
||||||
if (PhysicalAddress.u.LowPart == 0)
|
if (Pfn == 0 || Pfn >= MmPageArraySize)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
|
|
||||||
if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
if (MmPageArray[Pfn].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
||||||
{
|
{
|
||||||
DbgPrint("Getting reference count for free page\n");
|
DbgPrint("Getting reference count for free page\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
RCount = MmPageArray[Start].ReferenceCount;
|
RCount = MmPageArray[Pfn].ReferenceCount;
|
||||||
|
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
return(RCount);
|
return(RCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
MmIsUsablePage(PHYSICAL_ADDRESS PhysicalAddress)
|
MmIsUsablePage(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
|
|
||||||
DPRINT("MmIsUsablePage(PhysicalAddress %x)\n", PhysicalAddress);
|
DPRINT("MmIsUsablePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
|
||||||
|
|
||||||
if (PhysicalAddress.u.LowPart == 0)
|
if (Pfn == 0 || Pfn >= MmPageArraySize)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED &&
|
if (MmPageArray[Pfn].Flags.Type != MM_PHYSICAL_PAGE_USED &&
|
||||||
MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_BIOS)
|
MmPageArray[Pfn].Flags.Type != MM_PHYSICAL_PAGE_BIOS)
|
||||||
{
|
{
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
|
@ -800,64 +725,67 @@ MmIsUsablePage(PHYSICAL_ADDRESS PhysicalAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDereferencePage(PHYSICAL_ADDRESS PhysicalAddress)
|
MmDereferencePage(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
DPRINT("MmDereferencePage(PhysicalAddress %I64x)\n", PhysicalAddress);
|
DPRINT("MmDereferencePage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
|
||||||
|
|
||||||
if (PhysicalAddress.u.LowPart == 0)
|
if (Pfn == 0 || Pfn >= MmPageArraySize)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
|
|
||||||
|
if (MmPageArray[Pfn].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
||||||
if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
|
||||||
{
|
{
|
||||||
DbgPrint("Dereferencing free page\n");
|
DbgPrint("Dereferencing free page\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
if (MmPageArray[Pfn].ReferenceCount == 0)
|
||||||
|
{
|
||||||
|
DbgPrint("Derefrencing page with reference count 0\n");
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
|
|
||||||
MmPageArray[Start].ReferenceCount--;
|
MmPageArray[Pfn].ReferenceCount--;
|
||||||
if (MmPageArray[Start].ReferenceCount == 0)
|
if (MmPageArray[Pfn].ReferenceCount == 0)
|
||||||
{
|
{
|
||||||
MmStats.NrFreePages++;
|
MmStats.NrFreePages++;
|
||||||
MmStats.NrSystemPages--;
|
MmStats.NrSystemPages--;
|
||||||
RemoveEntryList(&MmPageArray[Start].ListEntry);
|
RemoveEntryList(&MmPageArray[Pfn].ListEntry);
|
||||||
if (MmPageArray[Start].RmapListHead != NULL)
|
if (MmPageArray[Pfn].RmapListHead != NULL)
|
||||||
{
|
{
|
||||||
DbgPrint("Freeing page with rmap entries.\n");
|
DbgPrint("Freeing page with rmap entries.\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
if (MmPageArray[Start].MapCount != 0)
|
if (MmPageArray[Pfn].MapCount != 0)
|
||||||
{
|
{
|
||||||
DbgPrint("Freeing mapped page (0x%I64x count %d)\n",
|
DbgPrint("Freeing mapped page (0x%x count %d)\n",
|
||||||
PhysicalAddress, MmPageArray[Start].MapCount);
|
Pfn << PAGE_SHIFT, MmPageArray[Pfn].MapCount);
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
if (MmPageArray[Start].LockCount > 0)
|
if (MmPageArray[Pfn].LockCount > 0)
|
||||||
{
|
{
|
||||||
DbgPrint("Freeing locked page\n");
|
DbgPrint("Freeing locked page\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
if (MmPageArray[Start].SavedSwapEntry != 0)
|
if (MmPageArray[Pfn].SavedSwapEntry != 0)
|
||||||
{
|
{
|
||||||
DbgPrint("Freeing page with swap entry.\n");
|
DbgPrint("Freeing page with swap entry.\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
if (MmPageArray[Pfn].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
||||||
{
|
{
|
||||||
DbgPrint("Freeing page with flags %x\n",
|
DbgPrint("Freeing page with flags %x\n",
|
||||||
MmPageArray[Start].Flags.Type);
|
MmPageArray[Pfn].Flags.Type);
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
MmPageArray[Start].Flags.Type = MM_PHYSICAL_PAGE_FREE;
|
MmPageArray[Pfn].Flags.Type = MM_PHYSICAL_PAGE_FREE;
|
||||||
MmPageArray[Start].Flags.Zero = 0;
|
MmPageArray[Pfn].Flags.Consumer = MC_MAXIMUM;
|
||||||
InsertTailList(&FreeUnzeroedPageListHead,
|
InsertTailList(&FreeUnzeroedPageListHead,
|
||||||
&MmPageArray[Start].ListEntry);
|
&MmPageArray[Pfn].ListEntry);
|
||||||
UnzeroedPageCount++;
|
UnzeroedPageCount++;
|
||||||
if (UnzeroedPageCount > 8 && 0 == KeReadStateEvent(&ZeroPageThreadEvent))
|
if (UnzeroedPageCount > 8 && 0 == KeReadStateEvent(&ZeroPageThreadEvent))
|
||||||
{
|
{
|
||||||
|
@ -868,87 +796,84 @@ MmDereferencePage(PHYSICAL_ADDRESS PhysicalAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
MmGetLockCountPage(PHYSICAL_ADDRESS PhysicalAddress)
|
MmGetLockCountPage(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
ULONG LockCount;
|
ULONG LockCount;
|
||||||
|
|
||||||
DPRINT("MmGetLockCountPage(PhysicalAddress %x)\n", PhysicalAddress);
|
DPRINT("MmGetLockCountPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
|
||||||
|
|
||||||
if (PhysicalAddress.u.LowPart == 0)
|
if (Pfn == 0 || Pfn >= MmPageArraySize)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
|
|
||||||
if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
if (MmPageArray[Pfn].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
||||||
{
|
{
|
||||||
DbgPrint("Getting lock count for free page\n");
|
DbgPrint("Getting lock count for free page\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LockCount = MmPageArray[Start].LockCount;
|
LockCount = MmPageArray[Pfn].LockCount;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
|
|
||||||
return(LockCount);
|
return(LockCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmLockPage(PHYSICAL_ADDRESS PhysicalAddress)
|
MmLockPage(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
DPRINT("MmLockPage(PhysicalAddress %x)\n", PhysicalAddress);
|
DPRINT("MmLockPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
|
||||||
|
|
||||||
if (PhysicalAddress.u.LowPart == 0)
|
if (Pfn == 0 || Pfn >= MmPageArraySize)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
|
|
||||||
if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
if (MmPageArray[Pfn].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
||||||
{
|
{
|
||||||
DbgPrint("Locking free page\n");
|
DbgPrint("Locking free page\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
MmPageArray[Start].LockCount++;
|
MmPageArray[Pfn].LockCount++;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmUnlockPage(PHYSICAL_ADDRESS PhysicalAddress)
|
MmUnlockPage(PFN_TYPE Pfn)
|
||||||
{
|
{
|
||||||
ULONG Start = PhysicalAddress.u.LowPart / PAGE_SIZE;
|
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
DPRINT("MmUnlockPage(PhysicalAddress %I64x)\n", PhysicalAddress);
|
DPRINT("MmUnlockPage(PhysicalAddress %x)\n", Pfn << PAGE_SHIFT);
|
||||||
|
|
||||||
if (PhysicalAddress.u.LowPart == 0)
|
if (Pfn == 0 || Pfn >= MmPageArraySize)
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
|
|
||||||
if (MmPageArray[Start].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
if (MmPageArray[Pfn].Flags.Type != MM_PHYSICAL_PAGE_USED)
|
||||||
{
|
{
|
||||||
DbgPrint("Unlocking free page\n");
|
DbgPrint("Unlocking free page\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
MmPageArray[Start].LockCount--;
|
MmPageArray[Pfn].LockCount--;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
PHYSICAL_ADDRESS
|
PFN_TYPE
|
||||||
MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
|
MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS PageOffset;
|
PFN_TYPE PfnOffset;
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
PPHYSICAL_PAGE PageDescriptor;
|
PPHYSICAL_PAGE PageDescriptor;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
@ -963,20 +888,7 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
|
||||||
{
|
{
|
||||||
DPRINT1("MmAllocPage(): Out of memory\n");
|
DPRINT1("MmAllocPage(): Out of memory\n");
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
#if defined(__GNUC__)
|
return 0;
|
||||||
|
|
||||||
return((PHYSICAL_ADDRESS)0LL);
|
|
||||||
#else
|
|
||||||
|
|
||||||
{
|
|
||||||
const PHYSICAL_ADDRESS dummyJunkNeeded =
|
|
||||||
{
|
|
||||||
0
|
|
||||||
};
|
|
||||||
return dummyJunkNeeded;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
ListEntry = RemoveTailList(&FreeUnzeroedPageListHead);
|
ListEntry = RemoveTailList(&FreeUnzeroedPageListHead);
|
||||||
UnzeroedPageCount--;
|
UnzeroedPageCount--;
|
||||||
|
@ -1002,8 +914,12 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
|
||||||
DbgPrint("Got mapped page from freelist\n");
|
DbgPrint("Got mapped page from freelist\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
if (PageDescriptor->ReferenceCount != 0)
|
||||||
|
{
|
||||||
|
DPRINT1("%d\n", PageDescriptor->ReferenceCount);
|
||||||
|
KEBUGCHECK(0);
|
||||||
|
}
|
||||||
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
|
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
|
||||||
PageDescriptor->Flags.Zero = 0;
|
|
||||||
PageDescriptor->Flags.Consumer = Consumer;
|
PageDescriptor->Flags.Consumer = Consumer;
|
||||||
PageDescriptor->ReferenceCount = 1;
|
PageDescriptor->ReferenceCount = 1;
|
||||||
PageDescriptor->LockCount = 0;
|
PageDescriptor->LockCount = 0;
|
||||||
|
@ -1016,19 +932,17 @@ MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry)
|
||||||
|
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
|
|
||||||
PageOffset.QuadPart = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray);
|
PfnOffset = PageDescriptor - MmPageArray;
|
||||||
PageOffset.QuadPart =
|
|
||||||
(PageOffset.QuadPart / sizeof(PHYSICAL_PAGE)) * PAGE_SIZE;
|
|
||||||
if (NeedClear)
|
if (NeedClear)
|
||||||
{
|
{
|
||||||
MiZeroPage(PageOffset);
|
MiZeroPage(PfnOffset);
|
||||||
}
|
}
|
||||||
if (PageDescriptor->MapCount != 0)
|
if (PageDescriptor->MapCount != 0)
|
||||||
{
|
{
|
||||||
DbgPrint("Returning mapped page.\n");
|
DbgPrint("Returning mapped page.\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
return(PageOffset);
|
return PfnOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1039,7 +953,7 @@ MmZeroPageThreadMain(PVOID Ignored)
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
PPHYSICAL_PAGE PageDescriptor;
|
PPHYSICAL_PAGE PageDescriptor;
|
||||||
PHYSICAL_ADDRESS PhysPage;
|
PFN_TYPE Pfn;
|
||||||
static PVOID Address = NULL;
|
static PVOID Address = NULL;
|
||||||
ULONG Count;
|
ULONG Count;
|
||||||
|
|
||||||
|
@ -1068,19 +982,18 @@ MmZeroPageThreadMain(PVOID Ignored)
|
||||||
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
|
PageDescriptor->Flags.Type = MM_PHYSICAL_PAGE_USED;
|
||||||
KeReleaseSpinLock(&PageListLock, oldIrql);
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
Count++;
|
Count++;
|
||||||
PhysPage.QuadPart = (ULONG)((ULONG)PageDescriptor - (ULONG)MmPageArray);
|
Pfn = PageDescriptor - MmPageArray;
|
||||||
PhysPage.QuadPart = (PhysPage.QuadPart / sizeof(PHYSICAL_PAGE)) * PAGE_SIZE;
|
|
||||||
if (Address == NULL)
|
if (Address == NULL)
|
||||||
{
|
{
|
||||||
Address = ExAllocatePageWithPhysPage(PhysPage);
|
Address = ExAllocatePageWithPhysPage(Pfn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
Address,
|
Address,
|
||||||
PAGE_READWRITE | PAGE_SYSTEM,
|
PAGE_READWRITE | PAGE_SYSTEM,
|
||||||
PhysPage,
|
&Pfn,
|
||||||
FALSE);
|
1);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: iospace.c,v 1.28 2004/05/20 08:37:20 hbirr Exp $
|
/* $Id: iospace.c,v 1.29 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/iospace.c
|
* FILE: ntoskrnl/mm/iospace.c
|
||||||
|
@ -77,6 +77,7 @@ MmMapIoSpace (IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG Attributes;
|
ULONG Attributes;
|
||||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||||
|
PFN_TYPE Pfn;
|
||||||
|
|
||||||
DPRINT("MmMapIoSpace(%lx, %d, %d)\n", PhysicalAddress, NumberOfBytes, CacheEnable);
|
DPRINT("MmMapIoSpace(%lx, %d, %d)\n", PhysicalAddress, NumberOfBytes, CacheEnable);
|
||||||
|
|
||||||
|
@ -116,11 +117,13 @@ MmMapIoSpace (IN PHYSICAL_ADDRESS PhysicalAddress,
|
||||||
{
|
{
|
||||||
Attributes |= (PAGE_NOCACHE | PAGE_WRITETHROUGH);
|
Attributes |= (PAGE_NOCACHE | PAGE_WRITETHROUGH);
|
||||||
}
|
}
|
||||||
for (i = 0; i < PAGE_ROUND_UP(NumberOfBytes); i += PAGE_SIZE, PhysicalAddress.QuadPart += PAGE_SIZE)
|
Pfn = PhysicalAddress.QuadPart >> PAGE_SHIFT;
|
||||||
|
for (i = 0; i < PAGE_ROUND_UP(NumberOfBytes); i += PAGE_SIZE, Pfn++)
|
||||||
{
|
{
|
||||||
Status = MmCreateVirtualMappingForKernel((char*)Result + i,
|
Status = MmCreateVirtualMappingForKernel((char*)Result + i,
|
||||||
Attributes,
|
Attributes,
|
||||||
PhysicalAddress);
|
&Pfn,
|
||||||
|
1);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: kmap.c,v 1.32 2004/04/10 22:35:25 gdalsnes Exp $
|
/* $Id: kmap.c,v 1.33 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -54,24 +54,24 @@ ExUnmapPage(PVOID Addr)
|
||||||
PVOID
|
PVOID
|
||||||
ExAllocatePage(VOID)
|
ExAllocatePage(VOID)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS PhysPage;
|
PFN_TYPE Page;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &PhysPage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ExAllocatePageWithPhysPage(PhysPage));
|
return(ExAllocatePageWithPhysPage(Page));
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MiZeroPage(PHYSICAL_ADDRESS PhysPage)
|
MiZeroPage(PFN_TYPE Page)
|
||||||
{
|
{
|
||||||
PVOID TempAddress;
|
PVOID TempAddress;
|
||||||
|
|
||||||
TempAddress = ExAllocatePageWithPhysPage(PhysPage);
|
TempAddress = ExAllocatePageWithPhysPage(Page);
|
||||||
if (TempAddress == NULL)
|
if (TempAddress == NULL)
|
||||||
{
|
{
|
||||||
return(STATUS_NO_MEMORY);
|
return(STATUS_NO_MEMORY);
|
||||||
|
@ -82,11 +82,11 @@ MiZeroPage(PHYSICAL_ADDRESS PhysPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MiCopyFromUserPage(PHYSICAL_ADDRESS DestPhysPage, PVOID SourceAddress)
|
MiCopyFromUserPage(PFN_TYPE DestPage, PVOID SourceAddress)
|
||||||
{
|
{
|
||||||
PVOID TempAddress;
|
PVOID TempAddress;
|
||||||
|
|
||||||
TempAddress = ExAllocatePageWithPhysPage(DestPhysPage);
|
TempAddress = ExAllocatePageWithPhysPage(DestPage);
|
||||||
if (TempAddress == NULL)
|
if (TempAddress == NULL)
|
||||||
{
|
{
|
||||||
return(STATUS_NO_MEMORY);
|
return(STATUS_NO_MEMORY);
|
||||||
|
@ -97,7 +97,7 @@ MiCopyFromUserPage(PHYSICAL_ADDRESS DestPhysPage, PVOID SourceAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
PVOID
|
PVOID
|
||||||
ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage)
|
ExAllocatePageWithPhysPage(PFN_TYPE Page)
|
||||||
{
|
{
|
||||||
KIRQL oldlvl;
|
KIRQL oldlvl;
|
||||||
PVOID Addr;
|
PVOID Addr;
|
||||||
|
@ -114,8 +114,8 @@ ExAllocatePageWithPhysPage(PHYSICAL_ADDRESS PhysPage)
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
Addr,
|
Addr,
|
||||||
PAGE_READWRITE | PAGE_SYSTEM,
|
PAGE_READWRITE | PAGE_SYSTEM,
|
||||||
PhysPage,
|
&Page,
|
||||||
TRUE);
|
1);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
|
|
@ -409,12 +409,12 @@ MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID BaseAddress,
|
PVOID BaseAddress,
|
||||||
ULONG Length,
|
ULONG Length,
|
||||||
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea,
|
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea,
|
||||||
PVOID Address, PHYSICAL_ADDRESS PhysAddr,
|
PVOID Address, PFN_TYPE Page,
|
||||||
SWAPENTRY SwapEntry, BOOLEAN Dirty),
|
SWAPENTRY SwapEntry, BOOLEAN Dirty),
|
||||||
PVOID FreePageContext)
|
PVOID FreePageContext)
|
||||||
{
|
{
|
||||||
MEMORY_AREA* MemoryArea;
|
MEMORY_AREA* MemoryArea;
|
||||||
ULONG i;
|
PVOID Address, EndAddress;
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
DPRINT("MmFreeMemoryArea(AddressSpace %x, BaseAddress %x, Length %x,"
|
DPRINT("MmFreeMemoryArea(AddressSpace %x, BaseAddress %x, Length %x,"
|
||||||
|
@ -433,43 +433,33 @@ MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
KeAttachProcess(AddressSpace->Process);
|
KeAttachProcess(AddressSpace->Process);
|
||||||
}
|
}
|
||||||
for (i=0; i<(PAGE_ROUND_UP(MemoryArea->Length)/PAGE_SIZE); i++)
|
EndAddress = MemoryArea->BaseAddress + PAGE_ROUND_UP(MemoryArea->Length);
|
||||||
|
for (Address = MemoryArea->BaseAddress; Address < EndAddress; Address += PAGE_SIZE)
|
||||||
{
|
{
|
||||||
#if defined(__GNUC__)
|
|
||||||
PHYSICAL_ADDRESS PhysAddr = (PHYSICAL_ADDRESS)0LL;
|
|
||||||
#else
|
|
||||||
|
|
||||||
PHYSICAL_ADDRESS PhysAddr = { 0 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (MemoryArea->Type == MEMORY_AREA_IO_MAPPING)
|
if (MemoryArea->Type == MEMORY_AREA_IO_MAPPING)
|
||||||
{
|
{
|
||||||
MmRawDeleteVirtualMapping((char*)MemoryArea->BaseAddress + (i * PAGE_SIZE));
|
MmRawDeleteVirtualMapping(Address);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BOOL Dirty = FALSE;
|
BOOL Dirty = FALSE;
|
||||||
SWAPENTRY SwapEntry = 0;
|
SWAPENTRY SwapEntry = 0;
|
||||||
|
PFN_TYPE Page = 0;
|
||||||
|
|
||||||
if (MmIsPageSwapEntry(AddressSpace->Process,
|
|
||||||
(char*)MemoryArea->BaseAddress + (i * PAGE_SIZE)))
|
if (MmIsPageSwapEntry(AddressSpace->Process, Address))
|
||||||
{
|
{
|
||||||
MmDeletePageFileMapping(AddressSpace->Process,
|
MmDeletePageFileMapping(AddressSpace->Process, Address, &SwapEntry);
|
||||||
(char*)MemoryArea->BaseAddress + (i * PAGE_SIZE),
|
|
||||||
&SwapEntry);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MmDeleteVirtualMapping(AddressSpace->Process,
|
MmDeleteVirtualMapping(AddressSpace->Process, Address, FALSE, &Dirty, &Page);
|
||||||
(char*)MemoryArea->BaseAddress + (i*PAGE_SIZE),
|
|
||||||
FALSE, &Dirty, &PhysAddr);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
if (FreePage != NULL)
|
if (FreePage != NULL)
|
||||||
{
|
{
|
||||||
FreePage(FreePageContext, MemoryArea,
|
FreePage(FreePageContext, MemoryArea, Address,
|
||||||
(char*)MemoryArea->BaseAddress + (i * PAGE_SIZE), PhysAddr,
|
Page, SwapEntry, (BOOLEAN)Dirty);
|
||||||
SwapEntry, (BOOLEAN)Dirty);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: mdl.c,v 1.65 2004/07/17 03:03:51 ion Exp $
|
/* $Id: mdl.c,v 1.66 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -126,7 +126,7 @@ MmUnlockPages(PMDL Mdl)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
PULONG MdlPages;
|
PULONG MdlPages;
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MmProbeAndLockPages MUST have been called to lock this mdl!
|
* MmProbeAndLockPages MUST have been called to lock this mdl!
|
||||||
|
@ -166,7 +166,7 @@ MmUnlockPages(PMDL Mdl)
|
||||||
MdlPages = (PULONG)(Mdl + 1);
|
MdlPages = (PULONG)(Mdl + 1);
|
||||||
for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGE_SIZE); i++)
|
for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGE_SIZE); i++)
|
||||||
{
|
{
|
||||||
Page.QuadPart = MdlPages[i] << PAGE_SHIFT;
|
Page = MdlPages[i];
|
||||||
MmUnlockPage(Page);
|
MmUnlockPage(Page);
|
||||||
MmDereferencePage(Page);
|
MmDereferencePage(Page);
|
||||||
}
|
}
|
||||||
|
@ -195,13 +195,12 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PVOID Base;
|
PVOID Base;
|
||||||
ULONG i;
|
|
||||||
PULONG MdlPages;
|
PULONG MdlPages;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
ULONG PageCount;
|
ULONG PageCount;
|
||||||
ULONG StartingOffset;
|
ULONG StartingOffset;
|
||||||
PEPROCESS CurrentProcess;
|
PEPROCESS CurrentProcess;
|
||||||
PHYSICAL_ADDRESS Page;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode);
|
DPRINT("MmMapLockedPages(Mdl %x, AccessMode %x)\n", Mdl, AccessMode);
|
||||||
|
|
||||||
|
@ -289,24 +288,20 @@ MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
|
||||||
|
|
||||||
/* Set the virtual mappings for the MDL pages. */
|
/* Set the virtual mappings for the MDL pages. */
|
||||||
MdlPages = (PULONG)(Mdl + 1);
|
MdlPages = (PULONG)(Mdl + 1);
|
||||||
for (i = 0; i < PageCount; i++)
|
|
||||||
|
Status = MmCreateVirtualMapping(CurrentProcess,
|
||||||
|
Base,
|
||||||
|
PAGE_READWRITE,
|
||||||
|
MdlPages,
|
||||||
|
PageCount);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
Page.QuadPart = MdlPages[i] << PAGE_SHIFT;
|
if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL)
|
||||||
Status = MmCreateVirtualMapping(CurrentProcess,
|
|
||||||
(PVOID)((ULONG)Base+(i*PAGE_SIZE)),
|
|
||||||
PAGE_READWRITE,
|
|
||||||
Page,
|
|
||||||
FALSE);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
return NULL;
|
||||||
if (Mdl->MdlFlags & MDL_MAPPING_CAN_FAIL)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
KEBUGCHECK(0);
|
|
||||||
}
|
}
|
||||||
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark the MDL has having being mapped. */
|
/* Mark the MDL has having being mapped. */
|
||||||
|
@ -449,18 +444,10 @@ MmUnmapReservedMapping (
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmBuildMdlFromPages(PMDL Mdl, PULONG Pages)
|
MmBuildMdlFromPages(PMDL Mdl, PPFN_TYPE Pages)
|
||||||
{
|
{
|
||||||
ULONG i;
|
memcpy(Mdl + 1, Pages, sizeof(PFN_TYPE) * (PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGE_SIZE));
|
||||||
PULONG MdlPages;
|
|
||||||
|
|
||||||
MdlPages = (PULONG)(Mdl + 1);
|
|
||||||
|
|
||||||
for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGE_SIZE);i++)
|
|
||||||
{
|
|
||||||
MdlPages[i] = Pages[i] >> PAGE_SHIFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
//FIXME: this flag should be set by the caller perhaps?
|
//FIXME: this flag should be set by the caller perhaps?
|
||||||
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
|
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
|
||||||
}
|
}
|
||||||
|
@ -513,12 +500,12 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
|
||||||
* work no matter what kind of mdl address you have.
|
* work no matter what kind of mdl address you have.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PULONG MdlPages;
|
PPFN_TYPE MdlPages;
|
||||||
ULONG i, j;
|
ULONG i, j;
|
||||||
ULONG NrPages;
|
ULONG NrPages;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KPROCESSOR_MODE Mode;
|
KPROCESSOR_MODE Mode;
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||||
|
|
||||||
DPRINT("MmProbeAndLockPages(Mdl %x)\n", Mdl);
|
DPRINT("MmProbeAndLockPages(Mdl %x)\n", Mdl);
|
||||||
|
@ -526,21 +513,21 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
|
||||||
assert(!(Mdl->MdlFlags & (MDL_PAGES_LOCKED|MDL_MAPPED_TO_SYSTEM_VA|MDL_PARTIAL|
|
assert(!(Mdl->MdlFlags & (MDL_PAGES_LOCKED|MDL_MAPPED_TO_SYSTEM_VA|MDL_PARTIAL|
|
||||||
MDL_IO_SPACE|MDL_SOURCE_IS_NONPAGED_POOL)));
|
MDL_IO_SPACE|MDL_SOURCE_IS_NONPAGED_POOL)));
|
||||||
|
|
||||||
MdlPages = (ULONG *)(Mdl + 1);
|
MdlPages = (PPFN_TYPE)(Mdl + 1);
|
||||||
NrPages = PAGE_ROUND_UP(Mdl->ByteOffset + Mdl->ByteCount) / PAGE_SIZE;
|
NrPages = PAGE_ROUND_UP(Mdl->ByteOffset + Mdl->ByteCount) / PAGE_SIZE;
|
||||||
|
|
||||||
/* mdl must have enough page entries */
|
/* mdl must have enough page entries */
|
||||||
assert(NrPages <= (Mdl->Size - sizeof(MDL))/sizeof(ULONG));
|
assert(NrPages <= (Mdl->Size - sizeof(MDL))/sizeof(PFN_TYPE));
|
||||||
|
|
||||||
|
|
||||||
if (Mdl->StartVa >= (PVOID)KERNEL_BASE &&
|
if (Mdl->StartVa >= (PVOID)KERNEL_BASE &&
|
||||||
(MmGetPhysicalAddressForProcess(NULL, Mdl->StartVa).QuadPart >> PAGE_SHIFT) > MmPageArraySize)
|
MmGetPfnForProcess(NULL, Mdl->StartVa) > MmPageArraySize)
|
||||||
{
|
{
|
||||||
/* phys addr is not phys memory so this must be io memory */
|
/* phys addr is not phys memory so this must be io memory */
|
||||||
|
|
||||||
for (i = 0; i < NrPages; i++)
|
for (i = 0; i < NrPages; i++)
|
||||||
{
|
{
|
||||||
MdlPages[i] = MmGetPhysicalAddressForProcess(NULL, (char*)Mdl->StartVa + (i*PAGE_SIZE)).QuadPart >> PAGE_SHIFT;
|
MdlPages[i] = MmGetPfnForProcess(NULL, (char*)Mdl->StartVa + (i*PAGE_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
Mdl->MdlFlags |= MDL_PAGES_LOCKED|MDL_IO_SPACE;
|
Mdl->MdlFlags |= MDL_PAGES_LOCKED|MDL_IO_SPACE;
|
||||||
|
@ -585,7 +572,7 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
|
||||||
{
|
{
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
{
|
{
|
||||||
Page.QuadPart = MdlPages[j] << PAGE_SHIFT;
|
Page = MdlPages[j];
|
||||||
MmUnlockPage(Page);
|
MmUnlockPage(Page);
|
||||||
MmDereferencePage(Page);
|
MmDereferencePage(Page);
|
||||||
}
|
}
|
||||||
|
@ -594,26 +581,26 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(MmGetPfnForProcess(NULL, Address));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Operation == IoWriteAccess || Operation == IoModifyAccess) &&
|
if ((Operation == IoWriteAccess || Operation == IoModifyAccess) &&
|
||||||
(!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE)))
|
(!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE)))
|
||||||
{
|
{
|
||||||
Status = MmAccessFault(Mode, (ULONG)Address, TRUE);
|
Status = MmAccessFault(Mode, (ULONG)Address, TRUE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
for (j = 0; j < i; j++)
|
for (j = 0; j < i; j++)
|
||||||
{
|
{
|
||||||
Page.QuadPart = (ULONGLONG)MdlPages[j] << PAGE_SHIFT;
|
Page = MdlPages[j];
|
||||||
MmUnlockPage(Page);
|
MmUnlockPage(Page);
|
||||||
MmDereferencePage(Page);
|
MmDereferencePage(Page);
|
||||||
}
|
}
|
||||||
ExRaiseStatus(Status);
|
ExRaiseStatus(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Page = MmGetPhysicalAddressForProcess(NULL, Address);
|
Page = MmGetPfnForProcess(NULL, Address);
|
||||||
MdlPages[i] = Page.QuadPart >> PAGE_SHIFT;
|
MdlPages[i] = Page;
|
||||||
MmReferencePage(Page);
|
MmReferencePage(Page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,7 +655,7 @@ ULONG STDCALL MmSizeOfMdl (PVOID Base,
|
||||||
|
|
||||||
len = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base,Length);
|
len = ADDRESS_AND_SIZE_TO_SPAN_PAGES(Base,Length);
|
||||||
|
|
||||||
return(sizeof(MDL)+(len*sizeof(ULONG)));
|
return(sizeof(MDL)+(len*sizeof(PFN_TYPE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -690,6 +677,7 @@ MmBuildMdlForNonPagedPool (PMDL Mdl)
|
||||||
{
|
{
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG PageCount;
|
ULONG PageCount;
|
||||||
|
PPFN_TYPE MdlPages;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mdl buffer must (at least) be in kernel space, thou this doesn't
|
* mdl buffer must (at least) be in kernel space, thou this doesn't
|
||||||
|
@ -698,14 +686,14 @@ MmBuildMdlForNonPagedPool (PMDL Mdl)
|
||||||
assert((ULONG)Mdl->StartVa >= KERNEL_BASE);
|
assert((ULONG)Mdl->StartVa >= KERNEL_BASE);
|
||||||
|
|
||||||
PageCount = PAGE_ROUND_UP(Mdl->ByteOffset + Mdl->ByteCount) / PAGE_SIZE;
|
PageCount = PAGE_ROUND_UP(Mdl->ByteOffset + Mdl->ByteCount) / PAGE_SIZE;
|
||||||
|
MdlPages = (PPFN_TYPE)(Mdl + 1);
|
||||||
|
|
||||||
/* mdl must have enough page entries */
|
/* mdl must have enough page entries */
|
||||||
assert(PageCount <= (Mdl->Size - sizeof(MDL))/sizeof(ULONG));
|
assert(PageCount <= (Mdl->Size - sizeof(MDL))/sizeof(PFN_TYPE));
|
||||||
|
|
||||||
for (i=0; i < PageCount; i++)
|
for (i=0; i < PageCount; i++)
|
||||||
{
|
{
|
||||||
((PULONG)(Mdl + 1))[i] =
|
*MdlPages++ = MmGetPfnForProcess(NULL, (char*)Mdl->StartVa + (i * PAGE_SIZE));
|
||||||
(MmGetPhysicalAddress((char*)Mdl->StartVa + (i * PAGE_SIZE))).QuadPart >> PAGE_SHIFT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mdl->MdlFlags |= MDL_SOURCE_IS_NONPAGED_POOL;
|
Mdl->MdlFlags |= MDL_SOURCE_IS_NONPAGED_POOL;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: mm.c,v 1.75 2004/07/17 03:03:51 ion Exp $
|
/* $Id: mm.c,v 1.76 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -312,7 +312,7 @@ NTSTATUS MmAccessFault(KPROCESSOR_MODE Mode,
|
||||||
NTSTATUS MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked)
|
NTSTATUS MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PHYSICAL_ADDRESS AllocatedPage;
|
PFN_TYPE AllocatedPage;
|
||||||
Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage);
|
Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -324,19 +324,8 @@ NTSTATUS MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked)
|
||||||
MmCreateVirtualMapping(NULL,
|
MmCreateVirtualMapping(NULL,
|
||||||
(PVOID)PAGE_ROUND_DOWN(Address),
|
(PVOID)PAGE_ROUND_DOWN(Address),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
AllocatedPage,
|
&AllocatedPage,
|
||||||
FALSE);
|
1);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(MmGetKernelAddressSpace());
|
|
||||||
Status =
|
|
||||||
MmCreateVirtualMapping(NULL,
|
|
||||||
(PVOID)PAGE_ROUND_DOWN(Address),
|
|
||||||
PAGE_READWRITE,
|
|
||||||
AllocatedPage,
|
|
||||||
FALSE);
|
|
||||||
MmLockAddressSpace(MmGetKernelAddressSpace());
|
|
||||||
}
|
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage(AllocatedPage);
|
MmLockPage(AllocatedPage);
|
||||||
|
@ -352,6 +341,7 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
|
||||||
MEMORY_AREA* MemoryArea;
|
MEMORY_AREA* MemoryArea;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
BOOLEAN Locked = FromMdl;
|
BOOLEAN Locked = FromMdl;
|
||||||
|
PFN_TYPE Pfn;
|
||||||
|
|
||||||
DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address);
|
DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address);
|
||||||
|
|
||||||
|
@ -433,23 +423,13 @@ NTSTATUS MmNotPresentFault(KPROCESSOR_MODE Mode,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MEMORY_AREA_SHARED_DATA:
|
case MEMORY_AREA_SHARED_DATA:
|
||||||
|
Pfn = MmSharedDataPagePhysicalAddress.QuadPart >> PAGE_SHIFT;
|
||||||
Status =
|
Status =
|
||||||
MmCreateVirtualMapping(PsGetCurrentProcess(),
|
MmCreateVirtualMapping(PsGetCurrentProcess(),
|
||||||
(PVOID)PAGE_ROUND_DOWN(Address),
|
(PVOID)PAGE_ROUND_DOWN(Address),
|
||||||
PAGE_READONLY,
|
PAGE_READONLY,
|
||||||
MmSharedDataPagePhysicalAddress,
|
&Pfn,
|
||||||
FALSE);
|
1);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(&PsGetCurrentProcess()->AddressSpace);
|
|
||||||
Status =
|
|
||||||
MmCreateVirtualMapping(PsGetCurrentProcess(),
|
|
||||||
(PVOID)PAGE_ROUND_DOWN(Address),
|
|
||||||
PAGE_READONLY,
|
|
||||||
MmSharedDataPagePhysicalAddress,
|
|
||||||
TRUE);
|
|
||||||
MmLockAddressSpace(&PsGetCurrentProcess()->AddressSpace);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: mminit.c,v 1.63 2004/04/10 22:35:25 gdalsnes Exp $
|
/* $Id: mminit.c,v 1.64 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -95,7 +95,7 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
|
||||||
ULONG ParamLength = KernelLength;
|
ULONG ParamLength = KernelLength;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||||
//ULONG i;
|
PFN_TYPE Pfn;
|
||||||
|
|
||||||
DPRINT("MmInitVirtualMemory(%x, %x)\n",LastKernelAddress, KernelLength);
|
DPRINT("MmInitVirtualMemory(%x, %x)\n",LastKernelAddress, KernelLength);
|
||||||
|
|
||||||
|
@ -281,13 +281,13 @@ MmInitVirtualMemory(ULONG LastKernelAddress,
|
||||||
FALSE,
|
FALSE,
|
||||||
FALSE,
|
FALSE,
|
||||||
BoundaryAddressMultiple);
|
BoundaryAddressMultiple);
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE,
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Pfn);
|
||||||
&MmSharedDataPagePhysicalAddress);
|
MmSharedDataPagePhysicalAddress.QuadPart = Pfn << PAGE_SHIFT;
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
(PVOID)KI_USER_SHARED_DATA,
|
(PVOID)KI_USER_SHARED_DATA,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
MmSharedDataPagePhysicalAddress,
|
&Pfn,
|
||||||
TRUE);
|
1);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
@ -499,13 +499,13 @@ MmInit3(VOID)
|
||||||
|
|
||||||
VOID STATIC
|
VOID STATIC
|
||||||
MiFreeInitMemoryPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
MiFreeInitMemoryPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry,
|
PFN_TYPE Page, SWAPENTRY SwapEntry,
|
||||||
BOOLEAN Dirty)
|
BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
assert(SwapEntry == 0);
|
assert(SwapEntry == 0);
|
||||||
if (PhysAddr.QuadPart != 0)
|
if (Page != 0)
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysAddr);
|
MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: mpw.c,v 1.18 2004/04/10 22:35:25 gdalsnes Exp $
|
/* $Id: mpw.c,v 1.19 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/mpw.c
|
* FILE: ntoskrnl/mm/mpw.c
|
||||||
|
@ -49,19 +49,12 @@ static volatile BOOLEAN MpwThreadShouldTerminate;
|
||||||
NTSTATUS STDCALL
|
NTSTATUS STDCALL
|
||||||
MmWriteDirtyPages(ULONG Target, PULONG Actual)
|
MmWriteDirtyPages(ULONG Target, PULONG Actual)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
PHYSICAL_ADDRESS NextPage;
|
PFN_TYPE NextPage;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Page = MmGetLRUFirstUserPage();
|
Page = MmGetLRUFirstUserPage();
|
||||||
#if defined(__GNUC__)
|
while (Page != 0 && Target > 0)
|
||||||
|
|
||||||
while (Page.QuadPart != 0LL && Target > 0)
|
|
||||||
#else
|
|
||||||
|
|
||||||
while (Page.QuadPart && Target > 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* FIXME: While the current page is write back it is possible
|
* FIXME: While the current page is write back it is possible
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: ncache.c,v 1.28 2004/04/10 22:35:25 gdalsnes Exp $
|
/* $Id: ncache.c,v 1.29 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -78,27 +78,27 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
|
||||||
PAGE_WRITETHROUGH;
|
PAGE_WRITETHROUGH;
|
||||||
for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE); i++)
|
for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE); i++)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS NPage;
|
PFN_TYPE NPage;
|
||||||
|
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &NPage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &NPage);
|
||||||
MmCreateVirtualMapping (NULL,
|
MmCreateVirtualMapping (NULL,
|
||||||
(char*)Result + (i * PAGE_SIZE),
|
(char*)Result + (i * PAGE_SIZE),
|
||||||
Attributes,
|
Attributes,
|
||||||
NPage,
|
&NPage,
|
||||||
TRUE);
|
1);
|
||||||
}
|
}
|
||||||
return ((PVOID)Result);
|
return ((PVOID)Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STATIC
|
VOID STATIC
|
||||||
MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry,
|
PFN_TYPE Page, SWAPENTRY SwapEntry,
|
||||||
BOOLEAN Dirty)
|
BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
assert(SwapEntry == 0);
|
assert(SwapEntry == 0);
|
||||||
if (PhysAddr.QuadPart != 0)
|
if (Page != 0)
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysAddr);
|
MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: npool.c,v 1.85 2004/04/10 22:35:25 gdalsnes Exp $
|
/* $Id: npool.c,v 1.86 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -1248,54 +1248,58 @@ static BOOLEAN
|
||||||
grow_block(BLOCK_HDR* blk, PVOID end)
|
grow_block(BLOCK_HDR* blk, PVOID end)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page[32];
|
||||||
BOOLEAN result = TRUE;
|
ULONG StartIndex, EndIndex;
|
||||||
ULONG index;
|
ULONG i, j, k;
|
||||||
|
|
||||||
|
StartIndex = (ULONG)((char*)(PVOID)PAGE_ROUND_UP((ULONG)((char*)blk + BLOCK_HDR_SIZE)) - (char*)MiNonPagedPoolStart) / PAGE_SIZE;
|
||||||
|
EndIndex = (ULONG)((char*)PAGE_ROUND_UP(end) - (char*)MiNonPagedPoolStart) / PAGE_SIZE;
|
||||||
|
|
||||||
PVOID start = (PVOID)PAGE_ROUND_UP((ULONG)((char*)blk + BLOCK_HDR_SIZE));
|
|
||||||
end = (PVOID)PAGE_ROUND_UP(end);
|
for (i = StartIndex; i < EndIndex; i++)
|
||||||
index = (ULONG)((char*)start - (char*)MiNonPagedPoolStart) / PAGE_SIZE;
|
|
||||||
while (start < end)
|
|
||||||
{
|
{
|
||||||
if (!(MiNonPagedPoolAllocMap[index / 32] & (1 << (index % 32))))
|
if (!(MiNonPagedPoolAllocMap[i / 32] & (1 << (i % 32))))
|
||||||
{
|
{
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page);
|
for (j = i + 1; j < EndIndex && j - i < 32; j++)
|
||||||
if (!NT_SUCCESS(Status))
|
{
|
||||||
{
|
if (MiNonPagedPoolAllocMap[j / 32] & (1 << (j % 32)))
|
||||||
result = FALSE;
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
for (k = 0; k < j - i; k++)
|
||||||
|
{
|
||||||
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Page[k]);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
for (i = 0; i < k; i++)
|
||||||
|
{
|
||||||
|
MmReleasePageMemoryConsumer(MC_NPPOOL, Page[i]);
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
start,
|
MiNonPagedPoolStart + i * PAGE_SIZE,
|
||||||
PAGE_READWRITE|PAGE_SYSTEM,
|
PAGE_READWRITE|PAGE_SYSTEM,
|
||||||
Page,
|
Page,
|
||||||
FALSE);
|
k);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
for (i = 0; i < k; i++)
|
||||||
MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
|
{
|
||||||
result = FALSE;
|
MmReleasePageMemoryConsumer(MC_NPPOOL, Page[i]);
|
||||||
break;
|
}
|
||||||
}
|
return FALSE;
|
||||||
MiNonPagedPoolAllocMap[index / 32] |= (1 << (index % 32));
|
}
|
||||||
memset(start, 0xcc, PAGE_SIZE);
|
for (j = i; j < k + i; j++)
|
||||||
MiNonPagedPoolNrOfPages++;
|
{
|
||||||
|
MiNonPagedPoolAllocMap[j / 32] |= (1 << (j % 32));
|
||||||
|
}
|
||||||
|
i += k - 1;
|
||||||
}
|
}
|
||||||
index++;
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
|
|
||||||
start += PAGE_SIZE;
|
|
||||||
#else
|
|
||||||
|
|
||||||
{
|
|
||||||
char* pTemp = start;
|
|
||||||
pTemp += PAGE_SIZE;
|
|
||||||
start = pTemp;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return result;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BLOCK_HDR* get_block(unsigned int size, unsigned long alignment)
|
static BLOCK_HDR* get_block(unsigned int size, unsigned long alignment)
|
||||||
|
@ -1729,7 +1733,7 @@ VOID INIT_FUNCTION
|
||||||
MiInitializeNonPagedPool(VOID)
|
MiInitializeNonPagedPool(VOID)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
PVOID Address;
|
PVOID Address;
|
||||||
#ifdef WHOLE_PAGE_ALLOCATIONS
|
#ifdef WHOLE_PAGE_ALLOCATIONS
|
||||||
|
@ -1793,8 +1797,8 @@ MiInitializeNonPagedPool(VOID)
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
Address,
|
Address,
|
||||||
PAGE_READWRITE|PAGE_SYSTEM,
|
PAGE_READWRITE|PAGE_SYSTEM,
|
||||||
Page,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: pagefile.c,v 1.48 2004/06/19 08:53:35 vizzini Exp $
|
/* $Id: pagefile.c,v 1.49 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/pagefile.c
|
* FILE: ntoskrnl/mm/pagefile.c
|
||||||
|
@ -191,7 +191,7 @@ MmGetOffsetPageFile(PGET_RETRIEVAL_DESCRIPTOR RetrievalPointers, LARGE_INTEGER O
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PHYSICAL_ADDRESS* Page)
|
NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
|
||||||
{
|
{
|
||||||
ULONG i, offset;
|
ULONG i, offset;
|
||||||
LARGE_INTEGER file_offset;
|
LARGE_INTEGER file_offset;
|
||||||
|
@ -225,7 +225,7 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PHYSICAL_ADDRESS* Page)
|
||||||
}
|
}
|
||||||
|
|
||||||
MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
|
MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
|
||||||
MmBuildMdlFromPages(Mdl, (PULONG)Page);
|
MmBuildMdlFromPages(Mdl, &Page);
|
||||||
|
|
||||||
file_offset.QuadPart = offset * PAGE_SIZE;
|
file_offset.QuadPart = offset * PAGE_SIZE;
|
||||||
file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
|
file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
|
||||||
|
@ -245,7 +245,7 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PHYSICAL_ADDRESS* Page)
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PHYSICAL_ADDRESS* Page)
|
NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page)
|
||||||
{
|
{
|
||||||
ULONG i, offset;
|
ULONG i, offset;
|
||||||
LARGE_INTEGER file_offset;
|
LARGE_INTEGER file_offset;
|
||||||
|
@ -279,7 +279,7 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PHYSICAL_ADDRESS* Page)
|
||||||
}
|
}
|
||||||
|
|
||||||
MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
|
MmInitializeMdl(Mdl, NULL, PAGE_SIZE);
|
||||||
MmBuildMdlFromPages(Mdl, (PULONG)Page);
|
MmBuildMdlFromPages(Mdl, &Page);
|
||||||
|
|
||||||
file_offset.QuadPart = offset * PAGE_SIZE;
|
file_offset.QuadPart = offset * PAGE_SIZE;
|
||||||
file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
|
file_offset = MmGetOffsetPageFile(PagingFileList[i]->RetrievalPointers, file_offset);
|
||||||
|
@ -591,12 +591,11 @@ MmDumpToPagingFile(ULONG BugCode,
|
||||||
{
|
{
|
||||||
for (i = 0; i < MmStats.NrTotalPages; i++)
|
for (i = 0; i < MmStats.NrTotalPages; i++)
|
||||||
{
|
{
|
||||||
LARGE_INTEGER PhysicalAddress;
|
|
||||||
PhysicalAddress.QuadPart = i * PAGE_SIZE;
|
|
||||||
MdlMap[0] = i;
|
MdlMap[0] = i;
|
||||||
MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
|
MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
PhysicalAddress);
|
MdlMap,
|
||||||
|
1);
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
|
|
||||||
DiskOffset = MmGetOffsetPageFile(RetrievalPointers,
|
DiskOffset = MmGetOffsetPageFile(RetrievalPointers,
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: rmap.c,v 1.28 2004/04/10 22:35:25 gdalsnes Exp $
|
/* $Id: rmap.c,v 1.29 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -69,7 +69,7 @@ MmInitializeRmapList(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
|
MmWritePagePhysicalAddress(PFN_TYPE Page)
|
||||||
{
|
{
|
||||||
PMM_RMAP_ENTRY entry;
|
PMM_RMAP_ENTRY entry;
|
||||||
PMEMORY_AREA MemoryArea;
|
PMEMORY_AREA MemoryArea;
|
||||||
|
@ -86,7 +86,7 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
|
||||||
* process so it isn't freed while we are working.
|
* process so it isn't freed while we are working.
|
||||||
*/
|
*/
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&RmapListLock);
|
||||||
entry = MmGetRmapListHeadPage(PhysicalAddress);
|
entry = MmGetRmapListHeadPage(Page);
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
{
|
{
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
ExReleaseFastMutex(&RmapListLock);
|
||||||
|
@ -202,7 +202,7 @@ MmWritePagePhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
|
MmPageOutPhysicalAddress(PFN_TYPE Page)
|
||||||
{
|
{
|
||||||
PMM_RMAP_ENTRY entry;
|
PMM_RMAP_ENTRY entry;
|
||||||
PMEMORY_AREA MemoryArea;
|
PMEMORY_AREA MemoryArea;
|
||||||
|
@ -215,8 +215,8 @@ MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&RmapListLock);
|
||||||
entry = MmGetRmapListHeadPage(PhysicalAddress);
|
entry = MmGetRmapListHeadPage(Page);
|
||||||
if (entry == NULL || MmGetLockCountPage(PhysicalAddress) != 0)
|
if (entry == NULL || MmGetLockCountPage(Page) != 0)
|
||||||
{
|
{
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
ExReleaseFastMutex(&RmapListLock);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
@ -324,12 +324,12 @@ MmPageOutPhysicalAddress(PHYSICAL_ADDRESS PhysicalAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmSetCleanAllRmaps(PHYSICAL_ADDRESS PhysicalAddress)
|
MmSetCleanAllRmaps(PFN_TYPE Page)
|
||||||
{
|
{
|
||||||
PMM_RMAP_ENTRY current_entry;
|
PMM_RMAP_ENTRY current_entry;
|
||||||
|
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&RmapListLock);
|
||||||
current_entry = MmGetRmapListHeadPage(PhysicalAddress);
|
current_entry = MmGetRmapListHeadPage(Page);
|
||||||
if (current_entry == NULL)
|
if (current_entry == NULL)
|
||||||
{
|
{
|
||||||
DPRINT1("MmIsDirtyRmap: No rmaps.\n");
|
DPRINT1("MmIsDirtyRmap: No rmaps.\n");
|
||||||
|
@ -344,12 +344,12 @@ MmSetCleanAllRmaps(PHYSICAL_ADDRESS PhysicalAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmSetDirtyAllRmaps(PHYSICAL_ADDRESS PhysicalAddress)
|
MmSetDirtyAllRmaps(PFN_TYPE Page)
|
||||||
{
|
{
|
||||||
PMM_RMAP_ENTRY current_entry;
|
PMM_RMAP_ENTRY current_entry;
|
||||||
|
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&RmapListLock);
|
||||||
current_entry = MmGetRmapListHeadPage(PhysicalAddress);
|
current_entry = MmGetRmapListHeadPage(Page);
|
||||||
if (current_entry == NULL)
|
if (current_entry == NULL)
|
||||||
{
|
{
|
||||||
DPRINT1("MmIsDirtyRmap: No rmaps.\n");
|
DPRINT1("MmIsDirtyRmap: No rmaps.\n");
|
||||||
|
@ -364,12 +364,12 @@ MmSetDirtyAllRmaps(PHYSICAL_ADDRESS PhysicalAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
MmIsDirtyPageRmap(PHYSICAL_ADDRESS PhysicalAddress)
|
MmIsDirtyPageRmap(PFN_TYPE Page)
|
||||||
{
|
{
|
||||||
PMM_RMAP_ENTRY current_entry;
|
PMM_RMAP_ENTRY current_entry;
|
||||||
|
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&RmapListLock);
|
||||||
current_entry = MmGetRmapListHeadPage(PhysicalAddress);
|
current_entry = MmGetRmapListHeadPage(Page);
|
||||||
if (current_entry == NULL)
|
if (current_entry == NULL)
|
||||||
{
|
{
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
ExReleaseFastMutex(&RmapListLock);
|
||||||
|
@ -389,7 +389,7 @@ MmIsDirtyPageRmap(PHYSICAL_ADDRESS PhysicalAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process,
|
MmInsertRmap(PFN_TYPE Page, PEPROCESS Process,
|
||||||
PVOID Address)
|
PVOID Address)
|
||||||
{
|
{
|
||||||
PMM_RMAP_ENTRY current_entry;
|
PMM_RMAP_ENTRY current_entry;
|
||||||
|
@ -405,25 +405,24 @@ MmInsertRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process,
|
||||||
new_entry->Address = Address;
|
new_entry->Address = Address;
|
||||||
new_entry->Process = Process;
|
new_entry->Process = Process;
|
||||||
|
|
||||||
if (MmGetPhysicalAddressForProcess(Process, Address).QuadPart !=
|
if (MmGetPfnForProcess(Process, Address) != Page)
|
||||||
PhysicalAddress.QuadPart)
|
|
||||||
{
|
{
|
||||||
DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical "
|
DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical "
|
||||||
"address 0x%.8X\n", Process->UniqueProcessId, Address,
|
"address 0x%.8X\n", Process->UniqueProcessId, Address,
|
||||||
MmGetPhysicalAddressForProcess(Process, Address).u.LowPart,
|
MmGetPfnForProcess(Process, Address) << PAGE_SHIFT,
|
||||||
PhysicalAddress.u.LowPart);
|
Page << PAGE_SHIFT);
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&RmapListLock);
|
||||||
current_entry = MmGetRmapListHeadPage(PhysicalAddress);
|
current_entry = MmGetRmapListHeadPage(Page);
|
||||||
new_entry->Next = current_entry;
|
new_entry->Next = current_entry;
|
||||||
MmSetRmapListHeadPage(PhysicalAddress, new_entry);
|
MmSetRmapListHeadPage(Page, new_entry);
|
||||||
ExReleaseFastMutex(&RmapListLock);
|
ExReleaseFastMutex(&RmapListLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress, PVOID Context,
|
MmDeleteAllRmaps(PFN_TYPE Page, PVOID Context,
|
||||||
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process,
|
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process,
|
||||||
PVOID Address))
|
PVOID Address))
|
||||||
{
|
{
|
||||||
|
@ -431,13 +430,13 @@ MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress, PVOID Context,
|
||||||
PMM_RMAP_ENTRY previous_entry;
|
PMM_RMAP_ENTRY previous_entry;
|
||||||
|
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&RmapListLock);
|
||||||
current_entry = MmGetRmapListHeadPage(PhysicalAddress);
|
current_entry = MmGetRmapListHeadPage(Page);
|
||||||
if (current_entry == NULL)
|
if (current_entry == NULL)
|
||||||
{
|
{
|
||||||
DPRINT1("MmDeleteAllRmaps: No rmaps.\n");
|
DPRINT1("MmDeleteAllRmaps: No rmaps.\n");
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
MmSetRmapListHeadPage(PhysicalAddress, NULL);
|
MmSetRmapListHeadPage(Page, NULL);
|
||||||
while (current_entry != NULL)
|
while (current_entry != NULL)
|
||||||
{
|
{
|
||||||
previous_entry = current_entry;
|
previous_entry = current_entry;
|
||||||
|
@ -453,14 +452,14 @@ MmDeleteAllRmaps(PHYSICAL_ADDRESS PhysicalAddress, PVOID Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process,
|
MmDeleteRmap(PFN_TYPE Page, PEPROCESS Process,
|
||||||
PVOID Address)
|
PVOID Address)
|
||||||
{
|
{
|
||||||
PMM_RMAP_ENTRY current_entry, previous_entry;
|
PMM_RMAP_ENTRY current_entry, previous_entry;
|
||||||
|
|
||||||
ExAcquireFastMutex(&RmapListLock);
|
ExAcquireFastMutex(&RmapListLock);
|
||||||
previous_entry = NULL;
|
previous_entry = NULL;
|
||||||
current_entry = MmGetRmapListHeadPage(PhysicalAddress);
|
current_entry = MmGetRmapListHeadPage(Page);
|
||||||
while (current_entry != NULL)
|
while (current_entry != NULL)
|
||||||
{
|
{
|
||||||
if (current_entry->Process == Process &&
|
if (current_entry->Process == Process &&
|
||||||
|
@ -468,7 +467,7 @@ MmDeleteRmap(PHYSICAL_ADDRESS PhysicalAddress, PEPROCESS Process,
|
||||||
{
|
{
|
||||||
if (previous_entry == NULL)
|
if (previous_entry == NULL)
|
||||||
{
|
{
|
||||||
MmSetRmapListHeadPage(PhysicalAddress, current_entry->Next);
|
MmSetRmapListHeadPage(Page, current_entry->Next);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: section.c,v 1.154 2004/07/17 03:03:52 ion Exp $
|
/* $Id: section.c,v 1.155 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/section.c
|
* FILE: ntoskrnl/mm/section.c
|
||||||
|
@ -71,6 +71,7 @@ static GENERIC_MAPPING MmpSectionMapping = {
|
||||||
#define TAG_SECTION_PAGE_TABLE TAG('M', 'S', 'P', 'T')
|
#define TAG_SECTION_PAGE_TABLE TAG('M', 'S', 'P', 'T')
|
||||||
|
|
||||||
#define PAGE_FROM_SSE(E) ((E) & 0xFFFFF000)
|
#define PAGE_FROM_SSE(E) ((E) & 0xFFFFF000)
|
||||||
|
#define PFN_FROM_SSE(E) ((E) >> PAGE_SHIFT)
|
||||||
#define SHARE_COUNT_FROM_SSE(E) (((E) & 0x00000FFE) >> 1)
|
#define SHARE_COUNT_FROM_SSE(E) (((E) & 0x00000FFE) >> 1)
|
||||||
#define IS_SWAP_FROM_SSE(E) ((E) & 0x00000001)
|
#define IS_SWAP_FROM_SSE(E) ((E) & 0x00000001)
|
||||||
#define MAX_SHARE_COUNT 0x7FF
|
#define MAX_SHARE_COUNT 0x7FF
|
||||||
|
@ -327,7 +328,7 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section,
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PBCB Bcb;
|
PBCB Bcb;
|
||||||
SWAPENTRY SavedSwapEntry;
|
SWAPENTRY SavedSwapEntry;
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
BOOLEAN IsImageSection;
|
BOOLEAN IsImageSection;
|
||||||
ULONG FileOffset;
|
ULONG FileOffset;
|
||||||
|
|
||||||
|
@ -335,7 +336,7 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section,
|
||||||
|
|
||||||
IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
|
IsImageSection = Section->AllocationAttributes & SEC_IMAGE ? TRUE : FALSE;
|
||||||
|
|
||||||
Page.QuadPart = (LONGLONG)PAGE_FROM_SSE(Entry);
|
Page = PFN_FROM_SSE(Entry);
|
||||||
FileObject = Section->FileObject;
|
FileObject = Section->FileObject;
|
||||||
if (FileObject != NULL &&
|
if (FileObject != NULL &&
|
||||||
!(Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED))
|
!(Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED))
|
||||||
|
@ -396,7 +397,7 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section,
|
||||||
* process and the current segment (also not within an other process).
|
* process and the current segment (also not within an other process).
|
||||||
*/
|
*/
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
Status = MmWriteToSwapPage(SavedSwapEntry, &Page);
|
Status = MmWriteToSwapPage(SavedSwapEntry, Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status);
|
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n", Status);
|
||||||
|
@ -443,7 +444,7 @@ BOOL MiIsPageFromCache(PMEMORY_AREA MemoryArea,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MiReadPage(PMEMORY_AREA MemoryArea,
|
MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
ULONG SegOffset,
|
ULONG SegOffset,
|
||||||
PHYSICAL_ADDRESS* Page)
|
PPFN_TYPE Page)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Read a page for a section backed memory area.
|
* FUNCTION: Read a page for a section backed memory area.
|
||||||
* PARAMETERS:
|
* PARAMETERS:
|
||||||
|
@ -480,8 +481,8 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
* then get the related cache segment.
|
* then get the related cache segment.
|
||||||
*/
|
*/
|
||||||
if ((FileOffset % PAGE_SIZE) == 0 &&
|
if ((FileOffset % PAGE_SIZE) == 0 &&
|
||||||
(SegOffset + PAGE_SIZE <= RawLength || !IsImageSection) &&
|
(SegOffset + PAGE_SIZE <= RawLength || !IsImageSection) &&
|
||||||
!(MemoryArea->Data.SectionData.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED))
|
!(MemoryArea->Data.SectionData.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED))
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -516,7 +517,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
|
||||||
* Retrieve the page from the cache segment that we actually want.
|
* Retrieve the page from the cache segment that we actually want.
|
||||||
*/
|
*/
|
||||||
(*Page) = MmGetPhysicalAddress((char*)BaseAddress +
|
(*Page) = MmGetPhysicalAddress((char*)BaseAddress +
|
||||||
FileOffset - BaseOffset);
|
FileOffset - BaseOffset).QuadPart >> PAGE_SHIFT;
|
||||||
|
|
||||||
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, TRUE);
|
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, TRUE);
|
||||||
}
|
}
|
||||||
|
@ -618,7 +619,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
BOOLEAN Locked)
|
BOOLEAN Locked)
|
||||||
{
|
{
|
||||||
ULONG Offset;
|
ULONG Offset;
|
||||||
LARGE_INTEGER Page;
|
PFN_TYPE Page;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG PAddress;
|
ULONG PAddress;
|
||||||
PSECTION_OBJECT Section;
|
PSECTION_OBJECT Section;
|
||||||
|
@ -639,7 +640,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage(MmGetPhysicalAddressForProcess(AddressSpace->Process, Address));
|
MmLockPage(MmGetPfnForProcess(AddressSpace->Process, Address));
|
||||||
}
|
}
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -661,8 +662,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* Check if this page needs to be mapped COW
|
* Check if this page needs to be mapped COW
|
||||||
*/
|
*/
|
||||||
if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
|
if ((Segment->WriteCopy || MemoryArea->Data.SectionData.WriteCopyView) &&
|
||||||
(Region->Protect == PAGE_READWRITE ||
|
(Region->Protect == PAGE_READWRITE ||
|
||||||
Region->Protect == PAGE_EXECUTE_READWRITE))
|
Region->Protect == PAGE_EXECUTE_READWRITE))
|
||||||
{
|
{
|
||||||
Attributes = Region->Protect == PAGE_READWRITE ? PAGE_READONLY : PAGE_EXECUTE_READ;
|
Attributes = Region->Protect == PAGE_READWRITE ? PAGE_READONLY : PAGE_EXECUTE_READ;
|
||||||
}
|
}
|
||||||
|
@ -744,26 +745,15 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
return(STATUS_MM_RESTART_OPERATION);
|
return(STATUS_MM_RESTART_OPERATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.QuadPart = (LONGLONG)(PAGE_FROM_SSE(Entry));
|
Page = PFN_FROM_SSE(Entry);
|
||||||
|
|
||||||
MmSharePageEntrySectionSegment(Segment, Offset);
|
MmSharePageEntrySectionSegment(Segment, Offset);
|
||||||
|
|
||||||
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
||||||
Address,
|
Address,
|
||||||
Attributes,
|
Attributes,
|
||||||
Page,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
if (Status == STATUS_NO_MEMORY)
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
|
||||||
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
|
||||||
Address,
|
|
||||||
Attributes,
|
|
||||||
Page,
|
|
||||||
TRUE);
|
|
||||||
MmLockAddressSpace(AddressSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
@ -809,7 +799,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = MmReadFromSwapPage(SwapEntry, &Page);
|
Status = MmReadFromSwapPage(SwapEntry, Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
|
DPRINT1("MmReadFromSwapPage failed, status = %x\n", Status);
|
||||||
|
@ -819,18 +809,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
||||||
Address,
|
Address,
|
||||||
Region->Protect,
|
Region->Protect,
|
||||||
Page,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
if (Status == STATUS_NO_MEMORY)
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
|
||||||
Address,
|
|
||||||
Region->Protect,
|
|
||||||
Page,
|
|
||||||
TRUE);
|
|
||||||
MmLockAddressSpace(AddressSpace);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
|
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
|
||||||
|
@ -853,7 +833,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
if (Locked)
|
if (Locked)
|
||||||
{
|
{
|
||||||
MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
|
MmLockPage(Page);
|
||||||
}
|
}
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
MmspCompleteAndReleasePageOp(PageOp);
|
MmspCompleteAndReleasePageOp(PageOp);
|
||||||
|
@ -870,22 +850,12 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Just map the desired physical page
|
* Just map the desired physical page
|
||||||
*/
|
*/
|
||||||
Page.QuadPart = Offset + MemoryArea->Data.SectionData.ViewOffset;
|
Page = (Offset + MemoryArea->Data.SectionData.ViewOffset) >> PAGE_SHIFT;
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
||||||
Address,
|
Address,
|
||||||
Region->Protect,
|
Region->Protect,
|
||||||
Page,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
if (Status == STATUS_NO_MEMORY)
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
|
||||||
Address,
|
|
||||||
Region->Protect,
|
|
||||||
Page,
|
|
||||||
TRUE);
|
|
||||||
MmLockAddressSpace(AddressSpace);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
|
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
|
||||||
|
@ -930,19 +900,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
||||||
Address,
|
Address,
|
||||||
Region->Protect,
|
Region->Protect,
|
||||||
Page,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
if (Status == STATUS_NO_MEMORY)
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
|
||||||
Address,
|
|
||||||
Region->Protect,
|
|
||||||
Page,
|
|
||||||
TRUE);
|
|
||||||
MmLockAddressSpace(AddressSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
|
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
|
||||||
|
@ -983,7 +942,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
MmUnlockAddressSpace(AddressSpace);
|
||||||
|
|
||||||
if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
|
if ((Segment->Flags & MM_PAGEFILE_SEGMENT) ||
|
||||||
(Offset >= PAGE_ROUND_UP(Segment->RawLength) && Section->AllocationAttributes & SEC_IMAGE))
|
(Offset >= PAGE_ROUND_UP(Segment->RawLength) && Section->AllocationAttributes & SEC_IMAGE))
|
||||||
{
|
{
|
||||||
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
|
Status = MmRequestPageMemoryConsumer(MC_USER, TRUE, &Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -1034,25 +993,15 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* Mark the offset within the section as having valid, in-memory
|
* Mark the offset within the section as having valid, in-memory
|
||||||
* data
|
* data
|
||||||
*/
|
*/
|
||||||
Entry = MAKE_SSE(Page.u.LowPart, 1);
|
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
|
||||||
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
|
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
|
||||||
MmUnlockSectionSegment(Segment);
|
MmUnlockSectionSegment(Segment);
|
||||||
|
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
||||||
Address,
|
Address,
|
||||||
Attributes,
|
Attributes,
|
||||||
Page,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
if (Status == STATUS_NO_MEMORY)
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
|
||||||
Address,
|
|
||||||
Attributes,
|
|
||||||
Page,
|
|
||||||
TRUE);
|
|
||||||
MmLockAddressSpace(AddressSpace);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
@ -1088,7 +1037,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = MmReadFromSwapPage(SwapEntry, &Page);
|
Status = MmReadFromSwapPage(SwapEntry, Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
|
@ -1115,7 +1064,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* Mark the offset within the section as having valid, in-memory
|
* Mark the offset within the section as having valid, in-memory
|
||||||
* data
|
* data
|
||||||
*/
|
*/
|
||||||
Entry = MAKE_SSE(Page.u.LowPart, 1);
|
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
|
||||||
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
|
MmSetPageEntrySectionSegment(Segment, Offset, Entry);
|
||||||
MmUnlockSectionSegment(Segment);
|
MmUnlockSectionSegment(Segment);
|
||||||
|
|
||||||
|
@ -1126,18 +1075,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
||||||
Address,
|
Address,
|
||||||
Region->Protect,
|
Region->Protect,
|
||||||
Page,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
if (Status == STATUS_NO_MEMORY)
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
|
||||||
Address,
|
|
||||||
Region->Protect,
|
|
||||||
Page,
|
|
||||||
TRUE);
|
|
||||||
MmLockAddressSpace(AddressSpace);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
@ -1160,7 +1099,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* take another reference to the page
|
* take another reference to the page
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Page.QuadPart = (LONGLONG)PAGE_FROM_SSE(Entry);
|
Page = PFN_FROM_SSE(Entry);
|
||||||
|
|
||||||
MmSharePageEntrySectionSegment(Segment, Offset);
|
MmSharePageEntrySectionSegment(Segment, Offset);
|
||||||
MmUnlockSectionSegment(Segment);
|
MmUnlockSectionSegment(Segment);
|
||||||
|
@ -1168,18 +1107,8 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
||||||
Address,
|
Address,
|
||||||
Attributes,
|
Attributes,
|
||||||
Page,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
if (Status == STATUS_NO_MEMORY)
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
|
||||||
Address,
|
|
||||||
Attributes,
|
|
||||||
Page,
|
|
||||||
TRUE);
|
|
||||||
MmLockAddressSpace(AddressSpace);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
@ -1205,8 +1134,8 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
PMM_SECTION_SEGMENT Segment;
|
PMM_SECTION_SEGMENT Segment;
|
||||||
PSECTION_OBJECT Section;
|
PSECTION_OBJECT Section;
|
||||||
PHYSICAL_ADDRESS OldPage;
|
PFN_TYPE OldPage;
|
||||||
PHYSICAL_ADDRESS NewPage;
|
PFN_TYPE NewPage;
|
||||||
PVOID NewAddress;
|
PVOID NewAddress;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG PAddress;
|
ULONG PAddress;
|
||||||
|
@ -1241,7 +1170,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
*/
|
*/
|
||||||
MmLockSectionSegment(Segment);
|
MmLockSectionSegment(Segment);
|
||||||
|
|
||||||
OldPage = MmGetPhysicalAddressForProcess(NULL, Address);
|
OldPage = MmGetPfnForProcess(NULL, Address);
|
||||||
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
|
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
|
||||||
|
|
||||||
MmUnlockSectionSegment(Segment);
|
MmUnlockSectionSegment(Segment);
|
||||||
|
@ -1258,7 +1187,7 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_SWAP_FROM_SSE(Entry) ||
|
if (IS_SWAP_FROM_SSE(Entry) ||
|
||||||
PAGE_FROM_SSE(Entry) != OldPage.u.LowPart)
|
PFN_FROM_SSE(Entry) != OldPage)
|
||||||
{
|
{
|
||||||
/* This is a private page. We must only change the page protection. */
|
/* This is a private page. We must only change the page protection. */
|
||||||
MmSetPageProtect(AddressSpace->Process, (PVOID)PAddress, Region->Protect);
|
MmSetPageProtect(AddressSpace->Process, (PVOID)PAddress, Region->Protect);
|
||||||
|
@ -1339,18 +1268,8 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
||||||
Address,
|
Address,
|
||||||
Region->Protect,
|
Region->Protect,
|
||||||
NewPage,
|
&NewPage,
|
||||||
FALSE);
|
1);
|
||||||
if (Status == STATUS_NO_MEMORY)
|
|
||||||
{
|
|
||||||
MmUnlockAddressSpace(AddressSpace);
|
|
||||||
Status = MmCreateVirtualMapping(AddressSpace->Process,
|
|
||||||
Address,
|
|
||||||
Region->Protect,
|
|
||||||
NewPage,
|
|
||||||
TRUE);
|
|
||||||
MmLockAddressSpace(AddressSpace);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
|
DPRINT("MmCreateVirtualMapping failed, not out of memory\n");
|
||||||
|
@ -1388,7 +1307,7 @@ MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
|
||||||
{
|
{
|
||||||
MM_SECTION_PAGEOUT_CONTEXT* PageOutContext;
|
MM_SECTION_PAGEOUT_CONTEXT* PageOutContext;
|
||||||
BOOL WasDirty;
|
BOOL WasDirty;
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
|
|
||||||
PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
|
PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
|
||||||
MmDeleteVirtualMapping(Process,
|
MmDeleteVirtualMapping(Process,
|
||||||
|
@ -1422,7 +1341,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
PVOID Address,
|
PVOID Address,
|
||||||
PMM_PAGEOP PageOp)
|
PMM_PAGEOP PageOp)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS PhysicalAddress;
|
PFN_TYPE Page;
|
||||||
MM_SECTION_PAGEOUT_CONTEXT Context;
|
MM_SECTION_PAGEOUT_CONTEXT Context;
|
||||||
SWAPENTRY SwapEntry;
|
SWAPENTRY SwapEntry;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
|
@ -1449,7 +1368,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
FileObject = Context.Section->FileObject;
|
FileObject = Context.Section->FileObject;
|
||||||
DirectMapped = FALSE;
|
DirectMapped = FALSE;
|
||||||
if (FileObject != NULL &&
|
if (FileObject != NULL &&
|
||||||
!(Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED))
|
!(Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED))
|
||||||
{
|
{
|
||||||
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
|
|
||||||
|
@ -1488,9 +1407,8 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0, Address);
|
AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0, Address);
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
PhysicalAddress =
|
Page = MmGetPfnForProcess(AddressSpace->Process, Address);
|
||||||
MmGetPhysicalAddressForProcess(AddressSpace->Process, Address);
|
SwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||||
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare the context structure for the rmap delete call.
|
* Prepare the context structure for the rmap delete call.
|
||||||
|
@ -1498,7 +1416,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Context.WasDirty = FALSE;
|
Context.WasDirty = FALSE;
|
||||||
if (Context.Segment->Characteristics & IMAGE_SECTION_CHAR_BSS ||
|
if (Context.Segment->Characteristics & IMAGE_SECTION_CHAR_BSS ||
|
||||||
IS_SWAP_FROM_SSE(Entry) ||
|
IS_SWAP_FROM_SSE(Entry) ||
|
||||||
(LONGLONG)PAGE_FROM_SSE(Entry) != PhysicalAddress.QuadPart)
|
PFN_FROM_SSE(Entry) != Page)
|
||||||
{
|
{
|
||||||
Context.Private = TRUE;
|
Context.Private = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1520,10 +1438,10 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MmReferencePage(PhysicalAddress);
|
MmReferencePage(Page);
|
||||||
}
|
}
|
||||||
|
|
||||||
MmDeleteAllRmaps(PhysicalAddress, (PVOID)&Context, MmPageOutDeleteMapping);
|
MmDeleteAllRmaps(Page, (PVOID)&Context, MmPageOutDeleteMapping);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this wasn't a private page then we should have reduced the entry to
|
* If this wasn't a private page then we should have reduced the entry to
|
||||||
|
@ -1545,7 +1463,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
* If the page is from a pagefile section and has no swap entry,
|
* If the page is from a pagefile section and has no swap entry,
|
||||||
* we can't free the page at this point.
|
* we can't free the page at this point.
|
||||||
*/
|
*/
|
||||||
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
SwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||||
if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT)
|
if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT)
|
||||||
{
|
{
|
||||||
if (Context.Private)
|
if (Context.Private)
|
||||||
|
@ -1556,9 +1474,9 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
if (!Context.WasDirty && SwapEntry != 0)
|
if (!Context.WasDirty && SwapEntry != 0)
|
||||||
{
|
{
|
||||||
MmSetSavedSwapEntryPage(PhysicalAddress, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry));
|
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry));
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
MmspCompleteAndReleasePageOp(PageOp);
|
MmspCompleteAndReleasePageOp(PageOp);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -1574,12 +1492,12 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
if (!Context.WasDirty || SwapEntry != 0)
|
if (!Context.WasDirty || SwapEntry != 0)
|
||||||
{
|
{
|
||||||
MmSetSavedSwapEntryPage(PhysicalAddress, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
if (SwapEntry != 0)
|
if (SwapEntry != 0)
|
||||||
{
|
{
|
||||||
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry));
|
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, MAKE_SWAP_SSE(SwapEntry));
|
||||||
}
|
}
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
MmspCompleteAndReleasePageOp(PageOp);
|
MmspCompleteAndReleasePageOp(PageOp);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -1611,14 +1529,14 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Address);
|
Address);
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
MmspCompleteAndReleasePageOp(PageOp);
|
MmspCompleteAndReleasePageOp(PageOp);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
else if (!Context.WasDirty && Context.Private && SwapEntry != 0)
|
else if (!Context.WasDirty && Context.Private && SwapEntry != 0)
|
||||||
{
|
{
|
||||||
MmSetSavedSwapEntryPage(PhysicalAddress, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
Status = MmCreatePageFileMapping(AddressSpace->Process,
|
Status = MmCreatePageFileMapping(AddressSpace->Process,
|
||||||
Address,
|
Address,
|
||||||
SwapEntry);
|
SwapEntry);
|
||||||
|
@ -1626,7 +1544,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
MmspCompleteAndReleasePageOp(PageOp);
|
MmspCompleteAndReleasePageOp(PageOp);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -1650,10 +1568,10 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
PhysicalAddress,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
MmSetDirtyPage(MemoryArea->Process, Address);
|
MmSetDirtyPage(MemoryArea->Process, Address);
|
||||||
MmInsertRmap(PhysicalAddress,
|
MmInsertRmap(Page,
|
||||||
MemoryArea->Process,
|
MemoryArea->Process,
|
||||||
Address);
|
Address);
|
||||||
}
|
}
|
||||||
|
@ -1667,13 +1585,13 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
PhysicalAddress,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
MmSetDirtyPage(MemoryArea->Process, Address);
|
MmSetDirtyPage(MemoryArea->Process, Address);
|
||||||
MmInsertRmap(PhysicalAddress,
|
MmInsertRmap(Page,
|
||||||
MemoryArea->Process,
|
MemoryArea->Process,
|
||||||
Address);
|
Address);
|
||||||
Entry = MAKE_SSE(PhysicalAddress.u.LowPart, 1);
|
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
|
||||||
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
|
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
|
||||||
}
|
}
|
||||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
|
@ -1685,7 +1603,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Write the page to the pagefile
|
* Write the page to the pagefile
|
||||||
*/
|
*/
|
||||||
Status = MmWriteToSwapPage(SwapEntry, &PhysicalAddress);
|
Status = MmWriteToSwapPage(SwapEntry, Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
|
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
|
||||||
|
@ -1699,10 +1617,10 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
PhysicalAddress,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
MmSetDirtyPage(MemoryArea->Process, Address);
|
MmSetDirtyPage(MemoryArea->Process, Address);
|
||||||
MmInsertRmap(PhysicalAddress,
|
MmInsertRmap(Page,
|
||||||
MemoryArea->Process,
|
MemoryArea->Process,
|
||||||
Address);
|
Address);
|
||||||
}
|
}
|
||||||
|
@ -1711,13 +1629,13 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
Status = MmCreateVirtualMapping(MemoryArea->Process,
|
||||||
Address,
|
Address,
|
||||||
MemoryArea->Attributes,
|
MemoryArea->Attributes,
|
||||||
PhysicalAddress,
|
&Page,
|
||||||
FALSE);
|
1);
|
||||||
MmSetDirtyPage(MemoryArea->Process, Address);
|
MmSetDirtyPage(MemoryArea->Process, Address);
|
||||||
MmInsertRmap(PhysicalAddress,
|
MmInsertRmap(Page,
|
||||||
MemoryArea->Process,
|
MemoryArea->Process,
|
||||||
Address);
|
Address);
|
||||||
Entry = MAKE_SSE(PhysicalAddress.u.LowPart, 1);
|
Entry = MAKE_SSE(Page << PAGE_SHIFT, 1);
|
||||||
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
|
MmSetPageEntrySectionSegment(Context.Segment, Context.Offset, Entry);
|
||||||
}
|
}
|
||||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
|
@ -1728,8 +1646,8 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Otherwise we have succeeded.
|
* Otherwise we have succeeded.
|
||||||
*/
|
*/
|
||||||
DPRINT("MM: Wrote section page 0x%.8X to swap!\n", PhysicalAddress);
|
DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT);
|
||||||
MmSetSavedSwapEntryPage(PhysicalAddress, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT ||
|
if (Context.Segment->Flags & MM_PAGEFILE_SEGMENT ||
|
||||||
Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)
|
Context.Segment->Characteristics & IMAGE_SECTION_CHAR_SHARED)
|
||||||
{
|
{
|
||||||
|
@ -1737,7 +1655,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysicalAddress);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Context.Private)
|
if (Context.Private)
|
||||||
|
@ -1770,7 +1688,7 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
ULONG Offset;
|
ULONG Offset;
|
||||||
PSECTION_OBJECT Section;
|
PSECTION_OBJECT Section;
|
||||||
PMM_SECTION_SEGMENT Segment;
|
PMM_SECTION_SEGMENT Segment;
|
||||||
PHYSICAL_ADDRESS PhysicalAddress;
|
PFN_TYPE Page;
|
||||||
SWAPENTRY SwapEntry;
|
SWAPENTRY SwapEntry;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
BOOLEAN Private;
|
BOOLEAN Private;
|
||||||
|
@ -1832,16 +1750,15 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0, Address);
|
AddressSpace->Process ? AddressSpace->Process->UniqueProcessId : 0, Address);
|
||||||
KEBUGCHECK(0);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
PhysicalAddress =
|
Page = MmGetPfnForProcess(AddressSpace->Process, Address);
|
||||||
MmGetPhysicalAddressForProcess(AddressSpace->Process, Address);
|
SwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||||
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for a private (COWed) page.
|
* Check for a private (COWed) page.
|
||||||
*/
|
*/
|
||||||
if (Segment->Characteristics & IMAGE_SECTION_CHAR_BSS ||
|
if (Segment->Characteristics & IMAGE_SECTION_CHAR_BSS ||
|
||||||
IS_SWAP_FROM_SSE(Entry) ||
|
IS_SWAP_FROM_SSE(Entry) ||
|
||||||
(LONGLONG)PAGE_FROM_SSE(Entry) != PhysicalAddress.QuadPart)
|
PFN_FROM_SSE(Entry) != Page)
|
||||||
{
|
{
|
||||||
Private = TRUE;
|
Private = TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1853,7 +1770,7 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Speculatively set all mappings of the page to clean.
|
* Speculatively set all mappings of the page to clean.
|
||||||
*/
|
*/
|
||||||
MmSetCleanAllRmaps(PhysicalAddress);
|
MmSetCleanAllRmaps(Page);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this page was direct mapped from the cache then the cache manager
|
* If this page was direct mapped from the cache then the cache manager
|
||||||
|
@ -1876,23 +1793,23 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
SwapEntry = MmAllocSwapPage();
|
SwapEntry = MmAllocSwapPage();
|
||||||
if (SwapEntry == 0)
|
if (SwapEntry == 0)
|
||||||
{
|
{
|
||||||
MmSetDirtyAllRmaps(PhysicalAddress);
|
MmSetDirtyAllRmaps(Page);
|
||||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
MmspCompleteAndReleasePageOp(PageOp);
|
MmspCompleteAndReleasePageOp(PageOp);
|
||||||
return(STATUS_PAGEFILE_QUOTA);
|
return(STATUS_PAGEFILE_QUOTA);
|
||||||
}
|
}
|
||||||
MmSetSavedSwapEntryPage(PhysicalAddress, SwapEntry);
|
MmSetSavedSwapEntryPage(Page, SwapEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write the page to the pagefile
|
* Write the page to the pagefile
|
||||||
*/
|
*/
|
||||||
Status = MmWriteToSwapPage(SwapEntry, &PhysicalAddress);
|
Status = MmWriteToSwapPage(SwapEntry, Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
|
DPRINT1("MM: Failed to write to swap page (Status was 0x%.8X)\n",
|
||||||
Status);
|
Status);
|
||||||
MmSetDirtyAllRmaps(PhysicalAddress);
|
MmSetDirtyAllRmaps(Page);
|
||||||
PageOp->Status = STATUS_UNSUCCESSFUL;
|
PageOp->Status = STATUS_UNSUCCESSFUL;
|
||||||
MmspCompleteAndReleasePageOp(PageOp);
|
MmspCompleteAndReleasePageOp(PageOp);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return(STATUS_UNSUCCESSFUL);
|
||||||
|
@ -1901,7 +1818,7 @@ MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
|
||||||
/*
|
/*
|
||||||
* Otherwise we have succeeded.
|
* Otherwise we have succeeded.
|
||||||
*/
|
*/
|
||||||
DPRINT("MM: Wrote section page 0x%.8X to swap!\n", PhysicalAddress);
|
DPRINT("MM: Wrote section page 0x%.8X to swap!\n", Page << PAGE_SHIFT);
|
||||||
PageOp->Status = STATUS_SUCCESS;
|
PageOp->Status = STATUS_SUCCESS;
|
||||||
MmspCompleteAndReleasePageOp(PageOp);
|
MmspCompleteAndReleasePageOp(PageOp);
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
|
@ -1945,17 +1862,16 @@ MmAlterViewAttributes(PMADDRESS_SPACE AddressSpace,
|
||||||
{
|
{
|
||||||
ULONG Offset;
|
ULONG Offset;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
LARGE_INTEGER PhysicalAddress;
|
PFN_TYPE Page;
|
||||||
|
|
||||||
Offset = (ULONG)Address - (ULONG)MemoryArea->BaseAddress;
|
Offset = (ULONG)Address - (ULONG)MemoryArea->BaseAddress;
|
||||||
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
|
Entry = MmGetPageEntrySectionSegment(Segment, Offset);
|
||||||
PhysicalAddress =
|
Page = MmGetPfnForProcess(AddressSpace->Process, Address);
|
||||||
MmGetPhysicalAddressForProcess(AddressSpace->Process, Address);
|
|
||||||
|
|
||||||
Protect = PAGE_READONLY;
|
Protect = PAGE_READONLY;
|
||||||
if ((Segment->Characteristics & IMAGE_SECTION_CHAR_BSS ||
|
if (Segment->Characteristics & IMAGE_SECTION_CHAR_BSS ||
|
||||||
IS_SWAP_FROM_SSE(Entry) ||
|
IS_SWAP_FROM_SSE(Entry) ||
|
||||||
(LONGLONG)PAGE_FROM_SSE(Entry) != PhysicalAddress.QuadPart))
|
PFN_FROM_SSE(Entry) != Page)
|
||||||
{
|
{
|
||||||
Protect = NewProtect;
|
Protect = NewProtect;
|
||||||
}
|
}
|
||||||
|
@ -2061,9 +1977,9 @@ MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
|
||||||
ULONG Offset;
|
ULONG Offset;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
ULONG SavedSwapEntry;
|
ULONG SavedSwapEntry;
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
|
|
||||||
Page.u.HighPart = 0;
|
Page = 0;
|
||||||
|
|
||||||
Length = PAGE_ROUND_UP(Segment->Length);
|
Length = PAGE_ROUND_UP(Segment->Length);
|
||||||
for (Offset = 0; Offset < Length; Offset += PAGE_SIZE)
|
for (Offset = 0; Offset < Length; Offset += PAGE_SIZE)
|
||||||
|
@ -2077,7 +1993,7 @@ MmpFreePageFileSegment(PMM_SECTION_SEGMENT Segment)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Page.u.LowPart = PAGE_FROM_SSE(Entry);
|
Page = PFN_FROM_SSE(Entry);
|
||||||
SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
|
SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||||
if (SavedSwapEntry != 0)
|
if (SavedSwapEntry != 0)
|
||||||
{
|
{
|
||||||
|
@ -3330,8 +3246,7 @@ NtMapViewOfSection(HANDLE SectionHandle,
|
||||||
|
|
||||||
VOID STATIC
|
VOID STATIC
|
||||||
MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry,
|
PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
|
||||||
BOOLEAN Dirty)
|
|
||||||
{
|
{
|
||||||
PMEMORY_AREA MArea;
|
PMEMORY_AREA MArea;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
|
@ -3382,7 +3297,7 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
*/
|
*/
|
||||||
if (Segment->Flags & MM_DATAFILE_SEGMENT)
|
if (Segment->Flags & MM_DATAFILE_SEGMENT)
|
||||||
{
|
{
|
||||||
if (PhysAddr.QuadPart == PAGE_FROM_SSE(Entry) && Dirty)
|
if (Page == PFN_FROM_SSE(Entry) && Dirty)
|
||||||
{
|
{
|
||||||
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
|
FileObject = MemoryArea->Data.SectionData.Section->FileObject;
|
||||||
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
|
||||||
|
@ -3403,10 +3318,10 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
}
|
}
|
||||||
MmFreeSwapPage(SwapEntry);
|
MmFreeSwapPage(SwapEntry);
|
||||||
}
|
}
|
||||||
else if (PhysAddr.QuadPart != 0)
|
else if (Page != 0)
|
||||||
{
|
{
|
||||||
if (IS_SWAP_FROM_SSE(Entry) ||
|
if (IS_SWAP_FROM_SSE(Entry) ||
|
||||||
PhysAddr.QuadPart != (PAGE_FROM_SSE(Entry)))
|
Page != PFN_FROM_SSE(Entry))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Sanity check
|
* Sanity check
|
||||||
|
@ -3419,18 +3334,18 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
/*
|
/*
|
||||||
* Just dereference private pages
|
* Just dereference private pages
|
||||||
*/
|
*/
|
||||||
SavedSwapEntry = MmGetSavedSwapEntryPage(PhysAddr);
|
SavedSwapEntry = MmGetSavedSwapEntryPage(Page);
|
||||||
if (SavedSwapEntry != 0)
|
if (SavedSwapEntry != 0)
|
||||||
{
|
{
|
||||||
MmFreeSwapPage(SavedSwapEntry);
|
MmFreeSwapPage(SavedSwapEntry);
|
||||||
MmSetSavedSwapEntryPage(PhysAddr, 0);
|
MmSetSavedSwapEntryPage(Page, 0);
|
||||||
}
|
}
|
||||||
MmDeleteRmap(PhysAddr, MArea->Process, Address);
|
MmDeleteRmap(Page, MArea->Process, Address);
|
||||||
MmReleasePageMemoryConsumer(MC_USER, PhysAddr);
|
MmReleasePageMemoryConsumer(MC_USER, Page);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MmDeleteRmap(PhysAddr, MArea->Process, Address);
|
MmDeleteRmap(Page, MArea->Process, Address);
|
||||||
MmUnsharePageEntrySectionSegment(Section, Segment, Offset, Dirty, FALSE);
|
MmUnsharePageEntrySectionSegment(Section, Segment, Offset, Dirty, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3778,7 +3693,7 @@ MmAllocateSection (IN ULONG Length)
|
||||||
DPRINT("Result %p\n",Result);
|
DPRINT("Result %p\n",Result);
|
||||||
for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)
|
for (i = 0; i < PAGE_ROUND_UP(Length) / PAGE_SIZE; i++)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS Page;
|
PFN_TYPE Page;
|
||||||
|
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -3789,8 +3704,8 @@ MmAllocateSection (IN ULONG Length)
|
||||||
Status = MmCreateVirtualMapping (NULL,
|
Status = MmCreateVirtualMapping (NULL,
|
||||||
((char*)Result + (i * PAGE_SIZE)),
|
((char*)Result + (i * PAGE_SIZE)),
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
Page,
|
&Page,
|
||||||
TRUE);
|
1);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DbgPrint("Unable to create virtual mapping\n");
|
DbgPrint("Unable to create virtual mapping\n");
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: slab.c,v 1.12 2004/04/10 22:35:26 gdalsnes Exp $
|
/* $Id: slab.c,v 1.13 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top directory
|
* COPYRIGHT: See COPYING in the top directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -107,23 +107,23 @@ PSLAB_CACHE_PAGE
|
||||||
ExGrowSlabCache(PSLAB_CACHE Slab)
|
ExGrowSlabCache(PSLAB_CACHE Slab)
|
||||||
{
|
{
|
||||||
PSLAB_CACHE_PAGE SlabPage;
|
PSLAB_CACHE_PAGE SlabPage;
|
||||||
PHYSICAL_ADDRESS PhysicalPage;
|
PFN_TYPE Pfn;
|
||||||
PVOID Page;
|
PVOID Page;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
PSLAB_CACHE_BUFCTL BufCtl;
|
PSLAB_CACHE_BUFCTL BufCtl;
|
||||||
PVOID Object;
|
PVOID Object;
|
||||||
|
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &PhysicalPage);
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Pfn);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page = ExAllocatePageWithPhysPage(PhysicalPage);
|
Page = ExAllocatePageWithPhysPage(Pfn);
|
||||||
if (Page == NULL)
|
if (Page == NULL)
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage);
|
MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ ExDestroySlabCache(PSLAB_CACHE Slab)
|
||||||
while (current_entry != &Slab->PageListHead)
|
while (current_entry != &Slab->PageListHead)
|
||||||
{
|
{
|
||||||
PVOID Base;
|
PVOID Base;
|
||||||
PHYSICAL_ADDRESS PhysicalPage;
|
PFN_TYPE Page;
|
||||||
|
|
||||||
current = CONTAINING_RECORD(current_entry,
|
current = CONTAINING_RECORD(current_entry,
|
||||||
SLAB_CACHE_PAGE,
|
SLAB_CACHE_PAGE,
|
||||||
|
@ -318,9 +318,9 @@ ExDestroySlabCache(PSLAB_CACHE Slab)
|
||||||
Slab->Destructor(Object, Slab->BaseSize);
|
Slab->Destructor(Object, Slab->BaseSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PhysicalPage = MmGetPhysicalAddressForProcess(NULL, Base);
|
Page = MmGetPfnForProcess(NULL, Base);
|
||||||
ExUnmapPage(Base);
|
ExUnmapPage(Base);
|
||||||
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage);
|
MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
|
||||||
}
|
}
|
||||||
ExFreePool(Slab);
|
ExFreePool(Slab);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: wset.c,v 1.19 2004/07/17 03:03:52 ion Exp $
|
/* $Id: wset.c,v 1.20 2004/08/01 07:24:58 hbirr Exp $
|
||||||
*
|
*
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* FILE: ntoskrnl/mm/wset.c
|
* FILE: ntoskrnl/mm/wset.c
|
||||||
|
@ -41,18 +41,18 @@
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages)
|
MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS CurrentPhysicalAddress;
|
PFN_TYPE CurrentPage;
|
||||||
PHYSICAL_ADDRESS NextPhysicalAddress;
|
PFN_TYPE NextPage;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
(*NrFreedPages) = 0;
|
(*NrFreedPages) = 0;
|
||||||
|
|
||||||
CurrentPhysicalAddress = MmGetLRUFirstUserPage();
|
CurrentPage = MmGetLRUFirstUserPage();
|
||||||
while (CurrentPhysicalAddress.QuadPart != 0 && Target > 0)
|
while (CurrentPage != 0 && Target > 0)
|
||||||
{
|
{
|
||||||
NextPhysicalAddress = MmGetLRUNextUserPage(CurrentPhysicalAddress);
|
NextPage = MmGetLRUNextUserPage(CurrentPage);
|
||||||
|
|
||||||
Status = MmPageOutPhysicalAddress(CurrentPhysicalAddress);
|
Status = MmPageOutPhysicalAddress(CurrentPage);
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("Succeeded\n");
|
DPRINT("Succeeded\n");
|
||||||
|
@ -61,10 +61,10 @@ MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages)
|
||||||
}
|
}
|
||||||
else if (Status == STATUS_PAGEFILE_QUOTA)
|
else if (Status == STATUS_PAGEFILE_QUOTA)
|
||||||
{
|
{
|
||||||
MmSetLRULastPage(CurrentPhysicalAddress);
|
MmSetLRULastPage(CurrentPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentPhysicalAddress = NextPhysicalAddress;
|
CurrentPage = NextPage;
|
||||||
}
|
}
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: w32call.c,v 1.12 2004/02/29 11:51:49 hbirr Exp $
|
/* $Id: w32call.c,v 1.13 2004/08/01 07:24:59 hbirr Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -32,6 +32,14 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
void * alloca(size_t size);
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
void* _alloca(size_t size);
|
||||||
|
#else
|
||||||
|
#error Unknown compiler for alloca intrinsic stack allocation "function"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TYPES *******************************************************************/
|
/* TYPES *******************************************************************/
|
||||||
|
|
||||||
typedef struct _NTW32CALL_SAVED_STATE
|
typedef struct _NTW32CALL_SAVED_STATE
|
||||||
|
@ -139,13 +147,13 @@ NtCallbackReturn (PVOID Result,
|
||||||
|
|
||||||
VOID STATIC
|
VOID STATIC
|
||||||
PsFreeCallbackStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
PsFreeCallbackStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
|
||||||
PHYSICAL_ADDRESS PhysAddr, SWAPENTRY SwapEntry,
|
PFN_TYPE Page, SWAPENTRY SwapEntry,
|
||||||
BOOLEAN Dirty)
|
BOOLEAN Dirty)
|
||||||
{
|
{
|
||||||
assert(SwapEntry == 0);
|
assert(SwapEntry == 0);
|
||||||
if (PhysAddr.QuadPart != 0)
|
if (Page != 0)
|
||||||
{
|
{
|
||||||
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysAddr);
|
MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,8 +191,10 @@ PsAllocateCallbackStack(ULONG StackSize)
|
||||||
PVOID KernelStack = NULL;
|
PVOID KernelStack = NULL;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PMEMORY_AREA StackArea;
|
PMEMORY_AREA StackArea;
|
||||||
ULONG i;
|
ULONG i, j;
|
||||||
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
PHYSICAL_ADDRESS BoundaryAddressMultiple;
|
||||||
|
PPFN_TYPE Pages = alloca(sizeof(PFN_TYPE) * (StackSize /PAGE_SIZE));
|
||||||
|
|
||||||
|
|
||||||
BoundaryAddressMultiple.QuadPart = 0;
|
BoundaryAddressMultiple.QuadPart = 0;
|
||||||
StackSize = PAGE_ROUND_UP(StackSize);
|
StackSize = PAGE_ROUND_UP(StackSize);
|
||||||
|
@ -207,17 +217,28 @@ PsAllocateCallbackStack(ULONG StackSize)
|
||||||
}
|
}
|
||||||
for (i = 0; i < (StackSize / PAGE_SIZE); i++)
|
for (i = 0; i < (StackSize / PAGE_SIZE); i++)
|
||||||
{
|
{
|
||||||
PHYSICAL_ADDRESS Page;
|
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Pages[i]);
|
||||||
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
MmReleasePageMemoryConsumer(MC_NPPOOL, Pages[j]);
|
||||||
|
}
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
Status = MmCreateVirtualMapping(NULL,
|
}
|
||||||
(char*)KernelStack + (i * PAGE_SIZE),
|
Status = MmCreateVirtualMapping(NULL,
|
||||||
PAGE_EXECUTE_READWRITE,
|
KernelStack,
|
||||||
Page,
|
PAGE_READWRITE,
|
||||||
TRUE);
|
Pages,
|
||||||
|
StackSize / PAGE_SIZE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
for (i = 0; i < (StackSize / PAGE_SIZE); i++)
|
||||||
|
{
|
||||||
|
MmReleasePageMemoryConsumer(MC_NPPOOL, Pages[i]);
|
||||||
|
}
|
||||||
|
return(NULL);
|
||||||
}
|
}
|
||||||
return(KernelStack);
|
return(KernelStack);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue