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_SYSTEM
:
109 Status
= STATUS_ACCESS_VIOLATION
;
112 case MEMORY_AREA_PAGED_POOL
:
113 Status
= STATUS_SUCCESS
;
116 case MEMORY_AREA_SECTION_VIEW
:
117 Status
= MmAccessFaultSectionView(AddressSpace
,
123 case MEMORY_AREA_VIRTUAL_MEMORY
:
124 Status
= STATUS_ACCESS_VIOLATION
;
127 case MEMORY_AREA_SHARED_DATA
:
128 Status
= STATUS_ACCESS_VIOLATION
;
132 Status
= STATUS_ACCESS_VIOLATION
;
136 while (Status
== STATUS_MM_RESTART_OPERATION
);
138 DPRINT("Completed page fault handling\n");
141 MmUnlockAddressSpace(AddressSpace
);
148 MmNotPresentFault(KPROCESSOR_MODE Mode
,
152 PMMSUPPORT AddressSpace
;
153 MEMORY_AREA
* MemoryArea
;
155 BOOLEAN Locked
= FromMdl
;
156 extern PMMPTE MmSharedUserDataPte
;
158 DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode
, Address
);
160 if (KeGetCurrentIrql() >= DISPATCH_LEVEL
)
162 DPRINT1("Page fault at high IRQL was %d, address %x\n", KeGetCurrentIrql(), Address
);
163 return(STATUS_UNSUCCESSFUL
);
167 * Find the memory area for the faulting address
169 if (Address
>= (ULONG_PTR
)MmSystemRangeStart
)
174 if (Mode
!= KernelMode
)
176 DPRINT1("Address: %x\n", Address
);
177 return(STATUS_ACCESS_VIOLATION
);
179 AddressSpace
= MmGetKernelAddressSpace();
183 AddressSpace
= &PsGetCurrentProcess()->Vm
;
188 MmLockAddressSpace(AddressSpace
);
192 * Call the memory area specific fault handler
196 MemoryArea
= MmLocateMemoryAreaByAddress(AddressSpace
, (PVOID
)Address
);
197 if (MemoryArea
== NULL
|| MemoryArea
->DeleteInProgress
)
201 MmUnlockAddressSpace(AddressSpace
);
203 return (STATUS_ACCESS_VIOLATION
);
206 switch (MemoryArea
->Type
)
208 case MEMORY_AREA_PAGED_POOL
:
210 Status
= MmCommitPagedPoolAddress((PVOID
)Address
, Locked
);
214 case MEMORY_AREA_SYSTEM
:
215 Status
= STATUS_ACCESS_VIOLATION
;
218 case MEMORY_AREA_SECTION_VIEW
:
219 Status
= MmNotPresentFaultSectionView(AddressSpace
,
225 case MEMORY_AREA_VIRTUAL_MEMORY
:
226 case MEMORY_AREA_PEB_OR_TEB
:
227 Status
= MmNotPresentFaultVirtualMemory(AddressSpace
,
233 case MEMORY_AREA_SHARED_DATA
:
234 *MiAddressToPte(USER_SHARED_DATA
) = *MmSharedUserDataPte
;
235 Status
= STATUS_SUCCESS
;
239 Status
= STATUS_ACCESS_VIOLATION
;
243 while (Status
== STATUS_MM_RESTART_OPERATION
);
245 DPRINT("Completed page fault handling\n");
248 MmUnlockAddressSpace(AddressSpace
);
253 extern BOOLEAN
Mmi386MakeKernelPageTableGlobal(PVOID Address
);
257 MmAccessFault(IN BOOLEAN StoreInstruction
,
259 IN KPROCESSOR_MODE Mode
,
260 IN PVOID TrapInformation
)
262 PMEMORY_AREA MemoryArea
;
264 /* Cute little hack for ROS */
265 if ((ULONG_PTR
)Address
>= (ULONG_PTR
)MmSystemRangeStart
)
268 /* Check for an invalid page directory in kernel mode */
269 if (Mmi386MakeKernelPageTableGlobal(Address
))
271 /* All is well with the world */
272 return STATUS_SUCCESS
;
278 * Check if this is an ARM3 memory area or if there's no memory area at all.
279 * The latter can happen early in the boot cycle when ARM3 paged pool is in
280 * use before having defined the memory areas proper.
281 * A proper fix would be to define memory areas in the ARM3 code, but we want
282 * to avoid adding this ReactOS-specific construct to ARM3 code.
283 * Either way, in the future, as ReactOS-paged pool is eliminated, this hack
286 MemoryArea
= MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address
);
287 if ((!(MemoryArea
) && ((ULONG_PTR
)Address
>= (ULONG_PTR
)MmPagedPoolStart
)) ||
288 ((MemoryArea
) && (MemoryArea
->Type
== MEMORY_AREA_OWNED_BY_ARM3
)))
291 // Hand it off to more competent hands...
293 DPRINT("ARM3 fault %p\n", MemoryArea
);
294 return MmArmAccessFault(StoreInstruction
, Address
, Mode
, TrapInformation
);
297 /* Keep same old ReactOS Behaviour */
298 if (StoreInstruction
)
300 /* Call access fault */
301 return MmpAccessFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);
305 /* Call not present */
306 return MmNotPresentFault(Mode
, (ULONG_PTR
)Address
, TrapInformation
? FALSE
: TRUE
);
312 MmCommitPagedPoolAddress(PVOID Address
, BOOLEAN Locked
)
315 PFN_TYPE AllocatedPage
;
317 Status
= MmRequestPageMemoryConsumer(MC_PPOOL
, FALSE
, &AllocatedPage
);
318 if (!NT_SUCCESS(Status
))
320 MmUnlockAddressSpace(MmGetKernelAddressSpace());
321 Status
= MmRequestPageMemoryConsumer(MC_PPOOL
, TRUE
, &AllocatedPage
);
322 MmLockAddressSpace(MmGetKernelAddressSpace());
325 MmCreateVirtualMapping(NULL
,
326 (PVOID
)PAGE_ROUND_DOWN(Address
),