ReactOS  0.4.15-dev-2985-g54406bf
page.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: ntoskrnl/mm/i386/page.c
5  * PURPOSE: Low level memory managment manipulation
6  *
7  * PROGRAMMERS: David Welch (welch@cwcom.net)
8  */
9 
10 /* INCLUDES ***************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 #include <mm/ARM3/miarm.h>
17 
18 #ifndef _MI_PAGING_LEVELS
19 #error "Dude, fix your stuff before using this file"
20 #endif
21 
22 /* GLOBALS *****************************************************************/
23 const
26 {
27  //
28  // These are the base MM_ protection flags
29  //
30  0,
31  PTE_READONLY | PTE_ENABLE_CACHE,
32  PTE_EXECUTE | PTE_ENABLE_CACHE,
33  PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
34  PTE_READWRITE | PTE_ENABLE_CACHE,
35  PTE_WRITECOPY | PTE_ENABLE_CACHE,
36  PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
37  PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
38  //
39  // These OR in the MM_NOCACHE flag
40  //
41  0,
42  PTE_READONLY | PTE_DISABLE_CACHE,
43  PTE_EXECUTE | PTE_DISABLE_CACHE,
44  PTE_EXECUTE_READ | PTE_DISABLE_CACHE,
45  PTE_READWRITE | PTE_DISABLE_CACHE,
46  PTE_WRITECOPY | PTE_DISABLE_CACHE,
47  PTE_EXECUTE_READWRITE | PTE_DISABLE_CACHE,
48  PTE_EXECUTE_WRITECOPY | PTE_DISABLE_CACHE,
49  //
50  // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM
51  //
52  0,
53  PTE_READONLY | PTE_ENABLE_CACHE,
54  PTE_EXECUTE | PTE_ENABLE_CACHE,
55  PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
56  PTE_READWRITE | PTE_ENABLE_CACHE,
57  PTE_WRITECOPY | PTE_ENABLE_CACHE,
58  PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
59  PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
60  //
61  // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining?
62  //
63  0,
64  PTE_READONLY | PTE_WRITECOMBINED_CACHE,
65  PTE_EXECUTE | PTE_WRITECOMBINED_CACHE,
66  PTE_EXECUTE_READ | PTE_WRITECOMBINED_CACHE,
67  PTE_READWRITE | PTE_WRITECOMBINED_CACHE,
68  PTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
69  PTE_EXECUTE_READWRITE | PTE_WRITECOMBINED_CACHE,
70  PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
71 };
72 
73 const
75 {
108 };
109 
110 /* FUNCTIONS ***************************************************************/
111 
112 NTSTATUS
113 NTAPI
116 
117 static
118 BOOLEAN
120 {
121 #if _MI_PAGING_LEVELS == 2
123 #else
124  PMMPDE PointerPde;
125  PMMPPE PointerPpe;
126 #if _MI_PAGING_LEVELS == 4
127  PMMPXE PointerPxe;
128 #endif
129  PMMPFN Pfn;
130 
131  /* Make sure we're locked */
132  ASSERT((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) || (PsGetCurrentThread()->OwnsProcessWorkingSetShared));
133 
134  /* Must not hold the PFN lock! */
136 
137  /* Check if PXE or PPE have references first. */
138 #if _MI_PAGING_LEVELS == 4
139  PointerPxe = MiAddressToPxe(Address);
140  if ((PointerPxe->u.Hard.Valid == 1) || (PointerPxe->u.Soft.Transition == 1))
141  {
142  Pfn = MiGetPfnEntry(PFN_FROM_PXE(PointerPxe));
143  if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0)
144  return FALSE;
145  }
146  else if (PointerPxe->u.Soft.UsedPageTableEntries == 0)
147  {
148  return FALSE;
149  }
150 
151  if (PointerPxe->u.Hard.Valid == 0)
152  {
154  }
155 #endif
156 
157  PointerPpe = MiAddressToPpe(Address);
158  if ((PointerPpe->u.Hard.Valid == 1) || (PointerPpe->u.Soft.Transition == 1))
159  {
160  Pfn = MiGetPfnEntry(PFN_FROM_PPE(PointerPpe));
161  if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0)
162  return FALSE;
163  }
164  else if (PointerPpe->u.Soft.UsedPageTableEntries == 0)
165  {
166  return FALSE;
167  }
168 
169  if (PointerPpe->u.Hard.Valid == 0)
170  {
172  }
173 
174  PointerPde = MiAddressToPde(Address);
175  if ((PointerPde->u.Hard.Valid == 0) && (PointerPde->u.Soft.Transition == 0))
176  {
177  return PointerPde->u.Soft.UsedPageTableEntries != 0;
178  }
179 
180  /* This lies on the PFN */
181  Pfn = MiGetPfnEntry(PFN_FROM_PDE(PointerPde));
182  return Pfn->OriginalPte.u.Soft.UsedPageTableEntries != 0;
183 #endif
184 }
185 
187 NTAPI
189  PVOID Address)
190 {
191  PMMPTE PointerPte;
193 
194  /* Must be called for user mode only */
195  ASSERT(Process != NULL);
197 
198  /* And for our process */
200 
201  /* Lock for reading */
203 
205  {
207  return 0;
208  }
209 
210  /* Make sure we can read the PTE */
212 
213  PointerPte = MiAddressToPte(Address);
214  Page = PointerPte->u.Hard.Valid ? PFN_FROM_PTE(PointerPte) : 0;
215 
217  return Page;
218 }
219 
220 VOID
221 NTAPI
223  BOOLEAN* WasDirty, PPFN_NUMBER Page)
224 /*
225  * FUNCTION: Delete a virtual mapping
226  */
227 {
228  PMMPTE PointerPte;
229  MMPTE OldPte;
230 
231  DPRINT("MmDeleteVirtualMapping(%p, %p, %p, %p)\n", Process, Address, WasDirty, Page);
232 
233  ASSERT(((ULONG_PTR)Address % PAGE_SIZE) == 0);
234 
235  /* And we should be at low IRQL */
237 
238  /* Make sure our PDE is valid, and that everything is going fine */
239  if (Process == NULL)
240  {
242  {
243  DPRINT1("NULL process given for user-mode mapping at %p\n", Address);
244  KeBugCheck(MEMORY_MANAGEMENT);
245  }
246 #if (_MI_PAGING_LEVELS == 2)
247  if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
248 #else
250 #endif
251  {
252  /* There can't be a page if there is no PDE */
253  if (WasDirty)
254  *WasDirty = FALSE;
255  if (Page)
256  *Page = 0;
257  return;
258  }
259  }
260  else
261  {
263  {
264  DPRINT1("Process %p given for kernel-mode mapping at %p -- %lu pages starting at %Ix\n", Process, Address);
265  KeBugCheck(MEMORY_MANAGEMENT);
266  }
267 
268  /* Only for current process !!! */
271 
272  /* No PDE --> No page */
274  {
276  if (WasDirty)
277  *WasDirty = 0;
278  if (Page)
279  *Page = 0;
280  return;
281  }
282 
284  }
285 
286  PointerPte = MiAddressToPte(Address);
287  OldPte.u.Long = InterlockedExchangePte(PointerPte, 0);
288 
289  if (OldPte.u.Long == 0)
290  {
291  /* There was nothing here */
294  if (WasDirty)
295  *WasDirty = 0;
296  if (Page)
297  *Page = 0;
298  return;
299  }
300 
301  /* It must have been present, or not a swap entry */
302  ASSERT(OldPte.u.Hard.Valid || !FlagOn(OldPte.u.Long, 0x800));
303 
304  if (OldPte.u.Hard.Valid)
306 
308  {
309  /* Remove PDE reference */
311  {
312  KIRQL OldIrql = MiAcquirePfnLock();
314  MiReleasePfnLock(OldIrql);
315  }
316 
318  }
319 
320  if (WasDirty)
321  *WasDirty = !!OldPte.u.Hard.Dirty;
322  if (Page)
323  *Page = OldPte.u.Hard.PageFrameNumber;
324 }
325 
326 
327 VOID
328 NTAPI
331  PVOID Address,
332  SWAPENTRY* SwapEntry)
333 {
334  PMMPTE PointerPte;
335  MMPTE OldPte;
336 
337  /* This should not be called for kernel space anymore */
338  ASSERT(Process != NULL);
340 
341  /* And we don't support deleting for other process */
343 
344  /* And we should be at low IRQL */
346 
347  /* We are tinkering with the PDE here. Ensure it will be there */
349 
350  /* Callers must ensure there is actually something there */
351  ASSERT(MiAddressToPde(Address)->u.Long != 0);
352 
354 
355  PointerPte = MiAddressToPte(Address);
356  OldPte.u.Long = InterlockedExchangePte(PointerPte, 0);
357  /* This must be a swap entry ! */
358  if (!FlagOn(OldPte.u.Long, 0x800) || OldPte.u.Hard.Valid)
359  {
360  KeBugCheckEx(MEMORY_MANAGEMENT, OldPte.u.Long, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
361  }
362 
363  /* This used to be a non-zero PTE, now we can let the PDE go. */
365  {
366  /* We can let it go */
367  KIRQL OldIrql = MiAcquirePfnLock();
368  MiDeletePde(MiPteToPde(PointerPte), Process);
369  MiReleasePfnLock(OldIrql);
370  }
371 
373 
374  *SwapEntry = OldPte.u.Long >> 1;
375 }
376 
377 BOOLEAN
378 NTAPI
380 {
381  BOOLEAN Ret;
382 
384  {
385  ASSERT(Process == NULL);
386 #if _MI_PAGING_LEVELS == 2
387  if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
388 #else
390 #endif
391  {
392  /* It can't be present if there is no PDE */
393  return FALSE;
394  }
395 
396  return MiAddressToPte(Address)->u.Hard.Valid;
397  }
398 
399  ASSERT(Process != NULL);
401 
403 
405  {
406  /* It can't be present if there is no PDE */
408  return FALSE;
409  }
410 
412 
413  Ret = MiAddressToPte(Address)->u.Hard.Valid;
414 
416 
417  return Ret;
418 }
419 
420 BOOLEAN
421 NTAPI
423 {
424  BOOLEAN Ret;
425  PMMPTE PointerPte;
426 
428  {
429  ASSERT(Process == NULL);
430 #if _MI_PAGING_LEVELS == 2
431  if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
432 #else
434 #endif
435  {
436  /* It's not disabled if it's not present */
437  return FALSE;
438  }
439  }
440  else
441  {
442  ASSERT(Process != NULL);
444 
446 
448  {
449  /* It can't be disabled if there is no PDE */
451  return FALSE;
452  }
453 
455  }
456 
457  PointerPte = MiAddressToPte(Address);
458  Ret = !PointerPte->u.Hard.Valid
459  && !FlagOn(PointerPte->u.Long, 0x800)
460  && (PointerPte->u.Hard.PageFrameNumber != 0);
461 
464 
465  return Ret;
466 }
467 
468 BOOLEAN
469 NTAPI
471 {
472  BOOLEAN Ret;
473  PMMPTE PointerPte;
474 
475  /* We never set swap entries for kernel addresses */
477  {
478  ASSERT(Process == NULL);
479  return FALSE;
480  }
481 
482  ASSERT(Process != NULL);
484 
486 
488  {
489  /* There can't be a swap entry if there is no PDE */
491  return FALSE;
492  }
493 
495 
496  PointerPte = MiAddressToPte(Address);
497  Ret = !PointerPte->u.Hard.Valid && FlagOn(PointerPte->u.Long, 0x800);
498 
500 
501  return Ret;
502 }
503 
504 VOID
505 NTAPI
507 {
508  PMMPTE PointerPte;
509 
510  /* We never set swap entries for kernel addresses */
512  {
513  ASSERT(Process == NULL);
514  *SwapEntry = 0;
515  return;
516  }
517 
518  ASSERT(Process != NULL);
520 
522 
524  {
525  /* There can't be a swap entry if there is no PDE */
527  *SwapEntry = 0;
528  return;
529  }
530 
532 
533  PointerPte = MiAddressToPte(Address);
534  if (!PointerPte->u.Hard.Valid && FlagOn(PointerPte->u.Long, 0x800))
535  *SwapEntry = PointerPte->u.Long >> 1;
536  else
537  *SwapEntry = 0;
538 
540 }
541 
542 NTSTATUS
543 NTAPI
545  PVOID Address,
546  SWAPENTRY SwapEntry)
547 {
548  PMMPTE PointerPte;
549  ULONG_PTR Pte;
550 
551  /* This should not be called for kernel space anymore */
552  ASSERT(Process != NULL);
554 
555  /* And we don't support creating for other process */
557 
558  if (SwapEntry & (1 << 31))
559  {
560  KeBugCheck(MEMORY_MANAGEMENT);
561  }
562 
563  /* We are tinkering with the PDE here. Ensure it will be there */
566 
568 
569  PointerPte = MiAddressToPte(Address);
570  Pte = InterlockedExchangePte(PointerPte, SwapEntry << 1);
571  if (Pte != 0)
572  {
573  KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
574  }
575 
576  /* This used to be a 0 PTE, now we need a valid PDE to keep it around */
579 
580  return STATUS_SUCCESS;
581 }
582 
583 
584 NTSTATUS
585 NTAPI
587  PVOID Address,
588  ULONG flProtect,
590 {
591  ULONG ProtectionMask;
592  PMMPTE PointerPte;
593  MMPTE TempPte;
594  ULONG_PTR Pte;
595 
596  DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %x)\n",
597  Process, Address, flProtect, Page);
598 
599  ASSERT(((ULONG_PTR)Address % PAGE_SIZE) == 0);
600 
601  ProtectionMask = MiMakeProtectionMask(flProtect);
602  /* Caller must have checked ! */
603  ASSERT(ProtectionMask != MM_INVALID_PROTECTION);
604  ASSERT(ProtectionMask != MM_NOACCESS);
605  ASSERT(ProtectionMask != MM_ZERO_ACCESS);
606 
607  /* Make sure our PDE is valid, and that everything is going fine */
608  if (Process == NULL)
609  {
610  /* We don't support this in legacy Mm for kernel mappings */
611  ASSERT(ProtectionMask != MM_WRITECOPY);
612  ASSERT(ProtectionMask != MM_EXECUTE_WRITECOPY);
613 
615  {
616  DPRINT1("NULL process given for user-mode mapping at %p\n", Address);
617  KeBugCheck(MEMORY_MANAGEMENT);
618  }
619 #if _MI_PAGING_LEVELS == 2
620  if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
622 #endif
623  }
624  else
625  {
627  {
628  DPRINT1("Process %p given for kernel-mode mapping at %p -- %lu pages starting at %Ix\n", Process, Address);
629  KeBugCheck(MEMORY_MANAGEMENT);
630  }
631 
632  /* Only for current process !!! */
635 
637  }
638 
639  PointerPte = MiAddressToPte(Address);
640 
641  MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, ProtectionMask, Page);
642 
643  Pte = InterlockedExchangePte(PointerPte, TempPte.u.Long);
644  /* There should not have been anything valid here */
645  if (Pte != 0)
646  {
647  DPRINT1("Bad PTE %lx at %p for %p\n", Pte, PointerPte, Address);
648  KeBugCheck(MEMORY_MANAGEMENT);
649  }
650 
651  /* We don't need to flush the TLB here because it only caches valid translations
652  * and we're moving this PTE from invalid to valid so it can't be cached right now */
653 
655  {
656  /* Add PDE reference */
659  }
660 
661  return(STATUS_SUCCESS);
662 }
663 
664 NTSTATUS
665 NTAPI
667  PVOID Address,
668  ULONG flProtect,
670 {
672  if (!MmIsPageInUse(Page))
673  {
674  DPRINT1("Page %lx is not in use\n", Page);
675  KeBugCheck(MEMORY_MANAGEMENT);
676  }
677 
678  return MmCreateVirtualMappingUnsafe(Process, Address, flProtect, Page);
679 }
680 
681 ULONG
682 NTAPI
684 {
685  PMMPTE PointerPte;
686  ULONG Protect;
687 
689  {
690  ASSERT(Process == NULL);
691 
692 #if _MI_PAGING_LEVELS == 2
693  if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
694 #else
696 #endif
697  {
698  return PAGE_NOACCESS;
699  }
700  }
701  else
702  {
704  ASSERT(Process != NULL);
705 
707 
709 
711  {
712  /* It can't be present if there is no PDE */
714  return PAGE_NOACCESS;
715  }
716 
718  }
719 
720  PointerPte = MiAddressToPte(Address);
721 
722  if (!PointerPte->u.Flush.Valid)
723  {
725  }
726  else
727  {
728  if (PointerPte->u.Flush.CopyOnWrite)
730  else if (PointerPte->u.Flush.Write)
732  else
734 #if _MI_PAGING_LEVELS >= 3
735  /* PAE & AMD64 long mode support NoExecute bit */
736  if (!PointerPte->u.Flush.NoExecute)
737  Protect <<= 4;
738 #endif
739  if (PointerPte->u.Flush.CacheDisable)
741  if (PointerPte->u.Flush.WriteThrough)
743  }
744 
747 
748  return(Protect);
749 }
750 
751 VOID
752 NTAPI
754 {
755  ULONG ProtectionMask;
756  PMMPTE PointerPte;
757  MMPTE TempPte, OldPte;
758 
759  DPRINT("MmSetPageProtect(Process %p Address %p flProtect %x)\n",
760  Process, Address, flProtect);
761 
762  ASSERT(Process != NULL);
764 
766 
767  ProtectionMask = MiMakeProtectionMask(flProtect);
768  /* Caller must have checked ! */
769  ASSERT(ProtectionMask != MM_INVALID_PROTECTION);
770 
772 
774 
775  PointerPte = MiAddressToPte(Address);
776 
777  /* Sanity check */
778  ASSERT(PointerPte->u.Hard.Owner == 1);
779 
780  TempPte.u.Long = 0;
781  TempPte.u.Hard.PageFrameNumber = PointerPte->u.Hard.PageFrameNumber;
782  TempPte.u.Long |= MmProtectToPteMask[ProtectionMask];
783  TempPte.u.Hard.Owner = 1;
784 
785  /* Only set valid bit if we have to */
786  if ((ProtectionMask != MM_NOACCESS) && !FlagOn(ProtectionMask, MM_GUARDPAGE))
787  TempPte.u.Hard.Valid = 1;
788 
789  /* Keep dirty & accessed bits */
790  TempPte.u.Hard.Accessed = PointerPte->u.Hard.Accessed;
791  TempPte.u.Hard.Dirty = PointerPte->u.Hard.Dirty;
792 
793  OldPte.u.Long = InterlockedExchangePte(PointerPte, TempPte.u.Long);
794 
795  // We should be able to bring a page back from PAGE_NOACCESS
796  if (!OldPte.u.Hard.Valid && (FlagOn(OldPte.u.Long, 0x800) || (OldPte.u.Hard.PageFrameNumber == 0)))
797  {
798  DPRINT1("Invalid Pte %lx\n", OldPte.u.Long);
799  KeBugCheck(MEMORY_MANAGEMENT);
800  }
801 
802  if (OldPte.u.Long != TempPte.u.Long)
804 
806 }
807 
808 VOID
809 NTAPI
811 {
812  PMMPTE PointerPte;
813 
814  DPRINT("MmSetDirtyBit(Process %p Address %p Bit %x)\n",
815  Process, Address, Bit);
816 
817  ASSERT(Process != NULL);
819 
821 
823 
825 
826  PointerPte = MiAddressToPte(Address);
827  // We shouldnl't set dirty bit on non-mapped adresses
828  if (!PointerPte->u.Hard.Valid && (FlagOn(PointerPte->u.Long, 0x800) || (PointerPte->u.Hard.PageFrameNumber == 0)))
829  {
830  DPRINT1("Invalid Pte %lx\n", PointerPte->u.Long);
831  KeBugCheck(MEMORY_MANAGEMENT);
832  }
833 
834  PointerPte->u.Hard.Dirty = !!Bit;
835 
836  if (!Bit)
838 
840 }
841 
842 CODE_SEG("INIT")
843 VOID
844 NTAPI
846 {
847  /* Nothing to do here */
848 }
849 
850 #ifdef _M_IX86
851 BOOLEAN
853 {
854  PMMPDE PointerPde = MiAddressToPde(Address);
855  PMMPTE PointerPte = MiAddressToPte(Address);
856 
857  if (PointerPde->u.Hard.Valid == 0)
858  {
859  if (!MiSynchronizeSystemPde(PointerPde))
860  return FALSE;
861  return PointerPte->u.Hard.Valid != 0;
862  }
863  return FALSE;
864 }
865 #endif
866 
867 /* EOF */
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define PAGE_WRITETHROUGH
Definition: mm.h:98
ULONG64 Valid
Definition: mmtypes.h:66
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define PAGE_NOCACHE
Definition: nt_native.h:1311
VOID NTAPI MmSetPageProtect(IN PEPROCESS Process, IN PVOID Address, IN ULONG Protection)
Definition: page.c:267
BOOLEAN NTAPI MmIsPageSwapEntry(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:249
#define IN
Definition: typedefs.h:39
#define MM_INVALID_PROTECTION
Definition: miarm.h:67
VOID NTAPI MmSetDirtyBit(PEPROCESS Process, PVOID Address, BOOLEAN Bit)
Definition: page.c:810
#define PFN_FROM_PDE(v)
Definition: mm.h:93
#define Add2Ptr(PTR, INC)
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1244
#define MiAddressToPde(x)
Definition: mmx86.c:20
VOID NTAPI MmDeletePageFileMapping(IN PEPROCESS Process, IN PVOID Address, IN SWAPENTRY *SwapEntry)
Definition: page.c:187
static BOOLEAN MiIsPageTablePresent(PVOID Address)
Definition: page.c:119
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
USHORT UsedPageTableEntries[768]
Definition: mmtypes.h:883
NTSTATUS NTAPI MmCreatePageFileMapping(IN PEPROCESS Process, IN PVOID Address, IN SWAPENTRY SwapEntry)
Definition: page.c:196
BOOLEAN NTAPI MmIsPagePresent(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:240
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T _In_ SECTION_INHERIT _In_ ULONG _In_ ULONG Protect
Definition: zwfuncs.h:214
FORCEINLINE VOID MiUnlockProcessWorkingSetShared(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1220
BOOLEAN NTAPI MmIsPageInUse(PFN_NUMBER Page)
Definition: freelist.c:558
#define PAGE_GUARD
Definition: nt_native.h:1310
ULONG64 CacheDisable
Definition: mmtypes.h:70
LONG NTSTATUS
Definition: precomp.h:26
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:154
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
FORCEINLINE USHORT MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2504
#define MM_NOACCESS
Definition: miarm.h:65
HARDWARE_PTE Flush
Definition: mmtypes.h:216
FORCEINLINE BOOLEAN MiIsPdeForAddressValid(PVOID Address)
Definition: mm.h:359
VOID NTAPI MmInitGlobalKernelPageDirectory(VOID)
Definition: page.c:277
ULONG64 CopyOnWrite
Definition: mmtypes.h:75
FORCEINLINE PMMPDE MiPteToPde(PMMPTE PointerPte)
Definition: mm.h:261
#define MiGetPdeOffset(x)
Definition: mm.h:188
uint32_t ULONG_PTR
Definition: typedefs.h:65
BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
Definition: pagepae.c:844
#define MM_EXECUTE_WRITECOPY
Definition: miarm.h:50
ULONG64 Dirty
Definition: mmtypes.h:164
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG * PPFN_NUMBER
Definition: ke.h:9
#define MM_WRITECOPY
Definition: miarm.h:48
const ULONG MmProtectToValue[32]
Definition: page.c:71
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
#define MM_NOIRQL
Definition: mm.h:59
ULONG PFN_NUMBER
Definition: ke.h:9
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
const ULONG MmProtectToPteMask[32]
Definition: page.c:22
ULONG64 Owner
Definition: mmtypes.h:160
#define FALSE
Definition: types.h:117
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
#define PsGetCurrentProcess
Definition: psfuncs.h:17
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(IN PEPROCESS Process, IN PVOID Address, IN ULONG Protection, IN PPFN_NUMBER Pages, IN ULONG PageCount)
Definition: page.c:146
#define PAGE_NOACCESS
Definition: nt_native.h:1302
unsigned char BOOLEAN
VOID NTAPI MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
Definition: virtual.c:2470
static WCHAR Address[46]
Definition: ping.c:68
ULONG64 WriteThrough
Definition: mmtypes.h:69
#define PAGE_EXECUTE
Definition: nt_native.h:1306
PFN_NUMBER Page
Definition: section.c:4888
ULONG NTAPI MiMakeSystemAddressValid(IN PVOID PageTableVirtualAddress, IN PEPROCESS CurrentProcess)
Definition: virtual.c:183
KIRQL OldIrql
Definition: mm.h:1502
#define MM_ZERO_ACCESS
Definition: miarm.h:43
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:164
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1174
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:260
VOID NTAPI MmDeleteVirtualMapping(IN PEPROCESS Process, IN PVOID Address, OUT PBOOLEAN WasDirty, OUT PPFN_NUMBER Page)
Definition: page.c:177
#define ASSERT(a)
Definition: mode.c:44
BOOLEAN NTAPI MmIsDisabledPage(PEPROCESS Process, PVOID Address)
Definition: page.c:309
ULONG64 UsedPageTableEntries
Definition: mmtypes.h:91
ULONG64 Valid
Definition: mmtypes.h:150
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
NTSTATUS NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes)
Definition: section.c:480
FORCEINLINE VOID MiLockProcessWorkingSetShared(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1151
FORCEINLINE USHORT MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2478
#define MM_GUARDPAGE
Definition: miarm.h:57
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:158
Definition: mm.h:362
#define InterlockedExchangePte(PointerPte, Value)
Definition: mm.h:179
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
FORCEINLINE VOID MiDeletePde(_In_ PMMPDE PointerPde, _In_ PEPROCESS CurrentProcess)
Definition: miarm.h:2538
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1000
PMMWSL MmWorkingSetList
Definition: wslist.cpp:19
ULONG_PTR Long
Definition: mmtypes.h:215
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
ULONG_PTR SIZE_T
Definition: typedefs.h:80
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG NTAPI MmGetPageProtect(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:258
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:299
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
ULONG64 Transition
Definition: mmtypes.h:90
ULONG_PTR SWAPENTRY
Definition: mm.h:53
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1035
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
#define NULL
Definition: types.h:112
MMPTE OriginalPte
Definition: mm.h:396
#define PAGE_READONLY
Definition: compat.h:138
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#define DPRINT1
Definition: precomp.h:8
ULONG64 Write
Definition: mmtypes.h:67
PFN_NUMBER NTAPI MmGetPfnForProcess(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:206
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define PFN_FROM_PXE(v)
Definition: mm.h:95
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
NTSTATUS NTAPI MmCreateVirtualMapping(IN PEPROCESS Process, IN PVOID Address, IN ULONG Protection, IN PPFN_NUMBER Pages, IN ULONG PageCount)
Definition: page.c:158
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
union _MMPTE::@2287 u
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
#define PFN_FROM_PTE(v)
Definition: mm.h:92
ULONG64 NoExecute
Definition: mmtypes.h:81
#define MmSystemRangeStart
Definition: mm.h:32
#define PFN_FROM_PPE(v)
Definition: mm.h:94
ULONG64 Accessed
Definition: mmtypes.h:163
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:812
ULONG PageFrameNumber
Definition: mmtypes.h:109
#define PAGE_READWRITE
Definition: nt_native.h:1304