2 * COPYRIGHT: See COPYING in the top directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/mm/mm.c
5 * PURPOSE: Kernel memory managment functions
6 * PROGRAMMERS: David Welch (welch@cwcom.net)
9 /* INCLUDES *****************************************************************/
13 #include <internal/debug.h>
15 /* GLOBALS *****************************************************************/
17 ULONG MmUserProbeAddress
= 0;
18 PVOID MmHighestUserAddress
= NULL
;
19 PBOOLEAN Mm64BitPhysicalAddress
= FALSE
;
20 PVOID MmSystemRangeStart
= NULL
;
21 ULONG MmReadClusterSize
;
25 /* FUNCTIONS ****************************************************************/
30 BOOLEAN NTAPI
MmIsNonPagedSystemAddressValid(PVOID VirtualAddress
)
32 return MmIsAddressValid(VirtualAddress
);
38 BOOLEAN NTAPI
MmIsAddressValid(PVOID VirtualAddress
)
40 * FUNCTION: Checks whether the given address is valid for a read or write
42 * VirtualAddress = address to check
43 * RETURNS: True if the access would be valid
44 * False if the access would cause a page fault
45 * NOTES: This function checks whether a byte access to the page would
46 * succeed. Is this realistic for RISC processors which don't
47 * allow byte granular access?
50 MEMORY_AREA
* MemoryArea
;
51 PMM_AVL_TABLE AddressSpace
;
53 if (VirtualAddress
>= MmSystemRangeStart
)
55 AddressSpace
= MmGetKernelAddressSpace();
59 AddressSpace
= &PsGetCurrentProcess()->VadRoot
;
62 MmLockAddressSpace(AddressSpace
);
63 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
,
66 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
68 MmUnlockAddressSpace(AddressSpace
);
71 MmUnlockAddressSpace(AddressSpace
);
77 MmpAccessFault(KPROCESSOR_MODE Mode
,
81 PMM_AVL_TABLE AddressSpace
;
82 MEMORY_AREA
* MemoryArea
;
84 BOOLEAN Locked
= FromMdl
;
86 DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode
, Address
);
88 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
90 CPRINT("Page fault at high IRQL was %d\n", KeGetCurrentIrql());
91 return(STATUS_UNSUCCESSFUL
);
93 if (PsGetCurrentProcess() == NULL
)
95 DPRINT("No current process\n");
96 return(STATUS_UNSUCCESSFUL
);
100 * Find the memory area for the faulting address
102 if (Address
>= (ULONG_PTR
)MmSystemRangeStart
)
107 if (Mode
!= KernelMode
)
109 DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode
, Address
);
110 DbgPrint("%s:%d\n",__FILE__
,__LINE__
);
111 return(STATUS_ACCESS_VIOLATION
);
113 AddressSpace
= MmGetKernelAddressSpace();
117 AddressSpace
= &PsGetCurrentProcess()->VadRoot
;
122 MmLockAddressSpace(AddressSpace
);
126 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
127 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
131 MmUnlockAddressSpace(AddressSpace
);
133 return (STATUS_ACCESS_VIOLATION
);
136 switch (MemoryArea
->Type
)
138 case MEMORY_AREA_SYSTEM
:
139 Status
= STATUS_ACCESS_VIOLATION
;
142 case MEMORY_AREA_PAGED_POOL
:
143 Status
= STATUS_SUCCESS
;
146 case MEMORY_AREA_SECTION_VIEW
:
147 Status
= MmAccessFaultSectionView(AddressSpace
,
153 case MEMORY_AREA_VIRTUAL_MEMORY
:
154 Status
= STATUS_ACCESS_VIOLATION
;
157 case MEMORY_AREA_SHARED_DATA
:
158 Status
= STATUS_ACCESS_VIOLATION
;
162 Status
= STATUS_ACCESS_VIOLATION
;
166 while (Status
== STATUS_MM_RESTART_OPERATION
);
168 DPRINT("Completed page fault handling\n");
171 MmUnlockAddressSpace(AddressSpace
);
178 MmNotPresentFault(KPROCESSOR_MODE Mode
,
182 PMM_AVL_TABLE AddressSpace
;
183 MEMORY_AREA
* MemoryArea
;
185 BOOLEAN Locked
= FromMdl
;
188 DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode
, Address
);
190 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
192 CPRINT("Page fault at high IRQL was %d, address %x\n", KeGetCurrentIrql(), Address
);
193 return(STATUS_UNSUCCESSFUL
);
197 * Find the memory area for the faulting address
199 if (Address
>= (ULONG_PTR
)MmSystemRangeStart
)
204 if (Mode
!= KernelMode
)
206 CPRINT("Address: %x\n", Address
);
207 return(STATUS_ACCESS_VIOLATION
);
209 AddressSpace
= MmGetKernelAddressSpace();
213 AddressSpace
= &PsGetCurrentProcess()->VadRoot
;
218 MmLockAddressSpace(AddressSpace
);
222 * Call the memory area specific fault handler
226 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
227 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
231 MmUnlockAddressSpace(AddressSpace
);
233 return (STATUS_ACCESS_VIOLATION
);
236 switch (MemoryArea
->Type
)
238 case MEMORY_AREA_PAGED_POOL
:
240 Status
= MmCommitPagedPoolAddress((PVOID
)Address
, Locked
);
244 case MEMORY_AREA_SYSTEM
:
245 Status
= STATUS_ACCESS_VIOLATION
;
248 case MEMORY_AREA_SECTION_VIEW
:
249 Status
= MmNotPresentFaultSectionView(AddressSpace
,
255 case MEMORY_AREA_VIRTUAL_MEMORY
:
256 case MEMORY_AREA_PEB_OR_TEB
:
257 Status
= MmNotPresentFaultVirtualMemory(AddressSpace
,
263 case MEMORY_AREA_SHARED_DATA
:
264 Pfn
= MmSharedDataPagePhysicalAddress
.LowPart
>> PAGE_SHIFT
;
266 MmCreateVirtualMapping(PsGetCurrentProcess(),
267 (PVOID
)PAGE_ROUND_DOWN(Address
),
274 Status
= STATUS_ACCESS_VIOLATION
;
278 while (Status
== STATUS_MM_RESTART_OPERATION
);
280 DPRINT("Completed page fault handling\n");
283 MmUnlockAddressSpace(AddressSpace
);
288 extern BOOLEAN
Mmi386MakeKernelPageTableGlobal(PVOID Address
);
292 MmAccessFault(IN BOOLEAN StoreInstruction
,
294 IN KPROCESSOR_MODE Mode
,
295 IN PVOID TrapInformation
)
297 /* Cute little hack for ROS */
298 if ((ULONG_PTR
)Address
>= (ULONG_PTR
)MmSystemRangeStart
)
301 /* Check for an invalid page directory in kernel mode */
302 if (Mmi386MakeKernelPageTableGlobal(Address
))
304 /* All is well with the world */
305 return STATUS_SUCCESS
;
310 /* Keep same old ReactOS Behaviour */
311 if (StoreInstruction
)
313 /* Call access fault */
314 return MmpAccessFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);
318 /* Call not present */
319 return MmNotPresentFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);
325 MmCommitPagedPoolAddress(PVOID Address
, BOOLEAN Locked
)
328 PFN_TYPE AllocatedPage
;
329 Status
= MmRequestPageMemoryConsumer(MC_PPOOL
, FALSE
, &AllocatedPage
);
330 if (!NT_SUCCESS(Status
))
332 MmUnlockAddressSpace(MmGetKernelAddressSpace());
333 Status
= MmRequestPageMemoryConsumer(MC_PPOOL
, TRUE
, &AllocatedPage
);
334 MmLockAddressSpace(MmGetKernelAddressSpace());
337 MmCreateVirtualMapping(NULL
,
338 (PVOID
)PAGE_ROUND_DOWN(Address
),
344 MmLockPage(AllocatedPage
);
351 /* Miscellanea functions: they may fit somewhere else */
357 MmAdjustWorkingSetSize (ULONG Unknown0
,
370 MmSetAddressRangeModified (
381 NtGetWriteWatch(IN HANDLE ProcessHandle
,
383 IN PVOID BaseAddress
,
385 IN PVOID
*UserAddressArray
,
386 OUT PULONG EntriesInUserAddressArray
,
387 OUT PULONG Granularity
)
390 return STATUS_NOT_IMPLEMENTED
;
395 NtResetWriteWatch(IN HANDLE ProcessHandle
,
396 IN PVOID BaseAddress
,
400 return STATUS_NOT_IMPLEMENTED
;