[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 ok(MdlPages[i] != 0 && MdlPages[i] != (PFN_NUMBER)-1,
124 "MdlPages[%lu] = 0x%I64x\n", i, (ULONGLONG)MdlPages[i]);
125 }
126 SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
127 KernelMode,
128 MmCached,
129 NULL,
130 FALSE,
131 NormalPagePriority);
132 ok(SystemVa == NULL, "MmMapLockedPagesSpecifyCache succeeded for 2 GB\n");
133 if (SystemVa != NULL)
134 MmUnmapLockedPages(SystemVa, Mdl);
135 ok(MmGetMdlByteCount(Mdl) != 2UL * 1024 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
136 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
137 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
138 MmFreePagesFromMdl(Mdl);
139 ExFreePoolWithTag(Mdl, 0);
140 }
141
142 /* now allocate and map 32 MB Mdls until we fail */
143 for (i = 0; i < sizeof(Mdls) / sizeof(Mdls[0]); i++)
144 {
145 Mdls[i] = MmAllocatePagesForMdl(LowAddress,
146 HighAddress,
147 SkipBytes,
148 32 * 1024 * 1024);
149 if (Mdls[i] == NULL)
150 {
151 trace("MmAllocatePagesForMdl failed with i = %lu\n", i);
152 break;
153 }
154 ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdls[i]));
155 ok(!(Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
156 SystemVas[i] = MmMapLockedPagesSpecifyCache(Mdls[i],
157 KernelMode,
158 MmCached,
159 NULL,
160 FALSE,
161 NormalPagePriority);
162 if (SystemVas[i] == NULL)
163 {
164 ok(MmGetMdlByteCount(Mdls[i]) <= 32 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdls[i]));
165 ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdls[i]));
166 ok(!(Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
167 trace("MmMapLockedPagesSpecifyCache failed with i = %lu\n", i);
168 break;
169 }
170 ok(MmGetMdlByteCount(Mdls[i]) == 32 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdls[i]));
171 ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p, System VA: %p\n", MmGetMdlVirtualAddress(Mdls[i]), SystemVas[i]);
172 ok(Mdls[i]->MappedSystemVa == SystemVas[i], "MappedSystemVa: %p\n", Mdls[i]->MappedSystemVa, SystemVas[i]);
173 ok((Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
174 }
175 for (i = 0; i < sizeof(Mdls) / sizeof(Mdls[0]); i++)
176 {
177 if (Mdls[i] == NULL)
178 break;
179 if (SystemVas[i] != NULL)
180 MmUnmapLockedPages(SystemVas[i], Mdls[i]);
181 MmFreePagesFromMdl(Mdls[i]);
182 ExFreePoolWithTag(Mdls[i], 0);
183 if (SystemVas[i] == NULL)
184 break;
185 }
186 }
187
188 START_TEST(MmMdl)
189 {
190 TestMmAllocatePagesForMdl();
191 }