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