ReactOS  0.4.15-dev-2701-g34593d9
procsup.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/procsup.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 
17 #define MODULE_INVOLVED_IN_ARM3
18 #include <mm/ARM3/miarm.h>
19 
20 BOOLEAN
23  _In_ PULONG_PTR DirectoryTableBase)
24 {
25  KIRQL OldIrql;
26  PFN_NUMBER TableBasePfn, HyperPfn, HyperPdPfn, HyperPtPfn;
27  PMMPTE SystemPte;
28  MMPTE TempPte, PdePte;
29  ULONG TableIndex;
30  PMMPTE PageTablePointer;
31  ULONG PageColor;
32 
33  /* Non-arch specific code-path allocated those for us */
34  TableBasePfn = DirectoryTableBase[0] >> PAGE_SHIFT;
35  HyperPfn = DirectoryTableBase[1] >> PAGE_SHIFT;
36 
37  /*
38  * Lock PFN database. Try getting zero pages.
39  * If that doesn't work, we take the slow path
40  * outside of the PFN lock.
41  */
44  HyperPdPfn = MiRemoveZeroPageSafe(PageColor);
45  if(!HyperPdPfn)
46  {
47  HyperPdPfn = MiRemoveAnyPage(PageColor);
49  MiZeroPhysicalPage(HyperPdPfn);
51  }
53  HyperPtPfn = MiRemoveZeroPageSafe(PageColor);
54  if(!HyperPtPfn)
55  {
56  HyperPtPfn = MiRemoveAnyPage(PageColor);
58  MiZeroPhysicalPage(HyperPtPfn);
59  }
60  else
61  {
63  }
64 
65  /* Get a PTE to map the page directory */
66  SystemPte = MiReserveSystemPtes(1, SystemPteSpace);
67  if (!SystemPte)
68  return FALSE;
69 
70  /* Get its address */
71  PageTablePointer = MiPteToAddress(SystemPte);
72 
73  /* Build the PTE for the page directory and map it */
74  MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte, SystemPte, MM_READWRITE, TableBasePfn);
75  MI_WRITE_VALID_PTE(SystemPte, PdePte);
76 
77  /* Copy the kernel mappings and zero out the rest */
78  TableIndex = PXE_PER_PAGE / 2;
79  RtlZeroMemory(PageTablePointer, TableIndex * sizeof(MMPTE));
80  RtlCopyMemory(PageTablePointer + TableIndex,
81  MiAddressToPxe(0) + TableIndex,
82  PAGE_SIZE - TableIndex * sizeof(MMPTE));
83 
84  /* Sanity check */
85  ASSERT(MiAddressToPxi(MmHyperSpaceEnd) >= TableIndex);
86 
87  /* Setup a PTE for the page directory mappings */
89 
90  /* Update the self mapping of the PML4 */
91  TableIndex = MiAddressToPxi((PVOID)PXE_SELFMAP);
92  TempPte.u.Hard.PageFrameNumber = TableBasePfn;
93  PageTablePointer[TableIndex] = TempPte;
94 
95  /* Write the PML4 entry for hyperspace */
96  TableIndex = MiAddressToPxi((PVOID)HYPER_SPACE);
97  TempPte.u.Hard.PageFrameNumber = HyperPfn;
98  PageTablePointer[TableIndex] = TempPte;
99 
100  /* Map the hyperspace PDPT to the system PTE */
101  PdePte.u.Hard.PageFrameNumber = HyperPfn;
102  *SystemPte = PdePte;
103  __invlpg(PageTablePointer);
104 
105  /* Write the hyperspace entry for the first PD */
106  TempPte.u.Hard.PageFrameNumber = HyperPdPfn;
107  PageTablePointer[0] = TempPte;
108 
109  /* Map the hyperspace PD to the system PTE */
110  PdePte.u.Hard.PageFrameNumber = HyperPdPfn;
111  *SystemPte = PdePte;
112  __invlpg(PageTablePointer);
113 
114  /* Write the hyperspace entry for the first PT */
115  TempPte.u.Hard.PageFrameNumber = HyperPtPfn;
116  PageTablePointer[0] = TempPte;
117 
118  /* Map the hyperspace PT to the system PTE */
119  PdePte.u.Hard.PageFrameNumber = HyperPtPfn;
120  *SystemPte = PdePte;
121  __invlpg(PageTablePointer);
122 
123  /* Write the hyperspace PTE for the working set list index */
124  TempPte.u.Hard.PageFrameNumber = Process->WorkingSetPage;
125  TableIndex = MiAddressToPti(MmWorkingSetList);
126  PageTablePointer[TableIndex] = TempPte;
127 
128  /* Release the system PTE */
129  MiReleaseSystemPtes(SystemPte, 1, SystemPteSpace);
130 
131  return TRUE;
132 }
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define PXE_PER_PAGE
#define TRUE
Definition: types.h:120
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:930
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:937
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PFN_NUMBER
Definition: ke.h:9
#define FALSE
Definition: types.h:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:969
union _MMPTE::@2311 u
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe(IN ULONG Color)
Definition: miarm.h:2425
unsigned char BOOLEAN
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:264
#define PXE_SELFMAP
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:164
#define ASSERT(a)
Definition: mode.c:44
#define MI_GET_NEXT_PROCESS_COLOR(x)
Definition: miarm.h:243
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
MMPTE ValidKernelPte
Definition: init.c:29
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define MM_READWRITE
Definition: inbv.c:12
FORCEINLINE ULONG MiAddressToPxi(PVOID Address)
Definition: mm.h:193
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define _In_
Definition: no_sal2.h:158
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
PMMWSL MmWorkingSetList
Definition: procsup.c:21
_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:1969
#define HYPER_SPACE
Definition: mm.h:14
PVOID MmHyperSpaceEnd
Definition: init.c:56
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t * PULONG_PTR
Definition: typedefs.h:65
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:783
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:201
FORCEINLINE ULONG MiAddressToPti(PVOID Address)
Definition: mm.h:174
BOOLEAN MiArchCreateProcessAddressSpace(_In_ PEPROCESS Process, _In_ PULONG_PTR DirectoryTableBase)
Definition: procsup.c:21
ULONG PageFrameNumber
Definition: mmtypes.h:109