ReactOS 0.4.15-dev-8348-gc1b9bb5
sptab.c File Reference
#include <ntoskrnl.h>
#include "newmm.h"
#include <debug.h>
Include dependency graph for sptab.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define DPRINTC   DPRINT
 

Functions

 _Function_class_ (RTL_GENERIC_ALLOCATE_ROUTINE)
 
 _Function_class_ (RTL_GENERIC_FREE_ROUTINE)
 
 _Function_class_ (RTL_GENERIC_COMPARE_ROUTINE)
 
static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGet (PRTL_GENERIC_TABLE Table, PLARGE_INTEGER FileOffset)
 
static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGetOrAllocate (PRTL_GENERIC_TABLE Table, PLARGE_INTEGER FileOffset)
 
VOID NTAPI MiInitializeSectionPageTable (PMM_SECTION_SEGMENT Segment)
 
NTSTATUS NTAPI _MmSetPageEntrySectionSegment (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, ULONG_PTR Entry, const char *file, int line)
 
ULONG_PTR NTAPI _MmGetPageEntrySectionSegment (PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset, const char *file, int line)
 
VOID NTAPI MmFreePageTablesSectionSegment (PMM_SECTION_SEGMENT Segment, FREE_SECTION_PAGE_FUN FreePage)
 
PMM_SECTION_SEGMENT NTAPI MmGetSectionAssociation (PFN_NUMBER Page, PLARGE_INTEGER Offset)
 
