1 // SPDX-License-Identifier: GPL-2.0-or-later
2
compare_legacy_flags(vm_flags_t legacy_flags,vma_flags_t flags)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
test_copy_vma(void)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
test_vma_flags_unchanged(void)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
test_vma_flags_cleared(void)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 */
test_vma_flags_word(void)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. */
test_vma_flags_test(void)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. */
test_vma_flags_test_any(void)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. */
test_vma_flags_clear(void)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. */
test_vma_flags_empty(void)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. */
test_vma_flags_diff(void)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. */
test_vma_flags_and(void)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. */
test_append_vma_flags(void)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. */
test_vma_flags_count(void)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
run_vma_tests(int * num_tests,int * num_fail)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