ReactOS  r76032
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 {
25  ULONG64 Offset = (ULONG64)Address >> (PTI_SHIFT - 3);
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 
122  BaseAddress = MmMapLockedPagesWithReservedMapping(Mapping,
123  PoolTag,
124  Mdl,
125  MmCached);
126  ok(BaseAddress != NULL, "MmMapLockedPagesWithReservedMapping failed\n");
127  if (!skip(BaseAddress != NULL, "Failed to map MDL\n"))
128  {
129  ok_eq_pointer(BaseAddress, Mapping);
130 
131  ok_bool_true(ValidateMapping(BaseAddress, TotalPtes, PoolTag, 1, MdlPages),
132  "ValidateMapping returned");
133 
134  KmtStartSeh()
135  *(volatile ULONG *)BaseAddress = 0x01234567;
137 
138  MmUnmapReservedMapping(BaseAddress,
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 */
147  BaseAddress = MmMapLockedPagesWithReservedMapping((PUCHAR)Mapping + sizeof(ULONG),
148  PoolTag,
149  Mdl,
150  MmCached);
151  ok(BaseAddress != NULL, "MmMapLockedPagesWithReservedMapping failed\n");
152  if (!skip(BaseAddress != NULL, "Failed to map MDL\n"))
153  {
154  ok_eq_pointer(BaseAddress, (PUCHAR)Mapping + sizeof(ULONG));
155 
156  ok_bool_true(ValidateMapping(BaseAddress, TotalPtes, PoolTag, 1, MdlPages),
157  "ValidateMapping returned");
158 
159  KmtStartSeh()
160  *(volatile ULONG *)BaseAddress = 0x01234567;
162 
163  MmUnmapReservedMapping(BaseAddress,
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 
187  BaseAddress = MmMapLockedPagesWithReservedMapping(Mapping,
188  PoolTag,
189  Mdl,
190  MmCached);
191  ok(BaseAddress != NULL, "MmMapLockedPagesWithReservedMapping failed\n");
192  if (!skip(BaseAddress != NULL, "Failed to map MDL\n"))
193  {
194  ok_eq_pointer(BaseAddress, Mapping);
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 
206  MmUnmapReservedMapping(BaseAddress,
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 
228  BaseAddress = MmMapLockedPagesWithReservedMapping(Mapping,
229  PoolTag,
230  Mdl,
231  MmCached);
232  ok_eq_pointer(BaseAddress, NULL);
233  if (BaseAddress)
234  {
235  MmUnmapReservedMapping(BaseAddress,
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 */
280  Mapping = MmAllocateMappingAddress(1, 0);
281  ok(Mapping == NULL, "MmAllocateMappingAddress failed\n");
282  if (Mapping != NULL)
283  {
284  MmFreeMappingAddress(Mapping, 0);
285  }
286 
287  /* PoolTag = 1 */
288  Mapping = MmAllocateMappingAddress(1, 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 
297  MmFreeMappingAddress(Mapping, 1);
298  }
299 
300  /* Free an unaligned address */
301  Mapping = MmAllocateMappingAddress(PAGE_SIZE, 'MRmK');
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 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define ok_eq_ulong(value, expected)
#define _Must_inspect_result_
Definition: no_sal2.h:314
#define TRUE
Definition: types.h:120
PVOID ULONG Address
Definition: oprghdlr.h:14
#define LL
Definition: tui.h:72
Definition: bidi.c:75
static _Must_inspect_result_ _IRQL_requires_max_(DISPATCH_LEVEL)
return STATUS_SUCCESS
Definition: btrfs.c:2664
#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:238
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble * u
Definition: glfuncs.h:88
PVOID PMDL
Definition: usb.h:39
#define ok_bool_true(value, desc)
Definition: kmt_test.h:211
ULONG * PPFN_NUMBER
Definition: ke.h:8
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#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
uint64_t ULONG64
Definition: typedefs.h:65
VOID NTAPI MmFreePagesFromMdl(IN PMDL Mdl)
Definition: mdlsup.c:538
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
_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
smooth NULL
Definition: ftsmooth.c:557
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS _In_opt_ PHYSICAL_ADDRESS _In_ MEMORY_CACHING_TYPE CacheType
Definition: mmfuncs.h:214
#define ok_eq_tag(value, expected)
Definition: kmt_test.h:218
#define FORCEINLINE
Definition: ntbasedef.h:213
#define PTI_SHIFT
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
#define ULL(a, b)
Definition: format_msg.c:27
unsigned char BOOLEAN
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
PMMPTE FORCEINLINE _MiAddressToPte(PVOID Address)
Definition: mm.h:116
PVOID KmtGetSystemRoutineAddress(IN PCWSTR RoutineName)
unsigned char UCHAR
Definition: xmlstorage.h:181
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PTE_BASE
Definition: mmx86.c:14
#define KmtStartSeh()
Definition: kmt_test.h:232
#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
#define skip(...)
Definition: CString.cpp:57
PVOID NTAPI MmMapLockedPagesWithReservedMapping(IN PVOID MappingAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList, IN MEMORY_CACHING_TYPE CacheType)
Definition: mdlsup.c:1603
unsigned int ULONG
Definition: retypes.h:1
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
#define ok(value,...)
Definition: CImage.cpp:33
#define ok_eq_hex(value, expected)
union _MMPTE::@2072 u
VOID NTAPI MmUnmapReservedMapping(IN PVOID BaseAddress, IN ULONG PoolTag, IN PMDL MemoryDescriptorList)
Definition: mdlsup.c:1617
static VOID TestMap(_In_ PVOID Mapping, _In_ ULONG TotalPtes, _In_ ULONG PoolTag)
enum _MEMORY_CACHING_TYPE MEMORY_CACHING_TYPE
#define UL
Definition: tui.h:70
PVOID NTAPI MmAllocateMappingAddress(IN SIZE_T NumberOfBytes, IN ULONG PoolTag)
Definition: pool.c:1387
_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:1399