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, ¶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 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