2e437f239301d881f21cb71608881f04f9494c12
[reactos.git] / rostests / kmtests / ntos_mm / MmReservedMapping.c
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
22 FORCEINLINE
23 _MiAddressToPte(PVOID Address)
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
34 BOOLEAN
35 ValidateMapping(
36 _In_ PVOID BaseAddress,
37 _In_ ULONG TotalPtes,
38 _In_ ULONG ValidPtes,
39 _In_ PPFN_NUMBER Pfns)
40 {
41 BOOLEAN Valid = TRUE;
42 #if defined(_M_IX86) || defined(_M_AMD64)
43 PMMPTE PointerPte;
44 ULONG i;
45
46 PointerPte = MiAddressToPte(BaseAddress);
47 for (i = 0; i < ValidPtes; i++)
48 {
49 Valid = Valid &&
50 ok(PointerPte[i].u.Hard.Valid == 1,
51 "[%lu] PTE %p is not valid\n", i, &PointerPte[i]);
52
53 Valid = Valid &&
54 ok(PointerPte[i].u.Hard.PageFrameNumber == Pfns[i],
55 "[%lu] PTE %p has PFN %Ix, expected %Ix\n",
56 i, &PointerPte[i], PointerPte[i].u.Hard.PageFrameNumber, Pfns[i]);
57 }
58 for (; i < TotalPtes; i++)
59 {
60 Valid = Valid &&
61 ok_eq_hex(PointerPte[i].u.Long, 0UL);
62 }
63 Valid = Valid &&
64 ok_eq_tag(PointerPte[-1].u.Long, 'MRmK' & ~1);
65 Valid = Valid &&
66 ok_eq_ulong(PointerPte[-2].u.Long, (TotalPtes + 2) * 2);
67 #endif
68
69 return Valid;
70 }
71
72 static
73 VOID
74 TestMap(
75 _In_ PVOID Mapping)
76 {
77 PMDL Mdl;
78 PHYSICAL_ADDRESS ZeroPhysical;
79 PHYSICAL_ADDRESS MaxPhysical;
80 PVOID BaseAddress;
81 PPFN_NUMBER MdlPages;
82 ULONG i;
83
84 ZeroPhysical.QuadPart = 0;
85 MaxPhysical.QuadPart = 0xffffffffffffffffLL;
86
87 /* Create a one-page MDL and map it */
88 Mdl = MmAllocatePagesForMdlEx(ZeroPhysical,
89 MaxPhysical,
90 ZeroPhysical,
91 PAGE_SIZE,
92 MmCached,
93 0);
94 if (skip(Mdl != NULL, "No MDL\n"))
95 {
96 return;
97 }
98
99 MdlPages = (PVOID)(Mdl + 1);
100
101 BaseAddress = MmMapLockedPagesWithReservedMapping(Mapping,
102 'MRmK',
103 Mdl,
104 MmCached);
105 if (BaseAddress)
106 {
107 ok_eq_pointer(BaseAddress, Mapping);
108
109 ok_bool_true(ValidateMapping(BaseAddress, 10, 1, MdlPages),
110 "ValidateMapping returned");
111
112 KmtStartSeh()
113 *(volatile ULONG *)BaseAddress = 0x01234567;
114 KmtEndSeh(STATUS_SUCCESS);
115
116 MmUnmapReservedMapping(BaseAddress,
117 'MRmK',
118 Mdl);
119
120 ok_bool_true(ValidateMapping(Mapping, 10, 0, NULL),
121 "ValidateMapping returned");
122 }
123
124 MmFreePagesFromMdl(Mdl);
125
126 /* Map all pages */
127 Mdl = MmAllocatePagesForMdlEx(ZeroPhysical,
128 MaxPhysical,
129 ZeroPhysical,
130 10 * PAGE_SIZE,
131 MmCached,
132 0);
133 if (skip(Mdl != NULL, "No MDL\n"))
134 {
135 return;
136 }
137
138 MdlPages = (PVOID)(Mdl + 1);
139
140 BaseAddress = MmMapLockedPagesWithReservedMapping(Mapping,
141 'MRmK',
142 Mdl,
143 MmCached);
144 if (BaseAddress)
145 {
146 ok_eq_pointer(BaseAddress, Mapping);
147
148 ok_bool_true(ValidateMapping(BaseAddress, 10, 10, MdlPages),
149 "ValidateMapping returned");
150
151 for (i = 0; i < 10; i++)
152 {
153 KmtStartSeh()
154 *((volatile ULONG *)BaseAddress + i * PAGE_SIZE / sizeof(ULONG)) = 0x01234567;
155 KmtEndSeh(STATUS_SUCCESS);
156 }
157
158 MmUnmapReservedMapping(BaseAddress,
159 'MRmK',
160 Mdl);
161
162 ok_bool_true(ValidateMapping(Mapping, 10, 0, NULL),
163 "ValidateMapping returned");
164 }
165
166 MmFreePagesFromMdl(Mdl);
167
168 /* Try to map more pages than we reserved */
169 Mdl = MmAllocatePagesForMdlEx(ZeroPhysical,
170 MaxPhysical,
171 ZeroPhysical,
172 11 * PAGE_SIZE,
173 MmCached,
174 0);
175 if (skip(Mdl != NULL, "No MDL\n"))
176 {
177 return;
178 }
179
180 BaseAddress = MmMapLockedPagesWithReservedMapping(Mapping,
181 'MRmK',
182 Mdl,
183 MmCached);
184 ok_eq_pointer(BaseAddress, NULL);
185 if (BaseAddress)
186 {
187 MmUnmapReservedMapping(BaseAddress,
188 'MRmK',
189 Mdl);
190 }
191
192 MmFreePagesFromMdl(Mdl);
193 }
194
195 START_TEST(MmReservedMapping)
196 {
197 PVOID Mapping;
198
199 /* one byte - single page */
200 Mapping = MmAllocateMappingAddress(1, 'MRmK');
201 ok(Mapping != NULL, "MmAllocateMappingAddress failed\n");
202 if (!skip(Mapping != NULL, "No mapping\n"))
203 {
204 ok_bool_true(ValidateMapping(Mapping, 1, 0, NULL),
205 "ValidateMapping returned");
206
207 MmFreeMappingAddress(Mapping, 'MRmK');
208 }
209
210 /* 10 pages */
211 Mapping = MmAllocateMappingAddress(10 * PAGE_SIZE, 'MRmK' & ~1);
212 ok(Mapping != NULL, "MmAllocateMappingAddress failed\n");
213 if (!skip(Mapping != NULL, "No mapping\n"))
214 {
215 ok_bool_true(ValidateMapping(Mapping, 10, 0, NULL),
216 "ValidateMapping returned");
217
218 /* PAGE_FAULT_IN_NONPAGED_AREA can't be caught with SEH */
219 if (0)
220 {
221 (void)*(volatile UCHAR *)Mapping;
222 }
223
224 TestMap(Mapping);
225
226 MmFreeMappingAddress(Mapping, 'MRmK');
227 }
228 }