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
;
33 DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode
, Address
);
35 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
37 DPRINT1("Page fault at high IRQL was %d\n", KeGetCurrentIrql());
38 return(STATUS_UNSUCCESSFUL
);
42 * Find the memory area for the faulting address
44 if (Address
>= (ULONG_PTR
)MmSystemRangeStart
)
49 if (Mode
!= KernelMode
)
51 DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode
, Address
);
52 return(STATUS_ACCESS_VIOLATION
);
54 AddressSpace
= MmGetKernelAddressSpace();
58 AddressSpace
= &PsGetCurrentProcess()->Vm
;
63 MmLockAddressSpace(AddressSpace
);
67 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
68 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
72 MmUnlockAddressSpace(AddressSpace
);
74 return (STATUS_ACCESS_VIOLATION
);
77 switch (MemoryArea
->Type
)
79 case MEMORY_AREA_SECTION_VIEW
:
80 Status
= MmAccessFaultSectionView(AddressSpace
,
85 case MEMORY_AREA_VIRTUAL_MEMORY
:
86 Status
= STATUS_ACCESS_VIOLATION
;
90 case MEMORY_AREA_CACHE
:
91 // This code locks for itself to keep from having to break a lock
94 MmUnlockAddressSpace(AddressSpace
);
95 Status
= MmAccessFaultCacheSection(Mode
, Address
, Locked
);
97 MmLockAddressSpace(AddressSpace
);
102 Status
= STATUS_ACCESS_VIOLATION
;
106 while (Status
== STATUS_MM_RESTART_OPERATION
);
108 DPRINT("Completed page fault handling\n");
111 MmUnlockAddressSpace(AddressSpace
);
118 MmNotPresentFault(KPROCESSOR_MODE Mode
,
122 PMMSUPPORT AddressSpace
;
123 MEMORY_AREA
* MemoryArea
;
126 DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode
, Address
);
128 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
130 DPRINT1("Page fault at high IRQL was %d, address %x\n", KeGetCurrentIrql(), Address
);
131 return(STATUS_UNSUCCESSFUL
);
135 * Find the memory area for the faulting address
137 if (Address
>= (ULONG_PTR
)MmSystemRangeStart
)
142 if (Mode
!= KernelMode
)
144 DPRINT1("Address: %x\n", Address
);
145 return(STATUS_ACCESS_VIOLATION
);
147 AddressSpace
= MmGetKernelAddressSpace();
151 AddressSpace
= &PsGetCurrentProcess()->Vm
;
156 MmLockAddressSpace(AddressSpace
);
160 * Call the memory area specific fault handler
164 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
165 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
169 MmUnlockAddressSpace(AddressSpace
);
171 return (STATUS_ACCESS_VIOLATION
);
174 switch (MemoryArea
->Type
)
176 case MEMORY_AREA_SECTION_VIEW
:
177 Status
= MmNotPresentFaultSectionView(AddressSpace
,
182 case MEMORY_AREA_VIRTUAL_MEMORY
:
183 Status
= MmNotPresentFaultVirtualMemory(AddressSpace
,
189 case MEMORY_AREA_CACHE
:
190 // This code locks for itself to keep from having to break a lock
193 MmUnlockAddressSpace(AddressSpace
);
194 Status
= MmNotPresentFaultCacheSection(Mode
, Address
, Locked
);
196 MmLockAddressSpace(AddressSpace
);
201 Status
= STATUS_ACCESS_VIOLATION
;
205 while (Status
== STATUS_MM_RESTART_OPERATION
);
207 DPRINT("Completed page fault handling\n");
210 MmUnlockAddressSpace(AddressSpace
);
215 extern BOOLEAN
Mmi386MakeKernelPageTableGlobal(PVOID Address
);
219 MmAccessFault(IN BOOLEAN StoreInstruction
,
221 IN KPROCESSOR_MODE Mode
,
222 IN PVOID TrapInformation
)
224 PMEMORY_AREA MemoryArea
= NULL
;
226 /* Cute little hack for ROS */
227 if ((ULONG_PTR
)Address
>= (ULONG_PTR
)MmSystemRangeStart
)
230 /* Check for an invalid page directory in kernel mode */
231 if (Mmi386MakeKernelPageTableGlobal(Address
))
233 /* All is well with the world */
234 return STATUS_SUCCESS
;
239 /* Is there a ReactOS address space yet? */
240 if (MmGetKernelAddressSpace())
242 /* Check if this is an ARM3 memory area */
243 MemoryArea
= MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address
);
244 if (!(MemoryArea
) && (Address
<= MM_HIGHEST_USER_ADDRESS
))
246 /* Could this be a VAD fault from user-mode? */
247 MemoryArea
= MmLocateMemoryAreaByAddress(MmGetCurrentAddressSpace(), Address
);
251 /* Is this an ARM3 memory area, or is there no address space yet? */
252 if (((MemoryArea
) && (MemoryArea
->Type
== MEMORY_AREA_OWNED_BY_ARM3
)) ||
253 (!(MemoryArea
) && ((ULONG_PTR
)Address
>= (ULONG_PTR
)MmPagedPoolStart
)) ||
254 (!MmGetKernelAddressSpace()))
256 /* This is an ARM3 fault */
257 DPRINT("ARM3 fault %p\n", MemoryArea
);
258 return MmArmAccessFault(StoreInstruction
, Address
, Mode
, TrapInformation
);
261 /* Keep same old ReactOS Behaviour */
262 if (StoreInstruction
)
264 /* Call access fault */
265 return MmpAccessFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);
269 /* Call not present */
270 return MmNotPresentFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);