NTSTATUS NTAPI MmSetSectionAssociation (PFN_NUMBER Page, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
 

Variables

KSPIN_LOCK MiSectionPageTableLock
 

Macro Definition Documentation

◆ DPRINTC

#define DPRINTC   DPRINT

Definition at line 61 of file sptab.c.

◆ NDEBUG

#define NDEBUG

Definition at line 58 of file sptab.c.

Function Documentation

◆ _Function_class_() [1/3]

_Function_class_ ( RTL_GENERIC_ALLOCATE_ROUTINE  )

Definition at line 67 of file sptab.c.

72{
75 //DPRINT("MiSectionPageTableAllocate(%d) => %p\n", Bytes, Result);
76 return Result;
77}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
_In_ UINT Bytes
Definition: mmcopy.h:9
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

◆ _Function_class_() [2/3]

_Function_class_ ( RTL_GENERIC_COMPARE_ROUTINE  )

Definition at line 89 of file sptab.c.

96{
97 PLARGE_INTEGER A = PtrA, B = PtrB;
98 BOOLEAN Result = (A->QuadPart < B->QuadPart) ? GenericLessThan :
99 (A->QuadPart == B->QuadPart) ? GenericEqual : GenericGreaterThan;
100
101#if 0
102 DPRINT
103 ("Compare: %08x%08x vs %08x%08x => %s\n",
104 A->u.HighPart, A->u.LowPart,
105 B->u.HighPart, B->u.LowPart,
106 Result == GenericLessThan ? "GenericLessThan" :
107 Result == GenericGreaterThan ? "GenericGreaterThan" :
108 "GenericEqual");
109#endif
110
111 return Result;
112}
unsigned char BOOLEAN
Definition: ehthrow.cxx:93
Definition: ehthrow.cxx:54
#define DPRINT
Definition: sndvol32.h:73
@ GenericLessThan
Definition: rtltypes.h:389
@ GenericEqual
Definition: rtltypes.h:391
@ GenericGreaterThan
Definition: rtltypes.h:390

◆ _Function_class_() [3/3]

_Function_class_ ( RTL_GENERIC_FREE_ROUTINE  )

Definition at line 79 of file sptab.c.

84{
85 //DPRINT("MiSectionPageTableFree(%p)\n", Data);
86 ExFreePoolWithTag(Data, 'tPmM');
87}
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109

◆ _MmGetPageEntrySectionSegment()

ULONG_PTR NTAPI _MmGetPageEntrySectionSegment ( PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  Offset,
const char file,
int  line 
)

Definition at line 280 of file sptab.c.

284{
286 ULONG_PTR PageIndex, Result;
288
289 ASSERT(Segment->Locked);
290 FileOffset.QuadPart = ROUND_DOWN(Offset->QuadPart,
293 if (!PageTable) return 0;
294 PageIndex = (ULONG_PTR)((Offset->QuadPart - PageTable->FileOffset.QuadPart) / PAGE_SIZE);
295 Result = PageTable->PageEntries[PageIndex];
296#if 0
297 DPRINTC
298 ("MiGetPageEntrySectionSegment(%p,%08x%08x) => %x %s:%d\n",
299 Segment,
300 FileOffset.u.HighPart,
301 FileOffset.u.LowPart + PageIndex * PAGE_SIZE,
302 Result,
303 file, line);
304#endif
305 return Result;
306}
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define ROUND_DOWN(n, align)
Definition: eventvwr.h:33
#define ASSERT(a)
Definition: mode.c:44
#define ENTRIES_PER_ELEMENT
Definition: newmm.h:21
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define DPRINTC
Definition: sptab.c:61
static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGet(PRTL_GENERIC_TABLE Table, PLARGE_INTEGER FileOffset)
Definition: sptab.c:117
Definition: fci.c:127
Definition: parser.c:49
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:43
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Inout_ PVOID Segment
Definition: exfuncs.h:1101

◆ _MmSetPageEntrySectionSegment()

NTSTATUS NTAPI _MmSetPageEntrySectionSegment ( PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  Offset,
ULONG_PTR  Entry,
const char file,
int  line 
)

Definition at line 178 of file sptab.c.

183{
184 ULONG_PTR PageIndex, OldEntry;
186
187 ASSERT(Segment->Locked);
189
191
192 if (!PageTable) return STATUS_NO_MEMORY;
193
195
196 PageTable->Segment = Segment;
197 PageIndex = (ULONG_PTR)((Offset->QuadPart - PageTable->FileOffset.QuadPart) / PAGE_SIZE);
198 OldEntry = PageTable->PageEntries[PageIndex];
199
200 DPRINT("MiSetPageEntrySectionSegment(%p,%08x%08x,%x=>%x)\n",
201 Segment,
202 Offset->u.HighPart,
203 Offset->u.LowPart,
204 OldEntry,
205 Entry);
206
207 /* Manage ref on segment */
208 if (Entry && !OldEntry)
209 {
210 InterlockedIncrement64(Segment->ReferenceCount);
211 }
212 if (OldEntry && !Entry)
213 {
214 MmDereferenceSegment(Segment);
215 }
216
218 {
219 /* We have a valid entry. See if we must do something */
220 if (OldEntry && !IS_SWAP_FROM_SSE(OldEntry))
221 {
222 /* The previous entry was valid. Shall we swap the Rmaps ? */
223 if (PFN_FROM_SSE(Entry) != PFN_FROM_SSE(OldEntry))
224 {
226
227 /* This has to be done before setting the new section association
228 to prevent a race condition with the paging out path */
229 PageTable->PageEntries[PageIndex] = Entry;
230
232 }
233 else
234 {
235 PageTable->PageEntries[PageIndex] = Entry;
236 }
237 }
238 else
239 {
240 /*
241 * We're switching to a valid entry from an invalid one.
242 * Add the Rmap and take a ref on the segment.
243 */
244 PageTable->PageEntries[PageIndex] = Entry;
246
247 if (Offset->QuadPart >= (Segment->LastPage << PAGE_SHIFT))
248 Segment->LastPage = (Offset->QuadPart >> PAGE_SHIFT) + 1;
249 }
250 }
251 else if (OldEntry && !IS_SWAP_FROM_SSE(OldEntry))
252 {
253 /* We're switching to an invalid entry from a valid one */
255 PageTable->PageEntries[PageIndex] = Entry;
256
257 if (Offset->QuadPart == ((Segment->LastPage - 1ULL) << PAGE_SHIFT))
258 {
259 /* We are unsetting the last page */
260 while (--Segment->LastPage)
261 {
262 LARGE_INTEGER CheckOffset;
263 CheckOffset.QuadPart = (Segment->LastPage - 1) << PAGE_SHIFT;
265 if ((Entry != 0) && !IS_SWAP_FROM_SSE(Entry))
266 break;
267 }
268 }
269 }
270 else
271 {
272 PageTable->PageEntries[PageIndex] = Entry;
273 }
274
275 return STATUS_SUCCESS;
276}
#define InterlockedIncrement64(a)
Definition: btrfs_drv.h:143
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
VOID NTAPI MmDeleteSectionAssociation(PFN_NUMBER Page)
Definition: rmap.c:506
#define MmGetPageEntrySectionSegment(S, O)
Definition: mm.h:1602
#define IS_DIRTY_SSE(E)
Definition: mm.h:1377
#define PFN_FROM_SSE(E)
Definition: mm.h:1368
#define IS_SWAP_FROM_SSE(E)
Definition: mm.h:1369
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_SUCCESS
Definition: shellext.h:65
static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGetOrAllocate(PRTL_GENERIC_TABLE Table, PLARGE_INTEGER FileOffset)
Definition: sptab.c:136
NTSTATUS NTAPI MmSetSectionAssociation(PFN_NUMBER Page, PMM_SECTION_SEGMENT Segment, PLARGE_INTEGER Offset)
Definition: sptab.c:400
base of all file and directory entries
Definition: entries.h:83
LONGLONG QuadPart
Definition: typedefs.h:114

◆ MiInitializeSectionPageTable()

VOID NTAPI MiInitializeSectionPageTable ( PMM_SECTION_SEGMENT  Segment)

Definition at line 165 of file sptab.c.

166{
168 MiSectionPageTableCompare,
169 MiSectionPageTableAllocate,
170 MiSectionPageTableFree,
171 NULL);
172
173 DPRINT("MiInitializeSectionPageTable(%p)\n", &Segment->PageTable);
174}
#define NULL
Definition: types.h:112
VOID NTAPI RtlInitializeGenericTable(IN PRTL_GENERIC_TABLE Table, IN PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine, IN PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine, IN PRTL_GENERIC_FREE_ROUTINE FreeRoutine, IN PVOID TableContext)
Definition: generictable.c:100

Referenced by ExeFmtpCreateImageSection(), MmCreateDataFileSection(), and MmCreatePhysicalMemorySection().

◆ MiSectionPageTableGet()

static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGet ( PRTL_GENERIC_TABLE  Table,
PLARGE_INTEGER  FileOffset 
)
static

Definition at line 117 of file sptab.c.

119{
120 LARGE_INTEGER SearchFileOffset;
122 SearchFileOffset.QuadPart = ROUND_DOWN(FileOffset->QuadPart,
124 PageTable = RtlLookupElementGenericTable(Table, &SearchFileOffset);
125
126 DPRINT("MiSectionPageTableGet(%p,%I64x)\n",
127 Table,
128 FileOffset->QuadPart);
129
130 return PageTable;
131}
ASMGENDATA Table[]
Definition: genincdata.c:61
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlLookupElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ PVOID Buffer)

Referenced by _MmGetPageEntrySectionSegment(), _MmSetPageEntrySectionSegment(), MiSectionPageTableGetOrAllocate(), and MmSetSectionAssociation().

◆ MiSectionPageTableGetOrAllocate()

static PCACHE_SECTION_PAGE_TABLE NTAPI MiSectionPageTableGetOrAllocate ( PRTL_GENERIC_TABLE  Table,
PLARGE_INTEGER  FileOffset 
)
static

Definition at line 136 of file sptab.c.

138{
139 LARGE_INTEGER SearchFileOffset;
140 CACHE_SECTION_PAGE_TABLE SectionZeroPageTable;
142 FileOffset);
143 /* Please zero memory when taking away zero initialization. */
144 RtlZeroMemory(&SectionZeroPageTable, sizeof(CACHE_SECTION_PAGE_TABLE));
145 if (!PageTableSlice)
146 {
147 SearchFileOffset.QuadPart = ROUND_DOWN(FileOffset->QuadPart,
149 SectionZeroPageTable.FileOffset = SearchFileOffset;
150 SectionZeroPageTable.Refcount = 1;
151 PageTableSlice = RtlInsertElementGenericTable(Table,
152 &SectionZeroPageTable,
153 sizeof(SectionZeroPageTable),
154 NULL);
155 if (!PageTableSlice) return NULL;
156 DPRINT("Allocate page table %p (%I64x)\n",
157 PageTableSlice,
158 PageTableSlice->FileOffset.QuadPart);
159 }
160 return PageTableSlice;
161}
LARGE_INTEGER FileOffset
Definition: newmm.h:27
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
NTSYSAPI PVOID NTAPI RtlInsertElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_reads_bytes_(BufferSize) PVOID Buffer, _In_ CLONG BufferSize, _Out_opt_ PBOOLEAN NewElement)

