ReactOS 0.4.17-dev-1190-g4c812f4
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)
 
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:395
#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:2000
#define MmSystemRangeStart
Definition: mm.h:34
ULONG_PTR NTAPI KeIpiGenericCall(_In_ PKIPI_BROADCAST_WORKER Function, _In_ ULONG_PTR Argument)
Definition: ipi.c:44
CCHAR KeNumberProcessors
Definition: processor.c:19
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(), 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:361
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by MiFlushTlb().

◆ MmCreatePageFileMapping()

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

Definition at line 932 of file pagepae.c.

935{
937 {
938 DPRINT1("No process\n");
939 ASSERT(FALSE);
940 }
942 {
943 DPRINT1("Setting kernel address with process context\n");
944 ASSERT(FALSE);
945 }
946 if (SwapEntry & (1 << 31))
947 {
948 ASSERT(FALSE);
949 }
950
951 if (Ke386Pae)
952 {
953 PULONGLONG Pt;
954 ULONGLONG Pte;
955 ULONGLONG tmpPte;
956
958 if (Pt == NULL)
959 {
960 ASSERT(FALSE);
961 }
962 tmpPte = SwapEntry << 1;
963 Pte = ExfpInterlockedExchange64UL(Pt, &tmpPte);
964 if (PAE_PAGE_MASK((Pte)) != 0)
965 {
966 MmMarkPageUnmapped(PAE_PTE_TO_PFN((Pte)));
967 }
968
969 if (Pte != 0)
970 {
972 }
973 else
974 {
976 }
977 }
978 else
979 {
980 PULONG Pt;
981 ULONG Pte;
982
984 if (Pt == NULL)
985 {
986 ASSERT(FALSE);
987 }
988 Pte = *Pt;
989 if (PAGE_MASK((Pte)) != 0)
990 {
991 MmMarkPageUnmapped(PTE_TO_PFN((Pte)));
992 }
993 (void)InterlockedExchangeUL(Pt, SwapEntry << 1);
994 if (Pte != 0)
995 {
996 MiFlushTlb(Pt, Address);
997 }
998 else
999 {
1000 MmUnmapPageTable(Pt);
1001 }
1002 }
1003 if (Process != NULL &&
1004 ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
1006 {
1007 PUSHORT Ptrc;
1008 ULONG Idx;
1009
1010 Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
1012 Ptrc[Idx]++;
1013 }
1014 return(STATUS_SUCCESS);
1015}
#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:1547
_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}
ULONG_PTR PFN_NUMBER
#define PTE_BASE
Definition: winldr.c:20
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:24
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
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
#define DPRINT
Definition: sndvol32.h:73

◆ MmCreateVirtualMapping()

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

Definition at line 1226 of file pagepae.c.

1231{
1232 ULONG i;
1233
1234 for (i = 0; i < PageCount; i++)
1235 {
1236 if (!MmIsPageInUse(Pages[i]))
1237 {
1238 DPRINT1("Page at address %x not in use\n", PFN_TO_PTE(Pages[i]));
1239 ASSERT(FALSE);
1240 }
1241 }
1242
1244 Address,
1245 flProtect,
1246 Pages,
1247 PageCount));
1248}
BOOLEAN NTAPI MmIsPageInUse(PFN_NUMBER Page)
Definition: freelist.c:559
NTSTATUS NTAPI MmCreateVirtualMappingUnsafe(PEPROCESS Process, PVOID Address, ULONG flProtect, PPFN_NUMBER Pages, ULONG PageCount)
Definition: pagepae.c:1020

◆ MmCreateVirtualMappingUnsafe()

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

Definition at line 1020 of file pagepae.c.

