Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0-or-later
2
3static 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
29static 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
63static 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
103static 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 */
130static 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. */
175static 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. */
232static 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. */
337static 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. */
432static 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. */
455static 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. */
510static 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. */
590static 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. */
614static 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
640static 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}