1 /* $NetBSD: t_ufetchstore.c,v 1.1 2019/04/15 23:41:23 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2019 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 __COPYRIGHT("@(#) Copyright (c) 2019\ 34 The NetBSD Foundation, inc. All rights reserved."); 35 __RCSID("$NetBSD: t_ufetchstore.c,v 1.1 2019/04/15 23:41:23 christos Exp $"); 36 37 #include <sys/types.h> 38 #include <sys/endian.h> 39 #include <sys/module.h> 40 #include <sys/sysctl.h> 41 42 #include <err.h> 43 #include <errno.h> 44 #include <limits.h> 45 46 #include <atf-c.h> 47 48 #include "common.h" 49 50 #define mib_name "kern.ufetchstore_test.test" 51 52 static bool module_loaded; 53 54 #define MODULE_PATH \ 55 "/usr/tests/modules/ufetchstore_tester/ufetchstore_tester.kmod" 56 #define MODULE_NAME "ufetchstore_tester" 57 58 #define CHECK_MODULE() \ 59 do { \ 60 load_module(); \ 61 if (! module_loaded) { \ 62 atf_tc_skip("loading '%s' module failed.", MODULE_NAME);\ 63 } \ 64 } while (/*CONSTCOND*/0) 65 66 static void 67 load_module(void) 68 { 69 #ifndef SKIP_MODULE 70 if (module_loaded) 71 return; 72 73 modctl_load_t params = { 74 .ml_filename = MODULE_PATH, 75 .ml_flags = MODCTL_NO_PROP, 76 }; 77 78 if (modctl(MODCTL_LOAD, ¶ms) != 0) { 79 warn("failed to load module '%s'", MODULE_PATH); 80 } else { 81 module_loaded = true; 82 } 83 #else 84 module_loaded = true; 85 #endif /* ! SKIP_MODULE */ 86 } 87 88 #define UADDR(x) ((uintptr_t)(x)) 89 90 static void 91 unload_module(void) 92 { 93 #ifndef SKIP_MODULE 94 char module_name[] = MODULE_NAME; 95 96 if (modctl(MODCTL_UNLOAD, module_name) != 0) { 97 warn("failed to unload module '%s'", MODULE_NAME); 98 } else { 99 module_loaded = false; 100 } 101 #endif /* ! SKIP_MODULE */ 102 } 103 104 static unsigned long 105 vm_max_address_raw(void) 106 { 107 static unsigned long max_addr = 0; 108 int rv; 109 110 if (max_addr == 0) { 111 size_t max_addr_size = sizeof(max_addr); 112 rv = sysctlbyname("vm.maxaddress", &max_addr, &max_addr_size, 113 NULL, 0); 114 if (rv != 0) 115 err(1, "sysctlbyname('vm.maxaddress')"); 116 } 117 return max_addr; 118 } 119 120 static void * 121 vm_max_address(void) 122 { 123 return (void *)vm_max_address_raw(); 124 } 125 126 static void * 127 vm_max_address_minus(unsigned int adj) 128 { 129 return (void *)(vm_max_address_raw() - adj); 130 } 131 132 static int 133 do_sysctl(struct ufetchstore_test_args *args) 134 { 135 uint64_t arg_addr64 = (uintptr_t)args; 136 int rv; 137 138 args->fetchstore_error = EBADF; /* poison */ 139 args->pointer_size = (int)sizeof(void *); 140 141 /* 142 * Yes, the intent is to provide the pointer, not the structure, 143 * to the kernel side of the test harness. 144 */ 145 rv = sysctlbyname(mib_name, NULL, NULL, &arg_addr64, 146 sizeof(arg_addr64)); 147 if (rv != 0) { 148 rv = errno; 149 warn("sysctlbyname('%s') -> %d", mib_name, rv); 150 return rv; 151 } 152 return 0; 153 } 154 155 static int 156 do_ufetch_8(const uint8_t *uaddr, uint8_t *res) 157 { 158 struct ufetchstore_test_args args = { 159 .uaddr64 = UADDR(uaddr), 160 .test_op = OP_LOAD, 161 .size = 8, 162 }; 163 164 ATF_REQUIRE_EQ(do_sysctl(&args), 0); 165 *res = args.val8; 166 return args.fetchstore_error; 167 } 168 169 static int 170 do_ufetch_16(const uint16_t *uaddr, uint16_t *res) 171 { 172 struct ufetchstore_test_args args = { 173 .uaddr64 = UADDR(uaddr), 174 .test_op = OP_LOAD, 175 .size = 16, 176 }; 177 178 ATF_REQUIRE_EQ(do_sysctl(&args), 0); 179 *res = args.val16; 180 return args.fetchstore_error; 181 } 182 183 static int 184 do_ufetch_32(const uint32_t *uaddr, uint32_t *res) 185 { 186 struct ufetchstore_test_args args = { 187 .uaddr64 = UADDR(uaddr), 188 .test_op = OP_LOAD, 189 .size = 32, 190 }; 191 192 ATF_REQUIRE_EQ(do_sysctl(&args), 0); 193 *res = args.val32; 194 return args.fetchstore_error; 195 } 196 197 #ifdef _LP64 198 static int 199 do_ufetch_64(const uint64_t *uaddr, uint64_t *res) 200 { 201 struct ufetchstore_test_args args = { 202 .uaddr64 = UADDR(uaddr), 203 .test_op = OP_LOAD, 204 .size = 64, 205 }; 206 207 ATF_REQUIRE_EQ(do_sysctl(&args), 0); 208 *res = args.val64; 209 return args.fetchstore_error; 210 } 211 #endif /* _LP64 */ 212 213 static int 214 do_ustore_8(uint8_t *uaddr, uint8_t val) 215 { 216 struct ufetchstore_test_args args = { 217 .uaddr64 = UADDR(uaddr), 218 .test_op = OP_STORE, 219 .size = 8, 220 .val8 = val, 221 }; 222 223 ATF_REQUIRE_EQ(do_sysctl(&args), 0); 224 return args.fetchstore_error; 225 } 226 227 static int 228 do_ustore_16(uint16_t *uaddr, uint16_t val) 229 { 230 struct ufetchstore_test_args args = { 231 .uaddr64 = UADDR(uaddr), 232 .test_op = OP_STORE, 233 .size = 16, 234 .val16 = val, 235 }; 236 237 ATF_REQUIRE_EQ(do_sysctl(&args), 0); 238 return args.fetchstore_error; 239 } 240 241 static int 242 do_ustore_32(uint32_t *uaddr, uint32_t val) 243 { 244 struct ufetchstore_test_args args = { 245 .uaddr64 = UADDR(uaddr), 246 .test_op = OP_STORE, 247 .size = 32, 248 .val32 = val, 249 }; 250 251 ATF_REQUIRE_EQ(do_sysctl(&args), 0); 252 return args.fetchstore_error; 253 } 254 255 #ifdef _LP64 256 static int 257 do_ustore_64(uint64_t *uaddr, uint64_t val) 258 { 259 struct ufetchstore_test_args args = { 260 .uaddr64 = UADDR(uaddr), 261 .test_op = OP_STORE, 262 .size = 64, 263 .val64 = val, 264 }; 265 266 ATF_REQUIRE_EQ(do_sysctl(&args), 0); 267 return args.fetchstore_error; 268 } 269 #endif /* _LP64 */ 270 271 static int 272 do_ucas_32(uint32_t *uaddr, uint32_t expected, uint32_t new, uint32_t *actualp) 273 { 274 struct ufetchstore_test_args args = { 275 .uaddr64 = UADDR(uaddr), 276 .test_op = OP_CAS, 277 .size = 32, 278 .val32 = new, 279 .ea_val32 = expected, 280 }; 281 282 ATF_REQUIRE_EQ(do_sysctl(&args), 0); 283 *actualp = args.ea_val32; 284 return args.fetchstore_error; 285 } 286 287 #ifdef _LP64 288 static int 289 do_ucas_64(uint64_t *uaddr, uint64_t expected, uint64_t new, uint64_t *actualp) 290 { 291 struct ufetchstore_test_args args = { 292 .uaddr64 = UADDR(uaddr), 293 .test_op = OP_CAS, 294 .size = 64, 295 .val64 = new, 296 .ea_val64 = expected, 297 }; 298 299 ATF_REQUIRE_EQ(do_sysctl(&args), 0); 300 *actualp = args.ea_val64; 301 return args.fetchstore_error; 302 } 303 #endif /* _LP64 */ 304 305 struct memory_cell { 306 unsigned long guard0; 307 union { 308 unsigned long test_cell; 309 #ifdef _LP64 310 uint64_t val64; 311 #endif 312 uint32_t val32[sizeof(long) / 4]; 313 uint16_t val16[sizeof(long) / 2]; 314 uint8_t val8 [sizeof(long) ]; 315 }; 316 unsigned long guard1; 317 }; 318 319 #define index8 1 320 #define index16 1 321 #define index32 0 322 323 #define test_pattern8 0xa5 324 #define test_pattern16 0x5a6b 325 #define test_pattern32 0xb01cafe1 326 #ifdef _LP64 327 #define test_pattern64 0xcafedeadfeedbabe 328 #endif 329 330 #if _BYTE_ORDER == _LITTLE_ENDIAN 331 #define test_cell_val8 ((unsigned long)test_pattern8 << (index8 * NBBY)) 332 #define test_cell_val16 ((unsigned long)test_pattern16 << (index16 * NBBY*2)) 333 #define test_cell_val32 ((unsigned long)test_pattern32 << (index32 * NBBY*4)) 334 #ifdef _LP64 335 #define test_cell_val64 ((unsigned long)test_pattern64) 336 #endif 337 #endif /* _BYTE_ORDER == _LITTLE_ENDIAN */ 338 339 #if _BYTE_ORDER == _BIG_ENDIAN 340 #ifdef _LP64 341 #define test_cell_val8 ((unsigned long)test_pattern8 << (56-(index8 * NBBY))) 342 #define test_cell_val16 ((unsigned long)test_pattern16 << (48-(index16 * NBBY*2))) 343 #define test_cell_val32 ((unsigned long)test_pattern32 << (32-(index32 * NBBY*4))) 344 #define test_cell_val64 ((unsigned long)test_pattern64) 345 #else /* ! _LP64 */ 346 #define test_cell_val8 ((unsigned long)test_pattern8 << (24-(index8 * NBBY))) 347 #define test_cell_val16 ((unsigned long)test_pattern16 << (16-(index16 * NBBY*2))) 348 #define test_cell_val32 ((unsigned long)test_pattern32) 349 #endif /* _LP64 */ 350 #endif /* #if _BYTE_ORDER == _BIG_ENDIAN */ 351 352 #define read_test_cell(cell) (cell)->test_cell 353 #define write_test_cell(cell, v) (cell)->test_cell = (v) 354 355 #define memory_cell_initializer \ 356 { \ 357 .guard0 = ULONG_MAX, \ 358 .test_cell = 0, \ 359 .guard1 = ULONG_MAX, \ 360 } 361 362 static bool 363 memory_cell_check_guard(const struct memory_cell * const cell) 364 { 365 return cell->guard0 == ULONG_MAX && 366 cell->guard1 == ULONG_MAX; 367 } 368 369 ATF_TC_WITH_CLEANUP(ufetch_8); 370 ATF_TC_HEAD(ufetch_8, tc) 371 { 372 atf_tc_set_md_var(tc, "descr", 373 "test for correct ufetch_8 behavior"); 374 } 375 ATF_TC_BODY(ufetch_8, tc) 376 { 377 struct memory_cell cell = memory_cell_initializer; 378 uint8_t res; 379 380 CHECK_MODULE(); 381 382 write_test_cell(&cell, test_cell_val8); 383 ATF_REQUIRE_EQ(do_ufetch_8(&cell.val8[index8], &res), 0); 384 ATF_REQUIRE(memory_cell_check_guard(&cell)); 385 ATF_REQUIRE(res == test_pattern8); 386 } 387 ATF_TC_CLEANUP(ufetch_8, tc) 388 { 389 unload_module(); 390 } 391 392 ATF_TC_WITH_CLEANUP(ufetch_16); 393 ATF_TC_HEAD(ufetch_16, tc) 394 { 395 atf_tc_set_md_var(tc, "descr", 396 "test for correct ufetch_16 behavior"); 397 } 398 ATF_TC_BODY(ufetch_16, tc) 399 { 400 struct memory_cell cell = memory_cell_initializer; 401 uint16_t res; 402 403 CHECK_MODULE(); 404 405 write_test_cell(&cell, test_cell_val16); 406 ATF_REQUIRE_EQ(do_ufetch_16(&cell.val16[index16], &res), 0); 407 ATF_REQUIRE(memory_cell_check_guard(&cell)); 408 ATF_REQUIRE(res == test_pattern16); 409 } 410 ATF_TC_CLEANUP(ufetch_16, tc) 411 { 412 unload_module(); 413 } 414 415 ATF_TC_WITH_CLEANUP(ufetch_32); 416 ATF_TC_HEAD(ufetch_32, tc) 417 { 418 atf_tc_set_md_var(tc, "descr", 419 "test for correct ufetch_32 behavior"); 420 } 421 ATF_TC_BODY(ufetch_32, tc) 422 { 423 struct memory_cell cell = memory_cell_initializer; 424 uint32_t res; 425 426 CHECK_MODULE(); 427 428 write_test_cell(&cell, test_cell_val32); 429 ATF_REQUIRE_EQ(do_ufetch_32(&cell.val32[index32], &res), 0); 430 ATF_REQUIRE(memory_cell_check_guard(&cell)); 431 ATF_REQUIRE(res == test_pattern32); 432 } 433 ATF_TC_CLEANUP(ufetch_32, tc) 434 { 435 unload_module(); 436 } 437 438 #ifdef _LP64 439 ATF_TC_WITH_CLEANUP(ufetch_64); 440 ATF_TC_HEAD(ufetch_64, tc) 441 { 442 atf_tc_set_md_var(tc, "descr", 443 "test for correct ufetch_64 behavior"); 444 } 445 ATF_TC_BODY(ufetch_64, tc) 446 { 447 struct memory_cell cell = memory_cell_initializer; 448 uint64_t res; 449 450 CHECK_MODULE(); 451 452 write_test_cell(&cell, test_cell_val64); 453 ATF_REQUIRE_EQ(do_ufetch_64(&cell.val64, &res), 0); 454 ATF_REQUIRE(memory_cell_check_guard(&cell)); 455 ATF_REQUIRE(res == test_pattern64); 456 } 457 ATF_TC_CLEANUP(ufetch_64, tc) 458 { 459 unload_module(); 460 } 461 #endif /* _LP64 */ 462 463 ATF_TC_WITH_CLEANUP(ufetch_8_null); 464 ATF_TC_HEAD(ufetch_8_null, tc) 465 { 466 atf_tc_set_md_var(tc, "descr", 467 "test for correct ufetch_8 NULL pointer behavior"); 468 } 469 ATF_TC_BODY(ufetch_8_null, tc) 470 { 471 uint8_t res; 472 473 CHECK_MODULE(); 474 475 ATF_REQUIRE_EQ(do_ufetch_8(NULL, &res), EFAULT); 476 } 477 ATF_TC_CLEANUP(ufetch_8_null, tc) 478 { 479 unload_module(); 480 } 481 482 ATF_TC_WITH_CLEANUP(ufetch_16_null); 483 ATF_TC_HEAD(ufetch_16_null, tc) 484 { 485 atf_tc_set_md_var(tc, "descr", 486 "test for correct ufetch_16 NULL pointer behavior"); 487 } 488 ATF_TC_BODY(ufetch_16_null, tc) 489 { 490 uint16_t res; 491 492 CHECK_MODULE(); 493 494 ATF_REQUIRE_EQ(do_ufetch_16(NULL, &res), EFAULT); 495 } 496 ATF_TC_CLEANUP(ufetch_16_null, tc) 497 { 498 unload_module(); 499 } 500 501 ATF_TC_WITH_CLEANUP(ufetch_32_null); 502 ATF_TC_HEAD(ufetch_32_null, tc) 503 { 504 atf_tc_set_md_var(tc, "descr", 505 "test for correct ufetch_32 NULL pointer behavior"); 506 } 507 ATF_TC_BODY(ufetch_32_null, tc) 508 { 509 uint32_t res; 510 511 CHECK_MODULE(); 512 513 ATF_REQUIRE_EQ(do_ufetch_32(NULL, &res), EFAULT); 514 } 515 ATF_TC_CLEANUP(ufetch_32_null, tc) 516 { 517 unload_module(); 518 } 519 520 #ifdef _LP64 521 ATF_TC_WITH_CLEANUP(ufetch_64_null); 522 ATF_TC_HEAD(ufetch_64_null, tc) 523 { 524 atf_tc_set_md_var(tc, "descr", 525 "test for correct ufetch_64 NULL pointer behavior"); 526 } 527 ATF_TC_BODY(ufetch_64_null, tc) 528 { 529 uint64_t res; 530 531 CHECK_MODULE(); 532 533 ATF_REQUIRE_EQ(do_ufetch_64(NULL, &res), EFAULT); 534 } 535 ATF_TC_CLEANUP(ufetch_64_null, tc) 536 { 537 unload_module(); 538 } 539 #endif /* _LP64 */ 540 541 ATF_TC_WITH_CLEANUP(ufetch_8_max); 542 ATF_TC_HEAD(ufetch_8_max, tc) 543 { 544 atf_tc_set_md_var(tc, "descr", 545 "test for correct ufetch_8 VM_MAX_ADDRESS pointer behavior"); 546 } 547 ATF_TC_BODY(ufetch_8_max, tc) 548 { 549 uint8_t res; 550 551 CHECK_MODULE(); 552 553 ATF_REQUIRE_EQ(do_ufetch_8(vm_max_address(), &res), EFAULT); 554 } 555 ATF_TC_CLEANUP(ufetch_8_max, tc) 556 { 557 unload_module(); 558 } 559 560 ATF_TC_WITH_CLEANUP(ufetch_16_max); 561 ATF_TC_HEAD(ufetch_16_max, tc) 562 { 563 atf_tc_set_md_var(tc, "descr", 564 "test for correct ufetch_16 VM_MAX_ADDRESS pointer behavior"); 565 } 566 ATF_TC_BODY(ufetch_16_max, tc) 567 { 568 uint16_t res; 569 570 CHECK_MODULE(); 571 572 ATF_REQUIRE_EQ(do_ufetch_16(vm_max_address(), &res), EFAULT); 573 } 574 ATF_TC_CLEANUP(ufetch_16_max, tc) 575 { 576 unload_module(); 577 } 578 579 ATF_TC_WITH_CLEANUP(ufetch_32_max); 580 ATF_TC_HEAD(ufetch_32_max, tc) 581 { 582 atf_tc_set_md_var(tc, "descr", 583 "test for correct ufetch_32 VM_MAX_ADDRESS pointer behavior"); 584 } 585 ATF_TC_BODY(ufetch_32_max, tc) 586 { 587 uint32_t res; 588 589 CHECK_MODULE(); 590 591 ATF_REQUIRE_EQ(do_ufetch_32(vm_max_address(), &res), EFAULT); 592 } 593 ATF_TC_CLEANUP(ufetch_32_max, tc) 594 { 595 unload_module(); 596 } 597 598 #ifdef _LP64 599 ATF_TC_WITH_CLEANUP(ufetch_64_max); 600 ATF_TC_HEAD(ufetch_64_max, tc) 601 { 602 atf_tc_set_md_var(tc, "descr", 603 "test for correct ufetch_64 VM_MAX_ADDRESS pointer behavior"); 604 } 605 ATF_TC_BODY(ufetch_64_max, tc) 606 { 607 uint64_t res; 608 609 CHECK_MODULE(); 610 611 ATF_REQUIRE_EQ(do_ufetch_64(vm_max_address(), &res), EFAULT); 612 } 613 ATF_TC_CLEANUP(ufetch_64_max, tc) 614 { 615 unload_module(); 616 } 617 #endif /* _LP64 */ 618 619 ATF_TC_WITH_CLEANUP(ufetch_16_nearmax_overflow); 620 ATF_TC_HEAD(ufetch_16_nearmax_overflow, tc) 621 { 622 atf_tc_set_md_var(tc, "descr", 623 "test for correct ufetch_16 near-VM_MAX_ADDRESS pointer behavior"); 624 } 625 ATF_TC_BODY(ufetch_16_nearmax_overflow, tc) 626 { 627 uint16_t res; 628 629 CHECK_MODULE(); 630 631 /* 632 * For no-strict-alignment platforms: address checks must return 633 * EFAULT. 634 * 635 * For strict-alignment platforms: alignment checks must return 636 * EFAULT. 637 */ 638 ATF_REQUIRE_EQ(do_ufetch_16(vm_max_address_minus(1), &res), EFAULT); 639 } 640 ATF_TC_CLEANUP(ufetch_16_nearmax_overflow, tc) 641 { 642 unload_module(); 643 } 644 645 ATF_TC_WITH_CLEANUP(ufetch_32_nearmax_overflow); 646 ATF_TC_HEAD(ufetch_32_nearmax_overflow, tc) 647 { 648 atf_tc_set_md_var(tc, "descr", 649 "test for correct ufetch_32 near-VM_MAX_ADDRESS pointer behavior"); 650 } 651 ATF_TC_BODY(ufetch_32_nearmax_overflow, tc) 652 { 653 uint32_t res; 654 655 CHECK_MODULE(); 656 657 /* 658 * For no-strict-alignment platforms: address checks must return 659 * EFAULT. 660 * 661 * For strict-alignment platforms: alignment checks must return 662 * EFAULT. 663 */ 664 ATF_REQUIRE_EQ(do_ufetch_32(vm_max_address_minus(3), &res), EFAULT); 665 } 666 ATF_TC_CLEANUP(ufetch_32_nearmax_overflow, tc) 667 { 668 unload_module(); 669 } 670 671 #ifdef _LP64 672 ATF_TC_WITH_CLEANUP(ufetch_64_nearmax_overflow); 673 ATF_TC_HEAD(ufetch_64_nearmax_overflow, tc) 674 { 675 atf_tc_set_md_var(tc, "descr", 676 "test for correct ufetch_64 near-VM_MAX_ADDRESS pointer behavior"); 677 } 678 ATF_TC_BODY(ufetch_64_nearmax_overflow, tc) 679 { 680 uint64_t res; 681 682 CHECK_MODULE(); 683 684 /* 685 * For no-strict-alignment platforms: address checks must return 686 * EFAULT. 687 * 688 * For strict-alignment platforms: alignment checks must return 689 * EFAULT. 690 */ 691 ATF_REQUIRE_EQ(do_ufetch_64(vm_max_address_minus(7), &res), EFAULT); 692 } 693 ATF_TC_CLEANUP(ufetch_64_nearmax_overflow, tc) 694 { 695 unload_module(); 696 } 697 #endif /* _LP64 */ 698 699 700 ATF_TC_WITH_CLEANUP(ustore_8); 701 ATF_TC_HEAD(ustore_8, tc) 702 { 703 atf_tc_set_md_var(tc, "descr", 704 "test for correct ustore_8 behavior"); 705 } 706 ATF_TC_BODY(ustore_8, tc) 707 { 708 struct memory_cell cell = memory_cell_initializer; 709 710 CHECK_MODULE(); 711 712 ATF_REQUIRE_EQ(do_ustore_8(&cell.val8[index8], test_pattern8), 0); 713 ATF_REQUIRE(memory_cell_check_guard(&cell)); 714 ATF_REQUIRE(read_test_cell(&cell) == test_cell_val8); 715 } 716 ATF_TC_CLEANUP(ustore_8, tc) 717 { 718 unload_module(); 719 } 720 721 ATF_TC_WITH_CLEANUP(ustore_16); 722 ATF_TC_HEAD(ustore_16, tc) 723 { 724 atf_tc_set_md_var(tc, "descr", 725 "test for correct ustore_16 behavior"); 726 } 727 ATF_TC_BODY(ustore_16, tc) 728 { 729 struct memory_cell cell = memory_cell_initializer; 730 731 CHECK_MODULE(); 732 733 ATF_REQUIRE_EQ(do_ustore_16(&cell.val16[index16], test_pattern16), 0); 734 ATF_REQUIRE(memory_cell_check_guard(&cell)); 735 ATF_REQUIRE(read_test_cell(&cell) == test_cell_val16); 736 } 737 ATF_TC_CLEANUP(ustore_16, tc) 738 { 739 unload_module(); 740 } 741 742 ATF_TC_WITH_CLEANUP(ustore_32); 743 ATF_TC_HEAD(ustore_32, tc) 744 { 745 atf_tc_set_md_var(tc, "descr", 746 "test for correct ustore_32 behavior"); 747 } 748 ATF_TC_BODY(ustore_32, tc) 749 { 750 struct memory_cell cell = memory_cell_initializer; 751 752 CHECK_MODULE(); 753 754 ATF_REQUIRE_EQ(do_ustore_32(&cell.val32[index32], test_pattern32), 0); 755 ATF_REQUIRE(memory_cell_check_guard(&cell)); 756 ATF_REQUIRE(read_test_cell(&cell) == test_cell_val32); 757 } 758 ATF_TC_CLEANUP(ustore_32, tc) 759 { 760 unload_module(); 761 } 762 763 #ifdef _LP64 764 ATF_TC_WITH_CLEANUP(ustore_64); 765 ATF_TC_HEAD(ustore_64, tc) 766 { 767 atf_tc_set_md_var(tc, "descr", 768 "test for correct ustore_64 behavior"); 769 } 770 ATF_TC_BODY(ustore_64, tc) 771 { 772 struct memory_cell cell = memory_cell_initializer; 773 774 CHECK_MODULE(); 775 776 ATF_REQUIRE_EQ(do_ustore_64(&cell.val64, test_pattern64), 0); 777 ATF_REQUIRE(memory_cell_check_guard(&cell)); 778 ATF_REQUIRE(read_test_cell(&cell) == test_cell_val64); 779 } 780 ATF_TC_CLEANUP(ustore_64, tc) 781 { 782 unload_module(); 783 } 784 #endif /* _LP64 */ 785 786 ATF_TC_WITH_CLEANUP(ustore_8_null); 787 ATF_TC_HEAD(ustore_8_null, tc) 788 { 789 atf_tc_set_md_var(tc, "descr", 790 "test for correct ustore_8 NULL pointer behavior"); 791 } 792 ATF_TC_BODY(ustore_8_null, tc) 793 { 794 CHECK_MODULE(); 795 796 ATF_REQUIRE_EQ(do_ustore_8(NULL, 0), EFAULT); 797 } 798 ATF_TC_CLEANUP(ustore_8_null, tc) 799 { 800 unload_module(); 801 } 802 803 ATF_TC_WITH_CLEANUP(ustore_16_null); 804 ATF_TC_HEAD(ustore_16_null, tc) 805 { 806 atf_tc_set_md_var(tc, "descr", 807 "test for correct ustore_16 NULL pointer behavior"); 808 } 809 ATF_TC_BODY(ustore_16_null, tc) 810 { 811 CHECK_MODULE(); 812 813 ATF_REQUIRE_EQ(do_ustore_16(NULL, 0), EFAULT); 814 } 815 ATF_TC_CLEANUP(ustore_16_null, tc) 816 { 817 unload_module(); 818 } 819 820 ATF_TC_WITH_CLEANUP(ustore_32_null); 821 ATF_TC_HEAD(ustore_32_null, tc) 822 { 823 atf_tc_set_md_var(tc, "descr", 824 "test for correct ustore_32 NULL pointer behavior"); 825 } 826 ATF_TC_BODY(ustore_32_null, tc) 827 { 828 CHECK_MODULE(); 829 830 ATF_REQUIRE_EQ(do_ustore_32(NULL, 0), EFAULT); 831 } 832 ATF_TC_CLEANUP(ustore_32_null, tc) 833 { 834 unload_module(); 835 } 836 837 #ifdef _LP64 838 ATF_TC_WITH_CLEANUP(ustore_64_null); 839 ATF_TC_HEAD(ustore_64_null, tc) 840 { 841 atf_tc_set_md_var(tc, "descr", 842 "test for correct ustore_64 NULL pointer behavior"); 843 } 844 ATF_TC_BODY(ustore_64_null, tc) 845 { 846 CHECK_MODULE(); 847 848 ATF_REQUIRE_EQ(do_ustore_64(NULL, 0), EFAULT); 849 } 850 ATF_TC_CLEANUP(ustore_64_null, tc) 851 { 852 unload_module(); 853 } 854 #endif /* _LP64 */ 855 856 ATF_TC_WITH_CLEANUP(ustore_8_max); 857 ATF_TC_HEAD(ustore_8_max, tc) 858 { 859 atf_tc_set_md_var(tc, "descr", 860 "test for correct ustore_8 VM_MAX_ADDRESS pointer behavior"); 861 } 862 ATF_TC_BODY(ustore_8_max, tc) 863 { 864 CHECK_MODULE(); 865 866 ATF_REQUIRE_EQ(do_ustore_8(vm_max_address(), 0), EFAULT); 867 } 868 ATF_TC_CLEANUP(ustore_8_max, tc) 869 { 870 unload_module(); 871 } 872 873 ATF_TC_WITH_CLEANUP(ustore_16_max); 874 ATF_TC_HEAD(ustore_16_max, tc) 875 { 876 atf_tc_set_md_var(tc, "descr", 877 "test for correct ustore_16 VM_MAX_ADDRESS pointer behavior"); 878 } 879 ATF_TC_BODY(ustore_16_max, tc) 880 { 881 CHECK_MODULE(); 882 883 ATF_REQUIRE_EQ(do_ustore_16(vm_max_address(), 0), EFAULT); 884 } 885 ATF_TC_CLEANUP(ustore_16_max, tc) 886 { 887 unload_module(); 888 } 889 890 ATF_TC_WITH_CLEANUP(ustore_32_max); 891 ATF_TC_HEAD(ustore_32_max, tc) 892 { 893 atf_tc_set_md_var(tc, "descr", 894 "test for correct ustore_32 VM_MAX_ADDRESS pointer behavior"); 895 } 896 ATF_TC_BODY(ustore_32_max, tc) 897 { 898 CHECK_MODULE(); 899 900 ATF_REQUIRE_EQ(do_ustore_32(vm_max_address(), 0), EFAULT); 901 } 902 ATF_TC_CLEANUP(ustore_32_max, tc) 903 { 904 unload_module(); 905 } 906 907 #ifdef _LP64 908 ATF_TC_WITH_CLEANUP(ustore_64_max); 909 ATF_TC_HEAD(ustore_64_max, tc) 910 { 911 atf_tc_set_md_var(tc, "descr", 912 "test for correct ustore_64 VM_MAX_ADDRESS pointer behavior"); 913 } 914 ATF_TC_BODY(ustore_64_max, tc) 915 { 916 CHECK_MODULE(); 917 918 ATF_REQUIRE_EQ(do_ustore_64(vm_max_address(), 0), EFAULT); 919 } 920 ATF_TC_CLEANUP(ustore_64_max, tc) 921 { 922 unload_module(); 923 } 924 #endif /* _LP64 */ 925 926 ATF_TC_WITH_CLEANUP(ustore_16_nearmax_overflow); 927 ATF_TC_HEAD(ustore_16_nearmax_overflow, tc) 928 { 929 atf_tc_set_md_var(tc, "descr", 930 "test for correct ustore_16 VM_MAX_ADDRESS pointer behavior"); 931 } 932 ATF_TC_BODY(ustore_16_nearmax_overflow, tc) 933 { 934 CHECK_MODULE(); 935 936 /* 937 * For no-strict-alignment platforms: address checks must return 938 * EFAULT. 939 * 940 * For strict-alignment platforms: alignment checks must return 941 * EFAULT. 942 */ 943 ATF_REQUIRE_EQ(do_ustore_16(vm_max_address_minus(1), 0), EFAULT); 944 } 945 ATF_TC_CLEANUP(ustore_16_nearmax_overflow, tc) 946 { 947 unload_module(); 948 } 949 950 ATF_TC_WITH_CLEANUP(ustore_32_nearmax_overflow); 951 ATF_TC_HEAD(ustore_32_nearmax_overflow, tc) 952 { 953 atf_tc_set_md_var(tc, "descr", 954 "test for correct ustore_32 VM_MAX_ADDRESS pointer behavior"); 955 } 956 ATF_TC_BODY(ustore_32_nearmax_overflow, tc) 957 { 958 CHECK_MODULE(); 959 960 /* 961 * For no-strict-alignment platforms: address checks must return 962 * EFAULT. 963 * 964 * For strict-alignment platforms: alignment checks must return 965 * EFAULT. 966 */ 967 ATF_REQUIRE_EQ(do_ustore_32(vm_max_address_minus(3), 0), EFAULT); 968 } 969 ATF_TC_CLEANUP(ustore_32_nearmax_overflow, tc) 970 { 971 unload_module(); 972 } 973 974 #ifdef _LP64 975 ATF_TC_WITH_CLEANUP(ustore_64_nearmax_overflow); 976 ATF_TC_HEAD(ustore_64_nearmax_overflow, tc) 977 { 978 atf_tc_set_md_var(tc, "descr", 979 "test for correct ustore_64 VM_MAX_ADDRESS pointer behavior"); 980 } 981 ATF_TC_BODY(ustore_64_nearmax_overflow, tc) 982 { 983 CHECK_MODULE(); 984 985 /* 986 * For no-strict-alignment platforms: address checks must return 987 * EFAULT. 988 * 989 * For strict-alignment platforms: alignment checks must return 990 * EFAULT. 991 */ 992 ATF_REQUIRE_EQ(do_ustore_64(vm_max_address_minus(7), 0), EFAULT); 993 } 994 ATF_TC_CLEANUP(ustore_64_nearmax_overflow, tc) 995 { 996 unload_module(); 997 } 998 #endif /* _LP64 */ 999 1000 1001 ATF_TC_WITH_CLEANUP(ucas_32); 1002 ATF_TC_HEAD(ucas_32, tc) 1003 { 1004 atf_tc_set_md_var(tc, "descr", 1005 "test for correct ucas_32 behavior"); 1006 } 1007 ATF_TC_BODY(ucas_32, tc) 1008 { 1009 uint32_t cell = 0xdeadbeef; 1010 uint32_t actual = 0; 1011 1012 CHECK_MODULE(); 1013 1014 ATF_REQUIRE_EQ(do_ucas_32(&cell, 0xdeadbeef, 0xbeefdead, &actual), 0); 1015 ATF_REQUIRE(actual == 0xdeadbeef); 1016 ATF_REQUIRE(cell == 0xbeefdead); 1017 } 1018 ATF_TC_CLEANUP(ucas_32, tc) 1019 { 1020 unload_module(); 1021 } 1022 1023 #ifdef _LP64 1024 ATF_TC_WITH_CLEANUP(ucas_64); 1025 ATF_TC_HEAD(ucas_64, tc) 1026 { 1027 atf_tc_set_md_var(tc, "descr", 1028 "test for correct ucas_64 behavior"); 1029 } 1030 ATF_TC_BODY(ucas_64, tc) 1031 { 1032 uint64_t cell = 0xdeadbeef; 1033 uint64_t actual = 0; 1034 1035 CHECK_MODULE(); 1036 1037 ATF_REQUIRE_EQ(do_ucas_64(&cell, 0xdeadbeef, 0xbeefdead, &actual), 0); 1038 ATF_REQUIRE(actual == 0xdeadbeef); 1039 ATF_REQUIRE(cell == 0xbeefdead); 1040 } 1041 ATF_TC_CLEANUP(ucas_64, tc) 1042 { 1043 unload_module(); 1044 } 1045 #endif /* _LP64 */ 1046 1047 ATF_TC_WITH_CLEANUP(ucas_32_miscompare); 1048 ATF_TC_HEAD(ucas_32_miscompare, tc) 1049 { 1050 atf_tc_set_md_var(tc, "descr", 1051 "test for correct ucas_32 behavior with miscompare"); 1052 } 1053 ATF_TC_BODY(ucas_32_miscompare, tc) 1054 { 1055 uint32_t cell = 0xa5a5a5a5; 1056 uint32_t actual = 0; 1057 1058 CHECK_MODULE(); 1059 1060 ATF_REQUIRE_EQ(do_ucas_32(&cell, 0xdeadbeef, 0xbeefdead, &actual), 0); 1061 ATF_REQUIRE(actual == 0xa5a5a5a5); 1062 ATF_REQUIRE(cell == 0xa5a5a5a5); 1063 } 1064 ATF_TC_CLEANUP(ucas_32_miscompare, tc) 1065 { 1066 unload_module(); 1067 } 1068 1069 #ifdef _LP64 1070 ATF_TC_WITH_CLEANUP(ucas_64_miscompare); 1071 ATF_TC_HEAD(ucas_64_miscompare, tc) 1072 { 1073 atf_tc_set_md_var(tc, "descr", 1074 "test for correct ucas_64 behavior with miscompare"); 1075 } 1076 ATF_TC_BODY(ucas_64_miscompare, tc) 1077 { 1078 uint64_t cell = 0xa5a5a5a5; 1079 uint64_t actual = 0; 1080 1081 CHECK_MODULE(); 1082 1083 ATF_REQUIRE_EQ(do_ucas_64(&cell, 0xdeadbeef, 0xbeefdead, &actual), 0); 1084 ATF_REQUIRE(actual == 0xa5a5a5a5); 1085 ATF_REQUIRE(cell == 0xa5a5a5a5); 1086 } 1087 ATF_TC_CLEANUP(ucas_64_miscompare, tc) 1088 { 1089 unload_module(); 1090 } 1091 #endif /* _LP64 */ 1092 1093 ATF_TC_WITH_CLEANUP(ucas_32_null); 1094 ATF_TC_HEAD(ucas_32_null, tc) 1095 { 1096 atf_tc_set_md_var(tc, "descr", 1097 "test for correct ucas_32 NULL pointer behavior"); 1098 } 1099 ATF_TC_BODY(ucas_32_null, tc) 1100 { 1101 uint32_t actual = 0; 1102 1103 CHECK_MODULE(); 1104 1105 ATF_REQUIRE_EQ(do_ucas_32(NULL, 0xdeadbeef, 0xbeefdead, &actual), 1106 EFAULT); 1107 } 1108 ATF_TC_CLEANUP(ucas_32_null, tc) 1109 { 1110 unload_module(); 1111 } 1112 1113 #ifdef _LP64 1114 ATF_TC_WITH_CLEANUP(ucas_64_null); 1115 ATF_TC_HEAD(ucas_64_null, tc) 1116 { 1117 atf_tc_set_md_var(tc, "descr", 1118 "test for correct ucas_64 NULL pointer behavior"); 1119 } 1120 ATF_TC_BODY(ucas_64_null, tc) 1121 { 1122 uint64_t actual = 0; 1123 1124 CHECK_MODULE(); 1125 1126 ATF_REQUIRE_EQ(do_ucas_64(NULL, 0xdeadbeef, 0xbeefdead, &actual), 1127 EFAULT); 1128 } 1129 ATF_TC_CLEANUP(ucas_64_null, tc) 1130 { 1131 unload_module(); 1132 } 1133 #endif /* _LP64 */ 1134 1135 ATF_TC_WITH_CLEANUP(ucas_32_max); 1136 ATF_TC_HEAD(ucas_32_max, tc) 1137 { 1138 atf_tc_set_md_var(tc, "descr", 1139 "test for correct ucas_32 VM_MAX_ADDRESS pointer behavior"); 1140 } 1141 ATF_TC_BODY(ucas_32_max, tc) 1142 { 1143 uint32_t actual = 0; 1144 1145 CHECK_MODULE(); 1146 1147 ATF_REQUIRE_EQ(do_ucas_32(vm_max_address(), 0xdeadbeef, 0xbeefdead, 1148 &actual), EFAULT); 1149 } 1150 ATF_TC_CLEANUP(ucas_32_max, tc) 1151 { 1152 unload_module(); 1153 } 1154 1155 #ifdef _LP64 1156 ATF_TC_WITH_CLEANUP(ucas_64_max); 1157 ATF_TC_HEAD(ucas_64_max, tc) 1158 { 1159 atf_tc_set_md_var(tc, "descr", 1160 "test for correct ucas_64 VM_MAX_ADDRESS pointer behavior"); 1161 } 1162 ATF_TC_BODY(ucas_64_max, tc) 1163 { 1164 uint64_t actual = 0; 1165 1166 CHECK_MODULE(); 1167 1168 ATF_REQUIRE_EQ(do_ucas_64(vm_max_address(), 0xdeadbeef, 0xbeefdead, 1169 &actual), EFAULT); 1170 } 1171 ATF_TC_CLEANUP(ucas_64_max, tc) 1172 { 1173 unload_module(); 1174 } 1175 #endif /* _LP64 */ 1176 1177 ATF_TC_WITH_CLEANUP(ucas_32_nearmax_overflow); 1178 ATF_TC_HEAD(ucas_32_nearmax_overflow, tc) 1179 { 1180 atf_tc_set_md_var(tc, "descr", 1181 "test for correct ucas_32 near-VM_MAX_ADDRESS pointer behavior"); 1182 } 1183 ATF_TC_BODY(ucas_32_nearmax_overflow, tc) 1184 { 1185 uint32_t actual = 0; 1186 1187 CHECK_MODULE(); 1188 1189 /* 1190 * For no-strict-alignment platforms: address checks must return 1191 * EFAULT. 1192 * 1193 * For strict-alignment platforms: alignment checks must return 1194 * EFAULT. 1195 */ 1196 ATF_REQUIRE_EQ(do_ucas_32(vm_max_address_minus(3), 0xdeadbeef, 1197 0xbeefdead, &actual), EFAULT); 1198 } 1199 ATF_TC_CLEANUP(ucas_32_nearmax_overflow, tc) 1200 { 1201 unload_module(); 1202 } 1203 1204 #ifdef _LP64 1205 ATF_TC_WITH_CLEANUP(ucas_64_nearmax_overflow); 1206 ATF_TC_HEAD(ucas_64_nearmax_overflow, tc) 1207 { 1208 atf_tc_set_md_var(tc, "descr", 1209 "test for correct ucas_64 near-VM_MAX_ADDRESS pointer behavior"); 1210 } 1211 ATF_TC_BODY(ucas_64_nearmax_overflow, tc) 1212 { 1213 uint64_t actual = 0; 1214 1215 CHECK_MODULE(); 1216 1217 /* 1218 * For no-strict-alignment platforms: address checks must return 1219 * EFAULT. 1220 * 1221 * For strict-alignment platforms: alignment checks must return 1222 * EFAULT. 1223 */ 1224 ATF_REQUIRE_EQ(do_ucas_64(vm_max_address_minus(7), 0xdeadbeef, 1225 0xbeefdead, &actual), EFAULT); 1226 } 1227 ATF_TC_CLEANUP(ucas_64_nearmax_overflow, tc) 1228 { 1229 unload_module(); 1230 } 1231 #endif /* _LP64 */ 1232 1233 ATF_TP_ADD_TCS(tp) 1234 { 1235 ATF_TP_ADD_TC(tp, ufetch_8); 1236 ATF_TP_ADD_TC(tp, ufetch_16); 1237 ATF_TP_ADD_TC(tp, ufetch_32); 1238 #ifdef _LP64 1239 ATF_TP_ADD_TC(tp, ufetch_64); 1240 #endif 1241 1242 ATF_TP_ADD_TC(tp, ufetch_8_null); 1243 ATF_TP_ADD_TC(tp, ufetch_16_null); 1244 ATF_TP_ADD_TC(tp, ufetch_32_null); 1245 #ifdef _LP64 1246 ATF_TP_ADD_TC(tp, ufetch_64_null); 1247 #endif 1248 1249 ATF_TP_ADD_TC(tp, ufetch_8_max); 1250 ATF_TP_ADD_TC(tp, ufetch_16_max); 1251 ATF_TP_ADD_TC(tp, ufetch_32_max); 1252 #ifdef _LP64 1253 ATF_TP_ADD_TC(tp, ufetch_64_max); 1254 #endif 1255 1256 ATF_TP_ADD_TC(tp, ufetch_16_nearmax_overflow); 1257 ATF_TP_ADD_TC(tp, ufetch_32_nearmax_overflow); 1258 #ifdef _LP64 1259 ATF_TP_ADD_TC(tp, ufetch_64_nearmax_overflow); 1260 #endif 1261 1262 ATF_TP_ADD_TC(tp, ustore_8); 1263 ATF_TP_ADD_TC(tp, ustore_16); 1264 ATF_TP_ADD_TC(tp, ustore_32); 1265 #ifdef _LP64 1266 ATF_TP_ADD_TC(tp, ustore_64); 1267 #endif 1268 1269 ATF_TP_ADD_TC(tp, ustore_8_null); 1270 ATF_TP_ADD_TC(tp, ustore_16_null); 1271 ATF_TP_ADD_TC(tp, ustore_32_null); 1272 #ifdef _LP64 1273 ATF_TP_ADD_TC(tp, ustore_64_null); 1274 #endif 1275 1276 ATF_TP_ADD_TC(tp, ustore_8_max); 1277 ATF_TP_ADD_TC(tp, ustore_16_max); 1278 ATF_TP_ADD_TC(tp, ustore_32_max); 1279 #ifdef _LP64 1280 ATF_TP_ADD_TC(tp, ustore_64_max); 1281 #endif 1282 1283 ATF_TP_ADD_TC(tp, ustore_16_nearmax_overflow); 1284 ATF_TP_ADD_TC(tp, ustore_32_nearmax_overflow); 1285 #ifdef _LP64 1286 ATF_TP_ADD_TC(tp, ustore_64_nearmax_overflow); 1287 #endif 1288 1289 ATF_TP_ADD_TC(tp, ucas_32); 1290 #ifdef _LP64 1291 ATF_TP_ADD_TC(tp, ucas_64); 1292 #endif 1293 1294 ATF_TP_ADD_TC(tp, ucas_32_miscompare); 1295 #ifdef _LP64 1296 ATF_TP_ADD_TC(tp, ucas_64_miscompare); 1297 #endif 1298 1299 ATF_TP_ADD_TC(tp, ucas_32_null); 1300 #ifdef _LP64 1301 ATF_TP_ADD_TC(tp, ucas_64_null); 1302 #endif 1303 1304 ATF_TP_ADD_TC(tp, ucas_32_max); 1305 #ifdef _LP64 1306 ATF_TP_ADD_TC(tp, ucas_64_max); 1307 #endif 1308 1309 ATF_TP_ADD_TC(tp, ucas_32_nearmax_overflow); 1310 #ifdef _LP64 1311 ATF_TP_ADD_TC(tp, ucas_64_nearmax_overflow); 1312 #endif 1313 1314 return atf_no_error(); 1315 } 1316