ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mmfault.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.