[KMTESTS:MM]
[reactos.git] / rostests / kmtests / ntos_mm / MmMdl.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 MDL test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <kmt_test.h>
9
10 static
11 VOID
12 TestMmAllocatePagesForMdl(VOID)
13 {
14 PMDL Mdl;
15 PHYSICAL_ADDRESS LowAddress;
16 PHYSICAL_ADDRESS HighAddress;
17 PHYSICAL_ADDRESS SkipBytes;
18 PVOID SystemVa;
19 PMDL Mdls[32];
20 PVOID SystemVas[32];
21 ULONG i;
22 PPFN_NUMBER MdlPages;
23 ULONG MdlPageCount;
24
25 LowAddress.QuadPart = 0;
26 HighAddress.QuadPart = -1;
27 SkipBytes.QuadPart = 0;
28 /* simple allocate/free */
29 Mdl = MmAllocatePagesForMdl(LowAddress,
30 HighAddress,
31 SkipBytes,
32 2 * 1024 * 1024);
33 ok(Mdl != NULL, "MmAllocatePagesForMdl failed\n");
34 if (skip(Mdl != NULL, "No Mdl\n"))
35 return;
36 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
37 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
38 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
39 MdlPages = MmGetMdlPfnArray(Mdl);
40 MdlPageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Mdl), MmGetMdlByteCount(Mdl));
41 ok(MdlPageCount == 2 * 1024 * 1024 / PAGE_SIZE, "MdlPageCount = %lu\n", MdlPageCount);
42 for (i = 0; i < MdlPageCount; i++)
43 {
44 ok(MdlPages[i] != 0 && MdlPages[i] != (PFN_NUMBER)-1,
45 "MdlPages[%lu] = 0x%I64x\n", i, (ULONGLONG)MdlPages[i]);
46 }
47 MmFreePagesFromMdl(Mdl);
48 ExFreePoolWithTag(Mdl, 0);
49
50 /* Now map/unmap it */
51 Mdl = MmAllocatePagesForMdl(LowAddress,
52 HighAddress,
53 SkipBytes,
54 2 * 1024 * 1024);
55 ok(Mdl != NULL, "MmAllocatePagesForMdl failed\n");
56 if (skip(Mdl != NULL, "No Mdl\n"))
57 return;
58 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
59 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
60 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
61 SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
62 KernelMode,
63 MmCached,
64 NULL,
65 FALSE,
66 NormalPagePriority);
67 ok(SystemVa != NULL, "MmMapLockedPagesSpecifyCache failed\n");
68 if (!skip(SystemVa != NULL, "No system VA\n"))
69 {
70 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
71 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p, System VA: %p\n", MmGetMdlVirtualAddress(Mdl), SystemVa);
72 ok(Mdl->MappedSystemVa == SystemVa, "MappedSystemVa: %p, System VA: %p\n", Mdl->MappedSystemVa, SystemVa);
73 ok((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
74 MmUnmapLockedPages(SystemVa, Mdl);
75 }
76 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
77 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
78 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
79 MmFreePagesFromMdl(Mdl);
80 ExFreePoolWithTag(Mdl, 0);
81
82 /* Now map it, and free without unmapping */
83 Mdl = MmAllocatePagesForMdl(LowAddress,
84 HighAddress,
85 SkipBytes,
86 2 * 1024 * 1024);
87 ok(Mdl != NULL, "MmAllocatePagesForMdl failed\n");
88 if (skip(Mdl != NULL, "No Mdl\n"))
89 return;
90 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
91 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
92 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
93 SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
94 KernelMode,
95 MmCached,
96 NULL,
97 FALSE,
98 NormalPagePriority);
99 ok(SystemVa != NULL, "MmMapLockedPagesSpecifyCache failed\n");
100 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
101 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p, System VA: %p\n", MmGetMdlVirtualAddress(Mdl), SystemVa);
102 ok(Mdl->MappedSystemVa == SystemVa, "MappedSystemVa: %p, System VA: %p\n", Mdl->MappedSystemVa, SystemVa);
103 ok((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
104 MmFreePagesFromMdl(Mdl);
105 ExFreePoolWithTag(Mdl, 0);
106
107 /* try to allocate 2 GB -- should succeed but not map */
108 Mdl = MmAllocatePagesForMdl(LowAddress,
109 HighAddress,
110 SkipBytes,
111 2UL * 1024 * 1024 * 1024);
112 ok(Mdl != NULL, "MmAllocatePagesForMdl failed for 2 GB\n");
113 if (Mdl != NULL)
114 {
115 ok(MmGetMdlByteCount(Mdl) != 2UL * 1024 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
116 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
117 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
118 MdlPages = MmGetMdlPfnArray(Mdl);
119 MdlPageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Mdl), MmGetMdlByteCount(Mdl));
120 ok(MdlPageCount < 2UL * 1024 * 1024 * 1024 / PAGE_SIZE, "MdlPageCount = %lu\n", MdlPageCount);
121 for (i = 0; i < MdlPageCount; i++)
122 {
123 if (MdlPages[i] == 0 ||
124 MdlPages[i] == (PFN_NUMBER)-1)
125 {
126 ok(0, "MdlPages[%lu] = 0x%I64x\n", i, (ULONGLONG)MdlPages[i]);
127 }
128 }
129 SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
130 KernelMode,
131 MmCached,
132 NULL,
133 FALSE,
134 NormalPagePriority);
135 ok(SystemVa == NULL, "MmMapLockedPagesSpecifyCache succeeded for 2 GB\n");
136 if (SystemVa != NULL)
137 MmUnmapLockedPages(SystemVa, Mdl);
138 ok(MmGetMdlByteCount(Mdl) != 2UL * 1024 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
139 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
140 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
141 MmFreePagesFromMdl(Mdl);
142 ExFreePoolWithTag(Mdl, 0);
143 }
144
145 /* now allocate and map 32 MB Mdls until we fail */
146 for (i = 0; i < sizeof(Mdls) / sizeof(Mdls[0]); i++)
147 {
148 Mdls[i] = MmAllocatePagesForMdl(LowAddress,
149 HighAddress,
150 SkipBytes,
151 32 * 1024 * 1024);
152 if (Mdls[i] == NULL)
153 {
154 trace("MmAllocatePagesForMdl failed with i = %lu\n", i);
155 break;
156 }
157 ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdls[i]));
158 ok(!(Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
159 SystemVas[i] = MmMapLockedPagesSpecifyCache(Mdls[i],
160 KernelMode,
161 MmCached,
162 NULL,
163 FALSE,
164 NormalPagePriority);
165 if (SystemVas[i] == NULL)
166 {
167 ok(MmGetMdlByteCount(Mdls[i]) <= 32 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdls[i]));
168 ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdls[i]));
169 ok(!(Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
170 trace("MmMapLockedPagesSpecifyCache failed with i = %lu\n", i);
171 break;
172 }
173 ok(MmGetMdlByteCount(Mdls[i]) == 32 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdls[i]));
174 ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p, System VA: %p\n", MmGetMdlVirtualAddress(Mdls[i]), SystemVas[i]);
175 ok(Mdls[i]->MappedSystemVa == SystemVas[i], "MappedSystemVa: %p\n", Mdls[i]->MappedSystemVa, SystemVas[i]);
176 ok((Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
177 }
178 for (i = 0; i < sizeof(Mdls) / sizeof(Mdls[0]); i++)
179 {
180 if (Mdls[i] == NULL)
181 break;
182 if (SystemVas[i] != NULL)
183 MmUnmapLockedPages(SystemVas[i], Mdls[i]);
184 MmFreePagesFromMdl(Mdls[i]);
185 ExFreePoolWithTag(Mdls[i], 0);
186 if (SystemVas[i] == NULL)
187 break;
188 }
189 }
190
191 START_TEST(MmMdl)
192 {
193 TestMmAllocatePagesForMdl();
194 }