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