ReactOS  0.4.15-dev-1377-ga59cecd
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 #define ADDR_TO_PDE_OFFSET MiAddressToPdeOffset
19 #define ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (1024 * PAGE_SIZE))
20 
21 /* GLOBALS *****************************************************************/
22 
23 #define PA_BIT_PRESENT (0)
24 #define PA_BIT_READWRITE (1)
25 #define PA_BIT_USER (2)
26 #define PA_BIT_WT (3)
27 #define PA_BIT_CD (4)
28 #define PA_BIT_ACCESSED (5)
29 #define PA_BIT_DIRTY (6)
30 #define PA_BIT_GLOBAL (8)
31 
32 #define PA_PRESENT (1 << PA_BIT_PRESENT)
33 #define PA_READWRITE (1 << PA_BIT_READWRITE)
34 #define PA_USER (1 << PA_BIT_USER)
35 #define PA_DIRTY (1 << PA_BIT_DIRTY)
36 #define PA_WT (1 << PA_BIT_WT)
37 #define PA_CD (1 << PA_BIT_CD)
38 #define PA_ACCESSED (1 << PA_BIT_ACCESSED)
39 #define PA_GLOBAL (1 << PA_BIT_GLOBAL)
40 
41 #define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPER_SPACE && (ULONG)(v) <= HYPER_SPACE_END))
42 
43 #define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT)
44 #define PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
45 
46 #define PAGE_MASK(x) ((x)&(~0xfff))
47 
48 const
49 ULONG
51 {
52  //
53  // These are the base MM_ protection flags
54  //
55  0,
56  PTE_READONLY | PTE_ENABLE_CACHE,
57  PTE_EXECUTE | PTE_ENABLE_CACHE,
58  PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
59  PTE_READWRITE | PTE_ENABLE_CACHE,
60  PTE_WRITECOPY | PTE_ENABLE_CACHE,
61  PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
62  PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
63  //
64  // These OR in the MM_NOCACHE flag
65  //
66  0,
67  PTE_READONLY | PTE_DISABLE_CACHE,
68  PTE_EXECUTE | PTE_DISABLE_CACHE,
69  PTE_EXECUTE_READ | PTE_DISABLE_CACHE,
70  PTE_READWRITE | PTE_DISABLE_CACHE,
71  PTE_WRITECOPY | PTE_DISABLE_CACHE,
72  PTE_EXECUTE_READWRITE | PTE_DISABLE_CACHE,
73  PTE_EXECUTE_WRITECOPY | PTE_DISABLE_CACHE,
74  //
75  // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM
76  //
77  0,
78  PTE_READONLY | PTE_ENABLE_CACHE,
79  PTE_EXECUTE | PTE_ENABLE_CACHE,
80  PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
81  PTE_READWRITE | PTE_ENABLE_CACHE,
82  PTE_WRITECOPY | PTE_ENABLE_CACHE,
83  PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
84  PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
85  //
86  // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining?
87  //
88  0,
89  PTE_READONLY | PTE_WRITECOMBINED_CACHE,
90  PTE_EXECUTE | PTE_WRITECOMBINED_CACHE,
91  PTE_EXECUTE_READ | PTE_WRITECOMBINED_CACHE,
92  PTE_READWRITE | PTE_WRITECOMBINED_CACHE,
93  PTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
94  PTE_EXECUTE_READWRITE | PTE_WRITECOMBINED_CACHE,
95  PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
96 };
97 
98 const
100 {
103  PAGE_EXECUTE,
133 };
134 
135 /* FUNCTIONS ***************************************************************/
136 
137 static BOOLEAN MmUnmapPageTable(PULONG Pt);
138 
139 VOID
141 {
142  if ((Pt && MmUnmapPageTable(Pt)) || Address >= MmSystemRangeStart)
143  {
145  }
146 }
147 
148 static ULONG
149 ProtectToPTE(ULONG flProtect)
150 {
151  ULONG Attributes = 0;
152 
153  if (flProtect & (PAGE_NOACCESS|PAGE_GUARD))
154  {
155  Attributes = 0;
156  }
157  else if (flProtect & PAGE_IS_WRITABLE)
158  {
160  }
161  else if (flProtect & (PAGE_IS_READABLE | PAGE_IS_EXECUTABLE))
162  {
164  }
165  else
166  {
167  DPRINT1("Unknown main protection type.\n");
168  KeBugCheck(MEMORY_MANAGEMENT);
169  }
170 
171  if (flProtect & PAGE_SYSTEM)
172  {
173  }
174  else
175  {
177  }
178  if (flProtect & PAGE_NOCACHE)
179  {
181  }
182  if (flProtect & PAGE_WRITETHROUGH)
183  {
185  }
186  return(Attributes);
187 }
188 
189 NTSTATUS
190 NTAPI
191 MiDispatchFault(IN ULONG FaultCode,
192  IN PVOID Address,
193  IN PMMPTE PointerPte,
194  IN PMMPTE PointerProtoPte,
195  IN BOOLEAN Recursive,
197  IN PVOID TrapInformation,
198  IN PVOID Vad);
199 
200 NTSTATUS
201 NTAPI
204 
205 static PULONG
207 {
208  PFN_NUMBER Pfn;
209  PULONG Pt;
210  PMMPDE PointerPde;
211 
213  {
214  /* We should have a process for user land addresses */
215  ASSERT(Process != NULL);
216 
218  {
219  PMMPDE PdeBase;
220  ULONG PdeOffset = MiGetPdeOffset(Address);
221 
222  /* Nobody but page fault should ask for creating the PDE,
223  * Which imples that Process is the current one */
224  ASSERT(Create == FALSE);
225 
226  PdeBase = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase[0]));
227  if (PdeBase == NULL)
228  {
229  KeBugCheck(MEMORY_MANAGEMENT);
230  }
231  PointerPde = PdeBase + PdeOffset;
232  if (PointerPde->u.Hard.Valid == 0)
233  {
234  MmDeleteHyperspaceMapping(PdeBase);
235  return NULL;
236  }
237  else
238  {
239  Pfn = PointerPde->u.Hard.PageFrameNumber;
240  }
241  MmDeleteHyperspaceMapping(PdeBase);
242  Pt = MmCreateHyperspaceMapping(Pfn);
243  if (Pt == NULL)
244  {
245  KeBugCheck(MEMORY_MANAGEMENT);
246  }
247  return Pt + MiAddressToPteOffset(Address);
248  }
249  /* This is for our process */
250  PointerPde = MiAddressToPde(Address);
252  if (PointerPde->u.Hard.Valid == 0)
253  {
255  if (Create == FALSE)
256  {
257  return NULL;
258  }
259  ASSERT(PointerPde->u.Long == 0);
260 
261  MI_WRITE_INVALID_PTE(PointerPde, DemandZeroPde);
262  // Tiny HACK: Parameter 1 is the architecture specific FaultCode for an access violation (i.e. page is present)
264  Pt,
265  PointerPde,
266  NULL,
267  FALSE,
269  NULL,
270  NULL);
273  ASSERT(PointerPde->u.Hard.Valid == 1);
274  }
275  return (PULONG)MiAddressToPte(Address);
276  }
277 
278  /* This is for kernel land address */
279  ASSERT(Process == NULL);
280  PointerPde = MiAddressToPde(Address);
282  if (PointerPde->u.Hard.Valid == 0)
283  {
284  /* Let ARM3 synchronize the PDE */
285  if(!MiSynchronizeSystemPde(PointerPde))
286  {
287  /* PDE (still) not valid, let ARM3 allocate one if asked */
288  if(Create == FALSE)
289  return NULL;
291  }
292  }
293  return Pt;
294 }
295 
297 {
298  if (!IS_HYPERSPACE(Pt))
299  {
300  return TRUE;
301  }
302 
303  if (Pt)
304  {
306  }
307  return FALSE;
308 }
309 
311 {
312  ULONG Pte;
313  PULONG Pt;
314 
316  if (Pt)
317  {
318  Pte = *Pt;
319  MmUnmapPageTable(Pt);
320  return Pte;
321  }
322  return 0;
323 }
324 
326 NTAPI
328  PVOID Address)
329 {
330  ULONG Entry;
332  if (!(Entry & PA_PRESENT))
333  {
334  return 0;
335  }
336  return(PTE_TO_PFN(Entry));
337 }
338 
339 VOID
340 NTAPI
342  BOOLEAN* WasDirty, PPFN_NUMBER Page)
343 /*
344  * FUNCTION: Delete a virtual mapping
345  */
346 {
347  BOOLEAN WasValid = FALSE;
348  PFN_NUMBER Pfn;
349  ULONG Pte;
350  PULONG Pt;
351 
352  DPRINT("MmDeleteVirtualMapping(%p, %p, %p, %p)\n",
353  Process, Address, WasDirty, Page);
354 
356 
357  if (Pt == NULL)
358  {
359  if (WasDirty != NULL)
360  {
361  *WasDirty = FALSE;
362  }
363  if (Page != NULL)
364  {
365  *Page = 0;
366  }
367  return;
368  }
369 
370  /*
371  * Atomically set the entry to zero and get the old value.
372  */
373  Pte = InterlockedExchangePte(Pt, 0);
374 
375  /* We count a mapping as valid if it's a present page, or it's a nonzero pfn with
376  * the swap bit unset, indicating a valid page protected to PAGE_NOACCESS. */
377  WasValid = (Pte & PA_PRESENT) || ((Pte >> PAGE_SHIFT) && !(Pte & 0x800));
378  if (WasValid)
379  {
380  /* Flush the TLB since we transitioned this PTE
381  * from valid to invalid so any stale translations
382  * are removed from the cache */
383  MiFlushTlb(Pt, Address);
384 
386  {
387  /* Remove PDE reference */
388  Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
389  ASSERT(Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] < PTE_PER_PAGE);
390  }
391 
392  Pfn = PTE_TO_PFN(Pte);
393  }
394  else
395  {
396  MmUnmapPageTable(Pt);
397  Pfn = 0;
398  }
399 
400  /*
401  * Return some information to the caller
402  */
403  if (WasDirty != NULL)
404  {
405  *WasDirty = ((Pte & PA_DIRTY) && (Pte & PA_PRESENT)) ? TRUE : FALSE;
406  }
407  if (Page != NULL)
408  {
409  *Page = Pfn;
410  }
411 }
412 
413 VOID
414 NTAPI
416  SWAPENTRY* SwapEntry)
417 /*
418  * FUNCTION: Get a page file mapping
419  */
420 {
422  *SwapEntry = Entry >> 1;
423 }
424 
425 VOID
426 NTAPI
428  SWAPENTRY* SwapEntry)
429 /*
430  * FUNCTION: Delete a virtual mapping
431  */
432 {
433  ULONG Pte;
434  PULONG Pt;
435 
437 
438  if (Pt == NULL)
439  {
440  *SwapEntry = 0;
441  return;
442  }
443 
444  /*
445  * Atomically set the entry to zero and get the old value.
446  */
447  Pte = InterlockedExchangePte(Pt, 0);
448 
450  {
451  /* Remove PDE reference */
452  Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]--;
453  ASSERT(Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] < PTE_PER_PAGE);
454  }
455 
456  /* We don't need to flush here because page file entries
457  * are invalid translations, so the processor won't cache them */
458  MmUnmapPageTable(Pt);
459 
460  if ((Pte & PA_PRESENT) || !(Pte & 0x800))
461  {
462  DPRINT1("Pte %x (want not 1 and 0x800)\n", Pte);
463  KeBugCheck(MEMORY_MANAGEMENT);
464  }
465 
466  /*
467  * Return some information to the caller
468  */
469  *SwapEntry = Pte >> 1;
470 }
471 
472 BOOLEAN
474 {
475  PMMPDE PointerPde = MiAddressToPde(Address);
476  PMMPTE PointerPte = MiAddressToPte(Address);
477 
478  if (PointerPde->u.Hard.Valid == 0)
479  {
480  if(!MiSynchronizeSystemPde(PointerPde))
481  return FALSE;
482  return PointerPte->u.Hard.Valid != 0;
483  }
484  return FALSE;
485 }
486 
487 BOOLEAN
488 NTAPI
490 {
492 }
493 
494 VOID
495 NTAPI
497 {
498  PULONG Pt;
499  ULONG Pte;
500 
502  {
503  DPRINT1("MmSetCleanPage is called for user space without a process.\n");
504  KeBugCheck(MEMORY_MANAGEMENT);
505  }
506 
508  if (Pt == NULL)
509  {
510  KeBugCheck(MEMORY_MANAGEMENT);
511  }
512 
513  do
514  {
515  Pte = *Pt;
516  } while (Pte != InterlockedCompareExchangePte(Pt, Pte & ~PA_DIRTY, Pte));
517 
518  if (!(Pte & PA_PRESENT))
519  {
520  KeBugCheck(MEMORY_MANAGEMENT);
521  }
522  else if (Pte & PA_DIRTY)
523  {
524  MiFlushTlb(Pt, Address);
525  }
526  else
527  {
528  MmUnmapPageTable(Pt);
529  }
530 }
531 
532 VOID
533 NTAPI
535 {
536  PULONG Pt;
537  ULONG Pte;
538 
540  {
541  DPRINT1("MmSetDirtyPage is called for user space without a process.\n");
542  KeBugCheck(MEMORY_MANAGEMENT);
543  }
544 
546  if (Pt == NULL)
547  {
548  KeBugCheck(MEMORY_MANAGEMENT);
549  }
550 
551  do
552  {
553  Pte = *Pt;
554  } while (Pte != InterlockedCompareExchangePte(Pt, Pte | PA_DIRTY, Pte));
555 
556  if (!(Pte & PA_PRESENT))
557  {
558  KeBugCheck(MEMORY_MANAGEMENT);
559  }
560  else
561  {
562  /* The processor will never clear this bit itself, therefore
563  * we do not need to flush the TLB here when setting it */
564  MmUnmapPageTable(Pt);
565  }
566 }
567 
568 BOOLEAN
569 NTAPI
571 {
573 }
574 
575 BOOLEAN
576 NTAPI
578 {
580  return !(Entry & PA_PRESENT) && !(Entry & 0x800) && (Entry >> PAGE_SHIFT);
581 }
582 
583 BOOLEAN
584 NTAPI
586 {
587  ULONG Entry;
589  return !(Entry & PA_PRESENT) && (Entry & 0x800);
590 }
591 
592 NTSTATUS
593 NTAPI
595  PVOID Address,
596  SWAPENTRY SwapEntry)
597 {
598  PULONG Pt;
599  ULONG Pte;
600 
602  {
603  DPRINT1("No process\n");
604  KeBugCheck(MEMORY_MANAGEMENT);
605  }
606  if (Process != NULL && Address >= MmSystemRangeStart)
607  {
608  DPRINT1("Setting kernel address with process context\n");
609  KeBugCheck(MEMORY_MANAGEMENT);
610  }
611 
612  if (SwapEntry & (1 << 31))
613  {
614  KeBugCheck(MEMORY_MANAGEMENT);
615  }
616 
618  if (Pt == NULL)
619  {
620  /* Nobody should page out an address that hasn't even been mapped */
621  /* But we might place a wait entry first, requiring the page table */
622  if (SwapEntry != MM_WAIT_ENTRY)
623  {
624  KeBugCheck(MEMORY_MANAGEMENT);
625  }
627  }
628  Pte = InterlockedExchangePte(Pt, SwapEntry << 1);
629  if (Pte != 0)
630  {
631  KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
632  }
633 
635  {
636  /* Add PDE reference */
637  Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)]++;
638  ASSERT(Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Address)] <= PTE_PER_PAGE);
639  }
640 
641  /* We don't need to flush the TLB here because it
642  * only caches valid translations and a zero PTE
643  * is not a valid translation */
644  MmUnmapPageTable(Pt);
645 
646  return(STATUS_SUCCESS);
647 }
648 
649 
650 NTSTATUS
651 NTAPI
653  PVOID Address,
654  ULONG flProtect,
655  PPFN_NUMBER Pages,
656  ULONG PageCount)
657 {
659  PVOID Addr;
660  ULONG i;
661  ULONG oldPdeOffset, PdeOffset;
662  PULONG Pt = NULL;
663  ULONG Pte;
664  DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %p (%x), %lu)\n",
665  Process, Address, flProtect, Pages, *Pages, PageCount);
666 
667  ASSERT(((ULONG_PTR)Address % PAGE_SIZE) == 0);
668 
669  if (Process == NULL)
670  {
672  {
673  DPRINT1("NULL process given for user-mode mapping at %p -- %lu pages starting at %Ix\n", Address, PageCount, *Pages);
674  KeBugCheck(MEMORY_MANAGEMENT);
675  }
676  if (PageCount > 0x10000 ||
677  (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000)
678  {
679  DPRINT1("Page count too large for kernel-mode mapping at %p -- %lu pages starting at %Ix\n", Address, PageCount, *Pages);
680  KeBugCheck(MEMORY_MANAGEMENT);
681  }
682  }
683  else
684  {
686  {
687  DPRINT1("Process %p given for kernel-mode mapping at %p -- %lu pages starting at %Ix\n", Process, Address, PageCount, *Pages);
688  KeBugCheck(MEMORY_MANAGEMENT);
689  }
690  if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE ||
691  (ULONG_PTR) Address / PAGE_SIZE + PageCount >
693  {
694  DPRINT1("Page count too large for process %p user-mode mapping at %p -- %lu pages starting at %Ix\n", Process, Address, PageCount, *Pages);
695  KeBugCheck(MEMORY_MANAGEMENT);
696  }
697  }
698 
699  Attributes = ProtectToPTE(flProtect);
700  Attributes &= 0xfff;
702  {
703  Attributes &= ~PA_USER;
704  }
705  else
706  {
707  Attributes |= PA_USER;
708  }
709 
710  Addr = Address;
711  /* MmGetPageTableForProcess should be called on the first run, so
712  * let this trigger it */
713  oldPdeOffset = ADDR_TO_PDE_OFFSET(Addr) + 1;
714  for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
715  {
716  if (!(Attributes & PA_PRESENT) && Pages[i] != 0)
717  {
718  DPRINT1("Setting physical address but not allowing access at address "
719  "0x%p with attributes %x/%x.\n",
720  Addr, Attributes, flProtect);
721  KeBugCheck(MEMORY_MANAGEMENT);
722  }
723  PdeOffset = ADDR_TO_PDE_OFFSET(Addr);
724  if (oldPdeOffset != PdeOffset)
725  {
726  if(Pt) MmUnmapPageTable(Pt);
728  if (Pt == NULL)
729  {
730  KeBugCheck(MEMORY_MANAGEMENT);
731  }
732  }
733  else
734  {
735  Pt++;
736  }
737  oldPdeOffset = PdeOffset;
738 
739  Pte = InterlockedExchangePte(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
740 
741  /* There should not be anything valid here */
742  if (Pte != 0)
743  {
744  DPRINT1("Bad PTE %lx at %p for %p + %lu\n", Pte, Pt, Address, i);
745  KeBugCheck(MEMORY_MANAGEMENT);
746  }
747 
748  /* We don't need to flush the TLB here because it only caches valid translations
749  * and we're moving this PTE from invalid to valid so it can't be cached right now */
750 
751  if (Addr < MmSystemRangeStart)
752  {
753  /* Add PDE reference */
754  Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Addr)]++;
755  ASSERT(Process->Vm.VmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Addr)] <= PTE_PER_PAGE);
756  }
757  }
758 
759  ASSERT(Addr > Address);
760  MmUnmapPageTable(Pt);
761 
762  return(STATUS_SUCCESS);
763 }
764 
765 NTSTATUS
766 NTAPI
768  PVOID Address,
769  ULONG flProtect,
770  PPFN_NUMBER Pages,
771  ULONG PageCount)
772 {
773  ULONG i;
774 
776  for (i = 0; i < PageCount; i++)
777  {
778  if (!MmIsPageInUse(Pages[i]))
779  {
780  DPRINT1("Page at address %x not in use\n", PFN_TO_PTE(Pages[i]));
781  KeBugCheck(MEMORY_MANAGEMENT);
782  }
783  }
784 
786  Address,
787  flProtect,
788  Pages,
789  PageCount));
790 }
791 
792 ULONG
793 NTAPI
795 {
796  ULONG Entry;
797  ULONG Protect;
798 
800 
801 
802  if (!(Entry & PA_PRESENT))
803  {
805  }
806  else
807  {
808  if (Entry & PA_READWRITE)
809  {
811  }
812  else
813  {
815  }
816  if (Entry & PA_CD)
817  {
819  }
820  if (Entry & PA_WT)
821  {
823  }
824  if (!(Entry & PA_USER))
825  {
826  Protect |= PAGE_SYSTEM;
827  }
828 
829  }
830  return(Protect);
831 }
832 
833 VOID
834 NTAPI
836 {
837  ULONG Attributes = 0;
838  PULONG Pt;
839  ULONG Pte;
840 
841  DPRINT("MmSetPageProtect(Process %p Address %p flProtect %x)\n",
842  Process, Address, flProtect);
843 
844  Attributes = ProtectToPTE(flProtect);
845 
846  Attributes &= 0xfff;
848  {
849  Attributes &= ~PA_USER;
850  }
851  else
852  {
853  Attributes |= PA_USER;
854  }
855 
857  if (Pt == NULL)
858  {
859  KeBugCheck(MEMORY_MANAGEMENT);
860  }
861  Pte = InterlockedExchangePte(Pt, PAGE_MASK(*Pt) | Attributes | (*Pt & (PA_ACCESSED|PA_DIRTY)));
862 
863  // We should be able to bring a page back from PAGE_NOACCESS
864  if ((Pte & 0x800) || !(Pte >> PAGE_SHIFT))
865  {
866  DPRINT1("Invalid Pte %lx\n", Pte);
867  KeBugCheck(MEMORY_MANAGEMENT);
868  }
869 
870  if((Pte & Attributes) != Attributes)
871  MiFlushTlb(Pt, Address);
872  else
873  MmUnmapPageTable(Pt);
874 }
875 
876 CODE_SEG("INIT")
877 VOID
878 NTAPI
880 {
881  /* Nothing to do here */
882 }
883 
884 /* EOF */
#define PAGE_WRITETHROUGH
Definition: mm.h:85
#define PAGE_NOCACHE
Definition: nt_native.h:1311
static BOOLEAN MmUnmapPageTable(PULONG Pt)
Definition: page.c:296
VOID NTAPI MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:462
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:39
BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID Address)
Definition: page.c:473
BOOLEAN NTAPI MmIsPagePresent(PEPROCESS Process, PVOID Address)
Definition: page.c:292
#define PAGE_IS_EXECUTABLE
Definition: mm.h:139
#define MiAddressToPde(x)
Definition: mmx86.c:20
BOOLEAN NTAPI KeAreAllApcsDisabled(VOID)
Definition: apc.c:985
struct _Entry Entry
Definition: kefuncs.h:627
_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
BOOLEAN NTAPI MmIsDisabledPage(PEPROCESS Process, PVOID Address)
Definition: page.c:301
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI MmIsPageInUse(PFN_NUMBER Page)
Definition: freelist.c:530
union _MMPTE::@2312 u
_In_ BOOLEAN Create
Definition: pstypes.h:519
#define PAGE_GUARD
Definition: nt_native.h:1310
static ULONG ProtectToPTE(ULONG flProtect)
Definition: page.c:149
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3706
VOID NTAPI MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
Definition: page.c:420
LONG NTSTATUS
Definition: precomp.h:26
#define PA_DIRTY
Definition: page.c:35
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2373
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
#define InterlockedExchangePte(pte1, pte2)
Definition: page.c:19
VOID NTAPI MmSetDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:398
#define PTE_TO_PFN(X)
Definition: page.c:43
BOOLEAN NTAPI MmIsDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:337
VOID NTAPI MmInitGlobalKernelPageDirectory(VOID)
Definition: page.c:278
VOID NTAPI MmSetCleanPage(PEPROCESS Process, PVOID Address)
Definition: page.c:376
#define MiGetPdeOffset(x)
Definition: mm.h:188
#define PFN_TO_PTE(X)
Definition: page.c:44
#define PA_WT
Definition: page.c:36
uint32_t ULONG_PTR
Definition: typedefs.h:65
ULONG * PPFN_NUMBER
Definition: ke.h:8
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
ULONG PFN_NUMBER
Definition: ke.h:8
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define PAGE_IS_WRITABLE
Definition: mm.h:133
#define PA_ACCESSED
Definition: page.c:38
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1427
NTSTATUS NTAPI MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry)
Definition: page.c:486
BOOLEAN NTAPI MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
Definition: page.c:313
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define PAGE_NOACCESS
Definition: nt_native.h:1302
unsigned char BOOLEAN
#define PA_PRESENT
Definition: page.c:32
static WCHAR Address[46]
Definition: ping.c:68
#define PAGE_EXECUTE
Definition: nt_native.h:1306
ULONG NTAPI MmGetPageProtect(PEPROCESS Process, PVOID Address)
Definition: page.c:346
void DPRINT(...)
Definition: polytest.cpp:61
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(PEPROCESS Process, PVOID Address, ULONG PageProtection, PPFN_NUMBER Pages, ULONG PageCount)
Definition: page.c:526
void * PVOID
Definition: retypes.h:9
PFN_NUMBER NTAPI MmGetPfnForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:282
#define InterlockedCompareExchangePte(PointerPte, Exchange, Comperand)
Definition: mm.h:160
#define PA_READWRITE
Definition: page.c:33
Status
Definition: gdiplustypes.h:24
#define DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:320
#define IS_HYPERSPACE(v)
Definition: page.c:41
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:201
#define PAGE_MASK(x)
Definition: page.c:46
#define ASSERT(a)
Definition: mode.c:45
const ULONG64 MmProtectToPteMask[32]
Definition: page.c:32
ULONG64 Valid
Definition: mmtypes.h:150
VOID MiFlushTlb(PMMPTE Pte, PVOID Address)
Definition: page.c:128
#define PA_CD
Definition: page.c:37
MMPDE DemandZeroPde
Definition: page.c:114
#define PTE_PER_PAGE
Definition: mm.h:20
CODE_SEG("INIT")
Definition: fsrtlpc.c:19
NTSTATUS NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes)
Definition: section.c:476
#define PAGE_SYSTEM
Definition: mm.h:86
#define MmDeleteHyperspaceMapping(x)
Definition: mm.h:1033
#define ADDR_TO_PDE_OFFSET
Definition: page.c:18
#define PAGE_SIZE
Definition: env_spec_w32.h:49
const ULONG MmProtectToValue[32]
Definition: page.c:81
VOID NTAPI MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
Definition: page.c:357
ULONG_PTR Long
Definition: mmtypes.h:215
static PULONG MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: page.c:206
ULONG_PTR SIZE_T
Definition: typedefs.h:80
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:975
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
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 const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG_PTR SWAPENTRY
Definition: mm.h:47
FORCEINLINE PVOID MmCreateHyperspaceMapping(IN PFN_NUMBER Page)
Definition: mm.h:1027
#define PA_USER
Definition: page.c:34
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1018
unsigned int * PULONG
Definition: retypes.h:1
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:322
#define NULL
Definition: types.h:112
#define PAGE_READONLY
Definition: compat.h:138
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#define DPRINT1
Definition: precomp.h:8
_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
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define MiAddressToPteOffset(x)
Definition: mmx86.c:21
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSTATUS NTAPI MiDispatchFault(IN ULONG FaultCode, IN PVOID Address, IN PMMPTE PointerPte, IN PMMPTE PointerProtoPte, IN BOOLEAN Recursive, IN PEPROCESS Process, IN PVOID TrapInformation, IN PVOID Vad)
#define MmSystemRangeStart
Definition: mm.h:32
NTSTATUS NTAPI MmCreateVirtualMapping(PEPROCESS Process, PVOID Address, ULONG Protect, PPFN_NUMBER Pages, ULONG PageCount)
Definition: page.c:580
base of all file and directory entries
Definition: entries.h:82
static ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:310
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
#define PAGE_IS_READABLE
Definition: mm.h:125
#define PAGE_READWRITE
Definition: nt_native.h:1304
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes