ReactOS  0.4.14-dev-55-g2da92ac
fault.c File Reference
#include <ntoskrnl.h>
#include "newmm.h"
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for fault.c:

Go to the source code of this file.

Classes

struct  _WORK_QUEUE_WITH_CONTEXT
 

Macros

#define NDEBUG
 
#define DPRINTC   DPRINT
 

Typedefs

typedef struct _WORK_QUEUE_WITH_CONTEXT WORK_QUEUE_WITH_CONTEXT
 
typedef struct _WORK_QUEUE_WITH_CONTEXTPWORK_QUEUE_WITH_CONTEXT
 

Functions

NTSTATUS NTAPI MmNotPresentFaultCachePage (_In_ PMMSUPPORT AddressSpace, _In_ MEMORY_AREA *MemoryArea, _In_ PVOID Address, _In_ BOOLEAN Locked, _Inout_ PMM_REQUIRED_RESOURCES Required)
 
NTSTATUS NTAPI MiCopyPageToPage (PFN_NUMBER DestPage, PFN_NUMBER SrcPage)
 
NTSTATUS NTAPI MiCowCacheSectionPage (_In_ PMMSUPPORT AddressSpace, _In_ PMEMORY_AREA MemoryArea, _In_ PVOID Address, _In_ BOOLEAN Locked, _Inout_ PMM_REQUIRED_RESOURCES Required)
 
 _Function_class_ (WORKER_THREAD_ROUTINE)
 
NTSTATUS NTAPI MmpSectionAccessFaultInner (KPROCESSOR_MODE Mode, PMMSUPPORT AddressSpace, ULONG_PTR Address, BOOLEAN FromMdl, PETHREAD Thread)
 
NTSTATUS NTAPI MmAccessFaultCacheSection (KPROCESSOR_MODE Mode, ULONG_PTR Address, BOOLEAN FromMdl)
 
NTSTATUS NTAPI MmNotPresentFaultCacheSectionInner (KPROCESSOR_MODE Mode, PMMSUPPORT AddressSpace, ULONG_PTR Address, BOOLEAN FromMdl, PETHREAD Thread)
 
NTSTATUS NTAPI MmNotPresentFaultCacheSection (KPROCESSOR_MODE Mode, ULONG_PTR Address, BOOLEAN FromMdl)
 

Variables

KEVENT MmWaitPageEvent
 
PMMWSL MmWorkingSetList
 

Macro Definition Documentation

◆ DPRINTC

#define DPRINTC   DPRINT

Definition at line 82 of file fault.c.

◆ NDEBUG

#define NDEBUG

Definition at line 78 of file fault.c.

Typedef Documentation

◆ PWORK_QUEUE_WITH_CONTEXT

◆ WORK_QUEUE_WITH_CONTEXT

Function Documentation

◆ _Function_class_()

_Function_class_ ( WORKER_THREAD_ROUTINE  )

Definition at line 479 of file fault.c.

483 {
485 
486  DPRINT("Calling work\n");
487  WorkItem->Status = WorkItem->Required->DoAcquisition(WorkItem->AddressSpace,
488  WorkItem->MemoryArea,
489  WorkItem->Required);
490  DPRINT("Status %x\n", WorkItem->Status);
491  KeSetEvent(&WorkItem->Wait, IO_NO_INCREMENT, FALSE);
492 }
AcquireResource DoAcquisition
Definition: newmm.h:89
_In_ PVOID Parameter
Definition: ldrtypes.h:241
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
PMMSUPPORT AddressSpace
Definition: fault.c:462
void DPRINT(...)
Definition: polytest.cpp:61
PMM_REQUIRED_RESOURCES Required
Definition: fault.c:464
PMEMORY_AREA MemoryArea
Definition: fault.c:463
#define IO_NO_INCREMENT
Definition: iotypes.h:566

◆ MiCopyPageToPage()

NTSTATUS NTAPI MiCopyPageToPage ( PFN_NUMBER  DestPage,
PFN_NUMBER  SrcPage 
)

Definition at line 282 of file fault.c.

