ReactOS 0.4.15-dev-7953-g1f49173
pagepae.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for pagepae.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define PA_BIT_PRESENT   (0)
 
#define PA_BIT_READWRITE   (1)
 
#define PA_BIT_USER   (2)
 
#define PA_BIT_WT   (3)
 
#define PA_BIT_CD   (4)
 
#define PA_BIT_ACCESSED   (5)
 
#define PA_BIT_DIRTY   (6)
 
#define PA_BIT_GLOBAL   (8)
 
#define PA_PRESENT   (1 << PA_BIT_PRESENT)
 
#define PA_READWRITE   (1 << PA_BIT_READWRITE)
 
#define PA_USER   (1 << PA_BIT_USER)
 
#define PA_DIRTY   (1 << PA_BIT_DIRTY)
 
#define PA_WT   (1 << PA_BIT_WT)
 
#define PA_CD   (1 << PA_BIT_CD)
 
#define PA_ACCESSED   (1 << PA_BIT_ACCESSED)
 
#define PA_GLOBAL   (1 << PA_BIT_GLOBAL)
 
#define PAGEDIRECTORY_MAP   (0xc0000000 + (PTE_BASE / (1024)))
 
#define PAE_PAGEDIRECTORY_MAP   (0xc0000000 + (PTE_BASE / (512)))
 
#define HYPERSPACE   (Ke386Pae ? 0xc0800000 : 0xc0400000)
 
#define IS_HYPERSPACE(v)   (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
 
#define PTE_TO_PFN(X)   ((X) >> PAGE_SHIFT)
 
#define PFN_TO_PTE(X)   ((X) << PAGE_SHIFT)
 
#define PAE_PTE_TO_PFN(X)   (PAE_PAGE_MASK(X) >> PAGE_SHIFT)
 
#define PAE_PFN_TO_PTE(X)   ((X) << PAGE_SHIFT)
 
#define PAGE_MASK(x)   ((x)&(~0xfff))
 
#define PAE_PAGE_MASK(x)   ((x)&(~0xfffLL))
 
#define ADDR_TO_PAGE_TABLE(v)   (((ULONG)(v)) / (1024 * PAGE_SIZE))
 
#define ADDR_TO_PDE(v)
 
#define ADDR_TO_PTE(v)   (PULONG)(PTE_BASE + ((((ULONG)(v) / 1024))&(~0x3)))
 
#define ADDR_TO_PDE_OFFSET(v)   ((((ULONG)(v)) / (1024 * PAGE_SIZE)))
 
#define ADDR_TO_PTE_OFFSET(v)   ((((ULONG)(v)) % (1024 * PAGE_SIZE)) / PAGE_SIZE)
 
#define PAE_ADDR_TO_PAGE_TABLE(v)   (((ULONG)(v)) / (512 * PAGE_SIZE))
 
#define PAE_ADDR_TO_PDE(v)
 
#define PAE_ADDR_TO_PTE(v)   (PULONGLONG) (PTE_BASE + ((((ULONG_PTR)(v) / 512))&(~0x7)))
 
#define PAE_ADDR_TO_PDTE_OFFSET(v)   (((ULONG_PTR)(v)) / (512 * 512 * PAGE_SIZE))
 
#define PAE_ADDR_TO_PDE_PAGE_OFFSET(v)   ((((ULONG_PTR)(v)) % (512 * 512 * PAGE_SIZE)) / (512 * PAGE_SIZE))
 
#define PAE_ADDR_TO_PDE_OFFSET(v)   (((ULONG_PTR)(v))/ (512 * PAGE_SIZE))
 
#define PAE_ADDR_TO_PTE_OFFSET(v)   ((((ULONG_PTR)(v)) % (512 * PAGE_SIZE)) / PAGE_SIZE)
 

Functions

BOOLEAN MmUnmapPageTable (PULONG Pt)
 
ULONG_PTR NTAPI MiFlushTlbIpiRoutine (ULONG_PTR Address)
 
VOID MiFlushTlb (PULONG Pt, PVOID Address)
 
static ULONG ProtectToPTE (ULONG flProtect)
 