1025{
1027 PVOID Addr;
1028 ULONG i;
1029 ULONG oldPdeOffset, PdeOffset;
1030 BOOLEAN NoExecute = FALSE;
1031
1032 DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
1033 Process, Address, flProtect, Pages, *Pages, PageCount);
1034
1035 if (Process == NULL)
1036 {
1038 {
1039 DPRINT1("No process\n");
1040 ASSERT(FALSE);
1041 }
1042 if (PageCount > 0x10000 ||
1043 (ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000)
1044 {
1045 DPRINT1("Page count to large\n");
1046 ASSERT(FALSE);
1047 }
1048 }
1049 else
1050 {
1052 {
1053 DPRINT1("Setting kernel address with process context\n");
1054 ASSERT(FALSE);
1055 }
1056 if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE ||
1057 (ULONG_PTR) Address / PAGE_SIZE + PageCount >
1059 {
1060 DPRINT1("Page Count to large\n");
1061 ASSERT(FALSE);
1062 }
1063 }
1064
1065 Attributes = ProtectToPTE(flProtect);
1066 if (Attributes & 0x80000000)
1067 {
1068 NoExecute = TRUE;
1069 }
1070 Attributes &= 0xfff;
1072 {
1073 Attributes &= ~PA_USER;
1074 if (Ke386GlobalPagesEnabled)
1075 {
1077 }
1078 }
1079 else
1080 {
1082 }
1083
1084 Addr = Address;
1085
1086 if (Ke386Pae)
1087 {
1088 ULONGLONG Pte, tmpPte;
1089 PULONGLONG Pt = NULL;
1090
1091 oldPdeOffset = PAE_ADDR_TO_PDE_OFFSET(Addr) + 1;
1092 for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
1093 {
1094 if (!(Attributes & PA_PRESENT) && Pages[i] != 0)
1095 {
1096 DPRINT1("Setting physical address but not allowing access at address "
1097 "0x%.8X with attributes %x/%x.\n",
1098 Addr, Attributes, flProtect);
1099 ASSERT(FALSE);
1100 }
1101 PdeOffset = PAE_ADDR_TO_PDE_OFFSET(Addr);
1102 if (oldPdeOffset != PdeOffset)
1103 {
1106 if (Pt == NULL)
1107 {
1108 ASSERT(FALSE);
1109 }
1110 }
1111 else
1112 {
1113 Pt++;
1114 }
1115 oldPdeOffset = PdeOffset;
1116
1117 MmMarkPageMapped(Pages[i]);
1118 tmpPte = PAE_PFN_TO_PTE(Pages[i]) | Attributes;
1119 if (NoExecute)
1120 {
1121 tmpPte |= 0x8000000000000000LL;
1122 }
1123 Pte = ExfpInterlockedExchange64UL(Pt, &tmpPte);
1124 if (PAE_PAGE_MASK((Pte)) != 0LL && !((Pte) & PA_PRESENT))
1125 {
1126 ASSERT(FALSE);
1127 }
1128 if (PAE_PAGE_MASK((Pte)) != 0LL)
1129 {
1130 MmMarkPageUnmapped(PAE_PTE_TO_PFN((Pte)));
1131 }
1133 ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
1135 {
1136 PUSHORT Ptrc;
1137
1138 Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
1139
1140 Ptrc[PAE_ADDR_TO_PAGE_TABLE(Addr)]++;
1141 }
1142 if (Pte != 0LL)
1143 {
1145 (Pt >= (PULONGLONG)PTE_BASE && Pt < (PULONGLONG)PTE_BASE + 4*512*512))
1146 {
1148 }
1149 }
1150 }
1151 if (Addr > Address)
1152 {
1154 }
1155 }
1156 else
1157 {
1158 PULONG Pt = NULL;
1159 ULONG Pte;
1160 oldPdeOffset = ADDR_TO_PDE_OFFSET(Addr) + 1;
1161 for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
1162 {
1163 if (!(Attributes & PA_PRESENT) && Pages[i] != 0)
1164 {
1165 DPRINT1("Setting physical address but not allowing access at address "
1166 "0x%.8X with attributes %x/%x.\n",
1167 Addr, Attributes, flProtect);
1168 ASSERT(FALSE);
1169 }
1170 PdeOffset = ADDR_TO_PDE_OFFSET(Addr);
1171 if (oldPdeOffset != PdeOffset)
1172 {
1173 MmUnmapPageTable(Pt);
1175 if (Pt == NULL)
1176 {
1177 ASSERT(FALSE);
1178 }
1179 }
1180 else
1181 {
1182 Pt++;
1183 }
1184 oldPdeOffset = PdeOffset;
1185
1186 Pte = *Pt;
1187 MmMarkPageMapped(Pages[i]);
1188 if (PAGE_MASK((Pte)) != 0 && !((Pte) & PA_PRESENT))
1189 {
1190 ASSERT(FALSE);
1191 }
1192 if (PAGE_MASK((Pte)) != 0)
1193 {
1194 MmMarkPageUnmapped(PTE_TO_PFN((Pte)));
1195 }
1198 ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
1200 {
1201 PUSHORT Ptrc;
1202
1203 Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
1204
1205 Ptrc[ADDR_TO_PAGE_TABLE(Addr)]++;
1206 }
1207 if (Pte != 0)
1208 {
1210 (Pt >= (PULONG)PTE_BASE && Pt < (PULONG)PTE_BASE + 1024*1024))
1211 {
1212 MiFlushTlb(Pt, Address);
1213 }
1214 }
1215 }
1216 if (Addr > Address)
1217 {
1218 MmUnmapPageTable(Pt);
1219 }
1220 }
1221 return(STATUS_SUCCESS);
1222}
unsigned char BOOLEAN
Definition: actypes.h:127
_In_ ULONG Attributes
Definition: dispmprt.h:1077
#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

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:1285
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1287
#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 1252 of file pagepae.c.

1253{
1254 ULONG Entry;
1255 ULONG Protect;
1256 if (Ke386Pae)
1257 {
1259 }
1260 else
1261 {
1263 }
1264
1265 if (!(Entry & PA_PRESENT))
1266 {
1268 }
1269 else
1270 {
1271 if (Entry & PA_READWRITE)
1272 {
1274 }
1275 else
1276 {
1278 }
1279 if (Entry & PA_CD)
1280 {
1282 }
1283 if (Entry & PA_WT)
1284 {
1286 }
1287 if (!(Entry & PA_USER))
1288 {
1289 Protect |= PAGE_SYSTEM;
1290 }
1291
1292 }
1293 return(Protect);
1294}
#define PAGE_NOCACHE
Definition: nt_native.h:1314
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1310
#define PAGE_NOACCESS
Definition: nt_native.h:1305
#define PAGE_WRITETHROUGH
Definition: mm.h:106
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
Entry
Definition: section.c:5216
static int Protect(const char **args)
Definition: vfdcmd.c:2132

