ReactOS  0.4.10-dev-19-g39281f0
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 */
168  OldIrql = MiAcquirePfnLock();
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 */
195  MiReleasePfnLock(OldIrql);
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 
316  return (Pte.u.Hard.Valid == 0) &&
317  (Pte.u.Trans.Transition == 0) &&
318  (Pte.u.Hard.PageFrameNumber != 0);
319 }
320 
321 BOOLEAN
322 NTAPI
324 {
325  MMPTE Pte;
326  Pte.u.Long = MiGetPteValueForProcess(Process, Address);
327  return Pte.u.Hard.Valid && Pte.u.Soft.Transition;
328 }
329 
330 static PMMPTE
332 {
333  __debugbreak();
334  return 0;
335 }
336 
338 {
339  ASSERT(FALSE);
340  return 0;
341 }
342 
344 {
345  MMPTE Pte, *PointerPte;
346 
347  PointerPte = MmGetPageTableForProcess(Process, Address, FALSE);
348  if (PointerPte)
349  {
350  Pte = *PointerPte;
351  MmUnmapPageTable(PointerPte);
352  return Pte.u.Long;
353  }
354  return 0;
355 }
356 
357 VOID
358 NTAPI
361  PVOID Address,
362  SWAPENTRY* SwapEntry)
363 {
364  ULONG64 Entry = MmGetPageEntryForProcess(Process, Address);
365  *SwapEntry = Entry >> 1;
366 }
367 
368 BOOLEAN
369 NTAPI
371 {
372  MMPTE Pte;
373  Pte.u.Long = MiGetPteValueForProcess(Process, Address);
374  return Pte.u.Hard.Valid && Pte.u.Hard.Dirty;
375 }
376 
377 ULONG
378 NTAPI
380 {
381  MMPTE Pte;
382 
383  Pte.u.Long = MiGetPteValueForProcess(Process, Address);
384 
385  return MiGetPteProtection(Pte);
386 }
387 
388 VOID
389 NTAPI
391 {
392  PMMPTE Pte;
393  MMPTE NewPte;
394 
395  Pte = MiGetPteForProcess(Process, Address, FALSE);
396  ASSERT(Pte != NULL);
397 
398  NewPte = *Pte;
399 
400  MiSetPteProtection(&NewPte, flProtect);
401 
402  InterlockedExchangePte(Pte, NewPte);
403 
404  MiFlushTlb(Pte, Address);
405 }
406 
407 VOID
408 NTAPI
410 {
411  PMMPTE Pte;
412 
413  Pte = MiGetPteForProcess(Process, Address, FALSE);
414  if (!Pte)
415  {
416  KeBugCheckEx(MEMORY_MANAGEMENT, 0x1234, (ULONG64)Address, 0, 0);
417  }
418 
419  /* Ckear the dirty bit */
420  if (InterlockedBitTestAndReset64((PVOID)Pte, 6))
421  {
422  if (!MiIsHyperspaceAddress(Pte))
423  __invlpg(Address);
424  }
425 
426  MiFlushTlb(Pte, Address);
427 }
428 
429 VOID
430 NTAPI
432 {
433  PMMPTE Pte;
434 
435  Pte = MiGetPteForProcess(Process, Address, FALSE);
436  if (!Pte)
437  {
438  KeBugCheckEx(MEMORY_MANAGEMENT, 0x1234, (ULONG64)Address, 0, 0);
439  }
440 
441  /* Ckear the dirty bit */
442  if (InterlockedBitTestAndSet64((PVOID)Pte, 6))
443  {
444  if (!MiIsHyperspaceAddress(Pte))
445  __invlpg(Address);
446  }
447 
448  MiFlushTlb(Pte, Address);
449 }
450 
451 VOID
452 NTAPI
455  PVOID Address,
456  BOOLEAN* WasDirty,
457  PPFN_NUMBER Page)
458 {
459  PFN_NUMBER Pfn;
460  PMMPTE Pte;
461  MMPTE OldPte;
462 
463  Pte = MiGetPteForProcess(Process, Address, FALSE);
464 
465  if (Pte)
466  {
467  /* Atomically set the entry to zero and get the old value. */
468  OldPte.u.Long = InterlockedExchange64((LONG64*)&Pte->u.Long, 0);
469 
470  if (OldPte.u.Hard.Valid)
471  {
472  Pfn = OldPte.u.Hard.PageFrameNumber;
473  }
474  else
475  Pfn = 0;
476  }
477  else
478  {
479  OldPte.u.Long = 0;
480  Pfn = 0;
481  }
482 
483  /* Return information to the caller */
484  if (WasDirty)
485  *WasDirty = (BOOLEAN)OldPte.u.Hard.Dirty;
486 
487  if (Page)
488  *Page = Pfn;
489 
490  MiFlushTlb(Pte, Address);
491 }
492 
493 VOID
494 NTAPI
496  SWAPENTRY* SwapEntry)
497 {
499 }
500 
501 NTSTATUS
502 NTAPI
504  PVOID Address,
505  SWAPENTRY SwapEntry)
506 {
508  return STATUS_UNSUCCESSFUL;
509 }
510 
511 
512 NTSTATUS
513 NTAPI
516  PVOID Address,
517  ULONG PageProtection,
518  PPFN_NUMBER Pages,
519  ULONG PageCount)
520 {
521  ULONG i;
522  MMPTE TmplPte, *Pte;
523 
524  ASSERT((ULONG_PTR)Address % PAGE_SIZE == 0);
525 
526  /* Check if the range is valid */
527  if ((Process == NULL && Address < MmSystemRangeStart) ||
528  (Process != NULL && Address > MmHighestUserAddress))
529  {
530  DPRINT1("Address 0x%p is invalid for process %p\n", Address, Process);
531  ASSERT(FALSE);
532  }
533 
534  TmplPte.u.Long = 0;
535  TmplPte.u.Hard.Valid = 1;
536  MiSetPteProtection(&TmplPte, PageProtection);
537 
538  TmplPte.u.Flush.Owner = (Address < MmHighestUserAddress) ? 1 : 0;
539 
540 //__debugbreak();
541 
542  for (i = 0; i < PageCount; i++)
543  {
544  TmplPte.u.Hard.PageFrameNumber = Pages[i];
545 
546  Pte = MiGetPteForProcess(Process, Address, TRUE);
547 
548 DPRINT("MmCreateVirtualMappingUnsafe, Address=%p, TmplPte=%p, Pte=%p\n",
549  Address, TmplPte.u.Long, Pte);
550 
551  if (InterlockedExchangePte(Pte, TmplPte))
552  {
553  KeInvalidateTlbEntry(Address);
554  }
555 
556  if (MiIsHyperspaceAddress(Pte))
558 
559  Address = (PVOID)((ULONG64)Address + PAGE_SIZE);
560  }
561 
562 
563  return STATUS_SUCCESS;
564 }
565 
566 NTSTATUS
567 NTAPI
569  PVOID Address,
570  ULONG Protect,
571  PPFN_NUMBER Pages,
572  ULONG PageCount)
573 {
574  ULONG i;
575 
576  ASSERT((ULONG_PTR)Address % PAGE_SIZE == 0);
577 
578  for (i = 0; i < PageCount; i++)
579  {
580  if (!MmIsPageInUse(Pages[i]))
581  {
582  DPRINT1("Page %x not in use\n", Pages[i]);
583  KeBugCheck(MEMORY_MANAGEMENT);
584  }
585  }
586 
587  return MmCreateVirtualMappingUnsafe(Process, Address, Protect, Pages, PageCount);
588 }
589 
590 BOOLEAN
591 NTAPI
594  OUT PULONG_PTR DirectoryTableBase)
595 {
596  KIRQL OldIrql;
597  PFN_NUMBER TableBasePfn, HyperPfn, HyperPdPfn, HyperPtPfn, WorkingSetPfn;
598  PMMPTE SystemPte;
599  MMPTE TempPte, PdePte;
600  ULONG TableIndex;
601  PMMPTE PageTablePointer;
602 
603  /* Make sure we don't already have a page directory setup */
604  ASSERT(Process->Pcb.DirectoryTableBase[0] == 0);
605  ASSERT(Process->Pcb.DirectoryTableBase[1] == 0);
606  ASSERT(Process->WorkingSetPage == 0);
607 
608  /* Choose a process color */
609  Process->NextPageColor = (USHORT)RtlRandom(&MmProcessColorSeed);
610 
611  /* Setup the hyperspace lock */
612  KeInitializeSpinLock(&Process->HyperSpaceLock);
613 
614  /* Lock PFN database */
615  OldIrql = MiAcquirePfnLock();
616 
617  /* Get a page for the table base and one for hyper space. The PFNs for
618  these pages will be initialized in MmInitializeProcessAddressSpace,
619  when we are already attached to the process. */
620  TableBasePfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
621  HyperPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
622  HyperPdPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
623  HyperPtPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
624  WorkingSetPfn = MiRemoveAnyPage(MI_GET_NEXT_PROCESS_COLOR(Process));
625 
626  /* Release PFN lock */
627  MiReleasePfnLock(OldIrql);
628 
629  /* Zero pages */
630  MiZeroPhysicalPage(HyperPfn);
631  MiZeroPhysicalPage(WorkingSetPfn);
632 
633  /* Set the base directory pointers */
634  Process->WorkingSetPage = WorkingSetPfn;
635  DirectoryTableBase[0] = TableBasePfn << PAGE_SHIFT;
636  DirectoryTableBase[1] = HyperPfn << PAGE_SHIFT;
637 
638  /* Get a PTE to map the page directory */
639  SystemPte = MiReserveSystemPtes(1, SystemPteSpace);
640  ASSERT(SystemPte != NULL);
641 
642  /* Get its address */
643  PageTablePointer = MiPteToAddress(SystemPte);
644 
645  /* Build the PTE for the page directory and map it */
646  PdePte = ValidKernelPte;
647  PdePte.u.Hard.PageFrameNumber = TableBasePfn;
648  *SystemPte = PdePte;
649 
651  //MiInitializePageDirectoryForProcess(
652 
653  /* Copy the kernel mappings and zero out the rest */
654  TableIndex = PXE_PER_PAGE / 2;
655  RtlZeroMemory(PageTablePointer, TableIndex * sizeof(MMPTE));
656  RtlCopyMemory(PageTablePointer + TableIndex,
657  MiAddressToPxe(0) + TableIndex,
658  PAGE_SIZE - TableIndex * sizeof(MMPTE));
659 
660  /* Sanity check */
661  ASSERT(MiAddressToPxi(MmHyperSpaceEnd) >= TableIndex);
662 
663  /* Setup a PTE for the page directory mappings */
664  TempPte = ValidKernelPte;
665 
666  /* Update the self mapping of the PML4 */
667  TableIndex = MiAddressToPxi((PVOID)PXE_SELFMAP);
668  TempPte.u.Hard.PageFrameNumber = TableBasePfn;
669  PageTablePointer[TableIndex] = TempPte;
670 
671  /* Write the PML4 entry for hyperspace */
672  TableIndex = MiAddressToPxi((PVOID)HYPER_SPACE);
673  TempPte.u.Hard.PageFrameNumber = HyperPfn;
674  PageTablePointer[TableIndex] = TempPte;
675 
676  /* Map the hyperspace PDPT to the system PTE */
677  PdePte.u.Hard.PageFrameNumber = HyperPfn;
678  *SystemPte = PdePte;
679  __invlpg(PageTablePointer);
680 
681  /* Write the hyperspace entry for the first PD */
682  TempPte.u.Hard.PageFrameNumber = HyperPdPfn;
683  PageTablePointer[0] = TempPte;
684 
685  /* Map the hyperspace PD to the system PTE */
686  PdePte.u.Hard.PageFrameNumber = HyperPdPfn;
687  *SystemPte = PdePte;
688  __invlpg(PageTablePointer);
689 
690  /* Write the hyperspace entry for the first PT */
691  TempPte.u.Hard.PageFrameNumber = HyperPtPfn;
692  PageTablePointer[0] = TempPte;
693 
694  /* Map the hyperspace PT to the system PTE */
695  PdePte.u.Hard.PageFrameNumber = HyperPtPfn;
696  *SystemPte = PdePte;
697  __invlpg(PageTablePointer);
698 
699  /* Write the hyperspace PTE for the working set list index */
700  TempPte.u.Hard.PageFrameNumber = WorkingSetPfn;
701  TableIndex = MiAddressToPti(MmWorkingSetList);
702  PageTablePointer[TableIndex] = TempPte;
703 
705 
706  /* Release the system PTE */
707  MiReleaseSystemPtes(SystemPte, 1, SystemPteSpace);
708 
709  /* Switch to phase 1 initialization */
710  ASSERT(Process->AddressSpaceInitialized == 0);
711  Process->AddressSpaceInitialized = 1;
712 
713  return TRUE;
714 }
715 
716 /* EOF */
#define PAGE_WRITETHROUGH
Definition: mm.h:85
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:495
NTSYSAPI ULONG NTAPI RtlRandom(_Inout_ PULONG Seed)
ULONG MmProcessColorSeed
Definition: procsup.c:20
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:38
#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
_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 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
return STATUS_SUCCESS
Definition: btrfs.c:2690
_In_ BOOLEAN Create
Definition: pstypes.h:511
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:453
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
#define InterlockedExchangePte(pte1, pte2)
Definition: page.c:19
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:875
VOID NTAPI MmSetDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:431
HARDWARE_PTE Flush
Definition: mmtypes.h:216
ULONG64 Transition
Definition: mmtypes.h:105
BOOLEAN NTAPI MmIsDirtyPage(PEPROCESS Process, PVOID Address)
Definition: page.c:370
PMMPTE FORCEINLINE MiAddressToPpe(PVOID Address)
Definition: mm.h:150
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
ULONG FORCEINLINE MiAddressToPti(PVOID Address)
Definition: mm.h:170
ULONG64 CopyOnWrite
Definition: mmtypes.h:75
VOID NTAPI MmSetCleanPage(PEPROCESS Process, PVOID Address)
Definition: page.c:409
union _MMPTE::@2171 u
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
static PMMPTE MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: page.c:331
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:882
PFN_NUMBER NTAPI MiRemoveZeroPage(IN ULONG Color)
Definition: pfnlist.c:531
uint32_t ULONG_PTR
Definition: typedefs.h:63
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:189
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:916
NTSTATUS NTAPI MmCreatePageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry)
Definition: page.c:503
BOOLEAN NTAPI MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
Definition: page.c:323
#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:416
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:197
ULONG64 WriteThrough
Definition: mmtypes.h:69
#define FORCEINLINE
Definition: ntbasedef.h:221
#define PAGE_EXECUTE
Definition: nt_native.h:1306
ULONG NTAPI MmGetPageProtect(PEPROCESS Process, PVOID Address)
Definition: page.c:379
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:514
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:66
unsigned char BOOLEAN
FORCEINLINE VOID KeInvalidateTlbEntry(IN PVOID Address)
Definition: ke.h:201
LONG NTSTATUS
Definition: precomp.h:26
if(!(yy_init))
Definition: macro.lex.yy.c:717
MMPTE_TRANSITION Trans
Definition: mmtypes.h:220
const ULONG64 MmProtectToPteMask[32]
Definition: page.c:32
#define MI_GET_NEXT_PROCESS_COLOR(x)
Definition: miarm.h:212
ULONG64 Valid
Definition: mmtypes.h:150
VOID MiFlushTlb(PMMPTE Pte, PVOID Address)
Definition: page.c:128
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:1008
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define HYPER_SPACE_END
Definition: mm.h:14
unsigned __int64 ULONG64
Definition: imports.h:198
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
PMMPTE FORCEINLINE MiAddressToPxe(PVOID Address)
Definition: mm.h:160
#define PAGE_SIZE
Definition: env_spec_w32.h:49
BOOLEAN MmUnmapPageTable(PMMPTE Pt)
Definition: page.c:337
const ULONG MmProtectToValue[32]
Definition: page.c:81
VOID NTAPI MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
Definition: page.c:390
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
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:47
BOOLEAN NTAPI MmCreateProcessAddressSpace(IN ULONG MinWs, IN PEPROCESS Process, OUT PULONG_PTR DirectoryTableBase)
Definition: page.c:592
MMPTE_SOFTWARE Soft
Definition: mmtypes.h:219
VOID NTAPI MmGetPageFileMapping(PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
Definition: page.c:359
PVOID MmHighestUserAddress
Definition: rtlcompat.c:29
#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:1870
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:39
#define HYPER_SPACE
Definition: mm.h:13
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:261
uint32_t * PULONG_PTR
Definition: typedefs.h:63
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
static ULONG64 MiGetPteValueForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:220
static ULONG64 MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
Definition: page.c:343
ULONG64 NoExecute
Definition: mmtypes.h:81
#define MmSystemRangeStart
Definition: mm.h:31
NTSTATUS NTAPI MmCreateVirtualMapping(PEPROCESS Process, PVOID Address, ULONG Protect, PPFN_NUMBER Pages, ULONG PageCount)
Definition: page.c:568
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:94
#define PAGE_READWRITE
Definition: nt_native.h:1304