ReactOS  0.4.13-dev-259-g5ca9c9c
MmReservedMapping.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS kernel-mode tests
3  * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE: Kernel-Mode Test Suite Reserved Mapping test
5  * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 
10 #ifdef _M_IX86
11 
12 #define PTE_BASE 0xC0000000
13 #define MiAddressToPte(x) \
14  ((PMMPTE)(((((ULONG)(x)) >> 12) << 2) + PTE_BASE))
15 #define MiPteToAddress(_Pte) ((PVOID)((ULONG)(_Pte) << 10))
16 
17 #elif defined(_M_AMD64)
18 
19 #define PTI_SHIFT 12L
20 #define PTE_BASE 0xFFFFF68000000000ULL
21 PMMPTE
24 {
26  Offset &= 0xFFFFFFFFFULL << 3;
27  return (PMMPTE)(PTE_BASE + Offset);
28 }
29 #define MiAddressToPte(x) _MiAddressToPte((PVOID)(x))
30 
31 #endif
32 
33 static
36 PMDL
37 (NTAPI
38 *pMmAllocatePagesForMdlEx)(
39  _In_ PHYSICAL_ADDRESS LowAddress,
44  _In_ ULONG Flags);
45 
46 static
47 BOOLEAN
48 ValidateMapping(
50  _In_ ULONG TotalPtes,
52  _In_ ULONG ValidPtes,
53  _In_ PPFN_NUMBER Pfns)
54 {
55  BOOLEAN Valid = TRUE;
56 #if defined(_M_IX86) || defined(_M_AMD64)
57  PMMPTE PointerPte;
58  ULONG i;
59 
60  PointerPte = MiAddressToPte(BaseAddress);
61  for (i = 0; i < ValidPtes; i++)
62  {
63  Valid = Valid &&
64  ok(PointerPte[i].u.Hard.Valid == 1,
65  "[%lu] PTE %p is not valid\n", i, &PointerPte[i]);
66 
67  Valid = Valid &&
68  ok(PointerPte[i].u.Hard.PageFrameNumber == Pfns[i],
69  "[%lu] PTE %p has PFN %Ix, expected %Ix\n",
70  i, &PointerPte[i], PointerPte[i].u.Hard.PageFrameNumber, Pfns[i]);
71  }
72  for (; i < TotalPtes; i++)
73  {
74  Valid = Valid &&
75  ok_eq_hex(PointerPte[i].u.Long, 0UL);
76  }
77  Valid = Valid &&
78  ok_eq_tag(PointerPte[-1].u.Long, PoolTag & ~1);
79  Valid = Valid &&
80  ok_eq_ulong(PointerPte[-2].u.Long, (TotalPtes + 2) * 2);
81 #endif
82 
83  return Valid;
84 }
85 
86 static
87 VOID
90  _In_ ULONG TotalPtes,
92 {
93  PMDL Mdl;
94  PHYSICAL_ADDRESS ZeroPhysical;
95  PHYSICAL_ADDRESS MaxPhysical;
97  PPFN_NUMBER MdlPages;
98  ULONG i;
99 
100  if (skip(pMmAllocatePagesForMdlEx != NULL, "MmAllocatePagesForMdlEx unavailable\n"))
101  {
102  return;
103  }
104 
105  ZeroPhysical.QuadPart = 0;
106  MaxPhysical.QuadPart = 0xffffffffffffffffLL;
107 
108  /* Create a one-page MDL and map it */
109  Mdl = pMmAllocatePagesForMdlEx(ZeroPhysical,
110  MaxPhysical,
111  ZeroPhysical,
112  PAGE_SIZE,
113  MmCached,
114  0);
115  if (skip(Mdl != NULL, "No MDL\n"))
116  {
117  return;
118  }
119 
120  MdlPages = (PVOID)(Mdl + 1);
121 
123  PoolTag,
124  Mdl,
125  MmCached);
126  ok(BaseAddress != NULL, "MmMapLockedPagesWithReservedMapping failed\n");
127  if (!skip(BaseAddress != NULL, "Failed to map MDL\n"))
128  {
130 
131  ok_bool_true(ValidateMapping(BaseAddress, TotalPtes, PoolTag, 1, MdlPages),
132  "ValidateMapping returned");
133 
134  KmtStartSeh()
135  *(volatile ULONG *)BaseAddress = 0x01234567;
137 
139  PoolTag,
140  Mdl);
141 
142  ok_bool_true(ValidateMapping(Mapping, TotalPtes, PoolTag, 0, NULL),
143  "ValidateMapping returned");
144  }
145 
146  /* Try again but at an unaligned address */
148  PoolTag,
149  Mdl,
150  MmCached);
151  ok(BaseAddress != NULL, "MmMapLockedPagesWithReservedMapping failed\n");
152  if (!skip(BaseAddress != NULL, "Failed to map MDL\n"))
153  {
155 
156  ok_bool_true(ValidateMapping(BaseAddress, TotalPtes, PoolTag, 1, MdlPages),
157  "ValidateMapping returned");
158 
159  KmtStartSeh()
160  *(volatile ULONG *)BaseAddress = 0x01234567;
162 
164  PoolTag,
165  Mdl);
166 
167  ok_bool_true(ValidateMapping(Mapping, TotalPtes, PoolTag, 0, NULL),
168  "ValidateMapping returned");
169  }
170 
171  MmFreePagesFromMdl(Mdl);
172 
173  /* Map all pages */
174  Mdl = pMmAllocatePagesForMdlEx(ZeroPhysical,
175  MaxPhysical,
176  ZeroPhysical,
177  TotalPtes * PAGE_SIZE,
178  MmCached,
179  0);
180  if (skip(Mdl != NULL, "No MDL\n"))
181  {
182  return;
183  }
184 
185  MdlPages = (PVOID)(Mdl + 1);
186 
188  PoolTag,
189  Mdl,
190  MmCached);
191  ok(BaseAddress != NULL, "MmMapLockedPagesWithReservedMapping failed\n");
192  if (!skip(BaseAddress != NULL, "Failed to map MDL\n"))
193  {
195 
196  ok_bool_true(ValidateMapping(BaseAddress, TotalPtes, PoolTag, TotalPtes, MdlPages),
197  "ValidateMapping returned");
198 
199  for (i = 0; i < TotalPtes; i++)
200  {
201  KmtStartSeh()
202  *((volatile ULONG *)BaseAddress + i * PAGE_SIZE / sizeof(ULONG)) = 0x01234567;
204  }
205 
207  PoolTag,
208  Mdl);
209 
210  ok_bool_true(ValidateMapping(Mapping, TotalPtes, PoolTag, 0, NULL),
211  "ValidateMapping returned");
212  }
213 
214  MmFreePagesFromMdl(Mdl);
215 
216  /* Try to map more pages than we reserved */
217  Mdl = pMmAllocatePagesForMdlEx(ZeroPhysical,
218  MaxPhysical,
219  ZeroPhysical,
220  (TotalPtes + 1) * PAGE_SIZE,
221  MmCached,
222  0);
223  if (skip(Mdl != NULL, "No MDL\n"))
224  {
225  return;
226  }
227 
229  PoolTag,
230  Mdl,
231  MmCached);
233  if (BaseAddress)
234  {
236  PoolTag,
237  Mdl);
238  }
239 
240  MmFreePagesFromMdl(Mdl);
241 }
242 
243 START_TEST(MmReservedMapping)
244 {
245  PVOID Mapping;
246 
247  pMmAllocatePagesForMdlEx = KmtGetSystemRoutineAddress(L"MmAllocatePagesForMdlEx");
248 
249  /* one byte - single page */
250  Mapping = MmAllocateMappingAddress(1, 'MRmK');
251  ok(Mapping != NULL, "MmAllocateMappingAddress failed\n");
252  if (!skip(Mapping != NULL, "No mapping\n"))
253  {
254  ok_bool_true(ValidateMapping(Mapping, 1, 'MRmK', 0, NULL),
255  "ValidateMapping returned");
256 
257  MmFreeMappingAddress(Mapping, 'MRmK');
258  }
259 
260  /* 10 pages */
261  Mapping = MmAllocateMappingAddress(10 * PAGE_SIZE, 'MRmK' & ~1);
262  ok(Mapping != NULL, "MmAllocateMappingAddress failed\n");
263  if (!skip(Mapping != NULL, "No mapping\n"))
264  {
265  ok_bool_true(ValidateMapping(Mapping, 10, 'MRmK', 0, NULL),
266  "ValidateMapping returned");
267 
268  /* PAGE_FAULT_IN_NONPAGED_AREA can't be caught with SEH */
269  if (0)
270  {
271  (void)*(volatile UCHAR *)Mapping;
272  }
273 
274  TestMap(Mapping, 10, 'MRmK');
275 
276  MmFreeMappingAddress(Mapping, 'MRmK');
277  }
278 
279  /* PoolTag = 0 */
281  ok(Mapping == NULL, "MmAllocateMappingAddress failed\n");
282  if (Mapping != NULL)
283  {
285  }
286 
287  /* PoolTag = 1 */
289  ok(Mapping != NULL, "MmAllocateMappingAddress failed\n");
290  if (Mapping != NULL)
291  {
292  ok_bool_true(ValidateMapping(Mapping, 1, 1, 0, NULL),
293  "ValidateMapping returned");
294 
295  TestMap(Mapping, 1, 1);
296 
298  }
299 
300  /* Free an unaligned address */
302  ok(Mapping != NULL, "MmAllocateMappingAddress failed\n");
303  if (Mapping != NULL)
304  {
305  ok_bool_true(ValidateMapping(Mapping, 1, 'MRmK', 0, NULL),
306  "ValidateMapping returned");
307 
308  TestMap(Mapping, 1, 'MRmK');
309 
310  MmFreeMappingAddress((PUCHAR)Mapping + sizeof(ULONG), 'MRmK');
311  }
312 }
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 * u
Definition: glfuncs.h:240
#define ok_eq_ulong(value, expected)
#define _Must_inspect_result_
Definition: no_sal2.h:314
#define TRUE
Definition: types.h:120
#define LL
Definition: tui.h:72
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static _Must_inspect_result_ _IRQL_requires_max_(DISPATCH_LEVEL)
union _MMPTE::@2227 u
#define ok_eq_pointer(value, expected)
static PVOID Mapping[EMS_PHYSICAL_PAGES]
Definition: emsdrv.c:41
unsigned char * PUCHAR
Definition: retypes.h:3
#define KmtEndSeh(ExpectedStatus)
Definition: kmt_test.h:283
PVOID PMDL
Definition: usb.h:39
#define ok_bool_true(value, desc)
Definition: kmt_test.h:256
ULONG * PPFN_NUMBER
Definition: ke.h:8
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
#define MiAddressToPte(x)
Definition: mmx86.c:19
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
VOID NTAPI MmFreePagesFromMdl(IN PMDL Mdl)
Definition: mdlsup.c:568
#define ok(value,...)
_Must_inspect_result_ _In_ LPCGUID ULONG _In_ FSRTL_ALLOCATE_ECP_FLAGS _In_opt_ PFSRTL_EXTRA_CREATE_PARAMETER_CLEANUP_CALLBACK _In_ ULONG PoolTag
Definition: fltkernel.h:2520
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS _In_ MEMORY_CACHING_TYPE CacheType
Definition: mmfuncs.h:214
static WCHAR Address[46]
Definition: ping.c:68
#define ok_eq_tag(value, expected)
Definition: kmt_test.h:263
#define FORCEINLINE
Definition: ntbasedef.h:221
#define PTI_SHIFT
void * PVOID
Definition: retypes.h:9
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
#define ULL(a, b)
Definition: format_msg.c:27
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
PMMPTE FORCEINLINE _MiAddressToPte(PVOID Address)
Definition: mm.h:129
PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
unsigned __int64 ULONG64
Definition: imports.h:198
unsigned char UCHAR
Definition: xmlstorage.h:181
static const WCHAR L[]
Definition: oid.c:1250
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PTE_BASE
Definition: mmx86.c:14
#define KmtStartSeh()
Definition: kmt_test.h:277
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define _In_
Definition: no_sal2.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:78
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
START_TEST(MmReservedMapping)
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS HighAddress
Definition: mmfuncs.h:226
PVOID NTAPI MmMapLockedPagesWithReservedMapping(IN PVOID MappingAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList, IN MEMORY_CACHING_TYPE CacheType)
Definition: mdlsup.c:1633
#define skip(...)
unsigned int ULONG
Definition: retypes.h:1
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define ok_eq_hex(value, expected)
VOID NTAPI MmUnmapReservedMapping(IN PVOID BaseAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList)
Definition: mdlsup.c:1647
static VOID TestMap(_In_ PVOID Mapping, _In_ ULONG TotalPtes, _In_ ULONG PoolTag)
enum _MEMORY_CACHING_TYPE MEMORY_CACHING_TYPE
return STATUS_SUCCESS
Definition: btrfs.c:2745
#define UL
Definition: tui.h:70
PVOID NTAPI MmAllocateMappingAddress(IN SIZE_T NumberOfBytes, IN ULONG PoolTag)
Definition: pool.c:1389
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_ SIZE_T TotalBytes
Definition: mmfuncs.h:226
LONGLONG QuadPart
Definition: typedefs.h:112
VOID NTAPI MmFreeMappingAddress(IN PVOID BaseAddress, IN ULONG PoolTag)
Definition: pool.c:1401