1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2020 ARM Limited 3 4 #define _GNU_SOURCE 5 6 #include <assert.h> 7 #include <errno.h> 8 #include <fcntl.h> 9 #include <signal.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <ucontext.h> 14 #include <sys/mman.h> 15 #include <sys/stat.h> 16 #include <sys/types.h> 17 18 #include "kselftest.h" 19 #include "mte_common_util.h" 20 #include "mte_def.h" 21 22 #define RUNS (MT_TAG_COUNT) 23 #define UNDERFLOW MT_GRANULE_SIZE 24 #define OVERFLOW MT_GRANULE_SIZE 25 #define TAG_CHECK_ON 0 26 #define TAG_CHECK_OFF 1 27 #define ATAG_CHECK_ON 1 28 #define ATAG_CHECK_OFF 0 29 30 #define TEST_NAME_MAX 256 31 32 enum mte_mem_check_type { 33 CHECK_ANON_MEM = 0, 34 CHECK_FILE_MEM = 1, 35 CHECK_CLEAR_PROT_MTE = 2, 36 }; 37 38 struct check_mmap_testcase { 39 int check_type; 40 int mem_type; 41 int mte_sync; 42 int mapping; 43 int tag_check; 44 int atag_check; 45 bool enable_tco; 46 }; 47 48 static size_t page_size; 49 static int sizes[] = { 50 1, 537, 989, 1269, MT_GRANULE_SIZE - 1, MT_GRANULE_SIZE, 51 /* page size - 1*/ 0, /* page_size */ 0, /* page size + 1 */ 0 52 }; 53 54 static int check_mte_memory(char *ptr, int size, int mode, int tag_check, int atag_check) 55 { 56 if (!mtefar_support && atag_check == ATAG_CHECK_ON) 57 return KSFT_SKIP; 58 59 if (atag_check == ATAG_CHECK_ON) 60 ptr = mte_insert_atag(ptr); 61 62 mte_initialize_current_context(mode, (uintptr_t)ptr, size); 63 memset(ptr, '1', size); 64 mte_wait_after_trig(); 65 if (cur_mte_cxt.fault_valid == true) 66 return KSFT_FAIL; 67 68 mte_initialize_current_context(mode, (uintptr_t)ptr, -UNDERFLOW); 69 memset(ptr - UNDERFLOW, '2', UNDERFLOW); 70 mte_wait_after_trig(); 71 if (cur_mte_cxt.fault_valid == false && tag_check == TAG_CHECK_ON) 72 return KSFT_FAIL; 73 if (cur_mte_cxt.fault_valid == true && tag_check == TAG_CHECK_OFF) 74 return KSFT_FAIL; 75 76 mte_initialize_current_context(mode, (uintptr_t)ptr, size + OVERFLOW); 77 memset(ptr + size, '3', OVERFLOW); 78 mte_wait_after_trig(); 79 if (cur_mte_cxt.fault_valid == false && tag_check == TAG_CHECK_ON) 80 return KSFT_FAIL; 81 if (cur_mte_cxt.fault_valid == true && tag_check == TAG_CHECK_OFF) 82 return KSFT_FAIL; 83 84 return KSFT_PASS; 85 } 86 87 static int check_anonymous_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check) 88 { 89 char *ptr, *map_ptr; 90 int run, result, map_size; 91 int item = ARRAY_SIZE(sizes); 92 93 mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 94 for (run = 0; run < item; run++) { 95 map_size = sizes[run] + OVERFLOW + UNDERFLOW; 96 map_ptr = (char *)mte_allocate_memory(map_size, mem_type, mapping, false); 97 if (check_allocated_memory(map_ptr, map_size, mem_type, false) != KSFT_PASS) 98 return KSFT_FAIL; 99 100 ptr = map_ptr + UNDERFLOW; 101 mte_initialize_current_context(mode, (uintptr_t)ptr, sizes[run]); 102 /* Only mte enabled memory will allow tag insertion */ 103 ptr = mte_insert_tags((void *)ptr, sizes[run]); 104 if (!ptr || cur_mte_cxt.fault_valid == true) { 105 ksft_print_msg("FAIL: Insert tags on anonymous mmap memory\n"); 106 munmap((void *)map_ptr, map_size); 107 return KSFT_FAIL; 108 } 109 result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check); 110 mte_clear_tags((void *)ptr, sizes[run]); 111 mte_free_memory((void *)map_ptr, map_size, mem_type, false); 112 if (result != KSFT_PASS) 113 return result; 114 } 115 return KSFT_PASS; 116 } 117 118 static int check_file_memory_mapping(int mem_type, int mode, int mapping, int tag_check, int atag_check) 119 { 120 char *ptr, *map_ptr; 121 int run, fd, map_size; 122 int total = ARRAY_SIZE(sizes); 123 int result = KSFT_PASS; 124 125 mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 126 for (run = 0; run < total; run++) { 127 fd = create_temp_file(); 128 if (fd == -1) 129 return KSFT_FAIL; 130 131 map_size = sizes[run] + UNDERFLOW + OVERFLOW; 132 map_ptr = (char *)mte_allocate_file_memory(map_size, mem_type, mapping, false, fd); 133 if (check_allocated_memory(map_ptr, map_size, mem_type, false) != KSFT_PASS) { 134 close(fd); 135 return KSFT_FAIL; 136 } 137 ptr = map_ptr + UNDERFLOW; 138 mte_initialize_current_context(mode, (uintptr_t)ptr, sizes[run]); 139 /* Only mte enabled memory will allow tag insertion */ 140 ptr = mte_insert_tags((void *)ptr, sizes[run]); 141 if (!ptr || cur_mte_cxt.fault_valid == true) { 142 ksft_print_msg("FAIL: Insert tags on file based memory\n"); 143 munmap((void *)map_ptr, map_size); 144 close(fd); 145 return KSFT_FAIL; 146 } 147 result = check_mte_memory(ptr, sizes[run], mode, tag_check, atag_check); 148 mte_clear_tags((void *)ptr, sizes[run]); 149 munmap((void *)map_ptr, map_size); 150 close(fd); 151 if (result != KSFT_PASS) 152 return result; 153 } 154 return KSFT_PASS; 155 } 156 157 static int check_clear_prot_mte_flag(int mem_type, int mode, int mapping, int atag_check) 158 { 159 char *ptr, *map_ptr; 160 int run, prot_flag, result, fd, map_size; 161 int total = ARRAY_SIZE(sizes); 162 163 prot_flag = PROT_READ | PROT_WRITE; 164 mte_switch_mode(mode, MTE_ALLOW_NON_ZERO_TAG); 165 for (run = 0; run < total; run++) { 166 map_size = sizes[run] + OVERFLOW + UNDERFLOW; 167 ptr = (char *)mte_allocate_memory_tag_range(sizes[run], mem_type, mapping, 168 UNDERFLOW, OVERFLOW); 169 if (check_allocated_memory_range(ptr, sizes[run], mem_type, 170 UNDERFLOW, OVERFLOW) != KSFT_PASS) 171 return KSFT_FAIL; 172 map_ptr = ptr - UNDERFLOW; 173 /* Try to clear PROT_MTE property and verify it by tag checking */ 174 if (mprotect(map_ptr, map_size, prot_flag)) { 175 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, 176 UNDERFLOW, OVERFLOW); 177 ksft_print_msg("FAIL: mprotect not ignoring clear PROT_MTE property\n"); 178 return KSFT_FAIL; 179 } 180 result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check); 181 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW); 182 if (result != KSFT_PASS) 183 return KSFT_FAIL; 184 185 fd = create_temp_file(); 186 if (fd == -1) 187 return KSFT_FAIL; 188 ptr = (char *)mte_allocate_file_memory_tag_range(sizes[run], mem_type, mapping, 189 UNDERFLOW, OVERFLOW, fd); 190 if (check_allocated_memory_range(ptr, sizes[run], mem_type, 191 UNDERFLOW, OVERFLOW) != KSFT_PASS) { 192 close(fd); 193 return KSFT_FAIL; 194 } 195 map_ptr = ptr - UNDERFLOW; 196 /* Try to clear PROT_MTE property and verify it by tag checking */ 197 if (mprotect(map_ptr, map_size, prot_flag)) { 198 ksft_print_msg("FAIL: mprotect not ignoring clear PROT_MTE property\n"); 199 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, 200 UNDERFLOW, OVERFLOW); 201 close(fd); 202 return KSFT_FAIL; 203 } 204 result = check_mte_memory(ptr, sizes[run], mode, TAG_CHECK_ON, atag_check); 205 mte_free_memory_tag_range((void *)ptr, sizes[run], mem_type, UNDERFLOW, OVERFLOW); 206 close(fd); 207 if (result != KSFT_PASS) 208 return result; 209 } 210 return KSFT_PASS; 211 } 212 213 const char *format_test_name(struct check_mmap_testcase *tc) 214 { 215 static char test_name[TEST_NAME_MAX]; 216 const char *check_type_str; 217 const char *mem_type_str; 218 const char *sync_str; 219 const char *mapping_str; 220 const char *tag_check_str; 221 const char *atag_check_str; 222 223 switch (tc->check_type) { 224 case CHECK_ANON_MEM: 225 check_type_str = "anonymous memory"; 226 break; 227 case CHECK_FILE_MEM: 228 check_type_str = "file memory"; 229 break; 230 case CHECK_CLEAR_PROT_MTE: 231 check_type_str = "clear PROT_MTE flags"; 232 break; 233 default: 234 assert(0); 235 break; 236 } 237 238 switch (tc->mem_type) { 239 case USE_MMAP: 240 mem_type_str = "mmap"; 241 break; 242 case USE_MPROTECT: 243 mem_type_str = "mmap/mprotect"; 244 break; 245 default: 246 assert(0); 247 break; 248 } 249 250 switch (tc->mte_sync) { 251 case MTE_NONE_ERR: 252 sync_str = "no error"; 253 break; 254 case MTE_SYNC_ERR: 255 sync_str = "sync error"; 256 break; 257 case MTE_ASYNC_ERR: 258 sync_str = "async error"; 259 break; 260 default: 261 assert(0); 262 break; 263 } 264 265 switch (tc->mapping) { 266 case MAP_SHARED: 267 mapping_str = "shared"; 268 break; 269 case MAP_PRIVATE: 270 mapping_str = "private"; 271 break; 272 default: 273 assert(0); 274 break; 275 } 276 277 switch (tc->tag_check) { 278 case TAG_CHECK_ON: 279 tag_check_str = "tag check on"; 280 break; 281 case TAG_CHECK_OFF: 282 tag_check_str = "tag check off"; 283 break; 284 default: 285 assert(0); 286 break; 287 } 288 289 switch (tc->atag_check) { 290 case ATAG_CHECK_ON: 291 atag_check_str = "with address tag [63:60]"; 292 break; 293 case ATAG_CHECK_OFF: 294 atag_check_str = "without address tag [63:60]"; 295 break; 296 default: 297 assert(0); 298 break; 299 } 300 301 snprintf(test_name, sizeof(test_name), 302 "Check %s with %s mapping, %s mode, %s memory and %s (%s)\n", 303 check_type_str, mapping_str, sync_str, mem_type_str, 304 tag_check_str, atag_check_str); 305 306 return test_name; 307 } 308 309 int main(int argc, char *argv[]) 310 { 311 int err, i; 312 int item = ARRAY_SIZE(sizes); 313 struct check_mmap_testcase test_cases[]= { 314 { 315 .check_type = CHECK_ANON_MEM, 316 .mem_type = USE_MMAP, 317 .mte_sync = MTE_SYNC_ERR, 318 .mapping = MAP_PRIVATE, 319 .tag_check = TAG_CHECK_OFF, 320 .atag_check = ATAG_CHECK_OFF, 321 .enable_tco = true, 322 }, 323 { 324 .check_type = CHECK_FILE_MEM, 325 .mem_type = USE_MPROTECT, 326 .mte_sync = MTE_SYNC_ERR, 327 .mapping = MAP_PRIVATE, 328 .tag_check = TAG_CHECK_OFF, 329 .atag_check = ATAG_CHECK_OFF, 330 .enable_tco = true, 331 }, 332 { 333 .check_type = CHECK_ANON_MEM, 334 .mem_type = USE_MMAP, 335 .mte_sync = MTE_NONE_ERR, 336 .mapping = MAP_PRIVATE, 337 .tag_check = TAG_CHECK_OFF, 338 .atag_check = ATAG_CHECK_OFF, 339 .enable_tco = false, 340 }, 341 { 342 .check_type = CHECK_FILE_MEM, 343 .mem_type = USE_MPROTECT, 344 .mte_sync = MTE_NONE_ERR, 345 .mapping = MAP_PRIVATE, 346 .tag_check = TAG_CHECK_OFF, 347 .atag_check = ATAG_CHECK_OFF, 348 .enable_tco = false, 349 }, 350 { 351 .check_type = CHECK_ANON_MEM, 352 .mem_type = USE_MMAP, 353 .mte_sync = MTE_SYNC_ERR, 354 .mapping = MAP_PRIVATE, 355 .tag_check = TAG_CHECK_ON, 356 .atag_check = ATAG_CHECK_OFF, 357 .enable_tco = false, 358 }, 359 { 360 .check_type = CHECK_ANON_MEM, 361 .mem_type = USE_MPROTECT, 362 .mte_sync = MTE_SYNC_ERR, 363 .mapping = MAP_PRIVATE, 364 .tag_check = TAG_CHECK_ON, 365 .atag_check = ATAG_CHECK_OFF, 366 .enable_tco = false, 367 }, 368 { 369 .check_type = CHECK_ANON_MEM, 370 .mem_type = USE_MMAP, 371 .mte_sync = MTE_SYNC_ERR, 372 .mapping = MAP_SHARED, 373 .tag_check = TAG_CHECK_ON, 374 .atag_check = ATAG_CHECK_OFF, 375 .enable_tco = false, 376 }, 377 { 378 .check_type = CHECK_ANON_MEM, 379 .mem_type = USE_MPROTECT, 380 .mte_sync = MTE_SYNC_ERR, 381 .mapping = MAP_SHARED, 382 .tag_check = TAG_CHECK_ON, 383 .atag_check = ATAG_CHECK_OFF, 384 .enable_tco = false, 385 }, 386 { 387 .check_type = CHECK_ANON_MEM, 388 .mem_type = USE_MMAP, 389 .mte_sync = MTE_ASYNC_ERR, 390 .mapping = MAP_PRIVATE, 391 .tag_check = TAG_CHECK_ON, 392 .atag_check = ATAG_CHECK_OFF, 393 .enable_tco = false, 394 }, 395 { 396 .check_type = CHECK_ANON_MEM, 397 .mem_type = USE_MPROTECT, 398 .mte_sync = MTE_ASYNC_ERR, 399 .mapping = MAP_PRIVATE, 400 .tag_check = TAG_CHECK_ON, 401 .atag_check = ATAG_CHECK_OFF, 402 .enable_tco = false, 403 }, 404 { 405 .check_type = CHECK_ANON_MEM, 406 .mem_type = USE_MMAP, 407 .mte_sync = MTE_ASYNC_ERR, 408 .mapping = MAP_SHARED, 409 .tag_check = TAG_CHECK_ON, 410 .atag_check = ATAG_CHECK_OFF, 411 .enable_tco = false, 412 }, 413 { 414 .check_type = CHECK_ANON_MEM, 415 .mem_type = USE_MPROTECT, 416 .mte_sync = MTE_ASYNC_ERR, 417 .mapping = MAP_SHARED, 418 .tag_check = TAG_CHECK_ON, 419 .atag_check = ATAG_CHECK_OFF, 420 .enable_tco = false, 421 }, 422 { 423 .check_type = CHECK_FILE_MEM, 424 .mem_type = USE_MMAP, 425 .mte_sync = MTE_SYNC_ERR, 426 .mapping = MAP_PRIVATE, 427 .tag_check = TAG_CHECK_ON, 428 .atag_check = ATAG_CHECK_OFF, 429 .enable_tco = false, 430 }, 431 { 432 .check_type = CHECK_FILE_MEM, 433 .mem_type = USE_MPROTECT, 434 .mte_sync = MTE_SYNC_ERR, 435 .mapping = MAP_PRIVATE, 436 .tag_check = TAG_CHECK_ON, 437 .atag_check = ATAG_CHECK_OFF, 438 .enable_tco = false, 439 }, 440 { 441 .check_type = CHECK_FILE_MEM, 442 .mem_type = USE_MMAP, 443 .mte_sync = MTE_SYNC_ERR, 444 .mapping = MAP_SHARED, 445 .tag_check = TAG_CHECK_ON, 446 .atag_check = ATAG_CHECK_OFF, 447 .enable_tco = false, 448 }, 449 { 450 .check_type = CHECK_FILE_MEM, 451 .mem_type = USE_MPROTECT, 452 .mte_sync = MTE_SYNC_ERR, 453 .mapping = MAP_SHARED, 454 .tag_check = TAG_CHECK_ON, 455 .atag_check = ATAG_CHECK_OFF, 456 .enable_tco = false, 457 }, 458 { 459 .check_type = CHECK_FILE_MEM, 460 .mem_type = USE_MMAP, 461 .mte_sync = MTE_ASYNC_ERR, 462 .mapping = MAP_PRIVATE, 463 .tag_check = TAG_CHECK_ON, 464 .atag_check = ATAG_CHECK_OFF, 465 .enable_tco = false, 466 }, 467 { 468 .check_type = CHECK_FILE_MEM, 469 .mem_type = USE_MPROTECT, 470 .mte_sync = MTE_ASYNC_ERR, 471 .mapping = MAP_PRIVATE, 472 .tag_check = TAG_CHECK_ON, 473 .atag_check = ATAG_CHECK_OFF, 474 .enable_tco = false, 475 }, 476 { 477 .check_type = CHECK_FILE_MEM, 478 .mem_type = USE_MMAP, 479 .mte_sync = MTE_ASYNC_ERR, 480 .mapping = MAP_SHARED, 481 .tag_check = TAG_CHECK_ON, 482 .atag_check = ATAG_CHECK_OFF, 483 .enable_tco = false, 484 }, 485 { 486 .check_type = CHECK_FILE_MEM, 487 .mem_type = USE_MPROTECT, 488 .mte_sync = MTE_ASYNC_ERR, 489 .mapping = MAP_SHARED, 490 .tag_check = TAG_CHECK_ON, 491 .atag_check = ATAG_CHECK_OFF, 492 .enable_tco = false, 493 }, 494 { 495 .check_type = CHECK_CLEAR_PROT_MTE, 496 .mem_type = USE_MMAP, 497 .mte_sync = MTE_SYNC_ERR, 498 .mapping = MAP_PRIVATE, 499 .tag_check = TAG_CHECK_ON, 500 .atag_check = ATAG_CHECK_OFF, 501 .enable_tco = false, 502 }, 503 { 504 .check_type = CHECK_CLEAR_PROT_MTE, 505 .mem_type = USE_MPROTECT, 506 .mte_sync = MTE_SYNC_ERR, 507 .mapping = MAP_PRIVATE, 508 .tag_check = TAG_CHECK_ON, 509 .atag_check = ATAG_CHECK_OFF, 510 .enable_tco = false, 511 }, 512 { 513 .check_type = CHECK_ANON_MEM, 514 .mem_type = USE_MMAP, 515 .mte_sync = MTE_SYNC_ERR, 516 .mapping = MAP_PRIVATE, 517 .tag_check = TAG_CHECK_ON, 518 .atag_check = ATAG_CHECK_ON, 519 .enable_tco = false, 520 }, 521 { 522 .check_type = CHECK_ANON_MEM, 523 .mem_type = USE_MPROTECT, 524 .mte_sync = MTE_SYNC_ERR, 525 .mapping = MAP_PRIVATE, 526 .tag_check = TAG_CHECK_ON, 527 .atag_check = ATAG_CHECK_ON, 528 .enable_tco = false, 529 }, 530 { 531 .check_type = CHECK_ANON_MEM, 532 .mem_type = USE_MMAP, 533 .mte_sync = MTE_SYNC_ERR, 534 .mapping = MAP_SHARED, 535 .tag_check = TAG_CHECK_ON, 536 .atag_check = ATAG_CHECK_ON, 537 .enable_tco = false, 538 }, 539 { 540 .check_type = CHECK_ANON_MEM, 541 .mem_type = USE_MPROTECT, 542 .mte_sync = MTE_SYNC_ERR, 543 .mapping = MAP_SHARED, 544 .tag_check = TAG_CHECK_ON, 545 .atag_check = ATAG_CHECK_ON, 546 .enable_tco = false, 547 }, 548 { 549 .check_type = CHECK_FILE_MEM, 550 .mem_type = USE_MMAP, 551 .mte_sync = MTE_SYNC_ERR, 552 .mapping = MAP_PRIVATE, 553 .tag_check = TAG_CHECK_ON, 554 .atag_check = ATAG_CHECK_ON, 555 .enable_tco = false, 556 }, 557 { 558 .check_type = CHECK_FILE_MEM, 559 .mem_type = USE_MPROTECT, 560 .mte_sync = MTE_SYNC_ERR, 561 .mapping = MAP_PRIVATE, 562 .tag_check = TAG_CHECK_ON, 563 .atag_check = ATAG_CHECK_ON, 564 .enable_tco = false, 565 }, 566 { 567 .check_type = CHECK_FILE_MEM, 568 .mem_type = USE_MMAP, 569 .mte_sync = MTE_SYNC_ERR, 570 .mapping = MAP_SHARED, 571 .tag_check = TAG_CHECK_ON, 572 .atag_check = ATAG_CHECK_ON, 573 .enable_tco = false, 574 }, 575 { 576 .check_type = CHECK_FILE_MEM, 577 .mem_type = USE_MPROTECT, 578 .mte_sync = MTE_SYNC_ERR, 579 .mapping = MAP_SHARED, 580 .tag_check = TAG_CHECK_ON, 581 .atag_check = ATAG_CHECK_ON, 582 .enable_tco = false, 583 }, 584 { 585 .check_type = CHECK_FILE_MEM, 586 .mem_type = USE_MMAP, 587 .mte_sync = MTE_ASYNC_ERR, 588 .mapping = MAP_PRIVATE, 589 .tag_check = TAG_CHECK_ON, 590 .atag_check = ATAG_CHECK_ON, 591 .enable_tco = false, 592 }, 593 { 594 .check_type = CHECK_CLEAR_PROT_MTE, 595 .mem_type = USE_MMAP, 596 .mte_sync = MTE_SYNC_ERR, 597 .mapping = MAP_PRIVATE, 598 .tag_check = TAG_CHECK_ON, 599 .atag_check = ATAG_CHECK_ON, 600 .enable_tco = false, 601 }, 602 { 603 .check_type = CHECK_CLEAR_PROT_MTE, 604 .mem_type = USE_MPROTECT, 605 .mte_sync = MTE_SYNC_ERR, 606 .mapping = MAP_PRIVATE, 607 .tag_check = TAG_CHECK_ON, 608 .atag_check = ATAG_CHECK_ON, 609 .enable_tco = false, 610 }, 611 }; 612 613 err = mte_default_setup(); 614 if (err) 615 return err; 616 page_size = getpagesize(); 617 if (!page_size) { 618 ksft_print_msg("ERR: Unable to get page size\n"); 619 return KSFT_FAIL; 620 } 621 sizes[item - 3] = page_size - 1; 622 sizes[item - 2] = page_size; 623 sizes[item - 1] = page_size + 1; 624 625 /* Set test plan */ 626 ksft_set_plan(ARRAY_SIZE(test_cases)); 627 628 for (i = 0 ; i < ARRAY_SIZE(test_cases); i++) { 629 /* Register signal handlers */ 630 mte_register_signal(SIGBUS, mte_default_handler, 631 test_cases[i].atag_check == ATAG_CHECK_ON); 632 mte_register_signal(SIGSEGV, mte_default_handler, 633 test_cases[i].atag_check == ATAG_CHECK_ON); 634 635 if (test_cases[i].enable_tco) 636 mte_enable_pstate_tco(); 637 else 638 mte_disable_pstate_tco(); 639 640 switch (test_cases[i].check_type) { 641 case CHECK_ANON_MEM: 642 evaluate_test(check_anonymous_memory_mapping(test_cases[i].mem_type, 643 test_cases[i].mte_sync, 644 test_cases[i].mapping, 645 test_cases[i].tag_check, 646 test_cases[i].atag_check), 647 format_test_name(&test_cases[i])); 648 break; 649 case CHECK_FILE_MEM: 650 evaluate_test(check_file_memory_mapping(test_cases[i].mem_type, 651 test_cases[i].mte_sync, 652 test_cases[i].mapping, 653 test_cases[i].tag_check, 654 test_cases[i].atag_check), 655 format_test_name(&test_cases[i])); 656 break; 657 case CHECK_CLEAR_PROT_MTE: 658 evaluate_test(check_clear_prot_mte_flag(test_cases[i].mem_type, 659 test_cases[i].mte_sync, 660 test_cases[i].mapping, 661 test_cases[i].atag_check), 662 format_test_name(&test_cases[i])); 663 break; 664 default: 665 exit(KSFT_FAIL); 666 } 667 } 668 669 mte_restore_setup(); 670 ksft_print_cnts(); 671 return ksft_get_fail_cnt() == 0 ? KSFT_PASS : KSFT_FAIL; 672 } 673