◆ 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:1553
#define ADDR_TO_PTE_OFFSET(v)
Definition: pagepae.c:158
ULONG LowPart
Definition: typedefs.h:106

Referenced by MmCreatePageFileMapping(), MmCreateVirtualMappingUnsafe(), MmDeletePageFileMapping(), MmDeleteVirtualMapping(), MmGetPageEntryForProcess(), Mmi386MakeKernelPageTableGlobal(), 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:1567
#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(), 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 1368 of file pagepae.c.

1369{
1370 ULONG i;
1371
1372 DPRINT("MmInitGlobalKernelPageDirectory()\n");
1373
1374 if (Ke386Pae)
1375 {
1376 PULONGLONG CurrentPageDirectory = (PULONGLONG)PAE_PAGEDIRECTORY_MAP;
1377 for (i = PAE_ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i < 4 * 512; i++)
1378 {
1381 0LL == MmGlobalKernelPageDirectoryForPAE[i] && 0LL != CurrentPageDirectory[i])
1382 {
1383 (void)ExfpInterlockedExchange64UL(&MmGlobalKernelPageDirectoryForPAE[i], &CurrentPageDirectory[i]);
1384 if (Ke386GlobalPagesEnabled)
1385 {
1387 CurrentPageDirectory[i] |= PA_GLOBAL;
1388 }
1389 }
1390 }
1391 }
1392 else
1393 {
1394 PULONG CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP;
1395 for (i = ADDR_TO_PDE_OFFSET(MmSystemRangeStart); i < 1024; i++)
1396 {
1397 if (i != ADDR_TO_PDE_OFFSET(PTE_BASE) &&
1399 0 == MmGlobalKernelPageDirectory[i] && 0 != CurrentPageDirectory[i])
1400 {
1401 MmGlobalKernelPageDirectory[i] = CurrentPageDirectory[i];
1402 if (Ke386GlobalPagesEnabled)
1403 {
1405 CurrentPageDirectory[i] |= PA_GLOBAL;
1406 }
1407 }
1408 }
1409 }
1410}

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 900 of file pagepae.c.

901{
902 if (Ke386Pae)
903 {
905 }
906 else
907 {
909 }
910}

◆ MmIsPageSwapEntry()

BOOLEAN NTAPI MmIsPageSwapEntry ( PEPROCESS  Process,
PVOID  Address 
)

Definition at line 914 of file pagepae.c.

915{
916 if (Ke386Pae)
917 {
920 return !(Entry & PA_PRESENT) && Entry != 0 ? TRUE : FALSE;
921 }
922 else
923 {
924 ULONG Entry;
926 return !(Entry & PA_PRESENT) && Entry != 0 ? TRUE : FALSE;
927 }
928}

◆ MmSetPageProtect()

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

Definition at line 1298 of file pagepae.c.

1299{
1300 ULONG Attributes = 0;
1301 BOOLEAN NoExecute = FALSE;
1302
1303 DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n",
1304 Process, Address, flProtect);
1305
1306 Attributes = ProtectToPTE(flProtect);
1307 if (Attributes & 0x80000000)
1308 {
1309 NoExecute = TRUE;
1310 }
1311 Attributes &= 0xfff;
1313 {
1314 Attributes &= ~PA_USER;
1315 if (Ke386GlobalPagesEnabled)
1316 {
1318 }
1319 }
1320 else
1321 {
1323 }
1324 if (Ke386Pae)
1325 {
1326 PULONGLONG Pt;
1327 ULONGLONG tmpPte, Pte;
1328
1330 if (Pt == NULL)
1331 {
1332 DPRINT1("Address %x\n", Address);
1333 ASSERT(FALSE);
1334 }
1335 do
1336 {
1337 Pte = *Pt;
1338 tmpPte = PAE_PAGE_MASK(Pte) | Attributes | (Pte & (PA_ACCESSED|PA_DIRTY));
1339 if (NoExecute)
1340 {
1341 tmpPte |= 0x8000000000000000LL;
1342 }
1343 else
1344 {
1345 tmpPte &= ~0x8000000000000000LL;
1346 }
1347 } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
1348
1350 }
1351 else
1352 {
1353 PULONG Pt;
1354
1356 if (Pt == NULL)
1357 {
1358 ASSERT(FALSE);
1359 }
1361 MiFlushTlb(Pt, Address);
1362 }
1363}
#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(), and MmGetPageEntryForProcessForPAE().

◆ 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:1313
#define PAGE_IS_WRITABLE
Definition: mm.h:155
#define PAGE_IS_EXECUTABLE
Definition: mm.h:161
#define PAGE_IS_READABLE
Definition: mm.h:147
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