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 *******************************************************************/
15 #define MODULE_INVOLVED_IN_ARM3
16 #include "ARM3/miarm.h"
18 /* PRIVATE FUNCTIONS **********************************************************/
22 MiSyncForProcessAttach(IN PKTHREAD Thread
,
25 PETHREAD Ethread
= CONTAINING_RECORD(Thread
, ETHREAD
, Tcb
);
27 /* Hack Sync because Mm is broken */
28 MmUpdatePageDir(Process
, Ethread
, sizeof(ETHREAD
));
29 MmUpdatePageDir(Process
, Ethread
->ThreadsProcess
, sizeof(EPROCESS
));
30 MmUpdatePageDir(Process
,
31 (PVOID
)Thread
->StackLimit
,
33 KERNEL_LARGE_STACK_SIZE
: KERNEL_STACK_SIZE
);
38 MiSyncForContextSwitch(IN PKTHREAD Thread
)
40 PVOID Process
= PsGetCurrentProcess();
41 PETHREAD Ethread
= CONTAINING_RECORD(Thread
, ETHREAD
, Tcb
);
43 /* Hack Sync because Mm is broken */
44 MmUpdatePageDir(Process
, Ethread
->ThreadsProcess
, sizeof(EPROCESS
));
45 MmUpdatePageDir(Process
,
46 (PVOID
)Thread
->StackLimit
,
48 KERNEL_LARGE_STACK_SIZE
: KERNEL_STACK_SIZE
);
53 MmpAccessFault(KPROCESSOR_MODE Mode
,
57 PMMSUPPORT AddressSpace
;
58 MEMORY_AREA
* MemoryArea
;
60 BOOLEAN Locked
= FromMdl
;
62 DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode
, Address
);
64 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
66 DPRINT1("Page fault at high IRQL was %d\n", KeGetCurrentIrql());
67 return(STATUS_UNSUCCESSFUL
);
71 * Find the memory area for the faulting address
73 if (Address
>= (ULONG_PTR
)MmSystemRangeStart
)
78 if (Mode
!= KernelMode
)
80 DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode
, Address
);
81 return(STATUS_ACCESS_VIOLATION
);
83 AddressSpace
= MmGetKernelAddressSpace();
87 AddressSpace
= &PsGetCurrentProcess()->Vm
;
92 MmLockAddressSpace(AddressSpace
);
96 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
97 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
101 MmUnlockAddressSpace(AddressSpace
);
103 return (STATUS_ACCESS_VIOLATION
);
106 switch (MemoryArea
->Type
)
108 case MEMORY_AREA_PAGED_POOL
:
109 Status
= STATUS_SUCCESS
;
112 case MEMORY_AREA_SECTION_VIEW
:
113 Status
= MmAccessFaultSectionView(AddressSpace
,
119 case MEMORY_AREA_VIRTUAL_MEMORY
:
120 Status
= STATUS_ACCESS_VIOLATION
;
124 Status
= STATUS_ACCESS_VIOLATION
;
128 while (Status
== STATUS_MM_RESTART_OPERATION
);
130 DPRINT("Completed page fault handling\n");
133 MmUnlockAddressSpace(AddressSpace
);
140 MmNotPresentFault(KPROCESSOR_MODE Mode
,
144 PMMSUPPORT AddressSpace
;
145 MEMORY_AREA
* MemoryArea
;
147 BOOLEAN Locked
= FromMdl
;
149 DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode
, Address
);
151 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
153 DPRINT1("Page fault at high IRQL was %d, address %x\n", KeGetCurrentIrql(), Address
);
154 return(STATUS_UNSUCCESSFUL
);
158 * Find the memory area for the faulting address
160 if (Address
>= (ULONG_PTR
)MmSystemRangeStart
)
165 if (Mode
!= KernelMode
)
167 DPRINT1("Address: %x\n", Address
);
168 return(STATUS_ACCESS_VIOLATION
);
170 AddressSpace
= MmGetKernelAddressSpace();
174 AddressSpace
= &PsGetCurrentProcess()->Vm
;
179 MmLockAddressSpace(AddressSpace
);
183 * Call the memory area specific fault handler
187 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
188 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
192 MmUnlockAddressSpace(AddressSpace
);
194 return (STATUS_ACCESS_VIOLATION
);
197 switch (MemoryArea
->Type
)
199 case MEMORY_AREA_PAGED_POOL
:
201 Status
= MmCommitPagedPoolAddress((PVOID
)Address
, Locked
);
205 case MEMORY_AREA_SECTION_VIEW
:
206 Status
= MmNotPresentFaultSectionView(AddressSpace
,
212 case MEMORY_AREA_VIRTUAL_MEMORY
:
213 Status
= MmNotPresentFaultVirtualMemory(AddressSpace
,
220 Status
= STATUS_ACCESS_VIOLATION
;
224 while (Status
== STATUS_MM_RESTART_OPERATION
);
226 DPRINT("Completed page fault handling\n");
229 MmUnlockAddressSpace(AddressSpace
);
234 extern BOOLEAN
Mmi386MakeKernelPageTableGlobal(PVOID Address
);
238 MmAccessFault(IN BOOLEAN StoreInstruction
,
240 IN KPROCESSOR_MODE Mode
,
241 IN PVOID TrapInformation
)
243 PMEMORY_AREA MemoryArea
;
245 /* Cute little hack for ROS */
246 if ((ULONG_PTR
)Address
>= (ULONG_PTR
)MmSystemRangeStart
)
249 /* Check for an invalid page directory in kernel mode */
250 if (Mmi386MakeKernelPageTableGlobal(Address
))
252 /* All is well with the world */
253 return STATUS_SUCCESS
;
259 * Check if this is an ARM3 memory area or if there's no memory area at all.
260 * The latter can happen early in the boot cycle when ARM3 paged pool is in
261 * use before having defined the memory areas proper.
262 * A proper fix would be to define memory areas in the ARM3 code, but we want
263 * to avoid adding this ReactOS-specific construct to ARM3 code.
264 * Either way, in the future, as ReactOS-paged pool is eliminated, this hack
267 MemoryArea
= MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address
);
268 if (!(MemoryArea
) && (Address
<= MM_HIGHEST_USER_ADDRESS
))
270 /* Could this be a VAD fault from user-mode? */
271 MemoryArea
= MmLocateMemoryAreaByAddress(MmGetCurrentAddressSpace(), Address
);
273 if ((!(MemoryArea
) && ((ULONG_PTR
)Address
>= (ULONG_PTR
)MmPagedPoolStart
)) ||
274 ((MemoryArea
) && (MemoryArea
->Type
== MEMORY_AREA_OWNED_BY_ARM3
)))
277 // Hand it off to more competent hands...
279 DPRINT("ARM3 fault %p\n", MemoryArea
);
280 return MmArmAccessFault(StoreInstruction
, Address
, Mode
, TrapInformation
);
283 /* Keep same old ReactOS Behaviour */
284 if (StoreInstruction
)
286 /* Call access fault */
287 return MmpAccessFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);
291 /* Call not present */
292 return MmNotPresentFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);
298 MmCommitPagedPoolAddress(PVOID Address
, BOOLEAN Locked
)
301 PFN_NUMBER AllocatedPage
;
303 Status
= MmRequestPageMemoryConsumer(MC_PPOOL
, FALSE
, &AllocatedPage
);
304 if (!NT_SUCCESS(Status
))
306 MmUnlockAddressSpace(MmGetKernelAddressSpace());
307 Status
= MmRequestPageMemoryConsumer(MC_PPOOL
, TRUE
, &AllocatedPage
);
308 MmLockAddressSpace(MmGetKernelAddressSpace());
311 MmCreateVirtualMapping(NULL
,
312 (PVOID
)PAGE_ROUND_DOWN(Address
),