xref: /netbsd-src/tests/modules/ufetchstore/t_ufetchstore.c (revision c3061c70584058d693bb0262f8b55a2af2a4d77f)
1 /*	$NetBSD: t_ufetchstore.c,v 1.4 2019/04/07 15:50:12 thorpej 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.4 2019/04/07 15:50:12 thorpej 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
load_module(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	UADDR(x)	((uintptr_t)(x))
89 
90 static void
unload_module(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
vm_max_address_raw(void)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 *
vm_max_address(void)121 vm_max_address(void)
122 {
123 	return (void *)vm_max_address_raw();
124 }
125 
126 static void *
vm_max_address_minus(unsigned int adj)127 vm_max_address_minus(unsigned int adj)
128 {
129 	return (void *)(vm_max_address_raw() - adj);
130 }
131 
132 static int
do_sysctl(struct ufetchstore_test_args * args)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
do_ufetch_8(const uint8_t * uaddr,uint8_t * res)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
do_ufetch_16(const uint16_t * uaddr,uint16_t * res)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
do_ufetch_32(const uint32_t * uaddr,uint32_t * res)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
do_ufetch_64(const uint64_t * uaddr,uint64_t * res)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
do_ustore_8(uint8_t * uaddr,uint8_t val)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
do_ustore_16(uint16_t * uaddr,uint16_t val)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
do_ustore_32(uint32_t * uaddr,uint32_t val)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
do_ustore_64(uint64_t * uaddr,uint64_t val)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
do_ucas_32(uint32_t * uaddr,uint32_t expected,uint32_t new,uint32_t * actualp)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
do_ucas_64(uint64_t * uaddr,uint64_t expected,uint64_t new,uint64_t * actualp)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
memory_cell_check_guard(const struct memory_cell * const cell)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);
ATF_TC_HEAD(ufetch_8,tc)370 ATF_TC_HEAD(ufetch_8, tc)
371 {
372 	atf_tc_set_md_var(tc, "descr",
373 	    "test for correct ufetch_8 behavior");
374 }
ATF_TC_BODY(ufetch_8,tc)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 }
ATF_TC_CLEANUP(ufetch_8,tc)387 ATF_TC_CLEANUP(ufetch_8, tc)
388 {
389 	unload_module();
390 }
391 
392 ATF_TC_WITH_CLEANUP(ufetch_16);
ATF_TC_HEAD(ufetch_16,tc)393 ATF_TC_HEAD(ufetch_16, tc)
394 {
395 	atf_tc_set_md_var(tc, "descr",
396 	    "test for correct ufetch_16 behavior");
397 }
ATF_TC_BODY(ufetch_16,tc)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 }
ATF_TC_CLEANUP(ufetch_16,tc)410 ATF_TC_CLEANUP(ufetch_16, tc)
411 {
412 	unload_module();
413 }
414 
415 ATF_TC_WITH_CLEANUP(ufetch_32);
ATF_TC_HEAD(ufetch_32,tc)416 ATF_TC_HEAD(ufetch_32, tc)
417 {
418 	atf_tc_set_md_var(tc, "descr",
419 	    "test for correct ufetch_32 behavior");
420 }
ATF_TC_BODY(ufetch_32,tc)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 }
ATF_TC_CLEANUP(ufetch_32,tc)433 ATF_TC_CLEANUP(ufetch_32, tc)
434 {
435 	unload_module();
436 }
437 
438 #ifdef _LP64
439 ATF_TC_WITH_CLEANUP(ufetch_64);
ATF_TC_HEAD(ufetch_64,tc)440 ATF_TC_HEAD(ufetch_64, tc)
441 {
442 	atf_tc_set_md_var(tc, "descr",
443 	    "test for correct ufetch_64 behavior");
444 }
ATF_TC_BODY(ufetch_64,tc)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 }
ATF_TC_CLEANUP(ufetch_64,tc)457 ATF_TC_CLEANUP(ufetch_64, tc)
458 {
459 	unload_module();
460 }
461 #endif /* _LP64 */
462 
463 ATF_TC_WITH_CLEANUP(ufetch_8_null);
ATF_TC_HEAD(ufetch_8_null,tc)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 }
ATF_TC_BODY(ufetch_8_null,tc)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 }
ATF_TC_CLEANUP(ufetch_8_null,tc)477 ATF_TC_CLEANUP(ufetch_8_null, tc)
478 {
479 	unload_module();
480 }
481 
482 ATF_TC_WITH_CLEANUP(ufetch_16_null);
ATF_TC_HEAD(ufetch_16_null,tc)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 }
ATF_TC_BODY(ufetch_16_null,tc)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 }
ATF_TC_CLEANUP(ufetch_16_null,tc)496 ATF_TC_CLEANUP(ufetch_16_null, tc)
497 {
498 	unload_module();
499 }
500 
501 ATF_TC_WITH_CLEANUP(ufetch_32_null);
ATF_TC_HEAD(ufetch_32_null,tc)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 }
ATF_TC_BODY(ufetch_32_null,tc)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 }
ATF_TC_CLEANUP(ufetch_32_null,tc)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);
ATF_TC_HEAD(ufetch_64_null,tc)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 }
ATF_TC_BODY(ufetch_64_null,tc)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 }
ATF_TC_CLEANUP(ufetch_64_null,tc)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);
ATF_TC_HEAD(ufetch_8_max,tc)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 }
ATF_TC_BODY(ufetch_8_max,tc)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 }
ATF_TC_CLEANUP(ufetch_8_max,tc)555 ATF_TC_CLEANUP(ufetch_8_max, tc)
556 {
557 	unload_module();
558 }
559 
560 ATF_TC_WITH_CLEANUP(ufetch_16_max);
ATF_TC_HEAD(ufetch_16_max,tc)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 }
ATF_TC_BODY(ufetch_16_max,tc)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 }
ATF_TC_CLEANUP(ufetch_16_max,tc)574 ATF_TC_CLEANUP(ufetch_16_max, tc)
575 {
576 	unload_module();
577 }
578 
579 ATF_TC_WITH_CLEANUP(ufetch_32_max);
ATF_TC_HEAD(ufetch_32_max,tc)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 }
ATF_TC_BODY(ufetch_32_max,tc)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 }
ATF_TC_CLEANUP(ufetch_32_max,tc)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);
ATF_TC_HEAD(ufetch_64_max,tc)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 }
ATF_TC_BODY(ufetch_64_max,tc)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 }
ATF_TC_CLEANUP(ufetch_64_max,tc)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);
ATF_TC_HEAD(ufetch_16_nearmax_overflow,tc)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 }
ATF_TC_BODY(ufetch_16_nearmax_overflow,tc)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 }
ATF_TC_CLEANUP(ufetch_16_nearmax_overflow,tc)640 ATF_TC_CLEANUP(ufetch_16_nearmax_overflow, tc)
641 {
642 	unload_module();
643 }
644 
645 ATF_TC_WITH_CLEANUP(ufetch_32_nearmax_overflow);
ATF_TC_HEAD(ufetch_32_nearmax_overflow,tc)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 }
ATF_TC_BODY(ufetch_32_nearmax_overflow,tc)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 }
ATF_TC_CLEANUP(ufetch_32_nearmax_overflow,tc)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);
ATF_TC_HEAD(ufetch_64_nearmax_overflow,tc)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 }
ATF_TC_BODY(ufetch_64_nearmax_overflow,tc)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 }
ATF_TC_CLEANUP(ufetch_64_nearmax_overflow,tc)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);
ATF_TC_HEAD(ustore_8,tc)701 ATF_TC_HEAD(ustore_8, tc)
702 {
703 	atf_tc_set_md_var(tc, "descr",
704 	    "test for correct ustore_8 behavior");
705 }
ATF_TC_BODY(ustore_8,tc)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 }
ATF_TC_CLEANUP(ustore_8,tc)716 ATF_TC_CLEANUP(ustore_8, tc)
717 {
718 	unload_module();
719 }
720 
721 ATF_TC_WITH_CLEANUP(ustore_16);
ATF_TC_HEAD(ustore_16,tc)722 ATF_TC_HEAD(ustore_16, tc)
723 {
724 	atf_tc_set_md_var(tc, "descr",
725 	    "test for correct ustore_16 behavior");
726 }
ATF_TC_BODY(ustore_16,tc)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 }
ATF_TC_CLEANUP(ustore_16,tc)737 ATF_TC_CLEANUP(ustore_16, tc)
738 {
739 	unload_module();
740 }
741 
742 ATF_TC_WITH_CLEANUP(ustore_32);
ATF_TC_HEAD(ustore_32,tc)743 ATF_TC_HEAD(ustore_32, tc)
744 {
745 	atf_tc_set_md_var(tc, "descr",
746 	    "test for correct ustore_32 behavior");
747 }
ATF_TC_BODY(ustore_32,tc)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 }
ATF_TC_CLEANUP(ustore_32,tc)758 ATF_TC_CLEANUP(ustore_32, tc)
759 {
760 	unload_module();
761 }
762 
763 #ifdef _LP64
764 ATF_TC_WITH_CLEANUP(ustore_64);
ATF_TC_HEAD(ustore_64,tc)765 ATF_TC_HEAD(ustore_64, tc)
766 {
767 	atf_tc_set_md_var(tc, "descr",
768 	    "test for correct ustore_64 behavior");
769 }
ATF_TC_BODY(ustore_64,tc)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 }
ATF_TC_CLEANUP(ustore_64,tc)780 ATF_TC_CLEANUP(ustore_64, tc)
781 {
782 	unload_module();
783 }
784 #endif /* _LP64 */
785 
786 ATF_TC_WITH_CLEANUP(ustore_8_null);
ATF_TC_HEAD(ustore_8_null,tc)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 }
ATF_TC_BODY(ustore_8_null,tc)792 ATF_TC_BODY(ustore_8_null, tc)
793 {
794 	CHECK_MODULE();
795 
796 	ATF_REQUIRE_EQ(do_ustore_8(NULL, 0), EFAULT);
797 }
ATF_TC_CLEANUP(ustore_8_null,tc)798 ATF_TC_CLEANUP(ustore_8_null, tc)
799 {
800 	unload_module();
801 }
802 
803 ATF_TC_WITH_CLEANUP(ustore_16_null);
ATF_TC_HEAD(ustore_16_null,tc)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 }
ATF_TC_BODY(ustore_16_null,tc)809 ATF_TC_BODY(ustore_16_null, tc)
810 {
811 	CHECK_MODULE();
812 
813 	ATF_REQUIRE_EQ(do_ustore_16(NULL, 0), EFAULT);
814 }
ATF_TC_CLEANUP(ustore_16_null,tc)815 ATF_TC_CLEANUP(ustore_16_null, tc)
816 {
817 	unload_module();
818 }
819 
820 ATF_TC_WITH_CLEANUP(ustore_32_null);
ATF_TC_HEAD(ustore_32_null,tc)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 }
ATF_TC_BODY(ustore_32_null,tc)826 ATF_TC_BODY(ustore_32_null, tc)
827 {
828 	CHECK_MODULE();
829 
830 	ATF_REQUIRE_EQ(do_ustore_32(NULL, 0), EFAULT);
831 }
ATF_TC_CLEANUP(ustore_32_null,tc)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);
ATF_TC_HEAD(ustore_64_null,tc)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 }
ATF_TC_BODY(ustore_64_null,tc)844 ATF_TC_BODY(ustore_64_null, tc)
845 {
846 	CHECK_MODULE();
847 
848 	ATF_REQUIRE_EQ(do_ustore_64(NULL, 0), EFAULT);
849 }
ATF_TC_CLEANUP(ustore_64_null,tc)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);
ATF_TC_HEAD(ustore_8_max,tc)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 }
ATF_TC_BODY(ustore_8_max,tc)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 }
ATF_TC_CLEANUP(ustore_8_max,tc)868 ATF_TC_CLEANUP(ustore_8_max, tc)
869 {
870 	unload_module();
871 }
872 
873 ATF_TC_WITH_CLEANUP(ustore_16_max);
ATF_TC_HEAD(ustore_16_max,tc)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 }
ATF_TC_BODY(ustore_16_max,tc)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 }
ATF_TC_CLEANUP(ustore_16_max,tc)885 ATF_TC_CLEANUP(ustore_16_max, tc)
886 {
887 	unload_module();
888 }
889 
890 ATF_TC_WITH_CLEANUP(ustore_32_max);
ATF_TC_HEAD(ustore_32_max,tc)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 }
ATF_TC_BODY(ustore_32_max,tc)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 }
ATF_TC_CLEANUP(ustore_32_max,tc)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);
ATF_TC_HEAD(ustore_64_max,tc)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 }
ATF_TC_BODY(ustore_64_max,tc)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 }
ATF_TC_CLEANUP(ustore_64_max,tc)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);
ATF_TC_HEAD(ustore_16_nearmax_overflow,tc)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 }
ATF_TC_BODY(ustore_16_nearmax_overflow,tc)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 }
ATF_TC_CLEANUP(ustore_16_nearmax_overflow,tc)945 ATF_TC_CLEANUP(ustore_16_nearmax_overflow, tc)
946 {
947 	unload_module();
948 }
949 
950 ATF_TC_WITH_CLEANUP(ustore_32_nearmax_overflow);
ATF_TC_HEAD(ustore_32_nearmax_overflow,tc)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 }
ATF_TC_BODY(ustore_32_nearmax_overflow,tc)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 }
ATF_TC_CLEANUP(ustore_32_nearmax_overflow,tc)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);
ATF_TC_HEAD(ustore_64_nearmax_overflow,tc)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 }
ATF_TC_BODY(ustore_64_nearmax_overflow,tc)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 }
ATF_TC_CLEANUP(ustore_64_nearmax_overflow,tc)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);
ATF_TC_HEAD(ucas_32,tc)1002 ATF_TC_HEAD(ucas_32, tc)
1003 {
1004 	atf_tc_set_md_var(tc, "descr",
1005 	    "test for correct ucas_32 behavior");
1006 }
ATF_TC_BODY(ucas_32,tc)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 }
ATF_TC_CLEANUP(ucas_32,tc)1018 ATF_TC_CLEANUP(ucas_32, tc)
1019 {
1020 	unload_module();
1021 }
1022 
1023 #ifdef _LP64
1024 ATF_TC_WITH_CLEANUP(ucas_64);
ATF_TC_HEAD(ucas_64,tc)1025 ATF_TC_HEAD(ucas_64, tc)
1026 {
1027 	atf_tc_set_md_var(tc, "descr",
1028 	    "test for correct ucas_64 behavior");
1029 }
ATF_TC_BODY(ucas_64,tc)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 }
ATF_TC_CLEANUP(ucas_64,tc)1041 ATF_TC_CLEANUP(ucas_64, tc)
1042 {
1043 	unload_module();
1044 }
1045 #endif /* _LP64 */
1046 
1047 ATF_TC_WITH_CLEANUP(ucas_32_miscompare);
ATF_TC_HEAD(ucas_32_miscompare,tc)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 }
ATF_TC_BODY(ucas_32_miscompare,tc)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 }
ATF_TC_CLEANUP(ucas_32_miscompare,tc)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);
ATF_TC_HEAD(ucas_64_miscompare,tc)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 }
ATF_TC_BODY(ucas_64_miscompare,tc)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 }
ATF_TC_CLEANUP(ucas_64_miscompare,tc)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);
ATF_TC_HEAD(ucas_32_null,tc)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 }
ATF_TC_BODY(ucas_32_null,tc)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 }
ATF_TC_CLEANUP(ucas_32_null,tc)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);
ATF_TC_HEAD(ucas_64_null,tc)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 }
ATF_TC_BODY(ucas_64_null,tc)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 }
ATF_TC_CLEANUP(ucas_64_null,tc)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);
ATF_TC_HEAD(ucas_32_max,tc)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 }
ATF_TC_BODY(ucas_32_max,tc)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 }
ATF_TC_CLEANUP(ucas_32_max,tc)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);
ATF_TC_HEAD(ucas_64_max,tc)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 }
ATF_TC_BODY(ucas_64_max,tc)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 }
ATF_TC_CLEANUP(ucas_64_max,tc)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);
ATF_TC_HEAD(ucas_32_nearmax_overflow,tc)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 }
ATF_TC_BODY(ucas_32_nearmax_overflow,tc)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 }
ATF_TC_CLEANUP(ucas_32_nearmax_overflow,tc)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);
ATF_TC_HEAD(ucas_64_nearmax_overflow,tc)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 }
ATF_TC_BODY(ucas_64_nearmax_overflow,tc)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 }
ATF_TC_CLEANUP(ucas_64_nearmax_overflow,tc)1227 ATF_TC_CLEANUP(ucas_64_nearmax_overflow, tc)
1228 {
1229 	unload_module();
1230 }
1231 #endif /* _LP64 */
1232 
ATF_TP_ADD_TCS(tp)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