Home | History | Annotate | Line # | Download | only in ufetchstore
t_ufetchstore.c revision 1.2
      1 /*	$NetBSD: t_ufetchstore.c,v 1.2 2019/04/07 03:35:25 rin 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.2 2019/04/07 03:35:25 rin 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, &params) != 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	UADDR64(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 void *
    105 vm_max_address(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 (void *)max_addr;
    118 }
    119 
    120 static int
    121 do_sysctl(struct ufetchstore_test_args *args)
    122 {
    123 	uint64_t arg_addr64 = (uintptr_t)args;
    124 	int rv;
    125 
    126 	args->fetchstore_error = EBADF;	/* poison */
    127 	args->pointer_size = (int)sizeof(void *);
    128 
    129 	/*
    130 	 * Yes, the intent is to provide the pointer, not the structure,
    131 	 * to the kernel side of the test harness.
    132 	 */
    133 	rv = sysctlbyname(mib_name, NULL, NULL, &arg_addr64,
    134 			  sizeof(arg_addr64));
    135 	if (rv != 0) {
    136 		rv = errno;
    137 		warn("sysctlbyname('%s') -> %d", mib_name, rv);
    138 		return rv;
    139 	}
    140 	return 0;
    141 }
    142 
    143 static int
    144 do_ufetch_8(const uint8_t *uaddr, uint8_t *res)
    145 {
    146 	struct ufetchstore_test_args args = {
    147 		.uaddr64 = UADDR64(uaddr),
    148 		.test_op = OP_LOAD,
    149 		.size = 8,
    150 	};
    151 
    152 	ATF_REQUIRE_EQ(do_sysctl(&args), 0);
    153 	*res = args.val8;
    154 	return args.fetchstore_error;
    155 }
    156 
    157 static int
    158 do_ufetch_16(const uint16_t *uaddr, uint16_t *res)
    159 {
    160 	struct ufetchstore_test_args args = {
    161 		.uaddr64 = UADDR64(uaddr),
    162 		.test_op = OP_LOAD,
    163 		.size = 16,
    164 	};
    165 
    166 	ATF_REQUIRE_EQ(do_sysctl(&args), 0);
    167 	*res = args.val16;
    168 	return args.fetchstore_error;
    169 }
    170 
    171 static int
    172 do_ufetch_32(const uint32_t *uaddr, uint32_t *res)
    173 {
    174 	struct ufetchstore_test_args args = {
    175 		.uaddr64 = UADDR64(uaddr),
    176 		.test_op = OP_LOAD,
    177 		.size = 32,
    178 	};
    179 
    180 	ATF_REQUIRE_EQ(do_sysctl(&args), 0);
    181 	*res = args.val32;
    182 	return args.fetchstore_error;
    183 }
    184 
    185 #ifdef _LP64
    186 static int
    187 do_ufetch_64(const uint64_t *uaddr, uint64_t *res)
    188 {
    189 	struct ufetchstore_test_args args = {
    190 		.uaddr64 = UADDR64(uaddr),
    191 		.test_op = OP_LOAD,
    192 		.size = 64,
    193 	};
    194 
    195 	ATF_REQUIRE_EQ(do_sysctl(&args), 0);
    196 	*res = args.val64;
    197 	return args.fetchstore_error;
    198 }
    199 #endif /* _LP64 */
    200 
    201 static int
    202 do_ustore_8(uint8_t *uaddr, uint8_t val)
    203 {
    204 	struct ufetchstore_test_args args = {
    205 		.uaddr64 = UADDR64(uaddr),
    206 		.test_op = OP_STORE,
    207 		.size = 8,
    208 		.val8 = val,
    209 	};
    210 
    211 	ATF_REQUIRE_EQ(do_sysctl(&args), 0);
    212 	return args.fetchstore_error;
    213 }
    214 
    215 static int
    216 do_ustore_16(uint16_t *uaddr, uint16_t val)
    217 {
    218 	struct ufetchstore_test_args args = {
    219 		.uaddr64 = UADDR64(uaddr),
    220 		.test_op = OP_STORE,
    221 		.size = 16,
    222 		.val16 = val,
    223 	};
    224 
    225 	ATF_REQUIRE_EQ(do_sysctl(&args), 0);
    226 	return args.fetchstore_error;
    227 }
    228 
    229 static int
    230 do_ustore_32(uint32_t *uaddr, uint32_t val)
    231 {
    232 	struct ufetchstore_test_args args = {
    233 		.uaddr64 = UADDR64(uaddr),
    234 		.test_op = OP_STORE,
    235 		.size = 32,
    236 		.val32 = val,
    237 	};
    238 
    239 	ATF_REQUIRE_EQ(do_sysctl(&args), 0);
    240 	return args.fetchstore_error;
    241 }
    242 
    243 #ifdef _LP64
    244 static int
    245 do_ustore_64(uint64_t *uaddr, uint64_t val)
    246 {
    247 	struct ufetchstore_test_args args = {
    248 		.uaddr64 = UADDR64(uaddr),
    249 		.test_op = OP_STORE,
    250 		.size = 64,
    251 		.val64 = val,
    252 	};
    253 
    254 	ATF_REQUIRE_EQ(do_sysctl(&args), 0);
    255 	return args.fetchstore_error;
    256 }
    257 #endif /* _LP64 */
    258 
    259 static int
    260 do_ucas_32(uint32_t *uaddr, uint32_t expected, uint32_t new, uint32_t *actualp)
    261 {
    262 	struct ufetchstore_test_args args = {
    263 		.uaddr64 = UADDR64(uaddr),
    264 		.test_op = OP_CAS,
    265 		.size = 32,
    266 		.val32 = new,
    267 		.ea_val32 = expected,
    268 	};
    269 
    270 	ATF_REQUIRE_EQ(do_sysctl(&args), 0);
    271 	*actualp = args.ea_val32;
    272 	return args.fetchstore_error;
    273 }
    274 
    275 #ifdef _LP64
    276 static int
    277 do_ucas_64(uint64_t *uaddr, uint64_t expected, uint64_t new, uint64_t *actualp)
    278 {
    279 	struct ufetchstore_test_args args = {
    280 		.uaddr64 = UADDR64(uaddr),
    281 		.test_op = OP_CAS,
    282 		.size = 64,
    283 		.val64 = new,
    284 		.ea_val64 = expected,
    285 	};
    286 
    287 	ATF_REQUIRE_EQ(do_sysctl(&args), 0);
    288 	*actualp = args.ea_val64;
    289 	return args.fetchstore_error;
    290 }
    291 #endif /* _LP64 */
    292 
    293 struct memory_cell {
    294 	unsigned long guard0;
    295 	union {
    296 		unsigned long test_cell;
    297 #ifdef _LP64
    298 		uint64_t val64;
    299 #endif
    300 		uint32_t val32[sizeof(long) / 4];
    301 		uint16_t val16[sizeof(long) / 2];
    302 		uint8_t  val8 [sizeof(long)    ];
    303 	};
    304 	unsigned long guard1;
    305 };
    306 
    307 #define	index8		1
    308 #define	index16		1
    309 #define	index32		0
    310 
    311 #define	test_pattern8	0xa5
    312 #define	test_pattern16	0x5a6b
    313 #define	test_pattern32	0xb01cafe1
    314 #ifdef _LP64
    315 #define	test_pattern64	0xcafedeadfeedbabe
    316 #endif
    317 
    318 #if _BYTE_ORDER == _LITTLE_ENDIAN
    319 #define	test_cell_val8	((unsigned long)test_pattern8  << (index8  * NBBY))
    320 #define	test_cell_val16	((unsigned long)test_pattern16 << (index16 * NBBY*2))
    321 #define	test_cell_val32	((unsigned long)test_pattern32 << (index32 * NBBY*4))
    322 #ifdef _LP64
    323 #define	test_cell_val64	((unsigned long)test_pattern64)
    324 #endif
    325 #endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
    326 
    327 #if _BYTE_ORDER == _BIG_ENDIAN
    328 #ifdef _LP64
    329 #define	test_cell_val8	((unsigned long)test_pattern8  << (56-(index8  * NBBY)))
    330 #define	test_cell_val16	((unsigned long)test_pattern16 << (48-(index16 * NBBY*2)))
    331 #define	test_cell_val32	((unsigned long)test_pattern32 << (32-(index32 * NBBY*4)))
    332 #define	test_cell_val64	((unsigned long)test_pattern64)
    333 #else /* ! _LP64 */
    334 #define	test_cell_val8	((unsigned long)test_pattern8  << (24-(index8  * NBBY)))
    335 #define	test_cell_val16	((unsigned long)test_pattern16 << (16-(index16 * NBBY*2)))
    336 #define	test_cell_val32	((unsigned long)test_pattern32)
    337 #endif /* _LP64 */
    338 #endif /* #if _BYTE_ORDER == _BIG_ENDIAN */
    339 
    340 #define	read_test_cell(cell)		(cell)->test_cell
    341 #define	write_test_cell(cell, v)	(cell)->test_cell = (v)
    342 
    343 #define	memory_cell_initializer		\
    344 	{				\
    345 		.guard0 = ULONG_MAX,	\
    346 		.test_cell = 0,		\
    347 		.guard1 = ULONG_MAX,	\
    348 	}
    349 
    350 static bool
    351 memory_cell_check_guard(const struct memory_cell * const cell)
    352 {
    353 	return cell->guard0 == ULONG_MAX &&
    354 	       cell->guard1 == ULONG_MAX;
    355 }
    356 
    357 ATF_TC_WITH_CLEANUP(ufetch_8);
    358 ATF_TC_HEAD(ufetch_8, tc)
    359 {
    360 	atf_tc_set_md_var(tc, "descr",
    361 	    "test for correct ufetch_8 behavior");
    362 }
    363 ATF_TC_BODY(ufetch_8, tc)
    364 {
    365 	struct memory_cell cell = memory_cell_initializer;
    366 	uint8_t res;
    367 
    368 	CHECK_MODULE();
    369 
    370 	write_test_cell(&cell, test_cell_val8);
    371 	ATF_REQUIRE_EQ(do_ufetch_8(&cell.val8[index8], &res), 0);
    372 	ATF_REQUIRE(memory_cell_check_guard(&cell));
    373 	ATF_REQUIRE(res == test_pattern8);
    374 }
    375 ATF_TC_CLEANUP(ufetch_8, tc)
    376 {
    377 	unload_module();
    378 }
    379 
    380 ATF_TC_WITH_CLEANUP(ufetch_16);
    381 ATF_TC_HEAD(ufetch_16, tc)
    382 {
    383 	atf_tc_set_md_var(tc, "descr",
    384 	    "test for correct ufetch_16 behavior");
    385 }
    386 ATF_TC_BODY(ufetch_16, tc)
    387 {
    388 	struct memory_cell cell = memory_cell_initializer;
    389 	uint16_t res;
    390 
    391 	CHECK_MODULE();
    392 
    393 	write_test_cell(&cell, test_cell_val16);
    394 	ATF_REQUIRE_EQ(do_ufetch_16(&cell.val16[index16], &res), 0);
    395 	ATF_REQUIRE(memory_cell_check_guard(&cell));
    396 	ATF_REQUIRE(res == test_pattern16);
    397 }
    398 ATF_TC_CLEANUP(ufetch_16, tc)
    399 {
    400 	unload_module();
    401 }
    402 
    403 ATF_TC_WITH_CLEANUP(ufetch_32);
    404 ATF_TC_HEAD(ufetch_32, tc)
    405 {
    406 	atf_tc_set_md_var(tc, "descr",
    407 	    "test for correct ufetch_32 behavior");
    408 }
    409 ATF_TC_BODY(ufetch_32, tc)
    410 {
    411 	struct memory_cell cell = memory_cell_initializer;
    412 	uint32_t res;
    413 
    414 	CHECK_MODULE();
    415 
    416 	write_test_cell(&cell, test_cell_val32);
    417 	ATF_REQUIRE_EQ(do_ufetch_32(&cell.val32[index32], &res), 0);
    418 	ATF_REQUIRE(memory_cell_check_guard(&cell));
    419 	ATF_REQUIRE(res == test_pattern32);
    420 }
    421 ATF_TC_CLEANUP(ufetch_32, tc)
    422 {
    423 	unload_module();
    424 }
    425 
    426 #ifdef _LP64
    427 ATF_TC_WITH_CLEANUP(ufetch_64);
    428 ATF_TC_HEAD(ufetch_64, tc)
    429 {
    430 	atf_tc_set_md_var(tc, "descr",
    431 	    "test for correct ufetch_64 behavior");
    432 }
    433 ATF_TC_BODY(ufetch_64, tc)
    434 {
    435 	struct memory_cell cell = memory_cell_initializer;
    436 	uint64_t res;
    437 
    438 	CHECK_MODULE();
    439 
    440 	write_test_cell(&cell, test_cell_val64);
    441 	ATF_REQUIRE_EQ(do_ufetch_64(&cell.val64, &res), 0);
    442 	ATF_REQUIRE(memory_cell_check_guard(&cell));
    443 	ATF_REQUIRE(res == test_pattern64);
    444 }
    445 ATF_TC_CLEANUP(ufetch_64, tc)
    446 {
    447 	unload_module();
    448 }
    449 #endif /* _LP64 */
    450 
    451 ATF_TC_WITH_CLEANUP(ufetch_8_null);
    452 ATF_TC_HEAD(ufetch_8_null, tc)
    453 {
    454 	atf_tc_set_md_var(tc, "descr",
    455 	    "test for correct ufetch_8 NULL pointer behavior");
    456 }
    457 ATF_TC_BODY(ufetch_8_null, tc)
    458 {
    459 	uint8_t res;
    460 
    461 	CHECK_MODULE();
    462 
    463 	ATF_REQUIRE_EQ(do_ufetch_8(NULL, &res), EFAULT);
    464 }
    465 ATF_TC_CLEANUP(ufetch_8_null, tc)
    466 {
    467 	unload_module();
    468 }
    469 
    470 ATF_TC_WITH_CLEANUP(ufetch_16_null);
    471 ATF_TC_HEAD(ufetch_16_null, tc)
    472 {
    473 	atf_tc_set_md_var(tc, "descr",
    474 	    "test for correct ufetch_16 NULL pointer behavior");
    475 }
    476 ATF_TC_BODY(ufetch_16_null, tc)
    477 {
    478 	uint16_t res;
    479 
    480 	CHECK_MODULE();
    481 
    482 	ATF_REQUIRE_EQ(do_ufetch_16(NULL, &res), EFAULT);
    483 }
    484 ATF_TC_CLEANUP(ufetch_16_null, tc)
    485 {
    486 	unload_module();
    487 }
    488 
    489 ATF_TC_WITH_CLEANUP(ufetch_32_null);
    490 ATF_TC_HEAD(ufetch_32_null, tc)
    491 {
    492 	atf_tc_set_md_var(tc, "descr",
    493 	    "test for correct ufetch_32 NULL pointer behavior");
    494 }
    495 ATF_TC_BODY(ufetch_32_null, tc)
    496 {
    497 	uint32_t res;
    498 
    499 	CHECK_MODULE();
    500 
    501 	ATF_REQUIRE_EQ(do_ufetch_32(NULL, &res), EFAULT);
    502 }
    503 ATF_TC_CLEANUP(ufetch_32_null, tc)
    504 {
    505 	unload_module();
    506 }
    507 
    508 #ifdef _LP64
    509 ATF_TC_WITH_CLEANUP(ufetch_64_null);
    510 ATF_TC_HEAD(ufetch_64_null, tc)
    511 {
    512 	atf_tc_set_md_var(tc, "descr",
    513 	    "test for correct ufetch_64 NULL pointer behavior");
    514 }
    515 ATF_TC_BODY(ufetch_64_null, tc)
    516 {
    517 	uint64_t res;
    518 
    519 	CHECK_MODULE();
    520 
    521 	ATF_REQUIRE_EQ(do_ufetch_64(NULL, &res), EFAULT);
    522 }
    523 ATF_TC_CLEANUP(ufetch_64_null, tc)
    524 {
    525 	unload_module();
    526 }
    527 #endif /* _LP64 */
    528 
    529 ATF_TC_WITH_CLEANUP(ufetch_8_max);
    530 ATF_TC_HEAD(ufetch_8_max, tc)
    531 {
    532 	atf_tc_set_md_var(tc, "descr",
    533 	    "test for correct ufetch_8 VM_MAX_ADDRESS pointer behavior");
    534 }
    535 ATF_TC_BODY(ufetch_8_max, tc)
    536 {
    537 	uint8_t res;
    538 
    539 	CHECK_MODULE();
    540 
    541 	ATF_REQUIRE_EQ(do_ufetch_8(vm_max_address(), &res), EFAULT);
    542 }
    543 ATF_TC_CLEANUP(ufetch_8_max, tc)
    544 {
    545 	unload_module();
    546 }
    547 
    548 ATF_TC_WITH_CLEANUP(ufetch_16_max);
    549 ATF_TC_HEAD(ufetch_16_max, tc)
    550 {
    551 	atf_tc_set_md_var(tc, "descr",
    552 	    "test for correct ufetch_16 VM_MAX_ADDRESS pointer behavior");
    553 }
    554 ATF_TC_BODY(ufetch_16_max, tc)
    555 {
    556 	uint16_t res;
    557 
    558 	CHECK_MODULE();
    559 
    560 	ATF_REQUIRE_EQ(do_ufetch_16(vm_max_address(), &res), EFAULT);
    561 }
    562 ATF_TC_CLEANUP(ufetch_16_max, tc)
    563 {
    564 	unload_module();
    565 }
    566 
    567 ATF_TC_WITH_CLEANUP(ufetch_32_max);
    568 ATF_TC_HEAD(ufetch_32_max, tc)
    569 {
    570 	atf_tc_set_md_var(tc, "descr",
    571 	    "test for correct ufetch_32 VM_MAX_ADDRESS pointer behavior");
    572 }
    573 ATF_TC_BODY(ufetch_32_max, tc)
    574 {
    575 	uint32_t res;
    576 
    577 	CHECK_MODULE();
    578 
    579 	ATF_REQUIRE_EQ(do_ufetch_32(vm_max_address(), &res), EFAULT);
    580 }
    581 ATF_TC_CLEANUP(ufetch_32_max, tc)
    582 {
    583 	unload_module();
    584 }
    585 
    586 #ifdef _LP64
    587 ATF_TC_WITH_CLEANUP(ufetch_64_max);
    588 ATF_TC_HEAD(ufetch_64_max, tc)
    589 {
    590 	atf_tc_set_md_var(tc, "descr",
    591 	    "test for correct ufetch_64 VM_MAX_ADDRESS pointer behavior");
    592 }
    593 ATF_TC_BODY(ufetch_64_max, tc)
    594 {
    595 	uint64_t res;
    596 
    597 	CHECK_MODULE();
    598 
    599 	ATF_REQUIRE_EQ(do_ufetch_64(vm_max_address(), &res), EFAULT);
    600 }
    601 ATF_TC_CLEANUP(ufetch_64_max, tc)
    602 {
    603 	unload_module();
    604 }
    605 #endif /* _LP64 */
    606 
    607 ATF_TC_WITH_CLEANUP(ustore_8);
    608 ATF_TC_HEAD(ustore_8, tc)
    609 {
    610 	atf_tc_set_md_var(tc, "descr",
    611 	    "test for correct ustore_8 behavior");
    612 }
    613 ATF_TC_BODY(ustore_8, tc)
    614 {
    615 	struct memory_cell cell = memory_cell_initializer;
    616 
    617 	CHECK_MODULE();
    618 
    619 	ATF_REQUIRE_EQ(do_ustore_8(&cell.val8[index8], test_pattern8), 0);
    620 	ATF_REQUIRE(memory_cell_check_guard(&cell));
    621 	ATF_REQUIRE(read_test_cell(&cell) == test_cell_val8);
    622 }
    623 ATF_TC_CLEANUP(ustore_8, tc)
    624 {
    625 	unload_module();
    626 }
    627 
    628 ATF_TC_WITH_CLEANUP(ustore_16);
    629 ATF_TC_HEAD(ustore_16, tc)
    630 {
    631 	atf_tc_set_md_var(tc, "descr",
    632 	    "test for correct ustore_16 behavior");
    633 }
    634 ATF_TC_BODY(ustore_16, tc)
    635 {
    636 	struct memory_cell cell = memory_cell_initializer;
    637 
    638 	CHECK_MODULE();
    639 
    640 	ATF_REQUIRE_EQ(do_ustore_16(&cell.val16[index16], test_pattern16), 0);
    641 	ATF_REQUIRE(memory_cell_check_guard(&cell));
    642 	ATF_REQUIRE(read_test_cell(&cell) == test_cell_val16);
    643 }
    644 ATF_TC_CLEANUP(ustore_16, tc)
    645 {
    646 	unload_module();
    647 }
    648 
    649 ATF_TC_WITH_CLEANUP(ustore_32);
    650 ATF_TC_HEAD(ustore_32, tc)
    651 {
    652 	atf_tc_set_md_var(tc, "descr",
    653 	    "test for correct ustore_32 behavior");
    654 }
    655 ATF_TC_BODY(ustore_32, tc)
    656 {
    657 	struct memory_cell cell = memory_cell_initializer;
    658 
    659 	CHECK_MODULE();
    660 
    661 	ATF_REQUIRE_EQ(do_ustore_32(&cell.val32[index32], test_pattern32), 0);
    662 	ATF_REQUIRE(memory_cell_check_guard(&cell));
    663 	ATF_REQUIRE(read_test_cell(&cell) == test_cell_val32);
    664 }
    665 ATF_TC_CLEANUP(ustore_32, tc)
    666 {
    667 	unload_module();
    668 }
    669 
    670 #ifdef _LP64
    671 ATF_TC_WITH_CLEANUP(ustore_64);
    672 ATF_TC_HEAD(ustore_64, tc)
    673 {
    674 	atf_tc_set_md_var(tc, "descr",
    675 	    "test for correct ustore_64 behavior");
    676 }
    677 ATF_TC_BODY(ustore_64, tc)
    678 {
    679 	struct memory_cell cell = memory_cell_initializer;
    680 
    681 	CHECK_MODULE();
    682 
    683 	ATF_REQUIRE_EQ(do_ustore_64(&cell.val64, test_pattern64), 0);
    684 	ATF_REQUIRE(memory_cell_check_guard(&cell));
    685 	ATF_REQUIRE(read_test_cell(&cell) == test_cell_val64);
    686 }
    687 ATF_TC_CLEANUP(ustore_64, tc)
    688 {
    689 	unload_module();
    690 }
    691 #endif /* _LP64 */
    692 
    693 ATF_TC_WITH_CLEANUP(ustore_8_null);
    694 ATF_TC_HEAD(ustore_8_null, tc)
    695 {
    696 	atf_tc_set_md_var(tc, "descr",
    697 	    "test for correct ustore_8 NULL pointer behavior");
    698 }
    699 ATF_TC_BODY(ustore_8_null, tc)
    700 {
    701 	CHECK_MODULE();
    702 
    703 	ATF_REQUIRE_EQ(do_ustore_8(NULL, 0), EFAULT);
    704 }
    705 ATF_TC_CLEANUP(ustore_8_null, tc)
    706 {
    707 	unload_module();
    708 }
    709 
    710 ATF_TC_WITH_CLEANUP(ustore_16_null);
    711 ATF_TC_HEAD(ustore_16_null, tc)
    712 {
    713 	atf_tc_set_md_var(tc, "descr",
    714 	    "test for correct ustore_16 NULL pointer behavior");
    715 }
    716 ATF_TC_BODY(ustore_16_null, tc)
    717 {
    718 	CHECK_MODULE();
    719 
    720 	ATF_REQUIRE_EQ(do_ustore_16(NULL, 0), EFAULT);
    721 }
    722 ATF_TC_CLEANUP(ustore_16_null, tc)
    723 {
    724 	unload_module();
    725 }
    726 
    727 ATF_TC_WITH_CLEANUP(ustore_32_null);
    728 ATF_TC_HEAD(ustore_32_null, tc)
    729 {
    730 	atf_tc_set_md_var(tc, "descr",
    731 	    "test for correct ustore_32 NULL pointer behavior");
    732 }
    733 ATF_TC_BODY(ustore_32_null, tc)
    734 {
    735 	CHECK_MODULE();
    736 
    737 	ATF_REQUIRE_EQ(do_ustore_32(NULL, 0), EFAULT);
    738 }
    739 ATF_TC_CLEANUP(ustore_32_null, tc)
    740 {
    741 	unload_module();
    742 }
    743 
    744 #ifdef _LP64
    745 ATF_TC_WITH_CLEANUP(ustore_64_null);
    746 ATF_TC_HEAD(ustore_64_null, tc)
    747 {
    748 	atf_tc_set_md_var(tc, "descr",
    749 	    "test for correct ustore_64 NULL pointer behavior");
    750 }
    751 ATF_TC_BODY(ustore_64_null, tc)
    752 {
    753 	CHECK_MODULE();
    754 
    755 	ATF_REQUIRE_EQ(do_ustore_64(NULL, 0), EFAULT);
    756 }
    757 ATF_TC_CLEANUP(ustore_64_null, tc)
    758 {
    759 	unload_module();
    760 }
    761 #endif /* _LP64 */
    762 
    763 ATF_TC_WITH_CLEANUP(ustore_8_max);
    764 ATF_TC_HEAD(ustore_8_max, tc)
    765 {
    766 	atf_tc_set_md_var(tc, "descr",
    767 	    "test for correct ustore_8 VM_MAX_ADDRESS pointer behavior");
    768 }
    769 ATF_TC_BODY(ustore_8_max, tc)
    770 {
    771 	CHECK_MODULE();
    772 
    773 	ATF_REQUIRE_EQ(do_ustore_8(vm_max_address(), 0), EFAULT);
    774 }
    775 ATF_TC_CLEANUP(ustore_8_max, tc)
    776 {
    777 	unload_module();
    778 }
    779 
    780 ATF_TC_WITH_CLEANUP(ustore_16_max);
    781 ATF_TC_HEAD(ustore_16_max, tc)
    782 {
    783 	atf_tc_set_md_var(tc, "descr",
    784 	    "test for correct ustore_16 VM_MAX_ADDRESS pointer behavior");
    785 }
    786 ATF_TC_BODY(ustore_16_max, tc)
    787 {
    788 	CHECK_MODULE();
    789 
    790 	ATF_REQUIRE_EQ(do_ustore_16(vm_max_address(), 0), EFAULT);
    791 }
    792 ATF_TC_CLEANUP(ustore_16_max, tc)
    793 {
    794 	unload_module();
    795 }
    796 
    797 ATF_TC_WITH_CLEANUP(ustore_32_max);
    798 ATF_TC_HEAD(ustore_32_max, tc)
    799 {
    800 	atf_tc_set_md_var(tc, "descr",
    801 	    "test for correct ustore_32 VM_MAX_ADDRESS pointer behavior");
    802 }
    803 ATF_TC_BODY(ustore_32_max, tc)
    804 {
    805 	CHECK_MODULE();
    806 
    807 	ATF_REQUIRE_EQ(do_ustore_32(vm_max_address(), 0), EFAULT);
    808 }
    809 ATF_TC_CLEANUP(ustore_32_max, tc)
    810 {
    811 	unload_module();
    812 }
    813 
    814 #ifdef _LP64
    815 ATF_TC_WITH_CLEANUP(ustore_64_max);
    816 ATF_TC_HEAD(ustore_64_max, tc)
    817 {
    818 	atf_tc_set_md_var(tc, "descr",
    819 	    "test for correct ustore_64 VM_MAX_ADDRESS pointer behavior");
    820 }
    821 ATF_TC_BODY(ustore_64_max, tc)
    822 {
    823 	CHECK_MODULE();
    824 
    825 	ATF_REQUIRE_EQ(do_ustore_64(vm_max_address(), 0), EFAULT);
    826 }
    827 ATF_TC_CLEANUP(ustore_64_max, tc)
    828 {
    829 	unload_module();
    830 }
    831 #endif /* _LP64 */
    832 
    833 ATF_TC_WITH_CLEANUP(ucas_32);
    834 ATF_TC_HEAD(ucas_32, tc)
    835 {
    836 	atf_tc_set_md_var(tc, "descr",
    837 	    "test for correct ucas_32 behavior");
    838 }
    839 ATF_TC_BODY(ucas_32, tc)
    840 {
    841 	uint32_t cell = 0xdeadbeef;
    842 	uint32_t actual = 0;
    843 
    844 	CHECK_MODULE();
    845 
    846 	ATF_REQUIRE_EQ(do_ucas_32(&cell, 0xdeadbeef, 0xbeefdead, &actual), 0);
    847 	ATF_REQUIRE(actual == 0xdeadbeef);
    848 	ATF_REQUIRE(cell == 0xbeefdead);
    849 }
    850 ATF_TC_CLEANUP(ucas_32, tc)
    851 {
    852 	unload_module();
    853 }
    854 
    855 #ifdef _LP64
    856 ATF_TC_WITH_CLEANUP(ucas_64);
    857 ATF_TC_HEAD(ucas_64, tc)
    858 {
    859 	atf_tc_set_md_var(tc, "descr",
    860 	    "test for correct ucas_64 behavior");
    861 }
    862 ATF_TC_BODY(ucas_64, tc)
    863 {
    864 	uint64_t cell = 0xdeadbeef;
    865 	uint64_t actual = 0;
    866 
    867 	CHECK_MODULE();
    868 
    869 	ATF_REQUIRE_EQ(do_ucas_64(&cell, 0xdeadbeef, 0xbeefdead, &actual), 0);
    870 	ATF_REQUIRE(actual == 0xdeadbeef);
    871 	ATF_REQUIRE(cell == 0xbeefdead);
    872 }
    873 ATF_TC_CLEANUP(ucas_64, tc)
    874 {
    875 	unload_module();
    876 }
    877 #endif /* _LP64 */
    878 
    879 ATF_TC_WITH_CLEANUP(ucas_32_miscompare);
    880 ATF_TC_HEAD(ucas_32_miscompare, tc)
    881 {
    882 	atf_tc_set_md_var(tc, "descr",
    883 	    "test for correct ucas_32 behavior with miscompare");
    884 }
    885 ATF_TC_BODY(ucas_32_miscompare, tc)
    886 {
    887 	uint32_t cell = 0xa5a5a5a5;
    888 	uint32_t actual = 0;
    889 
    890 	CHECK_MODULE();
    891 
    892 	ATF_REQUIRE_EQ(do_ucas_32(&cell, 0xdeadbeef, 0xbeefdead, &actual), 0);
    893 	ATF_REQUIRE(actual == 0xa5a5a5a5);
    894 	ATF_REQUIRE(cell == 0xa5a5a5a5);
    895 }
    896 ATF_TC_CLEANUP(ucas_32_miscompare, tc)
    897 {
    898 	unload_module();
    899 }
    900 
    901 #ifdef _LP64
    902 ATF_TC_WITH_CLEANUP(ucas_64_miscompare);
    903 ATF_TC_HEAD(ucas_64_miscompare, tc)
    904 {
    905 	atf_tc_set_md_var(tc, "descr",
    906 	    "test for correct ucas_64 behavior with miscompare");
    907 }
    908 ATF_TC_BODY(ucas_64_miscompare, tc)
    909 {
    910 	uint64_t cell = 0xa5a5a5a5;
    911 	uint64_t actual = 0;
    912 
    913 	CHECK_MODULE();
    914 
    915 	ATF_REQUIRE_EQ(do_ucas_64(&cell, 0xdeadbeef, 0xbeefdead, &actual), 0);
    916 	ATF_REQUIRE(actual == 0xa5a5a5a5);
    917 	ATF_REQUIRE(cell == 0xa5a5a5a5);
    918 }
    919 ATF_TC_CLEANUP(ucas_64_miscompare, tc)
    920 {
    921 	unload_module();
    922 }
    923 #endif /* _LP64 */
    924 
    925 ATF_TC_WITH_CLEANUP(ucas_32_null);
    926 ATF_TC_HEAD(ucas_32_null, tc)
    927 {
    928 	atf_tc_set_md_var(tc, "descr",
    929 	    "test for correct ucas_32 NULL pointer behavior");
    930 }
    931 ATF_TC_BODY(ucas_32_null, tc)
    932 {
    933 	uint32_t actual = 0;
    934 
    935 	CHECK_MODULE();
    936 
    937 	ATF_REQUIRE_EQ(do_ucas_32(NULL, 0xdeadbeef, 0xbeefdead, &actual),
    938 	    EFAULT);
    939 }
    940 ATF_TC_CLEANUP(ucas_32_null, tc)
    941 {
    942 	unload_module();
    943 }
    944 
    945 #ifdef _LP64
    946 ATF_TC_WITH_CLEANUP(ucas_64_null);
    947 ATF_TC_HEAD(ucas_64_null, tc)
    948 {
    949 	atf_tc_set_md_var(tc, "descr",
    950 	    "test for correct ucas_64 NULL pointer behavior");
    951 }
    952 ATF_TC_BODY(ucas_64_null, tc)
    953 {
    954 	uint64_t actual = 0;
    955 
    956 	CHECK_MODULE();
    957 
    958 	ATF_REQUIRE_EQ(do_ucas_64(NULL, 0xdeadbeef, 0xbeefdead, &actual),
    959 	    EFAULT);
    960 }
    961 ATF_TC_CLEANUP(ucas_64_null, tc)
    962 {
    963 	unload_module();
    964 }
    965 #endif /* _LP64 */
    966 
    967 ATF_TC_WITH_CLEANUP(ucas_32_max);
    968 ATF_TC_HEAD(ucas_32_max, tc)
    969 {
    970 	atf_tc_set_md_var(tc, "descr",
    971 	    "test for correct ucas_32 VM_MAX_ADDRESS pointer behavior");
    972 }
    973 ATF_TC_BODY(ucas_32_max, tc)
    974 {
    975 	uint32_t actual = 0;
    976 
    977 	CHECK_MODULE();
    978 
    979 	ATF_REQUIRE_EQ(do_ucas_32(vm_max_address(), 0xdeadbeef, 0xbeefdead,
    980 	    &actual), EFAULT);
    981 }
    982 ATF_TC_CLEANUP(ucas_32_max, tc)
    983 {
    984 	unload_module();
    985 }
    986 
    987 #ifdef _LP64
    988 ATF_TC_WITH_CLEANUP(ucas_64_max);
    989 ATF_TC_HEAD(ucas_64_max, tc)
    990 {
    991 	atf_tc_set_md_var(tc, "descr",
    992 	    "test for correct ucas_64 VM_MAX_ADDRESS pointer behavior");
    993 }
    994 ATF_TC_BODY(ucas_64_max, tc)
    995 {
    996 	uint64_t actual = 0;
    997 
    998 	CHECK_MODULE();
    999 
   1000 	ATF_REQUIRE_EQ(do_ucas_64(vm_max_address(), 0xdeadbeef, 0xbeefdead,
   1001 	    &actual), EFAULT);
   1002 }
   1003 ATF_TC_CLEANUP(ucas_64_max, tc)
   1004 {
   1005 	unload_module();
   1006 }
   1007 #endif /* _LP64 */
   1008 
   1009 ATF_TP_ADD_TCS(tp)
   1010 {
   1011 	ATF_TP_ADD_TC(tp, ufetch_8);
   1012 	ATF_TP_ADD_TC(tp, ufetch_16);
   1013 	ATF_TP_ADD_TC(tp, ufetch_32);
   1014 #ifdef _LP64
   1015 	ATF_TP_ADD_TC(tp, ufetch_64);
   1016 #endif
   1017 
   1018 	ATF_TP_ADD_TC(tp, ufetch_8_null);
   1019 	ATF_TP_ADD_TC(tp, ufetch_16_null);
   1020 	ATF_TP_ADD_TC(tp, ufetch_32_null);
   1021 #ifdef _LP64
   1022 	ATF_TP_ADD_TC(tp, ufetch_64_null);
   1023 #endif
   1024 
   1025 	ATF_TP_ADD_TC(tp, ufetch_8_max);
   1026 	ATF_TP_ADD_TC(tp, ufetch_16_max);
   1027 	ATF_TP_ADD_TC(tp, ufetch_32_max);
   1028 #ifdef _LP64
   1029 	ATF_TP_ADD_TC(tp, ufetch_64_max);
   1030 #endif
   1031 
   1032 	ATF_TP_ADD_TC(tp, ustore_8);
   1033 	ATF_TP_ADD_TC(tp, ustore_16);
   1034 	ATF_TP_ADD_TC(tp, ustore_32);
   1035 #ifdef _LP64
   1036 	ATF_TP_ADD_TC(tp, ustore_64);
   1037 #endif
   1038 
   1039 	ATF_TP_ADD_TC(tp, ustore_8_null);
   1040 	ATF_TP_ADD_TC(tp, ustore_16_null);
   1041 	ATF_TP_ADD_TC(tp, ustore_32_null);
   1042 #ifdef _LP64
   1043 	ATF_TP_ADD_TC(tp, ustore_64_null);
   1044 #endif
   1045 
   1046 	ATF_TP_ADD_TC(tp, ustore_8_max);
   1047 	ATF_TP_ADD_TC(tp, ustore_16_max);
   1048 	ATF_TP_ADD_TC(tp, ustore_32_max);
   1049 #ifdef _LP64
   1050 	ATF_TP_ADD_TC(tp, ustore_64_max);
   1051 #endif
   1052 
   1053 	ATF_TP_ADD_TC(tp, ucas_32);
   1054 #ifdef _LP64
   1055 	ATF_TP_ADD_TC(tp, ucas_64);
   1056 #endif
   1057 
   1058 	ATF_TP_ADD_TC(tp, ucas_32_miscompare);
   1059 #ifdef _LP64
   1060 	ATF_TP_ADD_TC(tp, ucas_64_miscompare);
   1061 #endif
   1062 
   1063 	ATF_TP_ADD_TC(tp, ucas_32_null);
   1064 #ifdef _LP64
   1065 	ATF_TP_ADD_TC(tp, ucas_64_null);
   1066 #endif
   1067 
   1068 	ATF_TP_ADD_TC(tp, ucas_32_max);
   1069 #ifdef _LP64
   1070 	ATF_TP_ADD_TC(tp, ucas_64_max);
   1071 #endif
   1072 
   1073 	return atf_no_error();
   1074 }
   1075