- 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:
Hartmut Birr 2004-08-01 07:24:59 +00:00
parent 5f1aa6ff61
commit fd411381da
26 changed files with 1029 additions and 1205 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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,34 +271,410 @@ 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,
PMEMORY_AREA MemoryArea,
PVOID BaseAddress,
ULONG Length,
ULONG Protect,
PULONG OldProtect);
NTSTATUS NTSTATUS
MmProtectSectionView(PMADDRESS_SPACE AddressSpace, MmProtectSectionView(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MemoryArea, PMEMORY_AREA MemoryArea,
@ -635,40 +682,63 @@ MmProtectSectionView(PMADDRESS_SPACE AddressSpace,
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

View file

@ -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));
} }

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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)
{ {

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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((PHYSICAL_ADDRESS)((LONGLONG)start * PAGE_SIZE)); return start;
#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");

View file

@ -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");

View file

@ -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");

View file

@ -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);
} }
} }
} }

View file

@ -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,17 +444,9 @@ 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;

View file

@ -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:

View file

@ -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);
} }
} }

View file

@ -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

View file

@ -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);
} }
} }

View file

@ -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;
PVOID start = (PVOID)PAGE_ROUND_UP((ULONG)((char*)blk + BLOCK_HDR_SIZE)); StartIndex = (ULONG)((char*)(PVOID)PAGE_ROUND_UP((ULONG)((char*)blk + BLOCK_HDR_SIZE)) - (char*)MiNonPagedPoolStart) / PAGE_SIZE;
end = (PVOID)PAGE_ROUND_UP(end); EndIndex = (ULONG)((char*)PAGE_ROUND_UP(end) - (char*)MiNonPagedPoolStart) / PAGE_SIZE;
index = (ULONG)((char*)start - (char*)MiNonPagedPoolStart) / PAGE_SIZE;
while (start < end)
for (i = StartIndex; i < EndIndex; i++)
{ {
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");

View file

@ -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,

View file

@ -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
{ {

View file

@ -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");

View file

@ -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);
} }

View file

@ -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);
} }

View file

@ -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);
} }