ReactOS 0.4.15-dev-6054-gbddd8b0
page.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/mm/i386/page.c
5 * PURPOSE: Low level memory managment manipulation
6 *
7 * PROGRAMMERS: David Welch (welch@cwcom.net)
8 */
9
10/* INCLUDES ***************************************************************/
11
12#include <ntoskrnl.h>
13#define NDEBUG
14#include <debug.h>
15
16#include <mm/ARM3/miarm.h>
17
18#ifndef _MI_PAGING_LEVELS
19#error "Dude, fix your stuff before using this file"
20#endif
21
22/* GLOBALS *****************************************************************/
23const
26{
27 //
28 // These are the base MM_ protection flags
29 //
30 0,
31 PTE_READONLY | PTE_ENABLE_CACHE,
32 PTE_EXECUTE | PTE_ENABLE_CACHE,
33 PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
34 PTE_READWRITE | PTE_ENABLE_CACHE,
35 PTE_WRITECOPY | PTE_ENABLE_CACHE,
36 PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
37 PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
38 //
39 // These OR in the MM_NOCACHE flag
40 //
41 0,
42 PTE_READONLY | PTE_DISABLE_CACHE,
43 PTE_EXECUTE | PTE_DISABLE_CACHE,
44 PTE_EXECUTE_READ | PTE_DISABLE_CACHE,
45 PTE_READWRITE | PTE_DISABLE_CACHE,
46 PTE_WRITECOPY | PTE_DISABLE_CACHE,
47 PTE_EXECUTE_READWRITE | PTE_DISABLE_CACHE,
48 PTE_EXECUTE_WRITECOPY | PTE_DISABLE_CACHE,
49 //
50 // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM
51 //
52 0,
53 PTE_READONLY | PTE_ENABLE_CACHE,
54 PTE_EXECUTE | PTE_ENABLE_CACHE,
55 PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
56 PTE_READWRITE | PTE_ENABLE_CACHE,
57 PTE_WRITECOPY | PTE_ENABLE_CACHE,
58 PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
59 PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
60 //
61 // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining?
62 //
63 0,
64 PTE_READONLY | PTE_WRITECOMBINED_CACHE,
65 PTE_EXECUTE | PTE_WRITECOMBINED_CACHE,
66 PTE_EXECUTE_READ | PTE_WRITECOMBINED_CACHE,
67 PTE_READWRITE | PTE_WRITECOMBINED_CACHE,
68 PTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
69 PTE_EXECUTE_READWRITE | PTE_WRITECOMBINED_CACHE,
70 PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
71};
72
73const
75{
108};
109
110/* FUNCTIONS ***************************************************************/
111
113NTAPI
116
117static
120{
121#if _MI_PAGING_LEVELS == 2
123
124 /* Some sanity check while we're here */
125 ASSERT(Ret == (MiAddressToPde(Address)->u.Hard.Valid != 0));
126
127 return Ret;
128#else
129 PMMPDE PointerPde;
130 PMMPPE PointerPpe;
131#if _MI_PAGING_LEVELS == 4
132 PMMPXE PointerPxe;
133#endif
134 PMMPFN Pfn;
135
136 /* Make sure we're locked */
137 ASSERT((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) || (PsGetCurrentThread()->OwnsProcessWorkingSetShared));
138
139 /* Must not hold the PFN lock! */
141
142 /* Check if PXE or PPE have references first. */
143#if _MI_PAGING_LEVELS == 4
144 PointerPxe = MiAddressToPxe(Address);
145 if ((PointerPxe->u.Hard.Valid == 1) || (PointerPxe->u.Soft.Transition == 1))
146 {
147 Pfn = MiGetPfnEntry(PFN_FROM_PXE(PointerPxe));
149 return FALSE;
150 }
151 else if (PointerPxe->u.Soft.UsedPageTableEntries == 0)
152 {
153 return FALSE;
154 }
155
156 if (PointerPxe->u.Hard.Valid == 0)
157 {
159 }
160#endif
161
162 PointerPpe = MiAddressToPpe(Address);
163 if ((PointerPpe->u.Hard.Valid == 1) || (PointerPpe->u.Soft.Transition == 1))
164 {
165 Pfn = MiGetPfnEntry(PFN_FROM_PPE(PointerPpe));
167 return FALSE;
168 }
169 else if (PointerPpe->u.Soft.UsedPageTableEntries == 0)
170 {
171 return FALSE;
172 }
173
174 if (PointerPpe->u.Hard.Valid == 0)
175 {
177 }
178
179 PointerPde = MiAddressToPde(Address);
180 if ((PointerPde->u.Hard.Valid == 0) && (PointerPde->u.Soft.Transition == 0))
181 {
182 return PointerPde->u.Soft.UsedPageTableEntries != 0;
183 }
184
185 /* This lies on the PFN */
186 Pfn = MiGetPfnEntry(PFN_FROM_PDE(PointerPde));
187 return Pfn->OriginalPte.u.Soft.UsedPageTableEntries != 0;
188#endif
189}
190
192NTAPI
195{
196 PMMPTE PointerPte;
198
199 /* Must be called for user mode only */
200 ASSERT(Process != NULL);
202
203 /* And for our process */
205
206 /* Lock for reading */
208
210 {
212 return 0;
213 }
214
215 /* Make sure we can read the PTE */
217
218 PointerPte = MiAddressToPte(Address);
219 Page = PointerPte->u.Hard.Valid ? PFN_FROM_PTE(PointerPte) : 0;
220
222 return Page;
223}
224
242{
243 PMMPTE PointerPte;
244 MMPTE OldPte;
245 BOOLEAN ValidPde;
246
247 OldPte.u.Long = 0;
248
249 DPRINT("MmDeleteVirtualMapping(%p, %p, %p, %p)\n", Process, Address, WasDirty, Page);
250
252
253 /* And we should be at low IRQL */
255
256 /* Make sure our PDE is valid, and that everything is going fine */
257 if (Process == NULL)
258 {
260 {
261 DPRINT1("NULL process given for user-mode mapping at %p\n", Address);
262 KeBugCheck(MEMORY_MANAGEMENT);
263 }
264#if (_MI_PAGING_LEVELS == 2)
265 ValidPde = MiSynchronizeSystemPde(MiAddressToPde(Address));
266#else
268#endif
269 }
270 else
271 {
273 {
274 DPRINT1("Process %p given for kernel-mode mapping at %p\n", Process, Address);
275 KeBugCheck(MEMORY_MANAGEMENT);
276 }
277
278 /* Only for current process !!! */
281
282 ValidPde = MiIsPageTablePresent(Address);
283 if (ValidPde)
284 {
286 }
287 }
288
289 /* Get the PTE if we're having anything */
290 if (ValidPde)
291 {
292 PointerPte = MiAddressToPte(Address);
293 OldPte.u.Long = InterlockedExchangePte(PointerPte, 0);
294
296
297 if (OldPte.u.Long != 0)
298 {
299 /* It must have been present, or not a swap entry */
300 ASSERT(OldPte.u.Hard.Valid || !FlagOn(OldPte.u.Long, 0x800));
301 if (WasDirty != NULL)
302 {
303 *WasDirty = !!OldPte.u.Hard.Dirty;
304 }
305 if (Page != NULL)
306 {
307 *Page = OldPte.u.Hard.PageFrameNumber;
308 }
309 }
310 }
311
312 if (Process != NULL)
313 {
314 /* Remove PDE reference, if needed */
315 if (OldPte.u.Long != 0)
316 {
318 {
319 KIRQL OldIrql = MiAcquirePfnLock();
321 MiReleasePfnLock(OldIrql);
322 }
323 }
324
326 }
327
328 return OldPte.u.Long != 0;
329}
330
331
332VOID
333NTAPI
337 SWAPENTRY* SwapEntry)
338{
339 PMMPTE PointerPte;
340 MMPTE OldPte;
341
342 /* This should not be called for kernel space anymore */
343 ASSERT(Process != NULL);
345
346 /* And we don't support deleting for other process */
348
349 /* And we should be at low IRQL */
351
352 /* We are tinkering with the PDE here. Ensure it will be there */
354
355 /* Callers must ensure there is actually something there */
356 ASSERT(MiAddressToPde(Address)->u.Long != 0);
357
359
360 PointerPte = MiAddressToPte(Address);
361 OldPte.u.Long = InterlockedExchangePte(PointerPte, 0);
362 /* This must be a swap entry ! */
363 if (!FlagOn(OldPte.u.Long, 0x800) || OldPte.u.Hard.Valid)
364 {
365 KeBugCheckEx(MEMORY_MANAGEMENT, OldPte.u.Long, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
366 }
367
368 /* This used to be a non-zero PTE, now we can let the PDE go. */
370 {
371 /* We can let it go */
372 KIRQL OldIrql = MiAcquirePfnLock();
373 MiDeletePde(MiPteToPde(PointerPte), Process);
374 MiReleasePfnLock(OldIrql);
375 }
376
378
379 *SwapEntry = OldPte.u.Long >> 1;
380}
381
383NTAPI
385{
386 BOOLEAN Ret;
387
389 {
390 ASSERT(Process == NULL);
391#if _MI_PAGING_LEVELS == 2
392 if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
393#else
395#endif
396 {
397 /* It can't be present if there is no PDE */
398 return FALSE;
399 }
400
401 return MiAddressToPte(Address)->u.Hard.Valid;
402 }
403
404 ASSERT(Process != NULL);
406
408
410 {
411 /* It can't be present if there is no PDE */
413 return FALSE;
414 }
415
417
418 Ret = MiAddressToPte(Address)->u.Hard.Valid;
419
421
422 return Ret;
423}
424
426NTAPI
428{
429 BOOLEAN Ret;
430 PMMPTE PointerPte;
431
433 {
434 ASSERT(Process == NULL);
435#if _MI_PAGING_LEVELS == 2
436 if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
437#else
439#endif
440 {
441 /* It's not disabled if it's not present */
442 return FALSE;
443 }
444 }
445 else
446 {
447 ASSERT(Process != NULL);
449
451
453 {
454 /* It can't be disabled if there is no PDE */
456 return FALSE;
457 }
458
460 }
461
462 PointerPte = MiAddressToPte(Address);
463 Ret = !PointerPte->u.Hard.Valid
464 && !FlagOn(PointerPte->u.Long, 0x800)
465 && (PointerPte->u.Hard.PageFrameNumber != 0);
466
469
470 return Ret;
471}
472
474NTAPI
476{
477 BOOLEAN Ret;
478 PMMPTE PointerPte;
479
480 /* We never set swap entries for kernel addresses */
482 {
483 ASSERT(Process == NULL);
484 return FALSE;
485 }
486
487 ASSERT(Process != NULL);
489
491
493 {
494 /* There can't be a swap entry if there is no PDE */
496 return FALSE;
497 }
498
500
501 PointerPte = MiAddressToPte(Address);
502 Ret = !PointerPte->u.Hard.Valid && FlagOn(PointerPte->u.Long, 0x800);
503
505
506 return Ret;
507}
508
509VOID
510NTAPI
512{
513 PMMPTE PointerPte;
514
515 /* We never set swap entries for kernel addresses */
517 {
518 ASSERT(Process == NULL);
519 *SwapEntry = 0;
520 return;
521 }
522
523 ASSERT(Process != NULL);
525
527
529 {
530 /* There can't be a swap entry if there is no PDE */
532 *SwapEntry = 0;
533 return;
534 }
535
537
538 PointerPte = MiAddressToPte(Address);
539 if (!PointerPte->u.Hard.Valid && FlagOn(PointerPte->u.Long, 0x800))
540 *SwapEntry = PointerPte->u.Long >> 1;
541 else
542 *SwapEntry = 0;
543
545}
546
548NTAPI
551 SWAPENTRY SwapEntry)
552{
553 PMMPTE PointerPte;
554 ULONG_PTR Pte;
555
556 /* This should not be called for kernel space anymore */
557 ASSERT(Process != NULL);
559
560 /* And we don't support creating for other process */
562
563 if (SwapEntry & (1 << 31))
564 {
565 KeBugCheck(MEMORY_MANAGEMENT);
566 }
567
568 /* We are tinkering with the PDE here. Ensure it will be there */
571
573
574 PointerPte = MiAddressToPte(Address);
575 Pte = InterlockedExchangePte(PointerPte, SwapEntry << 1);
576 if (Pte != 0)
577 {
578 KeBugCheckEx(MEMORY_MANAGEMENT, SwapEntry, (ULONG_PTR)Process, (ULONG_PTR)Address, 0);
579 }
580
581 /* This used to be a 0 PTE, now we need a valid PDE to keep it around */
584
585 return STATUS_SUCCESS;
586}
587
588
590NTAPI
593 ULONG flProtect,
595{
596 ULONG ProtectionMask;
597 PMMPTE PointerPte;
599 ULONG_PTR Pte;
600
601 DPRINT("MmCreateVirtualMappingUnsafe(%p, %p, %lu, %x)\n",
602 Process, Address, flProtect, Page);
603
605
606 ProtectionMask = MiMakeProtectionMask(flProtect);
607 /* Caller must have checked ! */
608 ASSERT(ProtectionMask != MM_INVALID_PROTECTION);
609 ASSERT(ProtectionMask != MM_NOACCESS);
610 ASSERT(ProtectionMask != MM_ZERO_ACCESS);
611
612 /* Make sure our PDE is valid, and that everything is going fine */
613 if (Process == NULL)
614 {
615 /* We don't support this in legacy Mm for kernel mappings */
616 ASSERT(ProtectionMask != MM_WRITECOPY);
617 ASSERT(ProtectionMask != MM_EXECUTE_WRITECOPY);
618
620 {
621 DPRINT1("NULL process given for user-mode mapping at %p\n", Address);
622 KeBugCheck(MEMORY_MANAGEMENT);
623 }
624#if _MI_PAGING_LEVELS == 2
625 if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
627#endif
628 }
629 else
630 {
632 {
633 DPRINT1("Process %p given for kernel-mode mapping at %p -- 1 page starting at %Ix\n",
635 KeBugCheck(MEMORY_MANAGEMENT);
636 }
637
638 /* Only for current process !!! */
641
643 }
644
645 PointerPte = MiAddressToPte(Address);
646
647 MI_MAKE_HARDWARE_PTE(&TempPte, PointerPte, ProtectionMask, Page);
648
649 Pte = InterlockedExchangePte(PointerPte, TempPte.u.Long);
650 /* There should not have been anything valid here */
651 if (Pte != 0)
652 {
653 DPRINT1("Bad PTE %lx at %p for %p\n", Pte, PointerPte, Address);
654 KeBugCheck(MEMORY_MANAGEMENT);
655 }
656
657 /* We don't need to flush the TLB here because it only caches valid translations
658 * and we're moving this PTE from invalid to valid so it can't be cached right now */
659
661 {
662 /* Add PDE reference */
665 }
666
667 return(STATUS_SUCCESS);
668}
669
671NTAPI
674 ULONG flProtect,
676{
678 if (!MmIsPageInUse(Page))
679 {
680 DPRINT1("Page %lx is not in use\n", Page);
681 KeBugCheck(MEMORY_MANAGEMENT);
682 }
683
685}
686
687ULONG
688NTAPI
690{
691 PMMPTE PointerPte;
693
695 {
696 ASSERT(Process == NULL);
697
698#if _MI_PAGING_LEVELS == 2
699 if (!MiSynchronizeSystemPde(MiAddressToPde(Address)))
700#else
702#endif
703 {
704 return PAGE_NOACCESS;
705 }
706 }
707 else
708 {
710 ASSERT(Process != NULL);
711
713
715
717 {
718 /* It can't be present if there is no PDE */
720 return PAGE_NOACCESS;
721 }
722
724 }
725
726 PointerPte = MiAddressToPte(Address);
727
728 if (!PointerPte->u.Flush.Valid)
729 {
731 }
732 else
733 {
734 if (PointerPte->u.Flush.CopyOnWrite)
736 else if (PointerPte->u.Flush.Write)
738 else
740#if _MI_PAGING_LEVELS >= 3
741 /* PAE & AMD64 long mode support NoExecute bit */
742 if (!PointerPte->u.Flush.NoExecute)
743 Protect <<= 4;
744#endif
745 if (PointerPte->u.Flush.CacheDisable)
747 if (PointerPte->u.Flush.WriteThrough)
749 }
750
753
754 return(Protect);
755}
756
757VOID
758NTAPI
760{
761 ULONG ProtectionMask;
762 PMMPTE PointerPte;
763 MMPTE TempPte, OldPte;
764
765 DPRINT("MmSetPageProtect(Process %p Address %p flProtect %x)\n",
766 Process, Address, flProtect);
767
768 ASSERT(Process != NULL);
770
772
773 ProtectionMask = MiMakeProtectionMask(flProtect);
774 /* Caller must have checked ! */
775 ASSERT(ProtectionMask != MM_INVALID_PROTECTION);
776
778
780
781 PointerPte = MiAddressToPte(Address);
782
783 /* Sanity check */
784 ASSERT(PointerPte->u.Hard.Owner == 1);
785
786 TempPte.u.Long = 0;
787 TempPte.u.Hard.PageFrameNumber = PointerPte->u.Hard.PageFrameNumber;
788 TempPte.u.Long |= MmProtectToPteMask[ProtectionMask];
789 TempPte.u.Hard.Owner = 1;
790
791 /* Only set valid bit if we have to */
792 if ((ProtectionMask != MM_NOACCESS) && !FlagOn(ProtectionMask, MM_GUARDPAGE))
793 TempPte.u.Hard.Valid = 1;
794
795 /* Keep dirty & accessed bits */
796 TempPte.u.Hard.Accessed = PointerPte->u.Hard.Accessed;
797 TempPte.u.Hard.Dirty = PointerPte->u.Hard.Dirty;
798
799 OldPte.u.Long = InterlockedExchangePte(PointerPte, TempPte.u.Long);
800
801 // We should be able to bring a page back from PAGE_NOACCESS
802 if (!OldPte.u.Hard.Valid && (FlagOn(OldPte.u.Long, 0x800) || (OldPte.u.Hard.PageFrameNumber == 0)))
803 {
804 DPRINT1("Invalid Pte %lx\n", OldPte.u.Long);
805 KeBugCheck(MEMORY_MANAGEMENT);
806 }
807
808 if (OldPte.u.Long != TempPte.u.Long)
810
812}
813
814VOID
815NTAPI
817{
818 PMMPTE PointerPte;
819
820 DPRINT("MmSetDirtyBit(Process %p Address %p Bit %x)\n",
821 Process, Address, Bit);
822
823 ASSERT(Process != NULL);
825
827
829
831
832 PointerPte = MiAddressToPte(Address);
833 // We shouldnl't set dirty bit on non-mapped adresses
834 if (!PointerPte->u.Hard.Valid && (FlagOn(PointerPte->u.Long, 0x800) || (PointerPte->u.Hard.PageFrameNumber == 0)))
835 {
836 DPRINT1("Invalid Pte %lx\n", PointerPte->u.Long);
837 KeBugCheck(MEMORY_MANAGEMENT);
838 }
839
840 PointerPte->u.Hard.Dirty = !!Bit;
841
842 if (!Bit)
844
846}
847
848CODE_SEG("INIT")
849VOID
850NTAPI
852{
853 /* Nothing to do here */
854}
855
856#ifdef _M_IX86
859{
860 PMMPDE PointerPde = MiAddressToPde(Address);
861 PMMPTE PointerPte = MiAddressToPte(Address);
862
863 if (PointerPde->u.Hard.Valid == 0)
864 {
865 if (!MiSynchronizeSystemPde(PointerPde))
866 return FALSE;
867 return PointerPte->u.Hard.Valid != 0;
868 }
869 return FALSE;
870}
871#endif
872
873/* EOF */
unsigned char BOOLEAN
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define PAGE_READONLY
Definition: compat.h:138
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define Add2Ptr(PTR, INC)
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
#define MM_EXECUTE_WRITECOPY
Definition: miarm.h:50
FORCEINLINE VOID MiLockProcessWorkingSetShared(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1146
FORCEINLINE VOID MiDeletePde(_In_ PMMPDE PointerPde, _In_ PEPROCESS CurrentProcess)
Definition: miarm.h:2541
#define MM_GUARDPAGE
Definition: miarm.h:57
FORCEINLINE VOID MiUnlockProcessWorkingSetShared(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1215
FORCEINLINE USHORT MiDecrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2507
#define MM_INVALID_PROTECTION
Definition: miarm.h:67
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1239
VOID NTAPI MiMakePdeExistAndMakeValid(IN PMMPDE PointerPde, IN PEPROCESS TargetProcess, IN KIRQL OldIrql)
Definition: virtual.c:2475
ULONG NTAPI MiMakeSystemAddressValid(IN PVOID PageTableVirtualAddress, IN PEPROCESS CurrentProcess)
Definition: virtual.c:183
#define MM_NOACCESS
Definition: miarm.h:65
#define MM_ZERO_ACCESS
Definition: miarm.h:43
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:807
ULONG NTAPI MiMakeProtectionMask(IN ULONG Protect)
Definition: section.c:140
FORCEINLINE USHORT MiIncrementPageTableReferences(IN PVOID Address)
Definition: miarm.h:2481
#define MM_WRITECOPY
Definition: miarm.h:48
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1169
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define ASSERT(a)
Definition: mode.c:44
#define _Out_opt_
Definition: ms_sal.h:346
#define _Success_(expr)
Definition: ms_sal.h:259
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2427
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#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_EXECUTE
Definition: nt_native.h:1306
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
#define PAGE_NOACCESS
Definition: nt_native.h:1302
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
#define PAGE_GUARD
Definition: nt_native.h:1310
PMMWSL MmWorkingSetList
Definition: wslist.cpp:19
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:264
#define PFN_FROM_PXE(v)
Definition: mm.h:95
FORCEINLINE BOOLEAN MiIsPdeForAddressValid(PVOID Address)
Definition: mm.h:366
#define MiGetPdeOffset(x)
Definition: mm.h:195
#define PFN_FROM_PPE(v)
Definition: mm.h:94
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:161
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:171
#define MmSystemRangeStart
Definition: mm.h:32
#define PFN_FROM_PDE(v)
Definition: mm.h:93
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define MiPteToPde(_Pte)
Definition: mm.h:121
#define MiPteToAddress(_Pte)
Definition: mm.h:116
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define MM_NOIRQL
Definition: mm.h:70
#define PAGE_WRITETHROUGH
Definition: mm.h:109
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1298
ULONG_PTR SWAPENTRY
Definition: mm.h:57
BOOLEAN NTAPI MmIsPageInUse(PFN_NUMBER Page)
Definition: freelist.c:558
_In_ PVOID _Out_opt_ BOOLEAN * WasDirty
Definition: mm.h:1296
#define InterlockedExchangePte(PointerPte, Value)
Definition: mm.h:190
VOID NTAPI MmSetPageProtect(IN PEPROCESS Process, IN PVOID Address, IN ULONG Protection)
Definition: page.c:267
NTSTATUS NTAPI MmCreatePageFileMapping(IN PEPROCESS Process, IN PVOID Address, IN SWAPENTRY SwapEntry)
Definition: page.c:196
BOOLEAN NTAPI MmIsDisabledPage(PEPROCESS Process, PVOID Address)
Definition: page.c:309
ULONG NTAPI MmGetPageProtect(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:258
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:299
BOOLEAN NTAPI MmIsPagePresent(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:240
NTSTATUS NTAPI MmCreateVirtualMapping(IN PEPROCESS Process, IN PVOID Address, IN ULONG Protection, IN PPFN_NUMBER Pages, IN ULONG PageCount)
Definition: page.c:158
VOID NTAPI MmDeletePageFileMapping(IN PEPROCESS Process, IN PVOID Address, IN SWAPENTRY *SwapEntry)
Definition: page.c:187
const ULONG MmProtectToPteMask[32]
Definition: page.c:22
PFN_NUMBER NTAPI MmGetPfnForProcess(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:206
const ULONG MmProtectToValue[32]
Definition: page.c:71
BOOLEAN NTAPI MmIsPageSwapEntry(IN PEPROCESS Process, IN PVOID Address)
Definition: page.c:249
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(IN PEPROCESS Process, IN PVOID Address, IN ULONG Protection, IN PPFN_NUMBER Pages, IN ULONG PageCount)
Definition: page.c:146
VOID NTAPI MmDeleteVirtualMapping(IN PEPROCESS Process, IN PVOID Address, OUT PBOOLEAN WasDirty, OUT PPFN_NUMBER Page)
Definition: page.c:177
VOID NTAPI MmInitGlobalKernelPageDirectory(VOID)
Definition: page.c:277
VOID NTAPI MmSetDirtyBit(PEPROCESS Process, PVOID Address, BOOLEAN Bit)
Definition: page.c:816
static BOOLEAN MiIsPageTablePresent(PVOID Address)
Definition: page.c:119
NTSTATUS NTAPI MiFillSystemPageDirectory(IN PVOID Base, IN SIZE_T NumberOfBytes)
Definition: section.c:462
BOOLEAN Mmi386MakeKernelPageTableGlobal(PVOID PAddress)
Definition: pagepae.c:844
static WCHAR Address[46]
Definition: ping.c:68
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:108
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
ULONG PageFrameNumber
Definition: mmtypes.h:109
ULONG64 WriteThrough
Definition: mmtypes.h:69
ULONG64 Write
Definition: mmtypes.h:67
ULONG64 Valid
Definition: mmtypes.h:66
ULONG64 CacheDisable
Definition: mmtypes.h:70
ULONG64 NoExecute
Definition: mmtypes.h:81
ULONG64 CopyOnWrite
Definition: mmtypes.h:75
Definition: mm.h:374
MMPTE OriginalPte
Definition: mm.h:407
ULONG64 Dirty
Definition: mmtypes.h:164
ULONG64 Accessed
Definition: mmtypes.h:163
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 Owner
Definition: mmtypes.h:160
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
ULONG64 UsedPageTableEntries
Definition: mmtypes.h:91
ULONG64 Transition
Definition: mmtypes.h:90
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
HARDWARE_PTE Flush
Definition: mmtypes.h:216
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG_PTR Long
Definition: mmtypes.h:215
union _MMPTE::@2307 u
USHORT UsedPageTableEntries[768]
Definition: mmtypes.h:883
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS _Inout_ PLARGE_INTEGER NumberOfBytes
Definition: iotypes.h:1036
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:792
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
#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