Use ULONG_PTR instead of ULONG when doing pointer arithmetics.

Use ULONG_PTR for physical adresses and PVOID for virtual addresses.
Added several consistency checks in the memory memory manager.

svn path=/trunk/; revision=2946
This commit is contained in:
Casper Hornstrup 2002-05-13 18:10:41 +00:00
parent 5e4527aff7
commit c804ca06be
39 changed files with 3165 additions and 1119 deletions

View file

@ -1,4 +1,4 @@
/* $Id: section.c,v 1.13 2001/02/17 17:42:46 ekohl Exp $ /* $Id: section.c,v 1.14 2002/05/13 18:10:38 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -157,6 +157,8 @@ MapViewOfFileEx(HANDLE hFileMappingObject,
BaseAddress = lpBaseAddress; BaseAddress = lpBaseAddress;
} }
ViewSize = (ULONG) dwNumberOfBytesToMap;
Status = ZwMapViewOfSection(hFileMappingObject, Status = ZwMapViewOfSection(hFileMappingObject,
NtCurrentProcess(), NtCurrentProcess(),
&BaseAddress, &BaseAddress,

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.38 2002/05/05 14:57:42 chorns Exp $ /* $Id: view.c,v 1.39 2002/05/13 18:10:38 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -284,7 +284,7 @@ CcRosCreateCacheSegment(PBCB Bcb,
ExReleaseFastMutex(&ViewLock); ExReleaseFastMutex(&ViewLock);
for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++) for (i = 0; i < (Bcb->CacheSegmentSize / PAGESIZE); i++)
{ {
PVOID Page; ULONG_PTR Page;
Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Page); Status = MmRequestPageMemoryConsumer(MC_CACHE, TRUE, &Page);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -295,7 +295,7 @@ CcRosCreateCacheSegment(PBCB Bcb,
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
current->BaseAddress + (i * PAGESIZE), current->BaseAddress + (i * PAGESIZE),
PAGE_READWRITE, PAGE_READWRITE,
(ULONG)Page, Page,
TRUE); TRUE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -452,14 +452,22 @@ CcRosRequestCacheSegment(PBCB Bcb,
CacheSeg)); CacheSeg));
} }
STATIC VOID VOID
CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, CcFreeCachePage(IN BOOLEAN Before,
ULONG PhysAddr, SWAPENTRY SwapEntry, BOOLEAN Dirty) IN PVOID Context,
IN PMEMORY_AREA MemoryArea,
IN PVOID Address,
IN ULONG_PTR PhysicalAddress,
IN SWAPENTRY SwapEntry,
IN BOOLEAN Dirty)
{ {
assert(SwapEntry == 0); if (!Before)
if (PhysAddr != 0)
{ {
MmReleasePageMemoryConsumer(MC_CACHE, (PVOID)PhysAddr); assert(SwapEntry == 0);
if (PhysicalAddress != 0)
{
MmReleasePageMemoryConsumer(MC_CACHE, PhysicalAddress);
}
} }
} }

View file

@ -206,7 +206,7 @@ CmiAddKeyToList(PKEY_OBJECT ParentKey,
if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys) if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys)
{ {
PKEY_OBJECT *tmpSubKeys = ExAllocatePool(PagedPool, PKEY_OBJECT *tmpSubKeys = ExAllocatePool(NonPagedPool,
(ParentKey->NumberOfSubKeys + 1) * sizeof(DWORD)); (ParentKey->NumberOfSubKeys + 1) * sizeof(DWORD));
if (ParentKey->NumberOfSubKeys > 0) if (ParentKey->NumberOfSubKeys > 0)

View file

@ -1,4 +1,4 @@
/* $Id: work.c,v 1.11 2001/08/26 17:26:23 ekohl Exp $ /* $Id: work.c,v 1.12 2002/05/13 18:10:39 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -99,8 +99,8 @@ ExWorkerThreadEntryPoint(PVOID context)
static VOID ExInitializeWorkQueue(PWORK_QUEUE WorkQueue, static VOID ExInitializeWorkQueue(PWORK_QUEUE WorkQueue,
KPRIORITY Priority) KPRIORITY Priority)
{ {
NTSTATUS Status;
ULONG i; ULONG i;
PETHREAD Thread;
InitializeListHead(&WorkQueue->Head); InitializeListHead(&WorkQueue->Head);
KeInitializeSpinLock(&WorkQueue->Lock); KeInitializeSpinLock(&WorkQueue->Lock);
@ -116,15 +116,13 @@ static VOID ExInitializeWorkQueue(PWORK_QUEUE WorkQueue,
NULL, NULL,
ExWorkerThreadEntryPoint, ExWorkerThreadEntryPoint,
WorkQueue); WorkQueue);
ObReferenceObjectByHandle(WorkQueue->Thread[i], Status = PiSetPriorityThread(WorkQueue->Thread[i], Priority);
THREAD_ALL_ACCESS,
PsThreadType, if (!NT_SUCCESS(Status))
KernelMode, {
(PVOID*)&Thread, DPRINT1("PiSetThreadPriority() failed with status 0x%.08x\n", Status);
NULL); KeBugCheck(0);
KeSetPriorityThread(&Thread->Tcb, }
Priority);
ObDereferenceObject(Thread);
} }
} }

View file

@ -15,5 +15,4 @@
#define InternalNotificationTimer (InternalBaseType + 10) #define InternalNotificationTimer (InternalBaseType + 10)
#define InternalSynchronizationTimer (InternalBaseType + 11) #define InternalSynchronizationTimer (InternalBaseType + 11)
#define InternalQueueType (InternalBaseType + 12) #define InternalQueueType (InternalBaseType + 12)
#define InternalTypeMaximum InternalQueueType

View file

@ -222,6 +222,15 @@ KeBugCheckWithTf(ULONG BugCheckCode,
VOID VOID
KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG ExceptionNr, ULONG cr2); KiDumpTrapFrame(PKTRAP_FRAME Tf, ULONG ExceptionNr, ULONG cr2);
VOID
KiValidateDispatcherObject(IN PDISPATCHER_HEADER Object);
#ifdef DBG
#define VALIDATE_DISPATCHER_OBJECT(Object) KiValidateDispatcherObject(Object);
#else /* !DBG */
#define VALIDATE_DISPATCHER_OBJECT(Object)
#endif /* DBG */
#endif /* not __ASM__ */ #endif /* not __ASM__ */
#define MAXIMUM_PROCESSORS 32 #define MAXIMUM_PROCESSORS 32

View file

@ -5,6 +5,7 @@
#ifndef __INCLUDE_INTERNAL_MM_H #ifndef __INCLUDE_INTERNAL_MM_H
#define __INCLUDE_INTERNAL_MM_H #define __INCLUDE_INTERNAL_MM_H
#include <roscfg.h>
#include <internal/ntoskrnl.h> #include <internal/ntoskrnl.h>
#include <internal/arch/mm.h> #include <internal/arch/mm.h>
@ -14,7 +15,8 @@ struct _EPROCESS;
struct _MM_RMAP_ENTRY; struct _MM_RMAP_ENTRY;
struct _MM_PAGEOP; struct _MM_PAGEOP;
typedef ULONG SWAPENTRY; typedef ULONG SWAPENTRY, *PSWAPENTRY;
#define MEMORY_AREA_INVALID (0) #define MEMORY_AREA_INVALID (0)
#define MEMORY_AREA_SECTION_VIEW_COMMIT (1) #define MEMORY_AREA_SECTION_VIEW_COMMIT (1)
@ -58,7 +60,7 @@ typedef ULONG SWAPENTRY;
typedef struct typedef struct
{ {
ULONG Entry[NR_SECTION_PAGE_ENTRIES]; ULONG_PTR Entry[NR_SECTION_PAGE_ENTRIES];
} SECTION_PAGE_TABLE, *PSECTION_PAGE_TABLE; } SECTION_PAGE_TABLE, *PSECTION_PAGE_TABLE;
typedef struct typedef struct
@ -117,14 +119,19 @@ typedef struct
BOOLEAN Executable; BOOLEAN Executable;
} SECTION_OBJECT, *PSECTION_OBJECT; } SECTION_OBJECT, *PSECTION_OBJECT;
typedef struct
typedef struct _MEMORY_AREA
{ {
#ifdef DBG
ULONG Magic;
#endif /* DBG */
ULONG Type; ULONG Type;
PVOID BaseAddress; PVOID BaseAddress;
ULONG Length; ULONG Length;
ULONG Attributes; ULONG Attributes;
LIST_ENTRY Entry; LIST_ENTRY Entry;
ULONG LockCount; ULONG LockCount;
ULONG ReferenceCount;
struct _EPROCESS* Process; struct _EPROCESS* Process;
union union
{ {
@ -143,46 +150,287 @@ typedef struct
} Data; } Data;
} MEMORY_AREA, *PMEMORY_AREA; } MEMORY_AREA, *PMEMORY_AREA;
#define MM_PAGEOP_PAGEIN (1)
#define MM_PAGEOP_PAGEOUT (2)
#define MM_PAGEOP_PAGESYNCH (3)
#define MM_PAGEOP_ACCESSFAULT (4)
#define MM_PAGEOP_MINIMUM MM_PAGEOP_PAGEIN
#define MM_PAGEOP_MAXIMUM MM_PAGEOP_ACCESSFAULT
typedef struct _MM_PAGEOP
{
#ifdef DBG
/* Magic ID */
ULONG Magic;
#endif /* DBG */
/* Type of operation. */
ULONG OpType;
/* Number of threads interested in this operation. */
ULONG ReferenceCount;
/* Event that will be set when the operation is completed. */
KEVENT CompletionEvent;
/* Status of the operation once it is completed. */
NTSTATUS Status;
/* TRUE if the operation was abandoned. */
BOOLEAN Abandoned;
/* The memory area to be affected by the operation. */
PMEMORY_AREA MArea;
ULONG Hash;
struct _MM_PAGEOP* Next;
struct _ETHREAD* Thread;
/*
* These fields are used to identify the operation if it is against a
* virtual memory area.
*/
ULONG Pid;
PVOID Address;
/*
* These fields are used to identify the operation if it is against a
* section mapping.
*/
PMM_SECTION_SEGMENT Segment;
ULONG Offset;
} MM_PAGEOP, *PMM_PAGEOP;
#define PAGE_STATE_VALID (0)
#define PAGE_STATE_PROTOTYPE (1)
#define PAGE_STATE_DEMAND_ZERO (2)
#define PAGE_STATE_TRANSITION (3)
#define MM_PTYPE(x) (x)
#define PAGE_LIST_FREE_ZEROED (0)
#define PAGE_LIST_FREE_UNZEROED (1)
#define PAGE_LIST_BIOS (2)
#define PAGE_LIST_STANDBY (3)
#define PAGE_LIST_MODIFIED (4)
#define PAGE_LIST_MODIFIED_NO_WRITE (5)
#define PAGE_LIST_MPW (6)
/* PHYSICAL_PAGE.Flags */
#define MM_PHYSICAL_PAGE_FREE (0x1)
#define MM_PHYSICAL_PAGE_USED (0x2)
#define MM_PHYSICAL_PAGE_BIOS (0x3)
#define MM_PHYSICAL_PAGE_STANDBY (0x4)
#define MM_PHYSICAL_PAGE_MODIFIED (0x5)
#define MM_PHYSICAL_PAGE_MPW (0x6)
typedef VOID (*PRMAP_DELETE_CALLBACK)(IN PVOID Context,
IN PEPROCESS Process,
IN PVOID Address);
/* FIXME: Unionize this structure */
typedef struct _PHYSICAL_PAGE
{
ULONG Flags;
LIST_ENTRY ListEntry;
ULONG ReferenceCount;
SWAPENTRY SavedSwapEntry;
ULONG LockCount;
ULONG MapCount;
struct _MM_RMAP_ENTRY* RmapListHead;
PRMAP_DELETE_CALLBACK RmapDelete;
PVOID RmapDeleteContext;
PMM_PAGEOP PageOp;
} PHYSICAL_PAGE, *PPHYSICAL_PAGE;
extern PPHYSICAL_PAGE MmPageArray;
#define MiPageFromDescriptor(pp)((((ULONG_PTR)(pp) - (ULONG_PTR) MmPageArray) / sizeof(PHYSICAL_PAGE)) * PAGESIZE)
typedef struct _MADDRESS_SPACE typedef struct _MADDRESS_SPACE
{ {
#ifdef DBG
ULONG Magic;
#endif /* DBG */
LIST_ENTRY MAreaListHead; LIST_ENTRY MAreaListHead;
KMUTEX Lock; KMUTEX Lock;
ULONG ReferenceCount;
ULONG LowestAddress; ULONG LowestAddress;
struct _EPROCESS* Process; struct _EPROCESS* Process;
PUSHORT PageTableRefCountTable; PUSHORT PageTableRefCountTable;
ULONG PageTableRefCountTableSize; ULONG PageTableRefCountTableSize;
} MADDRESS_SPACE, *PMADDRESS_SPACE; } MADDRESS_SPACE, *PMADDRESS_SPACE;
#define MmIsCopyOnWriteMemoryArea(MemoryArea) \
( \
((MemoryArea)->Data.SectionData.Segment->WriteCopy \
|| (MemoryArea)->Data.SectionData.WriteCopyView) \
&& ((MemoryArea)->Attributes == PAGE_READWRITE \
|| (MemoryArea)->Attributes == PAGE_EXECUTE_READWRITE) \
)
extern ULONG MiMaximumModifiedPageListSize;
extern ULONG MiModifiedPageListSize;
extern ULONG MiMaximumStandbyPageListSize;
extern ULONG MiStandbyPageListSize;
/* FUNCTIONS */ /* FUNCTIONS */
VOID MmLockAddressSpace(PMADDRESS_SPACE AddressSpace); #ifdef DBG
VOID MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace);
VOID MmInitializeKernelAddressSpace(VOID); VOID
PMADDRESS_SPACE MmGetCurrentAddressSpace(VOID); DbgMmDumpProtection(IN ULONG Value);
PMADDRESS_SPACE MmGetKernelAddressSpace(VOID);
NTSTATUS MmInitializeAddressSpace(struct _EPROCESS* Process, VOID
PMADDRESS_SPACE AddressSpace); MiDumpPTE(IN ULONG Value);
NTSTATUS MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace);
PVOID STDCALL MmAllocateSection (IN ULONG Length); VOID
NTSTATUS MmCreateMemoryArea(struct _EPROCESS* Process, MiDumpProcessPTE(IN PEPROCESS Process,
PMADDRESS_SPACE AddressSpace, IN PVOID Address);
ULONG Type,
PVOID* BaseAddress, #endif /* DBG */
ULONG Length,
ULONG Attributes, VOID
MEMORY_AREA** Result, MiAcquirePageListLock(IN ULONG PageList,
BOOL FixedAddress); OUT PLIST_ENTRY * ListHead);
MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
PVOID Address); VOID
NTSTATUS MmInitMemoryAreas(VOID); MiReleasePageListLock();
VOID ExInitNonPagedPool(ULONG BaseAddress);
NTSTATUS MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace, VOID
PVOID BaseAddress, MiReclaimPage(IN ULONG_PTR PhysicalAddress,
ULONG Length, IN BOOLEAN Dirty);
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea,
PVOID Address, ULONG PhysAddr, SWAPENTRY SwapEntry, VOID
BOOLEAN Dirty), MmInitMpwThreads();
PVOID FreePageContext);
VOID
MiShutdownMpwThreads();
VOID
MiSignalModifiedPageWriter();
VOID
MiSignalMappedPageWriter();
VOID
MmInitializeBalanceSetManager();
ULONG
MiGetLockCountPage(IN ULONG_PTR PhysicalAddress);
VOID
MiDisableAllRmaps(IN ULONG_PTR PhysicalAddress,
IN PBOOLEAN Modified);
VOID
MiEnableAllRmaps(IN ULONG_PTR PhysicalAddress,
IN BOOLEAN Modified);
VOID
MiGetDirtyAllRmaps(IN ULONG_PTR PhysicalAddress,
IN PBOOLEAN Dirty);
VOID
MiGetPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
IN ULONG PageState,
OUT PBOOLEAN Result);
VOID
MiClearPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
IN ULONG PageState);
VOID
MiSetPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
IN ULONG PageState);
VOID
MiSetDirtyAllRmaps(IN ULONG_PTR PhysicalAddress,
IN BOOLEAN Dirty);
BOOLEAN
MiPageState(IN PEPROCESS Process,
IN PVOID Address,
IN ULONG PageState);
VOID
MiClearPageState(IN PEPROCESS Process,
IN PVOID Address,
IN ULONG PageState);
VOID
MiSetPageState(IN PEPROCESS Process,
IN PVOID Address,
IN ULONG PageState);
VOID
MmInitializeKernelAddressSpace(VOID);
PMADDRESS_SPACE
MmGetCurrentAddressSpace();
PMADDRESS_SPACE
MmGetKernelAddressSpace();
NTSTATUS
MmInitializeAddressSpace(IN PEPROCESS Process,
IN PMADDRESS_SPACE AddressSpace);
NTSTATUS
MmDestroyAddressSpace(IN PMADDRESS_SPACE AddressSpace);
VOID
MmReferenceAddressSpace(IN PMADDRESS_SPACE AddressSpace);
VOID
MmDereferenceAddressSpace(IN PMADDRESS_SPACE AddressSpace);
VOID
MmApplyMemoryAreaProtection(IN PMEMORY_AREA MemoryArea);
NTSTATUS
MmFlushSection(IN PSECTION_OBJECT SectionObject,
IN PLARGE_INTEGER FileOffset OPTIONAL,
IN ULONG Length,
OUT PIO_STATUS_BLOCK IoStatus OPTIONAL);
PVOID STDCALL
MmAllocateSection(IN ULONG Length);
NTSTATUS
MmCreateMemoryArea(IN PEPROCESS Process,
IN PMADDRESS_SPACE AddressSpace,
IN ULONG Type,
IN OUT PVOID* BaseAddress,
IN ULONG Length,
IN ULONG Attributes,
OUT PMEMORY_AREA* Result,
IN BOOLEAN FixedAddress);
PMEMORY_AREA
MmOpenMemoryAreaByAddress(IN PMADDRESS_SPACE AddressSpace,
IN PVOID Address);
VOID
MmCloseMemoryArea(IN PMEMORY_AREA MemoryArea);
NTSTATUS
MmInitMemoryAreas();
VOID
ExInitNonPagedPool(IN PVOID BaseAddress);
typedef VOID (*PFREE_MEMORY_AREA_PAGE_CALLBACK)(IN BOOLEAN Before,
IN PVOID Context,
IN PMEMORY_AREA MemoryArea,
IN PVOID Address,
IN ULONG_PTR PhysicalAddress,
IN SWAPENTRY SwapEntry,
IN BOOLEAN Dirty);
NTSTATUS
MmFreeMemoryArea(IN PMADDRESS_SPACE AddressSpace,
IN PVOID BaseAddress,
IN ULONG Length,
IN PFREE_MEMORY_AREA_PAGE_CALLBACK FreePage,
IN PVOID FreePageContext);
VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead); VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead);
NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea); NTSTATUS MmLockMemoryArea(MEMORY_AREA* MemoryArea);
NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea); NTSTATUS MmUnlockMemoryArea(MEMORY_AREA* MemoryArea);
@ -204,10 +452,12 @@ PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
PADDRESS_RANGE BIOSMemoryMap, PADDRESS_RANGE BIOSMemoryMap,
ULONG AddressRangeCount); ULONG AddressRangeCount);
PVOID ULONG_PTR
MmAllocPage(ULONG Consumer, SWAPENTRY SavedSwapEntry); MmAllocPage(IN ULONG Consumer,
VOID MmDereferencePage(PVOID PhysicalAddress); IN SWAPENTRY SavedSwapEntry);
VOID MmReferencePage(PVOID PhysicalAddress);
VOID MmDereferencePage(IN ULONG_PTR PhysicalAddress);
VOID MmReferencePage(IN ULONG_PTR PhysicalAddress);
VOID MmDeletePageTable(struct _EPROCESS* Process, VOID MmDeletePageTable(struct _EPROCESS* Process,
PVOID Address); PVOID Address);
NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src, NTSTATUS MmCopyMmInfo(struct _EPROCESS* Src,
@ -217,21 +467,33 @@ NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
VOID VOID
MmDeleteVirtualMapping(struct _EPROCESS* Process, MmDeleteVirtualMapping(struct _EPROCESS* Process,
PVOID Address, PVOID Address,
BOOL FreePage, BOOLEAN FreePage,
BOOL* WasDirty, PBOOLEAN WasDirty,
ULONG* PhysicalPage); PULONG PhysicalPage);
#define MM_PAGE_CLEAN (0) #define MM_PAGE_CLEAN (0)
#define MM_PAGE_DIRTY (1) #define MM_PAGE_DIRTY (1)
VOID MmBuildMdlFromPages(PMDL Mdl, PULONG Pages); VOID
PVOID MmGetMdlPageAddress(PMDL Mdl, PVOID Offset); MmBuildMdlFromPages(IN PMDL Mdl,
VOID MiShutdownMemoryManager(VOID); IN PULONG_PTR Pages);
ULONG MmGetPhysicalAddressForProcess(struct _EPROCESS* Process,
PVOID Address); PVOID
MmGetMdlPageAddress(IN PMDL Mdl,
IN PVOID Offset);
VOID
MiShutdownMemoryManager(VOID);
ULONG
MmGetPhysicalAddressForProcess(IN struct _EPROCESS* Process,
IN PVOID Address);
NTSTATUS STDCALL NTSTATUS STDCALL
MmUnmapViewOfSection(struct _EPROCESS* Process, PVOID BaseAddress); MmUnmapViewOfSection(struct _EPROCESS* Process, PVOID BaseAddress);
VOID MmInitPagingFile(VOID);
VOID
MmInitPagingFile(VOID);
/* FIXME: it should be in ddk/mmfuncs.h */ /* FIXME: it should be in ddk/mmfuncs.h */
NTSTATUS NTSTATUS
@ -276,13 +538,14 @@ VOID MmClearWaitPage(PVOID Page);
VOID MmSetWaitPage(PVOID Page); VOID MmSetWaitPage(PVOID Page);
BOOLEAN MmIsPageDirty(struct _EPROCESS* Process, PVOID Address); BOOLEAN MmIsPageDirty(struct _EPROCESS* Process, PVOID Address);
BOOLEAN MmIsPageTablePresent(PVOID PAddress); BOOLEAN MmIsPageTablePresent(PVOID PAddress);
NTSTATUS NTSTATUS
MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace, MmFlushVirtualMemory(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MemoryArea, PMEMORY_AREA MemoryArea,
PVOID Address, PVOID Address,
struct _MM_PAGEOP* PageOp); struct _MM_PAGEOP* PageOp);
NTSTATUS NTSTATUS
MmPageOutSectionView(PMADDRESS_SPACE AddressSpace, MmFlushSectionView(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MemoryArea, PMEMORY_AREA MemoryArea,
PVOID Address, PVOID Address,
struct _MM_PAGEOP* PageOp); struct _MM_PAGEOP* PageOp);
@ -290,14 +553,44 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
PVOID Address, PVOID Address,
ULONG Length); ULONG Length);
VOID ExUnmapPage(PVOID Addr); VOID
PVOID ExAllocatePage(VOID); ExUnmapPage(IN PVOID Addr);
VOID MmInitPagingFile(VOID); PVOID
BOOLEAN MmReserveSwapPages(ULONG Nr); ExAllocatePage(VOID);
VOID MmDereserveSwapPages(ULONG Nr);
SWAPENTRY MmAllocSwapPage(VOID); VOID
VOID MmFreeSwapPage(SWAPENTRY Entry); MmInitPagingFile(VOID);
BOOLEAN
MmReserveSwapPages(IN ULONG Nr);
VOID
MmDereserveSwapPages(IN ULONG Nr);
SWAPENTRY
MmAllocSwapPage(VOID);
VOID
MmFreeSwapPage(IN SWAPENTRY Entry);
VOID
MiValidateSwapEntry(IN SWAPENTRY Entry);
VOID
MiValidatePageOp(IN PMM_PAGEOP PageOp);
VOID
MiValidatePhysicalAddress(IN ULONG_PTR PhysicalAddress);
VOID
MiValidateAddressSpace(IN PMADDRESS_SPACE AddressSpace);
VOID
MiValidateMemoryArea(IN PMEMORY_AREA MemoryArea);
VOID
MiValidateRmapList(struct _MM_RMAP_ENTRY* RmapList);
VOID MmInit1(ULONG FirstKernelPhysAddress, VOID MmInit1(ULONG FirstKernelPhysAddress,
ULONG LastKernelPhysAddress, ULONG LastKernelPhysAddress,
@ -327,107 +620,197 @@ typedef struct
extern MM_STATS MmStats; extern MM_STATS MmStats;
extern BOOLEAN MiInitialized;
#ifdef DBG
#define VALIDATE_PHYSICAL_ADDRESS(PhysicalAddress) MiValidatePhysicalAddress((ULONG_PTR)PhysicalAddress)
#define VALIDATE_SWAP_ENTRY(Entry) MiValidateSwapEntry(Entry)
#define VALIDATE_PAGEOP(PageOp) MiValidatePageOp(PageOp)
#define VALIDATE_ADDRESS_SPACE(AddressSpace) MiValidateAddressSpace(AddressSpace)
#define VALIDATE_MEMORY_AREA(MemoryArea) MiValidateMemoryArea(MemoryArea)
#define VALIDATE_RMAP_LIST(RmapList) MiValidateRmapList(RmapList)
#else /* !DBG */
#define VALIDATE_PHYSICAL_ADDRESS(PhysicalAddress)
#define VALIDATE_SWAP_ENTRY(Entry)
#define VALIDATE_PAGEOP(PageOp)
#define VALIDATE_ADDRESS_SPACE(AddressSpace)
#define VALIDATE_MEMORY_AREA(MemoryArea)
#define VALIDATE_RMAP_LIST(RmapList)
#endif /* DBG */
#ifdef DBG
VOID
MiLockAddressSpace(IN PMADDRESS_SPACE AddressSpace,
IN LPSTR FileName,
IN ULONG LineNumber);
VOID
MiUnlockAddressSpace(IN PMADDRESS_SPACE AddressSpace,
IN LPSTR FileName,
IN ULONG LineNumber);
/* Use macros for easier debugging */
#define MmLockAddressSpace(AddressSpace) MiLockAddressSpace(AddressSpace, __FILE__, __LINE__)
#define MmUnlockAddressSpace(AddressSpace) MiUnlockAddressSpace(AddressSpace, __FILE__, __LINE__)
#else /* !DBG */
VOID
MiLockAddressSpace(IN PMADDRESS_SPACE AddressSpace);
VOID
MiUnlockAddressSpace(IN PMADDRESS_SPACE AddressSpace);
#define MmLockAddressSpace MiLockAddressSpace
#define MmUnlockAddressSpace MiUnlockAddressSpace
#endif /* !DBG */
#ifdef DBG
VOID
MiReferenceMemoryArea(IN PMEMORY_AREA MemoryArea,
IN LPSTR FileName,
IN ULONG LineNumber);
VOID
MiDereferenceMemoryArea(IN PMEMORY_AREA MemoryArea,
IN LPSTR FileName,
IN ULONG LineNumber);
/* Use macros for easier debugging */
#define MmReferenceMemoryArea(MemoryArea) MiReferenceMemoryArea(MemoryArea, __FILE__, __LINE__)
#define MmDereferenceMemoryArea(MemoryArea) MiDereferenceMemoryArea(MemoryArea, __FILE__, __LINE__)
#else /* !DBG */
VOID
MiReferenceMemoryArea(IN PMEMORY_AREA MemoryArea);
VOID
MiDereferenceMemoryArea(IN PMEMORY_AREA MemoryArea);
#define MmReferenceMemoryArea MiReferenceMemoryArea
#define MmDereferenceMemoryArea MiDereferenceMemoryArea
#endif /* !DBG */
NTSTATUS NTSTATUS
MmWritePageSectionView(PMADDRESS_SPACE AddressSpace, MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MArea, PMEMORY_AREA MArea,
PVOID Address); PVOID Address);
NTSTATUS NTSTATUS
MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace, MmWritePageVirtualMemory(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MArea, PMEMORY_AREA MArea,
PVOID Address); PVOID Address);
PVOID PVOID
MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process); MmGetDirtyPagesFromWorkingSet(struct _EPROCESS* Process);
NTSTATUS NTSTATUS
MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl); MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
NTSTATUS NTSTATUS
MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl); MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl);
VOID
MmSetFlagsPage(PVOID PhysicalAddress, ULONG Flags);
ULONG
MmGetFlagsPage(PVOID PhysicalAddress);
VOID MmSetSavedSwapEntryPage(PVOID PhysicalAddress,
SWAPENTRY SavedSwapEntry);
SWAPENTRY MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
VOID MmSetCleanPage(struct _EPROCESS* Process, PVOID Address);
VOID MmLockPage(PVOID PhysicalPage);
VOID MmUnlockPage(PVOID PhysicalPage);
NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG Count);
NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG Count);
NTSTATUS
MmCreatePhysicalMemorySection(VOID);
PVOID
MmGetContinuousPages(ULONG NumberOfBytes,
PHYSICAL_ADDRESS HighestAcceptableAddress,
ULONG Alignment);
#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(ULONG PhysPage);
ULONG
MmGetReferenceCountPage(PVOID PhysicalAddress);
BOOLEAN
MmIsUsablePage(PVOID PhysicalAddress);
#define MM_PAGEOP_PAGEIN (1)
#define MM_PAGEOP_PAGEOUT (2)
#define MM_PAGEOP_PAGESYNCH (3)
#define MM_PAGEOP_ACCESSFAULT (4)
typedef struct _MM_PAGEOP
{
/* Type of operation. */
ULONG OpType;
/* Number of threads interested in this operation. */
ULONG ReferenceCount;
/* Event that will be set when the operation is completed. */
KEVENT CompletionEvent;
/* Status of the operation once it is completed. */
NTSTATUS Status;
/* TRUE if the operation was abandoned. */
BOOLEAN Abandoned;
/* The memory area to be affected by the operation. */
PMEMORY_AREA MArea;
ULONG Hash;
struct _MM_PAGEOP* Next;
struct _ETHREAD* Thread;
/*
* These fields are used to identify the operation if it is against a
* virtual memory area.
*/
ULONG Pid;
PVOID Address;
/*
* These fields are used to identify the operation if it is against a
* section mapping.
*/
PMM_SECTION_SEGMENT Segment;
ULONG Offset;
} MM_PAGEOP, *PMM_PAGEOP;
VOID VOID
MmReleasePageOp(PMM_PAGEOP PageOp); MmSetFlagsPage(IN ULONG_PTR PhysicalAddress,
IN ULONG Flags);
ULONG
MmGetFlagsPage(IN ULONG_PTR PhysicalAddress);
VOID
MmSetSavedSwapEntryPage(IN ULONG_PTR PhysicalAddress,
SWAPENTRY SavedSwapEntry);
SWAPENTRY
MmGetSavedSwapEntryPage(IN ULONG_PTR PhysicalAddress);
VOID
MmSetSavedPageOp(IN ULONG_PTR PhysicalAddress,
IN PMM_PAGEOP PageOp);
PMM_PAGEOP PMM_PAGEOP
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, MmGetSavedPageOp(IN ULONG_PTR PhysicalAddress);
PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType);
VOID
MmSetCleanPage(IN PEPROCESS Process,
IN PVOID Address);
VOID
MmLockPage(IN ULONG_PTR PhysicalPage);
VOID
MmUnlockPage(IN ULONG_PTR PhysicalPage);
NTSTATUS
MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG Count);
NTSTATUS
MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG Count);
NTSTATUS
MmCreatePhysicalMemorySection(VOID);
PVOID
MmGetContinuousPages(ULONG NumberOfBytes,
PHYSICAL_ADDRESS HighestAcceptableAddress,
ULONG Alignment);
NTSTATUS
MmAccessFaultSectionView(IN PMADDRESS_SPACE AddressSpace,
IN MEMORY_AREA* IN MemoryArea,
IN PVOID Address,
IN BOOLEAN Locked);
ULONG
MmGetPageProtect(IN struct _EPROCESS* Process,
IN PVOID Address);
PVOID
ExAllocatePageWithPhysPage(IN ULONG_PTR Page);
ULONG
MmGetReferenceCountPage(IN ULONG_PTR PhysicalAddress);
BOOLEAN
MmIsUsablePage(IN ULONG_PTR PhysicalAddress);
VOID
MmReleasePageOp(IN PMM_PAGEOP PageOp);
PMM_PAGEOP
MmGetPageOp(IN PMEMORY_AREA MArea,
IN ULONG Pid,
IN PVOID Address,
IN PMM_SECTION_SEGMENT Segment,
IN ULONG Offset,
IN ULONG OpType);
PMM_PAGEOP
MmGotPageOp(IN PMEMORY_AREA MArea,
IN ULONG Pid,
IN PVOID Address,
IN PMM_SECTION_SEGMENT Segment,
IN ULONG Offset);
VOID VOID
MiDebugDumpNonPagedPool(BOOLEAN NewOnly); MiDebugDumpNonPagedPool(BOOLEAN NewOnly);
VOID VOID
MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly); MiDebugDumpNonPagedPoolStats(BOOLEAN NewOnly);
VOID VOID
MmMarkPageMapped(PVOID PhysicalAddress); MmMarkPageMapped(IN ULONG_PTR PhysicalAddress);
VOID VOID
MmMarkPageUnmapped(PVOID PhysicalAddress); MmMarkPageUnmapped(IN ULONG_PTR PhysicalAddress);
VOID VOID
MmFreeSectionSegments(PFILE_OBJECT FileObject); MmFreeSectionSegments(PFILE_OBJECT FileObject);
@ -439,14 +822,15 @@ typedef struct _MM_IMAGE_SECTION_OBJECT
VOID VOID
MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea); MmFreeVirtualMemory(struct _EPROCESS* Process, PMEMORY_AREA MemoryArea);
NTSTATUS NTSTATUS
MiCopyFromUserPage(ULONG DestPhysPage, PVOID SourceAddress); MiCopyFromUserPage(ULONG DestPhysPage, PVOID SourceAddress);
NTSTATUS NTSTATUS
MiZeroPage(ULONG PhysPage); MiZeroPage(IN ULONG_PTR Page);
BOOLEAN BOOLEAN
MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address); MmIsAccessedAndResetAccessPage(struct _EPROCESS* Process, PVOID Address);
SWAPENTRY
MmGetSavedSwapEntryPage(PVOID PhysicalAddress);
#define STATUS_MM_RESTART_OPERATION (0xD0000001) #define STATUS_MM_RESTART_OPERATION (0xD0000001)
@ -463,10 +847,22 @@ MmInitializeMemoryConsumer(ULONG Consumer,
PULONG NrFreed)); PULONG NrFreed));
VOID VOID
MmInitializeBalancer(ULONG NrAvailablePages); MmInitializeBalancer(ULONG NrAvailablePages);
NTSTATUS NTSTATUS
MmReleasePageMemoryConsumer(ULONG Consumer, PVOID Page); MmReleasePageMemoryConsumer(IN ULONG Consumer,
IN ULONG_PTR Page);
NTSTATUS NTSTATUS
MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPage); MiFreePageMemoryConsumer(IN ULONG Consumer,
IN ULONG_PTR Page);
NTSTATUS
MmRequestPageMemoryConsumer(IN ULONG Consumer,
IN BOOLEAN CanWait,
OUT PULONG_PTR pPage);
VOID
MiSatisfyAllocationRequest();
#define MC_CACHE (0) #define MC_CACHE (0)
#define MC_USER (1) #define MC_USER (1)
@ -475,39 +871,109 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
#define MC_MAXIMUM (4) #define MC_MAXIMUM (4)
VOID VOID
MmSetRmapListHeadPage(PVOID PhysicalAddress, struct _MM_RMAP_ENTRY* ListHead); MiTransitionAllRmaps(IN ULONG_PTR PhysicalAddress,
IN BOOLEAN Reference,
OUT PBOOLEAN Modified);
NTSTATUS
MiAbortTransition(IN ULONG_PTR Address);
NTSTATUS
MiFinishTransition(IN ULONG_PTR PhysicalAddress,
IN BOOLEAN Dirty);
VOID
MmSetRmapListHeadPage(IN ULONG_PTR PhysicalAddress,
IN struct _MM_RMAP_ENTRY* ListHead);
struct _MM_RMAP_ENTRY* struct _MM_RMAP_ENTRY*
MmGetRmapListHeadPage(PVOID PhysicalAddress); MmGetRmapListHeadPage(IN ULONG_PTR PhysicalAddress);
VOID VOID
MmInsertRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address); MmSetRmapCallback(IN ULONG_PTR PhysicalAddress,
IN PRMAP_DELETE_CALLBACK RmapDelete,
IN PVOID RmapDeleteContext);
VOID VOID
MmDeleteAllRmaps(PVOID PhysicalAddress, PVOID Context, MmGetRmapCallback(IN ULONG_PTR PhysicalAddress,
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, PVOID Address)); IN PRMAP_DELETE_CALLBACK *RmapDelete,
IN PVOID *RmapDeleteContext);
NTSTATUS
MmPageOutPhysicalAddress(ULONG_PTR PhysicalAddress);
VOID VOID
MmDeleteRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address); MmInsertRmap(ULONG_PTR PhysicalAddress, PEPROCESS Process, PVOID Address);
VOID
MmDeleteAllRmaps(ULONG_PTR PhysicalAddress, PVOID Context,
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process,
PVOID Address));
VOID
MmDeleteRmap(IN ULONG_PTR PhysicalAddress,
IN PEPROCESS Process,
IN PVOID Address);
VOID VOID
MmInitializeRmapList(VOID); MmInitializeRmapList(VOID);
PVOID
MmGetLRUNextUserPage(PVOID PreviousPhysicalAddress); ULONG_PTR
PVOID MmGetLRUNextUserPage(IN ULONG_PTR PreviousPhysicalAddress);
ULONG_PTR
MmGetLRUFirstUserPage(VOID); MmGetLRUFirstUserPage(VOID);
NTSTATUS NTSTATUS
MmPageOutPhysicalAddress(PVOID PhysicalAddress); MmPrepareFlushPhysicalAddress(IN ULONG_PTR PhysicalAddress);
NTSTATUS
MmFlushPhysicalAddress(IN ULONG_PTR PhysicalAddress);
NTSTATUS NTSTATUS
MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages); MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages);
VOID VOID
MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, ULONG* PhysicalAddr); MmDisableVirtualMapping(IN PEPROCESS Process,
VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address); IN PVOID Address,
OUT PBOOLEAN WasDirty,
OUT PULONG_PTR PhysicalAddr);
VOID MmEnableVirtualMapping(IN PEPROCESS Process,
IN PVOID Address);
VOID VOID
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY* SwapEntry); MmDeletePageFileMapping(IN PEPROCESS Process,
IN PVOID Address,
OUT PSWAPENTRY SwapEntry);
NTSTATUS NTSTATUS
MmCreatePageFileMapping(PEPROCESS Process, MmCreatePageFileMapping(IN PEPROCESS Process,
PVOID Address, IN PVOID Address,
SWAPENTRY SwapEntry); IN SWAPENTRY SwapEntry);
BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address);
BOOLEAN
MmIsPageSwapEntry(IN PEPROCESS Process,
IN PVOID Address);
VOID VOID
MmTransferOwnershipPage(PVOID PhysicalAddress, ULONG NewConsumer); MmTransferOwnershipPage(IN ULONG_PTR PhysicalAddress,
VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address); IN ULONG NewConsumer);
VOID
MmSetDirtyPage(IN PEPROCESS Process,
IN PVOID Address);
NTSTATUS
MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
MEMORY_AREA* MemoryArea,
PVOID Address,
PMM_PAGEOP PageOp);
NTSTATUS
MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID Address,
PMM_PAGEOP PageOp);
#endif #endif

