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