BOOLEAN NTAPI MmCreateProcessAddressSpace (IN ULONG MinWs, IN PEPROCESS Process, IN PLARGE_INTEGER DirectoryTableBase)
 
VOID NTAPI MmFreePageTable (PEPROCESS Process, PVOID Address)
 
static PULONGLONG MmGetPageTableForProcessForPAE (PEPROCESS Process, PVOID Address, BOOLEAN Create)
 
static PULONG MmGetPageTableForProcess (PEPROCESS Process, PVOID Address, BOOLEAN Create)
 
static ULONGLONG MmGetPageEntryForProcessForPAE (PEPROCESS Process, PVOID Address)
 
static ULONG MmGetPageEntryForProcess (PEPROCESS Process, PVOID Address)
 
PFN_NUMBER NTAPI MmGetPfnForProcess (PEPROCESS Process, PVOID Address)
 
VOID NTAPI MmDeleteVirtualMapping (PEPROCESS Process, PVOID Address, BOOLEAN *WasDirty, PPFN_NUMBER Page)
 
VOID NTAPI MmDeletePageFileMapping (PEPROCESS Process, PVOID Address, SWAPENTRY *SwapEntry)
 
BOOLEAN Mmi386MakeKernelPageTableGlobal (PVOID PAddress)
 
BOOLEAN NTAPI MmIsDirtyPage (PEPROCESS Process, PVOID Address)
 
VOID NTAPI MmSetCleanPage (PEPROCESS Process, PVOID Address)
 
VOID NTAPI MmSetDirtyPage (PEPROCESS Process, PVOID Address)
 
BOOLEAN NTAPI MmIsPagePresent (PEPROCESS Process, PVOID Address)
 
BOOLEAN NTAPI MmIsPageSwapEntry (PEPROCESS Process, PVOID Address)
 