View file

@ -7,10 +7,17 @@
#ifndef __ASM__ #ifndef __ASM__
#include <roscfg.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <stdarg.h> #include <stdarg.h>
#ifdef DBG
#define SET_MAGIC(x, magic)(x)->Magic = (magic);
#else /* !DBG */
#define SET_MAGIC(x, magic)
#endif /* DBG */
/* /*
* Use these to place a function in a specific section of the executable * Use these to place a function in a specific section of the executable
*/ */

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: ps.h,v 1.31 2002/02/15 14:44:13 ekohl Exp $ /* $Id: ps.h,v 1.32 2002/05/13 18:10:39 chorns Exp $
* *
* FILE: ntoskrnl/ke/kthread.c * FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Process manager definitions * PURPOSE: Process manager definitions
@ -585,6 +585,10 @@ PiTimeoutThread(struct _KDPC *dpc,
VOID STDCALL VOID STDCALL
PsDispatchThread(ULONG NewThreadStatus); PsDispatchThread(ULONG NewThreadStatus);
NTSTATUS
PiSetPriorityThread(IN HANDLE ThreadHandle,
IN KPRIORITY Priority);
#endif /* ASSEMBLER */ #endif /* ASSEMBLER */
#endif /* __INCLUDE_INTERNAL_PS_H */ #endif /* __INCLUDE_INTERNAL_PS_H */

View file