Referenced by _MmSetPageEntrySectionSegment().

◆ MmFreePageTablesSectionSegment()

VOID NTAPI MmFreePageTablesSectionSegment ( PMM_SECTION_SEGMENT  Segment,
FREE_SECTION_PAGE_FUN  FreePage 
)

Definition at line 321 of file sptab.c.

323{
325 DPRINT("MiFreePageTablesSectionSegment(%p)\n", &Segment->PageTable);
326 while ((Element = RtlGetElementGenericTable(&Segment->PageTable, 0))) {
327 DPRINT("Delete table for <%wZ> %p -> %I64x\n",
328 Segment->FileObject ? &Segment->FileObject->FileName : NULL,
329 Segment,
330 Element->FileOffset.QuadPart);
331 if (FreePage)
332 {
333 ULONG i;
334 for (i = 0; i < ENTRIES_PER_ELEMENT; i++)
335 {
338 Offset.QuadPart = Element->FileOffset.QuadPart + i * PAGE_SIZE;
339 Entry = Element->PageEntries[i];
341 {
342 DPRINT("Freeing page %p:%Ix @ %I64x\n",
343 Segment,
344 Entry,
345 Offset.QuadPart);
346
348 }
349 }
350 }
351 DPRINT("Remove memory\n");
352 RtlDeleteElementGenericTable(&Segment->PageTable, Element);
353 }
354 DPRINT("Done\n");
355}
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
ULONG_PTR PageEntries[ENTRIES_PER_ELEMENT]
Definition: newmm.h:30
uint32_t ULONG
Definition: typedefs.h:59
@ FreePage
Definition: ketypes.h:416
NTSYSAPI BOOLEAN NTAPI RtlDeleteElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ PVOID Buffer)
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlGetElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ ULONG I)