NTSTATUS NTAPI MmCreatePageFileMapping (PEPROCESS Process, PVOID Address, SWAPENTRY SwapEntry)
 
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe (PEPROCESS Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
 
NTSTATUS NTAPI MmCreateVirtualMapping (PEPROCESS Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
 
ULONG NTAPI MmGetPageProtect (PEPROCESS Process, PVOID Address)
 
VOID NTAPI MmSetPageProtect (PEPROCESS Process, PVOID Address, ULONG flProtect)
 
VOID NTAPI MmInitGlobalKernelPageDirectory (VOID)
 

Variables

static ULONG MmGlobalKernelPageDirectory [1024]
 
static ULONGLONG MmGlobalKernelPageDirectoryForPAE [2048]
 
BOOLEAN Ke386Pae
 
BOOLEAN Ke386NoExecute
 

Macro Definition Documentation

◆ ADDR_TO_PAGE_TABLE

#define ADDR_TO_PAGE_TABLE (   v)    (((ULONG)(v)) / (1024 * PAGE_SIZE))

Definition at line 150 of file pagepae.c.

◆ ADDR_TO_PDE

#define ADDR_TO_PDE (   v)
Value:
((((ULONG)(v)) / (1024 * 1024))&(~0x3)))
const GLdouble * v
Definition: gl.h:2040
#define PAGEDIRECTORY_MAP
Definition: pagepae.c:36
uint32_t * PULONG
Definition: typedefs.h:59
uint32_t ULONG
Definition: typedefs.h:59

Definition at line 152 of file pagepae.c.

◆ ADDR_TO_PDE_OFFSET

#define ADDR_TO_PDE_OFFSET (   v)    ((((ULONG)(v)) / (1024 * PAGE_SIZE)))

Definition at line 156 of file pagepae.c.

◆ ADDR_TO_PTE

#define ADDR_TO_PTE (   v)    (PULONG)(PTE_BASE + ((((ULONG)(v) / 1024))&(~0x3)))

Definition at line 154 of file pagepae.c.

◆ ADDR_TO_PTE_OFFSET

#define ADDR_TO_PTE_OFFSET (   v)    ((((ULONG)(v)) % (1024 * PAGE_SIZE)) / PAGE_SIZE)

Definition at line 158 of file pagepae.c.

◆ HYPERSPACE

#define HYPERSPACE   (Ke386Pae ? 0xc0800000 : 0xc0400000)

Definition at line 39 of file pagepae.c.

◆ IS_HYPERSPACE

#define IS_HYPERSPACE (   v)    (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))

Definition at line 40 of file pagepae.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file pagepae.c.

◆ PA_ACCESSED

#define PA_ACCESSED   (1 << PA_BIT_ACCESSED)

Definition at line 33 of file pagepae.c.

◆ PA_BIT_ACCESSED

#define PA_BIT_ACCESSED   (5)

Definition at line 23 of file pagepae.c.

◆ PA_BIT_CD

#define PA_BIT_CD   (4)

Definition at line 22 of file pagepae.c.

◆ PA_BIT_DIRTY

#define PA_BIT_DIRTY   (6)

Definition at line 24 of file pagepae.c.

◆ PA_BIT_GLOBAL

#define PA_BIT_GLOBAL   (8)

Definition at line 25 of file pagepae.c.

◆ PA_BIT_PRESENT

#define PA_BIT_PRESENT   (0)

Definition at line 18 of file pagepae.c.

◆ PA_BIT_READWRITE

#define PA_BIT_READWRITE   (1)

Definition at line 19 of file pagepae.c.

◆ PA_BIT_USER

#define PA_BIT_USER   (2)

Definition at line 20 of file pagepae.c.

◆ PA_BIT_WT

#define PA_BIT_WT   (3)

Definition at line 21 of file pagepae.c.

◆ PA_CD

#define PA_CD   (1 << PA_BIT_CD)

Definition at line 32 of file pagepae.c.

◆ PA_DIRTY

#define PA_DIRTY   (1 << PA_BIT_DIRTY)

Definition at line 30 of file pagepae.c.

◆ PA_GLOBAL

#define PA_GLOBAL   (1 << PA_BIT_GLOBAL)

Definition at line 34 of file pagepae.c.

◆ PA_PRESENT

#define PA_PRESENT   (1 << PA_BIT_PRESENT)

Definition at line 27 of file pagepae.c.

◆ PA_READWRITE

#define PA_READWRITE   (1 << PA_BIT_READWRITE)

Definition at line 28 of file pagepae.c.

◆ PA_USER

#define PA_USER   (1 << PA_BIT_USER)

Definition at line 29 of file pagepae.c.

◆ PA_WT

#define PA_WT   (1 << PA_BIT_WT)

Definition at line 31 of file pagepae.c.

◆ PAE_ADDR_TO_PAGE_TABLE

#define PAE_ADDR_TO_PAGE_TABLE (   v)    (((ULONG)(v)) / (512 * PAGE_SIZE))

Definition at line 161 of file pagepae.c.

◆ PAE_ADDR_TO_PDE

#define PAE_ADDR_TO_PDE (   v)
Value:
((((ULONG_PTR)(v)) / (512 * 512))&(~0x7)))
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
#define PAE_PAGEDIRECTORY_MAP
Definition: pagepae.c:37
uint32_t ULONG_PTR
Definition: typedefs.h:65

Definition at line 163 of file pagepae.c.

◆ PAE_ADDR_TO_PDE_OFFSET

#define PAE_ADDR_TO_PDE_OFFSET (   v)    (((ULONG_PTR)(v))/ (512 * PAGE_SIZE))

Definition at line 172 of file pagepae.c.

◆ PAE_ADDR_TO_PDE_PAGE_OFFSET

#define PAE_ADDR_TO_PDE_PAGE_OFFSET (   v)    ((((ULONG_PTR)(v)) % (512 * 512 * PAGE_SIZE)) / (512 * PAGE_SIZE))

Definition at line 170 of file pagepae.c.

◆ PAE_ADDR_TO_PDTE_OFFSET

#define PAE_ADDR_TO_PDTE_OFFSET (   v)    (((ULONG_PTR)(v)) / (512 * 512 * PAGE_SIZE))

Definition at line 168 of file pagepae.c.

◆ PAE_ADDR_TO_PTE

