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 52static 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() \ 59do { \ 60 load_module(); \ 61 if (! module_loaded) { \ 62 atf_tc_skip("loading '%s' module failed.", MODULE_NAME);\ 63 } \ 64} while (/*CONSTCOND*/0) 65 66static void 67load_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 90static void 91unload_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 104static unsigned long 105vm_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 120static void * 121vm_max_address(void) 122{ 123 return (void *)vm_max_address_raw(); 124} 125 126static void * 127vm_max_address_minus(unsigned int adj) 128{ 129 return (void *)(vm_max_address_raw() - adj); 130} 131 132static int 133do_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 155static int 156do_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 169static int 170do_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 183static int 184do_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 198static int 199do_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 213static int 214do_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 227static int 228do_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 241static int 242do_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 256static int 257do_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 271static int 272do_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 288static int 289do_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 305struct 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 362static bool 363memory_cell_check_guard(const struct memory_cell * const cell) 364{ 365 return cell->guard0 == ULONG_MAX && 366 cell->guard1 == ULONG_MAX; 367} 368 369ATF_TC_WITH_CLEANUP(ufetch_8); 370ATF_TC_HEAD(ufetch_8, tc) 371{ 372 atf_tc_set_md_var(tc, "descr", 373 "test for correct ufetch_8 behavior"); 374} 375ATF_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} 387ATF_TC_CLEANUP(ufetch_8, tc) 388{ 389 unload_module(); 390} 391 392ATF_TC_WITH_CLEANUP(ufetch_16); 393ATF_TC_HEAD(ufetch_16, tc) 394{ 395 atf_tc_set_md_var(tc, "descr", 396 "test for correct ufetch_16 behavior"); 397} 398ATF_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} 410ATF_TC_CLEANUP(ufetch_16, tc) 411{ 412 unload_module(); 413} 414 415ATF_TC_WITH_CLEANUP(ufetch_32); 416ATF_TC_HEAD(ufetch_32, tc) 417{ 418 atf_tc_set_md_var(tc, "descr", 419 "test for correct ufetch_32 behavior"); 420} 421ATF_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} 433ATF_TC_CLEANUP(ufetch_32, tc) 434{ 435 unload_module(); 436} 437 438#ifdef _LP64 439ATF_TC_WITH_CLEANUP(ufetch_64); 440ATF_TC_HEAD(ufetch_64, tc) 441{ 442 atf_tc_set_md_var(tc, "descr", 443 "test for correct ufetch_64 behavior"); 444} 445ATF_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} 457ATF_TC_CLEANUP(ufetch_64, tc) 458{ 459 unload_module(); 460} 461#endif /* _LP64 */ 462 463ATF_TC_WITH_CLEANUP(ufetch_8_null); 464ATF_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} 469ATF_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} 477ATF_TC_CLEANUP(ufetch_8_null, tc) 478{ 479 unload_module(); 480} 481 482ATF_TC_WITH_CLEANUP(ufetch_16_null); 483ATF_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} 488ATF_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} 496ATF_TC_CLEANUP(ufetch_16_null, tc) 497{ 498 unload_module(); 499} 500 501ATF_TC_WITH_CLEANUP(ufetch_32_null); 502ATF_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} 507ATF_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} 515ATF_TC_CLEANUP(ufetch_32_null, tc) 516{ 517 unload_module(); 518} 519 520#ifdef _LP64 521ATF_TC_WITH_CLEANUP(ufetch_64_null); 522ATF_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} 527ATF_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} 535ATF_TC_CLEANUP(ufetch_64_null, tc) 536{ 537 unload_module(); 538} 539#endif /* _LP64 */ 540 541ATF_TC_WITH_CLEANUP(ufetch_8_max); 542ATF_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} 547ATF_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} 555ATF_TC_CLEANUP(ufetch_8_max, tc) 556{ 557 unload_module(); 558} 559 560ATF_TC_WITH_CLEANUP(ufetch_16_max); 561ATF_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} 566ATF_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} 574ATF_TC_CLEANUP(ufetch_16_max, tc) 575{ 576 unload_module(); 577} 578 579ATF_TC_WITH_CLEANUP(ufetch_32_max); 580ATF_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} 585ATF_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} 593ATF_TC_CLEANUP(ufetch_32_max, tc) 594{ 595 unload_module(); 596} 597 598#ifdef _LP64 599ATF_TC_WITH_CLEANUP(ufetch_64_max); 600ATF_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} 605ATF_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} 613ATF_TC_CLEANUP(ufetch_64_max, tc) 614{ 615 unload_module(); 616} 617#endif /* _LP64 */ 618 619ATF_TC_WITH_CLEANUP(ufetch_16_nearmax_overflow); 620ATF_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} 625ATF_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} 640ATF_TC_CLEANUP(ufetch_16_nearmax_overflow, tc) 641{ 642 unload_module(); 643} 644 645ATF_TC_WITH_CLEANUP(ufetch_32_nearmax_overflow); 646ATF_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} 651ATF_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} 666ATF_TC_CLEANUP(ufetch_32_nearmax_overflow, tc) 667{ 668 unload_module(); 669} 670 671#ifdef _LP64 672ATF_TC_WITH_CLEANUP(ufetch_64_nearmax_overflow); 673ATF_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} 678ATF_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} 693ATF_TC_CLEANUP(ufetch_64_nearmax_overflow, tc) 694{ 695 unload_module(); 696} 697#endif /* _LP64 */ 698 699 700ATF_TC_WITH_CLEANUP(ustore_8); 701ATF_TC_HEAD(ustore_8, tc) 702{ 703 atf_tc_set_md_var(tc, "descr", 704 "test for correct ustore_8 behavior"); 705} 706ATF_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} 716ATF_TC_CLEANUP(ustore_8, tc) 717{ 718 unload_module(); 719} 720 721ATF_TC_WITH_CLEANUP(ustore_16); 722ATF_TC_HEAD(ustore_16, tc) 723{ 724 atf_tc_set_md_var(tc, "descr", 725 "test for correct ustore_16 behavior"); 726} 727ATF_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} 737ATF_TC_CLEANUP(ustore_16, tc) 738{ 739 unload_module(); 740} 741 742ATF_TC_WITH_CLEANUP(ustore_32); 743ATF_TC_HEAD(ustore_32, tc) 744{ 745 atf_tc_set_md_var(tc, "descr", 746 "test for correct ustore_32 behavior"); 747} 748ATF_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} 758ATF_TC_CLEANUP(ustore_32, tc) 759{ 760 unload_module(); 761} 762 763#ifdef _LP64 764ATF_TC_WITH_CLEANUP(ustore_64); 765ATF_TC_HEAD(ustore_64, tc) 766{ 767 atf_tc_set_md_var(tc, "descr", 768 "test for correct ustore_64 behavior"); 769} 770ATF_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} 780ATF_TC_CLEANUP(ustore_64, tc) 781{ 782 unload_module(); 783} 784#endif /* _LP64 */ 785 786ATF_TC_WITH_CLEANUP(ustore_8_null); 787ATF_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} 792ATF_TC_BODY(ustore_8_null, tc) 793{ 794 CHECK_MODULE(); 795 796 ATF_REQUIRE_EQ(do_ustore_8(NULL, 0), EFAULT); 797} 798ATF_TC_CLEANUP(ustore_8_null, tc) 799{ 800 unload_module(); 801} 802 803ATF_TC_WITH_CLEANUP(ustore_16_null); 804ATF_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} 809ATF_TC_BODY(ustore_16_null, tc) 810{ 811 CHECK_MODULE(); 812 813 ATF_REQUIRE_EQ(do_ustore_16(NULL, 0), EFAULT); 814} 815ATF_TC_CLEANUP(ustore_16_null, tc) 816{ 817 unload_module(); 818} 819 820ATF_TC_WITH_CLEANUP(ustore_32_null); 821ATF_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} 826ATF_TC_BODY(ustore_32_null, tc) 827{ 828 CHECK_MODULE(); 829 830 ATF_REQUIRE_EQ(do_ustore_32(NULL, 0), EFAULT); 831} 832ATF_TC_CLEANUP(ustore_32_null, tc) 833{ 834 unload_module(); 835} 836 837#ifdef _LP64 838ATF_TC_WITH_CLEANUP(ustore_64_null); 839ATF_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} 844ATF_TC_BODY(ustore_64_null, tc) 845{ 846 CHECK_MODULE(); 847 848 ATF_REQUIRE_EQ(do_ustore_64(NULL, 0), EFAULT); 849} 850ATF_TC_CLEANUP(ustore_64_null, tc) 851{ 852 unload_module(); 853} 854#endif /* _LP64 */ 855 856ATF_TC_WITH_CLEANUP(ustore_8_max); 857ATF_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} 862ATF_TC_BODY(ustore_8_max, tc) 863{ 864 CHECK_MODULE(); 865 866 ATF_REQUIRE_EQ(do_ustore_8(vm_max_address(), 0), EFAULT); 867} 868ATF_TC_CLEANUP(ustore_8_max, tc) 869{ 870 unload_module(); 871} 872 873ATF_TC_WITH_CLEANUP(ustore_16_max); 874ATF_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} 879ATF_TC_BODY(ustore_16_max, tc) 880{ 881 CHECK_MODULE(); 882 883 ATF_REQUIRE_EQ(do_ustore_16(vm_max_address(), 0), EFAULT); 884} 885ATF_TC_CLEANUP(ustore_16_max, tc) 886{ 887 unload_module(); 888} 889 890ATF_TC_WITH_CLEANUP(ustore_32_max); 891ATF_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} 896ATF_TC_BODY(ustore_32_max, tc) 897{ 898 CHECK_MODULE(); 899 900 ATF_REQUIRE_EQ(do_ustore_32(vm_max_address(), 0), EFAULT); 901} 902ATF_TC_CLEANUP(ustore_32_max, tc) 903{ 904 unload_module(); 905} 906 907#ifdef _LP64 908ATF_TC_WITH_CLEANUP(ustore_64_max); 909ATF_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} 914ATF_TC_BODY(ustore_64_max, tc) 915{ 916 CHECK_MODULE(); 917 918 ATF_REQUIRE_EQ(do_ustore_64(vm_max_address(), 0), EFAULT); 919} 920ATF_TC_CLEANUP(ustore_64_max, tc) 921{ 922 unload_module(); 923} 924#endif /* _LP64 */ 925 926ATF_TC_WITH_CLEANUP(ustore_16_nearmax_overflow); 927ATF_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} 932ATF_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} 945ATF_TC_CLEANUP(ustore_16_nearmax_overflow, tc) 946{ 947 unload_module(); 948} 949 950ATF_TC_WITH_CLEANUP(ustore_32_nearmax_overflow); 951ATF_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} 956ATF_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} 969ATF_TC_CLEANUP(ustore_32_nearmax_overflow, tc) 970{ 971 unload_module(); 972} 973 974#ifdef _LP64 975ATF_TC_WITH_CLEANUP(ustore_64_nearmax_overflow); 976ATF_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} 981ATF_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} 994ATF_TC_CLEANUP(ustore_64_nearmax_overflow, tc) 995{ 996 unload_module(); 997} 998#endif /* _LP64 */ 999 1000 1001ATF_TC_WITH_CLEANUP(ucas_32); 1002ATF_TC_HEAD(ucas_32, tc) 1003{ 1004 atf_tc_set_md_var(tc, "descr", 1005 "test for correct ucas_32 behavior"); 1006} 1007ATF_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} 1018ATF_TC_CLEANUP(ucas_32, tc) 1019{ 1020 unload_module(); 1021} 1022 1023#ifdef _LP64 1024ATF_TC_WITH_CLEANUP(ucas_64); 1025ATF_TC_HEAD(ucas_64, tc) 1026{ 1027 atf_tc_set_md_var(tc, "descr", 1028 "test for correct ucas_64 behavior"); 1029} 1030ATF_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} 1041ATF_TC_CLEANUP(ucas_64, tc) 1042{ 1043 unload_module(); 1044} 1045#endif /* _LP64 */ 1046 1047ATF_TC_WITH_CLEANUP(ucas_32_miscompare); 1048ATF_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} 1053ATF_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} 1064ATF_TC_CLEANUP(ucas_32_miscompare, tc) 1065{ 1066 unload_module(); 1067} 1068 1069#ifdef _LP64 1070ATF_TC_WITH_CLEANUP(ucas_64_miscompare); 1071ATF_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} 1076ATF_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} 1087ATF_TC_CLEANUP(ucas_64_miscompare, tc) 1088{ 1089 unload_module(); 1090} 1091#endif /* _LP64 */ 1092 1093ATF_TC_WITH_CLEANUP(ucas_32_null); 1094ATF_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} 1099ATF_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} 1108ATF_TC_CLEANUP(ucas_32_null, tc) 1109{ 1110 unload_module(); 1111} 1112 1113#ifdef _LP64 1114ATF_TC_WITH_CLEANUP(ucas_64_null); 1115ATF_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} 1120ATF_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} 1129ATF_TC_CLEANUP(ucas_64_null, tc) 1130{ 1131 unload_module(); 1132} 1133#endif /* _LP64 */ 1134 1135ATF_TC_WITH_CLEANUP(ucas_32_max); 1136ATF_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} 1141ATF_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} 1150ATF_TC_CLEANUP(ucas_32_max, tc) 1151{ 1152 unload_module(); 1153} 1154 1155#ifdef _LP64 1156ATF_TC_WITH_CLEANUP(ucas_64_max); 1157ATF_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} 1162ATF_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} 1171ATF_TC_CLEANUP(ucas_64_max, tc) 1172{ 1173 unload_module(); 1174} 1175#endif /* _LP64 */ 1176 1177ATF_TC_WITH_CLEANUP(ucas_32_nearmax_overflow); 1178ATF_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} 1183ATF_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} 1199ATF_TC_CLEANUP(ucas_32_nearmax_overflow, tc) 1200{ 1201 unload_module(); 1202} 1203 1204#ifdef _LP64 1205ATF_TC_WITH_CLEANUP(ucas_64_nearmax_overflow); 1206ATF_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} 1211ATF_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} 1227ATF_TC_CLEANUP(ucas_64_nearmax_overflow, tc) 1228{ 1229 unload_module(); 1230} 1231#endif /* _LP64 */ 1232 1233ATF_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