283 {
285  KIRQL Irql, Irql2;
286  PVOID TempAddress, TempSource;
287 
289  TempAddress = MiMapPageInHyperSpace(Process, DestPage, &Irql);
290  if (TempAddress == NULL)
291  {
292  return STATUS_NO_MEMORY;
293  }
294  TempSource = MiMapPageInHyperSpace(Process, SrcPage, &Irql2);
295  if (!TempSource) {
296  MiUnmapPageInHyperSpace(Process, TempAddress, Irql);
297  return STATUS_NO_MEMORY;
298  }
299 
300  memcpy(TempAddress, TempSource, PAGE_SIZE);
301 
302  MiUnmapPageInHyperSpace(Process, TempSource, Irql2);
303  MiUnmapPageInHyperSpace(Process, TempAddress, Irql);
304  return STATUS_SUCCESS;
305 }
_Out_ PKIRQL Irql
Definition: csq.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentProcess
Definition: psfuncs.h:17
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:30
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:93
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
return STATUS_SUCCESS
Definition: btrfs.c:2966

Referenced by MiCowCacheSectionPage().

◆ MiCowCacheSectionPage()

NTSTATUS NTAPI MiCowCacheSectionPage ( _In_ PMMSUPPORT  AddressSpace,
_In_ PMEMORY_AREA  MemoryArea,
_In_ PVOID  Address,
_In_ BOOLEAN  Locked,
_Inout_ PMM_REQUIRED_RESOURCES  Required 
)

Definition at line 321 of file fault.c.

