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, ¶ms) != 0) {
79 warn("failed to load module '%s'", MODULE_PATH);
80 } else {
81 module_loaded = true;
82 }
83 #else
84 module_loaded = true;
85 #endif /* ! SKIP_MODULE */
86 }
87
88 #define UADDR(x) ((uintptr_t)(x))
89
90 static void
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