#define PAE_ADDR_TO_PTE (   v)    (PULONGLONG) (PTE_BASE + ((((ULONG_PTR)(v) / 512))&(~0x7)))

Definition at line 165 of file pagepae.c.

◆ PAE_ADDR_TO_PTE_OFFSET

#define PAE_ADDR_TO_PTE_OFFSET (   v)    ((((ULONG_PTR)(v)) % (512 * PAGE_SIZE)) / PAGE_SIZE)

Definition at line 174 of file pagepae.c.

◆ PAE_PAGE_MASK

#define PAE_PAGE_MASK (   x)    ((x)&(~0xfffLL))

Definition at line 52 of file pagepae.c.

◆ PAE_PAGEDIRECTORY_MAP

#define PAE_PAGEDIRECTORY_MAP   (0xc0000000 + (PTE_BASE / (512)))

Definition at line 37 of file pagepae.c.

◆ PAE_PFN_TO_PTE

#define PAE_PFN_TO_PTE (   X)    ((X) << PAGE_SHIFT)

Definition at line 49 of file pagepae.c.

◆ PAE_PTE_TO_PFN

#define PAE_PTE_TO_PFN (   X)    (PAE_PAGE_MASK(X) >> PAGE_SHIFT)

Definition at line 48 of file pagepae.c.

◆ PAGE_MASK

#define PAGE_MASK (   x)    ((x)&(~0xfff))

Definition at line 51 of file pagepae.c.

◆ PAGEDIRECTORY_MAP

#define PAGEDIRECTORY_MAP   (0xc0000000 + (PTE_BASE / (1024)))

Definition at line 36 of file pagepae.c.

◆ PFN_TO_PTE

#define PFN_TO_PTE (   X)    ((X) << PAGE_SHIFT)

Definition at line 46 of file pagepae.c.

◆ PTE_TO_PFN

#define PTE_TO_PFN (   X)    ((X) >> PAGE_SHIFT)

Definition at line 45 of file pagepae.c.

Function Documentation

◆ MiFlushTlb()

VOID MiFlushTlb ( PULONG  Pt,
PVOID  Address 
)

Definition at line 81 of file pagepae.c.

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}
__INTRIN_INLINE void __invlpg(void *Address)
Definition: intrin_x86.h:1968
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
#define MmSystemRangeStart
Definition: mm.h:32
ULONG_PTR NTAPI KeIpiGenericCall(_In_ PKIPI_BROADCAST_WORKER Function, _In_ ULONG_PTR Argument)
Definition: ipi.c:44
BOOLEAN MmUnmapPageTable(PULONG Pt)
Definition: pagepae.c:530
ULONG_PTR NTAPI MiFlushTlbIpiRoutine(ULONG_PTR Address)
Definition: pagepae.c:63
static WCHAR Address[46]
Definition: ping.c:68

Referenced by MmCreatePageFileMapping(), MmCreateVirtualMappingUnsafe(), MmDeletePageFileMapping(), MmDeleteVirtualMapping(), MmFreePageTable(), MmSetCleanPage(), MmSetDirtyPage(), and MmSetPageProtect().

◆ MiFlushTlbIpiRoutine()

ULONG_PTR NTAPI MiFlushTlbIpiRoutine ( ULONG_PTR  Address)

Definition at line 63 of file pagepae.c.

64{
65 if (Address == (ULONGLONG)-1)
66 {
68 }
69 else if (Address == (ULONGLONG)-2)
70 {
72 }
73 else
74 {
76 }
77 return 0;
78}
VOID NTAPI KeFlushCurrentTb(VOID)
Definition: cpu.c:526
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by MiFlushTlb().

◆ MmCreatePageFileMapping()

NTSTATUS NTAPI MmCreatePageFileMapping ( PEPROCESS  Process,
PVOID  Address,
SWAPENTRY  SwapEntry 
)

