2 * COPYRIGHT: See COPYING in the top directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/mm/mmfault.c
5 * PURPOSE: Kernel memory managment functions
6 * PROGRAMMERS: David Welch (welch@cwcom.net)
9 /* INCLUDES *******************************************************************/
13 #include "../cache/section/newmm.h"
18 #define MODULE_INVOLVED_IN_ARM3
19 #include "ARM3/miarm.h"
21 /* PRIVATE FUNCTIONS **********************************************************/
25 MmpAccessFault(KPROCESSOR_MODE Mode
,
29 PMMSUPPORT AddressSpace
;
30 MEMORY_AREA
* MemoryArea
;
32 BOOLEAN Locked
= FromMdl
;
34 DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode
, Address
);
36 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
38 DPRINT1("Page fault at high IRQL was %d\n", KeGetCurrentIrql());
39 return(STATUS_UNSUCCESSFUL
);
43 * Find the memory area for the faulting address
45 if (Address
>= (ULONG_PTR
)MmSystemRangeStart
)
50 if (Mode
!= KernelMode
)
52 DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode
, Address
);
53 return(STATUS_ACCESS_VIOLATION
);
55 AddressSpace
= MmGetKernelAddressSpace();
59 AddressSpace
= &PsGetCurrentProcess()->Vm
;
64 MmLockAddressSpace(AddressSpace
);
68 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
69 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
73 MmUnlockAddressSpace(AddressSpace
);
75 return (STATUS_ACCESS_VIOLATION
);
78 switch (MemoryArea
->Type
)
80 case MEMORY_AREA_SECTION_VIEW
:
81 Status
= MmAccessFaultSectionView(AddressSpace
,
87 case MEMORY_AREA_VIRTUAL_MEMORY
:
88 Status
= STATUS_ACCESS_VIOLATION
;
92 case MEMORY_AREA_CACHE
:
93 // This code locks for itself to keep from having to break a lock
96 MmUnlockAddressSpace(AddressSpace
);
97 Status
= MmAccessFaultCacheSection(Mode
, Address
, Locked
);
99 MmLockAddressSpace(AddressSpace
);
104 Status
= STATUS_ACCESS_VIOLATION
;
108 while (Status
== STATUS_MM_RESTART_OPERATION
);
110 DPRINT("Completed page fault handling\n");
113 MmUnlockAddressSpace(AddressSpace
);
120 MmNotPresentFault(KPROCESSOR_MODE Mode
,
124 PMMSUPPORT AddressSpace
;
125 MEMORY_AREA
* MemoryArea
;
127 BOOLEAN Locked
= FromMdl
;
129 DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode
, Address
);
131 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
133 DPRINT1("Page fault at high IRQL was %d, address %x\n", KeGetCurrentIrql(), Address
);
134 return(STATUS_UNSUCCESSFUL
);
138 * Find the memory area for the faulting address
140 if (Address
>= (ULONG_PTR
)MmSystemRangeStart
)
145 if (Mode
!= KernelMode
)
147 DPRINT1("Address: %x\n", Address
);
148 return(STATUS_ACCESS_VIOLATION
);
150 AddressSpace
= MmGetKernelAddressSpace();
154 AddressSpace
= &PsGetCurrentProcess()->Vm
;
159 MmLockAddressSpace(AddressSpace
);
163 * Call the memory area specific fault handler
167 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
168 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
172 MmUnlockAddressSpace(AddressSpace
);
174 return (STATUS_ACCESS_VIOLATION
);
177 switch (MemoryArea
->Type
)
179 case MEMORY_AREA_SECTION_VIEW
:
180 Status
= MmNotPresentFaultSectionView(AddressSpace
,
186 case MEMORY_AREA_VIRTUAL_MEMORY
:
187 Status
= MmNotPresentFaultVirtualMemory(AddressSpace
,
194 case MEMORY_AREA_CACHE
:
195 // This code locks for itself to keep from having to break a lock
198 MmUnlockAddressSpace(AddressSpace
);
199 Status
= MmNotPresentFaultCacheSection(Mode
, Address
, Locked
);
201 MmLockAddressSpace(AddressSpace
);
206 Status
= STATUS_ACCESS_VIOLATION
;
210 while (Status
== STATUS_MM_RESTART_OPERATION
);
212 DPRINT("Completed page fault handling\n");
215 MmUnlockAddressSpace(AddressSpace
);
220 extern BOOLEAN
Mmi386MakeKernelPageTableGlobal(PVOID Address
);
224 MmAccessFault(IN BOOLEAN StoreInstruction
,
226 IN KPROCESSOR_MODE Mode
,
227 IN PVOID TrapInformation
)
229 PMEMORY_AREA MemoryArea
= NULL
;
231 /* Cute little hack for ROS */
232 if ((ULONG_PTR
)Address
>= (ULONG_PTR
)MmSystemRangeStart
)
235 /* Check for an invalid page directory in kernel mode */
236 if (Mmi386MakeKernelPageTableGlobal(Address
))
238 /* All is well with the world */
239 return STATUS_SUCCESS
;
244 /* Is there a ReactOS address space yet? */
245 if (MmGetKernelAddressSpace())
247 /* Check if this is an ARM3 memory area */
248 MemoryArea
= MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address
);
249 if (!(MemoryArea
) && (Address
<= MM_HIGHEST_USER_ADDRESS
))
251 /* Could this be a VAD fault from user-mode? */
252 MemoryArea
= MmLocateMemoryAreaByAddress(MmGetCurrentAddressSpace(), Address
);
256 /* Is this an ARM3 memory area, or is there no address space yet? */
257 if (((MemoryArea
) && (MemoryArea
->Type
== MEMORY_AREA_OWNED_BY_ARM3
)) ||
258 (!(MemoryArea
) && ((ULONG_PTR
)Address
>= (ULONG_PTR
)MmPagedPoolStart
)) ||
259 (!MmGetKernelAddressSpace()))
261 /* This is an ARM3 fault */
262 DPRINT("ARM3 fault %p\n", MemoryArea
);
263 return MmArmAccessFault(StoreInstruction
, Address
, Mode
, TrapInformation
);
266 /* Keep same old ReactOS Behaviour */
267 if (StoreInstruction
)
269 /* Call access fault */
270 return MmpAccessFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);
274 /* Call not present */
275 return MmNotPresentFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);