Referenced by _When_().

◆ MmGetSectionAssociation()

PMM_SECTION_SEGMENT NTAPI MmGetSectionAssociation ( PFN_NUMBER  Page,
PLARGE_INTEGER  Offset 
)

Definition at line 374 of file sptab.c.

376{
377 ULONG RawOffset;
380
381 KIRQL OldIrql = MiAcquirePfnLock();
382
383 PageTable = MmGetSegmentRmap(Page, &RawOffset);
384 if (PageTable)
385 {
386 Segment = PageTable->Segment;
387 Offset->QuadPart = PageTable->FileOffset.QuadPart +
388 ((ULONG64)RawOffset << PAGE_SHIFT);
389 ASSERT(PFN_FROM_SSE(PageTable->PageEntries[RawOffset]) == Page);
390 InterlockedIncrement64(Segment->ReferenceCount);
391 }
392
393 MiReleasePfnLock(OldIrql);
394
395 return Segment;
396}
UCHAR KIRQL
Definition: env_spec_w32.h:591
unsigned __int64 ULONG64
Definition: imports.h:198
PVOID NTAPI MmGetSegmentRmap(PFN_NUMBER Page, PULONG RawOffset)
Definition: rmap.c:468
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1306
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by MiShutdownSystem(), MmPageOutPhysicalAddress(), and MmpPageOutPhysicalAddress().

◆ MmSetSectionAssociation()

NTSTATUS NTAPI MmSetSectionAssociation ( PFN_NUMBER  Page,
PMM_SECTION_SEGMENT  Segment,
PLARGE_INTEGER  Offset 
)

Definition at line 400 of file sptab.c.

403{
405 ULONG ActualOffset;
406
409
410 ActualOffset = (ULONG)(Offset->QuadPart - PageTable->FileOffset.QuadPart);
413 (PVOID)(RMAP_SEGMENT_MASK | (ActualOffset >> PAGE_SHIFT)));
414
415 return STATUS_SUCCESS;
416}
#define RMAP_SEGMENT_MASK
Definition: mm.h:939
VOID NTAPI MmInsertRmap(PFN_NUMBER Page, struct _EPROCESS *Process, PVOID Address)

Referenced by _MmSetPageEntrySectionSegment().

Variable Documentation

◆ MiSectionPageTableLock

KSPIN_LOCK MiSectionPageTableLock
extern