xref: /linux/tools/testing/vma/tests/vma.c (revision a6f14fb59337ec3b507856430e0636b1b10980ec)
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 		.flags = flags,
352 	};
353 	struct vm_area_desc desc = {
354 		.vma_flags = flags,
355 	};
356 
357 	/* Cursory check of _mask() variant, as the helper macros imply. */
358 	vma_flags_clear_mask(&flags, mask);
359 	vma_clear_flags_mask(&vma, mask);
360 	vma_desc_clear_flags_mask(&desc, mask);
361 #if NUM_VMA_FLAG_BITS > 64
362 	ASSERT_FALSE(vma_flags_test_any(&flags, VMA_EXEC_BIT, 64));
363 	ASSERT_FALSE(vma_test_any(&vma, VMA_EXEC_BIT, 64));
364 	ASSERT_FALSE(vma_desc_test_any(&desc, VMA_EXEC_BIT, 64));
365 	/* Reset. */
366 	vma_flags_set(&flags, VMA_EXEC_BIT, 64);
367 	vma_set_flags(&vma, VMA_EXEC_BIT, 64);
368 	vma_desc_set_flags(&desc, VMA_EXEC_BIT, 64);
369 #endif
370 
371 	/*
372 	 * Clear the flags and assert clear worked, then reset flags back to
373 	 * include specified flags.
374 	 */
375 #define do_test_and_reset(...)						\
376 	vma_flags_clear(&flags, __VA_ARGS__);				\
377 	vma_clear_flags(&vma, __VA_ARGS__);				\
378 	vma_desc_clear_flags(&desc, __VA_ARGS__);			\
379 	ASSERT_FALSE(vma_flags_test_any(&flags, __VA_ARGS__));		\
380 	ASSERT_FALSE(vma_test_any(&vma, __VA_ARGS__));			\
381 	ASSERT_FALSE(vma_desc_test_any(&desc, __VA_ARGS__));		\
382 	vma_flags_set(&flags, __VA_ARGS__);				\
383 	vma_set_flags(&vma, __VA_ARGS__);				\
384 	vma_desc_set_flags(&desc, __VA_ARGS__)
385 
386 	/* Single flags. */
387 	do_test_and_reset(VMA_READ_BIT);
388 	do_test_and_reset(VMA_WRITE_BIT);
389 	do_test_and_reset(VMA_EXEC_BIT);
390 #if NUM_VMA_FLAG_BITS > 64
391 	do_test_and_reset(64);
392 	do_test_and_reset(65);
393 #endif
394 
395 	/* Two flags, in different orders. */
396 	do_test_and_reset(VMA_READ_BIT, VMA_WRITE_BIT);
397 	do_test_and_reset(VMA_READ_BIT, VMA_EXEC_BIT);
398 #if NUM_VMA_FLAG_BITS > 64
399 	do_test_and_reset(VMA_READ_BIT, 64);
400 	do_test_and_reset(VMA_READ_BIT, 65);
401 #endif
402 	do_test_and_reset(VMA_WRITE_BIT, VMA_READ_BIT);
403 	do_test_and_reset(VMA_WRITE_BIT, VMA_EXEC_BIT);
404 #if NUM_VMA_FLAG_BITS > 64
405 	do_test_and_reset(VMA_WRITE_BIT, 64);
406 	do_test_and_reset(VMA_WRITE_BIT, 65);
407 #endif
408 	do_test_and_reset(VMA_EXEC_BIT, VMA_READ_BIT);
409 	do_test_and_reset(VMA_EXEC_BIT, VMA_WRITE_BIT);
410 #if NUM_VMA_FLAG_BITS > 64
411 	do_test_and_reset(VMA_EXEC_BIT, 64);
412 	do_test_and_reset(VMA_EXEC_BIT, 65);
413 	do_test_and_reset(64, VMA_READ_BIT);
414 	do_test_and_reset(64, VMA_WRITE_BIT);
415 	do_test_and_reset(64, VMA_EXEC_BIT);
416 	do_test_and_reset(64, 65);
417 	do_test_and_reset(65, VMA_READ_BIT);
418 	do_test_and_reset(65, VMA_WRITE_BIT);
419 	do_test_and_reset(65, VMA_EXEC_BIT);
420 	do_test_and_reset(65, 64);
421 #endif
422 
423 	/* Three flags. */
424 
425 #undef do_test_some_missing
426 #undef do_test_and_reset
427 
428 	return true;
429 }
430 
431 /* Ensure that vma_flags_empty() works correctly. */
432 static bool test_vma_flags_empty(void)
433 {
434 	vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
435 					 VMA_EXEC_BIT
436 #if NUM_VMA_FLAG_BITS > 64
437 					       , 64, 65
438 #endif
439 		);
440 
441 	ASSERT_FLAGS_NONEMPTY(&flags);
442 	vma_flags_clear(&flags, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
443 #if NUM_VMA_FLAG_BITS > 64
444 	ASSERT_FLAGS_NONEMPTY(&flags);
445 	vma_flags_clear(&flags, 64, 65);
446 	ASSERT_FLAGS_EMPTY(&flags);
447 #else
448 	ASSERT_FLAGS_EMPTY(&flags);
449 #endif
450 
451 	return true;
452 }
453 
454 /* Ensure that vma_flags_diff_pair() works correctly. */
455 static bool test_vma_flags_diff(void)
456 {
457 	vma_flags_t flags1 = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
458 					  VMA_EXEC_BIT
459 #if NUM_VMA_FLAG_BITS > 64
460 					       , 64, 65
461 #endif
462 		);
463 
464 	vma_flags_t flags2 = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
465 					  VMA_EXEC_BIT, VMA_MAYWRITE_BIT,
466 					  VMA_MAYEXEC_BIT
467 #if NUM_VMA_FLAG_BITS > 64
468 					  , 64, 65, 66, 67
469 #endif
470 		);
471 	vma_flags_t diff = vma_flags_diff_pair(&flags1, &flags2);
472 
473 #if NUM_VMA_FLAG_BITS > 64
474 	ASSERT_FLAGS_SAME(&diff, VMA_MAYWRITE_BIT, VMA_MAYEXEC_BIT, 66, 67);
475 #else
476 	ASSERT_FLAGS_SAME(&diff, VMA_MAYWRITE_BIT, VMA_MAYEXEC_BIT);
477 #endif
478 	/* Should be the same even if re-ordered. */
479 	diff = vma_flags_diff_pair(&flags2, &flags1);
480 #if NUM_VMA_FLAG_BITS > 64
481 	ASSERT_FLAGS_SAME(&diff, VMA_MAYWRITE_BIT, VMA_MAYEXEC_BIT, 66, 67);
482 #else
483 	ASSERT_FLAGS_SAME(&diff, VMA_MAYWRITE_BIT, VMA_MAYEXEC_BIT);
484 #endif
485 
486 	/* Should be no difference when applied against themselves. */
487 	diff = vma_flags_diff_pair(&flags1, &flags1);
488 	ASSERT_FLAGS_EMPTY(&diff);
489 	diff = vma_flags_diff_pair(&flags2, &flags2);
490 	ASSERT_FLAGS_EMPTY(&diff);
491 
492 	/* One set of flags against an empty one should equal the original. */
493 	flags2 = EMPTY_VMA_FLAGS;
494 	diff = vma_flags_diff_pair(&flags1, &flags2);
495 	ASSERT_FLAGS_SAME_MASK(&diff, flags1);
496 
497 	/* A subset should work too. */
498 	flags2 = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT);
499 	diff = vma_flags_diff_pair(&flags1, &flags2);
500 #if NUM_VMA_FLAG_BITS > 64
501 	ASSERT_FLAGS_SAME(&diff, VMA_EXEC_BIT, 64, 65);
502 #else
503 	ASSERT_FLAGS_SAME(&diff, VMA_EXEC_BIT);
504 #endif
505 
506 	return true;
507 }
508 
509 /* Ensure that vma_flags_and() and friends work correctly. */
510 static bool test_vma_flags_and(void)
511 {
512 	vma_flags_t flags1 = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
513 					  VMA_EXEC_BIT
514 #if NUM_VMA_FLAG_BITS > 64
515 					       , 64, 65
516 #endif
517 		);
518 	vma_flags_t flags2 = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
519 					  VMA_EXEC_BIT, VMA_MAYWRITE_BIT,
520 					  VMA_MAYEXEC_BIT
521 #if NUM_VMA_FLAG_BITS > 64
522 					  , 64, 65, 66, 67
523 #endif
524 		);
525 	vma_flags_t flags3 = mk_vma_flags(VMA_IO_BIT, VMA_MAYBE_GUARD_BIT
526 #if NUM_VMA_FLAG_BITS > 64
527 					  , 68, 69
528 #endif
529 		);
530 	vma_flags_t and = vma_flags_and_mask(&flags1, flags2);
531 
532 #if NUM_VMA_FLAG_BITS > 64
533 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
534 			  64, 65);
535 #else
536 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
537 #endif
538 
539 	and = vma_flags_and_mask(&flags1, flags1);
540 	ASSERT_FLAGS_SAME_MASK(&and, flags1);
541 
542 	and = vma_flags_and_mask(&flags2, flags2);
543 	ASSERT_FLAGS_SAME_MASK(&and, flags2);
544 
545 	and = vma_flags_and_mask(&flags1, flags3);
546 	ASSERT_FLAGS_EMPTY(&and);
547 	and = vma_flags_and_mask(&flags2, flags3);
548 	ASSERT_FLAGS_EMPTY(&and);
549 
550 	and = vma_flags_and(&flags1, VMA_READ_BIT);
551 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT);
552 
553 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT);
554 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT);
555 
556 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
557 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
558 
559 #if NUM_VMA_FLAG_BITS > 64
560 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
561 			    64);
562 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64);
563 
564 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
565 			    64, 65);
566 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT, 64,
567 			  65);
568 #endif
569 
570 	/* And against some missing values. */
571 
572 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
573 			    VMA_IO_BIT);
574 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
575 
576 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
577 			    VMA_IO_BIT, VMA_RAND_READ_BIT);
578 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
579 
580 #if NUM_VMA_FLAG_BITS > 64
581 	and = vma_flags_and(&flags1, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT,
582 			    VMA_IO_BIT, VMA_RAND_READ_BIT, 69);
583 	ASSERT_FLAGS_SAME(&and, VMA_READ_BIT, VMA_WRITE_BIT, VMA_EXEC_BIT);
584 #endif
585 
586 	return true;
587 }
588 
589 /* Ensure append_vma_flags() acts as expected. */
590 static bool test_append_vma_flags(void)
591 {
592 	vma_flags_t flags = append_vma_flags(VMA_REMAP_FLAGS, VMA_READ_BIT,
593 					     VMA_WRITE_BIT
594 #if NUM_VMA_FLAG_BITS > 64
595 					     , 64, 65
596 #endif
597 		);
598 
599 	ASSERT_FLAGS_SAME(&flags, VMA_IO_BIT, VMA_PFNMAP_BIT,
600 			  VMA_DONTEXPAND_BIT, VMA_DONTDUMP_BIT, VMA_READ_BIT,
601 			  VMA_WRITE_BIT
602 #if NUM_VMA_FLAG_BITS > 64
603 					     , 64, 65
604 #endif
605 		);
606 
607 	flags = append_vma_flags(EMPTY_VMA_FLAGS, VMA_READ_BIT, VMA_WRITE_BIT);
608 	ASSERT_FLAGS_SAME(&flags, VMA_READ_BIT, VMA_WRITE_BIT);
609 
610 	return true;
611 }
612 
613 /* Assert that vma_flags_count() behaves as expected. */
614 static bool test_vma_flags_count(void)
615 {
616 	vma_flags_t flags = mk_vma_flags(VMA_READ_BIT, VMA_WRITE_BIT,
617 					 VMA_EXEC_BIT
618 #if NUM_VMA_FLAG_BITS > 64
619 					 , 64, 65
620 #endif
621 		);
622 
623 #if NUM_VMA_FLAG_BITS > 64
624 	ASSERT_EQ(vma_flags_count(&flags), 5);
625 	vma_flags_clear(&flags, 64);
626 	ASSERT_EQ(vma_flags_count(&flags), 4);
627 	vma_flags_clear(&flags, 65);
628 #endif
629 	ASSERT_EQ(vma_flags_count(&flags), 3);
630 	vma_flags_clear(&flags, VMA_EXEC_BIT);
631 	ASSERT_EQ(vma_flags_count(&flags), 2);
632 	vma_flags_clear(&flags, VMA_WRITE_BIT);
633 	ASSERT_EQ(vma_flags_count(&flags), 1);
634 	vma_flags_clear(&flags, VMA_READ_BIT);
635 	ASSERT_EQ(vma_flags_count(&flags), 0);
636 
637 	return true;
638 }
639 
640 static void run_vma_tests(int *num_tests, int *num_fail)
641 {
642 	TEST(copy_vma);
643 	TEST(vma_flags_unchanged);
644 	TEST(vma_flags_cleared);
645 #if NUM_VMA_FLAG_BITS > 64
646 	TEST(vma_flags_word);
647 #endif
648 	TEST(vma_flags_test);
649 	TEST(vma_flags_test_any);
650 	TEST(vma_flags_clear);
651 	TEST(vma_flags_empty);
652 	TEST(vma_flags_diff);
653 	TEST(vma_flags_and);
654 	TEST(append_vma_flags);
655 	TEST(vma_flags_count);
656 }
657