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 *******************************************************************/
12 #include <cache/section/newmm.h>
16 #define MODULE_INVOLVED_IN_ARM3
17 #include "ARM3/miarm.h"
19 /* PRIVATE FUNCTIONS **********************************************************/
23 MmpAccessFault(KPROCESSOR_MODE Mode
,
27 PMMSUPPORT AddressSpace
;
28 MEMORY_AREA
* MemoryArea
;
31 DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode
, Address
);
33 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
35 DPRINT1("Page fault at high IRQL was %u\n", KeGetCurrentIrql());
36 return(STATUS_UNSUCCESSFUL
);
40 * Find the memory area for the faulting address
42 if (Address
>= (ULONG_PTR
)MmSystemRangeStart
)
47 if (Mode
!= KernelMode
)
49 DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode
, Address
);
50 return(STATUS_ACCESS_VIOLATION
);
52 AddressSpace
= MmGetKernelAddressSpace();
56 AddressSpace
= &PsGetCurrentProcess()->Vm
;
61 MmLockAddressSpace(AddressSpace
);
65 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
66 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
70 MmUnlockAddressSpace(AddressSpace
);
72 return (STATUS_ACCESS_VIOLATION
);
75 switch (MemoryArea
->Type
)
77 case MEMORY_AREA_SECTION_VIEW
:
78 Status
= MmAccessFaultSectionView(AddressSpace
,
83 case MEMORY_AREA_CACHE
:
84 // This code locks for itself to keep from having to break a lock
87 MmUnlockAddressSpace(AddressSpace
);
88 Status
= MmAccessFaultCacheSection(Mode
, Address
, FromMdl
);
90 MmLockAddressSpace(AddressSpace
);
94 Status
= STATUS_ACCESS_VIOLATION
;
98 while (Status
== STATUS_MM_RESTART_OPERATION
);
100 DPRINT("Completed page fault handling\n");
103 MmUnlockAddressSpace(AddressSpace
);
110 MmNotPresentFault(KPROCESSOR_MODE Mode
,
114 PMMSUPPORT AddressSpace
;
115 MEMORY_AREA
* MemoryArea
;
118 DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode
, Address
);
120 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
122 DPRINT1("Page fault at high IRQL was %u, address %x\n", KeGetCurrentIrql(), Address
);
123 return(STATUS_UNSUCCESSFUL
);
127 * Find the memory area for the faulting address
129 if (Address
>= (ULONG_PTR
)MmSystemRangeStart
)
134 if (Mode
!= KernelMode
)
136 DPRINT1("Address: %x\n", Address
);
137 return(STATUS_ACCESS_VIOLATION
);
139 AddressSpace
= MmGetKernelAddressSpace();
143 AddressSpace
= &PsGetCurrentProcess()->Vm
;
148 MmLockAddressSpace(AddressSpace
);
152 * Call the memory area specific fault handler
156 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
157 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
161 MmUnlockAddressSpace(AddressSpace
);
163 return (STATUS_ACCESS_VIOLATION
);
166 switch (MemoryArea
->Type
)
168 case MEMORY_AREA_SECTION_VIEW
:
169 Status
= MmNotPresentFaultSectionView(AddressSpace
,
175 case MEMORY_AREA_CACHE
:
176 // This code locks for itself to keep from having to break a lock
179 MmUnlockAddressSpace(AddressSpace
);
180 Status
= MmNotPresentFaultCacheSection(Mode
, Address
, FromMdl
);
182 MmLockAddressSpace(AddressSpace
);
186 Status
= STATUS_ACCESS_VIOLATION
;
190 while (Status
== STATUS_MM_RESTART_OPERATION
);
192 DPRINT("Completed page fault handling\n");
195 MmUnlockAddressSpace(AddressSpace
);
200 extern BOOLEAN
Mmi386MakeKernelPageTableGlobal(PVOID Address
);
204 MmAccessFault(IN BOOLEAN StoreInstruction
,
206 IN KPROCESSOR_MODE Mode
,
207 IN PVOID TrapInformation
)
209 PMEMORY_AREA MemoryArea
= NULL
;
211 /* Cute little hack for ROS */
212 if ((ULONG_PTR
)Address
>= (ULONG_PTR
)MmSystemRangeStart
)
215 /* Check for an invalid page directory in kernel mode */
216 if (Mmi386MakeKernelPageTableGlobal(Address
))
218 /* All is well with the world */
219 return STATUS_SUCCESS
;
224 /* Handle shared user page, which doesn't have a VAD / MemoryArea */
225 if (PAGE_ALIGN(Address
) == (PVOID
)MM_SHARED_USER_DATA_VA
)
227 /* This is an ARM3 fault */
228 DPRINT("ARM3 fault %p\n", MemoryArea
);
229 return MmArmAccessFault(StoreInstruction
, Address
, Mode
, TrapInformation
);
232 /* Is there a ReactOS address space yet? */
233 if (MmGetKernelAddressSpace())
235 /* Check if this is an ARM3 memory area */
236 MemoryArea
= MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address
);
237 if (!(MemoryArea
) && (Address
<= MM_HIGHEST_USER_ADDRESS
))
239 /* Could this be a VAD fault from user-mode? */
240 MemoryArea
= MmLocateMemoryAreaByAddress(MmGetCurrentAddressSpace(), Address
);
244 /* Is this an ARM3 memory area, or is there no address space yet? */
245 if (((MemoryArea
) && (MemoryArea
->Type
== MEMORY_AREA_OWNED_BY_ARM3
)) ||
246 (!(MemoryArea
) && ((ULONG_PTR
)Address
>= (ULONG_PTR
)MmPagedPoolStart
)) ||
247 (!MmGetKernelAddressSpace()))
249 /* This is an ARM3 fault */
250 DPRINT("ARM3 fault %p\n", MemoryArea
);
251 return MmArmAccessFault(StoreInstruction
, Address
, Mode
, TrapInformation
);
254 /* Keep same old ReactOS Behaviour */
255 if (StoreInstruction
)
257 /* Call access fault */
258 return MmpAccessFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);
262 /* Call not present */
263 return MmNotPresentFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);