Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmmfault.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: ntoskrnl/mm/mmfault.c 00005 * PURPOSE: Kernel memory managment functions 00006 * PROGRAMMERS: David Welch (welch@cwcom.net) 00007 */ 00008 00009 /* INCLUDES *******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #include "../cache/section/newmm.h" 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 #define MODULE_INVOLVED_IN_ARM3 00017 #include "ARM3/miarm.h" 00018 00019 /* PRIVATE FUNCTIONS **********************************************************/ 00020 00021 NTSTATUS 00022 NTAPI 00023 MmpAccessFault(KPROCESSOR_MODE Mode, 00024 ULONG_PTR Address, 00025 BOOLEAN FromMdl) 00026 { 00027 PMMSUPPORT AddressSpace; 00028 MEMORY_AREA* MemoryArea; 00029 NTSTATUS Status; 00030 00031 DPRINT("MmAccessFault(Mode %d, Address %x)\n", Mode, Address); 00032 00033 if (KeGetCurrentIrql() >= DISPATCH_LEVEL) 00034 { 00035 DPRINT1("Page fault at high IRQL was %d\n", KeGetCurrentIrql()); 00036 return(STATUS_UNSUCCESSFUL); 00037 } 00038 00039 /* 00040 * Find the memory area for the faulting address 00041 */ 00042 if (Address >= (ULONG_PTR)MmSystemRangeStart) 00043 { 00044 /* 00045 * Check permissions 00046 */ 00047 if (Mode != KernelMode) 00048 { 00049 DPRINT1("MmAccessFault(Mode %d, Address %x)\n", Mode, Address); 00050 return(STATUS_ACCESS_VIOLATION); 00051 } 00052 AddressSpace = MmGetKernelAddressSpace(); 00053 } 00054 else 00055 { 00056 AddressSpace = &PsGetCurrentProcess()->Vm; 00057 } 00058 00059 if (!FromMdl) 00060 { 00061 MmLockAddressSpace(AddressSpace); 00062 } 00063 do 00064 { 00065 MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address); 00066 if (MemoryArea == NULL || MemoryArea->DeleteInProgress) 00067 { 00068 if (!FromMdl) 00069 { 00070 MmUnlockAddressSpace(AddressSpace); 00071 } 00072 return (STATUS_ACCESS_VIOLATION); 00073 } 00074 00075 switch (MemoryArea->Type) 00076 { 00077 case MEMORY_AREA_SECTION_VIEW: 00078 Status = MmAccessFaultSectionView(AddressSpace, 00079 MemoryArea, 00080 (PVOID)Address); 00081 break; 00082 00083 case MEMORY_AREA_CACHE: 00084 // This code locks for itself to keep from having to break a lock 00085 // passed in. 00086 if (!FromMdl) 00087 MmUnlockAddressSpace(AddressSpace); 00088 Status = MmAccessFaultCacheSection(Mode, Address, FromMdl); 00089 if (!FromMdl) 00090 MmLockAddressSpace(AddressSpace); 00091 break; 00092 00093 default: 00094 Status = STATUS_ACCESS_VIOLATION; 00095 break; 00096 } 00097 } 00098 while (Status == STATUS_MM_RESTART_OPERATION); 00099 00100 DPRINT("Completed page fault handling\n"); 00101 if (!FromMdl) 00102 { 00103 MmUnlockAddressSpace(AddressSpace); 00104 } 00105 return(Status); 00106 } 00107 00108 NTSTATUS 00109 NTAPI 00110 MmNotPresentFault(KPROCESSOR_MODE Mode, 00111 ULONG_PTR Address, 00112 BOOLEAN FromMdl) 00113 { 00114 PMMSUPPORT AddressSpace; 00115 MEMORY_AREA* MemoryArea; 00116 NTSTATUS Status; 00117 00118 DPRINT("MmNotPresentFault(Mode %d, Address %x)\n", Mode, Address); 00119 00120 if (KeGetCurrentIrql() >= DISPATCH_LEVEL) 00121 { 00122 DPRINT1("Page fault at high IRQL was %d, address %x\n", KeGetCurrentIrql(), Address); 00123 return(STATUS_UNSUCCESSFUL); 00124 } 00125 00126 /* 00127 * Find the memory area for the faulting address 00128 */ 00129 if (Address >= (ULONG_PTR)MmSystemRangeStart) 00130 { 00131 /* 00132 * Check permissions 00133 */ 00134 if (Mode != KernelMode) 00135 { 00136 DPRINT1("Address: %x\n", Address); 00137 return(STATUS_ACCESS_VIOLATION); 00138 } 00139 AddressSpace = MmGetKernelAddressSpace(); 00140 } 00141 else 00142 { 00143 AddressSpace = &PsGetCurrentProcess()->Vm; 00144 } 00145 00146 if (!FromMdl) 00147 { 00148 MmLockAddressSpace(AddressSpace); 00149 } 00150 00151 /* 00152 * Call the memory area specific fault handler 00153 */ 00154 do 00155 { 00156 MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, (PVOID)Address); 00157 if (MemoryArea == NULL || MemoryArea->DeleteInProgress) 00158 { 00159 if (!FromMdl) 00160 { 00161 MmUnlockAddressSpace(AddressSpace); 00162 } 00163 return (STATUS_ACCESS_VIOLATION); 00164 } 00165 00166 switch (MemoryArea->Type) 00167 { 00168 case MEMORY_AREA_SECTION_VIEW: 00169 Status = MmNotPresentFaultSectionView(AddressSpace, 00170 MemoryArea, 00171 (PVOID)Address, 00172 FromMdl); 00173 break; 00174 00175 case MEMORY_AREA_CACHE: 00176 // This code locks for itself to keep from having to break a lock 00177 // passed in. 00178 if (!FromMdl) 00179 MmUnlockAddressSpace(AddressSpace); 00180 Status = MmNotPresentFaultCacheSection(Mode, Address, FromMdl); 00181 if (!FromMdl) 00182 MmLockAddressSpace(AddressSpace); 00183 break; 00184 00185 default: 00186 Status = STATUS_ACCESS_VIOLATION; 00187 break; 00188 } 00189 } 00190 while (Status == STATUS_MM_RESTART_OPERATION); 00191 00192 DPRINT("Completed page fault handling\n"); 00193 if (!FromMdl) 00194 { 00195 MmUnlockAddressSpace(AddressSpace); 00196 } 00197 return(Status); 00198 } 00199 00200 extern BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address); 00201 00202 NTSTATUS 00203 NTAPI 00204 MmAccessFault(IN BOOLEAN StoreInstruction, 00205 IN PVOID Address, 00206 IN KPROCESSOR_MODE Mode, 00207 IN PVOID TrapInformation) 00208 { 00209 PMEMORY_AREA MemoryArea = NULL; 00210 00211 /* Cute little hack for ROS */ 00212 if ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart) 00213 { 00214 #ifdef _M_IX86 00215 /* Check for an invalid page directory in kernel mode */ 00216 if (Mmi386MakeKernelPageTableGlobal(Address)) 00217 { 00218 /* All is well with the world */ 00219 return STATUS_SUCCESS; 00220 } 00221 #endif 00222 } 00223 00224 /* Is there a ReactOS address space yet? */ 00225 if (MmGetKernelAddressSpace()) 00226 { 00227 /* Check if this is an ARM3 memory area */ 00228 MemoryArea = MmLocateMemoryAreaByAddress(MmGetKernelAddressSpace(), Address); 00229 if (!(MemoryArea) && (Address <= MM_HIGHEST_USER_ADDRESS)) 00230 { 00231 /* Could this be a VAD fault from user-mode? */ 00232 MemoryArea = MmLocateMemoryAreaByAddress(MmGetCurrentAddressSpace(), Address); 00233 } 00234 } 00235 00236 /* Is this an ARM3 memory area, or is there no address space yet? */ 00237 if (((MemoryArea) && (MemoryArea->Type == MEMORY_AREA_OWNED_BY_ARM3)) || 00238 (!(MemoryArea) && ((ULONG_PTR)Address >= (ULONG_PTR)MmPagedPoolStart)) || 00239 (!MmGetKernelAddressSpace())) 00240 { 00241 /* This is an ARM3 fault */ 00242 DPRINT("ARM3 fault %p\n", MemoryArea); 00243 return MmArmAccessFault(StoreInstruction, Address, Mode, TrapInformation); 00244 } 00245 00246 /* Keep same old ReactOS Behaviour */ 00247 if (StoreInstruction) 00248 { 00249 /* Call access fault */ 00250 return MmpAccessFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE); 00251 } 00252 else 00253 { 00254 /* Call not present */ 00255 return MmNotPresentFault(Mode, (ULONG_PTR)Address, TrapInformation ? FALSE : TRUE); 00256 } 00257 } 00258 Generated on Sun May 27 2012 04:37:38 for ReactOS by
1.7.6.1
|