ReactOS  0.4.15-dev-3207-ga415bd4
pagepae.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/pagepae.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 /* GLOBALS *****************************************************************/
17 
18 #define PA_BIT_PRESENT (0)
19 #define PA_BIT_READWRITE (1)
20 #define PA_BIT_USER (2)
21 #define PA_BIT_WT (3)
22 #define PA_BIT_CD (4)
23 #define PA_BIT_ACCESSED (5)
24 #define PA_BIT_DIRTY (6)
25 #define PA_BIT_GLOBAL (8)
26 
27 #define PA_PRESENT (1 << PA_BIT_PRESENT)
28 #define PA_READWRITE (1 << PA_BIT_READWRITE)
29 #define PA_USER (1 << PA_BIT_USER)
30 #define PA_DIRTY (1 << PA_BIT_DIRTY)
31 #define PA_WT (1 << PA_BIT_WT)
32 #define PA_CD (1 << PA_BIT_CD)
33 #define PA_ACCESSED (1 << PA_BIT_ACCESSED)
34 #define PA_GLOBAL (1 << PA_BIT_GLOBAL)
35 
36 #define PAGEDIRECTORY_MAP (0xc0000000 + (PTE_BASE / (1024)))
37 #define PAE_PAGEDIRECTORY_MAP (0xc0000000 + (PTE_BASE / (512)))
38 
39 #define HYPERSPACE (Ke386Pae ? 0xc0800000 : 0xc0400000)
40 #define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
41 
44 
45 #define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT)
46 #define PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
47 
48 #define PAE_PTE_TO_PFN(X) (PAE_PAGE_MASK(X) >> PAGE_SHIFT)
49 #define PAE_PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
50 
51 #define PAGE_MASK(x) ((x)&(~0xfff))
52 #define PAE_PAGE_MASK(x) ((x)&(~0xfffLL))
53 
54 extern BOOLEAN Ke386Pae;
55 extern BOOLEAN Ke386NoExecute;
56 
57 /* FUNCTIONS ***************************************************************/
58 
60 
62 NTAPI
64 {
65  if (Address == (ULONGLONG)-1)
66  {
68  }
69  else if (Address == (ULONGLONG)-2)
70  {
72  }
73  else
74  {
76  }
77  return 0;
78 }
79 
80 VOID
82 {
83 #ifdef CONFIG_SMP
84  if (Pt)
85  {
86  MmUnmapPageTable(Pt);
87  }
88  if (KeNumberProcessors > 1)
89  {
91  }
92  else
93  {
95  }
96 #else
97  if ((Pt && MmUnmapPageTable(Pt)) || Address >= MmSystemRangeStart)
98  {
100  }
101 #endif
102 }
103 
104 static ULONG
105 ProtectToPTE(ULONG flProtect)
106 {
107  ULONG Attributes = 0;
108 
109  if (flProtect & (PAGE_NOACCESS|PAGE_GUARD))
110  {
111  Attributes = 0;
112  }
113  else if (flProtect & PAGE_IS_WRITABLE)
114  {
116  }
117  else if (flProtect & (PAGE_IS_READABLE | PAGE_IS_EXECUTABLE))
118  {
120  }
121  else
122  {
123  DPRINT1("Unknown main protection type.\n");
124  ASSERT(FALSE);
125  }
126  if (Ke386NoExecute &&
127  !(flProtect & PAGE_IS_EXECUTABLE))
128  {
129  Attributes = Attributes | 0x80000000;
130  }
131 
132  if (flProtect & PAGE_SYSTEM)
133  {
134  }
135  else
136  {
138  }
139  if (flProtect & PAGE_NOCACHE)
140  {
142  }
143  if (flProtect & PAGE_WRITETHROUGH)
144  {
146  }
147  return(Attributes);
148 }
149 
150 #define ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (1024 * PAGE_SIZE))
151 
152 #define ADDR_TO_PDE(v) (PULONG)(PAGEDIRECTORY_MAP + \
153  ((((ULONG)(v)) / (1024 * 1024))&(~0x3)))
154 #define ADDR_TO_PTE(v) (PULONG)(PTE_BASE + ((((ULONG)(v) / 1024))&(~0x3)))
155 
156 #define ADDR_TO_PDE_OFFSET(v) ((((ULONG)(v)) / (1024 * PAGE_SIZE)))
157 
158 #define ADDR_TO_PTE_OFFSET(v) ((((ULONG)(v)) % (1024 * PAGE_SIZE)) / PAGE_SIZE)
159 
160 
161 #define PAE_ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (512 * PAGE_SIZE))
162 
163 #define PAE_ADDR_TO_PDE(v) (PULONGLONG) (PAE_PAGEDIRECTORY_MAP + \
164  ((((ULONG_PTR)(v)) / (512 * 512))&(~0x7)))
165 #define PAE_ADDR_TO_PTE(v) (PULONGLONG) (PTE_BASE + ((((ULONG_PTR)(v) / 512))&(~0x7)))
166 
167 
168 #define PAE_ADDR_TO_PDTE_OFFSET(v) (((ULONG_PTR)(v)) / (512 * 512 * PAGE_SIZE))
169 
170 #define PAE_ADDR_TO_PDE_PAGE_OFFSET(v) ((((ULONG_PTR)(v)) % (512 * 512 * PAGE_SIZE)) / (512 * PAGE_SIZE))
171 
172 #define PAE_ADDR_TO_PDE_OFFSET(v) (((ULONG_PTR)(v))/ (512 * PAGE_SIZE))
173 
174 #define PAE_ADDR_TO_PTE_OFFSET(v) ((((ULONG_PTR)(v)) % (512 * PAGE_SIZE)) / PAGE_SIZE)
175 
176 BOOLEAN
177 NTAPI
180  IN PLARGE_INTEGER DirectoryTableBase)
181 {
183  ULONG i, j;
184  PFN_NUMBER Pfn[7];
185  ULONG Count;
186 
187  DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", MinWs, Process);
188 
189  Count = Ke386Pae ? 7 : 2;
190 
191  for (i = 0; i < Count; i++)
192  {
193  Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn[i]);
194  if (!NT_SUCCESS(Status))
195  {
196  for (j = 0; j < i; j++)
197  {
198  MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn[j]);
199  }
200 
201  return FALSE;
202  }
203  }
204 
205  if (Ke386Pae)
206  {
207  PULONGLONG PageDirTable;
208  PULONGLONG PageDir;
209 
210  PageDirTable = MmCreateHyperspaceMapping(Pfn[0]);
211  for (i = 0; i < 4; i++)
212  {
213  PageDirTable[i] = PAE_PFN_TO_PTE(Pfn[1+i]) | PA_PRESENT;
214  }
215  MmDeleteHyperspaceMapping(PageDirTable);
217  {
218  PageDir = (PULONGLONG)MmCreateHyperspaceMapping(Pfn[i+1]);
219  memcpy(PageDir, &MmGlobalKernelPageDirectoryForPAE[i * 512], 512 * sizeof(ULONGLONG));
221  {
222  for (j = 0; j < 4; j++)
223  {
225  }
226  }
228  {
231  }
232  MmDeleteHyperspaceMapping(PageDir);
233  }
234  }
235  else
236  {
237  PULONG PageDirectory;
238  PageDirectory = MmCreateHyperspaceMapping(Pfn[0]);
239 
242  (1024 - ADDR_TO_PDE_OFFSET(MmSystemRangeStart)) * sizeof(ULONG));
243 
244  DPRINT("Addr %x\n",ADDR_TO_PDE_OFFSET(PTE_BASE));
245  PageDirectory[ADDR_TO_PDE_OFFSET(PTE_BASE)] = PFN_TO_PTE(Pfn[0]) | PA_PRESENT | PA_READWRITE;
246  PageDirectory[ADDR_TO_PDE_OFFSET(HYPERSPACE)] = PFN_TO_PTE(Pfn[1]) | PA_PRESENT | PA_READWRITE;
247 
248  MmDeleteHyperspaceMapping(PageDirectory);
249  }
250 
251  DirectoryTableBase->QuadPart = PFN_TO_PTE(Pfn[0]);
252  DPRINT("Finished MmCopyMmInfo(): %I64x\n", DirectoryTableBase->QuadPart);
253  return TRUE;
254 }
255 
256 VOID
257 NTAPI
259 {
261  ULONG i;
262  PFN_NUMBER Pfn;
263 
264  DPRINT("ProcessId %d, Address %x\n", Process->UniqueProcessId, Address);
265  if (Process != NULL && Process != CurrentProcess)
266  {
267  KeAttachProcess(&Process->Pcb);
268  }
269  if (Ke386Pae)
270  {
272  ULONGLONG ZeroPte = 0LL;
274  for (i = 0; i < 512; i++)
275  {
276  if (PageTable[i] != 0LL)
277  {
278  DbgPrint("Page table entry not clear at %x/%x (is %I64x)\n",
279  ((ULONG)Address / (4*1024*1024)), i, PageTable[i]);
280  ASSERT(FALSE);
281  }
282  }
284  (void)ExfpInterlockedExchange64UL(PAE_ADDR_TO_PDE(Address), &ZeroPte);
286  }
287  else
288  {
291  for (i = 0; i < 1024; i++)
292  {
293  if (PageTable[i] != 0)
294  {
295  DbgPrint("Page table entry not clear at %x/%x (is %x)\n",
296  ((ULONG)Address / (4*1024*1024)), i, PageTable[i]);
297  ASSERT(FALSE);
298  }
299  }
300  Pfn = PTE_TO_PFN(*(ADDR_TO_PDE(Address)));
301  *(ADDR_TO_PDE(Address)) = 0;
303  }
304 
306  {
307  // MmGlobalKernelPageDirectory[ADDR_TO_PDE_OFFSET(Address)] = 0;
308  ASSERT(FALSE);
309  }
310  else
311  {
312  MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
313  }
314  if (Process != NULL && Process != CurrentProcess)
315  {
316  KeDetachProcess();
317  }
318 }
319 
320 static PULONGLONG
322 {
324  PFN_NUMBER Pfn;
326  ULONGLONG ZeroEntry = 0LL;
327  PULONGLONG Pt;
328  PULONGLONG PageDir;
329  PULONGLONG PageDirTable;
330 
331  DPRINT("MmGetPageTableForProcessForPAE(%x %x %d)\n",
333  if (Address >= (PVOID)PTE_BASE && Address < (PVOID)((ULONG_PTR)PTE_BASE + 0x800000))
334  {
335  ASSERT(FALSE);
336  }
338  {
339  PageDirTable = MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(Process->Pcb.DirectoryTableBase.QuadPart));
340  if (PageDirTable == NULL)
341  {
342  ASSERT(FALSE);
343  }
344  PageDir = MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(PageDirTable[PAE_ADDR_TO_PDTE_OFFSET(Address)]));
345  MmDeleteHyperspaceMapping(PageDirTable);
346  if (PageDir == NULL)
347  {
348  ASSERT(FALSE);
349  }
351  Entry = ExfInterlockedCompareExchange64UL(PageDir, &ZeroEntry, &ZeroEntry);
352  if (Entry == 0LL)
353  {
354  if (Create == FALSE)
355  {
356  MmDeleteHyperspaceMapping(PageDir);
357  return NULL;
358  }
359  Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
360  if (!NT_SUCCESS(Status))
361  {
362  ASSERT(FALSE);
363  }
365  Entry = ExfInterlockedCompareExchange64UL(PageDir, &Entry, &ZeroEntry);
366  if (Entry != 0LL)
367  {
368  MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
369  Pfn = PAE_PTE_TO_PFN(Entry);
370  }
371  }
372  else
373  {
374  Pfn = PAE_PTE_TO_PFN(Entry);
375  }
376  MmDeleteHyperspaceMapping(PageDir);
377  Pt = MmCreateHyperspaceMapping(Pfn);
378  if (Pt == NULL)
379  {
380  ASSERT(FALSE);
381  }
382  return Pt + PAE_ADDR_TO_PTE_OFFSET(Address);
383  }
384  PageDir = PAE_ADDR_TO_PDE(Address);
385  if (0LL == ExfInterlockedCompareExchange64UL(PageDir, &ZeroEntry, &ZeroEntry))
386  {
388  {
390  {
391  if (Create == FALSE)
392  {
393  return NULL;
394  }
395  Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
396  if (!NT_SUCCESS(Status))
397  {
398  ASSERT(FALSE);
399  }
401  if (Ke386GlobalPagesEnabled)
402  {
403  Entry |= PA_GLOBAL;
404  }
406  {
407  MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
408  }
409  }
411  }
412  else
413  {
414  if (Create == FALSE)
415  {
416  return NULL;
417  }
418  Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
419  if (!NT_SUCCESS(Status))
420  {
421  ASSERT(FALSE);
422  }
424  Entry = ExfInterlockedCompareExchange64UL(PageDir, &Entry, &ZeroEntry);
425  if (Entry != 0LL)
426  {
427  MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
428  }
429  }
430  }
432 }
433 
434 static PULONG
436 {
437  ULONG PdeOffset = ADDR_TO_PDE_OFFSET(Address);
439  PFN_NUMBER Pfn;
440  ULONG Entry;
441  PULONG Pt, PageDir;
442 
444  {
445  PageDir = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase.LowPart));
446  if (PageDir == NULL)
447  {
448  ASSERT(FALSE);
449  }
450  if (0 == InterlockedCompareExchangeUL(&PageDir[PdeOffset], 0, 0))
451  {
452  if (Create == FALSE)
453  {
454  MmDeleteHyperspaceMapping(PageDir);
455  return NULL;
456  }
457  Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
458  if (!NT_SUCCESS(Status) || Pfn == 0)
459  {
460  ASSERT(FALSE);
461  }
462  Entry = InterlockedCompareExchangeUL(&PageDir[PdeOffset], PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER, 0);
463  if (Entry != 0)
464  {
465  MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
466  Pfn = PTE_TO_PFN(Entry);
467  }
468  }
469  else
470  {
471  Pfn = PTE_TO_PFN(PageDir[PdeOffset]);
472  }
473  MmDeleteHyperspaceMapping(PageDir);
474  Pt = MmCreateHyperspaceMapping(Pfn);
475  if (Pt == NULL)
476  {
477  ASSERT(FALSE);
478  }
479  return Pt + ADDR_TO_PTE_OFFSET(Address);
480  }
481  PageDir = ADDR_TO_PDE(Address);
482  if (0 == InterlockedCompareExchangeUL(PageDir, 0, 0))
483  {
485  {
486  if (0 == InterlockedCompareExchangeUL(&MmGlobalKernelPageDirectory[PdeOffset], 0, 0))
487  {
488  if (Create == FALSE)
489  {
490  return NULL;
491  }
492  Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
493  if (!NT_SUCCESS(Status) || Pfn == 0)
494  {
495  ASSERT(FALSE);
496  }
498  if (Ke386GlobalPagesEnabled)
499  {
500  Entry |= PA_GLOBAL;
501  }
503  {
504  MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
505  }
506  }
508  }
509  else
510  {
511  if (Create == FALSE)
512  {
513  return NULL;
514  }
515  Status = MmRequestPageMemoryConsumer(MC_NPPOOL, FALSE, &Pfn);
516  if (!NT_SUCCESS(Status) || Pfn == 0)
517  {
518  ASSERT(FALSE);
519  }
521  if (Entry != 0)
522  {
523  MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
524  }
525  }
526  }
527  return (PULONG)ADDR_TO_PTE(Address);
528 }
529 
531 {
532  if (Ke386Pae)
533  {
534  if ((PULONGLONG)Pt >= (PULONGLONG)PTE_BASE && (PULONGLONG)Pt < (PULONGLONG)PTE_BASE + 4*512*512)
535  {
536  return TRUE;
537  }
538  }
539  else
540  {
541  if (Pt >= (PULONG)PTE_BASE && Pt < (PULONG)PTE_BASE + 1024*1024)
542  {
543  return TRUE;
544  }
545  }
546  if (Pt)
547  {
548  MmDeleteHyperspaceMapping((PVOID)PAGE_ROUND_DOWN(Pt));
549  }
550  return FALSE;
551 }
552 
554 {
555  ULONGLONG Pte;
556  PULONGLONG Pt;
557 
559  if (Pt)
560  {
561  Pte = *Pt;
563  return Pte;
564  }
565  return 0;
566 }
567 
569 {
570  ULONG Pte;
571  PULONG Pt;
572 
574  if (Pt)
575  {
576  Pte = *Pt;
577  MmUnmapPageTable(Pt);
578  return Pte;
579  }
580  return 0;
581 }
582 
584 NTAPI
586  PVOID Address)
587 {
588 
589  if (Ke386Pae)
590  {
593  if (!(Entry & PA_PRESENT))
594  {
595  return 0;
596  }
597  return(PAE_PTE_TO_PFN(Entry));
598  }
599  else
600  {
601  ULONG Entry;
603  if (!(Entry & PA_PRESENT))
604  {
605  return 0;
606  }
607  return(PTE_TO_PFN(Entry));
608  }
609 }
610 
611 VOID
612 NTAPI
614  BOOLEAN* WasDirty, PPFN_NUMBER Page)
615 /*
616  * FUNCTION: Delete a virtual mapping
617  */
618 {
619  BOOLEAN WasValid = FALSE;
620  PFN_NUMBER Pfn;
621 
622  DPRINT("MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n",
623  Process, Address, WasDirty, Page);
624  if (Ke386Pae)
625  {
626  ULONGLONG Pte;
627  PULONGLONG Pt;
628 
630  if (Pt == NULL)
631  {
632  if (WasDirty != NULL)
633  {
634  *WasDirty = FALSE;
635  }
636  if (Page != NULL)
637  {
638  *Page = 0;
639  }
640  return;
641  }
642 
643  /*
644  * Atomically set the entry to zero and get the old value.
645  */
646  Pte = 0LL;
647  Pte = ExfpInterlockedExchange64UL(Pt, &Pte);
648 
649  MiFlushTlb((PULONG)Pt, Address);
650 
651  WasValid = PAE_PAGE_MASK(Pte) != 0 ? TRUE : FALSE;
652  if (WasValid)
653  {
654  Pfn = PAE_PTE_TO_PFN(Pte);
655  MmMarkPageUnmapped(Pfn);
656  }
657  else
658  {
659  Pfn = 0;
660  }
661 
662  /*
663  * Return some information to the caller
664  */
665  if (WasDirty != NULL)
666  {
667  *WasDirty = Pte & PA_DIRTY ? TRUE : FALSE;
668  }
669  if (Page != NULL)
670  {
671  *Page = Pfn;
672  }
673  }
674  else
675  {
676  ULONG Pte;
677  PULONG Pt;
678 
680 
681  if (Pt == NULL)
682  {
683  if (WasDirty != NULL)
684  {
685  *WasDirty = FALSE;
686  }
687  if (Page != NULL)
688  {
689  *Page = 0;
690  }
691  return;
692  }
693 
694  /*
695  * Atomically set the entry to zero and get the old value.
696  */
697  Pte = InterlockedExchangeUL(Pt, 0);
698 
699  MiFlushTlb(Pt, Address);
700 
701  WasValid = (PAGE_MASK(Pte) != 0);
702  if (WasValid)
703  {
704  Pfn = PTE_TO_PFN(Pte);
705  MmMarkPageUnmapped(Pfn);
706  }
707  else
708  {
709  Pfn = 0;
710  }
711 
712  /*
713  * Return some information to the caller
714  */
715  if (WasDirty != NULL)
716  {
717  *WasDirty = Pte & PA_DIRTY ? TRUE : FALSE;
718  }
719  if (Page != NULL)
720  {
721  *Page = Pfn;
722  }
723  }
724  /*
725  * Decrement the reference count for this page table.
726  */
727  if (Process != NULL && WasValid &&
728  ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
730  {
731  PUSHORT Ptrc;
732  ULONG Idx;
733 
734  Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
736 
737  Ptrc[Idx]--;
738  if (Ptrc[Idx] == 0)
739  {
741  }
742  }
743 }
744 
745 VOID
746 NTAPI
748  SWAPENTRY* SwapEntry)
749 /*
750  * FUNCTION: Delete a virtual mapping
751  */
752 {
753  if (Ke386Pae)
754  {
755  ULONGLONG Pte;
756  PULONGLONG Pt;
757 
759  if (Pt == NULL)
760  {
761  *SwapEntry = 0;
762  return;
763  }
764 
765  /*
766  * Atomically set the entry to zero and get the old value.
767  */
768  Pte = 0LL;
769  Pte = ExfpInterlockedExchange64UL(Pt, &Pte);
770 
771  MiFlushTlb((PULONG)Pt, Address);
772 
773  /*
774  * Decrement the reference count for this page table.
775  */
776  if (Process != NULL && Pte &&
777  ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
779  {
780  PUSHORT Ptrc;
781 
782  Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
783 
785  if (Ptrc[PAE_ADDR_TO_PAGE_TABLE(Address)] == 0)
786  {
788  }
789  }
790 
791 
792  /*
793  * Return some information to the caller
794  */
795  *SwapEntry = Pte >> 1;
796  }
797  else
798  {
799  ULONG Pte;
800  PULONG Pt;
801 
803 
804  if (Pt == NULL)
805  {
806  *SwapEntry = 0;
807  return;
808  }
809 
810  /*
811  * Atomically set the entry to zero and get the old value.
812  */
813  Pte = InterlockedExchangeUL(Pt, 0);
814 
815  MiFlushTlb(Pt, Address);
816 
817  /*
818  * Decrement the reference count for this page table.
819  */
820  if (Process != NULL && Pte &&
821  ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
823  {
824  PUSHORT Ptrc;
825 
826  Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
827 
828  Ptrc[ADDR_TO_PAGE_TABLE(Address)]--;
829  if (Ptrc[ADDR_TO_PAGE_TABLE(Address)] == 0)
830  {
832  }
833  }
834 
835 
836  /*
837  * Return some information to the caller
838  */
839  *SwapEntry = Pte >> 1;
840  }
841 }
842 
843 BOOLEAN
845 {
846  if (Ke386Pae)
847  {
848  PULONGLONG Pt;
849  PULONGLONG Pde;
850  Pde = PAE_ADDR_TO_PDE(PAddress);
851  if (*Pde == 0LL)
852  {
853  Pt = MmGetPageTableForProcessForPAE(NULL, PAddress, FALSE);
854 #if 0
855  /* Non existing mappings are not cached within the tlb. We must not invalidate this entry */
856  FLASH_TLB_ONE(PAddress);
857 #endif
858  if (Pt != NULL)
859  {
860  return TRUE;
861  }
862  }
863  }
864  else
865  {
866  PULONG Pt, Pde;
867  Pde = ADDR_TO_PDE(PAddress);
868  if (*Pde == 0)
869  {
870  Pt = MmGetPageTableForProcess(NULL, PAddress, FALSE);
871 #if 0
872  /* Non existing mappings are not cached within the tlb. We must not invalidate this entry */
873  FLASH_TLB_ONE(PAddress);
874 #endif
875  if (Pt != NULL)
876  {
877  return TRUE;
878  }
879  }
880  }
881  return(FALSE);
882 }
883 
884 BOOLEAN
885 NTAPI
887 {
888  if (Ke386Pae)
889  {
891  }
892  else
893  {
895  }
896 }
897 
898 VOID
899 NTAPI
901 {
903  {
904  DPRINT1("MmSetCleanPage is called for user space without a process.\n");
905  ASSERT(FALSE);
906  }
907  if (Ke386Pae)
908  {
909  PULONGLONG Pt;
910  ULONGLONG Pte;
911  ULONGLONG tmpPte;
912 
914 
915  if (Pt == NULL)
916  {
917  ASSERT(FALSE);
918  }
919 
920  do
921  {
922  Pte = *Pt;
923  tmpPte = Pte & ~PA_DIRTY;
924  } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
925 
926  if (Pte & PA_DIRTY)
927  {
928  MiFlushTlb((PULONG)Pt, Address);
929  }
930  else
931  {
933  }
934  }
935  else
936  {
937  PULONG Pt;
938  ULONG Pte;
939 
941 
942  if (Pt == NULL)
943  {
944  ASSERT(FALSE);
945  }
946 
947  do
948  {
949  Pte = *Pt;
950  } while (Pte != InterlockedCompareExchangeUL(Pt, Pte & ~PA_DIRTY, Pte));
951 
952  if (Pte & PA_DIRTY)
953  {
954  MiFlushTlb(Pt, Address);
955  }
956  else
957  {
958  MmUnmapPageTable(Pt);
959  }
960  }
961 }
962 
963 VOID
964 NTAPI
966 {
968  {
969  DPRINT1("MmSetDirtyPage is called for user space without a process.\n");
970  ASSERT(FALSE);
971  }
972  if (Ke386Pae)
973  {
974  PULONGLONG Pt;
975  ULONGLONG Pte;
976  ULONGLONG tmpPte;
977 
979  if (Pt == NULL)
980  {
981  ASSERT(FALSE);
982  }
983 
984  do
985  {
986  Pte = *Pt;
987  tmpPte = Pte | PA_DIRTY;
988  } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
989  if (!(Pte & PA_DIRTY))
990  {
991  MiFlushTlb((PULONG)Pt, Address);
992  }
993  else
994  {
996  }
997  }
998  else
999  {
1000  PULONG Pt;
1001  ULONG Pte;
1002 
1004  if (Pt == NULL)
1005  {
1006  ASSERT(FALSE);
1007  }
1008 
1009  do
1010  {
1011  Pte = *Pt;
1012  } while (Pte != InterlockedCompareExchangeUL(Pt, Pte | PA_DIRTY, Pte));
1013  if (!(Pte & PA_DIRTY))
1014  {
1015  MiFlushTlb(Pt, Address);
1016  }
1017  else
1018  {
1019  MmUnmapPageTable(Pt);
1020  }
1021  }
1022 }
1023 
1024 BOOLEAN
1025 NTAPI
1027 {
1028  if (Ke386Pae)
1029  {
1031  }
1032  else
1033  {
1035  }
1036 }
1037 
1038 BOOLEAN
1039 NTAPI
1041 {
1042  if (Ke386Pae)
1043  {
1044  ULONGLONG Entry;
1046  return !(Entry & PA_PRESENT) && Entry != 0 ? TRUE : FALSE;
1047  }
1048  else
1049  {
1050  ULONG Entry;
1052  return !(Entry & PA_PRESENT) && Entry != 0 ? TRUE : FALSE;
1053  }
1054 }
1055 
1056 NTSTATUS
1057 NTAPI
1059  PVOID Address,
1060  SWAPENTRY SwapEntry)
1061 {
1062  if (Process == NULL && Address < MmSystemRangeStart)
1063  {
1064  DPRINT1("No process\n");
1065  ASSERT(FALSE);
1066  }
1067  if (Process != NULL && Address >= MmSystemRangeStart)
1068  {
1069  DPRINT1("Setting kernel address with process context\n");
1070  ASSERT(FALSE);
1071  }
1072  if (SwapEntry & (1 << 31))
1073  {
1074  ASSERT(FALSE);
1075  }
1076 
1077  if (Ke386Pae)
1078  {
1079  PULONGLONG Pt;
1080  ULONGLONG Pte;
1081  ULONGLONG tmpPte;
1082 
1084  if (Pt == NULL)
1085  {
1086  ASSERT(FALSE);
1087  }
1088  tmpPte = SwapEntry << 1;
1089  Pte = ExfpInterlockedExchange64UL(Pt, &tmpPte);
1090  if (PAE_PAGE_MASK((Pte)) != 0)
1091  {
1092  MmMarkPageUnmapped(PAE_PTE_TO_PFN((Pte)));
1093  }
1094 
1095  if (Pte != 0)
1096  {
1097  MiFlushTlb((PULONG)Pt, Address);
1098  }
1099  else
1100  {
1101  MmUnmapPageTable((PULONG)Pt);
1102  }
1103  }
1104  else
1105  {
1106  PULONG Pt;
1107  ULONG Pte;
1108 
1110  if (Pt == NULL)
1111  {
1112  ASSERT(FALSE);
1113  }
1114  Pte = *Pt;
1115  if (PAGE_MASK((Pte)) != 0)
1116  {
1117  MmMarkPageUnmapped(PTE_TO_PFN((Pte)));
1118  }
1119  (void)InterlockedExchangeUL(Pt, SwapEntry << 1);
1120  if (Pte != 0)
1121  {
1122  MiFlushTlb(Pt, Address);
1123  }
1124  else
1125  {
1126  MmUnmapPageTable(Pt);
1127  }
1128  }
1129  if (Process != NULL &&
1130  ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
1132  {
1133  PUSHORT Ptrc;
1134  ULONG Idx;
1135 
1136  Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
1138  Ptrc[Idx]++;
1139  }
1140  return(STATUS_SUCCESS);
1141 }
1142 
1143 
1144 NTSTATUS
1145 NTAPI
1147  PVOID Address,
1148  ULONG flProtect,
1149  PPFN_NUMBER Pages,
1150  ULONG PageCount)
1151 {
1152  ULONG Attributes;
1153  PVOID Addr;
1154  ULONG i;
1155  ULONG oldPdeOffset, PdeOffset;
1156  BOOLEAN NoExecute = FALSE;
1157 
1158  DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
1159  Process, Address, flProtect, Pages, *Pages, PageCount);
1160 
1161  if (Process == NULL)
1162  {
1164  {
1165  DPRINT1("No process\n");
1166  ASSERT(FALSE);
1167  }
1168  if (PageCount > 0x10000 ||
1169  (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000)
1170  {
1171  DPRINT1("Page count to large\n");
1172  ASSERT(FALSE);
1173  }
1174  }
1175  else
1176  {
1177  if (Address >= MmSystemRangeStart)
1178  {
1179  DPRINT1("Setting kernel address with process context\n");
1180  ASSERT(FALSE);
1181  }
1182  if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE ||
1183  (ULONG_PTR) Address / PAGE_SIZE + PageCount >
1185  {
1186  DPRINT1("Page Count to large\n");
1187  ASSERT(FALSE);
1188  }
1189  }
1190 
1191  Attributes = ProtectToPTE(flProtect);
1192  if (Attributes & 0x80000000)
1193  {
1194  NoExecute = TRUE;
1195  }
1196  Attributes &= 0xfff;
1197  if (Address >= MmSystemRangeStart)
1198  {
1199  Attributes &= ~PA_USER;
1200  if (Ke386GlobalPagesEnabled)
1201  {
1202  Attributes |= PA_GLOBAL;
1203  }
1204  }
1205  else
1206  {
1207  Attributes |= PA_USER;
1208  }
1209 
1210  Addr = Address;
1211 
1212  if (Ke386Pae)
1213  {
1214  ULONGLONG Pte, tmpPte;
1215  PULONGLONG Pt = NULL;
1216 
1217  oldPdeOffset = PAE_ADDR_TO_PDE_OFFSET(Addr) + 1;
1218  for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
1219  {
1220  if (!(Attributes & PA_PRESENT) && Pages[i] != 0)
1221  {
1222  DPRINT1("Setting physical address but not allowing access at address "
1223  "0x%.8X with attributes %x/%x.\n",
1224  Addr, Attributes, flProtect);
1225  ASSERT(FALSE);
1226  }
1227  PdeOffset = PAE_ADDR_TO_PDE_OFFSET(Addr);
1228  if (oldPdeOffset != PdeOffset)
1229  {
1230  MmUnmapPageTable((PULONG)Pt);
1232  if (Pt == NULL)
1233  {
1234  ASSERT(FALSE);
1235  }
1236  }
1237  else
1238  {
1239  Pt++;
1240  }
1241  oldPdeOffset = PdeOffset;
1242 
1243  MmMarkPageMapped(Pages[i]);
1244  tmpPte = PAE_PFN_TO_PTE(Pages[i]) | Attributes;
1245  if (NoExecute)
1246  {
1247  tmpPte |= 0x8000000000000000LL;
1248  }
1249  Pte = ExfpInterlockedExchange64UL(Pt, &tmpPte);
1250  if (PAE_PAGE_MASK((Pte)) != 0LL && !((Pte) & PA_PRESENT))
1251  {
1252  ASSERT(FALSE);
1253  }
1254  if (PAE_PAGE_MASK((Pte)) != 0LL)
1255  {
1256  MmMarkPageUnmapped(PAE_PTE_TO_PFN((Pte)));
1257  }
1258  if (Address < MmSystemRangeStart &&
1259  ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
1261  {
1262  PUSHORT Ptrc;
1263 
1264  Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
1265 
1266  Ptrc[PAE_ADDR_TO_PAGE_TABLE(Addr)]++;
1267  }
1268  if (Pte != 0LL)
1269  {
1270  if (Address > MmSystemRangeStart ||
1271  (Pt >= (PULONGLONG)PTE_BASE && Pt < (PULONGLONG)PTE_BASE + 4*512*512))
1272  {
1273  MiFlushTlb((PULONG)Pt, Address);
1274  }
1275  }
1276  }
1277  if (Addr > Address)
1278  {
1279  MmUnmapPageTable((PULONG)Pt);
1280  }
1281  }
1282  else
1283  {
1284  PULONG Pt = NULL;
1285  ULONG Pte;
1286  oldPdeOffset = ADDR_TO_PDE_OFFSET(Addr) + 1;
1287  for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
1288  {
1289  if (!(Attributes & PA_PRESENT) && Pages[i] != 0)
1290  {
1291  DPRINT1("Setting physical address but not allowing access at address "
1292  "0x%.8X with attributes %x/%x.\n",
1293  Addr, Attributes, flProtect);
1294  ASSERT(FALSE);
1295  }
1296  PdeOffset = ADDR_TO_PDE_OFFSET(Addr);
1297  if (oldPdeOffset != PdeOffset)
1298  {
1299  MmUnmapPageTable(Pt);
1300  Pt = MmGetPageTableForProcess(Process, Addr, TRUE);
1301  if (Pt == NULL)
1302  {
1303  ASSERT(FALSE);
1304  }
1305  }
1306  else
1307  {
1308  Pt++;
1309  }
1310  oldPdeOffset = PdeOffset;
1311 
1312  Pte = *Pt;
1313  MmMarkPageMapped(Pages[i]);
1314  if (PAGE_MASK((Pte)) != 0 && !((Pte) & PA_PRESENT))
1315  {
1316  ASSERT(FALSE);
1317  }
1318  if (PAGE_MASK((Pte)) != 0)
1319  {
1320  MmMarkPageUnmapped(PTE_TO_PFN((Pte)));
1321  }
1323  if (Address < MmSystemRangeStart &&
1324  ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
1326  {
1327  PUSHORT Ptrc;
1328 
1329  Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
1330 
1331  Ptrc[ADDR_TO_PAGE_TABLE(Addr)]++;
1332  }
1333  if (Pte != 0)
1334  {
1335  if (Address > MmSystemRangeStart ||
1336  (Pt >= (PULONG)PTE_BASE && Pt < (PULONG)PTE_BASE + 1024*1024))
1337  {
1338  MiFlushTlb(Pt, Address);
1339  }
1340  }
1341  }
1342  if (Addr > Address)
1343  {
1344  MmUnmapPageTable(Pt);
1345  }
1346  }
1347  return(STATUS_SUCCESS);
1348 }
1349 
1350 NTSTATUS
1351 NTAPI
1353  PVOID Address,
1354  ULONG flProtect,
1355  PPFN_NUMBER Pages,
1356  ULONG PageCount)
1357 {
1358  ULONG i;
1359 
1360  for (i = 0; i < PageCount; i++)
1361  {
1362  if (!MmIsPageInUse(Pages[i]))
1363  {
1364  DPRINT1("Page at address %x not in use\n", PFN_TO_PTE(Pages[i]));
1365  ASSERT(FALSE);
1366  }
1367  }
1368 
1370  Address,
1371  flProtect,
1372  Pages,
1373  PageCount));
1374 }
1375 
1376 ULONG
1377 NTAPI
1379 {
1380  ULONG Entry;
1381  ULONG Protect;
1382  if (Ke386Pae)
1383  {
1385  }
1386  else
1387  {
1389  }
1390 
1391  if (!(Entry & PA_PRESENT))
1392  {
1394  }
1395  else
1396  {
1397  if (Entry & PA_READWRITE)
1398  {
1400  }
1401  else
1402  {
1404  }
1405  if (Entry & PA_CD)
1406  {
1407  Protect |= PAGE_NOCACHE;
1408  }
1409  if (Entry & PA_WT)
1410  {
1412  }
1413  if (!(Entry & PA_USER))
1414  {
1415  Protect |= PAGE_SYSTEM;
1416  }
1417 
1418  }
1419  return(Protect);
1420 }
1421 
1422 VOID
1423 NTAPI
1425 {
1426  ULONG Attributes = 0;
1427  BOOLEAN NoExecute = FALSE;
1428 
1429  DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n",
1430  Process, Address, flProtect);
1431 
1432  Attributes = ProtectToPTE(flProtect);
1433  if (Attributes & 0x80000000)
1434  {
1435  NoExecute = TRUE;
1436  }
1437  Attributes &= 0xfff;
1438  if (Address >= MmSystemRangeStart)
1439  {
1440  Attributes &= ~PA_USER;
1441  if (Ke386GlobalPagesEnabled)
1442  {
1443  Attributes |= PA_GLOBAL;
1444  }
1445  }
1446  else
1447  {
1448  Attributes |= PA_USER;
1449  }
1450  if (Ke386Pae)
1451  {
1452  PULONGLONG Pt;
1453  ULONGLONG tmpPte, Pte;
1454 
1456  if (Pt == NULL)
1457  {
1458  DPRINT1("Address %x\n", Address);
1459  ASSERT(FALSE);
1460  }
1461  do
1462  {
1463  Pte = *Pt;
1464  tmpPte = PAE_PAGE_MASK(Pte) | Attributes | (Pte & (PA_ACCESSED|PA_DIRTY));
1465  if (NoExecute)
1466  {
1467  tmpPte |= 0x8000000000000000LL;
1468  }
1469  else
1470  {
1471  tmpPte &= ~0x8000000000000000LL;
1472  }
1473  } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
1474 
1475  MiFlushTlb((PULONG)Pt, Address);
1476  }
1477  else
1478  {
1479  PULONG Pt;
1480 
1482  if (Pt == NULL)
1483  {
1484  ASSERT(FALSE);
1485  }
1487  MiFlushTlb(Pt, Address);
1488  }
1489 }
1490 
1491 CODE_SEG("INIT")
1492 VOID
1493 NTAPI
1495 {
1496  ULONG i;
1497 
1498  DPRINT("MmInitGlobalKernelPageDirectory()\n");
1499 
1500  if (Ke386Pae)
1501  {
1502  PULONGLONG CurrentPageDirectory = (PULONGLONG)PAE_PAGEDIRECTORY_MAP;
1503  for (i = PAE_ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i < 4 * 512; i++)
1504  {
1507  0LL == MmGlobalKernelPageDirectoryForPAE[i] && 0LL != CurrentPageDirectory[i])
1508  {
1509  (void)ExfpInterlockedExchange64UL(&MmGlobalKernelPageDirectoryForPAE[i], &CurrentPageDirectory[i]);
1510  if (Ke386GlobalPagesEnabled)
1511  {
1513  CurrentPageDirectory[i] |= PA_GLOBAL;
1514  }
1515  }
1516  }
1517  }
1518  else
1519  {
1520  PULONG CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP;
1521  for (i = ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i < 1024; i++)
1522  {
1523  if (i != ADDR_TO_PDE_OFFSET(PTE_BASE) &&
1525  0 == MmGlobalKernelPageDirectory[i] && 0 != CurrentPageDirectory[i])
1526  {
1527  MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i];
1528  if (Ke386GlobalPagesEnabled)
1529  {
1531  CurrentPageDirectory[i] |= PA_GLOBAL;
1532  }
1533  }
1534  }
1535  }
1536 }
1537 
1538 /* EOF */
#define PAGE_WRITETHROUGH
Definition: mm.h:98
NTSTATUS NTAPI MmCreateVirtualMapping(PEPROCESS Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
Definition: pagepae.c:1352
#define PAGE_NOCACHE
Definition: nt_native.h:1311
#define PAE_ADDR_TO_PTE(v)
Definition: pagepae.c:165
NTSTATUS NTAPI MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry)
Definition: pagepae.c:1058
#define IN
Definition: typedefs.h:39
#define PAGE_MASK(x)
Definition: pagepae.c:51
#define LL
Definition: tui.h:84
BOOLEAN NTAPI MmIsPagePresent(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:1026
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define PA_CD
Definition: pagepae.c:32
#define PAGE_IS_EXECUTABLE
Definition: mm.h:148
#define DbgPrint
Definition: hal.h:12
struct _Entry Entry
Definition: kefuncs.h:627
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:40
VOID NTAPI MmSetDirtyPage(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:965
_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 MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:1040
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI MmIsPageInUse(PFN_NUMBER Page)
Definition: freelist.c:558
#define PAGEDIRECTORY_MAP
Definition: pagepae.c:36
_In_ BOOLEAN Create
Definition: pstypes.h:527
#define PAGE_GUARD
Definition: nt_native.h:1310
#define ADDR_TO_PTE_OFFSET(v)
Definition: pagepae.c:158
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:73
#define ADDR_TO_PTE(v)
Definition: pagepae.c:154
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(PEPROCESS Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
Definition: pagepae.c:1146
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
VOID NTAPI MmSetCleanPage(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:900
#define PTE_TO_PFN(X)
Definition: pagepae.c:45
VOID NTAPI MmFreePageTable(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:258
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:280
VOID NTAPI MmInitGlobalKernelPageDirectory(VOID)
Definition: pagepae.c:1494
static ULONG ProtectToPTE(ULONG flProtect)
Definition: pagepae.c:105
static ULONG MmGlobalKernelPageDirectory[1024]
Definition: pagepae.c:42
#define PA_PRESENT
Definition: pagepae.c:27
#define PA_USER
Definition: pagepae.c:29
#define PA_ACCESSED
Definition: pagepae.c:33
#define PA_DIRTY
Definition: pagepae.c:30
#define HYPERSPACE
Definition: pagepae.c:39
#define InterlockedCompareExchangeUL(Destination, Exchange, Comperand)
Definition: ex.h:1534
#define PAE_PAGEDIRECTORY_MAP
Definition: pagepae.c:37
ULONG NTAPI MmGetPageProtect(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:1378
uint32_t ULONG_PTR
Definition: typedefs.h:65
BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
Definition: pagepae.c:844
#define ExfInterlockedCompareExchange64UL(Destination, Exchange, Comperand)
Definition: ex.h:1540
#define ADDR_TO_PDE(v)
Definition: pagepae.c:152
VOID NTAPI MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
Definition: pagepae.c:613
ULONG * PPFN_NUMBER
Definition: ke.h:9
#define PAE_ADDR_TO_PDE_PAGE_OFFSET(v)
Definition: pagepae.c:170
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
#define FALSE
Definition: types.h:117
#define PAGE_IS_WRITABLE
Definition: mm.h:142
VOID NTAPI MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: pagepae.c:747
#define PFN_TO_PTE(X)
Definition: pagepae.c:46
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define PAGE_NOACCESS
Definition: nt_native.h:1302
unsigned char BOOLEAN
static WCHAR Address[46]
Definition: ping.c:68
static ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:568
PFN_NUMBER Page
Definition: section.c:4923
void * PVOID
Definition: retypes.h:9
#define InterlockedExchangeUL(Target, Value)
Definition: ex.h:1528
BOOLEAN MmUnmapPageTable(PULONG Pt)
Definition: pagepae.c:530
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 GLint GLint j
Definition: glfuncs.h:250
Status
Definition: gdiplustypes.h:24
int Count
Definition: noreturn.cpp:7
ULONG CurrentProcess
Definition: shell.c:125
#define ASSERT(a)
Definition: mode.c:44
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN NTAPI MmCreateProcessAddressSpace(IN ULONG MinWs, IN PEPROCESS Process, IN PLARGE_INTEGER DirectoryTableBase)
Definition: pagepae.c:178
uint64_t ULONGLONG
Definition: typedefs.h:67
#define PAE_PAGE_MASK(x)
Definition: pagepae.c:52
PFN_NUMBER NTAPI MmGetPfnForProcess(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:585
#define PAE_ADDR_TO_PTE_OFFSET(v)
Definition: pagepae.c:174
#define PAGE_SYSTEM
Definition: mm.h:99
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
static PULONGLONG MmGetPageTableForProcessForPAE(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: pagepae.c:321
ULONG LowPart
Definition: typedefs.h:106
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define PAE_ADDR_TO_PAGE_TABLE(v)
Definition: pagepae.c:161
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PTE_BASE
Definition: mmx86.c:14
static PULONG MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: pagepae.c:435
#define InterlockedExchange
Definition: armddk.h:54
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
BOOLEAN Ke386NoExecute
Definition: cpu.c:34
VOID MiFlushTlb(PULONG Pt, PVOID Address)
Definition: pagepae.c:81
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
#define PAE_PFN_TO_PTE(X)
Definition: pagepae.c:49
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
ULONG_PTR SWAPENTRY
Definition: mm.h:53
#define PAE_ADDR_TO_PDTE_OFFSET(v)
Definition: pagepae.c:168
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
BOOLEAN NTAPI MmIsDirtyPage(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:886
BOOLEAN Ke386Pae
Definition: cpu.c:33
#define DPRINT1
Definition: precomp.h:8
#define PA_READWRITE
Definition: pagepae.c:28
#define PAE_ADDR_TO_PDE(v)
Definition: pagepae.c:163
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
__INTRIN_INLINE void __invlpg(void *Address)
Definition: intrin_x86.h:1969
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
ULONG_PTR NTAPI MiFlushTlbIpiRoutine(ULONG_PTR Address)
Definition: pagepae.c:63
unsigned int ULONG
Definition: retypes.h:1
#define ADDR_TO_PDE_OFFSET(v)
Definition: pagepae.c:156
static ULONGLONG MmGetPageEntryForProcessForPAE(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:553
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAE_ADDR_TO_PDE_OFFSET(v)
Definition: pagepae.c:172
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define PAE_PTE_TO_PFN(X)
Definition: pagepae.c:48
signed int * PLONG
Definition: retypes.h:5
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
VOID NTAPI MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
Definition: pagepae.c:1424
#define MmSystemRangeStart
Definition: mm.h:32
unsigned short * PUSHORT
Definition: retypes.h:2
base of all file and directory entries
Definition: entries.h:82
ULONG_PTR NTAPI KeIpiGenericCall(IN PKIPI_BROADCAST_WORKER Function, IN ULONG_PTR Argument)
Definition: ipi.c:196
#define ADDR_TO_PAGE_TABLE(v)
Definition: pagepae.c:150
#define PAGE_IS_READABLE
Definition: mm.h:134
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:312
LONGLONG QuadPart
Definition: typedefs.h:114
#define PA_GLOBAL
Definition: pagepae.c:34
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define PA_WT
Definition: pagepae.c:31
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
static ULONGLONG MmGlobalKernelPageDirectoryForPAE[2048]
Definition: pagepae.c:43