Definition at line 1058 of file pagepae.c.

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}
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#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
#define ASSERT(a)
Definition: mode.c:44
#define ADDR_TO_PAGE_TABLE(v)
Definition: pagepae.c:150
#define PTE_TO_PFN(X)
Definition: pagepae.c:45
static PULONG MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: pagepae.c:435
static PULONGLONG MmGetPageTableForProcessForPAE(PEPROCESS Process, PVOID Address, BOOLEAN Create)
Definition: pagepae.c:321
#define PAGE_MASK(x)
Definition: pagepae.c:51
BOOLEAN Ke386Pae
Definition: cpu.c:35
VOID MiFlushTlb(PULONG Pt, PVOID Address)
Definition: pagepae.c:81
#define PAE_PAGE_MASK(x)
Definition: pagepae.c:52
#define PAE_ADDR_TO_PAGE_TABLE(v)
Definition: pagepae.c:161
#define PAE_PTE_TO_PFN(X)
Definition: pagepae.c:48
#define STATUS_SUCCESS
Definition: shellext.h:65
uint16_t * PUSHORT
Definition: typedefs.h:56

◆ MmCreateProcessAddressSpace()

BOOLEAN NTAPI MmCreateProcessAddressSpace ( IN ULONG  MinWs,
IN PEPROCESS  Process,
IN PLARGE_INTEGER  DirectoryTableBase 
)

Definition at line 178 of file pagepae.c.

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}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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 memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define PTE_BASE
Definition: mmx86.c:14
int Count
Definition: noreturn.cpp:7
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 PAE_PFN_TO_PTE(X)
Definition: pagepae.c:49
#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
#define PAE_ADDR_TO_PDE_PAGE_OFFSET(v)
Definition: pagepae.c:170
#define HYPERSPACE
Definition: pagepae.c:39
static ULONG MmGlobalKernelPageDirectory[1024]
Definition: pagepae.c:42
#define PA_READWRITE
Definition: pagepae.c:28
#define PAE_ADDR_TO_PDTE_OFFSET(v)
Definition: pagepae.c:168
#define PFN_TO_PTE(X)
Definition: pagepae.c:46
ULONG PFN_NUMBER
Definition: ke.h:9
#define DPRINT
Definition: sndvol32.h:71

◆ MmCreateVirtualMapping()

NTSTATUS NTAPI MmCreateVirtualMapping ( PEPROCESS  Process,
PVOID  Address,
ULONG  flProtect,
PPFN_NUMBER  Pages,
ULONG  PageCount 
)

Definition at line 1352 of file pagepae.c.

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}
BOOLEAN NTAPI MmIsPageInUse(PFN_NUMBER Page)
Definition: freelist.c:558
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(PEPROCESS Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
Definition: pagepae.c:1146

◆ MmCreateVirtualMappingUnsafe()

NTSTATUS NTAPI MmCreateVirtualMappingUnsafe ( PEPROCESS  Process,
PVOID  Address,
ULONG  flProtect,
PPFN_NUMBER  Pages,
ULONG  PageCount 
)

Definition at line 1146 of file pagepae.c.

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}
unsigned char BOOLEAN
#define PAGE_SIZE
Definition: env_spec_w32.h:49
static ULONG ProtectToPTE(ULONG flProtect)
Definition: pagepae.c:105
#define PAE_ADDR_TO_PDE_OFFSET(v)
Definition: pagepae.c:172
#define PA_USER
Definition: pagepae.c:29
#define PA_GLOBAL
Definition: pagepae.c:34
#define LL
Definition: tui.h:167
void * PVOID
Definition: typedefs.h:50
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes

Referenced by MmCreateVirtualMapping().

◆ MmDeletePageFileMapping()

VOID NTAPI MmDeletePageFileMapping ( PEPROCESS  Process,
PVOID  Address,
SWAPENTRY SwapEntry 
)

Definition at line 747 of file pagepae.c.

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}
VOID NTAPI MmFreePageTable(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:258

◆ MmDeleteVirtualMapping()

VOID NTAPI MmDeleteVirtualMapping ( PEPROCESS  Process,
PVOID  Address,
BOOLEAN WasDirty,
PPFN_NUMBER  Page 
)

Definition at line 613 of file pagepae.c.

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}
_In_ PVOID _Out_opt_ BOOLEAN * WasDirty
Definition: mm.h:1304
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
#define PA_DIRTY
Definition: pagepae.c:30

