-/*
- * ReactOS kernel
- * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
- *
- * 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
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
/* $Id$
*
- * COPYRIGHT: See COPYING in the top directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/mm/rmap.c
- * PURPOSE: kernel memory managment functions
- * PROGRAMMER: David Welch (welch@cwcom.net)
- * UPDATE HISTORY:
- * Created 27/12/01
+ * COPYRIGHT: See COPYING in the top directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/mm/rmap.c
+ * PURPOSE: Kernel memory managment functions
+ *
+ * PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* INCLUDES *****************************************************************/
#define NDEBUG
#include <internal/debug.h>
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, MmInitializeRmapList)
+#endif
+
/* TYPES ********************************************************************/
typedef struct _MM_RMAP_ENTRY
struct _MM_RMAP_ENTRY* Next;
PEPROCESS Process;
PVOID Address;
+#ifdef DBG
+ PVOID Caller;
+#endif
}
MM_RMAP_ENTRY, *PMM_RMAP_ENTRY;
-#define TAG_RMAP TAG('R', 'M', 'A', 'P')
-
/* GLOBALS ******************************************************************/
static FAST_MUTEX RmapListLock;
/* FUNCTIONS ****************************************************************/
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
+NTAPI
MmInitializeRmapList(VOID)
{
ExInitializeFastMutex(&RmapListLock);
}
NTSTATUS
+NTAPI
MmWritePagePhysicalAddress(PFN_TYPE Page)
{
PMM_RMAP_ENTRY entry;
{
KEBUGCHECK(0);
}
- if (Address < (PVOID)KERNEL_BASE)
+ if (Address < MmSystemRangeStart)
{
Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode);
ExReleaseFastMutex(&RmapListLock);
/*
* Lock the address space; then check that the address we are using
* still corresponds to a valid memory area (the page might have been
- * freed or paged out after we read the rmap entry.)
+ * freed or paged out after we read the rmap entry.)
*/
MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
{
MmUnlockAddressSpace(AddressSpace);
- if (Address < (PVOID)KERNEL_BASE)
+ if (Address < MmSystemRangeStart)
{
ObDereferenceObject(Process);
}
Type = MemoryArea->Type;
if (Type == MEMORY_AREA_SECTION_VIEW)
{
- Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress;
-
+ Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+ + MemoryArea->Data.SectionData.ViewOffset;
/*
* Get or create a pageop
*/
if (PageOp == NULL)
{
MmUnlockAddressSpace(AddressSpace);
- if (Address < (PVOID)KERNEL_BASE)
+ if (Address < MmSystemRangeStart)
{
ObDereferenceObject(Process);
}
Status = MmWritePageSectionView(AddressSpace, MemoryArea,
Address, PageOp);
}
- else if (Type == MEMORY_AREA_VIRTUAL_MEMORY)
+ else if ((Type == MEMORY_AREA_VIRTUAL_MEMORY) || (Type == MEMORY_AREA_PEB_OR_TEB))
{
- PageOp = MmGetPageOp(MemoryArea, Address < (PVOID)KERNEL_BASE ? Process->UniqueProcessId : NULL,
+ PageOp = MmGetPageOp(MemoryArea, Address < MmSystemRangeStart ? Process->UniqueProcessId : NULL,
Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE);
if (PageOp == NULL)
{
MmUnlockAddressSpace(AddressSpace);
- if (Address < (PVOID)KERNEL_BASE)
+ if (Address < MmSystemRangeStart)
{
ObDereferenceObject(Process);
}
{
KEBUGCHECK(0);
}
- if (Address < (PVOID)KERNEL_BASE)
+ if (Address < MmSystemRangeStart)
{
ObDereferenceObject(Process);
}
}
NTSTATUS
+NTAPI
MmPageOutPhysicalAddress(PFN_TYPE Page)
{
PMM_RMAP_ENTRY entry;
KEBUGCHECK(0);
}
- if (Address < (PVOID)KERNEL_BASE)
+ if (Address < MmSystemRangeStart)
{
Status = ObReferenceObjectByPointer(Process, PROCESS_ALL_ACCESS, NULL, KernelMode);
ExReleaseFastMutex(&RmapListLock);
if (MemoryArea == NULL || MemoryArea->DeleteInProgress)
{
MmUnlockAddressSpace(AddressSpace);
- if (Address < (PVOID)KERNEL_BASE)
+ if (Address < MmSystemRangeStart)
{
ObDereferenceObject(Process);
}
Type = MemoryArea->Type;
if (Type == MEMORY_AREA_SECTION_VIEW)
{
- Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress;
+ Offset = (ULONG_PTR)Address - (ULONG_PTR)MemoryArea->StartingAddress
+ + MemoryArea->Data.SectionData.ViewOffset;;
/*
* Get or create a pageop
if (PageOp == NULL)
{
MmUnlockAddressSpace(AddressSpace);
- if (Address < (PVOID)KERNEL_BASE)
+ if (Address < MmSystemRangeStart)
{
ObDereferenceObject(Process);
}
Status = MmPageOutSectionView(AddressSpace, MemoryArea,
Address, PageOp);
}
- else if (Type == MEMORY_AREA_VIRTUAL_MEMORY)
+ else if ((Type == MEMORY_AREA_VIRTUAL_MEMORY) || (Type == MEMORY_AREA_PEB_OR_TEB))
{
- PageOp = MmGetPageOp(MemoryArea, Address < (PVOID)KERNEL_BASE ? Process->UniqueProcessId : NULL,
+ PageOp = MmGetPageOp(MemoryArea, Address < MmSystemRangeStart ? Process->UniqueProcessId : NULL,
Address, NULL, 0, MM_PAGEOP_PAGEOUT, TRUE);
if (PageOp == NULL)
{
MmUnlockAddressSpace(AddressSpace);
- if (Address < (PVOID)KERNEL_BASE)
+ if (Address < MmSystemRangeStart)
{
ObDereferenceObject(Process);
}
{
KEBUGCHECK(0);
}
- if (Address < (PVOID)KERNEL_BASE)
+ if (Address < MmSystemRangeStart)
{
ObDereferenceObject(Process);
}
}
VOID
+NTAPI
MmSetCleanAllRmaps(PFN_TYPE Page)
{
PMM_RMAP_ENTRY current_entry;
}
VOID
+NTAPI
MmSetDirtyAllRmaps(PFN_TYPE Page)
{
PMM_RMAP_ENTRY current_entry;
}
BOOL
+NTAPI
MmIsDirtyPageRmap(PFN_TYPE Page)
{
PMM_RMAP_ENTRY current_entry;
}
VOID
+NTAPI
MmInsertRmap(PFN_TYPE Page, PEPROCESS Process,
PVOID Address)
{
}
new_entry->Address = Address;
new_entry->Process = Process;
+#ifdef DBG
+ new_entry->Caller = __builtin_return_address(0);
+#endif
if (MmGetPfnForProcess(Process, Address) != Page)
{
ExAcquireFastMutex(&RmapListLock);
current_entry = MmGetRmapListHeadPage(Page);
new_entry->Next = current_entry;
+#ifdef DBG
+ while (current_entry)
+ {
+ if (current_entry->Address == new_entry->Address && current_entry->Process == new_entry->Process)
+ {
+ DbgPrint("MmInsertRmap tries to add a second rmap entry for address %p\n current caller ",
+ current_entry->Address);
+ KeRosPrintAddress(new_entry->Caller);
+ DbgPrint("\n previous caller ");
+ KeRosPrintAddress(current_entry->Caller);
+ DbgPrint("\n");
+ KeBugCheck(0);
+ }
+ current_entry = current_entry->Next;
+ }
+#endif
MmSetRmapListHeadPage(Page, new_entry);
ExReleaseFastMutex(&RmapListLock);
if (Process == NULL)
}
VOID
+NTAPI
MmDeleteAllRmaps(PFN_TYPE Page, PVOID Context,
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process,
PVOID Address))
KEBUGCHECK(0);
}
MmSetRmapListHeadPage(Page, NULL);
+ ExReleaseFastMutex(&RmapListLock);
while (current_entry != NULL)
{
previous_entry = current_entry;
InterlockedExchangeAddUL(&Process->Vm.WorkingSetSize, -PAGE_SIZE);
}
}
- ExReleaseFastMutex(&RmapListLock);
}
VOID
+NTAPI
MmDeleteRmap(PFN_TYPE Page, PEPROCESS Process,
PVOID Address)
{