@ -87,6 +87,7 @@
#include <internal/kd.h> #include <internal/kd.h>
#include <internal/ke.h> #include <internal/ke.h>
#include <internal/ps.h> #include <internal/ps.h>
#include <internal/module.h>
#include <internal/ldr.h> #include <internal/ldr.h>
#define NDEBUG #define NDEBUG
@ -100,8 +101,10 @@ extern LIST_ENTRY PiThreadListHead;
/* at least NUMREGBYTES*2 are needed for register packets */ /* at least NUMREGBYTES*2 are needed for register packets */
#define BUFMAX 1000 #define BUFMAX 1000
static BOOLEAN GspInitialized; /* boolean flag. TRUE means we've been initialized */ static BOOLEAN GspInitialized;
#if 0
static PKINTERRUPT GspInterrupt; static PKINTERRUPT GspInterrupt;
#endif
static BOOLEAN GspRemoteDebug; static BOOLEAN GspRemoteDebug;
@ -1237,10 +1240,12 @@ extern ULONG KdpPortIrq;
VOID VOID
KdGdbStubInit(ULONG Phase) KdGdbStubInit(ULONG Phase)
{ {
#if 0
KAFFINITY Affinity; KAFFINITY Affinity;
NTSTATUS Status; NTSTATUS Status;
ULONG MappedIrq; ULONG MappedIrq;
KIRQL Dirql; KIRQL Dirql;
#endif
if (Phase == 0) if (Phase == 0)
{ {
@ -1250,9 +1255,12 @@ KdGdbStubInit(ULONG Phase)
GspRunThread = PsGetCurrentThread(); GspRunThread = PsGetCurrentThread();
GspDbgThread = PsGetCurrentThread(); GspDbgThread = PsGetCurrentThread();
GspEnumThread = NULL; GspEnumThread = NULL;
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
} }
else if (Phase == 1) else if (Phase == 1)
{ {
#if 0
/* Hook an interrupt handler to allow the debugger to break into /* Hook an interrupt handler to allow the debugger to break into
the system */ the system */
MappedIrq = HalGetInterruptVector (Internal, MappedIrq = HalGetInterruptVector (Internal,
@ -1283,30 +1291,58 @@ KdGdbStubInit(ULONG Phase)
KdPortEnableInterrupts(); KdPortEnableInterrupts();
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C); DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
#endif
} }
} }
/* This function will generate a breakpoint exception. It is used at the
beginning of a program to sync up with a debugger and can be used
otherwise as a quick means to stop program execution and "break" into
the debugger. */
VOID VOID
KdGdbDebugPrint (LPSTR Message) KdGdbDebugPrint(LPSTR Message)
{ {
/* This can be quite annoying! */
#if 0 #if 0
/* This can be quite annoying! */
if (GspInitialized) if (GspInitialized)
{ {
ULONG Length; ULONG Length;
GspOutBuffer[0] = 'O'; GspOutBuffer[0] = 'O';
GspOutBuffer[1] = '\0'; GspOutBuffer[1] = '\0';
strcat (&GspOutBuffer[0], Message); strcat (&GspOutBuffer[0], Message);
Length = strlen (Message); Length = strlen (Message);
GspOutBuffer[2 + Length] = '\n'; GspOutBuffer[2 + Length] = '\n';
GspOutBuffer[3 + Length] = '\0'; GspOutBuffer[3 + Length] = '\0';
GspPutPacketNoWait (&GspOutBuffer[0]); GspPutPacketNoWait (&GspOutBuffer[0]);
} }
#else
HalDisplayString(Message);
#endif #endif
} }
extern LIST_ENTRY ModuleListHead;
VOID
KdGdbListModules()
{
PLIST_ENTRY CurrentEntry;
PMODULE_OBJECT Current;
ULONG ModuleCount;
DPRINT1("\n");
ModuleCount = 0;
CurrentEntry = ModuleListHead.Flink;
while (CurrentEntry != (&ModuleListHead))
{
Current = CONTAINING_RECORD (CurrentEntry, MODULE_OBJECT, ListEntry);
DbgPrint ("Module %S Base 0x%.08x Length 0x%.08x\n",
Current->BaseName.Buffer, Current->Base, Current->Length);
ModuleCount++;
CurrentEntry = CurrentEntry->Flink;
}
DbgPrint ("%d modules listed\n", ModuleCount);
}

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: bug.c,v 1.21 2002/05/02 23:45:32 dwelch Exp $ /* $Id: bug.c,v 1.22 2002/05/13 18:10:39 chorns Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/bug.c * FILE: ntoskrnl/ke/bug.c
@ -103,9 +103,10 @@ KeBugCheckEx(ULONG BugCheckCode,
{ {
PRTL_MESSAGE_RESOURCE_ENTRY Message; PRTL_MESSAGE_RESOURCE_ENTRY Message;
NTSTATUS Status; NTSTATUS Status;
KIRQL OldIrql;
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
/* PJS: disable interrupts first, then do the rest */
__asm__("cli\n\t");
DbgPrint("Bug detected (code %x param %x %x %x %x)\n", DbgPrint("Bug detected (code %x param %x %x %x %x)\n",
BugCheckCode, BugCheckCode,
BugCheckParameter1, BugCheckParameter1,
@ -133,12 +134,19 @@ KeBugCheckEx(ULONG BugCheckCode,
if (InBugCheck == 1) if (InBugCheck == 1)
{ {
DbgPrint("Recursive bug check halting now\n"); DbgPrint("Recursive bug check halting now\n");
if (KdDebuggerEnabled)
{
DbgBreakPoint();
}
for (;;) for (;;)
{ {
__asm__("hlt\n\t"); __asm__("hlt\n\t");
} }
} }
InBugCheck = 1; InBugCheck = 1;
if (PsGetCurrentProcess() != NULL) if (PsGetCurrentProcess() != NULL)
{ {
DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId); DbgPrint("Pid: %x <", PsGetCurrentProcess()->UniqueProcessId);
@ -150,12 +158,10 @@ KeBugCheckEx(ULONG BugCheckCode,
PsGetCurrentThread(), PsGetCurrentThread(),
PsGetCurrentThread()->Cid.UniqueThread); PsGetCurrentThread()->Cid.UniqueThread);
} }
// PsDumpThreads();
KeDumpStackFrames((PULONG)__builtin_frame_address(0)); KeDumpStackFrames((PULONG)__builtin_frame_address(0));
if (KdDebuggerEnabled) if (KdDebuggerEnabled)
{ {
__asm__("sti\n\t");
DbgBreakPoint(); DbgBreakPoint();
} }

View file

@ -544,6 +544,10 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
*/ */
if (ExceptionNr == 14) if (ExceptionNr == 14)
{ {
#ifdef DBG
KIRQL SavedIrql = KeGetCurrentIrql();
#endif /* DBG */
__asm__("sti\n\t"); __asm__("sti\n\t");
Status = MmPageFault(Tf->Cs&0xffff, Status = MmPageFault(Tf->Cs&0xffff,
&Tf->Eip, &Tf->Eip,
@ -552,6 +556,9 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
Tf->ErrorCode); Tf->ErrorCode);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
assertmsg((KeGetCurrentIrql() == SavedIrql),
("Page fault handler changed IRQL (Before %d After %d). Forgot to release a spin lock?\n",
SavedIrql, KeGetCurrentIrql()));
return(0); return(0);
} }

View file

@ -40,7 +40,7 @@
ULONG KiPcrInitDone = 0; ULONG KiPcrInitDone = 0;
static ULONG PcrsAllocated = 0; static ULONG PcrsAllocated = 0;
static PVOID PcrPages[MAXIMUM_PROCESSORS]; static ULONG_PTR PcrPages[MAXIMUM_PROCESSORS];
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
@ -64,7 +64,7 @@ KeApplicationProcessorInit(VOID)
KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGESIZE)); KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGESIZE));
MmCreateVirtualMappingForKernel((PVOID)KPCR, MmCreateVirtualMappingForKernel((PVOID)KPCR,
PAGE_READWRITE, PAGE_READWRITE,
(ULONG)PcrPages[Offset]); PcrPages[Offset]);
memset(KPCR, 0, PAGESIZE); memset(KPCR, 0, PAGESIZE);
KPCR->ProcessorNumber = Offset; KPCR->ProcessorNumber = 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.23 2002/05/07 22:34:17 hbirr Exp $ /* $Id: kthread.c,v 1.24 2002/05/13 18:10:39 chorns Exp $
* *
* FILE: ntoskrnl/ke/kthread.c * FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Microkernel thread support * PURPOSE: Microkernel thread support
@ -44,13 +44,21 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID VOID
KeFreeStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr, KeFreeStackPage(IN BOOLEAN Before,
SWAPENTRY SwapEntry, BOOLEAN Dirty) IN PVOID Context,
IN PMEMORY_AREA MemoryArea,
IN PVOID Address,
IN ULONG_PTR PhysicalAddress,
IN SWAPENTRY SwapEntry,
IN BOOLEAN Dirty)
{ {
assert(SwapEntry == 0); if (!Before)
if (PhysAddr != 0)
{ {
MmDereferencePage((PVOID)PhysAddr); assert(SwapEntry == 0);
if (PhysicalAddress != 0)
{
MmDereferencePage(PhysicalAddress);
}
} }
} }
@ -109,7 +117,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
MEMORY_AREA_KERNEL_STACK, MEMORY_AREA_KERNEL_STACK,
&KernelStack, &KernelStack,
MM_STACK_SIZE, MM_STACK_SIZE,
0, PAGE_EXECUTE_READWRITE,
&StackArea, &StackArea,
FALSE); FALSE);
MmUnlockAddressSpace(MmGetKernelAddressSpace()); MmUnlockAddressSpace(MmGetKernelAddressSpace());
@ -121,7 +129,7 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
} }
for (i = 0; i < (MM_STACK_SIZE / PAGESIZE); i++) for (i = 0; i < (MM_STACK_SIZE / PAGESIZE); i++)
{ {
PVOID Page; ULONG_PTR Page;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page); Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -129,8 +137,8 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First)
} }
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
KernelStack + (i * PAGESIZE), KernelStack + (i * PAGESIZE),
PAGE_EXECUTE_READWRITE, StackArea->Attributes,
(ULONG)Page, Page,
TRUE); TRUE);
} }
Thread->InitialStack = KernelStack + MM_STACK_SIZE; Thread->InitialStack = KernelStack + MM_STACK_SIZE;

View file

@ -1,4 +1,4 @@
/* $Id: timer.c,v 1.48 2002/04/26 13:11:28 ekohl Exp $ /* $Id: timer.c,v 1.49 2002/05/13 18:10:39 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -138,7 +138,7 @@ KeDelayExecutionThread (KPROCESSOR_MODE WaitMode,
KeSetTimer(&Thread->Timer, *Interval, NULL); KeSetTimer(&Thread->Timer, *Interval, NULL);
return (KeWaitForSingleObject(&Thread->Timer, return (KeWaitForSingleObject(&Thread->Timer,
Executive, Executive,
UserMode, WaitMode,
Alertable, Alertable,
NULL)); NULL));
} }

View file

@ -35,6 +35,127 @@ static PKTHREAD Owner = NULL;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
#ifdef DBG
VOID
KiValidateDispatcherObject(IN PDISPATCHER_HEADER Object)
{
if ((Object->Type < InternalBaseType)
|| (Object->Type > InternalTypeMaximum))
{
assertmsg(FALSE, ("Bad dispatcher object type %d\n", Object->Type));
}
}
PKTHREAD
KiGetDispatcherObjectOwner(IN PDISPATCHER_HEADER Header)
{
switch (Header->Type)
{
case InternalMutexType:
{
PKMUTEX Mutex = (PKMUTEX)Header;
return Mutex->OwnerThread;
}
default:
/* No owner */
return NULL;
}
}
VOID KiDeadlockDetectionMutualResource(IN PDISPATCHER_HEADER CurrentObject,
IN PKTHREAD CurrentThread,
IN PKTHREAD OwnerThread)
/*
* PURPOSE: Perform deadlock detection.
* At this point, OwnerThread owns CurrentObject and CurrentThread
* is waiting on CurrentObject
* Deadlock happens if OwnerThread is waiting on a resource that
* InitialThread owns.
* NOTE: Called with the dispatcher database locked
*/
{
PDISPATCHER_HEADER Object;
PKWAIT_BLOCK WaitBlock;
PKTHREAD Thread;
DPRINT("KiDeadlockDetectionMutualResource("
"CurrentObject 0x%.08x, CurrentThread 0x%.08x OwnerThread 0x%.08x)\n",
CurrentObject, CurrentThread, OwnerThread);
/* Go through all dispather objects that OwnerThread is waiting on */
for (WaitBlock = OwnerThread->WaitBlockList;
WaitBlock;
WaitBlock = WaitBlock->NextWaitBlock)
{
Object = WaitBlock->Object;
/* If OwnerThread is waiting on a resource that CurrentThread has
* acquired then we have a deadlock */
Thread = KiGetDispatcherObjectOwner(Object);
if ((Thread != NULL) && (Thread == CurrentThread))
{
DbgPrint("Deadlock detected!\n");
DbgPrint("Thread 0x%.08x is waiting on Object 0x%.08x of type %d "
" which is owned by Thread 0x%.08x\n",
Thread, CurrentObject, CurrentObject->Type, OwnerThread);
DbgPrint("Thread 0x%.08x is waiting on Object 0x%.08x of type %d "
" which is owned by Thread 0x%.08x\n",
OwnerThread, Object, Object->Type, Thread);
KeBugCheck(0);
}
}
}
VOID KiDeadlockDetection(IN PDISPATCHER_HEADER Header)
/*
* PURPOSE: Perform deadlock detection
* NOTE: Called with the dispatcher database locked
*/
{
PLIST_ENTRY CurrentEntry;
PKWAIT_BLOCK WaitBlock;
PKWAIT_BLOCK Current;
PKTHREAD OwnerThread;
PKTHREAD Thread;
DPRINT("KiDeadlockDetection(Header %x)\n", Header);
if (IsListEmpty(&(Header->WaitListHead)))
return;
CurrentEntry = Header->WaitListHead.Flink;
Current = CONTAINING_RECORD(CurrentEntry, KWAIT_BLOCK, WaitListEntry);
/* Go through all threads waiting on this dispatcher object */
for (WaitBlock = Current->Thread->WaitBlockList;
WaitBlock;
WaitBlock = WaitBlock->NextWaitBlock)
{
Thread = WaitBlock->Thread;
DPRINT("KiDeadlockDetection: WaitBlock->Thread %x waiting on WaitBlock->Object %x\n",
WaitBlock->Thread, WaitBlock->Object);
/* If another thread is currently owning this dispatcher object,
see if we have a deadlock */
OwnerThread = KiGetDispatcherObjectOwner(Current->Object);
DPRINT("KiDeadlockDetection: OwnerThread %x\n", OwnerThread);
if ((OwnerThread != NULL) && (OwnerThread != Thread))
{
KiDeadlockDetectionMutualResource(Current->Object,
Current->Thread,
OwnerThread);
}
}
}
#endif /* DBG */
VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header,
ULONG Type, ULONG Type,
ULONG Size, ULONG Size,
@ -136,6 +257,7 @@ static VOID KiSideEffectsBeforeWake(DISPATCHER_HEADER* hdr,
DPRINT1("Thread == NULL!\n"); DPRINT1("Thread == NULL!\n");
KeBugCheck(0); KeBugCheck(0);
} }
if (Abandoned != NULL) if (Abandoned != NULL)
*Abandoned = Mutex->Abandoned; *Abandoned = Mutex->Abandoned;
if (Thread != NULL) if (Thread != NULL)
@ -433,6 +555,10 @@ KeWaitForSingleObject(PVOID Object,
KIRQL WaitIrql; KIRQL WaitIrql;
BOOLEAN Abandoned; BOOLEAN Abandoned;
assert_irql(DISPATCH_LEVEL);
VALIDATE_DISPATCHER_OBJECT(Object);
CurrentThread = KeGetCurrentThread(); CurrentThread = KeGetCurrentThread();
WaitIrql = KeGetCurrentIrql(); WaitIrql = KeGetCurrentIrql();
@ -489,9 +615,22 @@ KeWaitForSingleObject(PVOID Object,
return(STATUS_TIMEOUT); return(STATUS_TIMEOUT);
} }
/* #ifdef DBG
* Set up for a wait
*/ if (hdr->Type == InternalMutexType)
{
PKMUTEX Mutex;
Mutex = CONTAINING_RECORD(hdr, KMUTEX, Header);
assertmsg(Mutex->OwnerThread != CurrentThread,
("Recursive locking of mutex (0x%.08x)\n", Mutex));
}
#endif /* DBG */
/*
* Set up for a wait
*/
CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL; CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL;
/* Append wait block to the KTHREAD wait block list */ /* Append wait block to the KTHREAD wait block list */
CurrentThread->WaitBlockList = &CurrentThread->WaitBlock[0]; CurrentThread->WaitBlockList = &CurrentThread->WaitBlock[0];
@ -517,6 +656,16 @@ KeWaitForSingleObject(PVOID Object,
{ {
CurrentThread->WaitBlock[0].NextWaitBlock = NULL; CurrentThread->WaitBlock[0].NextWaitBlock = NULL;
} }
#ifdef DBG
/*
* Do deadlock detection in checked version
* NOTE: This must be done after the the dispatcher object is put on
* the wait block list.
*/
KiDeadlockDetection(Object);
#endif /* DBG */
PsBlockThread(&Status, (UCHAR)Alertable, WaitMode, TRUE, WaitIrql); PsBlockThread(&Status, (UCHAR)Alertable, WaitMode, TRUE, WaitIrql);
} while (Status == STATUS_KERNEL_APC); } while (Status == STATUS_KERNEL_APC);
@ -552,6 +701,8 @@ KeWaitForMultipleObjects(ULONG Count,
DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) " DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) "
"PsGetCurrentThread() %x\n",Count,Object,PsGetCurrentThread()); "PsGetCurrentThread() %x\n",Count,Object,PsGetCurrentThread());
assert_irql(APC_LEVEL);
CountSignaled = 0; CountSignaled = 0;
CurrentThread = KeGetCurrentThread(); CurrentThread = KeGetCurrentThread();
WaitIrql = KeGetCurrentIrql(); WaitIrql = KeGetCurrentIrql();
@ -610,6 +761,8 @@ KeWaitForMultipleObjects(ULONG Count,
{ {
hdr = (DISPATCHER_HEADER *)Object[i]; hdr = (DISPATCHER_HEADER *)Object[i];
VALIDATE_DISPATCHER_OBJECT(hdr);
if (KiIsObjectSignalled(hdr, CurrentThread, &Abandoned)) if (KiIsObjectSignalled(hdr, CurrentThread, &Abandoned))
{ {
CountSignaled++; CountSignaled++;
@ -655,7 +808,7 @@ KeWaitForMultipleObjects(ULONG Count,
for (i = 0; i < Count; i++) for (i = 0; i < Count; i++)
{ {
hdr = (DISPATCHER_HEADER *)Object[i]; hdr = (DISPATCHER_HEADER *)Object[i];
assertmsg(hdr != NULL, ("Waiting on uninitialized object\n"));
blk->Object = Object[i]; blk->Object = Object[i];
blk->Thread = CurrentThread; blk->Thread = CurrentThread;
blk->WaitKey = STATUS_WAIT_0 + i; blk->WaitKey = STATUS_WAIT_0 + i;

View file

@ -1,4 +1,4 @@
/* $Id: aspace.c,v 1.8 2001/12/31 01:53:45 dwelch Exp $ /* $Id: aspace.c,v 1.9 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -11,6 +11,7 @@
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include <roscfg.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/mm.h> #include <internal/mm.h>
#include <internal/ps.h> #include <internal/ps.h>
@ -18,33 +19,115 @@
#include <internal/debug.h> #include <internal/debug.h>
/* Define to track address space locking/unlocking */
//#define TRACK_ADDRESS_SPACE_LOCK
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
STATIC MADDRESS_SPACE KernelAddressSpace; STATIC MADDRESS_SPACE KernelAddressSpace;
#define TAG_ASPC TAG('A', 'S', 'P', 'C')
#define TAG_PTRC TAG('P', 'T', 'R', 'C') #define TAG_PTRC TAG('P', 'T', 'R', 'C')
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
#ifdef DBG
VOID VOID
MmLockAddressSpace(PMADDRESS_SPACE AddressSpace) MiValidateAddressSpace(IN PMADDRESS_SPACE AddressSpace)
{ {
assertmsg(AddressSpace != NULL,
("No address space can exist at 0x%.08x\n", AddressSpace));
assertmsg(AddressSpace->Magic == TAG_ASPC,
("Bad magic (0x%.08x) for address space (0x%.08x). It should be 0x%.08x\n",
AddressSpace->Magic, AddressSpace, TAG_ASPC));
assertmsg(AddressSpace->ReferenceCount > 0,
("No outstanding references on address space (0x%.08x)\n", AddressSpace));
}
#endif /* DBG */
#ifdef DBG
VOID
MiLockAddressSpace(IN PMADDRESS_SPACE AddressSpace,
IN LPSTR FileName,
IN ULONG LineNumber)
{
VALIDATE_ADDRESS_SPACE(AddressSpace);
/*
* Don't bother with locking if we are the first thread.
*/
if (KeGetCurrentThread() == NULL)
{
return;
}
#ifdef TRACK_ADDRESS_SPACE_LOCK
DbgPrint("(0x%.08x)(%s:%d) Locking address space 0x%.08x\n",
KeGetCurrentThread(), FileName, LineNumber, AddressSpace);
#endif /* TRACK_ADDRESS_SPACE_LOCK */
(VOID)KeWaitForMutexObject(&AddressSpace->Lock,
Executive,
KernelMode,
FALSE,
NULL);
#ifdef TRACK_ADDRESS_SPACE_LOCK
DbgPrint("(0x%.08x)(%s:%d) Locked address space 0x%.08x\n",
KeGetCurrentThread(), FileName, LineNumber, AddressSpace);
#endif /* TRACK_ADDRESS_SPACE_LOCK */
}
VOID
MiUnlockAddressSpace(IN PMADDRESS_SPACE AddressSpace,
IN LPSTR FileName,
IN ULONG LineNumber)
{
VALIDATE_ADDRESS_SPACE(AddressSpace);
/* /*
* Don't bother with locking if we are the first thread. * Don't bother locking if we are the first thread.
*/ */
if (KeGetCurrentThread() == NULL) if (KeGetCurrentThread() == NULL)
{ {
return; return;
} }
(VOID)KeWaitForMutexObject(&AddressSpace->Lock, KeReleaseMutex(&AddressSpace->Lock, FALSE);
0,
KernelMode, #ifdef TRACK_ADDRESS_SPACE_LOCK
FALSE, DbgPrint("(0x%.08x)(%s:%d) Unlocked address space 0x%.08x\n",
NULL); KeGetCurrentThread(), FileName, LineNumber, AddressSpace);
#endif /* TRACK_ADDRESS_SPACE_LOCK */
} }
#else /* !DBG */
VOID VOID
MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace) MiLockAddressSpace(IN PMADDRESS_SPACE AddressSpace)
{
/*
* Don't bother with locking if we are the first thread.
*/
if (KeGetCurrentThread() == NULL)
{
return;
}
(VOID)KeWaitForMutexObject(&AddressSpace->Lock,
Executive,
KernelMode,
FALSE,
NULL);
}
VOID
MiUnlockAddressSpace(IN PMADDRESS_SPACE AddressSpace)
{ {
/* /*
* Don't bother locking if we are the first thread. * Don't bother locking if we are the first thread.
@ -56,26 +139,37 @@ MmUnlockAddressSpace(PMADDRESS_SPACE AddressSpace)
KeReleaseMutex(&AddressSpace->Lock, FALSE); KeReleaseMutex(&AddressSpace->Lock, FALSE);
} }
#endif /* !DBG */
VOID VOID
MmInitializeKernelAddressSpace(VOID) MmInitializeKernelAddressSpace()
{ {
MmInitializeAddressSpace(NULL, &KernelAddressSpace); MmInitializeAddressSpace(NULL, &KernelAddressSpace);
} }
PMADDRESS_SPACE MmGetCurrentAddressSpace(VOID)
PMADDRESS_SPACE
MmGetCurrentAddressSpace()
{ {
return(&PsGetCurrentProcess()->AddressSpace); return(&PsGetCurrentProcess()->AddressSpace);
} }
PMADDRESS_SPACE MmGetKernelAddressSpace(VOID)
PMADDRESS_SPACE
MmGetKernelAddressSpace()
{ {
return(&KernelAddressSpace); return(&KernelAddressSpace);
} }
NTSTATUS NTSTATUS
MmInitializeAddressSpace(PEPROCESS Process, MmInitializeAddressSpace(IN PEPROCESS Process,
PMADDRESS_SPACE AddressSpace) IN PMADDRESS_SPACE AddressSpace)
{ {
SET_MAGIC(AddressSpace, TAG_ASPC)
AddressSpace->ReferenceCount = 1;
InitializeListHead(&AddressSpace->MAreaListHead); InitializeListHead(&AddressSpace->MAreaListHead);
KeInitializeMutex(&AddressSpace->Lock, 1); KeInitializeMutex(&AddressSpace->Lock, 1);
if (Process != NULL) if (Process != NULL)
@ -102,12 +196,38 @@ MmInitializeAddressSpace(PEPROCESS Process,
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS NTSTATUS
MmDestroyAddressSpace(PMADDRESS_SPACE AddressSpace) MmDestroyAddressSpace(IN PMADDRESS_SPACE AddressSpace)
{ {
VALIDATE_ADDRESS_SPACE(AddressSpace);
AddressSpace->ReferenceCount--;
assertmsg(AddressSpace->ReferenceCount == 0,
("There are %d outstanding references on address space (0x%.08x)\n",
AddressSpace->ReferenceCount, AddressSpace));
if (AddressSpace->PageTableRefCountTable != NULL) if (AddressSpace->PageTableRefCountTable != NULL)
{ {
ExFreePool(AddressSpace->PageTableRefCountTable); ExFreePool(AddressSpace->PageTableRefCountTable);
} }
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
VOID
MmReferenceAddressSpace(IN PMADDRESS_SPACE AddressSpace)
{
InterlockedIncrement(&AddressSpace->ReferenceCount);
}
VOID
MmDereferenceAddressSpace(IN PMADDRESS_SPACE AddressSpace)
{
InterlockedDecrement(&AddressSpace->ReferenceCount);
assertmsg(AddressSpace->ReferenceCount > 0,
("No outstanding references on address space (0x%.08x)\n", AddressSpace));
}

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.6 2002/02/28 17:44:48 hbirr Exp $ /* $Id: balance.c,v 1.7 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -47,7 +47,7 @@ typedef struct _MM_MEMORY_CONSUMER
typedef struct _MM_ALLOCATION_REQUEST typedef struct _MM_ALLOCATION_REQUEST
{ {
PVOID Page; ULONG_PTR Page;
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
KEVENT Event; KEVENT Event;
} MM_ALLOCATION_REQUEST, *PMM_ALLOCATION_REQUEST; } MM_ALLOCATION_REQUEST, *PMM_ALLOCATION_REQUEST;
@ -93,13 +93,13 @@ MmInitializeMemoryConsumer(ULONG Consumer,
} }
NTSTATUS NTSTATUS
MmReleasePageMemoryConsumer(ULONG Consumer, PVOID Page) MmReleasePageMemoryConsumer(ULONG Consumer, ULONG_PTR Page)
{ {
PMM_ALLOCATION_REQUEST Request; PMM_ALLOCATION_REQUEST Request;
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
KIRQL oldIrql; KIRQL oldIrql;
if (Page == NULL) if (Page == 0)
{ {
DPRINT1("Tried to release page zero.\n"); DPRINT1("Tried to release page zero.\n");
KeBugCheck(0); KeBugCheck(0);
@ -173,11 +173,11 @@ MiRebalanceMemoryConsumers(VOID)
} }
NTSTATUS NTSTATUS
MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPage) MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PULONG_PTR AllocatedPage)
{ {
ULONG OldUsed; ULONG OldUsed;
ULONG OldAvailable; ULONG OldAvailable;
PVOID Page; ULONG_PTR Page;
KIRQL oldIrql; KIRQL oldIrql;
/* /*
@ -211,7 +211,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
} }
/* Insert an allocation request. */ /* Insert an allocation request. */
Request.Page = NULL; Request.Page = 0;
KeInitializeEvent(&Request.Event, NotificationEvent, FALSE); KeInitializeEvent(&Request.Event, NotificationEvent, FALSE);
InterlockedIncrement(&MiPagesRequired); InterlockedIncrement(&MiPagesRequired);
@ -234,7 +234,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
{ {
Page = MmAllocPage(Consumer, 0); Page = MmAllocPage(Consumer, 0);
KeReleaseSpinLock(&AllocationListLock, oldIrql); KeReleaseSpinLock(&AllocationListLock, oldIrql);
if (Page == NULL) if (Page == 0)
{ {
KeBugCheck(0); KeBugCheck(0);
} }
@ -251,7 +251,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
NULL); NULL);
Page = Request.Page; Page = Request.Page;
if (Page == NULL) if (Page == 0)
{ {
KeBugCheck(0); KeBugCheck(0);
} }
@ -264,7 +264,7 @@ MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN CanWait, PVOID* AllocatedPag
* Actually allocate the page. * Actually allocate the page.
*/ */
Page = MmAllocPage(Consumer, 0); Page = MmAllocPage(Consumer, 0);
if (Page == NULL) if (Page == 0)
{ {
KeBugCheck(0); KeBugCheck(0);
} }

View file

@ -1,4 +1,4 @@
/* $Id: cont.c,v 1.17 2002/01/01 00:21:55 dwelch Exp $ /* $Id: cont.c,v 1.18 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -19,14 +19,22 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID STATIC VOID
MmFreeContinuousPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr, MmFreeContinuousPage(IN BOOLEAN Before,
SWAPENTRY SwapEntry, BOOLEAN Dirty) IN PVOID Context,
IN PMEMORY_AREA MemoryArea,
IN PVOID Address,
IN ULONG_PTR PhysicalAddress,
IN SWAPENTRY SwapEntry,
IN BOOLEAN Dirty)
{ {
assert(SwapEntry == 0); if (!Before)
if (PhysAddr != 0)
{ {
MmDereferencePage((PVOID)PhysAddr); assert(SwapEntry == 0);
if (PhysicalAddress != 0)
{
MmDereferencePage(PhysicalAddress);
}
} }
} }
@ -43,13 +51,13 @@ MmAllocateContiguousAlignedMemory(IN ULONG NumberOfBytes,
MmLockAddressSpace(MmGetKernelAddressSpace()); MmLockAddressSpace(MmGetKernelAddressSpace());
Status = MmCreateMemoryArea(NULL, Status = MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(), MmGetKernelAddressSpace(),
MEMORY_AREA_CONTINUOUS_MEMORY, MEMORY_AREA_CONTINUOUS_MEMORY,
&BaseAddress, &BaseAddress,
NumberOfBytes, NumberOfBytes,
0, 0,
&MArea, &MArea,
FALSE); FALSE);
MmUnlockAddressSpace(MmGetKernelAddressSpace()); MmUnlockAddressSpace(MmGetKernelAddressSpace());
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -141,11 +149,11 @@ MmAllocateContiguousMemory (IN ULONG NumberOfBytes,
VOID STDCALL VOID STDCALL
MmFreeContiguousMemory(IN PVOID BaseAddress) MmFreeContiguousMemory(IN PVOID BaseAddress)
{ {
MmFreeMemoryArea(MmGetKernelAddressSpace(), MmFreeMemoryArea(MmGetKernelAddressSpace(),
BaseAddress, BaseAddress,
0, 0,
MmFreeContinuousPage, MmFreeContinuousPage,
NULL); NULL);
} }

File diff suppressed because it is too large Load diff

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: page.c,v 1.34 2002/01/08 00:49:01 dwelch Exp $ /* $Id: page.c,v 1.35 2002/05/13 18:10:41 chorns Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/i386/page.c * FILE: ntoskrnl/mm/i386/page.c
@ -39,30 +39,141 @@
/* GLOBALS *****************************************************************/ /* GLOBALS *****************************************************************/
#define PA_BIT_PRESENT (0) /* See pagefile.c for the layout of a swap entry PTE */
#define PA_BIT_READWRITE (1) #define PA_BIT_PRESENT (0)
#define PA_BIT_USER (2) #define PA_BIT_READWRITE (1)
#define PA_BIT_WT (3) #define PA_BIT_USER (2)
#define PA_BIT_CD (4) #define PA_BIT_WT (3)
#define PA_BIT_ACCESSED (5) #define PA_BIT_CD (4)
#define PA_BIT_DIRTY (6) #define PA_BIT_ACCESSED (5)
#define PA_BIT_DIRTY (6)
#define PA_BIT_PROTOTYPE (7)
#define PA_BIT_TRANSITION (8)
#define PA_BIT_DEMAND_ZERO (9)
#define PA_PRESENT (1 << PA_BIT_PRESENT) #define PA_PRESENT (1 << PA_BIT_PRESENT)
#define PA_READWRITE (1 << PA_BIT_READWRITE) #define PA_READWRITE (1 << PA_BIT_READWRITE)
#define PA_USER (1 << PA_BIT_USER) #define PA_USER (1 << PA_BIT_USER)
#define PA_DIRTY (1 << PA_BIT_DIRTY) #define PA_DIRTY (1 << PA_BIT_DIRTY)
#define PA_WT (1 << PA_BIT_WT) #define PA_WT (1 << PA_BIT_WT)
#define PA_CD (1 << PA_BIT_CD) #define PA_CD (1 << PA_BIT_CD)
#define PA_ACCESSED (1 << PA_BIT_ACCESSED) #define PA_ACCESSED (1 << PA_BIT_ACCESSED)
#define PA_DIRTY (1 << PA_BIT_DIRTY) #define PA_DIRTY (1 << PA_BIT_DIRTY)
#define PA_PROTOTYPE (1 << PA_BIT_PROTOTYPE)
#define PA_TRANSITION (1 << PA_BIT_TRANSITION)
#define PA_DEMAND_ZERO (1 << PA_BIT_DEMAND_ZERO)
#define GET_SWAPENTRY_FROM_PTE(pte)((pte) & 0x1ffffffe) >> 1
#define SET_SWAPENTRY_IN_PTE(pte, entry)((pte) = ((entry << 1) & 0x1ffffffe))
#define IS_SWAPENTRY_PTE(pte)((!(Pte & PA_PRESENT)) && ((pte) & 0x1ffffffe))
#define PAGETABLE_MAP (0xf0000000) #define PAGETABLE_MAP (0xf0000000)
#define PAGEDIRECTORY_MAP (0xf0000000 + (PAGETABLE_MAP / (1024))) #define PAGEDIRECTORY_MAP (0xf0000000 + (PAGETABLE_MAP / (1024)))
ULONG MmGlobalKernelPageDirectory[1024] = {0, }; ULONG MmGlobalKernelPageDirectory[1024] = {0, };
#ifdef DBG
PVOID MiBreakPointAddressLow = (PVOID)0x0;
PVOID MiBreakPointAddressHigh = (PVOID)0x0;
#endif /* DBG */
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
#ifdef DBG
VOID
MiDumpPTE(IN ULONG Value)
{
if (Value & PA_PRESENT)
DbgPrint("Valid\n");
else
DbgPrint("Invalid\n");
if (Value & PA_READWRITE)
DbgPrint("Read/Write\n");
else
DbgPrint("Read only\n");
if (Value & PA_USER)
DbgPrint("User access\n");
else
DbgPrint("System access\n");
if (Value & PA_WT)
DbgPrint("Write through\n");
else
DbgPrint("Not write through\n");
if (Value & PA_CD)
DbgPrint("No cache\n");
else
DbgPrint("Cache\n");
if (Value & PA_ACCESSED)
DbgPrint("Accessed\n");
else
DbgPrint("Not accessed\n");
if (Value & PA_DIRTY)
DbgPrint("Dirty\n");
else
DbgPrint("Clean\n");
if (Value & PA_PROTOTYPE)
DbgPrint("Prototype\n");
else
DbgPrint("Not prototype\n");
if (Value & PA_TRANSITION)
DbgPrint("Transition\n");
else
DbgPrint("Not transition\n");
if (Value & PA_DEMAND_ZERO)
DbgPrint("Demand zero\n");
else
DbgPrint("Not demand zero\n");
}
/*
* Call from a debugger to have the OS break into the
* debugger when a PTE in this range is changed
*/
VOID
DbgMmSetBreakPointAddressRange(IN PVOID LowAddress,
IN PVOID HighAddress)
{
MiBreakPointAddressLow = LowAddress;
MiBreakPointAddressHigh = HighAddress;
}
/*
* Single page version of DbgSetBreakPointAddressRange()
*/
VOID
DbgMmSetBreakPointAddress(IN PVOID Address)
{
MiBreakPointAddressLow = Address;
MiBreakPointAddressHigh = Address;
}
VOID
MiValidatePhysicalAddress(IN ULONG_PTR PhysicalAddress)
{
if (!MiInitialized)
return;
assertmsg((PhysicalAddress / PAGESIZE) < MmStats.NrTotalPages,
("Bad physical address 0x%.08x\n", PhysicalAddress))
}
#endif /* DBG */
PULONG PULONG
MmGetPageDirectory(VOID) MmGetPageDirectory(VOID)
{ {
@ -72,6 +183,7 @@ MmGetPageDirectory(VOID)
return((PULONG)page_dir); return((PULONG)page_dir);
} }
static ULONG static ULONG
ProtectToPTE(ULONG flProtect) ProtectToPTE(ULONG flProtect)
{ {
@ -122,7 +234,7 @@ NTSTATUS Mmi386ReleaseMmInfo(PEPROCESS Process)
{ {
DPRINT("Mmi386ReleaseMmInfo(Process %x)\n",Process); DPRINT("Mmi386ReleaseMmInfo(Process %x)\n",Process);
MmDereferencePage(Process->Pcb.DirectoryTableBase[0]); MmDereferencePage((ULONG_PTR) Process->Pcb.DirectoryTableBase[0]);
Process->Pcb.DirectoryTableBase[0] = NULL; Process->Pcb.DirectoryTableBase[0] = NULL;
DPRINT("Finished Mmi386ReleaseMmInfo()\n"); DPRINT("Finished Mmi386ReleaseMmInfo()\n");
@ -145,6 +257,9 @@ NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest)
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
PhysPageDirectory = (PULONG)(MmGetPhysicalAddress(PageDirectory)).u.LowPart; PhysPageDirectory = (PULONG)(MmGetPhysicalAddress(PageDirectory)).u.LowPart;
VALIDATE_PHYSICAL_ADDRESS(PhysPageDirectory);
KProcess->DirectoryTableBase[0] = PhysPageDirectory; KProcess->DirectoryTableBase[0] = PhysPageDirectory;
CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP; CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP;
@ -176,7 +291,7 @@ VOID MmDeletePageTable(PEPROCESS Process, PVOID Address)
KeAttachProcess(Process); KeAttachProcess(Process);
} }
*(ADDR_TO_PDE(Address)) = 0; *(ADDR_TO_PDE(Address)) = 0;
if (Address >= (PVOID)KERNEL_BASE) if (Address >= (PVOID) KERNEL_BASE)
{ {
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0; MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
} }
@ -192,13 +307,13 @@ VOID MmFreePageTable(PEPROCESS Process, PVOID Address)
PEPROCESS CurrentProcess = PsGetCurrentProcess(); PEPROCESS CurrentProcess = PsGetCurrentProcess();
PULONG PageTable; PULONG PageTable;
ULONG i; ULONG i;
ULONG npage; ULONG_PTR npage;
if (Process != NULL && Process != CurrentProcess) if (Process != NULL && Process != CurrentProcess)
{ {
KeAttachProcess(Process); KeAttachProcess(Process);
} }
PageTable = (PULONG)PAGE_ROUND_DOWN((PVOID)ADDR_TO_PTE(Address)); PageTable = (PULONG) PAGE_ROUND_DOWN((PVOID) ADDR_TO_PTE(Address));
for (i = 0; i < 1024; i++) for (i = 0; i < 1024; i++)
{ {
if (PageTable[i] != 0) if (PageTable[i] != 0)
@ -210,11 +325,11 @@ VOID MmFreePageTable(PEPROCESS Process, PVOID Address)
} }
npage = *(ADDR_TO_PDE(Address)); npage = *(ADDR_TO_PDE(Address));
*(ADDR_TO_PDE(Address)) = 0; *(ADDR_TO_PDE(Address)) = 0;
if (Address >= (PVOID)KERNEL_BASE) if (Address >= (PVOID) KERNEL_BASE)
{ {
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0; MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
} }
MmDereferencePage((PVOID)PAGE_MASK(npage)); MmDereferencePage((ULONG_PTR) PAGE_MASK(npage));
FLUSH_TLB; FLUSH_TLB;
if (Process != NULL && Process != CurrentProcess) if (Process != NULL && Process != CurrentProcess)
{ {
@ -228,8 +343,8 @@ NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte, BOOLEAN MayWait)
*/ */
{ {
PULONG Pde; PULONG Pde;
ULONG Address = (ULONG)PAddress; ULONG_PTR Address = (ULONG)PAddress;
ULONG npage; ULONG_PTR npage;
DPRINT("MmGetPageEntry(Address %x)\n", Address); DPRINT("MmGetPageEntry(Address %x)\n", Address);
@ -245,18 +360,21 @@ NTSTATUS MmGetPageEntry2(PVOID PAddress, PULONG* Pte, BOOLEAN MayWait)
else else
{ {
NTSTATUS Status; NTSTATUS Status;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, (PVOID*)&npage); Status = MmRequestPageMemoryConsumer(MC_NPPOOL, MayWait, &npage);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(Status); return(Status);
} }
VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(npage));
(*Pde) = npage | 0x7; (*Pde) = npage | 0x7;
if (Address >= KERNEL_BASE) if (Address >= KERNEL_BASE)
{ {
MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] =
*Pde; *Pde;
} }
memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE); memset((PVOID) PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE);
FLUSH_TLB; FLUSH_TLB;
} }
} }
@ -290,7 +408,7 @@ ULONG MmGetPageEntry1(PVOID PAddress)
PULONG page_dir; PULONG page_dir;
ULONG Address = (ULONG)PAddress; ULONG Address = (ULONG)PAddress;
DPRINT("MmGetPageEntry(Address %x)\n", Address); DPRINT("MmGetPageEntry1(Address %x)\n", Address);
page_dir = ADDR_TO_PDE(Address); page_dir = ADDR_TO_PDE(Address);
if ((*page_dir) == 0 && if ((*page_dir) == 0 &&
@ -327,30 +445,31 @@ ULONG MmGetPageEntryForProcess1(PEPROCESS Process, PVOID Address)
} }
ULONG MmGetPhysicalAddressForProcess(PEPROCESS Process, ULONG
PVOID Address) MmGetPhysicalAddressForProcess(IN PEPROCESS Process,
IN PVOID Address)
{ {
ULONG PageEntry; ULONG PageEntry;
PageEntry = MmGetPageEntryForProcess(Process, Address); PageEntry = MmGetPageEntryForProcess(Process, Address);
if (!(PageEntry & PA_PRESENT)) VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(PageEntry));
{
return(0); return(PAGE_MASK(PageEntry));
}
return(PAGE_MASK(PageEntry));
} }
VOID VOID
MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, ULONG* PhysicalAddr) MmDisableVirtualMapping(IN PEPROCESS Process,
IN PVOID Address,
OUT PBOOLEAN WasDirty,
OUT PULONG_PTR PhysicalAddr)
/* /*
* FUNCTION: Delete a virtual mapping * FUNCTION: Disable a virtual mapping
*/ */
{ {
ULONG Pte; ULONG Pte;
PULONG Pde; PULONG Pde;
PEPROCESS CurrentProcess = PsGetCurrentProcess(); PEPROCESS CurrentProcess = PsGetCurrentProcess();
BOOLEAN WasValid;
/* /*
* If we are setting a page in another process we need to be in its * If we are setting a page in another process we need to be in its
@ -374,20 +493,16 @@ MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, ULONG*
} }
if ((*Pde) == 0) if ((*Pde) == 0)
{ {
DPRINT1("PDE for address 0x%.08x does not exist\n", Address);
KeBugCheck(0); KeBugCheck(0);
} }
/* /*
* Atomically set the entry to zero and get the old value. * Reset the present bit
*/ */
Pte = *ADDR_TO_PTE(Address); Pte = *ADDR_TO_PTE(Address);
*ADDR_TO_PTE(Address) = Pte & (~PA_PRESENT); *ADDR_TO_PTE(Address) = Pte & (~PA_PRESENT);
FLUSH_TLB; FLUSH_TLB;
WasValid = (PAGE_MASK(Pte) != 0);
if (!WasValid)
{
KeBugCheck(0);
}
/* /*
* If necessary go back to the original context * If necessary go back to the original context
@ -406,13 +521,18 @@ MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, ULONG*
} }
if (PhysicalAddr != NULL) if (PhysicalAddr != NULL)
{ {
*PhysicalAddr = PAGE_MASK(Pte); VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(Pte));
*PhysicalAddr = PAGE_MASK(Pte);
} }
} }
VOID VOID
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage, MmDeleteVirtualMapping(PEPROCESS Process,
BOOL* WasDirty, ULONG* PhysicalAddr) PVOID Address,
BOOLEAN FreePage,
PBOOLEAN WasDirty,
PULONG PhysicalAddr)
/* /*
* FUNCTION: Delete a virtual mapping * FUNCTION: Delete a virtual mapping
*/ */
@ -467,11 +587,11 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
WasValid = (PAGE_MASK(Pte) != 0); WasValid = (PAGE_MASK(Pte) != 0);
if (WasValid) if (WasValid)
{ {
MmMarkPageUnmapped((PVOID)PAGE_MASK(Pte)); MmMarkPageUnmapped((ULONG_PTR) PAGE_MASK(Pte));
} }
if (FreePage && WasValid) if (FreePage && WasValid)
{ {
MmDereferencePage((PVOID)PAGE_MASK(Pte)); MmDereferencePage((ULONG_PTR) PAGE_MASK(Pte));
} }
/* /*
@ -516,13 +636,16 @@ MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
} }
if (PhysicalAddr != NULL) if (PhysicalAddr != NULL)
{ {
VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(Pte));
*PhysicalAddr = PAGE_MASK(Pte); *PhysicalAddr = PAGE_MASK(Pte);
} }
} }
VOID VOID
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, MmDeletePageFileMapping(IN PEPROCESS Process,
SWAPENTRY* SwapEntry) IN PVOID Address,
OUT PSWAPENTRY SwapEntry)
/* /*
* FUNCTION: Delete a virtual mapping * FUNCTION: Delete a virtual mapping
*/ */
@ -530,7 +653,6 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
ULONG Pte; ULONG Pte;
PULONG Pde; PULONG Pde;
PEPROCESS CurrentProcess = PsGetCurrentProcess(); PEPROCESS CurrentProcess = PsGetCurrentProcess();
BOOLEAN WasValid;
/* /*
* If we are setting a page in another process we need to be in its * If we are setting a page in another process we need to be in its
@ -571,7 +693,7 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
/* /*
* Decrement the reference count for this page table. * Decrement the reference count for this page table.
*/ */
if (Process != NULL && WasValid && if (Process != NULL &&
Process->AddressSpace.PageTableRefCountTable != NULL && Process->AddressSpace.PageTableRefCountTable != NULL &&
ADDR_TO_PAGE_TABLE(Address) < 768) ADDR_TO_PAGE_TABLE(Address) < 768)
{ {
@ -597,7 +719,7 @@ MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
/* /*
* Return some information to the caller * Return some information to the caller
*/ */
*SwapEntry = Pte >> 1; *SwapEntry = GET_SWAPENTRY_FROM_PTE(Pte);
} }
BOOLEAN BOOLEAN
@ -635,8 +757,8 @@ BOOLEAN MmIsPageTablePresent(PVOID PAddress)
NTSTATUS MmCreatePageTable(PVOID PAddress) NTSTATUS MmCreatePageTable(PVOID PAddress)
{ {
PULONG page_dir; PULONG page_dir;
ULONG Address = (ULONG)PAddress; ULONG_PTR Address = (ULONG)PAddress;
ULONG npage; ULONG_PTR npage;
DPRINT("MmGetPageEntry(Address %x)\n", Address); DPRINT("MmGetPageEntry(Address %x)\n", Address);
@ -651,13 +773,16 @@ NTSTATUS MmCreatePageTable(PVOID PAddress)
if ((*page_dir) == 0) if ((*page_dir) == 0)
{ {
NTSTATUS Status; NTSTATUS Status;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, (PVOID*)&npage); Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(Status); return(Status);
} }
VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(npage));
(*page_dir) = npage | 0x7; (*page_dir) = npage | 0x7;
memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE); memset((PVOID) PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE);
FLUSH_TLB; FLUSH_TLB;
} }
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -670,8 +795,8 @@ PULONG MmGetPageEntry(PVOID PAddress)
{ {
PULONG page_tlb; PULONG page_tlb;
PULONG page_dir; PULONG page_dir;
ULONG Address = (ULONG)PAddress; ULONG_PTR Address = (ULONG)PAddress;
ULONG npage; ULONG_PTR npage;
DPRINT("MmGetPageEntry(Address %x)\n", Address); DPRINT("MmGetPageEntry(Address %x)\n", Address);
@ -686,13 +811,14 @@ PULONG MmGetPageEntry(PVOID PAddress)
if ((*page_dir) == 0) if ((*page_dir) == 0)
{ {
NTSTATUS Status; NTSTATUS Status;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, (PVOID*)&npage); Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &npage);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("\n");
KeBugCheck(0); KeBugCheck(0);
} }
(*page_dir) = npage | 0x7; (*page_dir) = npage | 0x7;
memset((PVOID)PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE); memset((PVOID) PAGE_ROUND_DOWN(ADDR_TO_PTE(Address)), 0, PAGESIZE);
FLUSH_TLB; FLUSH_TLB;
} }
page_tlb = ADDR_TO_PTE(Address); page_tlb = ADDR_TO_PTE(Address);
@ -700,11 +826,14 @@ PULONG MmGetPageEntry(PVOID PAddress)
return(page_tlb); return(page_tlb);
} }
BOOLEAN MmIsPageDirty(PEPROCESS Process, PVOID Address)
BOOLEAN
MmIsPageDirty(PEPROCESS Process, PVOID Address)
{ {
return((MmGetPageEntryForProcess(Process, Address)) & PA_DIRTY); return((MmGetPageEntryForProcess(Process, Address)) & PA_DIRTY);
} }
BOOLEAN BOOLEAN
MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address) MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address)
{ {
@ -731,7 +860,10 @@ MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address)
return(Accessed); return(Accessed);
} }
VOID MmSetCleanPage(PEPROCESS Process, PVOID Address)
VOID
MmSetCleanPage(IN PEPROCESS Process,
IN PVOID Address)
{ {
PULONG PageEntry; PULONG PageEntry;
PEPROCESS CurrentProcess = PsGetCurrentProcess(); PEPROCESS CurrentProcess = PsGetCurrentProcess();
@ -749,7 +881,143 @@ VOID MmSetCleanPage(PEPROCESS Process, PVOID Address)
} }
} }
VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address)
BOOLEAN
MiPageState(IN PEPROCESS Process,
IN PVOID Address,
IN ULONG PageState)
{
PULONG PageEntry;
BOOLEAN Value;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
if (Process != NULL && Process != CurrentProcess)
{
KeAttachProcess(Process);
}
PageEntry = MmGetPageEntry(Address);
switch (PageState)
{
case PAGE_STATE_VALID:
Value = ((*PageEntry) & PA_PRESENT) != 0;
break;
case PAGE_STATE_PROTOTYPE:
Value = ((*PageEntry) & PA_PROTOTYPE) != 0;
break;
case PAGE_STATE_TRANSITION:
Value = ((*PageEntry) & PA_TRANSITION) != 0;
break;
case PAGE_STATE_DEMAND_ZERO:
Value = ((*PageEntry) & PA_DEMAND_ZERO) != 0;
break;
default:
DPRINT1("Unknown page state 0x%.08x\n", PageState);
KeBugCheck(0);
break;
}
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
return Value;
}
VOID
MiClearPageState(IN PEPROCESS Process,
IN PVOID Address,
IN ULONG PageState)
{
PULONG PageEntry;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
if (Process != NULL && Process != CurrentProcess)
{
KeAttachProcess(Process);
}
PageEntry = MmGetPageEntry(Address);
switch (PageState)
{
case PAGE_STATE_VALID:
(*PageEntry) = (*PageEntry) & (~PA_PRESENT);
break;
case PAGE_STATE_PROTOTYPE:
(*PageEntry) = (*PageEntry) & (~PA_PROTOTYPE);
break;
case PAGE_STATE_TRANSITION:
assertmsg(!((*PageEntry) & PA_PRESENT), ("Page 0x%.08x in transition is present\n", Address));
(*PageEntry) = (*PageEntry) & (~PA_TRANSITION);
break;
case PAGE_STATE_DEMAND_ZERO:
assertmsg(!((*PageEntry) & PA_PRESENT), ("Demand zero page 0x%.08x is present\n", Address));
(*PageEntry) = (*PageEntry) & (~PA_DEMAND_ZERO);
break;
default:
DPRINT1("Unknown page state 0x%.08x\n", PageState);
KeBugCheck(0);
break;
}
FLUSH_TLB;
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
}
VOID
MiSetPageState(IN PEPROCESS Process,
IN PVOID Address,
IN ULONG PageState)
{
PULONG PageEntry;
PEPROCESS CurrentProcess = PsGetCurrentProcess();
if (Process != NULL && Process != CurrentProcess)
{
KeAttachProcess(Process);
}
PageEntry = MmGetPageEntry(Address);
switch (PageState)
{
case PAGE_STATE_VALID:
(*PageEntry) = (*PageEntry) | PA_PRESENT;
break;
case PAGE_STATE_PROTOTYPE:
(*PageEntry) = (*PageEntry) | PA_PROTOTYPE;
break;
case PAGE_STATE_TRANSITION:
assertmsg(!((*PageEntry) & PA_PRESENT), ("Page 0x%.08x in transition is present\n", Address));
(*PageEntry) = (*PageEntry) | PA_TRANSITION;
break;
case PAGE_STATE_DEMAND_ZERO:
assertmsg(!((*PageEntry) & PA_PRESENT), ("Demand zero page 0x%.08x is present\n", Address));
(*PageEntry) = (*PageEntry) | PA_DEMAND_ZERO;
break;
default:
DPRINT1("Unknown page state 0x%.08x\n", PageState);
KeBugCheck(0);
break;
}
FLUSH_TLB;
if (Process != NULL && Process != CurrentProcess)
{
KeDetachProcess();
}
}
VOID
MmSetDirtyPage(IN PEPROCESS Process,
IN PVOID Address)
{ {
PULONG PageEntry; PULONG PageEntry;
PEPROCESS CurrentProcess = PsGetCurrentProcess(); PEPROCESS CurrentProcess = PsGetCurrentProcess();
@ -767,7 +1035,10 @@ VOID MmSetDirtyPage(PEPROCESS Process, PVOID Address)
} }
} }
VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address)
VOID
MmEnableVirtualMapping(IN PEPROCESS Process,
IN PVOID Address)
{ {
PULONG PageEntry; PULONG PageEntry;
PEPROCESS CurrentProcess = PsGetCurrentProcess(); PEPROCESS CurrentProcess = PsGetCurrentProcess();
@ -785,16 +1056,19 @@ VOID MmEnableVirtualMapping(PEPROCESS Process, PVOID Address)
} }
} }
BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address) BOOLEAN MmIsPagePresent(PEPROCESS Process, PVOID Address)
{ {
return((MmGetPageEntryForProcess1(Process, Address)) & PA_PRESENT); return((MmGetPageEntryForProcess1(Process, Address)) & PA_PRESENT);
} }
BOOLEAN MmIsPageSwapEntry(PEPROCESS Process, PVOID Address) BOOLEAN
MmIsPageSwapEntry(IN PEPROCESS Process,
IN PVOID Address)
{ {
ULONG Pte; ULONG Pte;
Pte = MmGetPageEntryForProcess1(Process, Address); Pte = MmGetPageEntryForProcess1(Process, Address);
return((!(Pte & PA_PRESENT)) && Pte != 0); return(IS_SWAPENTRY_PTE(Pte));
} }
NTSTATUS NTSTATUS
@ -817,12 +1091,12 @@ MmCreateVirtualMappingForKernel(PVOID Address,
CurrentProcess = NULL; CurrentProcess = NULL;
} }
if (Process == NULL && Address < (PVOID)KERNEL_BASE) if (Process == NULL && Address < (PVOID) KERNEL_BASE)
{ {
DPRINT1("No process\n"); DPRINT1("No process\n");
KeBugCheck(0); KeBugCheck(0);
} }
if (Process != NULL && Address >= (PVOID)KERNEL_BASE) if (Process != NULL && Address >= (PVOID) KERNEL_BASE)
{ {
DPRINT1("Setting kernel address with process context\n"); DPRINT1("Setting kernel address with process context\n");
KeBugCheck(0); KeBugCheck(0);
@ -849,7 +1123,7 @@ MmCreateVirtualMappingForKernel(PVOID Address,
} }
if (PAGE_MASK((*Pte)) != 0) if (PAGE_MASK((*Pte)) != 0)
{ {
MmMarkPageUnmapped((PVOID)PAGE_MASK((*Pte))); MmMarkPageUnmapped((ULONG_PTR) PAGE_MASK((*Pte)));
} }
*Pte = PhysicalAddress | Attributes; *Pte = PhysicalAddress | Attributes;
if (Process != NULL && if (Process != NULL &&
@ -872,9 +1146,9 @@ MmCreateVirtualMappingForKernel(PVOID Address,
} }
NTSTATUS NTSTATUS
MmCreatePageFileMapping(PEPROCESS Process, MmCreatePageFileMapping(IN PEPROCESS Process,
PVOID Address, IN PVOID Address,
SWAPENTRY SwapEntry) IN SWAPENTRY SwapEntry)
{ {
PEPROCESS CurrentProcess; PEPROCESS CurrentProcess;
PULONG Pte; PULONG Pte;
@ -889,12 +1163,12 @@ MmCreatePageFileMapping(PEPROCESS Process,
CurrentProcess = NULL; CurrentProcess = NULL;
} }
if (Process == NULL && Address < (PVOID)KERNEL_BASE) if (Process == NULL && Address < (PVOID) KERNEL_BASE)
{ {
DPRINT1("No process\n"); DPRINT1("No process\n");
KeBugCheck(0); KeBugCheck(0);
} }
if (Process != NULL && Address >= (PVOID)KERNEL_BASE) if (Process != NULL && Address >= (PVOID) KERNEL_BASE)
{ {
DPRINT1("Setting kernel address with process context\n"); DPRINT1("Setting kernel address with process context\n");
KeBugCheck(0); KeBugCheck(0);
@ -920,9 +1194,9 @@ MmCreatePageFileMapping(PEPROCESS Process,
} }
if (PAGE_MASK((*Pte)) != 0) if (PAGE_MASK((*Pte)) != 0)
{ {
MmMarkPageUnmapped((PVOID)PAGE_MASK((*Pte))); MmMarkPageUnmapped((ULONG_PTR) PAGE_MASK((*Pte)));
} }
*Pte = SwapEntry << 1; SET_SWAPENTRY_IN_PTE(*Pte, SwapEntry);
if (Process != NULL && if (Process != NULL &&
Process->AddressSpace.PageTableRefCountTable != NULL && Process->AddressSpace.PageTableRefCountTable != NULL &&
ADDR_TO_PAGE_TABLE(Address) < 768) ADDR_TO_PAGE_TABLE(Address) < 768)
@ -962,17 +1236,17 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
CurrentProcess = NULL; CurrentProcess = NULL;
} }
if (Process == NULL && Address < (PVOID)KERNEL_BASE) if (Process == NULL && Address < (PVOID) KERNEL_BASE)
{ {
DPRINT1("No process\n"); DPRINT1("No process\n");
KeBugCheck(0); KeBugCheck(0);
} }
if (Process != NULL && Address >= (PVOID)KERNEL_BASE) if (Process != NULL && Address >= (PVOID) KERNEL_BASE)
{ {
DPRINT1("Setting kernel address with process context\n"); DPRINT1("Setting kernel address with process context\n");
KeBugCheck(0); KeBugCheck(0);
} }
MmMarkPageMapped((PVOID)PhysicalAddress); MmMarkPageMapped(PhysicalAddress);
Attributes = ProtectToPTE(flProtect); Attributes = ProtectToPTE(flProtect);
if (!(Attributes & PA_PRESENT) && PhysicalAddress != 0) if (!(Attributes & PA_PRESENT) && PhysicalAddress != 0)
@ -1003,8 +1277,24 @@ MmCreateVirtualMappingUnsafe(PEPROCESS Process,
} }
if (PAGE_MASK((*Pte)) != 0) if (PAGE_MASK((*Pte)) != 0)
{ {
MmMarkPageUnmapped((PVOID)PAGE_MASK((*Pte))); MmMarkPageUnmapped((ULONG_PTR) PAGE_MASK((*Pte)));
} }
#ifdef DBG
if ((MiBreakPointAddressLow != NULL) && (MiBreakPointAddressHigh != NULL) &&
((PAGE_ROUND_DOWN(Address) >= PAGE_ROUND_DOWN(MiBreakPointAddressLow))
&& (PAGE_ROUND_DOWN(Address) < PAGE_ROUND_UP(MiBreakPointAddressHigh))))
{
DbgPrint("Changing PTE of virtual address 0x%.08x from PTE 0x%.08x\n", Address, *Pte);
MiDumpPTE(*Pte);
DbgPrint("To 0x%.08x\n", PhysicalAddress | Attributes);
MiDumpPTE(PhysicalAddress | Attributes);
//assert(FALSE);
}
#endif /* DBG */
*Pte = PhysicalAddress | Attributes; *Pte = PhysicalAddress | Attributes;
if (Process != NULL && if (Process != NULL &&
Process->AddressSpace.PageTableRefCountTable != NULL && Process->AddressSpace.PageTableRefCountTable != NULL &&
@ -1032,7 +1322,7 @@ MmCreateVirtualMapping(PEPROCESS Process,
ULONG PhysicalAddress, ULONG PhysicalAddress,
BOOLEAN MayWait) BOOLEAN MayWait)
{ {
if (!MmIsUsablePage((PVOID)PhysicalAddress)) if (!MmIsUsablePage(PhysicalAddress))
{ {
DPRINT1("Page at address %x not usable\n", PhysicalAddress); DPRINT1("Page at address %x not usable\n", PhysicalAddress);
KeBugCheck(0); KeBugCheck(0);
@ -1079,14 +1369,15 @@ MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
Process, Address, flProtect); Process, Address, flProtect);
Attributes = ProtectToPTE(flProtect); Attributes = ProtectToPTE(flProtect);
if (Process != CurrentProcess)
if ((Process != NULL) && (Process != CurrentProcess))
{ {
KeAttachProcess(Process); KeAttachProcess(Process);
} }
PageEntry = MmGetPageEntry(Address); PageEntry = MmGetPageEntry(Address);
(*PageEntry) = PAGE_MASK(*PageEntry) | Attributes; (*PageEntry) = PAGE_MASK(*PageEntry) | Attributes;
FLUSH_TLB; FLUSH_TLB;
if (Process != CurrentProcess) if ((Process != NULL) && (Process != CurrentProcess))
{ {
KeDetachProcess(); KeDetachProcess();
} }
@ -1106,6 +1397,8 @@ MmGetPhysicalAddress(PVOID vaddr)
Pte = *MmGetPageEntry(vaddr); Pte = *MmGetPageEntry(vaddr);
if (Pte & PA_PRESENT) if (Pte & PA_PRESENT)
{ {
VALIDATE_PHYSICAL_ADDRESS(PAGE_MASK(Pte));
p.QuadPart = PAGE_MASK(Pte); p.QuadPart = PAGE_MASK(Pte);
} }
else else
@ -1116,5 +1409,19 @@ MmGetPhysicalAddress(PVOID vaddr)
return p; return p;
} }
#ifdef DBG
VOID
MiDumpProcessPTE(IN PEPROCESS Process,
IN PVOID Address)
{
ULONG Value;
Value = MmGetPageEntryForProcess1(Process, Address);
MiDumpPTE(Value);
}
#endif /* DBG */
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: kmap.c,v 1.14 2002/01/01 00:21:56 dwelch Exp $ /* $Id: kmap.c,v 1.15 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -50,28 +50,29 @@ ExUnmapPage(PVOID Addr)
PVOID PVOID
ExAllocatePage(VOID) ExAllocatePage(VOID)
{ {
ULONG PhysPage; ULONG_PTR Page;
NTSTATUS Status; NTSTATUS Status;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, (PVOID*)&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(ULONG PhysPage) MiZeroPage(IN ULONG_PTR 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);
} }
memset(TempAddress, 0, PAGESIZE); memset(TempAddress, 0, PAGESIZE);
ExUnmapPage(TempAddress); ExUnmapPage(TempAddress);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -93,10 +94,10 @@ MiCopyFromUserPage(ULONG DestPhysPage, PVOID SourceAddress)
} }
PVOID PVOID
ExAllocatePageWithPhysPage(ULONG PhysPage) ExAllocatePageWithPhysPage(IN ULONG_PTR Page)
{ {
KIRQL oldlvl; KIRQL oldlvl;
ULONG addr; PVOID addr;
ULONG i; ULONG i;
NTSTATUS Status; NTSTATUS Status;
@ -107,11 +108,11 @@ ExAllocatePageWithPhysPage(ULONG PhysPage)
{ {
DPRINT("i %x\n",i); DPRINT("i %x\n",i);
AllocMap[i / 32] |= (1 << (i % 32)); AllocMap[i / 32] |= (1 << (i % 32));
addr = (ULONG)(NonPagedPoolBase + (i*PAGESIZE)); addr = (PVOID) (NonPagedPoolBase + (i*PAGESIZE));
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
(PVOID)addr, addr,
PAGE_READWRITE | PAGE_SYSTEM, PAGE_READWRITE | PAGE_SYSTEM,
PhysPage, Page,
FALSE); FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -119,7 +120,7 @@ ExAllocatePageWithPhysPage(ULONG PhysPage)
KeBugCheck(0); KeBugCheck(0);
} }
KeReleaseSpinLock(&AllocMapLock, oldlvl); KeReleaseSpinLock(&AllocMapLock, oldlvl);
return((PVOID)addr); return(addr);
} }
} }
KeReleaseSpinLock(&AllocMapLock, oldlvl); KeReleaseSpinLock(&AllocMapLock, oldlvl);

View file

@ -1,6 +1,6 @@
/* /*
* ReactOS kernel * ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team * Copyright (C) 1998-2002 ReactOS Team
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -27,6 +27,7 @@
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include <roscfg.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/mm.h> #include <internal/mm.h>
#include <internal/ps.h> #include <internal/ps.h>
@ -39,6 +40,13 @@
#define TAG_MAREA TAG('M', 'A', 'R', 'E') #define TAG_MAREA TAG('M', 'A', 'R', 'E')
#ifdef DBG
PVOID MiMemoryAreaBugCheckAddress = (PVOID) NULL;
#endif /* DBG */
/* Define to track memory area references */
//#define TRACK_MEMORY_AREA_REFERENCES
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead) VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead)
@ -61,8 +69,94 @@ VOID MmDumpMemoryAreas(PLIST_ENTRY ListHead)
DbgPrint("Finished MmDumpMemoryAreas()\n"); DbgPrint("Finished MmDumpMemoryAreas()\n");
} }
MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace, #ifdef DBG
PVOID Address)
VOID
MiValidateMemoryAreaPTEs(IN PMEMORY_AREA MemoryArea)
{
ULONG PteProtect;
ULONG i;
if (!MiInitialized)
return;
for (i = 0; i <= (MemoryArea->Length / PAGESIZE); i++)
{
if (MmIsPagePresent(MemoryArea->Process, MemoryArea->BaseAddress + (i * PAGESIZE)))
{
PteProtect = MmGetPageProtect(MemoryArea->Process, MemoryArea->BaseAddress + (i * PAGESIZE));
if (PteProtect != MemoryArea->Attributes)
{
if (MmIsCopyOnWriteMemoryArea(MemoryArea))
{
if ((PteProtect != PAGE_READONLY) && (PteProtect != PAGE_EXECUTE_READ))
{
DPRINT1("COW memory area attributes 0x%.08x\n", MemoryArea->Attributes);
DbgMmDumpProtection(MemoryArea->Attributes);
DPRINT1("PTE attributes 0x%.08x\n", PteProtect);
DbgMmDumpProtection(PteProtect);
assertmsg(FALSE, ("PTE attributes and memory area protection are different. Area 0x%.08x\n",
MemoryArea->BaseAddress));
}
}
else
{
DPRINT1("Memory area attributes 0x%.08x\n", MemoryArea->Attributes);
DbgMmDumpProtection(MemoryArea->Attributes);
DPRINT1("PTE attributes 0x%.08x\n", PteProtect);
DbgMmDumpProtection(PteProtect);
assertmsg(FALSE, ("PTE attributes and memory area protection are different. Area 0x%.08x\n",
MemoryArea->BaseAddress));
}
}
}
}
}
VOID
MiValidateMemoryArea(IN PMEMORY_AREA MemoryArea)
{
assertmsg(MemoryArea != NULL,
("No memory area can exist at 0x%.08x\n", MemoryArea));
assertmsg(MemoryArea->Magic == TAG_MAREA,
("Bad magic (0x%.08x) for memory area (0x%.08x). It should be 0x%.08x\n",
MemoryArea->Magic, MemoryArea, TAG_MAREA));
/* FIXME: Can cause page faults and deadlock on the address space lock */
//MiValidateMemoryAreaPTEs(MemoryArea);
}
#endif /* DBG */
VOID
MmApplyMemoryAreaProtection(IN PMEMORY_AREA MemoryArea)
{
ULONG i;
if (!MiInitialized)
return;
for (i = 0; i <= (MemoryArea->Length / PAGESIZE); i++)
{
if (MmIsPagePresent(MemoryArea->Process, MemoryArea->BaseAddress + (i * PAGESIZE)))
{
MmSetPageProtect(MemoryArea->Process,
MemoryArea->BaseAddress + (i * PAGESIZE),
MemoryArea->Attributes);
}
}
}
/*
* NOTE: If the memory area is found, then it is referenced. The caller must
* call MmCloseMemoryArea() after use.
*/
PMEMORY_AREA
MmOpenMemoryAreaByAddress(IN PMADDRESS_SPACE AddressSpace,
IN PVOID Address)
{ {
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
MEMORY_AREA* current; MEMORY_AREA* current;
@ -102,6 +196,7 @@ MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
(current->BaseAddress + current->Length) > Address) (current->BaseAddress + current->Length) > Address)
{ {
DPRINT("%s() = %x\n",__FUNCTION__,current); DPRINT("%s() = %x\n",__FUNCTION__,current);
MmReferenceMemoryArea(current);
return(current); return(current);
} }
if (current->BaseAddress > Address) if (current->BaseAddress > Address)
@ -116,6 +211,10 @@ MEMORY_AREA* MmOpenMemoryAreaByAddress(PMADDRESS_SPACE AddressSpace,
return(NULL); return(NULL);
} }
/*
* NOTE: If the memory area is found, then it is referenced. The caller must
* call MmCloseMemoryArea() after use.
*/
MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace, MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
PVOID Address, PVOID Address,
ULONG Length) ULONG Length)
@ -140,6 +239,7 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
{ {
DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n", DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
current); current);
MmReferenceMemoryArea(current);
return(current); return(current);
} }
Extent = (ULONG)current->BaseAddress + current->Length; Extent = (ULONG)current->BaseAddress + current->Length;
@ -148,6 +248,7 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
{ {
DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n", DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
current); current);
MmReferenceMemoryArea(current);
return(current); return(current);
} }
if (current->BaseAddress <= Address && if (current->BaseAddress <= Address &&
@ -155,6 +256,7 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
{ {
DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n", DPRINT("Finished MmOpenMemoryAreaByRegion() = %x\n",
current); current);
MmReferenceMemoryArea(current);
return(current); return(current);
} }
if (current->BaseAddress >= (Address+Length)) if (current->BaseAddress >= (Address+Length))
@ -168,6 +270,14 @@ MEMORY_AREA* MmOpenMemoryAreaByRegion(PMADDRESS_SPACE AddressSpace,
return(NULL); return(NULL);
} }
VOID
MmCloseMemoryArea(IN PMEMORY_AREA MemoryArea)
{
MmDereferenceMemoryArea(MemoryArea);
}
static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace, static VOID MmInsertMemoryArea(PMADDRESS_SPACE AddressSpace,
MEMORY_AREA* marea) MEMORY_AREA* marea)
{ {
@ -290,50 +400,75 @@ NTSTATUS MmInitMemoryAreas(VOID)
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
/* NOTE: The address space lock must be held when called */
NTSTATUS NTSTATUS
MmFreeMemoryArea(PMADDRESS_SPACE AddressSpace, MmFreeMemoryArea(IN PMADDRESS_SPACE AddressSpace,
PVOID BaseAddress, IN PVOID BaseAddress,
ULONG Length, IN ULONG Length,
VOID (*FreePage)(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, IN PFREE_MEMORY_AREA_PAGE_CALLBACK FreePage,
ULONG PhysAddr, SWAPENTRY SwapEntry, BOOLEAN Dirty), IN PVOID FreePageContext)
PVOID FreePageContext)
{ {
MEMORY_AREA* MemoryArea; MEMORY_AREA* MemoryArea;
ULONG i; ULONG i;
DPRINT("MmFreeMemoryArea(AddressSpace %x, BaseAddress %x, Length %x," DPRINT("MmFreeMemoryArea(AddressSpace %x, BaseAddress %x, Length %x, "
"FreePageContext %d)\n",AddressSpace,BaseAddress,Length,FreePageContext); "FreePageContext %d)\n",AddressSpace,BaseAddress,Length,FreePageContext);
MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, MemoryArea = MmOpenMemoryAreaByAddress(AddressSpace, BaseAddress);
BaseAddress); if (MemoryArea == NULL)
if (MemoryArea == NULL) {
{ assertmsg(FALSE, ("Freeing non-existant memory area at 0x%.08x\n", BaseAddress));
KeBugCheck(0); return(STATUS_UNSUCCESSFUL);
return(STATUS_UNSUCCESSFUL); }
}
MmCloseMemoryArea(MemoryArea);
InterlockedDecrement(&MemoryArea->ReferenceCount);
#if 0
assertmsg(MemoryArea->ReferenceCount == 0,
("Memory area at address 0x%.08x has %d outstanding references\n",
BaseAddress, MemoryArea->ReferenceCount));
#endif
for (i=0; i<(PAGE_ROUND_UP(MemoryArea->Length)/PAGESIZE); i++) for (i=0; i<(PAGE_ROUND_UP(MemoryArea->Length)/PAGESIZE); i++)
{ {
ULONG PhysAddr = 0; ULONG_PTR PhysicalPage = 0;
BOOL Dirty; BOOLEAN Dirty = FALSE;
SWAPENTRY SwapEntry = 0; SWAPENTRY SwapEntry = 0;
PVOID VirtualPage = NULL;
if (MmIsPageSwapEntry(AddressSpace->Process, VirtualPage = MemoryArea->BaseAddress + (i * PAGESIZE);
MemoryArea->BaseAddress + (i * PAGESIZE)))
#ifdef DBG
if ((MiMemoryAreaBugCheckAddress != NULL)
&& ((MiMemoryAreaBugCheckAddress >= VirtualPage)
&& MiMemoryAreaBugCheckAddress < VirtualPage + PAGESIZE))
{
assertmsg(FALSE, ("VirtualPage 0x%.08x MiMemoryAreaBugCheckAddress 0x%.08x \n",
VirtualPage));
}
#endif
if (FreePage != NULL)
{
FreePage(TRUE, FreePageContext, MemoryArea,
VirtualPage, 0, 0, FALSE);
}
if (MmIsPageSwapEntry(AddressSpace->Process, VirtualPage))
{ {
MmDeletePageFileMapping(AddressSpace->Process, MmDeletePageFileMapping(AddressSpace->Process,
MemoryArea->BaseAddress + (i * PAGESIZE), VirtualPage,
&SwapEntry); &SwapEntry);
} }
else else
{ {
MmDeleteVirtualMapping(AddressSpace->Process, MmDeleteVirtualMapping(AddressSpace->Process,
MemoryArea->BaseAddress + (i*PAGESIZE), VirtualPage,
FALSE, &Dirty, &PhysAddr); FALSE, &Dirty, &PhysicalPage);
} }
if (FreePage != NULL) if (FreePage != NULL)
{ {
FreePage(FreePageContext, MemoryArea, FreePage(FALSE, FreePageContext, MemoryArea,
MemoryArea->BaseAddress + (i * PAGESIZE), PhysAddr, SwapEntry, Dirty); VirtualPage, PhysicalPage, SwapEntry, Dirty);
} }
} }
@ -364,6 +499,7 @@ PMEMORY_AREA MmSplitMemoryArea(PEPROCESS Process,
Result->Length = Length; Result->Length = Length;
Result->Attributes = NewAttributes; Result->Attributes = NewAttributes;
Result->LockCount = 0; Result->LockCount = 0;
Result->ReferenceCount = 1;
Result->Process = Process; Result->Process = Process;
if (BaseAddress == OriginalMemoryArea->BaseAddress) if (BaseAddress == OriginalMemoryArea->BaseAddress)
@ -394,14 +530,15 @@ PMEMORY_AREA MmSplitMemoryArea(PEPROCESS Process,
return(Split); return(Split);
} }
NTSTATUS MmCreateMemoryArea(PEPROCESS Process, NTSTATUS
PMADDRESS_SPACE AddressSpace, MmCreateMemoryArea(IN PEPROCESS Process,
ULONG Type, IN PMADDRESS_SPACE AddressSpace,
PVOID* BaseAddress, IN ULONG Type,
ULONG Length, IN OUT PVOID* BaseAddress,
ULONG Attributes, IN ULONG Length,
MEMORY_AREA** Result, IN ULONG Attributes,
BOOL FixedAddress) OUT PMEMORY_AREA* Result,
IN BOOLEAN FixedAddress)
/* /*
* FUNCTION: Create a memory area * FUNCTION: Create a memory area
* ARGUMENTS: * ARGUMENTS:
@ -411,10 +548,13 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
* Length = Length to allocate * Length = Length to allocate
* Attributes = Protection attributes for the memory area * Attributes = Protection attributes for the memory area
* Result = Receives a pointer to the memory area on exit * Result = Receives a pointer to the memory area on exit
* FixedAddress = Wether the memory area must be based at BaseAddress or not
* RETURNS: Status * RETURNS: Status
* NOTES: Lock the address space before calling this function * NOTES: Lock the address space before calling this function
*/ */
{ {
PMEMORY_AREA MemoryArea;
DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %x," DPRINT("MmCreateMemoryArea(Type %d, BaseAddress %x,"
"*BaseAddress %x, Length %x, Attributes %x, Result %x)\n", "*BaseAddress %x, Length %x, Attributes %x, Result %x)\n",
Type,BaseAddress,*BaseAddress,Length,Attributes,Result); Type,BaseAddress,*BaseAddress,Length,Attributes,Result);
@ -433,27 +573,90 @@ NTSTATUS MmCreateMemoryArea(PEPROCESS Process,
else else
{ {
(*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress)); (*BaseAddress) = (PVOID)PAGE_ROUND_DOWN((*BaseAddress));
if (MmOpenMemoryAreaByRegion(AddressSpace, MemoryArea = MmOpenMemoryAreaByRegion(AddressSpace, *BaseAddress, Length);
*BaseAddress, if (MemoryArea)
Length)!=NULL)
{ {
MmCloseMemoryArea(MemoryArea);
DPRINT("Memory area already occupied\n"); DPRINT("Memory area already occupied\n");
return(STATUS_CONFLICTING_ADDRESSES); return(STATUS_CONFLICTING_ADDRESSES);
} }
} }
DPRINT("MmCreateMemoryArea(*BaseAddress %x)\n", *BaseAddress);
*Result = ExAllocatePoolWithTag(NonPagedPool, sizeof(MEMORY_AREA), *Result = ExAllocatePoolWithTag(NonPagedPool, sizeof(MEMORY_AREA),
TAG_MAREA); TAG_MAREA);
RtlZeroMemory(*Result,sizeof(MEMORY_AREA)); RtlZeroMemory(*Result,sizeof(MEMORY_AREA));
SET_MAGIC(*Result, TAG_MAREA)
(*Result)->Type = Type; (*Result)->Type = Type;
(*Result)->BaseAddress = *BaseAddress; (*Result)->BaseAddress = *BaseAddress;
(*Result)->Length = Length; (*Result)->Length = Length;
(*Result)->Attributes = Attributes; (*Result)->Attributes = Attributes;
(*Result)->LockCount = 0; (*Result)->LockCount = 0;
(*Result)->ReferenceCount = 1;
(*Result)->Process = Process; (*Result)->Process = Process;
MmApplyMemoryAreaProtection(*Result);
MmInsertMemoryArea(AddressSpace, *Result); MmInsertMemoryArea(AddressSpace, *Result);
DPRINT("MmCreateMemoryArea() succeeded\n"); DPRINT("MmCreateMemoryArea() succeeded\n");
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
#ifdef DBG
VOID
MiReferenceMemoryArea(IN PMEMORY_AREA MemoryArea,
IN LPSTR FileName,
IN ULONG LineNumber)
{
VALIDATE_MEMORY_AREA(MemoryArea);
InterlockedIncrement(&MemoryArea->ReferenceCount);
#ifdef TRACK_MEMORY_AREA_REFERENCES
DbgPrint("(0x%.08x)(%s:%d) Referencing memory area 0x%.08x (New ref.count %d)\n",
KeGetCurrentThread(), FileName, LineNumber,
MemoryArea->BaseAddress,
MemoryArea->ReferenceCount);
#endif /* TRACK_MEMORY_AREA_REFERENCES */
}
VOID
MiDereferenceMemoryArea(IN PMEMORY_AREA MemoryArea,
IN LPSTR FileName,
IN ULONG LineNumber)
{
VALIDATE_MEMORY_AREA(MemoryArea);
InterlockedDecrement(&MemoryArea->ReferenceCount);
#ifdef TRACK_MEMORY_AREA_REFERENCES
DbgPrint("(0x%.08x)(%s:%d) Dereferencing memory area 0x%.08x (New ref.count %d)\n",
KeGetCurrentThread(), FileName, LineNumber,
MemoryArea->BaseAddress,
MemoryArea->ReferenceCount);
#endif /* TRACK_MEMORY_AREA_REFERENCES */
assertmsg(MemoryArea->ReferenceCount > 0,
("No outstanding references on memory area (0x%.08x)\n", MemoryArea));
}
#else /* !DBG */
VOID
MiReferenceMemoryArea(IN PMEMORY_AREA MemoryArea)
{
InterlockedIncrement(&MemoryArea->ReferenceCount);
}
VOID
MiDereferenceMemoryArea(IN PMEMORY_AREA MemoryArea)
{
InterlockedDecrement(&MemoryArea->ReferenceCount);
}
#endif /* !DBG */

View file

@ -1,4 +1,4 @@
/* $Id: mdl.c,v 1.37 2002/05/07 22:35:02 hbirr Exp $ /* $Id: mdl.c,v 1.38 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -28,11 +28,11 @@
PVOID PVOID
MmGetMdlPageAddress(PMDL Mdl, PVOID Offset) MmGetMdlPageAddress(PMDL Mdl, PVOID Offset)
{ {
PULONG MdlPages; PULONG_PTR MdlPages;
MdlPages = (PULONG)(Mdl + 1); MdlPages = (PULONG_PTR)(Mdl + 1);
return((PVOID)MdlPages[((ULONG)Offset) / PAGESIZE]); return((PVOID) MdlPages[((ULONG_PTR) Offset) / PAGESIZE]);
} }
VOID STDCALL VOID STDCALL
@ -46,8 +46,8 @@ MmUnlockPages(PMDL Mdl)
* MDL is updated * MDL is updated
*/ */
{ {
PULONG_PTR MdlPages;
ULONG i; ULONG i;
PULONG MdlPages;
/* /*
* FIXME: I don't know whether this right, but it looks sensible * FIXME: I don't know whether this right, but it looks sensible
@ -66,11 +66,11 @@ MmUnlockPages(PMDL Mdl)
return; return;
} }
MdlPages = (PULONG)(Mdl + 1); MdlPages = (PULONG_PTR) (Mdl + 1);
for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGESIZE); i++) for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGESIZE); i++)
{ {
MmUnlockPage((PVOID)MdlPages[i]); MmUnlockPage(MdlPages[i]);
MmDereferencePage((PVOID)MdlPages[i]); MmDereferencePage(MdlPages[i]);
} }
Mdl->MdlFlags = Mdl->MdlFlags & (~MDL_PAGES_LOCKED); Mdl->MdlFlags = Mdl->MdlFlags & (~MDL_PAGES_LOCKED);
} }
@ -88,7 +88,7 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
{ {
PVOID Base; PVOID Base;
ULONG i; ULONG i;
PULONG MdlPages; PULONG_PTR MdlPages;
MEMORY_AREA* Result; MEMORY_AREA* Result;
NTSTATUS Status; NTSTATUS Status;
@ -103,18 +103,18 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
Base = NULL; Base = NULL;
Status = MmCreateMemoryArea(NULL, Status = MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(), MmGetKernelAddressSpace(),
MEMORY_AREA_MDL_MAPPING, MEMORY_AREA_MDL_MAPPING,
&Base, &Base,
Mdl->ByteCount + Mdl->ByteOffset, Mdl->ByteCount + Mdl->ByteOffset,
0, PAGE_READWRITE,
&Result, &Result,
FALSE); FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
MmUnlockAddressSpace(MmGetKernelAddressSpace()); MmUnlockAddressSpace(MmGetKernelAddressSpace());
KeBugCheck(0); KeBugCheck(0);
return(STATUS_SUCCESS); return(NULL);
} }
MmUnlockAddressSpace(MmGetKernelAddressSpace()); MmUnlockAddressSpace(MmGetKernelAddressSpace());
@ -122,8 +122,8 @@ PVOID STDCALL MmMapLockedPages(PMDL Mdl, KPROCESSOR_MODE AccessMode)
for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGESIZE); i++) for (i=0; i<(PAGE_ROUND_UP(Mdl->ByteCount+Mdl->ByteOffset)/PAGESIZE); i++)
{ {
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
(PVOID)((ULONG)Base+(i*PAGESIZE)), (PVOID)((ULONG_PTR) Base+(i*PAGESIZE)),
PAGE_READWRITE, Result->Attributes,
MdlPages[i], MdlPages[i],
TRUE); TRUE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -171,15 +171,16 @@ MmUnmapLockedPages(PVOID BaseAddress, PMDL Mdl)
VOID VOID
MmBuildMdlFromPages(PMDL Mdl, PULONG Pages) MmBuildMdlFromPages(IN PMDL Mdl,
IN PULONG_PTR Pages)
{ {
ULONG i; ULONG i;
PULONG MdlPages; PULONG_PTR MdlPages;
Mdl->MdlFlags = Mdl->MdlFlags | Mdl->MdlFlags = Mdl->MdlFlags |
(MDL_PAGES_LOCKED | MDL_IO_PAGE_READ); (MDL_PAGES_LOCKED | MDL_IO_PAGE_READ);
MdlPages = (PULONG)(Mdl + 1); MdlPages = (PULONG_PTR) (Mdl + 1);
for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGESIZE);i++) for (i=0;i<(PAGE_ROUND_UP(Mdl->ByteOffset+Mdl->ByteCount)/PAGESIZE);i++)
{ {
@ -251,15 +252,15 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
{ {
for (j = 0; j < i; j++) for (j = 0; j < i; j++)
{ {
MmUnlockPage((PVOID)MdlPages[j]); MmUnlockPage((ULONG_PTR) MdlPages[j]);
MmDereferencePage((PVOID)MdlPages[j]); MmDereferencePage((ULONG_PTR) MdlPages[j]);
} }
ExRaiseStatus(Status); ExRaiseStatus(Status);
} }
} }
else else
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
if ((Operation == IoWriteAccess || Operation == IoModifyAccess) && if ((Operation == IoWriteAccess || Operation == IoModifyAccess) &&
(!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE))) (!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE)))
@ -269,14 +270,14 @@ VOID STDCALL MmProbeAndLockPages (PMDL Mdl,
{ {
for (j = 0; j < i; j++) for (j = 0; j < i; j++)
{ {
MmUnlockPage((PVOID)MdlPages[j]); MmUnlockPage((ULONG_PTR) MdlPages[j]);
MmDereferencePage((PVOID)MdlPages[j]); MmDereferencePage((ULONG_PTR) MdlPages[j]);
} }
ExRaiseStatus(Status); ExRaiseStatus(Status);
} }
} }
MdlPages[i] = MmGetPhysicalAddressForProcess(NULL, Address); MdlPages[i] = MmGetPhysicalAddressForProcess(NULL, Address);
MmReferencePage((PVOID)MdlPages[i]); MmReferencePage((ULONG_PTR) MdlPages[i]);
} }
MmUnlockAddressSpace(&Mdl->Process->AddressSpace); MmUnlockAddressSpace(&Mdl->Process->AddressSpace);
if (Mdl->Process != CurrentProcess) if (Mdl->Process != CurrentProcess)
@ -370,12 +371,3 @@ MmMapMemoryDumpMdl (PVOID Unknown0)
} }
/* EOF */ /* EOF */

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.54 2002/01/23 23:39:26 chorns Exp $ /* $Id: mm.c,v 1.55 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -48,6 +48,45 @@ extern PVOID MmSharedDataPagePhysicalAddress;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
#ifdef DBG
VOID
DbgMmDumpProtection(IN ULONG Value)
{
if (Value & PAGE_NOACCESS)
DbgPrint("No access\n");
if (Value & PAGE_GUARD)
DbgPrint("Guard\n");
if (Value & PAGE_READWRITE)
DbgPrint("Read/Write\n");
if (Value & PAGE_EXECUTE_READWRITE)
DbgPrint("Execute/Read/Write\n");
if (Value & PAGE_READONLY)
DbgPrint("Read only\n");
if (Value & PAGE_EXECUTE)
DbgPrint("Execute\n");
if (Value & PAGE_EXECUTE_READ)
DbgPrint("Execute/Read\n");
if (Value & PAGE_SYSTEM)
DbgPrint("System\n");
if (Value & PAGE_NOCACHE)
DbgPrint("No cache\n");
if (Value & PAGE_WRITETHROUGH)
DbgPrint("No cache\n");
}
#endif /* DBG */
NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea) NTSTATUS MmReleaseMemoryArea(PEPROCESS Process, PMEMORY_AREA Marea)
{ {
NTSTATUS Status; NTSTATUS Status;
@ -245,7 +284,7 @@ NTSTATUS MmAccessFault(KPROCESSOR_MODE Mode,
NTSTATUS MmCommitPagedPoolAddress(PVOID Address) NTSTATUS MmCommitPagedPoolAddress(PVOID Address)
{ {
NTSTATUS Status; NTSTATUS Status;
PVOID AllocatedPage; ULONG_PTR AllocatedPage;
Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage); Status = MmRequestPageMemoryConsumer(MC_PPOOL, FALSE, &AllocatedPage);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {

View file

@ -1,4 +1,4 @@
/* $Id: mminit.c,v 1.31 2002/04/26 13:11:55 ekohl Exp $ /* $Id: mminit.c,v 1.32 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -25,11 +25,6 @@
/* GLOBALS *****************************************************************/ /* GLOBALS *****************************************************************/
/*
* Size of extended memory (kb) (fixed for now)
*/
#define EXTENDED_MEMORY_SIZE (3*1024*1024)
/* /*
* Compiler defined symbols * Compiler defined symbols
*/ */
@ -48,7 +43,9 @@ static MEMORY_AREA* kernel_pool_desc = NULL;
static MEMORY_AREA* kernel_shared_data_desc = NULL; static MEMORY_AREA* kernel_shared_data_desc = NULL;
static MEMORY_AREA* MiPagedPoolDescriptor = NULL; static MEMORY_AREA* MiPagedPoolDescriptor = NULL;
PVOID MmSharedDataPagePhysicalAddress = NULL; ULONG_PTR MmSharedDataPagePhysicalAddress = 0;
BOOLEAN MiInitialized = FALSE;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
@ -62,18 +59,14 @@ MM_SYSTEM_SIZE STDCALL MmQuerySystemSize(VOID)
return(MmSystemSize); return(MmSystemSize);
} }
VOID MiShutdownMemoryManager(VOID) VOID
MiShutdownMemoryManager()
{ {
} }
VOID MmInitVirtualMemory(ULONG LastKernelAddress, VOID
ULONG KernelLength) MmInitVirtualMemory(IN ULONG LastKernelAddress,
/* IN ULONG KernelLength)
* FUNCTION: Intialize the memory areas list
* ARGUMENTS:
* bp = Pointer to the boot parameters
* kernel_len = Length of the kernel
*/
{ {
PVOID BaseAddress; PVOID BaseAddress;
ULONG Length; ULONG Length;
@ -86,7 +79,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress); LastKernelAddress = PAGE_ROUND_UP(LastKernelAddress);
MmInitMemoryAreas(); MmInitMemoryAreas();
ExInitNonPagedPool(LastKernelAddress + PAGESIZE); ExInitNonPagedPool((PVOID) (LastKernelAddress + PAGESIZE));
/* /*
* Setup the system area descriptor list * Setup the system area descriptor list
@ -183,7 +176,7 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
(PVOID)KI_USER_SHARED_DATA, (PVOID)KI_USER_SHARED_DATA,
PAGE_READWRITE, PAGE_READWRITE,
(ULONG)MmSharedDataPagePhysicalAddress, MmSharedDataPagePhysicalAddress,
TRUE); TRUE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -198,6 +191,9 @@ VOID MmInitVirtualMemory(ULONG LastKernelAddress,
MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory); MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory);
} }
/*
* Called at DISPATCH_LEVEL
*/
VOID MmInit1(ULONG FirstKrnlPhysAddr, VOID MmInit1(ULONG FirstKrnlPhysAddr,
ULONG LastKrnlPhysAddr, ULONG LastKrnlPhysAddr,
ULONG LastKernelAddress, ULONG LastKernelAddress,
@ -293,6 +289,7 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr,
#ifdef BIOS_MEM_FIX #ifdef BIOS_MEM_FIX
MmStats.NrTotalPages += 16; MmStats.NrTotalPages += 16;
#endif #endif
DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGESIZE) / 1024); DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGESIZE) / 1024);
LastKernelAddress = (ULONG)MmInitializePageList( LastKernelAddress = (ULONG)MmInitializePageList(
@ -338,20 +335,28 @@ VOID MmInit1(ULONG FirstKrnlPhysAddr,
* Intialize memory areas * Intialize memory areas
*/ */
MmInitVirtualMemory(LastKernelAddress, kernel_len); MmInitVirtualMemory(LastKernelAddress, kernel_len);
MiInitialized = TRUE;
} }
/*
* Called at DISPATCH_LEVEL
*/
VOID MmInit2(VOID) VOID MmInit2(VOID)
{ {
MmInitSectionImplementation(); MmInitSectionImplementation();
MmInitPagingFile(); MmInitPagingFile();
} }
/*
* Called at PASSIVE_LEVEL
*/
VOID MmInit3(VOID) VOID MmInit3(VOID)
{ {
MmInitPagerThread(); MmCreatePhysicalMemorySection();
MmCreatePhysicalMemorySection(); MmInitializeRmapList();
MmInitializeRmapList(); MmInitPagerThread();
/* FIXME: Read parameters from memory */ /* FIXME: Read parameters from memory */
} }

View file

@ -1,4 +1,4 @@
/* $Id: ncache.c,v 1.15 2002/01/01 00:21:56 dwelch Exp $ /* $Id: ncache.c,v 1.16 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -73,7 +73,7 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
PAGE_WRITETHROUGH; PAGE_WRITETHROUGH;
for (i = 0; i <= (NumberOfBytes / PAGESIZE); i++) for (i = 0; i <= (NumberOfBytes / PAGESIZE); i++)
{ {
PVOID NPage; ULONG_PTR NPage;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &NPage); Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &NPage);
MmCreateVirtualMapping (NULL, MmCreateVirtualMapping (NULL,
@ -85,14 +85,22 @@ MmAllocateNonCachedMemory(IN ULONG NumberOfBytes)
return ((PVOID)Result); return ((PVOID)Result);
} }
VOID STATIC VOID
MmFreeNonCachedPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr, MmFreeNonCachedPage(IN BOOLEAN Before,
SWAPENTRY SwapEntry, BOOLEAN Dirty) IN PVOID Context,
IN PMEMORY_AREA MemoryArea,
IN PVOID Address,
IN ULONG_PTR PhysicalAddress,
IN SWAPENTRY SwapEntry,
IN BOOLEAN Dirty)
{ {
assert(SwapEntry == 0); if (!Before)
if (PhysAddr != 0)
{ {
MmDereferencePage((PVOID)PhysAddr); assert(SwapEntry == 0);
if (PhysicalAddress != 0)
{
MmDereferencePage(PhysicalAddress);
}
} }
} }

View file

@ -1,4 +1,4 @@
/* $Id: npool.c,v 1.55 2002/01/01 05:09:50 dwelch Exp $ /* $Id: npool.c,v 1.56 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -78,7 +78,7 @@ ExFreeWholePageBlock(PVOID Addr);
/* /*
* Memory managment initalized symbol for the base of the pool * Memory managment initalized symbol for the base of the pool
*/ */
static unsigned int kernel_pool_base = 0; static PVOID kernel_pool_base = 0;
/* /*
* Head of the list of free blocks * Head of the list of free blocks
@ -222,7 +222,7 @@ MiAddToTagHashTable(BLOCK_HDR* block)
#endif /* TAG_STATISTICS_TRACKING */ #endif /* TAG_STATISTICS_TRACKING */
VOID VOID
ExInitNonPagedPool(ULONG BaseAddress) ExInitNonPagedPool(IN PVOID BaseAddress)
{ {
kernel_pool_base = BaseAddress; kernel_pool_base = BaseAddress;
KeInitializeSpinLock(&MmNpoolLock); KeInitializeSpinLock(&MmNpoolLock);
@ -390,13 +390,13 @@ static void validate_free_list(void)
KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
} }
if (base_addr < (kernel_pool_base) || if (base_addr < (ULONG_PTR) (kernel_pool_base) ||
(base_addr+current->Size) > (kernel_pool_base)+NONPAGED_POOL_SIZE) (base_addr+current->Size) > (ULONG_PTR) (kernel_pool_base)+NONPAGED_POOL_SIZE)
{ {
DbgPrint("Block %x found outside pool area\n",current); DbgPrint("Block %x found outside pool area\n",current);
DbgPrint("Size %d\n",current->Size); DbgPrint("Size %d\n",current->Size);
DbgPrint("Limits are %x %x\n",kernel_pool_base, DbgPrint("Limits are %x %x\n", kernel_pool_base,
kernel_pool_base+NONPAGED_POOL_SIZE); (ULONG_PTR) kernel_pool_base + NONPAGED_POOL_SIZE);
KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
} }
blocks_seen++; blocks_seen++;
@ -442,9 +442,9 @@ static void validate_used_list(void)
current); current);
KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT); KeBugCheck(KBUG_POOL_FREE_LIST_CORRUPT);
} }
if (base_addr < (kernel_pool_base) || if (base_addr < (ULONG_PTR) (kernel_pool_base) ||
(base_addr+current->Size) > (base_addr+current->Size) >
(kernel_pool_base)+NONPAGED_POOL_SIZE) (ULONG_PTR) (kernel_pool_base) + NONPAGED_POOL_SIZE)
{ {
DbgPrint("Block %x found outside pool area\n",current); DbgPrint("Block %x found outside pool area\n",current);
for(;;); for(;;);
@ -567,8 +567,8 @@ free_pages(BLOCK_HDR* blk)
ULONG end; ULONG end;
ULONG i; ULONG i;
start = (ULONG)blk; start = (ULONG_PTR) blk;
end = (ULONG)blk + sizeof(BLOCK_HDR) + blk->Size; end = (ULONG_PTR) blk + sizeof(BLOCK_HDR) + blk->Size;
/* /*
* If the block doesn't contain a whole page then there is nothing to do * If the block doesn't contain a whole page then there is nothing to do
@ -699,14 +699,15 @@ static BLOCK_HDR* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller)
NTSTATUS Status; NTSTATUS Status;
KIRQL oldIrql; KIRQL oldIrql;
start = (ULONG)MiAllocNonPagedPoolRegion(nr_pages); start = (ULONG_PTR) MiAllocNonPagedPoolRegion(nr_pages);
DPRINT("growing heap for block size %d, ",size); DPRINT("growing heap for block size %d, ",size);
DPRINT("start %x\n",start); DPRINT("start %x\n",start);
for (i=0;i<nr_pages;i++) for (i=0;i<nr_pages;i++)
{ {
PVOID Page; ULONG_PTR Page;
/* FIXME: Check whether we can really wait here. */ /* FIXME: Check whether we can really wait here. */
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page); Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -717,7 +718,7 @@ static BLOCK_HDR* grow_kernel_pool(unsigned int size, ULONG Tag, PVOID Caller)
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
(PVOID)(start + (i*PAGESIZE)), (PVOID)(start + (i*PAGESIZE)),
PAGE_READWRITE, PAGE_READWRITE,
(ULONG)Page, Page,
FALSE); FALSE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -853,9 +854,9 @@ VOID STDCALL ExFreeNonPagedPool (PVOID block)
return; return;
} }
DPRINT("freeing block %x\n",blk); DPRINT("freeing block %x\n",block);
POOL_TRACE("ExFreePool(block %x), size %d, caller %x\n",block,blk->size, POOL_TRACE("ExFreePool(block %x), size %d, caller %x\n",block,block->size,
((PULONG)&block)[-1]); ((PULONG)&block)[-1]);
KeAcquireSpinLock(&MmNpoolLock, &oldIrql); KeAcquireSpinLock(&MmNpoolLock, &oldIrql);
@ -1007,7 +1008,7 @@ PVOID STDCALL
ExAllocateWholePageBlock(ULONG UserSize) ExAllocateWholePageBlock(ULONG UserSize)
{ {
PVOID Address; PVOID Address;
PVOID Page; ULONG_PTR Page;
ULONG i; ULONG i;
ULONG Size; ULONG Size;
ULONG NrPages; ULONG NrPages;
@ -1020,19 +1021,19 @@ ExAllocateWholePageBlock(ULONG UserSize)
for (i = 0; i < NrPages; i++) for (i = 0; i < NrPages; i++)
{ {
Page = MmAllocPage(MC_NPPOOL, 0); Page = MmAllocPage(MC_NPPOOL, 0);
if (Page == NULL) if (Page == 0)
{ {
KeBugCheck(0); KeBugCheck(0);
} }
MmCreateVirtualMapping(NULL, MmCreateVirtualMapping(NULL,
Address + (i * PAGESIZE), Address + (i * PAGESIZE),
PAGE_READWRITE | PAGE_SYSTEM, PAGE_READWRITE | PAGE_SYSTEM,
(ULONG)Page, Page,
TRUE); TRUE);
} }
*((PULONG)((ULONG)Address + (NrPages * PAGESIZE) - Size)) = NrPages; *((PULONG)((ULONG_PTR) Address + (NrPages * PAGESIZE) - Size)) = NrPages;
return((PVOID)((ULONG)Address + (NrPages * PAGESIZE) - UserSize)); return((PVOID)((ULONG_PTR) Address + (NrPages * PAGESIZE) - UserSize));
} }
VOID STDCALL VOID STDCALL
@ -1040,14 +1041,14 @@ ExFreeWholePageBlock(PVOID Addr)
{ {
ULONG NrPages; ULONG NrPages;
if ((ULONG)Addr < kernel_pool_base || if ((ULONG_PTR)Addr < (ULONG_PTR) kernel_pool_base ||
(ULONG)Addr >= (kernel_pool_base + NONPAGED_POOL_SIZE)) (ULONG_PTR)Addr >= ((ULONG_PTR) kernel_pool_base + NONPAGED_POOL_SIZE))
{ {
DbgPrint("Block %x found outside pool area\n", Addr); DbgPrint("Block %x found outside pool area\n", Addr);
KeBugCheck(0); KeBugCheck(0);
} }
NrPages = *(PULONG)((ULONG)Addr - sizeof(ULONG)); NrPages = *(PULONG)((ULONG_PTR) Addr - sizeof(ULONG));
MiFreeNonPagedPoolRegion((PVOID)PAGE_ROUND_DOWN((ULONG)Addr), NrPages, TRUE); MiFreeNonPagedPoolRegion((PVOID)PAGE_ROUND_DOWN((ULONG_PTR) Addr), NrPages, TRUE);
} }
#endif /* WHOLE_PAGE_ALLOCATIONS */ #endif /* WHOLE_PAGE_ALLOCATIONS */

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.18 2002/03/18 16:15:08 ekohl Exp $ /* $Id: pagefile.c,v 1.19 2002/05/13 18:10:40 chorns Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/pagefile.c * FILE: ntoskrnl/mm/pagefile.c
@ -98,12 +98,40 @@ static BYTE MmCoreDumpHeader[PAGESIZE];
/* /*
* Translate between a swap entry and a file and offset pair. * Translate between a swap entry and a file and offset pair.
*/ */
#define FILE_FROM_ENTRY(i) ((i) >> 24) #define PTE_SWAP_FILE_MASK 0x0f000000
#define PTE_SWAP_FILE_BIT 24
#define FILE_FROM_ENTRY(i) (((i) & PTE_SWAP_FILE_MASK) >> PTE_SWAP_FILE_BIT)
#define OFFSET_FROM_ENTRY(i) (((i) & 0xffffff) - 1) #define OFFSET_FROM_ENTRY(i) (((i) & 0xffffff) - 1)
#define ENTRY_FROM_FILE_OFFSET(i, j) (((i) << 24) | ((j) + 1)) #define ENTRY_FROM_FILE_OFFSET(i, j) (((i) << PTE_SWAP_FILE_BIT) | ((j) + 1))
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
#ifdef DBG
VOID
MiValidateSwapEntry(SWAPENTRY Entry)
{
ULONG i;
ULONG off;
if (Entry != 0)
{
DPRINT("MiValidateSwapEntry(SwapEntry 0x%.08x)\n", Entry);
i = FILE_FROM_ENTRY(Entry);
assertmsg(i < MAX_PAGING_FILES,
("Bad SwapEntry (0x%.08x). Wrong paging file number (%d, 0x%.08x)\n", Entry, i, off));
off = OFFSET_FROM_ENTRY(Entry);
assertmsg(off / 32 <= PagingFileList[i]->AllocMapSize,
("Bad SwapEntry (0x%.08x). Wrong paging file offset (%d, 0x%.08x)\n", Entry, i, off));
}
}
#endif
NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl) NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
{ {
ULONG i, offset; ULONG i, offset;
@ -134,6 +162,12 @@ NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
file_offset.QuadPart = offset * 4096; file_offset.QuadPart = offset * 4096;
if (file_offset.QuadPart > PagingFileList[i]->MaximumSize.QuadPart)
{
DPRINT1("Bad swap file offset 0x%.08x\n", file_offset.u.LowPart);
KeBugCheck(0);
}
Status = IoPageWrite(PagingFileList[i]->FileObject, Status = IoPageWrite(PagingFileList[i]->FileObject,
Mdl, Mdl,
&file_offset, &file_offset,
@ -149,6 +183,10 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
IO_STATUS_BLOCK Iosb; IO_STATUS_BLOCK Iosb;
NTSTATUS Status; NTSTATUS Status;
DPRINT("MmReadFromSwapPage(SwapEntry 0x%.08x)\n", SwapEntry);
VALIDATE_SWAP_ENTRY(SwapEntry);
if (SwapEntry == 0) if (SwapEntry == 0)
{ {
KeBugCheck(0); KeBugCheck(0);
@ -172,11 +210,18 @@ NTSTATUS MmReadFromSwapPage(SWAPENTRY SwapEntry, PMDL Mdl)
file_offset.QuadPart = offset * 4096; file_offset.QuadPart = offset * 4096;
if (file_offset.QuadPart > PagingFileList[i]->MaximumSize.QuadPart)
{
DPRINT1("Bad swap file offset 0x%.08x\n", file_offset.u.LowPart);
KeBugCheck(0);
}
Status = IoPageRead(PagingFileList[i]->FileObject, Status = IoPageRead(PagingFileList[i]->FileObject,
Mdl, Mdl,
&file_offset, &file_offset,
&Iosb, &Iosb,
TRUE); TRUE);
DPRINT("MmReadFromSwapPage() Status 0x%.8X\n", Status);
return(Status); return(Status);
} }
@ -268,8 +313,15 @@ MmFreeSwapPage(SWAPENTRY Entry)
KIRQL oldIrql; KIRQL oldIrql;
i = FILE_FROM_ENTRY(Entry); i = FILE_FROM_ENTRY(Entry);
assertmsg(i < MAX_PAGING_FILES,
("Bad SwapEntry (0x%.08x). Wrong paging file number (%d, 0x%.08x)\n", Entry, i, off));
off = OFFSET_FROM_ENTRY(Entry); off = OFFSET_FROM_ENTRY(Entry);
assertmsg(off / 32 <= PagingFileList[i]->AllocMapSize,
("Bad SwapEntry (0x%.08x). Wrong paging file offset (%d, 0x%.08x)\n", Entry, i, off));
KeAcquireSpinLock(&PagingFileListLock, &oldIrql); KeAcquireSpinLock(&PagingFileListLock, &oldIrql);
if (PagingFileList[i] == NULL) if (PagingFileList[i] == NULL)
{ {
@ -278,7 +330,6 @@ MmFreeSwapPage(SWAPENTRY Entry)
KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock); KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
PagingFileList[i]->AllocMap[off / 32] &= (~(1 << (off % 32))); PagingFileList[i]->AllocMap[off / 32] &= (~(1 << (off % 32)));
PagingFileList[i]->FreePages++; PagingFileList[i]->FreePages++;
PagingFileList[i]->UsedPages--; PagingFileList[i]->UsedPages--;
@ -410,6 +461,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
SL_OPEN_PAGING_FILE); SL_OPEN_PAGING_FILE);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to open swap file (Status 0x%.08x)\n", Status);
return(Status); return(Status);
} }
@ -426,6 +478,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to write to swap file (Status 0x%.08x)\n", Status);
NtClose(FileHandle); NtClose(FileHandle);
return(Status); return(Status);
} }
@ -439,6 +492,7 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
NULL); NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Failed to reference swap file (Status 0x%.08x)\n", Status);
NtClose(FileHandle); NtClose(FileHandle);
return(Status); return(Status);
} }
@ -484,15 +538,10 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
MiPagingFileCount++; MiPagingFileCount++;
KeReleaseSpinLock(&PagingFileListLock, oldIrql); KeReleaseSpinLock(&PagingFileListLock, oldIrql);
DPRINT("Successfully opened swap file\n");
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
/* EOF */ /* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: pageop.c,v 1.7 2002/02/18 18:41:23 hbirr Exp $ /* $Id: pageop.c,v 1.8 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -29,8 +29,27 @@ PMM_PAGEOP MmPageOpHashTable[PAGEOP_HASH_TABLE_SIZE] = {NULL, } ;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
#ifdef DBG
VOID VOID
MmReleasePageOp(PMM_PAGEOP PageOp) MiValidatePageOp(IN PMM_PAGEOP PageOp)
{
if (PageOp != NULL)
{
DPRINT("MiValidatePageOp(PageOp 0x%.08x)\n", PageOp);
assertmsg(PageOp->Magic == TAG_MM_PAGEOP,
("Bad PageOp (0x%.08x). Wrong magic (0x%.08x)\n", PageOp->Magic));
assertmsg((PageOp->OpType >= MM_PAGEOP_MINIMUM) && (PageOp->OpType <= MM_PAGEOP_MAXIMUM),
("Bad PageOp (0x%.08x). Wrong type (%d)\n", PageOp->OpType));
}
}
#endif /* DBG */
VOID
MmReleasePageOp(IN PMM_PAGEOP PageOp)
/* /*
* FUNCTION: Release a reference to a page operation descriptor * FUNCTION: Release a reference to a page operation descriptor
*/ */
@ -38,6 +57,9 @@ MmReleasePageOp(PMM_PAGEOP PageOp)
KIRQL oldIrql; KIRQL oldIrql;
PMM_PAGEOP PrevPageOp; PMM_PAGEOP PrevPageOp;
assert(PageOp);
VALIDATE_PAGEOP(PageOp);
KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql); KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
PageOp->ReferenceCount--; PageOp->ReferenceCount--;
if (PageOp->ReferenceCount > 0) if (PageOp->ReferenceCount > 0)
@ -65,24 +87,31 @@ MmReleasePageOp(PMM_PAGEOP PageOp)
PrevPageOp = PrevPageOp->Next; PrevPageOp = PrevPageOp->Next;
} }
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
CPRINT("PageOp (0x%.08x) not found\n", PageOp);
KeBugCheck(0); KeBugCheck(0);
} }
PMM_PAGEOP PMM_PAGEOP
MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address, MmGetPageOp(IN PMEMORY_AREA MArea,
PMM_SECTION_SEGMENT Segment, ULONG Offset, ULONG OpType) IN ULONG Pid,
/* IN PVOID Address,
* FUNCTION: Get a page operation descriptor corresponding to IN PMM_SECTION_SEGMENT Segment,
* the memory area and either the segment, offset pair or the IN ULONG Offset,
* pid, address pair. IN ULONG OpType)
*/ /*
* FUNCTION: Get a page operation descriptor corresponding to
* the memory area and either the segment, offset pair or the
* pid, address pair. Create a new pageop if one does not exist.
* FIXME: Make Offset 64-bit
*/
{ {
ULONG Hash; ULONG Hash;
KIRQL oldIrql; KIRQL oldIrql;
PMM_PAGEOP PageOp; PMM_PAGEOP PageOp;
/* /*
* Calcuate the hash value for pageop structure * Calculate the hash value for pageop structure
*/ */
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT) if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
{ {
@ -90,6 +119,9 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
} }
else else
{ {
assertmsg(((ULONG_PTR)Address % PAGESIZE) == 0,
("Address must be page aligned (0x%.08x)\n", Address));
Hash = (((ULONG)Pid) | (((ULONG)Address) / PAGESIZE)); Hash = (((ULONG)Pid) | (((ULONG)Address) / PAGESIZE));
} }
Hash = Hash % PAGEOP_HASH_TABLE_SIZE; Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
@ -127,6 +159,8 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
*/ */
if (PageOp != NULL) if (PageOp != NULL)
{ {
VALIDATE_PAGEOP(PageOp);
PageOp->ReferenceCount++; PageOp->ReferenceCount++;
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
return(PageOp); return(PageOp);
@ -143,6 +177,8 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
return(NULL); return(NULL);
} }
SET_MAGIC(PageOp, TAG_MM_PAGEOP);
if (MArea->Type != MEMORY_AREA_SECTION_VIEW_COMMIT) if (MArea->Type != MEMORY_AREA_SECTION_VIEW_COMMIT)
{ {
PageOp->Pid = Pid; PageOp->Pid = Pid;
@ -163,14 +199,90 @@ MmGetPageOp(PMEMORY_AREA MArea, ULONG Pid, PVOID Address,
KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE); KeInitializeEvent(&PageOp->CompletionEvent, NotificationEvent, FALSE);
MmPageOpHashTable[Hash] = PageOp; MmPageOpHashTable[Hash] = PageOp;
VALIDATE_PAGEOP(PageOp);
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql); KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
return(PageOp); return(PageOp);
} }
PMM_PAGEOP
MmGotPageOp(IN PMEMORY_AREA MArea,
IN ULONG Pid,
IN PVOID Address,
IN PMM_SECTION_SEGMENT Segment,
IN ULONG Offset)
/*
* FUNCTION: Get a page operation descriptor corresponding to
* the memory area and either the segment, offset pair or the
* pid, address pair. Returns NULL if a pageop does not exist.
* FIXME: Make Offset 64-bit
*/
{
ULONG Hash;
KIRQL oldIrql;
PMM_PAGEOP PageOp;
/*
* Calculate the hash value for pageop structure
*/
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
{
Hash = (((ULONG)Segment) | (((ULONG)Offset) / PAGESIZE));
}
else
{
assertmsg(((ULONG_PTR)Address % PAGESIZE) == 0,
("Address must be page aligned (0x%.08x)\n", Address));
Hash = (((ULONG)Pid) | (((ULONG)Address) / PAGESIZE));
}
Hash = Hash % PAGEOP_HASH_TABLE_SIZE;
KeAcquireSpinLock(&MmPageOpHashTableLock, &oldIrql);
/*
* Check for an existing pageop structure
*/
PageOp = MmPageOpHashTable[Hash];
while (PageOp != NULL)
{
if (MArea->Type == MEMORY_AREA_SECTION_VIEW_COMMIT)
{
if (PageOp->Segment == Segment &&
PageOp->Offset == Offset)
{
break;
}
}
else
{
if (PageOp->Pid == Pid &&
PageOp->Address == Address)
{
break;
}
}
PageOp = PageOp->Next;
}
/*
* If we found an existing pageop then increment the reference count
* and return it.
*/
if (PageOp != NULL)
{
VALIDATE_PAGEOP(PageOp);
PageOp->ReferenceCount++;
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
return(PageOp);
}
KeReleaseSpinLock(&MmPageOpHashTableLock, oldIrql);
/*
* Otherwise return NULL.
*/
return(NULL);
}