◆ MmFreePageTable()

VOID NTAPI MmFreePageTable ( PEPROCESS  Process,
PVOID  Address 
)

Definition at line 258 of file pagepae.c.

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}
#define DbgPrint
Definition: hal.h:12
#define PAGE_ROUND_DOWN(x)
Definition: mmtypes.h:36
#define ADDR_TO_PDE(v)
Definition: pagepae.c:152
#define ADDR_TO_PTE(v)
Definition: pagepae.c:154
#define PAE_ADDR_TO_PDE(v)
Definition: pagepae.c:163
#define PAE_ADDR_TO_PTE(v)
Definition: pagepae.c:165
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:43
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by MmDeletePageFileMapping(), and MmDeleteVirtualMapping().

◆ MmGetPageEntryForProcess()

static ULONG MmGetPageEntryForProcess ( PEPROCESS  Process,
PVOID  Address 
)
static

Definition at line 568 of file pagepae.c.

569{
570 ULONG Pte;
571 PULONG Pt;
572
574 if (Pt)
575 {
576 Pte = *Pt;
578 return Pte;
579 }
580 return 0;
581}

Referenced by MmGetPageProtect(), MmGetPfnForProcess(), MmIsDirtyPage(), MmIsPagePresent(), and MmIsPageSwapEntry().

◆ MmGetPageEntryForProcessForPAE()

static ULONGLONG MmGetPageEntryForProcessForPAE ( PEPROCESS  Process,
PVOID  Address 
)
static

Definition at line 553 of file pagepae.c.

554{
555 ULONGLONG Pte;
556 PULONGLONG Pt;
557
559 if (Pt)
560 {
561 Pte = *Pt;
563 return Pte;
564 }
565 return 0;
566}

Referenced by MmGetPageProtect(), MmGetPfnForProcess(), MmIsDirtyPage(), MmIsPagePresent(), and MmIsPageSwapEntry().

◆ MmGetPageProtect()

ULONG NTAPI MmGetPageProtect ( PEPROCESS  Process,
PVOID  Address 
)

Definition at line 1378 of file pagepae.c.

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}
#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_WRITETHROUGH
Definition: mm.h:109
#define PAGE_SYSTEM
Definition: mm.h:110
static ULONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:568
static ULONGLONG MmGetPageEntryForProcessForPAE(PEPROCESS Process, PVOID Address)
Definition: pagepae.c:553
#define PA_WT
Definition: pagepae.c:31
#define PA_CD
Definition: pagepae.c:32
base of all file and directory entries
Definition: entries.h:83
_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

◆ MmGetPageTableForProcess()

static PULONG MmGetPageTableForProcess ( PEPROCESS  Process,
PVOID  Address,
BOOLEAN  Create 
)
static

Definition at line 435 of file pagepae.c.

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}
@ Create
Definition: registry.c:563
#define InterlockedCompareExchangeUL(Destination, Exchange, Comperand)
Definition: ex.h:1536
#define ADDR_TO_PTE_OFFSET(v)
Definition: pagepae.c:158
ULONG LowPart
Definition: typedefs.h:106

Referenced by MmCreatePageFileMapping(), MmCreateVirtualMappingUnsafe(), MmDeletePageFileMapping(), MmDeleteVirtualMapping(), MmGetPageEntryForProcess(), Mmi386MakeKernelPageTableGlobal(), MmSetCleanPage(), MmSetDirtyPage(), and MmSetPageProtect().

◆ MmGetPageTableForProcessForPAE()

static PULONGLONG MmGetPageTableForProcessForPAE ( PEPROCESS  Process,
PVOID  Address,
BOOLEAN  Create 
)
static

Definition at line 321 of file pagepae.c.

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}
#define ExfInterlockedCompareExchange64UL(Destination, Exchange, Comperand)
Definition: ex.h:1550
#define PAE_ADDR_TO_PTE_OFFSET(v)
Definition: pagepae.c:174
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by MmCreatePageFileMapping(), MmCreateVirtualMappingUnsafe(), MmDeletePageFileMapping(), MmDeleteVirtualMapping(), MmGetPageEntryForProcessForPAE(), Mmi386MakeKernelPageTableGlobal(), MmSetCleanPage(), MmSetDirtyPage(), and MmSetPageProtect().

