xref: /linux/tools/testing/vma/tests/vma.c (revision 3a6455d56bd7c4cfb1ea35ddae052943065e338e)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 static bool compare_legacy_flags(vm_flags_t legacy_flags, vma_flags_t flags)
4 {
5 	const unsigned long legacy_val = legacy_flags;
6 	/* The lower word should contain the precise same value. */
7 	const unsigned long flags_lower = flags.__vma_flags[0];
8 	vma_flags_t converted_flags;
9 #if NUM_VMA_FLAG_BITS > BITS_PER_LONG
10 	int i;
11 
12 	/* All bits in higher flag values should be zero. */
13 	for (i = 1; i < NUM_VMA_FLAG_BITS / BITS_PER_LONG; i++) {
14 		if (flags.__vma_flags[i] != 0)
15 			return false;
16 	}
17 #endif
18 
19 	static_assert(sizeof(legacy_flags) == sizeof(unsigned long));
20 
21 	/* Assert that legacy flag helpers work correctly. */
22 	converted_flags = legacy_to_vma_flags(legacy_flags);
23 	ASSERT_FLAGS_SAME_MASK(&converted_flags, flags);
24 	ASSERT_EQ(vma_flags_to_legacy(flags), legacy_flags);
25 
26 	return legacy_val == flags_lower;
27 }
28 
29 static bool test_copy_vma(void)
30 {
31 	vma_flags_t vma_flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
32 					     VMA_MAYREAD_BIT, VMA_MAYWRITE_BIT);
33 	struct mm_struct mm = {};
34 	bool need_locks = false;
35 	VMA_ITERATOR(vmi, &mm, 0);
36 	struct vm_area_struct *vma, *vma_new, *vma_next;
37 
38 	/* Move backwards and do not merge. */
39 
40 	vma = alloc_and_link_vma(&mm, 0x3000, 0x5000, 3, vma_flags);
41 	vma_new = copy_vma(&vma, 0, 0x2000, 0, &need_locks);
42 	ASSERT_NE(vma_new, vma);
43 	ASSERT_EQ(vma_new->vm_start, 0);
44 	ASSERT_EQ(vma_new->vm_end, 0x2000);
45 	ASSERT_EQ(vma_new->vm_pgoff, 0);
46 	vma_assert_attached(vma_new);
47 
48 	cleanup_mm(&mm, &vmi);
49 
50 	/* Move a VMA into position next to another and merge the two. */
51 
52 	vma = alloc_and_link_vma(&mm, 0, 0x2000, 0, vma_flags);
53 	vma_next = alloc_and_link_vma(&mm, 0x6000, 0x8000, 6, vma_flags);
54 	vma_new = copy_vma(&vma, 0x4000, 0x2000, 4, &need_locks);
55 	vma_assert_attached(vma_new);
56 
57 	ASSERT_EQ(vma_new, vma_next);
58 
59 	cleanup_mm(&mm, &vmi);
60 	return true;
61 }
62 
63 static bool test_vma_flags_unchanged(void)
64 {
65 	vma_flags_t flags = EMPTY_VMA_FLAGS;
66 	vm_flags_t legacy_flags = 0;
67 	int bit;
68 	struct vm_area_struct vma;
69 	struct vm_area_desc desc;
70 
71 	vma.flags = EMPTY_VMA_FLAGS;
72 	desc.vma_flags = EMPTY_VMA_FLAGS;
73 
74 	for (bit = 0; bit < BITS_PER_LONG; bit++) {
75 		vma_flags_t mask = mk_vma_flags(bit);
76 
77 		legacy_flags |= (1UL << bit);
78 
79 		/* Individual flags. */
80 		vma_flags_set(&flags, bit);
81 		ASSERT_TRUE(compare_legacy_flags(legacy_flags, flags));
82 
83 		/* Via mask. */
84 		vma_flags_set_mask(&flags, mask);
85 		ASSERT_TRUE(compare_legacy_flags(legacy_flags, flags));
86 
87 		/* Same for VMA. */
88 		vma_set_flags(&vma, bit);
89 		ASSERT_TRUE(compare_legacy_flags(legacy_flags, vma.flags));
90 		vma_set_flags_mask(&vma, mask);
91 		ASSERT_TRUE(compare_legacy_flags(legacy_flags, vma.flags));
92 
93 		/* Same for VMA descriptor. */
94 		vma_desc_set_flags(&desc, bit);
95 		ASSERT_TRUE(compare_legacy_flags(legacy_flags, desc.vma_flags));
96 		vma_desc_set_flags_mask(&desc, mask);
97 		ASSERT_TRUE(compare_legacy_flags(legacy_flags, desc.vma_flags));
98 	}
99 
100 	return true;
101 }
102 
103 static bool test_vma_flags_cleared(void)
104 {
105 	const vma_flags_t empty = EMPTY_VMA_FLAGS;
106 	vma_flags_t flags;
107 	int i;
108 
109 	/* Set all bits high. */
110 	memset(&flags, 1, sizeof(flags));
111 	/* Try to clear. */
112 	vma_flags_clear_all(&flags);
113 	/* Equal to EMPTY_VMA_FLAGS? */
114 	ASSERT_EQ(memcmp(&empty, &flags, sizeof(flags)), 0);
115 	/* Make sure every unsigned long entry in bitmap array zero. */
116 	for (i = 0; i < sizeof(flags) / BITS_PER_LONG; i++) {
117 		const unsigned long val = flags.__vma_flags[i];
118 
119 		ASSERT_EQ(val, 0);
120 	}
121 
122 	return true;
123 }
124 
125 #if NUM_VMA_FLAG_BITS > 64
126 /*
127  * Assert that VMA flag functions that operate at the system word level function
128  * correctly.
129  */
130 static bool test_vma_flags_word(void)
131 {
132 	vma_flags_t flags = EMPTY_VMA_FLAGS;
133 	const vma_flags_t comparison =
134 		mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT
135 
136 			     , 64, 65
137 			);
138 
139 	/* Set some custom high flags. */
140 	vma_flags_set(&flags, 64, 65);
141 
142 	/* Now overwrite the first word. */
143 	vma_flags_overwrite_word(&flags, VM_READ | VM_WRITE);
144 	/* Ensure they are equal. */
145 	ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0);
146 
147 	flags = EMPTY_VMA_FLAGS;
148 	vma_flags_set(&flags, 64, 65);
149 
150 	/* Do the same with the _once() equivalent. */
151 	vma_flags_overwrite_word_once(&flags, VM_READ | VM_WRITE);
152 	ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0);
153 
154 	flags = EMPTY_VMA_FLAGS;
155 	vma_flags_set(&flags, 64, 65);
156 
157 	/* Make sure we can set a word without disturbing other bits. */
158 	vma_flags_set(&flags, VMA_WRITE_BIT);
159 	vma_flags_set_word(&flags, VM_READ);
160 	ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0);
161 
162 	flags = EMPTY_VMA_FLAGS;
163 	vma_flags_set(&flags, 64, 65);
164 
165 	/* Make sure we can clear a word without disturbing other bits. */
166 	vma_flags_set(&flags, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
167 	vma_flags_clear_word(&flags, VM_EXEC);
168 	ASSERT_EQ(memcmp(&flags, &comparison, sizeof(flags)), 0);
169 
170 	return true;
171 }
172 #endif /* NUM_VMA_FLAG_BITS > 64 */
173 
174 /* Ensure that vma_flags_test() and friends works correctly. */
175 static bool test_vma_flags_test(void)
176 {
177 	vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
178 					 VMA_EXEC_BIT
179 #if NUM_VMA_FLAG_BITS > 64
180 					 , 64, 65
181 #endif
182 		);
183 	struct vm_area_desc desc = {
184 		.vma_flags = flags,
185 	};
186 	struct vm_area_struct vma = {
187 		.flags = flags,
188 	};
189 
190 #define do_test(_flag)							    \
191 	ASSERT_TRUE(vma_flags_test(&flags, _flag));			    \
192 	ASSERT_TRUE(vma_flags_test_single_mask(&flags, mk_vma_flags(_flag))); \
193 	ASSERT_TRUE(vma_test(&vma, _flag));				    \
194 	ASSERT_TRUE(vma_test_single_mask(&vma, mk_vma_flags(_flag)));	    \
195 	ASSERT_TRUE(vma_desc_test(&desc, _flag))
196 
197 #define do_test_false(_flag)						     \
198 	ASSERT_FALSE(vma_flags_test(&flags, _flag));			     \
199 	ASSERT_FALSE(vma_flags_test_single_mask(&flags, mk_vma_flags(_flag))); \
200 	ASSERT_FALSE(vma_test(&vma, _flag));				     \
201 	ASSERT_FALSE(vma_test_single_mask(&vma, mk_vma_flags(_flag)));	     \
202 	ASSERT_FALSE(vma_desc_test(&desc, _flag))
203 
204 	do_test(VMA_READ_BIT);
205 	do_test(VMA_WRITE_BIT);
206 	do_test(VMA_EXEC_BIT);
207 #if NUM_VMA_FLAG_BITS > 64
208 	do_test(64);
209 	do_test(65);
210 #endif
211 	do_test_false(VMA_MAYWRITE_BIT);
212 #if NUM_VMA_FLAG_BITS > 64
213 	do_test_false(66);
214 #endif
215 
216 #undef do_test
217 #undef do_test_false
218 
219 	/* We define the _single_mask() variants to return false if empty. */
220 	ASSERT_FALSE(vma_flags_test_single_mask(&flags, EMPTY_VMA_FLAGS));
221 	ASSERT_FALSE(vma_test_single_mask(&vma, EMPTY_VMA_FLAGS));
222 	/* Even when both flags and tested flag mask are empty! */
223 	flags = EMPTY_VMA_FLAGS;
224 	vma.flags = EMPTY_VMA_FLAGS;
225 	ASSERT_FALSE(vma_flags_test_single_mask(&flags, EMPTY_VMA_FLAGS));
226 	ASSERT_FALSE(vma_test_single_mask(&vma, EMPTY_VMA_FLAGS));
227 
228 	return true;
229 }
230 
231 /* Ensure that vma_flags_test_any() and friends works correctly. */
232 static bool test_vma_flags_test_any(void)
233 {
234 	const vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
235 					       VMA_EXEC_BIT
236 #if NUM_VMA_FLAG_BITS > 64
237 					       , 64, 65
238 #endif
239 		);
240 	struct vm_area_struct vma = {
241 		.flags = flags,
242 	};
243 	struct vm_area_desc desc = {
244 		.vma_flags = flags,
245 	};
246 
247 #define do_test(...)						\
248 	ASSERT_TRUE(vma_flags_test_any(&flags, __VA_ARGS__));	\
249 	ASSERT_TRUE(vma_desc_test_any(&desc, __VA_ARGS__));	\
250 	ASSERT_TRUE(vma_test_any(&vma, __VA_ARGS__));
251 
252 #define do_test_all_true(...)					\
253 	ASSERT_TRUE(vma_flags_test_all(&flags, __VA_ARGS__));	\
254 	ASSERT_TRUE(vma_test_all(&vma, __VA_ARGS__))
255 
256 #define do_test_all_false(...)					\
257 	ASSERT_FALSE(vma_flags_test_all(&flags, __VA_ARGS__));	\
258 	ASSERT_FALSE(vma_test_all(&vma, __VA_ARGS__))
259 
260 	/*
261 	 * Testing for some flags that are present, some that are not - should
262 	 * pass. ANY flags matching should work.
263 	 */
264 	do_test(VMA_READ_BIT, VMA_MAYREAD_BIT, VMA_SEQ_READ_BIT);
265 	/* However, the ...test_all() variant should NOT pass. */
266 	do_test_all_false(VMA_READ_BIT, VMA_MAYREAD_BIT, VMA_SEQ_READ_BIT);
267 #if NUM_VMA_FLAG_BITS > 64
268 	/* But should pass for flags present. */
269 	do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64, 65);
270 	/* Also subsets... */
271 	do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64);
272 #endif
273 	do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
274 	do_test_all_true(VMA_READ_BIT, VMA_WRITE_BIT);
275 	do_test_all_true(VMA_READ_BIT);
276 	/*
277 	 * Check _mask variant. We don't need to test extensively as macro
278 	 * helper is the equivalent.
279 	 */
280 	ASSERT_TRUE(vma_flags_test_any_mask(&flags, flags));
281 	ASSERT_TRUE(vma_flags_test_all_mask(&flags, flags));
282 
283 	/* Single bits. */
284 	do_test(VMA_READ_BIT);
285 	do_test(VMA_WRITE_BIT);
286 	do_test(VMA_EXEC_BIT);
287 #if NUM_VMA_FLAG_BITS > 64
288 	do_test(64);
289 	do_test(65);
290 #endif
291 
292 	/* Two bits. */
293 	do_test(VMA_READ_BIT, VMA_WRITE_BIT);
294 	do_test(VMA_READ_BIT, VMA_EXEC_BIT);
295 	do_test(VMA_WRITE_BIT, VMA_EXEC_BIT);
296 	/* Ordering shouldn't matter. */
297 	do_test(VMA_WRITE_BIT, VMA_READ_BIT);
298 	do_test(VMA_EXEC_BIT, VMA_READ_BIT);
299 	do_test(VMA_EXEC_BIT, VMA_WRITE_BIT);
300 #if NUM_VMA_FLAG_BITS > 64
301 	do_test(VMA_READ_BIT, 64);
302 	do_test(VMA_WRITE_BIT, 64);
303 	do_test(64, VMA_READ_BIT);
304 	do_test(64, VMA_WRITE_BIT);
305 	do_test(VMA_READ_BIT, 65);
306 	do_test(VMA_WRITE_BIT, 65);
307 	do_test(65, VMA_READ_BIT);
308 	do_test(65, VMA_WRITE_BIT);
309 #endif
310 	/* Three bits. */
311 	do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
312 #if NUM_VMA_FLAG_BITS > 64
313 	/* No need to consider every single permutation. */
314 	do_test(VMA_READ_BIT, VMA_WRITE_BIT, 64);
315 	do_test(VMA_READ_BIT, VMA_WRITE_BIT, 65);
316 
317 	/* Four bits. */
318 	do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64);
319 	do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 65);
320 
321 	/* Five bits. */
322 	do_test(VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64, 65);
323 #endif
324 
325 	/* Testing all flags against none trivially succeeds. */
326 	ASSERT_TRUE(vma_flags_test_all_mask(&flags, EMPTY_VMA_FLAGS));
327 	ASSERT_TRUE(vma_test_all_mask(&vma, EMPTY_VMA_FLAGS));
328 
329 #undef do_test
330 #undef do_test_all_true
331 #undef do_test_all_false
332 
333 	return true;
334 }
335 
336 /* Ensure that vma_flags_clear() and friends works correctly. */
337 static bool test_vma_flags_clear(void)
338 {
339 	vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
340 					 VMA_EXEC_BIT
341 #if NUM_VMA_FLAG_BITS > 64
342 					       , 64, 65
343 #endif
344 		);
345 	vma_flags_t mask = mk_vma_flags(VMA_EXEC_BIT
346 #if NUM_VMA_FLAG_BITS > 64
347 					, 64
348 #endif
349 		);
350 	struct vm_area_struct vma;
351 	struct vm_area_desc desc;
352 
353 	vma.flags = flags;
354 	desc.vma_flags = flags;
355 
356 	/* Cursory check of _mask() variant, as the helper macros imply. */
357 	vma_flags_clear_mask(&flags, mask);
358 	vma_flags_clear_mask(&vma.flags, mask);
359 	vma_desc_clear_flags_mask(&desc, mask);
360 #if NUM_VMA_FLAG_BITS > 64
361 	ASSERT_FALSE(vma_flags_test_any(&flags, VMA_EXEC_BIT, 64));
362 	ASSERT_FALSE(vma_flags_test_any(&vma.flags, VMA_EXEC_BIT, 64));
363 	ASSERT_FALSE(vma_desc_test_any(&desc, VMA_EXEC_BIT, 64));
364 	/* Reset. */
365 	vma_flags_set(&flags, VMA_EXEC_BIT, 64);
366 	vma_set_flags(&vma, VMA_EXEC_BIT, 64);
367 	vma_desc_set_flags(&desc, VMA_EXEC_BIT, 64);
368 #endif
369 
370 	/*
371 	 * Clear the flags and assert clear worked, then reset flags back to
372 	 * include specified flags.
373 	 */
374 #define do_test_and_reset(...)					\
375 	vma_flags_clear(&flags, __VA_ARGS__);			\
376 	vma_flags_clear(&vma.flags, __VA_ARGS__);		\
377 	vma_desc_clear_flags(&desc, __VA_ARGS__);		\
378 	ASSERT_FALSE(vma_flags_test_any(&flags, __VA_ARGS__));	\
379 	ASSERT_FALSE(vma_flags_test_any(&vma.flags, __VA_ARGS__));	\
380 	ASSERT_FALSE(vma_desc_test_any(&desc, __VA_ARGS__));	\
381 	vma_flags_set(&flags, __VA_ARGS__);			\
382 	vma_set_flags(&vma, __VA_ARGS__);			\
383 	vma_desc_set_flags(&desc, __VA_ARGS__)
384 
385 	/* Single flags. */
386 	do_test_and_reset(VMA_READ_BIT);
387 	do_test_and_reset(VMA_WRITE_BIT);
388 	do_test_and_reset(VMA_EXEC_BIT);
389 #if NUM_VMA_FLAG_BITS > 64
390 	do_test_and_reset(64);
391 	do_test_and_reset(65);
392 #endif
393 
394 	/* Two flags, in different orders. */
395 	do_test_and_reset(VMA_READ_BIT, VMA_WRITE_BIT);
396 	do_test_and_reset(VMA_READ_BIT, VMA_EXEC_BIT);
397 #if NUM_VMA_FLAG_BITS > 64
398 	do_test_and_reset(VMA_READ_BIT, 64);
399 	do_test_and_reset(VMA_READ_BIT, 65);
400 #endif
401 	do_test_and_reset(VMA_WRITE_BIT, VMA_READ_BIT);
402 	do_test_and_reset(VMA_WRITE_BIT, VMA_EXEC_BIT);
403 #if NUM_VMA_FLAG_BITS > 64
404 	do_test_and_reset(VMA_WRITE_BIT, 64);
405 	do_test_and_reset(VMA_WRITE_BIT, 65);
406 #endif
407 	do_test_and_reset(VMA_EXEC_BIT, VMA_READ_BIT);
408 	do_test_and_reset(VMA_EXEC_BIT, VMA_WRITE_BIT);
409 #if NUM_VMA_FLAG_BITS > 64
410 	do_test_and_reset(VMA_EXEC_BIT, 64);
411 	do_test_and_reset(VMA_EXEC_BIT, 65);
412 	do_test_and_reset(64, VMA_READ_BIT);
413 	do_test_and_reset(64, VMA_WRITE_BIT);
414 	do_test_and_reset(64, VMA_EXEC_BIT);
415 	do_test_and_reset(64, 65);
416 	do_test_and_reset(65, VMA_READ_BIT);
417 	do_test_and_reset(65, VMA_WRITE_BIT);
418 	do_test_and_reset(65, VMA_EXEC_BIT);
419 	do_test_and_reset(65, 64);
420 #endif
421 
422 	/* Three flags. */
423 
424 #undef do_test_some_missing
425 #undef do_test_and_reset
426 
427 	return true;
428 }
429 
430 /* Ensure that vma_flags_empty() works correctly. */
431 static bool test_vma_flags_empty(void)
432 {
433 	vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
434 					 VMA_EXEC_BIT
435 #if NUM_VMA_FLAG_BITS > 64
436 					       , 64, 65
437 #endif
438 		);
439 
440 	ASSERT_FLAGS_NONEMPTY(&flags);
441 	vma_flags_clear(&flags, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
442 #if NUM_VMA_FLAG_BITS > 64
443 	ASSERT_FLAGS_NONEMPTY(&flags);
444 	vma_flags_clear(&flags, 64, 65);
445 	ASSERT_FLAGS_EMPTY(&flags);
446 #else
447 	ASSERT_FLAGS_EMPTY(&flags);
448 #endif
449 
450 	return true;
451 }
452 
453 /* Ensure that vma_flags_diff_pair() works correctly. */
454 static bool test_vma_flags_diff(void)
455 {
456 	vma_flags_t flags1 = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
457 					  VMA_EXEC_BIT
458 #if NUM_VMA_FLAG_BITS > 64
459 					       , 64, 65
460 #endif
461 		);
462 
463 	vma_flags_t flags2 = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
464 					  VMA_EXEC_BIT, VMA_MAYWRITE_BIT,
465 					  VMA_MAYEXEC_BIT
466 #if NUM_VMA_FLAG_BITS > 64
467 					  , 64, 65, 66, 67
468 #endif
469 		);
470 	vma_flags_t diff = vma_flags_diff_pair(&flags1, &flags2);
471 
472 #if NUM_VMA_FLAG_BITS > 64
473 	ASSERT_FLAGS_SAME(&diff, VMA_MAYWRITE_BIT, VMA_MAYEXEC_BIT, 66, 67);
474 #else
475 	ASSERT_FLAGS_SAME(&diff, VMA_MAYWRITE_BIT, VMA_MAYEXEC_BIT);
476 #endif
477 	/* Should be the same even if re-ordered. */
478 	diff = vma_flags_diff_pair(&flags2, &flags1);
479 #if NUM_VMA_FLAG_BITS > 64
480 	ASSERT_FLAGS_SAME(&diff, VMA_MAYWRITE_BIT, VMA_MAYEXEC_BIT, 66, 67);
481 #else
482 	ASSERT_FLAGS_SAME(&diff, VMA_MAYWRITE_BIT, VMA_MAYEXEC_BIT);
483 #endif
484 
485 	/* Should be no difference when applied against themselves. */
486 	diff = vma_flags_diff_pair(&flags1, &flags1);
487 	ASSERT_FLAGS_EMPTY(&diff);
488 	diff = vma_flags_diff_pair(&flags2, &flags2);
489 	ASSERT_FLAGS_EMPTY(&diff);
490 
491 	/* One set of flags against an empty one should equal the original. */
492 	flags2 = EMPTY_VMA_FLAGS;
493 	diff = vma_flags_diff_pair(&flags1, &flags2);
494 	ASSERT_FLAGS_SAME_MASK(&diff, flags1);
495 
496 	/* A subset should work too. */
497 	flags2 = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT);
498 	diff = vma_flags_diff_pair(&flags1, &flags2);
499 #if NUM_VMA_FLAG_BITS > 64
500 	ASSERT_FLAGS_SAME(&diff, VMA_EXEC_BIT, 64, 65);
501 #else
502 	ASSERT_FLAGS_SAME(&diff, VMA_EXEC_BIT);
503 #endif
504 
505 	return true;
506 }
507 
508 /* Ensure that vma_flags_and() and friends work correctly. */
509 static bool test_vma_flags_and(void)
510 {
511 	vma_flags_t flags1 = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
512 					  VMA_EXEC_BIT
513 #if NUM_VMA_FLAG_BITS > 64
514 					       , 64, 65
515 #endif
516 		);
517 	vma_flags_t flags2 = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
518 					  VMA_EXEC_BIT, VMA_MAYWRITE_BIT,
519 					  VMA_MAYEXEC_BIT
520 #if NUM_VMA_FLAG_BITS > 64
521 					  , 64, 65, 66, 67
522 #endif
523 		);
524 	vma_flags_t flags3 = mk_vma_flags(VMA_IO_BIT, VMA_MAYBE_GUARD_BIT
525 #if NUM_VMA_FLAG_BITS > 64
526 					  , 68, 69
527 #endif
528 		);
529 	vma_flags_t and = vma_flags_and_mask(&flags1, flags2);
530 
531 #if NUM_VMA_FLAG_BITS > 64
532 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
533 			  64, 65);
534 #else
535 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
536 #endif
537 
538 	and = vma_flags_and_mask(&flags1, flags1);
539 	ASSERT_FLAGS_SAME_MASK(&and, flags1);
540 
541 	and = vma_flags_and_mask(&flags2, flags2);
542 	ASSERT_FLAGS_SAME_MASK(&and, flags2);
543 
544 	and = vma_flags_and_mask(&flags1, flags3);
545 	ASSERT_FLAGS_EMPTY(&and);
546 	and = vma_flags_and_mask(&flags2, flags3);
547 	ASSERT_FLAGS_EMPTY(&and);
548 
549 	and = vma_flags_and(&flags1, VMA_READ_BIT);
550 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT);
551 
552 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT);
553 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT);
554 
555 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
556 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
557 
558 #if NUM_VMA_FLAG_BITS > 64
559 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
560 			    64);
561 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64);
562 
563 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
564 			    64, 65);
565 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64,
566 			  65);
567 #endif
568 
569 	/* And against some missing values. */
570 
571 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
572 			    VMA_IO_BIT);
573 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
574 
575 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
576 			    VMA_IO_BIT, VMA_RAND_READ_BIT);
577 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
578 
579 #if NUM_VMA_FLAG_BITS > 64
580 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
581 			    VMA_IO_BIT, VMA_RAND_READ_BIT, 69);
582 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
583 #endif
584 
585 	return true;
586 }
587 
588 /* Ensure append_vma_flags() acts as expected. */
589 static bool test_append_vma_flags(void)
590 {
591 	vma_flags_t flags = append_vma_flags(VMA_REMAP_FLAGS, VMA_READ_BIT,
592 					     VMA_WRITE_BIT
593 #if NUM_VMA_FLAG_BITS > 64
594 					     , 64, 65
595 #endif
596 		);
597 
598 	ASSERT_FLAGS_SAME(&flags, VMA_IO_BIT, VMA_PFNMAP_BIT,
599 			  VMA_DONTEXPAND_BIT, VMA_DONTDUMP_BIT, VMA_READ_BIT,
600 			  VMA_WRITE_BIT
601 #if NUM_VMA_FLAG_BITS > 64
602 					     , 64, 65
603 #endif
604 		);
605 
606 	flags = append_vma_flags(EMPTY_VMA_FLAGS, VMA_READ_BIT, VMA_WRITE_BIT);
607 	ASSERT_FLAGS_SAME(&flags, VMA_READ_BIT, VMA_WRITE_BIT);
608 
609 	return true;
610 }
611 
612 /* Assert that vma_flags_count() behaves as expected. */
613 static bool test_vma_flags_count(void)
614 {
615 	vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
616 					 VMA_EXEC_BIT
617 #if NUM_VMA_FLAG_BITS > 64
618 					 , 64, 65
619 #endif
620 		);
621 
622 #if NUM_VMA_FLAG_BITS > 64
623 	ASSERT_EQ(vma_flags_count(&flags), 5);
624 	vma_flags_clear(&flags, 64);
625 	ASSERT_EQ(vma_flags_count(&flags), 4);
626 	vma_flags_clear(&flags, 65);
627 #endif
628 	ASSERT_EQ(vma_flags_count(&flags), 3);
629 	vma_flags_clear(&flags, VMA_EXEC_BIT);
630 	ASSERT_EQ(vma_flags_count(&flags), 2);
631 	vma_flags_clear(&flags, VMA_WRITE_BIT);
632 	ASSERT_EQ(vma_flags_count(&flags), 1);
633 	vma_flags_clear(&flags, VMA_READ_BIT);
634 	ASSERT_EQ(vma_flags_count(&flags), 0);
635 
636 	return true;
637 }
638 
639 static void run_vma_tests(int *num_tests, int *num_fail)
640 {
641 	TEST(copy_vma);
642 	TEST(vma_flags_unchanged);
643 	TEST(vma_flags_cleared);
644 #if NUM_VMA_FLAG_BITS > 64
645 	TEST(vma_flags_word);
646 #endif
647 	TEST(vma_flags_test);
648 	TEST(vma_flags_test_any);
649 	TEST(vma_flags_clear);
650 	TEST(vma_flags_empty);
651 	TEST(vma_flags_diff);
652 	TEST(vma_flags_and);
653 	TEST(append_vma_flags);
654 	TEST(vma_flags_count);
655 }
656