View file

@ -1,4 +1,4 @@
/* $Id: ppool.c,v 1.7 2002/02/14 00:07:23 hbirr Exp $ /* $Id: ppool.c,v 1.8 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -75,6 +75,8 @@ ExAllocatePagedPoolWithTag (IN POOL_TYPE PoolType,
PMM_PPOOL_FREE_BLOCK_HEADER BestPreviousBlock; PMM_PPOOL_FREE_BLOCK_HEADER BestPreviousBlock;
PVOID BlockAddress; PVOID BlockAddress;
assert_irql(APC_LEVEL);
/* /*
* Don't bother allocating anything for a zero-byte block. * Don't bother allocating anything for a zero-byte block.
*/ */

View file

@ -16,13 +16,14 @@
* 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.3 2002/01/08 00:49:00 dwelch Exp $ /* $Id: rmap.c,v 1.4 2002/05/13 18:10:40 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/rmap.c * FILE: ntoskrnl/mm/rmap.c
* PURPOSE: kernel memory managment functions * PURPOSE: kernel memory managment functions
* PROGRAMMER: David Welch (welch@cwcom.net) * PROGRAMMER: David Welch (welch@cwcom.net)
* Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY: * UPDATE HISTORY:
* Created 27/12/01 * Created 27/12/01
*/ */
@ -43,22 +44,61 @@ typedef struct _MM_RMAP_ENTRY
struct _MM_RMAP_ENTRY* Next; struct _MM_RMAP_ENTRY* Next;
PEPROCESS Process; PEPROCESS Process;
PVOID Address; PVOID Address;
ULONG ReferenceCount;
} MM_RMAP_ENTRY, *PMM_RMAP_ENTRY; } MM_RMAP_ENTRY, *PMM_RMAP_ENTRY;
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
static FAST_MUTEX RmapListLock; static FAST_MUTEX MiRmapListLock;
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
#ifdef DBG
VOID
MiValidateRmapList(struct _MM_RMAP_ENTRY* RmapList)
{
if (RmapList != NULL)
{
PMM_RMAP_ENTRY CurrentEntry = RmapList;
while (CurrentEntry != NULL)
{
PMM_RMAP_ENTRY Entry = RmapList;
ULONG Count = 0;
assertmsg(RmapList->ReferenceCount >= 0, ("Bad reference count %d for rmap entry\n",
RmapList->ReferenceCount));
while (Entry != NULL)
{
if (Entry->Process == CurrentEntry->Process)
{
Count++;
}
Entry = Entry->Next;
}
assertmsg(Count == 1, ("%d rmap entries for process 0x%.08x\n",
Count, CurrentEntry->Process));
CurrentEntry = CurrentEntry->Next;
}
}
}
#endif /* DBG */
VOID VOID
MmInitializeRmapList(VOID) MmInitializeRmapList(VOID)
{ {
ExInitializeFastMutex(&RmapListLock); ExInitializeFastMutex(&MiRmapListLock);
} }
NTSTATUS NTSTATUS
MmPageOutPhysicalAddress(PVOID PhysicalAddress) MmPageOutPhysicalAddress(ULONG_PTR PhysicalAddress)
{ {
PMM_RMAP_ENTRY entry; PMM_RMAP_ENTRY entry;
PMEMORY_AREA MemoryArea; PMEMORY_AREA MemoryArea;
@ -69,11 +109,11 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
NTSTATUS Status; NTSTATUS Status;
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&MiRmapListLock);
entry = MmGetRmapListHeadPage(PhysicalAddress); entry = MmGetRmapListHeadPage(PhysicalAddress);
if (entry == NULL) if (entry == NULL)
{ {
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&MiRmapListLock);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
Process = entry->Process; Process = entry->Process;
@ -107,7 +147,7 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
{ {
MmReleasePageOp(PageOp); MmReleasePageOp(PageOp);
MmUnlockAddressSpace(&Process->AddressSpace); MmUnlockAddressSpace(&Process->AddressSpace);
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&MiRmapListLock);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
@ -115,7 +155,7 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
* Release locks now we have a page op. * Release locks now we have a page op.
*/ */
MmUnlockAddressSpace(&Process->AddressSpace); MmUnlockAddressSpace(&Process->AddressSpace);
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&MiRmapListLock);
/* /*
* Do the actual page out work. * Do the actual page out work.
@ -131,7 +171,7 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
{ {
MmReleasePageOp(PageOp); MmReleasePageOp(PageOp);
MmUnlockAddressSpace(&Process->AddressSpace); MmUnlockAddressSpace(&Process->AddressSpace);
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&MiRmapListLock);
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
@ -139,7 +179,7 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
* Release locks now we have a page op. * Release locks now we have a page op.
*/ */
MmUnlockAddressSpace(&Process->AddressSpace); MmUnlockAddressSpace(&Process->AddressSpace);
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&MiRmapListLock);
/* /*
* Do the actual page out work. * Do the actual page out work.
@ -154,48 +194,324 @@ MmPageOutPhysicalAddress(PVOID PhysicalAddress)
return(Status); return(Status);
} }
VOID VOID
MmInsertRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address) MmReferenceRmap(IN PMM_RMAP_ENTRY RmapEntry)
{ {
PMM_RMAP_ENTRY current_entry; InterlockedIncrement(&RmapEntry->ReferenceCount);
PMM_RMAP_ENTRY new_entry; }
VOID
MmDereferenceRmap(IN PMM_RMAP_ENTRY RmapEntry)
{
InterlockedDecrement(&RmapEntry->ReferenceCount);
assertmsg(RmapEntry->ReferenceCount > 0, ("Bad reference count (%d) for "
"Process (0x%.08x) Addresss (0x%.08x)\n",
RmapEntry->ReferenceCount, RmapEntry->Process, RmapEntry->Address));
}
VOID
MiDisableAllRmaps(IN ULONG_PTR PhysicalAddress,
IN PBOOLEAN Modified)
{
PMM_RMAP_ENTRY CurrentEntry;
PMM_RMAP_ENTRY NextEntry;
BOOLEAN WasDirty;
ExAcquireFastMutex(&MiRmapListLock);
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
assertmsg(CurrentEntry != NULL, ("MiDisableAllRmaps: No rmaps.\n"))
*Modified = FALSE;
while (CurrentEntry != NULL)
{
NextEntry = CurrentEntry->Next;
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
MmDisableVirtualMapping(CurrentEntry->Process,
CurrentEntry->Address,
&WasDirty,
NULL);
if (WasDirty)
{
*Modified = TRUE;
}
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
CurrentEntry = NextEntry;
}
ExReleaseFastMutex(&MiRmapListLock);
}
VOID
MiEnableAllRmaps(IN ULONG_PTR PhysicalAddress,
IN BOOLEAN Modified)
{
PMM_RMAP_ENTRY CurrentEntry;
PMM_RMAP_ENTRY NextEntry;
ExAcquireFastMutex(&MiRmapListLock);
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
assertmsg(CurrentEntry != NULL, ("MiEnableAllRmaps: No rmaps.\n"))
while (CurrentEntry != NULL)
{
NextEntry = CurrentEntry->Next;
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
MmEnableVirtualMapping(CurrentEntry->Process,
CurrentEntry->Address);
if (Modified)
{
MmSetDirtyPage(CurrentEntry->Process,
CurrentEntry->Address);
}
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
CurrentEntry = NextEntry;
}
ExReleaseFastMutex(&MiRmapListLock);
}
VOID
MiGetDirtyAllRmaps(IN ULONG_PTR PhysicalAddress,
OUT PBOOLEAN Dirty)
{
PMM_RMAP_ENTRY CurrentEntry;
PMM_RMAP_ENTRY NextEntry;
BOOLEAN WasDirty;
ExAcquireFastMutex(&MiRmapListLock);
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
assertmsg(CurrentEntry != NULL, ("MiGetDirtyAllRmaps: No rmaps.\n"))
*Dirty = FALSE;
while (CurrentEntry != NULL)
{
NextEntry = CurrentEntry->Next;
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
WasDirty = MmIsPageDirty(CurrentEntry->Process,
CurrentEntry->Address);
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
if (WasDirty)
{
*Dirty = TRUE;
}
CurrentEntry = NextEntry;
}
ExReleaseFastMutex(&MiRmapListLock);
}
VOID
MiSetDirtyAllRmaps(IN ULONG_PTR PhysicalAddress,
IN BOOLEAN Dirty)
{
PMM_RMAP_ENTRY CurrentEntry;
PMM_RMAP_ENTRY NextEntry;
ExAcquireFastMutex(&MiRmapListLock);
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
assertmsg(CurrentEntry != NULL, ("MiSetDirtyAllRmaps: No rmaps.\n"))
while (CurrentEntry != NULL)
{
NextEntry = CurrentEntry->Next;
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
if (Dirty)
{
MmSetDirtyPage(CurrentEntry->Process,
CurrentEntry->Address);
}
else
{
MmSetCleanPage(CurrentEntry->Process,
CurrentEntry->Address);
}
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
CurrentEntry = NextEntry;
}
ExReleaseFastMutex(&MiRmapListLock);
}
VOID
MiGetPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
IN ULONG PageState,
OUT PBOOLEAN Result)
{
PMM_RMAP_ENTRY CurrentEntry;
PMM_RMAP_ENTRY NextEntry;
ULONG State;
ExAcquireFastMutex(&MiRmapListLock);
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
assertmsg(CurrentEntry != NULL, ("MiGetPageStateAllRmaps: No rmaps.\n"))
*Result = FALSE;
while (CurrentEntry != NULL)
{
NextEntry = CurrentEntry->Next;
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
State = MiPageState(CurrentEntry->Process,
CurrentEntry->Address,
PageState);
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
if (State)
{
*Result = TRUE;
}
CurrentEntry = NextEntry;
}
ExReleaseFastMutex(&MiRmapListLock);
}
VOID
MiClearPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
IN ULONG PageState)
{
PMM_RMAP_ENTRY CurrentEntry;
PMM_RMAP_ENTRY NextEntry;
ExAcquireFastMutex(&MiRmapListLock);
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
assertmsg(CurrentEntry != NULL, ("MiClearPageStateAllRmaps: No rmaps.\n"))
while (CurrentEntry != NULL)
{
NextEntry = CurrentEntry->Next;
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
MiClearPageState(CurrentEntry->Process,
CurrentEntry->Address,
PageState);
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
CurrentEntry = NextEntry;
}
ExReleaseFastMutex(&MiRmapListLock);
}
VOID
MiSetPageStateAllRmaps(IN ULONG_PTR PhysicalAddress,
IN ULONG PageState)
{
PMM_RMAP_ENTRY CurrentEntry;
PMM_RMAP_ENTRY NextEntry;
ExAcquireFastMutex(&MiRmapListLock);
CurrentEntry = MmGetRmapListHeadPage(PhysicalAddress);
assertmsg(CurrentEntry != NULL, ("MiSetPageStateAllRmaps: No rmaps.\n"))
while (CurrentEntry != NULL)
{
NextEntry = CurrentEntry->Next;
MmLockAddressSpace(&CurrentEntry->Process->AddressSpace);
MiSetPageState(CurrentEntry->Process,
CurrentEntry->Address,
PageState);
MmUnlockAddressSpace(&CurrentEntry->Process->AddressSpace);
CurrentEntry = NextEntry;
}
ExReleaseFastMutex(&MiRmapListLock);
}
VOID
MmInsertRmap(ULONG_PTR PhysicalAddress, PEPROCESS Process, PVOID Address)
{
PMM_RMAP_ENTRY Current;
PMM_RMAP_ENTRY New;
Address = (PVOID)PAGE_ROUND_DOWN(Address); Address = (PVOID)PAGE_ROUND_DOWN(Address);
new_entry = ExAllocatePool(NonPagedPool, sizeof(MM_RMAP_ENTRY)); New = ExAllocatePool(NonPagedPool, sizeof(MM_RMAP_ENTRY));
if (new_entry == NULL) assert(New);
{ New->ReferenceCount = 1;
KeBugCheck(0); New->Address = Address;
} New->Process = Process;
new_entry->Address = Address;
new_entry->Process = Process;
if (MmGetPhysicalAddressForProcess(Process, Address) != if (MmGetPhysicalAddressForProcess(Process, Address) !=
(ULONG)PhysicalAddress) (ULONG_PTR)PhysicalAddress)
{ {
DPRINT1("Insert rmap (%d, 0x%.8X) 0x%.8X which doesn't match physical " DPRINT("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), MmGetPhysicalAddressForProcess(Process, Address),
PhysicalAddress) PhysicalAddress)
KeBugCheck(0); KeBugCheck(0);
} }
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&MiRmapListLock);
current_entry = MmGetRmapListHeadPage(PhysicalAddress); Current = MmGetRmapListHeadPage(PhysicalAddress);
new_entry->Next = current_entry; New->Next = Current;
MmSetRmapListHeadPage(PhysicalAddress, new_entry); MmSetRmapListHeadPage(PhysicalAddress, New);
ExReleaseFastMutex(&RmapListLock); MmSetRmapCallback(PhysicalAddress, NULL, NULL);
ExReleaseFastMutex(&MiRmapListLock);
} }
VOID VOID
MmDeleteAllRmaps(PVOID PhysicalAddress, PVOID Context, MmDeleteAllRmaps(ULONG_PTR PhysicalAddress, PVOID Context,
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process,
PVOID Address)) PVOID Address))
{ {
PMM_RMAP_ENTRY current_entry; PMM_RMAP_ENTRY current_entry;
PMM_RMAP_ENTRY previous_entry; PMM_RMAP_ENTRY previous_entry;
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&MiRmapListLock);
current_entry = MmGetRmapListHeadPage(PhysicalAddress); current_entry = MmGetRmapListHeadPage(PhysicalAddress);
if (current_entry == NULL) if (current_entry == NULL)
{ {
@ -214,38 +530,47 @@ MmDeleteAllRmaps(PVOID PhysicalAddress, PVOID Context,
ExFreePool(previous_entry); ExFreePool(previous_entry);
} }
MmSetRmapListHeadPage(PhysicalAddress, NULL); MmSetRmapListHeadPage(PhysicalAddress, NULL);
ExReleaseFastMutex(&RmapListLock); ExReleaseFastMutex(&MiRmapListLock);
} }
VOID VOID
MmDeleteRmap(PVOID PhysicalAddress, PEPROCESS Process, PVOID Address) MmDeleteRmap(IN ULONG_PTR PhysicalAddress,
IN PEPROCESS Process,
IN PVOID Address)
{ {
PMM_RMAP_ENTRY current_entry, previous_entry; PMM_RMAP_ENTRY Current;
PMM_RMAP_ENTRY Previous;
ExAcquireFastMutex(&RmapListLock); ExAcquireFastMutex(&MiRmapListLock);
previous_entry = NULL; Previous = NULL;
current_entry = MmGetRmapListHeadPage(PhysicalAddress); Current = MmGetRmapListHeadPage(PhysicalAddress);
while (current_entry != NULL) while (Current != NULL)
{ {
if (current_entry->Process == Process && if (Current->Process == Process && Current->Address == Address)
current_entry->Address == Address) {
{ Current->ReferenceCount--;
if (previous_entry == NULL) assertmsg(Current->ReferenceCount == 0, ("Rmap has outstanding references (%d) for Page (0x%.08x) "
{ "Process (0x%.08x) Addresss (0x%.08x)\n",
MmSetRmapListHeadPage(PhysicalAddress, current_entry->Next); Current->ReferenceCount, PhysicalAddress, Process, Address));
ExReleaseFastMutex(&RmapListLock);
ExFreePool(current_entry); if (Previous == NULL)
} {
else MmSetRmapListHeadPage(PhysicalAddress, Current->Next);
{ ExReleaseFastMutex(&MiRmapListLock);
previous_entry->Next = current_entry->Next; ExFreePool(Current);
ExReleaseFastMutex(&RmapListLock); }
ExFreePool(current_entry); else
} {
return; Previous->Next = Current->Next;
} ExReleaseFastMutex(&MiRmapListLock);
previous_entry = current_entry; ExFreePool(Current);
current_entry = current_entry->Next; }
return;
}
Previous = Current;
Current = Current->Next;
} }
KeBugCheck(0); assertmsg(FALSE, ("No rmap entry for Page (0x%.08x) Process (0x%.08x) Addresss (0x%.08x)\n",
PhysicalAddress, Process, Address));
} }

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.80 2002/05/07 22:53:05 hbirr Exp $ /* $Id: section.c,v 1.81 2002/05/13 18:10:40 chorns Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c * FILE: ntoskrnl/mm/section.c
@ -306,7 +306,7 @@ MmUnsharePageEntrySectionSegment(PSECTION_OBJECT Section,
NTSTATUS NTSTATUS
MiReadPage(PMEMORY_AREA MemoryArea, MiReadPage(PMEMORY_AREA MemoryArea,
PLARGE_INTEGER Offset, PLARGE_INTEGER Offset,
PVOID* Page) PULONG_PTR Page)
/* /*
* FUNCTION: Read a page for a section backed memory area. * FUNCTION: Read a page for a section backed memory area.
* PARAMETERS: * PARAMETERS:
@ -381,7 +381,7 @@ MiReadPage(PMEMORY_AREA MemoryArea,
*/ */
Addr = MmGetPhysicalAddress(BaseAddress + Addr = MmGetPhysicalAddress(BaseAddress +
Offset->QuadPart - BaseOffset); Offset->QuadPart - BaseOffset);
(*Page) = (PVOID)(ULONG)Addr.QuadPart; (*Page) = (ULONG_PTR)Addr.QuadPart;
MmReferencePage((*Page)); MmReferencePage((*Page));
CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, TRUE); CcRosReleaseCacheSegment(Fcb->Bcb, CacheSeg, TRUE, FALSE, TRUE);
@ -423,7 +423,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
BOOLEAN Locked) BOOLEAN Locked)
{ {
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
PVOID Page; ULONG_PTR Page;
NTSTATUS Status; NTSTATUS Status;
ULONG PAddress; ULONG PAddress;
PSECTION_OBJECT Section; PSECTION_OBJECT Section;
@ -442,7 +442,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
{ {
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -534,7 +534,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
return(STATUS_MM_RESTART_OPERATION); return(STATUS_MM_RESTART_OPERATION);
} }
Page = (PVOID)(PAGE_FROM_SSE(Entry)); Page = (ULONG_PTR)(PAGE_FROM_SSE(Entry));
MmReferencePage(Page); MmReferencePage(Page);
MmSharePageEntrySectionSegment(Segment, Offset.u.LowPart); MmSharePageEntrySectionSegment(Segment, Offset.u.LowPart);
@ -553,7 +553,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
} }
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
MmUnlockSectionSegment(Segment); MmUnlockSectionSegment(Segment);
MmUnlockSection(Section); MmUnlockSection(Section);
@ -627,7 +627,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
*/ */
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
PageOp->Status = STATUS_SUCCESS; PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
@ -655,7 +655,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
*/ */
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
/* /*
@ -696,7 +696,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
(PVOID)PAGE_ROUND_DOWN(Address)); (PVOID)PAGE_ROUND_DOWN(Address));
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
/* /*
@ -827,7 +827,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
} }
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
PageOp->Status = STATUS_SUCCESS; PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
@ -910,7 +910,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
} }
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
PageOp->Status = STATUS_SUCCESS; PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
@ -927,14 +927,14 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
* take another reference to the page * take another reference to the page
*/ */
Page = (PVOID)PAGE_FROM_SSE(Entry); Page = (ULONG_PTR)PAGE_FROM_SSE(Entry);
MmReferencePage(Page); MmReferencePage(Page);
MmSharePageEntrySectionSegment(Segment, Offset.QuadPart); MmSharePageEntrySectionSegment(Segment, Offset.QuadPart);
Status = MmCreateVirtualMapping(PsGetCurrentProcess(), Status = MmCreateVirtualMapping(PsGetCurrentProcess(),
Address, Address,
Attributes, Attributes,
(ULONG)Page, Page,
FALSE); FALSE);
MmInsertRmap(Page, PsGetCurrentProcess(), MmInsertRmap(Page, PsGetCurrentProcess(),
(PVOID)PAGE_ROUND_DOWN(Address)); (PVOID)PAGE_ROUND_DOWN(Address));
@ -945,7 +945,7 @@ MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
} }
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
PageOp->Status = STATUS_SUCCESS; PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
@ -964,8 +964,8 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
{ {
PMM_SECTION_SEGMENT Segment; PMM_SECTION_SEGMENT Segment;
PSECTION_OBJECT Section; PSECTION_OBJECT Section;
ULONG OldPage; ULONG_PTR OldPage;
PVOID NewPage; ULONG_PTR NewPage;
PVOID NewAddress; PVOID NewAddress;
NTSTATUS Status; NTSTATUS Status;
ULONG PAddress; ULONG PAddress;
@ -1106,16 +1106,16 @@ MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
} }
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
/* /*
* Unshare the old page. * Unshare the old page.
*/ */
MmUnsharePageEntrySectionSegment(Section, Segment, Offset.QuadPart, FALSE); MmUnsharePageEntrySectionSegment(Section, Segment, Offset.QuadPart, FALSE);
MmDeleteRmap((PVOID)OldPage, PsGetCurrentProcess(), MmDeleteRmap(OldPage, PsGetCurrentProcess(),
(PVOID)PAGE_ROUND_DOWN(Address)); (PVOID)PAGE_ROUND_DOWN(Address));
MmDereferencePage((PVOID)OldPage); MmDereferencePage(OldPage);
PageOp->Status = STATUS_SUCCESS; PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
@ -1127,15 +1127,15 @@ VOID
MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address) MmPageOutDeleteMapping(PVOID Context, PEPROCESS Process, PVOID Address)
{ {
MM_SECTION_PAGEOUT_CONTEXT* PageOutContext; MM_SECTION_PAGEOUT_CONTEXT* PageOutContext;
BOOL WasDirty; BOOLEAN WasDirty;
PVOID PhysicalAddress; ULONG_PTR PhysicalAddress;
PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context; PageOutContext = (MM_SECTION_PAGEOUT_CONTEXT*)Context;
MmDeleteVirtualMapping(Process, MmDeleteVirtualMapping(Process,
Address, Address,
FALSE, FALSE,
&WasDirty, &WasDirty,
(PULONG)&PhysicalAddress); (PULONG_PTR)&PhysicalAddress);
if (WasDirty) if (WasDirty)
{ {
PageOutContext->WasDirty = TRUE; PageOutContext->WasDirty = TRUE;
@ -1159,7 +1159,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
LARGE_INTEGER Offset; LARGE_INTEGER Offset;
PSECTION_OBJECT Section; PSECTION_OBJECT Section;
PMM_SECTION_SEGMENT Segment; PMM_SECTION_SEGMENT Segment;
PVOID PhysicalAddress; ULONG_PTR PhysicalAddress;
MM_SECTION_PAGEOUT_CONTEXT Context; MM_SECTION_PAGEOUT_CONTEXT Context;
SWAPENTRY SwapEntry; SWAPENTRY SwapEntry;
PMDL Mdl; PMDL Mdl;
@ -1221,7 +1221,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
KeBugCheck(0); KeBugCheck(0);
} }
PhysicalAddress = PhysicalAddress =
(PVOID)MmGetPhysicalAddressForProcess(AddressSpace->Process, MmGetPhysicalAddressForProcess(AddressSpace->Process,
Address); Address);
SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress); SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
@ -1234,7 +1234,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
Context.WasDirty = FALSE; Context.WasDirty = FALSE;
if (Segment->Characteristics & IMAGE_SECTION_CHAR_BSS || if (Segment->Characteristics & IMAGE_SECTION_CHAR_BSS ||
IS_SWAP_FROM_SSE(Entry) || IS_SWAP_FROM_SSE(Entry) ||
(PVOID)(PAGE_FROM_SSE(Entry)) != PhysicalAddress) (ULONG_PTR)(PAGE_FROM_SSE(Entry)) != PhysicalAddress)
{ {
Context.Private = Private = TRUE; Context.Private = Private = TRUE;
} }
@ -1361,7 +1361,7 @@ MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
if (DirectMapped && !Private) if (DirectMapped && !Private)
{ {
assert(SwapEntry == 0); assert(SwapEntry == 0);
MmDereferencePage((PVOID)PhysicalAddress); MmDereferencePage(PhysicalAddress);
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);
@ -1371,7 +1371,7 @@ MmPageOutSectionView(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((PVOID)PhysicalAddress); SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
if (SwapEntry == 0) if (SwapEntry == 0)
{ {
SwapEntry = MmAllocSwapPage(); SwapEntry = MmAllocSwapPage();
@ -2557,13 +2557,21 @@ NtMapViewOfSection(HANDLE SectionHandle,
return(Status); return(Status);
} }
VOID STATIC VOID
MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG PhysAddr, MmFreeSectionPage (IN BOOLEAN Before,
SWAPENTRY SwapEntry, BOOLEAN Dirty) IN PVOID Context,
IN PMEMORY_AREA MemoryArea,
IN PVOID Address,
IN ULONG_PTR PhysAddr,
IN SWAPENTRY SwapEntry,
IN BOOLEAN Dirty)
{ {
PMEMORY_AREA MArea; PMEMORY_AREA MArea;
ULONG Entry; ULONG Entry;
if (Before)
return;
MArea = (PMEMORY_AREA)Context; MArea = (PMEMORY_AREA)Context;
if (SwapEntry != 0) if (SwapEntry != 0)
@ -2589,8 +2597,8 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG P
/* /*
* Just dereference private pages * Just dereference private pages
*/ */
MmDeleteRmap((PVOID)PhysAddr, MArea->Process, Address); MmDeleteRmap(PhysAddr, MArea->Process, Address);
MmDereferencePage((PVOID)PhysAddr); MmDereferencePage(PhysAddr);
} }
else else
{ {
@ -2598,8 +2606,8 @@ MmFreeSectionPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, ULONG P
MArea->Data.SectionData.Segment, MArea->Data.SectionData.Segment,
Offset, Offset,
Dirty); Dirty);
MmDeleteRmap((PVOID)PhysAddr, MArea->Process, Address); MmDeleteRmap(PhysAddr, MArea->Process, Address);
MmDereferencePage((PVOID)PhysAddr); MmDereferencePage(PhysAddr);
} }
} }
} }
@ -2856,7 +2864,7 @@ MmAllocateSection (IN ULONG Length)
DPRINT("Result %p\n",Result); DPRINT("Result %p\n",Result);
for (i = 0; (i <= (Length / PAGESIZE)); i++) for (i = 0; (i <= (Length / PAGESIZE)); i++)
{ {
PVOID Page; ULONG_PTR Page;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page); Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))

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.2 2002/01/03 22:52:29 dwelch Exp $ /* $Id: slab.c,v 1.3 2002/05/13 18:10:41 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -103,7 +103,7 @@ PSLAB_CACHE_PAGE
ExGrowSlabCache(PSLAB_CACHE Slab) ExGrowSlabCache(PSLAB_CACHE Slab)
{ {
PSLAB_CACHE_PAGE SlabPage; PSLAB_CACHE_PAGE SlabPage;
PVOID PhysicalPage; ULONG_PTR PhysicalPage;
PVOID Page; PVOID Page;
NTSTATUS Status; NTSTATUS Status;
ULONG i; ULONG i;
@ -116,7 +116,7 @@ ExGrowSlabCache(PSLAB_CACHE Slab)
return(NULL); return(NULL);
} }
Page = ExAllocatePageWithPhysPage((ULONG)PhysicalPage); Page = ExAllocatePageWithPhysPage(PhysicalPage);
if (Page == NULL) if (Page == NULL)
{ {
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage); MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage);
@ -299,22 +299,22 @@ ExDestroySlabCache(PSLAB_CACHE Slab)
while (current_entry != &Slab->PageListHead) while (current_entry != &Slab->PageListHead)
{ {
PVOID Base; PVOID Base;
PVOID PhysicalPage; ULONG_PTR PhysicalPage;
current = CONTAINING_RECORD(current_entry, current = CONTAINING_RECORD(current_entry,
SLAB_CACHE_PAGE, SLAB_CACHE_PAGE,
PageListEntry); PageListEntry);
Base = (PVOID)current + sizeof(SLAB_CACHE_PAGE) - PAGESIZE; Base = (PVOID)(current + sizeof(SLAB_CACHE_PAGE) - PAGESIZE);
if (Slab->Destructor != NULL) if (Slab->Destructor != NULL)
{ {
for (i = 0; i < Slab->ObjectsPerPage; i++) for (i = 0; i < Slab->ObjectsPerPage; i++)
{ {
Object = Base + (i * Slab->ObjectSize) + Object = (PVOID)(Base + (i * Slab->ObjectSize) +
sizeof(SLAB_CACHE_BUFCTL); sizeof(SLAB_CACHE_BUFCTL));
Slab->Destructor(Object, Slab->BaseSize); Slab->Destructor(Object, Slab->BaseSize);
} }
} }
PhysicalPage = (PVOID)MmGetPhysicalAddressForProcess(NULL, Base); PhysicalPage = MmGetPhysicalAddressForProcess(NULL, Base);
ExUnmapPage(Base); ExUnmapPage(Base);
MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage); MmReleasePageMemoryConsumer(MC_NPPOOL, PhysicalPage);
} }

View file

@ -1,4 +1,4 @@
/* $Id: virtual.c,v 1.56 2002/05/07 22:36:46 hbirr Exp $ /* $Id: virtual.c,v 1.57 2002/05/13 18:10:41 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top directory * COPYRIGHT: See COPYING in the top directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -101,8 +101,8 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
PVOID Address, PVOID Address,
PMM_PAGEOP PageOp) PMM_PAGEOP PageOp)
{ {
PVOID PhysicalAddress; ULONG_PTR PhysicalAddress;
BOOL WasDirty; BOOLEAN WasDirty;
SWAPENTRY SwapEntry; SWAPENTRY SwapEntry;
NTSTATUS Status; NTSTATUS Status;
PMDL Mdl; PMDL Mdl;
@ -136,7 +136,7 @@ MmPageOutVirtualMemory(PMADDRESS_SPACE AddressSpace,
* Otherwise this is read-write data * Otherwise this is read-write data
*/ */
MmDisableVirtualMapping(MemoryArea->Process, Address, MmDisableVirtualMapping(MemoryArea->Process, Address,
&WasDirty, (PULONG)&PhysicalAddress); &WasDirty, (PULONG_PTR)&PhysicalAddress);
if (PhysicalAddress == 0) if (PhysicalAddress == 0)
{ {
KeBugCheck(0); KeBugCheck(0);
@ -160,7 +160,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((PVOID)PhysicalAddress); SwapEntry = MmGetSavedSwapEntryPage(PhysicalAddress);
if (SwapEntry == 0) if (SwapEntry == 0)
{ {
SwapEntry = MmAllocSwapPage(); SwapEntry = MmAllocSwapPage();
@ -221,7 +221,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.
*/ */
{ {
PVOID Page; ULONG_PTR Page;
NTSTATUS Status; NTSTATUS Status;
PMM_SEGMENT Segment; PMM_SEGMENT Segment;
PVOID CurrentAddress; PVOID CurrentAddress;
@ -236,7 +236,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
{ {
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -312,7 +312,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
MmLockAddressSpace(AddressSpace); MmLockAddressSpace(AddressSpace);
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
MmReleasePageOp(PageOp); MmReleasePageOp(PageOp);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -384,7 +384,7 @@ MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
*/ */
if (Locked) if (Locked)
{ {
MmLockPage((PVOID)MmGetPhysicalAddressForProcess(NULL, Address)); MmLockPage(MmGetPhysicalAddressForProcess(NULL, Address));
} }
PageOp->Status = STATUS_SUCCESS; PageOp->Status = STATUS_SUCCESS;
KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(&PageOp->CompletionEvent, IO_NO_INCREMENT, FALSE);
@ -434,9 +434,9 @@ MmModifyAttributes(PMADDRESS_SPACE AddressSpace,
FALSE, NULL, NULL); FALSE, NULL, NULL);
if (PhysicalAddr.u.LowPart != 0) if (PhysicalAddr.u.LowPart != 0)
{ {
MmDeleteRmap((PVOID)PhysicalAddr.u.LowPart, AddressSpace->Process, MmDeleteRmap((ULONG_PTR)PhysicalAddr.u.LowPart, AddressSpace->Process,
BaseAddress + (i * PAGESIZE)); BaseAddress + (i * PAGESIZE));
MmDereferencePage((PVOID)(ULONG)(PhysicalAddr.u.LowPart)); MmDereferencePage((ULONG_PTR)(PhysicalAddr.u.LowPart));
} }
} }
} }
@ -1048,21 +1048,24 @@ NtFlushVirtualMemory(IN HANDLE ProcessHandle,
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
VOID
VOID STATIC MmFreeVirtualMemoryPage (IN BOOLEAN Before,
MmFreeVirtualMemoryPage(PVOID Context, IN PVOID Context,
MEMORY_AREA* MemoryArea, IN PMEMORY_AREA MemoryArea,
PVOID Address, IN PVOID Address,
ULONG PhysicalAddr, IN ULONG_PTR PhysicalAddress,
SWAPENTRY SwapEntry, IN SWAPENTRY SwapEntry,
BOOLEAN Dirty) IN BOOLEAN Dirty)
{ {
PEPROCESS Process = (PEPROCESS)Context; PEPROCESS Process = (PEPROCESS)Context;
if (PhysicalAddr != 0) if (Before)
return;
if (PhysicalAddress != 0)
{ {
MmDeleteRmap((PVOID)PhysicalAddr, Process, Address); MmDeleteRmap(PhysicalAddress, Process, Address);
MmDereferencePage((PVOID)PhysicalAddr); MmDereferencePage(PhysicalAddress);
} }
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: wset.c,v 1.11 2001/12/31 01:53:45 dwelch Exp $ /* $Id: wset.c,v 1.12 2002/05/13 18:10:41 chorns Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/wset.c * FILE: ntoskrnl/mm/wset.c
@ -41,14 +41,14 @@
NTSTATUS NTSTATUS
MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages) MmTrimUserMemory(ULONG Target, ULONG Priority, PULONG NrFreedPages)
{ {
PVOID CurrentPhysicalAddress; ULONG_PTR CurrentPhysicalAddress;
PVOID NextPhysicalAddress; ULONG_PTR NextPhysicalAddress;
NTSTATUS Status; NTSTATUS Status;
(*NrFreedPages) = 0; (*NrFreedPages) = 0;
CurrentPhysicalAddress = MmGetLRUFirstUserPage(); CurrentPhysicalAddress = MmGetLRUFirstUserPage();
while (CurrentPhysicalAddress != NULL && Target > 0) while (CurrentPhysicalAddress != 0 && Target > 0)
{ {
NextPhysicalAddress = MmGetLRUNextUserPage(CurrentPhysicalAddress); NextPhysicalAddress = MmGetLRUNextUserPage(CurrentPhysicalAddress);

View file

@ -1,4 +1,4 @@
/* $Id: object.c,v 1.47 2002/05/07 22:39:26 hbirr Exp $ /* $Id: object.c,v 1.48 2002/05/13 18:10:41 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -143,7 +143,7 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
Path = ObjectAttributes->ObjectName->Buffer; Path = ObjectAttributes->ObjectName->Buffer;
if (Path[0] == 0) if ((Path == NULL) && (Path[0] == 0))
{ {
*ReturnedObject = CurrentObject; *ReturnedObject = CurrentObject;
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
@ -155,16 +155,8 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes,
return(STATUS_UNSUCCESSFUL); return(STATUS_UNSUCCESSFUL);
} }
if (Path)
{
RtlCreateUnicodeString (&PathString, Path); RtlCreateUnicodeString (&PathString, Path);
current = PathString.Buffer; current = PathString.Buffer;
}
else
{
RtlInitUnicodeString (&PathString, NULL);
current = NULL;
}
RootObject = CurrentObject; RootObject = CurrentObject;
@ -244,15 +236,18 @@ ObCreateObject(OUT PHANDLE Handle,
DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n", DPRINT("ObCreateObject(Handle %x, ObjectAttributes %x, Type %x)\n",
Handle, ObjectAttributes, Type); Handle, ObjectAttributes, Type);
if (ObjectAttributes != NULL && if (ObjectAttributes != NULL &&
ObjectAttributes->ObjectName != NULL) ObjectAttributes->ObjectName != NULL &&
ObjectAttributes->ObjectName->Buffer != NULL)
{ {
DPRINT("ObjectAttributes->ObjectName->Buffer %S\n", DPRINT("ObjectAttributes->ObjectName->Buffer %S\n",
ObjectAttributes->ObjectName->Buffer); ObjectAttributes->ObjectName->Buffer);
} }
if (ObjectAttributes != NULL && if (ObjectAttributes != NULL &&
ObjectAttributes->ObjectName != NULL) ObjectAttributes->ObjectName != NULL &&
ObjectAttributes->ObjectName->Buffer != NULL)
{ {
Status = ObFindObject(ObjectAttributes, Status = ObFindObject(ObjectAttributes,
&Parent, &Parent,
@ -268,7 +263,6 @@ ObCreateObject(OUT PHANDLE Handle,
{ {
RtlInitUnicodeString(&RemainingPath, NULL); RtlInitUnicodeString(&RemainingPath, NULL);
} }
RtlMapGenericMask(&DesiredAccess, RtlMapGenericMask(&DesiredAccess,
Type->Mapping); Type->Mapping);
@ -304,6 +298,7 @@ ObCreateObject(OUT PHANDLE Handle,
Parent, Parent,
RemainingPath.Buffer, RemainingPath.Buffer,
ObjectAttributes); ObjectAttributes);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
if (ObjectAttached == TRUE) if (ObjectAttached == TRUE)
@ -320,6 +315,7 @@ ObCreateObject(OUT PHANDLE Handle,
return(Status); return(Status);
} }
} }
RtlFreeUnicodeString( &RemainingPath ); RtlFreeUnicodeString( &RemainingPath );
*Object = HEADER_TO_BODY(Header); *Object = HEADER_TO_BODY(Header);

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.90 2002/03/08 17:04:03 hbirr Exp $ /* $Id: thread.c,v 1.91 2002/05/13 18:10:41 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -57,6 +57,30 @@ static GENERIC_MAPPING PiThreadMapping = {THREAD_READ,
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
NTSTATUS
PiSetPriorityThread(IN HANDLE ThreadHandle,
IN KPRIORITY Priority)
{
PETHREAD Thread;
NTSTATUS Status;
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_ALL_ACCESS,
PsThreadType,
KernelMode,
(PVOID*) &Thread,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
KeSetPriorityThread(&Thread->Tcb, Priority);
ObReferenceObject(Thread);
return(STATUS_SUCCESS);
}
PKTHREAD STDCALL KeGetCurrentThread(VOID) PKTHREAD STDCALL KeGetCurrentThread(VOID)
{ {
return(KeGetCurrentKPCR()->CurrentThread); return(KeGetCurrentKPCR()->CurrentThread);
@ -142,23 +166,6 @@ VOID PsDumpThreads(BOOLEAN IncludeSystem)
static PETHREAD PsScanThreadList (KPRIORITY Priority, ULONG Affinity) static PETHREAD PsScanThreadList (KPRIORITY Priority, ULONG Affinity)
{ {
#if 0
PLIST_ENTRY current_entry;
PETHREAD current;
current_entry = RemoveHeadList(&PriorityListHead[Priority]);
if (current_entry != &PriorityListHead[Priority])
{
current = CONTAINING_RECORD(current_entry, ETHREAD,
Tcb.QueueListEntry);
}
else
{
current = NULL;
}
return(current);
#else
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
PETHREAD current; PETHREAD current;
@ -179,7 +186,6 @@ static PETHREAD PsScanThreadList (KPRIORITY Priority, ULONG Affinity)
current_entry = current_entry->Flink; current_entry = current_entry->Flink;
} }
return(NULL); return(NULL);
#endif
} }
@ -594,7 +600,7 @@ PsAllocateCallbackStack(ULONG StackSize)
} }
for (i = 0; i < (StackSize / PAGESIZE); i++) for (i = 0; i < (StackSize / PAGESIZE); i++)
{ {
PVOID Page; ULONG_PTR Page;
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page); Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -603,7 +609,7 @@ PsAllocateCallbackStack(ULONG StackSize)
Status = MmCreateVirtualMapping(NULL, Status = MmCreateVirtualMapping(NULL,
KernelStack + (i * PAGESIZE), KernelStack + (i * PAGESIZE),
PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_READWRITE,
(ULONG)Page, Page,
TRUE); TRUE);
} }
return(KernelStack); return(KernelStack);

View file

@ -1,4 +1,4 @@
/* $Id: mem.c,v 1.11 2001/03/16 10:58:47 dwelch Exp $ /* $Id: mem.c,v 1.12 2002/05/13 18:10:41 chorns Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -24,6 +24,8 @@ MmCopyToCaller(PVOID Dest, PVOID Src, ULONG NumberOfBytes)
{ {
NTSTATUS Status; NTSTATUS Status;
//assertmsg(KeGetCurrentIrql() < DISPATCH_LEVEL, ("MmCopyToCaller() called at >= DISPATCH_LEVEL\n"));
if (ExGetPreviousMode() == UserMode) if (ExGetPreviousMode() == UserMode)
{ {
if ((ULONG)Dest >= KERNEL_BASE) if ((ULONG)Dest >= KERNEL_BASE)
@ -45,6 +47,8 @@ MmCopyFromCaller(PVOID Dest, PVOID Src, ULONG NumberOfBytes)
{ {
NTSTATUS Status; NTSTATUS Status;
//assertmsg(KeGetCurrentIrql() < DISPATCH_LEVEL, ("MmCopyFromCaller() called at >= DISPATCH_LEVEL\n"));
if (ExGetPreviousMode() == UserMode) if (ExGetPreviousMode() == UserMode)
{ {
if ((ULONG)Src >= KERNEL_BASE) if ((ULONG)Src >= KERNEL_BASE)