ReactOS 0.4.15-dev-7660-g0086d05
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 management 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
54extern BOOLEAN Ke386Pae;
56
57/* FUNCTIONS ***************************************************************/
58
60
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
80VOID
82{
83#ifdef CONFIG_SMP
84 if (Pt)
85 {
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
104static ULONG
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
177NTAPI
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
256VOID
257NTAPI
259{
260 PEPROCESS CurrentProcess = PsGetCurrentProcess();
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 {
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 {
317 }
318}
319
320static 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
434static 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 {
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;
578 return Pte;
579 }
580 return 0;
581}
582
584NTAPI
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
611VOID
612NTAPI
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",
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
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
745VOID
746NTAPI
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
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
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
845{
846 if (Ke386Pae)
847 {
848 PULONGLONG Pt;
849 PULONGLONG Pde;
850 Pde = PAE_ADDR_TO_PDE(PAddress);
851 if (*Pde == 0LL)
852 {
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
885NTAPI
887{
888 if (Ke386Pae)
889 {
891 }
892 else
893 {
895 }
896}
897
898VOID
899NTAPI
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 {
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 {
959 }
960 }
961}
962
963VOID
964NTAPI
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 {
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
1024BOOLEAN
1025NTAPI
1027{
1028 if (Ke386Pae)
1029 {
1031 }
1032 else
1033 {
1035 }
1036}
1037
1038BOOLEAN
1039NTAPI
1041{
1042 if (Ke386Pae)
1043 {
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
1057NTAPI
1059 PVOID Address,
1060 SWAPENTRY SwapEntry)
1061{
1063 {
1064 DPRINT1("No process\n");
1065 ASSERT(FALSE);
1066 }
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 {
1098 }
1099 else
1100 {
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
1145NTAPI
1147 PVOID Address,
1148 ULONG flProtect,
1149 PPFN_NUMBER Pages,
1150 ULONG PageCount)
1151{
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 {
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;
1198 {
1199 Attributes &= ~PA_USER;
1200 if (Ke386GlobalPagesEnabled)
1201 {
1203 }
1204 }
1205 else
1206 {
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 {
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 }
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 {
1271 (Pt >= (PULONGLONG)PTE_BASE && Pt < (PULONGLONG)PTE_BASE + 4*512*512))
1272 {
1274 }
1275 }
1276 }
1277 if (Addr > Address)
1278 {
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);
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 }
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 {
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
1351NTAPI
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
1376ULONG
1377NTAPI
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 {
1408 }
1409 if (Entry & PA_WT)
1410 {
1412 }
1413 if (!(Entry & PA_USER))
1414 {
1416 }
1417
1418 }
1419 return(Protect);
1420}
1421
1422VOID
1423NTAPI
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;
1439 {
1440 Attributes &= ~PA_USER;
1441 if (Ke386GlobalPagesEnabled)
1442 {
1444 }
1445 }
1446 else
1447 {
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
1476 }
1477 else
1478 {
1479 PULONG Pt;
1480
1482 if (Pt == NULL)
1483 {
1484 ASSERT(FALSE);
1485 }
1487 MiFlushTlb(Pt, Address);
1488 }
1489}
1490
1491CODE_SEG("INIT")
1492VOID
1493NTAPI
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 */
unsigned char BOOLEAN
#define InterlockedExchange
Definition: armddk.h:54
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
@ Create
Definition: registry.c:563
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define InterlockedCompareExchangeUL(Destination, Exchange, Comperand)
Definition: ex.h:1536
#define ExfInterlockedCompareExchange64UL(Destination, Exchange, Comperand)
Definition: ex.h:1550
#define InterlockedExchangeUL(Target, Value)
Definition: ex.h:1530
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
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
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
#define DbgPrint
Definition: hal.h:12
__INTRIN_INLINE void __invlpg(void *Address)
Definition: intrin_x86.h:1968
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define PTE_BASE
Definition: mmx86.c:14
#define ASSERT(a)
Definition: mode.c:44
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
int Count
Definition: noreturn.cpp:7
#define PAGE_NOCACHE
Definition: nt_native.h:1311
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_NOACCESS
Definition: nt_native.h:1302
#define PAGE_GUARD
Definition: nt_native.h:1310
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
#define MmSystemRangeStart
Definition: mm.h:32
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:526
#define MmSetDirtyPage(__P, __A)
Definition: mm.h:1252
_In_ PVOID _Out_opt_ BOOLEAN * WasDirty
Definition: mm.h:1304
#define MmSetCleanPage(__P, __A)
Definition: mm.h:1251
#define PAGE_WRITETHROUGH
Definition: mm.h:109
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
ULONG_PTR SWAPENTRY
Definition: mm.h:57
BOOLEAN NTAPI MmIsPageInUse(PFN_NUMBER Page)
Definition: freelist.c:558
#define PAGE_IS_WRITABLE
Definition: mm.h:153
#define PAGE_SYSTEM
Definition: mm.h:110
#define PAGE_IS_EXECUTABLE
Definition: mm.h:159
NTSTATUS NTAPI MmRequestPageMemoryConsumer(ULONG Consumer, BOOLEAN MyWait, PPFN_NUMBER AllocatedPage)
Definition: balance.c:313
NTSTATUS NTAPI MmReleasePageMemoryConsumer(ULONG Consumer, PFN_NUMBER Page)
Definition: balance.c:72
#define PAGE_IS_READABLE
Definition: mm.h:145
ULONG_PTR NTAPI KeIpiGenericCall(_In_ PKIPI_BROADCAST_WORKER Function, _In_ ULONG_PTR Argument)
Definition: ipi.c:44
#define ADDR_TO_PAGE_TABLE(v)
Definition: pagepae.c:150
static ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:568
#define PTE_TO_PFN(X)
Definition: pagepae.c:45
#define PA_ACCESSED
Definition: pagepae.c:33
#define ADDR_TO_PDE(v)
Definition: pagepae.c:152
static PULONG MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: pagepae.c:435
BOOLEAN MmUnmapPageTable(PULONG Pt)
Definition: pagepae.c:530
#define PAE_PFN_TO_PTE(X)
Definition: pagepae.c:49
VOID NTAPI MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
Definition: pagepae.c:1424
#define PA_PRESENT
Definition: pagepae.c:27
static ULONGLONG MmGlobalKernelPageDirectoryForPAE[2048]
Definition: pagepae.c:43
#define ADDR_TO_PDE_OFFSET(v)
Definition: pagepae.c:156
VOID NTAPI MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
Definition: pagepae.c:613
static ULONG ProtectToPTE(ULONG flProtect)
Definition: pagepae.c:105
VOID NTAPI MmFreePageTable(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:258
#define ADDR_TO_PTE(v)
Definition: pagepae.c:154
#define PAE_ADDR_TO_PDE_PAGE_OFFSET(v)
Definition: pagepae.c:170
#define PAE_ADDR_TO_PDE(v)
Definition: pagepae.c:163
static PULONGLONG MmGetPageTableForProcessForPAE(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: pagepae.c:321
#define PAGE_MASK(x)
Definition: pagepae.c:51
#define HYPERSPACE
Definition: pagepae.c:39
ULONG_PTR NTAPI MiFlushTlbIpiRoutine(ULONG_PTR Address)
Definition: pagepae.c:63
#define PAE_ADDR_TO_PTE_OFFSET(v)
Definition: pagepae.c:174
VOID NTAPI MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: pagepae.c:747
ULONG NTAPI MmGetPageProtect(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:1378
BOOLEAN Ke386Pae
Definition: cpu.c:35
static ULONGLONG MmGetPageEntryForProcessForPAE(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:553
static ULONG MmGlobalKernelPageDirectory[1024]
Definition: pagepae.c:42
VOID MiFlushTlb(PULONG Pt, PVOID Address)
Definition: pagepae.c:81
#define ADDR_TO_PTE_OFFSET(v)
Definition: pagepae.c:158
#define PAE_ADDR_TO_PDE_OFFSET(v)
Definition: pagepae.c:172
#define PAGEDIRECTORY_MAP
Definition: pagepae.c:36
#define PA_WT
Definition: pagepae.c:31
NTSTATUS NTAPI MmCreateVirtualMapping(PEPROCESS Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
Definition: pagepae.c:1352
BOOLEAN NTAPI MmIsDirtyPage(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:886
#define PA_DIRTY
Definition: pagepae.c:30
#define PAE_PAGE_MASK(x)
Definition: pagepae.c:52
#define PA_CD
Definition: pagepae.c:32
NTSTATUS NTAPI MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry)
Definition: pagepae.c:1058
BOOLEAN NTAPI MmCreateProcessAddressSpace(IN ULONG MinWs, IN PEPROCESS Process, IN PLARGE_INTEGER DirectoryTableBase)
Definition: pagepae.c:178
BOOLEAN NTAPI MmIsPagePresent(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:1026
#define PA_USER
Definition: pagepae.c:29
BOOLEAN Ke386NoExecute
Definition: cpu.c:36
#define PA_READWRITE
Definition: pagepae.c:28
BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
Definition: pagepae.c:844
BOOLEAN NTAPI MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:1040
#define PAE_ADDR_TO_PDTE_OFFSET(v)
Definition: pagepae.c:168
#define PAE_ADDR_TO_PAGE_TABLE(v)
Definition: pagepae.c:161
PFN_NUMBER NTAPI MmGetPfnForProcess(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:585
#define PFN_TO_PTE(X)
Definition: pagepae.c:46
VOID NTAPI MmInitGlobalKernelPageDirectory(VOID)
Definition: pagepae.c:1494
#define PAE_PAGEDIRECTORY_MAP
Definition: pagepae.c:37
#define PA_GLOBAL
Definition: pagepae.c:34
#define PAE_ADDR_TO_PTE(v)
Definition: pagepae.c:165
#define PAE_PTE_TO_PFN(X)
Definition: pagepae.c:48
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(PEPROCESS Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
Definition: pagepae.c:1146
static WCHAR Address[46]
Definition: ping.c:68
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
ULONG * PPFN_NUMBER
Definition: ke.h:9
ULONG PFN_NUMBER
Definition: ke.h:9
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
base of all file and directory entries
Definition: entries.h:83
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:43
#define LL
Definition: tui.h:150
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint16_t * PUSHORT
Definition: typedefs.h:56
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_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:221