327 {
329  PFN_NUMBER NewPage, OldPage;
331  PVOID PAddress;
334 
335  DPRINT("MmAccessFaultSectionView(%p, %p, %p, %u)\n",
336  AddressSpace,
337  MemoryArea,
338  Address,
339  Locked);
340 
341  Segment = MemoryArea->Data.SectionData.Segment;
342 
343  /* Lock the segment */
345 
346  /* Find the offset of the page */
347  PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
348  Offset.QuadPart = (ULONG_PTR)PAddress - MA_GetStartingAddress(MemoryArea) +
349  MemoryArea->Data.SectionData.ViewOffset.QuadPart;
350 
351  if (!Segment->WriteCopy /*&&
352  !MemoryArea->Data.SectionData.WriteCopyView*/ ||
353  Segment->Image.Characteristics & IMAGE_SCN_MEM_SHARED)
354  {
355 #if 0
356  if (Region->Protect == PAGE_READWRITE ||
357  Region->Protect == PAGE_EXECUTE_READWRITE)
358 #endif
359  {
361  DPRINTC("setting non-cow page %p %p:%p offset %I64x (%Ix) to writable\n",
362  Segment,
363  Process,
364  PAddress,
367  if (Segment->FileObject)
368  {
369  DPRINTC("file %wZ\n", &Segment->FileObject->FileName);
370  }
372  DPRINT("Entry %x\n", Entry);
373  if (Entry &&
376 
378  &Offset,
379  DIRTY_SSE(Entry));
380  }
382  MmSetDirtyPage(Process, PAddress);
384  DPRINT("Done\n");
385  return STATUS_SUCCESS;
386  }
387 #if 0
388  else
389  {
390  DPRINT("Not supposed to be writable\n");
393  }
394 #endif
395  }
396 
397  if (!Required->Page[0])
398  {
399  SWAPENTRY SwapEntry;
401  {
402  MmGetPageFileMapping(Process, Address, &SwapEntry);
404  if (SwapEntry == MM_WAIT_ENTRY)
405  return STATUS_SUCCESS + 1; // Wait ... somebody else is getting it right now
406  else
407  return STATUS_SUCCESS; // Nonwait swap entry ... handle elsewhere
408  }
409  /* Call out to acquire a page to copy to. We'll be re-called when
410  * the page has been allocated. */
412  Required->Consumer = MC_CACHE;
413  Required->Amount = 1;
414  Required->File = __FILE__;
415  Required->Line = __LINE__;
416  Required->DoAcquisition = MiGetOnePage;
420  }
421 
422  NewPage = Required->Page[0];
423  OldPage = Required->Page[1];
424 
425  DPRINT("Allocated page %x\n", NewPage);
426 
427  /* Unshare the old page */
428  MmDeleteRmap(OldPage, Process, PAddress);
429 
430  /* Copy the old page */
431  DPRINT("Copying\n");
432  MiCopyPageToPage(NewPage, OldPage);
433 
434  /* Set the PTE to point to the new page */
436  Address,
438  &NewPage,
439  1);
440 
441  if (!NT_SUCCESS(Status))
442  {
443  DPRINT1("MmCreateVirtualMapping failed, not out of memory\n");
444  ASSERT(FALSE);
446  return Status;
447  }
448 
449  MmInsertRmap(NewPage, Process, PAddress);
452 
453  DPRINT("Address 0x%p\n", Address);
454  return STATUS_SUCCESS;
455 }
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: newmm.h:141
VOID NTAPI MmInsertRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
struct _Entry Entry
Definition: kefuncs.h:640
#define PFN_FROM_SSE(E)
Definition: newmm.h:7
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
NTSTATUS NTAPI MmCreateVirtualMapping(struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
VOID NTAPI MmDeleteRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:97
NTSTATUS NTAPI MmCreatePageFileMapping(struct _EPROCESS *Process, PVOID Address, SWAPENTRY SwapEntry)
#define MM_WAIT_ENTRY
Definition: mm.h:152
union _MEMORY_AREA::@1725 Data
uint32_t ULONG_PTR
Definition: typedefs.h:63
ULONG PFN_NUMBER
Definition: ke.h:8
VOID NTAPI MmSetDirtyPage(struct _EPROCESS *Process, PVOID Address)
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
NTSTATUS NTAPI MiGetOnePage(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_REQUIRED_RESOURCES RequiredResources)
Definition: reqtools.c:83
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:260
static WCHAR Address[46]
Definition: ping.c:68
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS NTAPI MiCopyPageToPage(PFN_NUMBER DestPage, PFN_NUMBER SrcPage)
Definition: fault.c:282
VOID NTAPI MmGetPageFileMapping(struct _EPROCESS *Process, PVOID Address, SWAPENTRY *SwapEntry)
_Inout_ PVOID Segment
Definition: exfuncs.h:893
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DPRINTC
Definition: fault.c:82
VOID NTAPI MmSetPageProtect(struct _EPROCESS *Process, PVOID Address, ULONG flProtect)
BOOLEAN NTAPI MmIsPageSwapEntry(struct _EPROCESS *Process, PVOID Address)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define MM_ROUND_DOWN(x, s)
Definition: mm.h:111
struct _MEMORY_AREA::@1725::@1726 SectionData
#define IMAGE_SCN_MEM_SHARED
Definition: ntimage.h:238
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define IS_SWAP_FROM_SSE(E)
Definition: newmm.h:8
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:207
Status
Definition: gdiplustypes.h:24
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
PFN_NUMBER NTAPI MmGetPfnForProcess(struct _EPROCESS *Process, PVOID Address)
ULONG_PTR SWAPENTRY
Definition: mm.h:47
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1438
#define DPRINT1
Definition: precomp.h:8
#define MmLockSectionSegment(x)
Definition: newmm.h:276
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define MC_CACHE
Definition: mm.h:93
#define DIRTY_SSE(E)
Definition: newmm.h:14
#define ULONG_PTR
Definition: config.h:101
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
struct _MEMORY_AREA struct _MM_REQUIRED_RESOURCES * Required
Definition: newmm.h:66
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
return STATUS_SUCCESS
Definition: btrfs.c:2966
base of all file and directory entries
Definition: entries.h:82
#define MmGetPageEntrySectionSegment(S, O)
Definition: newmm.h:143
LONGLONG QuadPart
Definition: typedefs.h:112
#define PAGE_READWRITE
Definition: nt_native.h:1304

Referenced by MmpSectionAccessFaultInner().

◆ MmAccessFaultCacheSection()

NTSTATUS NTAPI MmAccessFaultCacheSection ( KPROCESSOR_MODE  Mode,
ULONG_PTR  Address,
BOOLEAN  FromMdl 
)

Definition at line 688 of file fault.c.

691 {
695 
696  DPRINT("MmpAccessFault(Mode %d, Address %Ix)\n", Mode, Address);
697 
699 
701  {
702  DPRINT1("Page fault at high IRQL %u, address %Ix\n",
704  Address);
705  return STATUS_UNSUCCESSFUL;
706  }
707 
708  /* Find the memory area for the faulting address */
710  {
711  /* Check permissions */
712  if (Mode != KernelMode)
713  {
714  DPRINT1("Address: %p:%Ix\n", PsGetCurrentProcess(), Address);
716  }
718  }
719  else
720  {
722  }
723 
726  AddressSpace,
727  Address,
728  FromMdl,
729  Thread);
731 
732  return Status;
733 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
_In_ ULONG Mode
Definition: hubbusif.h:303
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
LONG NTSTATUS
Definition: precomp.h:26
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define PsGetCurrentProcess
Definition: psfuncs.h:17
static WCHAR Address[46]
Definition: ping.c:68
void DPRINT(...)
Definition: polytest.cpp:61
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
NTSTATUS NTAPI MmpSectionAccessFaultInner(KPROCESSOR_MODE Mode, PMMSUPPORT AddressSpace, ULONG_PTR Address, BOOLEAN FromMdl, PETHREAD Thread)
Definition: fault.c:528
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
Status
Definition: gdiplustypes.h:24
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1453
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
UCHAR ActiveFaultCount
Definition: pstypes.h:1174
#define DPRINT1
Definition: precomp.h:8
#define MmSystemRangeStart
Definition: mm.h:32

Referenced by MmpAccessFault().

◆ MmNotPresentFaultCachePage()

NTSTATUS NTAPI MmNotPresentFaultCachePage ( _In_ PMMSUPPORT  AddressSpace,
_In_ MEMORY_AREA MemoryArea,
_In_ PVOID  Address,
_In_ BOOLEAN  Locked,
_Inout_ PMM_REQUIRED_RESOURCES  Required 
)

Definition at line 105 of file fault.c.

111 {
113  PVOID PAddress;
114  ULONG Consumer;
116  LARGE_INTEGER FileOffset, TotalOffset;
120  KIRQL OldIrql;
121 
122  DPRINT("Not Present: %p %p (%p-%p)\n",
123  AddressSpace,
124  Address,
127 
128  /*
129  * There is a window between taking the page fault and locking the
130  * address space when another thread could load the page so we check
131  * that.
132  */
134  {
135  DPRINT("Done\n");
136  return STATUS_SUCCESS;
137  }
138 
139  PAddress = MM_ROUND_DOWN(Address, PAGE_SIZE);
140  TotalOffset.QuadPart = (ULONG_PTR)PAddress -
142 
143  Segment = MemoryArea->Data.SectionData.Segment;
144 
145  TotalOffset.QuadPart += MemoryArea->Data.SectionData.ViewOffset.QuadPart;
146  FileOffset = TotalOffset;
147 
148  //Consumer = (Segment->Flags & MM_DATAFILE_SEGMENT) ? MC_CACHE : MC_USER;
149  Consumer = MC_CACHE;
150 
151  if (Segment->FileObject)
152  {
153  DPRINT("FileName %wZ\n", &Segment->FileObject->FileName);
154  }
155 
156  DPRINT("Total Offset %08x%08x\n", TotalOffset.HighPart, TotalOffset.LowPart);
157 
158  /* Lock the segment */
160 
161  /* Get the entry corresponding to the offset within the section */
162  Entry = MmGetPageEntrySectionSegment(Segment, &TotalOffset);
163 
165 
166  if (Required->State && Required->Page[0])
167  {
168  DPRINT("Have file and page, set page %x in section @ %x #\n",
169  Required->Page[0],
170  TotalOffset.LowPart);
171 
172  if (Required->SwapEntry)
173  MmSetSavedSwapEntryPage(Required->Page[0], Required->SwapEntry);
174 
175  if (Required->State & 2)
176  {
177  DPRINT("Set in section @ %x\n", TotalOffset.LowPart);
179  &TotalOffset,
180  Entry = MAKE_PFN_SSE(Required->Page[0]));
181  if (!NT_SUCCESS(Status))
182  {
184  }
187  DPRINT("Status %x\n", Status);
189  }
190  else
191  {
192  DPRINT("Set %x in address space @ %p\n", Required->Page[0], Address);
194  Address,
195  Attributes,
196  Required->Page,
197  1);
198  if (NT_SUCCESS(Status))
199  {
200  MmInsertRmap(Required->Page[0], Process, Address);
201  }
202  else
203  {
204  /* Drop the reference for our address space ... */
206  }
208  DPRINTC("XXX Set Event %x\n", Status);
210  DPRINT("Status %x\n", Status);
211  return Status;
212  }
213  }
214  else if (MM_IS_WAIT_PTE(Entry))
215  {
216  // Whenever MM_WAIT_ENTRY is required as a swap entry, we need to
217  // ask the fault handler to wait until we should continue. Rathern
218  // than recopy this boilerplate code everywhere, we just ask them
219  // to wait.
221  return STATUS_SUCCESS + 1;
222  }
223  else if (Entry)
224  {
225  PFN_NUMBER Page = PFN_FROM_SSE(Entry);
226  DPRINT("Take reference to page %x #\n", Page);
227 
228  if (MiGetPfnEntry(Page) == NULL)
229  {
230  DPRINT1("Found no PFN entry for page 0x%x in page entry 0x%x (segment: 0x%p, offset: %08x%08x)\n",
231  Page,
232  Entry,
233  Segment,
234  TotalOffset.HighPart,
235  TotalOffset.LowPart);
236  KeBugCheck(CACHE_MANAGER);
237  }
238 
240  MmReferencePage(Page);
242 
244  if (NT_SUCCESS(Status))
245  {
246  MmInsertRmap(Page, Process, Address);
247  }
248  DPRINT("XXX Set Event %x\n", Status);
251  DPRINT("Status %x\n", Status);
252  return Status;
253  }
254  else
255  {
256  DPRINT("Get page into section\n");
257  /*
258  * If the entry is zero (and it can't change because we have
259  * locked the segment) then we need to load the page.
260  */
261  //DPRINT1("Read from file %08x %wZ\n", FileOffset.LowPart, &Section->FileObject->FileName);
262  Required->State = 2;
263  Required->Context = Segment->FileObject;
264  Required->Consumer = Consumer;
265  Required->FileOffset = FileOffset;
266  Required->Amount = PAGE_SIZE;
267  Required->DoAcquisition = MiReadFilePage;
268 
270  &TotalOffset,
272 
275  }
276  ASSERT(FALSE);
278 }
#define MmSetPageEntrySectionSegment(S, O, E)
Definition: newmm.h:141
VOID NTAPI MmInsertRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)
#define MiSetPageEvent(Process, Address)
Definition: newmm.h:43
struct _Entry Entry
Definition: kefuncs.h:640
#define PFN_FROM_SSE(E)
Definition: newmm.h:7
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
NTSTATUS NTAPI MmCreateVirtualMapping(struct _EPROCESS *Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
#define STATUS_MM_RESTART_OPERATION
Definition: mm.h:80
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:97
#define MAKE_PFN_SSE(P)
Definition: newmm.h:11
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define MM_WAIT_ENTRY
Definition: mm.h:152
NTSTATUS NTAPI MiReadFilePage(PMMSUPPORT AddressSpace, PMEMORY_AREA MemoryArea, PMM_REQUIRED_RESOURCES RequiredResources)
Definition: reqtools.c:133
union _MEMORY_AREA::@1725 Data
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
uint32_t ULONG_PTR
Definition: typedefs.h:63
UCHAR KIRQL
Definition: env_spec_w32.h:591
BOOLEAN NTAPI MmIsPagePresent(struct _EPROCESS *Process, PVOID Address)
ULONG PFN_NUMBER
Definition: ke.h:8
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1507
_Inout_ PVOID Segment
Definition: exfuncs.h:893
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DPRINTC
Definition: fault.c:82
#define MA_GetEndingAddress(_MemoryArea)
Definition: mm.h:208
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define MM_ROUND_DOWN(x, s)
Definition: mm.h:111
struct _MEMORY_AREA::@1725::@1726 SectionData
ULONG LowPart
Definition: typedefs.h:104
#define PAGE_SIZE
Definition: env_spec_w32.h:49
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:940
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:207
Status
Definition: gdiplustypes.h:24
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:151
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1438
#define PAGE_READONLY
Definition: compat.h:127
#define DPRINT1
Definition: precomp.h:8
#define MmLockSectionSegment(x)
Definition: newmm.h:276
#define MM_IS_WAIT_PTE(E)
Definition: newmm.h:9
VOID NTAPI MmSetSavedSwapEntryPage(PFN_NUMBER Page, SWAPENTRY SavedSwapEntry)
Definition: freelist.c:454
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define MC_CACHE
Definition: mm.h:93
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
struct _MEMORY_AREA struct _MM_REQUIRED_RESOURCES * Required
Definition: newmm.h:66
#define MmUnlockSectionSegment(x)
Definition: newmm.h:284
return STATUS_SUCCESS
Definition: btrfs.c:2966
VOID NTAPI MmReferencePage(PFN_NUMBER Page)
Definition: freelist.c:489
#define MAKE_SWAP_SSE(S)
Definition: newmm.h:13
base of all file and directory entries
Definition: entries.h:82
#define MmGetPageEntrySectionSegment(S, O)
Definition: newmm.h:143
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by MmNotPresentFaultCacheSectionInner().

◆ MmNotPresentFaultCacheSection()

NTSTATUS NTAPI MmNotPresentFaultCacheSection ( KPROCESSOR_MODE  Mode,
ULONG_PTR  Address,
BOOLEAN  FromMdl 
)

Definition at line 907 of file fault.c.

910 {
914 
915  Address &= ~(PAGE_SIZE - 1);
916  DPRINT("MmNotPresentFault(Mode %d, Address %Ix)\n", Mode, Address);
917 
919 
921  {
922  DPRINT1("Page fault at high IRQL %u, address %Ix\n",
924  Address);
925 
926  ASSERT(FALSE);
927  return STATUS_UNSUCCESSFUL;
928  }
929 
930  /* Find the memory area for the faulting address */
932  {
933  /* Check permissions */
934  if (Mode != KernelMode)
935  {
936  DPRINTC("Address: %x\n", Address);
938  }
940  }
941  else
942  {
944  }
945 
948  AddressSpace,
949  Address,
950  FromMdl,
951  Thread);
953 
956  DPRINT("MmAccessFault %p:%Ix -> %x\n",
958  Address,
959  Status);
960 
961  return Status;
962 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
_In_ ULONG Mode
Definition: hubbusif.h:303
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
LONG NTSTATUS
Definition: precomp.h:26
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define PsGetCurrentProcess
Definition: psfuncs.h:17
static WCHAR Address[46]
Definition: ping.c:68
NTSTATUS NTAPI MmNotPresentFaultCacheSectionInner(KPROCESSOR_MODE Mode, PMMSUPPORT AddressSpace, ULONG_PTR Address, BOOLEAN FromMdl, PETHREAD Thread)
Definition: fault.c:747
void DPRINT(...)
Definition: polytest.cpp:61
#define DPRINTC
Definition: fault.c:82
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Status
Definition: gdiplustypes.h:24
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1453
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1438
UCHAR ActiveFaultCount
Definition: pstypes.h:1174
#define DPRINT1
Definition: precomp.h:8
#define MmSystemRangeStart
Definition: mm.h:32

Referenced by MmNotPresentFault().

◆ MmNotPresentFaultCacheSectionInner()

NTSTATUS NTAPI MmNotPresentFaultCacheSectionInner ( KPROCESSOR_MODE  Mode,
PMMSUPPORT  AddressSpace,
ULONG_PTR  Address,
BOOLEAN  FromMdl,
PETHREAD  Thread 
)

Definition at line 747 of file fault.c.

752 {
753  BOOLEAN Locked = FromMdl;
758 
760 
761  if (!FromMdl)
762  {
764  }
765 
766  /* Call the memory area specific fault handler */
767  do
768  {
771  {
773  if (MemoryArea)
774  {
775  DPRINT1("Type %x DIP %x\n",
776  MemoryArea->Type,
778  }
779  else
780  {
781  DPRINT1("No memory area\n");
782  }
783  DPRINT1("Process %p, Address %Ix\n",
785  Address);
786  break;
787  }
788 
789  DPRINTC("Type %x (%p -> %08Ix -> %p) in %p\n",
790  MemoryArea->Type,
792  Address,
795 
796  Resources.DoAcquisition = NULL;
797 
798  // Note: fault handlers are called with address space locked
799  // We return STATUS_MORE_PROCESSING_REQUIRED if anything is needed
800 
802  MemoryArea,
803  (PVOID)Address,
804  Locked,
805  &Resources);
806 
807  if (!FromMdl)
808  {
810  }
811 
812  if (Status == STATUS_SUCCESS)
813  {
814  ; // Nothing
815  }
816  else if (Status == STATUS_SUCCESS + 1)
817  {
818  /* Wait page ... */
819  DPRINT("Waiting for %Ix\n", Address);
821  DPRINT("Done waiting for %Ix\n", Address);
823  }
825  {
826  /* Clean slate */
827  DPRINT("Clear resource\n");
828  RtlZeroMemory(&Resources, sizeof(Resources));
829  }
831  {
832  if (Thread->ActiveFaultCount > 2)
833  {
834  DPRINTC("Already fault handling ... going to work item (%Ix)\n", Address);
835  Context.AddressSpace = AddressSpace;
836  Context.MemoryArea = MemoryArea;
837  Context.Required = &Resources;
839 
840  ExInitializeWorkItem(&Context.WorkItem,
841  (PWORKER_THREAD_ROUTINE)MmpFaultWorker,
842  &Context);
843 
844  DPRINT("Queue work item\n");
846  DPRINT("Wait\n");
848  Status = Context.Status;
849  DPRINTC("Status %x\n", Status);
850  }
851  else
852  {
853  DPRINT("DoAcquisition %p\n", Resources.DoAcquisition);
854 
855  Status = Resources.DoAcquisition(AddressSpace,
856  MemoryArea,
857  &Resources);
858 
859  DPRINT("DoAcquisition %p -> %x\n",
860  Resources.DoAcquisition,
861  Status);
862  }
863 
864  if (NT_SUCCESS(Status))
865  {
867  }
868  }
869  else if (NT_SUCCESS(Status))
870  {
871  ASSERT(FALSE);
872  }
873 
874  if (!FromMdl)
875  {
877  }
878  }
880 
881  DPRINTC("Completed page fault handling: %p:%Ix %x\n",
883  Address,
884  Status);
885 
886  if (!FromMdl)
887  {
889  }
890 
892  DPRINT("Done %x\n", Status);
893 
894  return Status;
895 }
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
ULONG Type
Definition: mm.h:214
#define MiSetPageEvent(Process, Address)
Definition: newmm.h:43
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
#define STATUS_MM_RESTART_OPERATION
Definition: mm.h:80
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1431
LONG NTSTATUS
Definition: precomp.h:26
#define MiWaitForPageEvent(Process, Address)
Definition: newmm.h:38
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:260
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
void DPRINT(...)
Definition: polytest.cpp:61
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define DPRINTC
Definition: fault.c:82
BOOLEAN DeleteInProgress
Definition: mm.h:217
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define MA_GetEndingAddress(_MemoryArea)
Definition: mm.h:208
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:207
Status
Definition: gdiplustypes.h:24
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1438
UCHAR ActiveFaultCount
Definition: pstypes.h:1174
#define DPRINT1
Definition: precomp.h:8
struct tagContext Context
Definition: acpixf.h:1024
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2966
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:65
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1424
NTSTATUS NTAPI MmNotPresentFaultCachePage(_In_ PMMSUPPORT AddressSpace, _In_ MEMORY_AREA *MemoryArea, _In_ PVOID Address, _In_ BOOLEAN Locked, _Inout_ PMM_REQUIRED_RESOURCES Required)
Definition: fault.c:105
WORKER_THREAD_ROUTINE * PWORKER_THREAD_ROUTINE
Definition: extypes.h:200

Referenced by MmNotPresentFaultCacheSection().

◆ MmpSectionAccessFaultInner()

NTSTATUS NTAPI MmpSectionAccessFaultInner ( KPROCESSOR_MODE  Mode,
PMMSUPPORT  AddressSpace,
ULONG_PTR  Address,
BOOLEAN  FromMdl,
PETHREAD  Thread 
)

Definition at line 528 of file fault.c.

533 {
536  BOOLEAN Locked = FromMdl;
539 
541 
542  DPRINT("MmAccessFault(Mode %d, Address %Ix)\n", Mode, Address);
543 
545  {
546  DPRINT1("Page fault at high IRQL was %u\n", KeGetCurrentIrql());
547  return STATUS_UNSUCCESSFUL;
548  }
549 
550  /* Find the memory area for the faulting address */
552  {
553  /* Check permissions */
554  if (Mode != KernelMode)
555  {
556  DPRINT("MmAccessFault(Mode %d, Address %Ix)\n", Mode, Address);
558  }
560  }
561  else
562  {
564  }
565 
566  if (!FromMdl)
567  {
569  }
570 
571  do
572  {
574  if (MemoryArea == NULL ||
576  {
577  if (!FromMdl)
578  {
580  }
581  DPRINT("Address: %Ix\n", Address);
583  }
584 
585  DPRINT("Type %x (%p -> %p)\n",
586  MemoryArea->Type,
589 
590  Resources.DoAcquisition = NULL;
591 
592  // Note: fault handlers are called with address space locked
593  // We return STATUS_MORE_PROCESSING_REQUIRED if anything is needed
595  MemoryArea,
596  (PVOID)Address,
597  Locked,
598  &Resources);
599 
600  if (!FromMdl)
601  {
603  }
604 
605  if (Status == STATUS_SUCCESS + 1)
606  {
607  /* Wait page ... */
608  DPRINT("Waiting for %Ix\n", Address);
610  DPRINT("Restarting fault %Ix\n", Address);
612  }
614  {
615  /* Clean slate */
616  RtlZeroMemory(&Resources, sizeof(Resources));
617  }
619  {
620  if (Thread->ActiveFaultCount > 0)
621  {
622  DPRINT("Already fault handling ... going to work item (%Ix)\n",
623  Address);
624  Context.AddressSpace = AddressSpace;
625  Context.MemoryArea = MemoryArea;
626  Context.Required = &Resources;
628 
629  ExInitializeWorkItem(&Context.WorkItem,
630  MmpFaultWorker,
631  &Context);
632 
633  DPRINT("Queue work item\n");
635  DPRINT("Wait\n");
637  Status = Context.Status;
638  DPRINT("Status %x\n", Status);
639  }
640  else
641  {
642  Status = Resources.DoAcquisition(AddressSpace, MemoryArea, &Resources);
643  }
644 
645  if (NT_SUCCESS(Status))
646  {
648  }
649  }
650 
651  if (!FromMdl)
652  {
654  }
655  }
657 
658  if (!NT_SUCCESS(Status) && MemoryArea->Type == 1)
659  {
660  DPRINT1("Completed page fault handling %Ix %x\n", Address, Status);
661  DPRINT1("Type %x (%p -> %p)\n",
662  MemoryArea->Type,
665  }
666 
667  if (!FromMdl)
668  {
670  }
671 
672  return Status;
673 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
ULONG Type
Definition: mm.h:214
_In_ ULONG Mode
Definition: hubbusif.h:303
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
#define STATUS_MM_RESTART_OPERATION
Definition: mm.h:80
_In_ ULONG _In_ PHYSICAL_ADDRESS _Inout_ PULONG AddressSpace
Definition: iofuncs.h:2268
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1431
LONG NTSTATUS
Definition: precomp.h:26
#define MiWaitForPageEvent(Process, Address)
Definition: newmm.h:38
PMEMORY_AREA NTAPI MmLocateMemoryAreaByAddress(PMMSUPPORT AddressSpace, PVOID Address)
Definition: marea.c:60
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ PMEMORY_AREA _In_ PVOID _In_ BOOLEAN Locked
Definition: newmm.h:260
#define PsGetCurrentProcess
Definition: psfuncs.h:17
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
void DPRINT(...)
Definition: polytest.cpp:61
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN DeleteInProgress
Definition: mm.h:217
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
#define MA_GetEndingAddress(_MemoryArea)
Definition: mm.h:208
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define MA_GetStartingAddress(_MemoryArea)
Definition: mm.h:207
Status
Definition: gdiplustypes.h:24
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
FORCEINLINE PMMSUPPORT MmGetKernelAddressSpace(VOID)
Definition: mm.h:1453
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define STATUS_ACCESS_VIOLATION
Definition: ntstatus.h:228
FORCEINLINE PEPROCESS MmGetAddressSpaceOwner(IN PMMSUPPORT AddressSpace)
Definition: mm.h:1438
UCHAR ActiveFaultCount
Definition: pstypes.h:1174
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI MiCowCacheSectionPage(_In_ PMMSUPPORT AddressSpace, _In_ PMEMORY_AREA MemoryArea, _In_ PVOID Address, _In_ BOOLEAN Locked, _Inout_ PMM_REQUIRED_RESOURCES Required)
Definition: fault.c:321
struct tagContext Context
Definition: acpixf.h:1024
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2966
struct _MEMORY_AREA * MemoryArea
Definition: newmm.h:65
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1424
#define MmSystemRangeStart
Definition: mm.h:32

Referenced by MmAccessFaultCacheSection().

Variable Documentation

◆ MmWaitPageEvent

KEVENT MmWaitPageEvent

Definition at line 457 of file fault.c.

◆ MmWorkingSetList

PMMWSL MmWorkingSetList

Definition at line 21 of file procsup.c.