◆ MmGetPfnForProcess()

PFN_NUMBER NTAPI MmGetPfnForProcess ( PEPROCESS  Process,
PVOID  Address 
)

Definition at line 585 of file pagepae.c.

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}

◆ Mmi386MakeKernelPageTableGlobal()

BOOLEAN Mmi386MakeKernelPageTableGlobal ( PVOID  PAddress)

Definition at line 844 of file pagepae.c.

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}

Referenced by MmAccessFault().

◆ MmInitGlobalKernelPageDirectory()

VOID NTAPI MmInitGlobalKernelPageDirectory ( VOID  )

Definition at line 1494 of file pagepae.c.

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}

Referenced by MmInitSystem().

◆ MmIsDirtyPage()

BOOLEAN NTAPI MmIsDirtyPage ( PEPROCESS  Process,
PVOID  Address 
)

Definition at line 886 of file pagepae.c.

887{
888 if (Ke386Pae)
889 {
891 }
892 else
893 {
895 }
896}

◆ MmIsPagePresent()

BOOLEAN NTAPI MmIsPagePresent ( PEPROCESS  Process,
PVOID  Address 
)

Definition at line 1026 of file pagepae.c.

1027{
1028 if (Ke386Pae)
1029 {
1031 }
1032 else
1033 {
1035 }
1036}

◆ MmIsPageSwapEntry()

BOOLEAN NTAPI MmIsPageSwapEntry ( PEPROCESS  Process,
PVOID  Address 
)

Definition at line 1040 of file pagepae.c.

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}

◆ MmSetCleanPage()

VOID NTAPI MmSetCleanPage ( PEPROCESS  Process,
PVOID  Address 
)

Definition at line 900 of file pagepae.c.

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}

◆ MmSetDirtyPage()

VOID NTAPI MmSetDirtyPage ( PEPROCESS  Process,
PVOID  Address 
)

Definition at line 965 of file pagepae.c.

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}

◆ MmSetPageProtect()

VOID NTAPI MmSetPageProtect ( PEPROCESS  Process,
PVOID  Address,
ULONG  flProtect 
)

Definition at line 1424 of file pagepae.c.

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}
#define InterlockedExchange
Definition: armddk.h:54
#define PA_ACCESSED
Definition: pagepae.c:33
int32_t * PLONG
Definition: typedefs.h:58

◆ MmUnmapPageTable()

BOOLEAN MmUnmapPageTable ( PULONG  Pt)

Definition at line 530 of file pagepae.c.

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}

Referenced by MiFlushTlb(), MmCreatePageFileMapping(), MmCreateVirtualMappingUnsafe(), MmGetPageEntryForProcess(), MmGetPageEntryForProcessForPAE(), MmSetCleanPage(), and MmSetDirtyPage().

◆ ProtectToPTE()

static ULONG ProtectToPTE ( ULONG  flProtect)
static

Definition at line 105 of file pagepae.c.

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}
#define PAGE_GUARD
Definition: nt_native.h:1310
#define PAGE_IS_WRITABLE
Definition: mm.h:153
#define PAGE_IS_EXECUTABLE
Definition: mm.h:159
#define PAGE_IS_READABLE
Definition: mm.h:145
BOOLEAN Ke386NoExecute
Definition: cpu.c:36

Referenced by MmCreateVirtualMappingUnsafe(), and MmSetPageProtect().

Variable Documentation

◆ Ke386NoExecute

BOOLEAN Ke386NoExecute
extern

Definition at line 36 of file cpu.c.

Referenced by ProtectToPTE().

◆ Ke386Pae

◆ MmGlobalKernelPageDirectory

ULONG MmGlobalKernelPageDirectory[1024]
static

◆ MmGlobalKernelPageDirectoryForPAE

ULONGLONG MmGlobalKernelPageDirectoryForPAE[2048]
static