ReactOS  0.4.15-dev-5640-g0dde428
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 
124  /* Some sanity check while we're here */
125  ASSERT(Ret == (MiAddressToPde(Address)->u.Hard.Valid != 0));
126 
127  return Ret;
128 #else
129  PMMPDE PointerPde;
130  PMMPPE PointerPpe;
131 #if _MI_PAGING_LEVELS == 4
132  PMMPXE PointerPxe;
133 #endif
134  PMMPFN Pfn;
135 
136  /* Make sure we're locked */
137  ASSERT((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) || (PsGetCurrentThread()->OwnsProcessWorkingSetShared));
138 
139  /* Must not hold the PFN lock! */
141 
142  /* Check if PXE or PPE have references first. */
143 #if _MI_PAGING_LEVELS == 4
144  PointerPxe = MiAddressToPxe(Address);
145  if ((PointerPxe->u.Hard.Valid == 1) || (PointerPxe->u.Soft.Transition == 1))
146  {
147  Pfn = MiGetPfnEntry(PFN_FROM_PXE(PointerPxe));
148  if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0)
149  return FALSE;
150  }
151  else if (PointerPxe->u.Soft.UsedPageTableEntries == 0)
152  {
153  return FALSE;
154  }
155 
156  if (PointerPxe->u.Hard.Valid == 0)
157  {
159  }
160 #endif
161 
162  PointerPpe = MiAddressToPpe(Address);
163  if ((PointerPpe->u.Hard.Valid == 1) || (PointerPpe->u.Soft.Transition == 1))
164  {
165  Pfn = MiGetPfnEntry(PFN_FROM_PPE(PointerPpe));
166  if (Pfn->OriginalPte.u.Soft.UsedPageTableEntries == 0)
167  return FALSE;
168  }
169  else if (PointerPpe->u.Soft.UsedPageTableEntries == 0)
170  {
171  return FALSE;
172  }
173 
174  if (PointerPpe->u.Hard.Valid == 0)
175  {
177  }
178 
179  PointerPde = MiAddressToPde(Address);
180  if ((PointerPde->u.Hard.Valid == 0) && (PointerPde->u.Soft.Transition == 0))
181  {
182  return PointerPde->u.Soft.UsedPageTableEntries != 0;
183  }
184 
185  /* This lies on the PFN */
186  Pfn = MiGetPfnEntry(PFN_FROM_PDE(PointerPde));
187  return Pfn->OriginalPte.u.Soft.UsedPageTableEntries != 0;
188 #endif
189 }
190 
192 NTAPI
194  PVOID Address)
195 {
196  PMMPTE PointerPte;
198 
199  /* Must be called for user mode only */
200  ASSERT(Process != NULL);
202 
203  /* And for our process */
205 
206  /* Lock for reading */
208 
210  {
212  return 0;
213  }
214 
215  /* Make sure we can read the PTE */
217 
218  PointerPte = MiAddressToPte(Address);
219  Page = PointerPte->u.Hard.Valid ? PFN_FROM_PTE(PointerPte) : 0;
220 
222  return Page;
223 }
224 
235 _Success_(return)
236 BOOLEAN
242 {
243  PMMPTE PointerPte;
244  MMPTE OldPte;
245  BOOLEAN ValidPde;
246 
247  OldPte.u.Long = 0;
248 
249  DPRINT("MmDeleteVirtualMapping(%p, %p, %p, %p)\n", Process, Address, WasDirty, Page);
250 
251  ASSERT(((ULONG_PTR)Address % PAGE_SIZE) == 0);
252 
253  /* And we should be at low IRQL */
255 
256  /* Make sure our PDE is valid, and that everything is going fine */
257  if (Process == NULL)
258  {
260  {
261  DPRINT1("NULL process given for user-mode mapping at %p\n", Address);
262  KeBugCheck(MEMORY_MANAGEMENT);
263  }
264 #if (_MI_PAGING_LEVELS == 2)
265  ValidPde = MiSynchronizeSystemPde(MiAddressToPde(Address));
266 #else
267  ValidPde = MiIsPdeForAddressValid(Address);
268 #endif
269  }
270  else
271  {
273  {
274  DPRINT1("Process %p given for kernel-mode mapping at %p\n", Process, Address);
275  KeBugCheck(MEMORY_MANAGEMENT);
276  }
277 
278  /* Only for current process !!! */
281 
282  ValidPde = MiIsPageTablePresent(Address);
283  if (ValidPde)
284  {
286  }
287  }
288 
289  /* Get the PTE if we're having anything */
290  if (ValidPde)
291  {
292  PointerPte = MiAddressToPte(Address);
293  OldPte.u.Long = InterlockedExchangePte(PointerPte, 0);
294 
296 
297  if (OldPte.u.Long != 0)
298  {
299  /* It must have been present, or not a swap entry */
300  ASSERT(OldPte.u.Hard.Valid || !FlagOn(OldPte.u.Long, 0x800));
301  if (WasDirty != NULL)
302  {
303  *WasDirty = !!OldPte.u.Hard.Dirty;
304  }
305  if (Page != NULL)
306  {
307  *Page = OldPte.u.Hard.PageFrameNumber;
308  }
309  }
310  }
311 
312  if (Process != NULL)
313  {
314  /* Remove PDE reference, if needed */
315  if (OldPte.u.Long != 0)
316  {
318  {
319  KIRQL OldIrql = MiAcquirePfnLock();
321  MiReleasePfnLock(OldIrql);
322  }
323  }
324 
326  }
327 
328  return OldPte.u.Long != 0;
329 }
330 
331 
332 VOID
333 NTAPI
336  PVOID Address,
337  SWAPENTRY* SwapEntry)
338 {
339  PMMPTE PointerPte;
340  MMPTE OldPte;
341 
342  /* This should not be called for kernel space anymore */
343  ASSERT(Process != NULL);
345 
346  /* And we don't support deleting for other process */
348 
349  /* And we should be at low IRQL */
351 
352  /* We are tinkering with the PDE here. Ensure it will be there */
354 
355  /* Callers must ensure there is actually something there */
356  ASSERT(MiAddressToPde(Address)->u.Long != 0);
357 
359 
360  PointerPte = MiAddressToPte(Address);
361  OldPte.u.Long = InterlockedExchangePte(PointerPte, 0);
362  /* This must be a swap entry ! */
363  if (!FlagOn(OldPte.u.Long, 0x800) || OldPte.u.Hard.Valid)
364  {
365  KeBugCheckEx(MEMORY_MANAGEMENT, OldPte.u.Long, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
366  }
367 
368  /* This used to be a non-zero PTE, now we can let the PDE go. */
370  {
371  /* We can let it go */
372  KIRQL OldIrql = MiAcquirePfnLock();
373  MiDeletePde(MiPteToPde(PointerPte), Process);
374  MiReleasePfnLock(OldIrql);
375  }
376 
378 
379  *SwapEntry = OldPte.u.Long >> 1;
380 }
381 
382 BOOLEAN
383 NTAPI
385 {
386  BOOLEAN Ret;
387 
389  {
390  ASSERT(Process == NULL);
391 #if _MI_PAGING_LEVELS == 2
392  if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
393 #else
395 #endif
396  {
397  /* It can't be present if there is no PDE */
398  return FALSE;
399  }
400 
401  return MiAddressToPte(Address)->u.Hard.Valid;
402  }
403 
404  ASSERT(Process != NULL);
406 
408 
410  {
411  /* It can't be present if there is no PDE */
413  return FALSE;
414  }
415 
417 
418  Ret = MiAddressToPte(Address)->u.Hard.Valid;
419 
421 
422  return Ret;
423 }
424 
425 BOOLEAN
426 NTAPI
428 {
429  BOOLEAN Ret;
430  PMMPTE PointerPte;
431 
433  {
434  ASSERT(Process == NULL);
435 #if _MI_PAGING_LEVELS == 2
436  if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
437 #else
439 #endif
440  {
441  /* It's not disabled if it's not present */
442  return FALSE;
443  }
444  }
445  else
446  {
447  ASSERT(Process != NULL);
449 
451 
453  {
454  /* It can't be disabled if there is no PDE */
456  return FALSE;
457  }
458 
460  }
461 
462  PointerPte = MiAddressToPte(Address);
463  Ret = !PointerPte->u.Hard.Valid
464  && !FlagOn(PointerPte->u.Long, 0x800)
465  && (PointerPte->u.Hard.PageFrameNumber != 0);
466 
469 
470  return Ret;
471 }
472 
473 BOOLEAN
474 NTAPI
476 {
477  BOOLEAN Ret;
478  PMMPTE PointerPte;
479 
480  /* We never set swap entries for kernel addresses */
482  {
483  ASSERT(Process == NULL);
484  return FALSE;
485  }
486 
487  ASSERT(Process != NULL);
489 
491 
493  {
494  /* There can't be a swap entry if there is no PDE */
496  return FALSE;
497  }
498 
500 
501  PointerPte = MiAddressToPte(Address);
502  Ret = !PointerPte->u.Hard.Valid && FlagOn(PointerPte->u.Long, 0x800);
503 
505 
506  return Ret;
507 }
508 
509 VOID
510 NTAPI
512 {
513  PMMPTE PointerPte;
514 
515  /* We never set swap entries for kernel addresses */
517  {
518  ASSERT(Process == NULL);
519  *SwapEntry = 0;
520  return;
521  }
522 
523  ASSERT(Process != NULL);
525 
527 
529  {
530  /* There can't be a swap entry if there is no PDE */
532  *SwapEntry = 0;
533  return;
534  }
535 
537 
538  PointerPte = MiAddressToPte(Address);
539  if (!PointerPte->u.Hard.Valid && FlagOn(PointerPte->u.Long, 0x800))
540  *SwapEntry = PointerPte->u.Long >> 1;
541  else
542  *SwapEntry = 0;
543 
545 }
546 
547 NTSTATUS
548 NTAPI
550  PVOID Address,
551  SWAPENTRY SwapEntry)
552 {
553  PMMPTE PointerPte;
554  ULONG_PTR Pte;
555 
556  /* This should not be called for kernel space anymore */
557  ASSERT(Process != NULL);
559 
560  /* And we don't support creating for other process */
562 
563  if (SwapEntry & (1 << 31))
564  {
565  KeBugCheck(MEMORY_MANAGEMENT);
566  }
567 
568  /* We are tinkering with the PDE here. Ensure it will be there */
571 
573 
574  PointerPte = MiAddressToPte(Address);
575  Pte = InterlockedExchangePte(PointerPte, SwapEntry << 1);
576  if (Pte != 0)
577  {
578  KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
579  }
580 
581  /* This used to be a 0 PTE, now we need a valid PDE to keep it around */
584 
585  return STATUS_SUCCESS;
586 }
587 
588 
589 NTSTATUS
590 NTAPI
592  PVOID Address,
593  ULONG flProtect,
595 {
596  ULONG ProtectionMask;
597  PMMPTE PointerPte;
598  MMPTE TempPte;
599  ULONG_PTR Pte;
600 
601  DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %x)\n",
602  Process, Address, flProtect, Page);
603 
604  ASSERT(((ULONG_PTR)Address % PAGE_SIZE) == 0);
605 
606  ProtectionMask = MiMakeProtectionMask(flProtect);
607  /* Caller must have checked ! */
608  ASSERT(ProtectionMask != MM_INVALID_PROTECTION);
609  ASSERT(ProtectionMask != MM_NOACCESS);
610  ASSERT(ProtectionMask != MM_ZERO_ACCESS);
611 
612  /* Make sure our PDE is valid, and that everything is going fine */
613  if (Process == NULL)
614  {
615  /* We don't support this in legacy Mm for kernel mappings */
616  ASSERT(ProtectionMask != MM_WRITECOPY);
617  ASSERT(ProtectionMask != MM_EXECUTE_WRITECOPY);
618 
620  {
621  DPRINT1("NULL process given for user-mode mapping at %p\n", Address);
622  KeBugCheck(MEMORY_MANAGEMENT);
623  }
624 #if _MI_PAGING_LEVELS == 2
625  if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
627 #endif
628  }
629  else
630  {
632  {
633  DPRINT1("Process %p given for kernel-mode mapping at %p -- 1 page starting at %Ix\n",
634  Process, Address, Page);
635  KeBugCheck(MEMORY_MANAGEMENT);
636  }
637 
638  /* Only for current process !!! */
641 
643  }
644 
645  PointerPte = MiAddressToPte(Address);
646 
647  MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, ProtectionMask, Page);
648 
649  Pte = InterlockedExchangePte(PointerPte, TempPte.u.Long);
650  /* There should not have been anything valid here */
651  if (Pte != 0)
652  {
653  DPRINT1("Bad PTE %lx at %p for %p\n", Pte, PointerPte, Address);
654  KeBugCheck(MEMORY_MANAGEMENT);
655  }
656 
657  /* We don't need to flush the TLB here because it only caches valid translations
658  * and we're moving this PTE from invalid to valid so it can't be cached right now */
659 
661  {
662  /* Add PDE reference */
665  }
666 
667  return(STATUS_SUCCESS);
668 }
669 
670 NTSTATUS
671 NTAPI
673  PVOID Address,
674  ULONG flProtect,
676 {
678  if (!MmIsPageInUse(Page))
679  {
680  DPRINT1("Page %lx is not in use\n", Page);
681  KeBugCheck(MEMORY_MANAGEMENT);
682  }
683 
684  return MmCreateVirtualMappingUnsafe(Process, Address, flProtect, Page);
685 }
686 
687 ULONG
688 NTAPI
690 {
691  PMMPTE PointerPte;
692  ULONG Protect;
693 
695  {
696  ASSERT(Process == NULL);
697 
698 #if _MI_PAGING_LEVELS == 2
699  if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
700 #else
702 #endif
703  {
704  return PAGE_NOACCESS;
705  }
706  }
707  else
708  {
710  ASSERT(Process != NULL);
711 
713 
715 
717  {
718  /* It can't be present if there is no PDE */
720  return PAGE_NOACCESS;
721  }
722 
724  }
725 
726  PointerPte = MiAddressToPte(Address);
727 
728  if (!PointerPte->u.Flush.Valid)
729  {
731  }
732  else
733  {
734  if (PointerPte->u.Flush.CopyOnWrite)
736  else if (PointerPte->u.Flush.Write)
738  else
740 #if _MI_PAGING_LEVELS >= 3
741  /* PAE & AMD64 long mode support NoExecute bit */
742  if (!PointerPte->u.Flush.NoExecute)
743  Protect <<= 4;
744 #endif
745  if (PointerPte->u.Flush.CacheDisable)
747  if (PointerPte->u.Flush.WriteThrough)
749  }
750 
753 
754  return(Protect);
755 }
756 
757 VOID
758 NTAPI
760 {
761  ULONG ProtectionMask;
762  PMMPTE PointerPte;
763  MMPTE TempPte, OldPte;
764 
765  DPRINT("MmSetPageProtect(Process %p Address %p flProtect %x)\n",
766  Process, Address, flProtect);
767 
768  ASSERT(Process != NULL);
770 
772 
773  ProtectionMask = MiMakeProtectionMask(flProtect);
774  /* Caller must have checked ! */
775  ASSERT(ProtectionMask != MM_INVALID_PROTECTION);
776 
778 
780 
781  PointerPte = MiAddressToPte(Address);
782 
783  /* Sanity check */
784  ASSERT(PointerPte->u.Hard.Owner == 1);
785 
786  TempPte.u.Long = 0;
787  TempPte.u.Hard.PageFrameNumber = PointerPte->u.Hard.PageFrameNumber;
788  TempPte.u.Long |= MmProtectToPteMask[ProtectionMask];
789  TempPte.u.Hard.Owner = 1;
790 
791  /* Only set valid bit if we have to */
792  if ((ProtectionMask != MM_NOACCESS) && !FlagOn(ProtectionMask, MM_GUARDPAGE))
793  TempPte.u.Hard.Valid = 1;
794 
795  /* Keep dirty & accessed bits */
796  TempPte.u.Hard.Accessed = PointerPte->u.Hard.Accessed;
797  TempPte.u.Hard.Dirty = PointerPte->u.Hard.Dirty;
798 
799  OldPte.u.Long = InterlockedExchangePte(PointerPte, TempPte.u.Long);
800 
801  // We should be able to bring a page back from PAGE_NOACCESS
802  if (!OldPte.u.Hard.Valid && (FlagOn(OldPte.u.Long, 0x800) || (OldPte.u.Hard.PageFrameNumber == 0)))
803  {
804  DPRINT1("Invalid Pte %lx\n", OldPte.u.Long);
805  KeBugCheck(MEMORY_MANAGEMENT);
806  }
807 
808  if (OldPte.u.Long != TempPte.u.Long)
810 
812 }
813 
814 VOID
815 NTAPI
817 {
818  PMMPTE PointerPte;
819 
820  DPRINT("MmSetDirtyBit(Process %p Address %p Bit %x)\n",
821  Process, Address, Bit);
822 
823  ASSERT(Process != NULL);
825 
827 
829 
831 
832  PointerPte = MiAddressToPte(Address);
833  // We shouldnl't set dirty bit on non-mapped adresses
834  if (!PointerPte->u.Hard.Valid && (FlagOn(PointerPte->u.Long, 0x800) || (PointerPte->u.Hard.PageFrameNumber == 0)))
835  {
836  DPRINT1("Invalid Pte %lx\n", PointerPte->u.Long);
837  KeBugCheck(MEMORY_MANAGEMENT);
838  }
839 
840  PointerPte->u.Hard.Dirty = !!Bit;
841 
842  if (!Bit)
844 
846 }
847 
848 CODE_SEG("INIT")
849 VOID
850 NTAPI
852 {
853  /* Nothing to do here */
854 }
855 
856 #ifdef _M_IX86
857 BOOLEAN
859 {
860  PMMPDE PointerPde = MiAddressToPde(Address);
861  PMMPTE PointerPte = MiAddressToPte(Address);
862 
863  if (PointerPde->u.Hard.Valid == 0)
864  {
865  if (!MiSynchronizeSystemPde(PointerPde))
866  return FALSE;
867  return PointerPte->u.Hard.Valid != 0;
868  }
869  return FALSE;
870 }
871 #endif
872 
873 /* 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:109
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:816
#define PFN_FROM_PDE(v)
Definition: mm.h:93
#define Add2Ptr(PTR, INC)
#define _In_opt_
Definition: ms_sal.h:309
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:161
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2427
_In_ PVOID _Out_opt_ BOOLEAN * WasDirty
Definition: mm.h:1295
FORCEINLINE USHORT MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2512
#define MM_NOACCESS
Definition: miarm.h:65
HARDWARE_PTE Flush
Definition: mmtypes.h:216
FORCEINLINE BOOLEAN MiIsPdeForAddressValid(PVOID Address)
Definition: mm.h:366
VOID NTAPI MmInitGlobalKernelPageDirectory(VOID)
Definition: page.c:277
ULONG64 CopyOnWrite
Definition: mmtypes.h:75
union _MMPTE::@2309 u
FORCEINLINE PMMPDE MiPteToPde(PMMPTE PointerPte)
Definition: mm.h:268
#define MiGetPdeOffset(x)
Definition: mm.h:195
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:70
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
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1295
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:2475
static WCHAR Address[46]
Definition: ping.c:68
ULONG64 WriteThrough
Definition: mmtypes.h:69
#define _In_
Definition: ms_sal.h:308
#define PAGE_EXECUTE
Definition: nt_native.h:1306
ULONG NTAPI MiMakeSystemAddressValid(IN PVOID PageTableVirtualAddress, IN PEPROCESS CurrentProcess)
Definition: virtual.c:183
#define MM_ZERO_ACCESS
Definition: miarm.h:43
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:171
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1174
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:264
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:462
FORCEINLINE VOID MiLockProcessWorkingSetShared(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1151
_Success_(return)
Deletes the virtual mapping and optionally gives back the page & dirty bit.
Definition: page.c:235
FORCEINLINE USHORT MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2486
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
#define MM_GUARDPAGE
Definition: miarm.h:57
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:140
Definition: mm.h:373
#define InterlockedExchangePte(PointerPte, Value)
Definition: mm.h:190
#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:2546
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
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:56
#define _Out_opt_
Definition: ms_sal.h:346
_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:407
#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:208
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