ReactOS  r75619
page.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: GPL, See COPYING in the top level directory
3  * PROJECT: ReactOS kernel
4  * FILE: ntoskrnl/mm/amd64/page.c
5  * PURPOSE: Low level memory managment manipulation
6  *
7  * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
8  * ReactOS Portable Systems Group
9  */
10 
11 /* INCLUDES ***************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 #include <mm/ARM3/miarm.h>
17 
18 #undef InterlockedExchangePte
19 #define InterlockedExchangePte(pte1, pte2) \
20  InterlockedExchange64((LONG64*)&pte1->u.Long, pte2.u.Long)
21 
22 #define PAGE_EXECUTE_ANY (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY)
23 #define PAGE_WRITE_ANY (PAGE_EXECUTE_READWRITE|PAGE_READWRITE|PAGE_EXECUTE_WRITECOPY|PAGE_WRITECOPY)
24 #define PAGE_WRITECOPY_ANY (PAGE_EXECUTE_WRITECOPY|PAGE_WRITECOPY)
25 
26 extern MMPTE HyperTemplatePte;
27 
28 /* GLOBALS *****************************************************************/
29 
30 const
31 ULONG64
33 {
34  //
35  // These are the base MM_ protection flags
36  //
37  0,
38  PTE_READONLY | PTE_ENABLE_CACHE,
39  PTE_EXECUTE | PTE_ENABLE_CACHE,
40  PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
41  PTE_READWRITE | PTE_ENABLE_CACHE,
42  PTE_WRITECOPY | PTE_ENABLE_CACHE,
43  PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
44  PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
45  //
46  // These OR in the MM_NOCACHE flag
47  //
48  0,
49  PTE_READONLY | PTE_DISABLE_CACHE,
50  PTE_EXECUTE | PTE_DISABLE_CACHE,
51  PTE_EXECUTE_READ | PTE_DISABLE_CACHE,
52  PTE_READWRITE | PTE_DISABLE_CACHE,
53  PTE_WRITECOPY | PTE_DISABLE_CACHE,
54  PTE_EXECUTE_READWRITE | PTE_DISABLE_CACHE,
55  PTE_EXECUTE_WRITECOPY | PTE_DISABLE_CACHE,
56  //
57  // These OR in the MM_DECOMMIT flag, which doesn't seem supported on x86/64/ARM
58  //
59  0,
60  PTE_READONLY | PTE_ENABLE_CACHE,
61  PTE_EXECUTE | PTE_ENABLE_CACHE,
62  PTE_EXECUTE_READ | PTE_ENABLE_CACHE,
63  PTE_READWRITE | PTE_ENABLE_CACHE,
64  PTE_WRITECOPY | PTE_ENABLE_CACHE,
65  PTE_EXECUTE_READWRITE | PTE_ENABLE_CACHE,
66  PTE_EXECUTE_WRITECOPY | PTE_ENABLE_CACHE,
67  //
68  // These OR in the MM_NOACCESS flag, which seems to enable WriteCombining?
69  //
70  0,
71  PTE_READONLY | PTE_WRITECOMBINED_CACHE,
72  PTE_EXECUTE | PTE_WRITECOMBINED_CACHE,
73  PTE_EXECUTE_READ | PTE_WRITECOMBINED_CACHE,
74  PTE_READWRITE | PTE_WRITECOMBINED_CACHE,
75  PTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
76  PTE_EXECUTE_READWRITE | PTE_WRITECOMBINED_CACHE,
77  PTE_EXECUTE_WRITECOPY | PTE_WRITECOMBINED_CACHE,
78 };
79 
80 const
82 {
114  PAGE_WRITECOMBINE | PAGE_EXECUTE_WRITECOPY
115 };
116 
117 /* PRIVATE FUNCTIONS *******************************************************/
118 
119 BOOLEAN
122 {
123  return ((ULONG64)Address >= HYPER_SPACE &&
124  (ULONG64)Address <= HYPER_SPACE_END);
125 }
126 
127 VOID
129 {
130  if (MiIsHyperspaceAddress(Pte))
131  {
133  }
134  else
135  {
136  __invlpg(Address);
137  }
138 }
139 
140 static
141 PMMPTE
144  PVOID Address,
145  BOOLEAN Create)
146 {
147  MMPTE TmplPte, *Pte;
148 
149  /* Check if we need hypersapce mapping */
150  if (Address < MmSystemRangeStart &&
151  Process && Process != PsGetCurrentProcess())
152  {
154  __debugbreak();
155  return NULL;
156  }
157  else if (Create)
158  {
159  KIRQL OldIrql;
160  TmplPte.u.Long = 0;
161  TmplPte.u.Flush.Valid = 1;
162  TmplPte.u.Flush.Write = 1;
163 
164  /* All page table levels of user pages are user owned */
165  TmplPte.u.Flush.Owner = (Address < MmHighestUserAddress) ? 1 : 0;
166 
167  /* Lock the PFN database */
169 
170  /* Get the PXE */
171  Pte = MiAddressToPxe(Address);
172  if (!Pte->u.Hard.Valid)
173  {
174  TmplPte.u.Hard.PageFrameNumber = MiRemoveZeroPage(0);
175  MI_WRITE_VALID_PTE(Pte, TmplPte);
176  }
177 
178  /* Get the PPE */
179  Pte = MiAddressToPpe(Address);
180  if (!Pte->u.Hard.Valid)
181  {
182  TmplPte.u.Hard.PageFrameNumber = MiRemoveZeroPage(1);
183  MI_WRITE_VALID_PTE(Pte, TmplPte);
184  }
185 
186  /* Get the PDE */
187  Pte = MiAddressToPde(Address);
188  if (!Pte->u.Hard.Valid)
189  {
190  TmplPte.u.Hard.PageFrameNumber = MiRemoveZeroPage(2);
191  MI_WRITE_VALID_PTE(Pte, TmplPte);
192  }
193 
194  /* Unlock PFN database */
196  }
197  else
198  {
199  /* Get the PXE */
200  Pte = MiAddressToPxe(Address);
201  if (!Pte->u.Hard.Valid)
202  return NULL;
203 
204  /* Get the PPE */
205  Pte = MiAddressToPpe(Address);
206  if (!Pte->u.Hard.Valid)
207  return NULL;
208 
209  /* Get the PDE */
210  Pte = MiAddressToPde(Address);
211  if (!Pte->u.Hard.Valid)
212  return NULL;
213  }
214 
215  return MiAddressToPte(Address);
216 }
217 
218 static
219 ULONG64
222  PVOID Address)
223 {
224  PMMPTE Pte;
225  ULONG64 PteValue;
226 
227  Pte = MiGetPteForProcess(Process, Address, FALSE);
228  PteValue = Pte ? Pte->u.Long : 0;
229 
230  if (MiIsHyperspaceAddress(Pte))
232 
233  return PteValue;
234 }
235 
236 ULONG
237 NTAPI
239 {
240  ULONG Protect;
241 
242  if (!Pte.u.Flush.Valid)
243  {
244  Protect = PAGE_NOACCESS;
245  }
246  else if (Pte.u.Flush.NoExecute)
247  {
248  if (Pte.u.Flush.CopyOnWrite)
249  Protect = PAGE_WRITECOPY;
250  else if (Pte.u.Flush.Write)
251  Protect = PAGE_READWRITE;
252  else
253  Protect = PAGE_READONLY;
254  }
255  else
256  {
257  if (Pte.u.Flush.CopyOnWrite)
258  Protect = PAGE_EXECUTE_WRITECOPY;
259  else if (Pte.u.Flush.Write)
260  Protect = PAGE_EXECUTE_READWRITE;
261  else
262  Protect = PAGE_EXECUTE_READ;
263  }
264 
265  if (Pte.u.Flush.CacheDisable)
266  Protect |= PAGE_NOCACHE;
267 
268  if (Pte.u.Flush.WriteThrough)
269  Protect |= PAGE_WRITETHROUGH;
270 
271  // PAGE_GUARD ?
272  return Protect;
273 }
274 
275 VOID
276 NTAPI
278 {
279  Pte->u.Flush.CopyOnWrite = (Protection & PAGE_WRITECOPY_ANY) ? 1 : 0;
280  Pte->u.Flush.Write = (Protection & PAGE_WRITE_ANY) ? 1 : 0;
281  Pte->u.Flush.CacheDisable = (Protection & PAGE_NOCACHE) ? 1 : 0;
282  Pte->u.Flush.WriteThrough = (Protection & PAGE_WRITETHROUGH) ? 1 : 0;
283 
284  // FIXME: This doesn't work. Why?
285 // Pte->u.Flush.NoExecute = (Protection & PAGE_EXECUTE_ANY) ? 0 : 1;
286 }
287 
288 /* FUNCTIONS ***************************************************************/
289 
291 NTAPI
293  PVOID Address)
294 {
295  MMPTE Pte;
296  Pte.u.Long = MiGetPteValueForProcess(Process, Address);
297  return Pte.u.Hard.Valid ? Pte.u.Hard.PageFrameNumber : 0;
298 }
299 
300 BOOLEAN
301 NTAPI
303 {
304  MMPTE Pte;
305  Pte.u.Long = MiGetPteValueForProcess(Process, Address);
306  return (BOOLEAN)Pte.u.Hard.Valid;
307 }
308 
309 BOOLEAN
310 NTAPI
312 {
313  MMPTE Pte;
314  Pte.u.Long = MiGetPteValueForProcess(Process, Address);
315  __debugbreak(); // FIXME
316  return !Pte.u.Hard.Valid && !(Pte.u.Long & 0x800) && Pte.u.Hard.PageFrameNumber;
317 }
318 
319 BOOLEAN
320 NTAPI
322 {
323  MMPTE Pte;
324  Pte.u.Long = MiGetPteValueForProcess(Process, Address);
325  return Pte.u.Hard.Valid && Pte.u.Soft.Transition;
326 }
327 
328 static PMMPTE
330 {
331  __debugbreak();
332  return 0;
333 }
334 
336 {
337  ASSERT(FALSE);
338  return 0;
339 }
340 
342 {
343  MMPTE Pte, *PointerPte;
344 
345  PointerPte = MmGetPageTableForProcess(Process, Address, FALSE);
346  if (PointerPte)
347  {
348  Pte = *PointerPte;
349  MmUnmapPageTable(PointerPte);
350  return Pte.u.Long;
351  }
352  return 0;
353 }
354 
355 VOID
356 NTAPI
359  PVOID Address,
360  SWAPENTRY* SwapEntry)
361 {
362  ULONG64 Entry = MmGetPageEntryForProcess(Process, Address);
363  *SwapEntry = Entry >> 1;
364 }
365 
366 BOOLEAN
367 NTAPI
369 {
370  MMPTE Pte;
371  Pte.u.Long = MiGetPteValueForProcess(Process, Address);
372  return Pte.u.Hard.Valid && Pte.u.Hard.Dirty;
373 }
374 
375 ULONG
376 NTAPI
378 {
379  MMPTE Pte;
380 
381  Pte.u.Long = MiGetPteValueForProcess(Process, Address);
382 
383  return MiGetPteProtection(Pte);
384 }
385 
386 VOID
387 NTAPI
389 {
390  PMMPTE Pte;
391  MMPTE NewPte;
392 
393  Pte = MiGetPteForProcess(Process, Address, FALSE);
394  ASSERT(Pte != NULL);
395 
396  NewPte = *Pte;
397 
398  MiSetPteProtection(&NewPte, flProtect);
399 
400  InterlockedExchangePte(Pte, NewPte);
401 
402  MiFlushTlb(Pte, Address);
403 }
404 
405 VOID
406 NTAPI
408 {
409  PMMPTE Pte;
410 
411  Pte = MiGetPteForProcess(Process, Address, FALSE);
412  if (!Pte)
413  {
414  KeBugCheckEx(MEMORY_MANAGEMENT, 0x1234, (ULONG64)Address, 0, 0);
415  }
416 
417  /* Ckear the dirty bit */
418  if (InterlockedBitTestAndReset64((PVOID)Pte, 6))
419  {
420  if (!MiIsHyperspaceAddress(Pte))
421  __invlpg(Address);
422  }
423 
424  MiFlushTlb(Pte, Address);
425 }
426 
427 VOID
428 NTAPI
430 {
431  PMMPTE Pte;
432 
433  Pte = MiGetPteForProcess(Process, Address, FALSE);
434  if (!Pte)
435  {
436  KeBugCheckEx(MEMORY_MANAGEMENT, 0x1234, (ULONG64)Address, 0, 0);
437  }
438 
439  /* Ckear the dirty bit */
440  if (InterlockedBitTestAndSet64((PVOID)Pte, 6))
441  {
442  if (!MiIsHyperspaceAddress(Pte))
443  __invlpg(Address);
444  }
445 
446  MiFlushTlb(Pte, Address);
447 }
448 
449 VOID
450 NTAPI
453  PVOID Address,
454  BOOLEAN* WasDirty,
455  PPFN_NUMBER Page)
456 {
457  PFN_NUMBER Pfn;
458  PMMPTE Pte;
459  MMPTE OldPte;
460 
461  Pte = MiGetPteForProcess(Process, Address, FALSE);
462 
463  if (Pte)
464  {
465  /* Atomically set the entry to zero and get the old value. */
466  OldPte.u.Long = InterlockedExchange64((LONG64*)&Pte->u.Long, 0);
467 
468  if (OldPte.u.Hard.Valid)
469  {
470  Pfn = OldPte.u.Hard.PageFrameNumber;
471  }
472  else
473  Pfn = 0;
474  }
475  else
476  {
477  OldPte.u.Long = 0;
478  Pfn = 0;
479  }
480 
481  /* Return information to the caller */
482  if (WasDirty)
483  *WasDirty = (BOOLEAN)OldPte.u.Hard.Dirty;
484 
485  if (Page)
486  *Page = Pfn;
487 
488  MiFlushTlb(Pte, Address);
489 }
490 
491 VOID
492 NTAPI
494  SWAPENTRY* SwapEntry)
495 {
497 }
498 
499 NTSTATUS
500 NTAPI
502  PVOID Address,
503  SWAPENTRY SwapEntry)
504 {
506  return STATUS_UNSUCCESSFUL;
507 }
508 
509 
510 NTSTATUS
511 NTAPI
514  PVOID Address,
515  ULONG PageProtection,
516  PPFN_NUMBER Pages,
517  ULONG PageCount)
518 {
519  ULONG i;
520  MMPTE TmplPte, *Pte;
521 
522  ASSERT((ULONG_PTR)Address % PAGE_SIZE == 0);
523 
524  /* Check if the range is valid */
525  if ((Process == NULL && Address < MmSystemRangeStart) ||
526  (Process != NULL && Address > MmHighestUserAddress))
527  {
528  DPRINT1("Address 0x%p is invalid for process %p\n", Address, Process);
529  ASSERT(FALSE);
530  }
531 
532  TmplPte.u.Long = 0;
533  TmplPte.u.Hard.Valid = 1;
534  MiSetPteProtection(&TmplPte, PageProtection);
535 
536  TmplPte.u.Flush.Owner = (Address < MmHighestUserAddress) ? 1 : 0;
537 
538 //__debugbreak();
539 
540  for (i = 0; i < PageCount; i++)
541  {
542  TmplPte.u.Hard.PageFrameNumber = Pages[i];
543 
544  Pte = MiGetPteForProcess(Process, Address, TRUE);
545 
546 DPRINT("MmCreateVirtualMappingUnsafe, Address=%p, TmplPte=%p, Pte=%p\n",
547  Address, TmplPte.u.Long, Pte);
548 
549  if (InterlockedExchangePte(Pte, TmplPte))
550  {
551  KeInvalidateTlbEntry(Address);
552  }
553 
554  if (MiIsHyperspaceAddress(Pte))
556 
557  Address = (PVOID)((ULONG64)Address + PAGE_SIZE);
558  }
559 
560 
561  return STATUS_SUCCESS;
562 }
563 
564 NTSTATUS
565 NTAPI
567  PVOID Address,
568  ULONG Protect,
569  PPFN_NUMBER Pages,
570  ULONG PageCount)
571 {
572  ULONG i;
573 
574  ASSERT((ULONG_PTR)Address % PAGE_SIZE == 0);
575 
576  for (i = 0; i < PageCount; i++)
577  {
578  if (!MmIsPageInUse(Pages[i]))
579  {
580  DPRINT1("Page %x not in use\n", Pages[i]);
581  KeBugCheck(MEMORY_MANAGEMENT);
582  }
583  }
584 
585  return MmCreateVirtualMappingUnsafe(Process, Address, Protect, Pages, PageCount);
586 }
587 
588 BOOLEAN
589 NTAPI
592  OUT PULONG_PTR DirectoryTableBase)
593 {
594  KIRQL OldIrql;
595  PFN_NUMBER TableBasePfn, HyperPfn, HyperPdPfn, HyperPtPfn, WorkingSetPfn;
596  PMMPTE SystemPte;
597  MMPTE TempPte, PdePte;
598  ULONG TableIndex;
599  PMMPTE PageTablePointer;
600 
601  /* Make sure we don't already have a page directory setup */
602  ASSERT(Process->Pcb.DirectoryTableBase[0] == 0);
603  ASSERT(Process->Pcb.DirectoryTableBase[1] == 0);
604  ASSERT(Process->WorkingSetPage == 0);
605 
606  /* Choose a process color */
607  Process->NextPageColor = (USHORT)RtlRandom(&MmProcessColorSeed);
608 
609  /* Setup the hyperspace lock */
610  KeInitializeSpinLock(&Process->HyperSpaceLock);
611 
612  /* Lock PFN database */
614 
615  /* Get a page for the table base and one for hyper space. The PFNs for
616  these pages will be initialized in MmInitializeProcessAddressSpace,
617  when we are already attached to the process. */
618  TableBasePfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
619  HyperPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
620  HyperPdPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
621  HyperPtPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
622  WorkingSetPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
623 
624  /* Release PFN lock */
626 
627  /* Zero pages */
628  MiZeroPhysicalPage(HyperPfn);
629  MiZeroPhysicalPage(WorkingSetPfn);
630 
631  /* Set the base directory pointers */
632  Process->WorkingSetPage = WorkingSetPfn;
633  DirectoryTableBase[0] = TableBasePfn << PAGE_SHIFT;
634  DirectoryTableBase[1] = HyperPfn << PAGE_SHIFT;
635 
636  /* Get a PTE to map the page directory */
637  SystemPte = MiReserveSystemPtes(1, SystemPteSpace);
638  ASSERT(SystemPte != NULL);
639 
640  /* Get its address */
641  PageTablePointer = MiPteToAddress(SystemPte);
642 
643  /* Build the PTE for the page directory and map it */
644  PdePte = ValidKernelPte;
645  PdePte.u.Hard.PageFrameNumber = TableBasePfn;
646  *SystemPte = PdePte;
647 
649  //MiInitializePageDirectoryForProcess(
650 
651  /* Copy the kernel mappings and zero out the rest */
652  TableIndex = PXE_PER_PAGE / 2;
653  RtlZeroMemory(PageTablePointer, TableIndex * sizeof(MMPTE));
654  RtlCopyMemory(PageTablePointer + TableIndex,
655  MiAddressToPxe(0) + TableIndex,
656  PAGE_SIZE - TableIndex * sizeof(MMPTE));
657 
658  /* Sanity check */
659  ASSERT(MiAddressToPxi(MmHyperSpaceEnd) >= TableIndex);
660 
661  /* Setup a PTE for the page directory mappings */
662  TempPte = ValidKernelPte;
663 
664  /* Update the self mapping of the PML4 */
665  TableIndex = MiAddressToPxi((PVOID)PXE_SELFMAP);
666  TempPte.u.Hard.PageFrameNumber = TableBasePfn;
667  PageTablePointer[TableIndex] = TempPte;
668 
669  /* Write the PML4 entry for hyperspace */
670  TableIndex = MiAddressToPxi((PVOID)HYPER_SPACE);
671  TempPte.u.Hard.PageFrameNumber = HyperPfn;
672  PageTablePointer[TableIndex] = TempPte;
673 
674  /* Map the hyperspace PDPT to the system PTE */
675  PdePte.u.Hard.PageFrameNumber = HyperPfn;
676  *SystemPte = PdePte;
677  __invlpg(PageTablePointer);
678 
679  /* Write the hyperspace entry for the first PD */
680  TempPte.u.Hard.PageFrameNumber = HyperPdPfn;
681  PageTablePointer[0] = TempPte;
682 
683  /* Map the hyperspace PD to the system PTE */
684  PdePte.u.Hard.PageFrameNumber = HyperPdPfn;
685  *SystemPte = PdePte;
686  __invlpg(PageTablePointer);
687 
688  /* Write the hyperspace entry for the first PT */
689  TempPte.u.Hard.PageFrameNumber = HyperPtPfn;
690  PageTablePointer[0] = TempPte;
691 
692  /* Map the hyperspace PT to the system PTE */
693  PdePte.u.Hard.PageFrameNumber = HyperPtPfn;
694  *SystemPte = PdePte;
695  __invlpg(PageTablePointer);
696 
697  /* Write the hyperspace PTE for the working set list index */
698  TempPte.u.Hard.PageFrameNumber = WorkingSetPfn;
699  TableIndex = MiAddressToPti(MmWorkingSetList);
700  PageTablePointer[TableIndex] = TempPte;
701 
703 
704  /* Release the system PTE */
705  MiReleaseSystemPtes(SystemPte, 1, SystemPteSpace);
706 
707  /* Switch to phase 1 initialization */
708  ASSERT(Process->AddressSpaceInitialized == 0);
709  Process->AddressSpaceInitialized = 1;
710 
711  return TRUE;
712 }
713 
714 /* EOF */
#define PAGE_WRITETHROUGH
Definition: mm.h:83
ULONG64 Valid
Definition: mmtypes.h:66
DWORD *typedef PVOID
Definition: winlogon.h:52
#define PAGE_NOCACHE
Definition: nt_native.h:1311
VOID NTAPI MmDeletePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:493
NTSYSAPI ULONG NTAPI RtlRandom(_Inout_ PULONG Seed)
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
ULONG MmProcessColorSeed
Definition: procsup.c:20
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:39
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define PXE_PER_PAGE
#define InterlockedExchange64
Definition: interlocked.h:171
PVOID ULONG Address
Definition: oprghdlr.h:14
#define PAGE_WRITECOPY_ANY
Definition: page.c:24
BOOLEAN NTAPI MmIsPagePresent(PEPROCESS Process, PVOID Address)
Definition: page.c:302
#define MiAddressToPde(x)
Definition: mmx86.c:20
BOOLEAN NTAPI MmIsDisabledPage(PEPROCESS Process, PVOID Address)
Definition: page.c:311
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
BOOLEAN NTAPI MmIsPageInUse(PFN_NUMBER Page)
Definition: freelist.c:530
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
VOID NTAPI MiSetPteProtection(PMMPTE Pte, ULONG Protection)
Definition: page.c:277
ULONG64 Owner
Definition: mmtypes.h:68
#define PAGE_GUARD
Definition: nt_native.h:1310
ULONG64 CacheDisable
Definition: mmtypes.h:70
VOID NTAPI MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
Definition: page.c:451
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
#define InterlockedExchangePte(pte1, pte2)
Definition: page.c:19
VOID NTAPI MmSetDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:429
HARDWARE_PTE Flush
Definition: mmtypes.h:216
BOOLEAN NTAPI MmIsDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:368
PMMPTE FORCEINLINE MiAddressToPpe(PVOID Address)
Definition: mm.h:138
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
ULONG FORCEINLINE MiAddressToPti(PVOID Address)
Definition: mm.h:158
ULONG64 CopyOnWrite
Definition: mmtypes.h:75
VOID NTAPI MmSetCleanPage(PEPROCESS Process, PVOID Address)
Definition: page.c:407
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
static PMMPTE MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: page.c:329
_In_ BOOLEAN Create
Definition: pstypes.h:512
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:531
uint32_t ULONG_PTR
Definition: typedefs.h:64
ULONG64 Dirty
Definition: mmtypes.h:164
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG * PPFN_NUMBER
Definition: ke.h:8
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1309
ULONG PFN_NUMBER
Definition: ke.h:8
ULONG FORCEINLINE MiAddressToPxi(PVOID Address)
Definition: mm.h:177
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:914
_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
uint64_t ULONG64
Definition: typedefs.h:66
NTSTATUS NTAPI MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry)
Definition: page.c:501
BOOLEAN NTAPI MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
Definition: page.c:321
#define PsGetCurrentProcess
Definition: psfuncs.h:17
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
#define PAGE_NOACCESS
Definition: nt_native.h:1302
smooth NULL
Definition: ftsmooth.c:513
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
ULONG64 WriteThrough
Definition: mmtypes.h:69
#define FORCEINLINE
Definition: ntbasedef.h:213
#define PAGE_EXECUTE
Definition: nt_native.h:1306
ULONG NTAPI MmGetPageProtect(PEPROCESS Process, PVOID Address)
Definition: page.c:377
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1469
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(PEPROCESS Process, PVOID Address, ULONG PageProtection, PPFN_NUMBER Pages, ULONG PageCount)
Definition: page.c:512
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:275
PFN_NUMBER NTAPI MmGetPfnForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:292
#define PXE_SELFMAP
MMPTE HyperTemplatePte
Definition: hypermap.c:22
int64_t LONG64
Definition: typedefs.h:67
unsigned char BOOLEAN
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:177
if(!(yy_init))
Definition: macro.lex.yy.c:704
const ULONG64 MmProtectToPteMask[32]
Definition: page.c:32
#define MI_GET_NEXT_PROCESS_COLOR(x)
Definition: miarm.h:210
ULONG64 Valid
Definition: mmtypes.h:150
VOID MiFlushTlb(PMMPTE Pte, PVOID Address)
Definition: page.c:128
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
MMPTE ValidKernelPte
Definition: page.c:111
ULONG NTAPI MiGetPteProtection(MMPTE Pte)
Definition: page.c:238
#define MmDeleteHyperspaceMapping(x)
Definition: mm.h:967
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define HYPER_SPACE_END
Definition: mm.h:13
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
PMMPTE FORCEINLINE MiAddressToPxe(PVOID Address)
Definition: mm.h:148
#define PAGE_SIZE
Definition: env_spec_w32.h:49
BOOLEAN MmUnmapPageTable(PMMPTE Pt)
Definition: page.c:335
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
const ULONG MmProtectToValue[32]
Definition: page.c:81
VOID NTAPI MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
Definition: page.c:388
PMMWSL MmWorkingSetList
Definition: procsup.c:21
BOOLEAN FORCEINLINE MiIsHyperspaceAddress(PVOID Address)
Definition: page.c:121
ULONG_PTR Long
Definition: mmtypes.h:215
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
#define PAGE_WRITE_ANY
Definition: page.c:23
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define PAGE_WRITECOMBINE
Definition: mmtypes.h:78
LONG NTSTATUS
Definition: DriverTester.h:11
static PMMPTE MiGetPteForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: page.c:142
unsigned short USHORT
Definition: pedump.c:61
ULONG64 Transition
Definition: mmtypes.h:90
ULONG_PTR SWAPENTRY
Definition: mm.h:45
BOOLEAN NTAPI MmCreateProcessAddressSpace(IN ULONG MinWs, IN PEPROCESS Process, OUT PULONG_PTR DirectoryTableBase)
Definition: page.c:590
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:357
PVOID MmHighestUserAddress
Definition: rtlcompat.c:26
#define PAGE_READONLY
Definition: compat.h:127
#define PAGE_WRITECOPY
Definition: nt_native.h:1305
#define DPRINT1
Definition: precomp.h:8
ULONG64 Write
Definition: mmtypes.h:67
_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:1758
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:40
#define HYPER_SPACE
Definition: mm.h:12
PVOID MmHyperSpaceEnd
Definition: init.c:56
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t * PULONG_PTR
Definition: typedefs.h:64
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
union _MMPTE::@2063 u
static ULONG64 MiGetPteValueForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:220
static ULONG64 MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:341
ULONG64 NoExecute
Definition: mmtypes.h:81
#define MmSystemRangeStart
Definition: mm.h:25
NTSTATUS NTAPI MmCreateVirtualMapping(PEPROCESS Process, PVOID Address, ULONG Protect, PPFN_NUMBER Pages, ULONG PageCount)
Definition: page.c:566
base of all file and directory entries
Definition: entries.h:82
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:90
#define PAGE_READWRITE
Definition: nt_native.h:1304