1 /*
2  * Copyright (c) 2013-2018, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  *  * Redistributions of source code must retain the above copyright notice,
8  *    this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright notice,
10  *    this list of conditions and the following disclaimer in the documentation
11  *    and/or other materials provided with the distribution.
12  *  * Neither the name of Intel Corporation nor the names of its contributors
13  *    may be used to endorse or promote products derived from this software
14  *    without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "ptunit_threads.h"
30 #include "ptunit_mkfile.h"
31 
32 #include "pt_section.h"
33 #include "pt_block_cache.h"
34 
35 #include "intel-pt.h"
36 
37 #include <stdlib.h>
38 #include <stdio.h>
39 
40 
41 
42 struct pt_image_section_cache {
43 	int map;
44 };
45 
46 extern int pt_iscache_notify_map(struct pt_image_section_cache *iscache,
47 				 struct pt_section *section);
48 extern int pt_iscache_notify_resize(struct pt_image_section_cache *iscache,
49 				    struct pt_section *section, uint64_t size);
50 
51 int pt_iscache_notify_map(struct pt_image_section_cache *iscache,
52 			  struct pt_section *section)
53 {
54 	if (!iscache)
55 		return -pte_internal;
56 
57 	if (iscache->map <= 0)
58 		return iscache->map;
59 
60 	/* Avoid recursion. */
61 	iscache->map = 0;
62 
63 	return pt_section_map_share(section);
64 }
65 
66 int pt_iscache_notify_resize(struct pt_image_section_cache *iscache,
67 			     struct pt_section *section, uint64_t size)
68 {
69 	uint64_t memsize;
70 	int errcode;
71 
72 	if (!iscache)
73 		return -pte_internal;
74 
75 	if (iscache->map <= 0)
76 		return iscache->map;
77 
78 	/* Avoid recursion. */
79 	iscache->map = 0;
80 
81 	errcode = pt_section_memsize(section, &memsize);
82 	if (errcode < 0)
83 		return errcode;
84 
85 	if (size != memsize)
86 		return -pte_internal;
87 
88 	return pt_section_map_share(section);
89 }
90 
91 struct pt_block_cache *pt_bcache_alloc(uint64_t nentries)
92 {
93 	struct pt_block_cache *bcache;
94 
95 	if (!nentries || (UINT32_MAX < nentries))
96 		return NULL;
97 
98 	/* The cache is not really used by tests.  It suffices to allocate only
99 	 * the cache struct with the single default entry.
100 	 *
101 	 * We still set the number of entries to the requested size.
102 	 */
103 	bcache = malloc(sizeof(*bcache));
104 	if (bcache)
105 		bcache->nentries = (uint32_t) nentries;
106 
107 	return bcache;
108 }
109 
110 void pt_bcache_free(struct pt_block_cache *bcache)
111 {
112 	free(bcache);
113 }
114 
115 /* A test fixture providing a temporary file and an initially NULL section. */
116 struct section_fixture {
117 	/* Threading support. */
118 	struct ptunit_thrd_fixture thrd;
119 
120 	/* A temporary file name. */
121 	char *name;
122 
123 	/* That file opened for writing. */
124 	FILE *file;
125 
126 	/* The section. */
127 	struct pt_section *section;
128 
129 	/* The test fixture initialization and finalization functions. */
130 	struct ptunit_result (*init)(struct section_fixture *);
131 	struct ptunit_result (*fini)(struct section_fixture *);
132 };
133 
134 enum {
135 #if defined(FEATURE_THREADS)
136 
137 	num_threads	= 4,
138 
139 #endif /* defined(FEATURE_THREADS) */
140 
141 	num_work	= 0x4000
142 };
143 
144 static struct ptunit_result sfix_write_aux(struct section_fixture *sfix,
145 					   const uint8_t *buffer, size_t size)
146 {
147 	size_t written;
148 
149 	written = fwrite(buffer, 1, size, sfix->file);
150 	ptu_uint_eq(written, size);
151 
152 	fflush(sfix->file);
153 
154 	return ptu_passed();
155 }
156 
157 #define sfix_write(sfix, buffer)				\
158 	ptu_check(sfix_write_aux, sfix, buffer, sizeof(buffer))
159 
160 static struct ptunit_result create(struct section_fixture *sfix)
161 {
162 	const char *name;
163 	uint8_t bytes[] = { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc };
164 	uint64_t offset, size;
165 
166 	sfix_write(sfix, bytes);
167 
168 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
169 	ptu_ptr(sfix->section);
170 
171 	name = pt_section_filename(sfix->section);
172 	ptu_str_eq(name, sfix->name);
173 
174 	offset = pt_section_offset(sfix->section);
175 	ptu_uint_eq(offset, 0x1ull);
176 
177 	size = pt_section_size(sfix->section);
178 	ptu_uint_eq(size, 0x3ull);
179 
180 	return ptu_passed();
181 }
182 
183 static struct ptunit_result create_bad_offset(struct section_fixture *sfix)
184 {
185 	sfix->section = pt_mk_section(sfix->name, 0x10ull, 0x0ull);
186 	ptu_null(sfix->section);
187 
188 	return ptu_passed();
189 }
190 
191 static struct ptunit_result create_truncated(struct section_fixture *sfix)
192 {
193 	const char *name;
194 	uint8_t bytes[] = { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc };
195 	uint64_t offset, size;
196 
197 	sfix_write(sfix, bytes);
198 
199 	sfix->section = pt_mk_section(sfix->name, 0x1ull, UINT64_MAX);
200 	ptu_ptr(sfix->section);
201 
202 	name = pt_section_filename(sfix->section);
203 	ptu_str_eq(name, sfix->name);
204 
205 	offset = pt_section_offset(sfix->section);
206 	ptu_uint_eq(offset, 0x1ull);
207 
208 	size = pt_section_size(sfix->section);
209 	ptu_uint_eq(size, sizeof(bytes) - 1);
210 
211 	return ptu_passed();
212 }
213 
214 static struct ptunit_result create_empty(struct section_fixture *sfix)
215 {
216 	sfix->section = pt_mk_section(sfix->name, 0x0ull, 0x10ull);
217 	ptu_null(sfix->section);
218 
219 	return ptu_passed();
220 }
221 
222 static struct ptunit_result filename_null(void)
223 {
224 	const char *name;
225 
226 	name = pt_section_filename(NULL);
227 	ptu_null(name);
228 
229 	return ptu_passed();
230 }
231 
232 static struct ptunit_result size_null(void)
233 {
234 	uint64_t size;
235 
236 	size = pt_section_size(NULL);
237 	ptu_uint_eq(size, 0ull);
238 
239 	return ptu_passed();
240 }
241 
242 static struct ptunit_result memsize_null(struct section_fixture *sfix)
243 {
244 	uint64_t size;
245 	int errcode;
246 
247 	errcode = pt_section_memsize(NULL, &size);
248 	ptu_int_eq(errcode, -pte_internal);
249 
250 	errcode = pt_section_memsize(sfix->section, NULL);
251 	ptu_int_eq(errcode, -pte_internal);
252 
253 	errcode = pt_section_memsize(NULL, NULL);
254 	ptu_int_eq(errcode, -pte_internal);
255 
256 	return ptu_passed();
257 }
258 
259 static struct ptunit_result offset_null(void)
260 {
261 	uint64_t offset;
262 
263 	offset = pt_section_offset(NULL);
264 	ptu_uint_eq(offset, 0ull);
265 
266 	return ptu_passed();
267 }
268 
269 static struct ptunit_result get_null(void)
270 {
271 	int errcode;
272 
273 	errcode = pt_section_get(NULL);
274 	ptu_int_eq(errcode, -pte_internal);
275 
276 	return ptu_passed();
277 }
278 
279 static struct ptunit_result put_null(void)
280 {
281 	int errcode;
282 
283 	errcode = pt_section_put(NULL);
284 	ptu_int_eq(errcode, -pte_internal);
285 
286 	return ptu_passed();
287 }
288 
289 static struct ptunit_result attach_null(void)
290 {
291 	struct pt_image_section_cache iscache;
292 	struct pt_section section;
293 	int errcode;
294 
295 	errcode = pt_section_attach(NULL, &iscache);
296 	ptu_int_eq(errcode, -pte_internal);
297 
298 	errcode = pt_section_attach(&section, NULL);
299 	ptu_int_eq(errcode, -pte_internal);
300 
301 	errcode = pt_section_attach(NULL, NULL);
302 	ptu_int_eq(errcode, -pte_internal);
303 
304 	return ptu_passed();
305 }
306 
307 static struct ptunit_result detach_null(void)
308 {
309 	struct pt_image_section_cache iscache;
310 	struct pt_section section;
311 	int errcode;
312 
313 	errcode = pt_section_detach(NULL, &iscache);
314 	ptu_int_eq(errcode, -pte_internal);
315 
316 	errcode = pt_section_detach(&section, NULL);
317 	ptu_int_eq(errcode, -pte_internal);
318 
319 	errcode = pt_section_detach(NULL, NULL);
320 	ptu_int_eq(errcode, -pte_internal);
321 
322 	return ptu_passed();
323 }
324 
325 static struct ptunit_result map_null(void)
326 {
327 	int errcode;
328 
329 	errcode = pt_section_map(NULL);
330 	ptu_int_eq(errcode, -pte_internal);
331 
332 	return ptu_passed();
333 }
334 
335 static struct ptunit_result unmap_null(void)
336 {
337 	int errcode;
338 
339 	errcode = pt_section_unmap(NULL);
340 	ptu_int_eq(errcode, -pte_internal);
341 
342 	return ptu_passed();
343 }
344 
345 static struct ptunit_result cache_null(void)
346 {
347 	struct pt_block_cache *bcache;
348 
349 	bcache = pt_section_bcache(NULL);
350 	ptu_null(bcache);
351 
352 	return ptu_passed();
353 }
354 
355 static struct ptunit_result get_overflow(struct section_fixture *sfix)
356 {
357 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
358 	int errcode;
359 
360 	sfix_write(sfix, bytes);
361 
362 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
363 	ptu_ptr(sfix->section);
364 
365 	sfix->section->ucount = UINT16_MAX;
366 
367 	errcode = pt_section_get(sfix->section);
368 	ptu_int_eq(errcode, -pte_overflow);
369 
370 	sfix->section->ucount = 1;
371 
372 	return ptu_passed();
373 }
374 
375 static struct ptunit_result attach_overflow(struct section_fixture *sfix)
376 {
377 	struct pt_image_section_cache iscache;
378 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
379 	int errcode;
380 
381 	sfix_write(sfix, bytes);
382 
383 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
384 	ptu_ptr(sfix->section);
385 
386 	sfix->section->acount = UINT16_MAX;
387 
388 	errcode = pt_section_attach(sfix->section, &iscache);
389 	ptu_int_eq(errcode, -pte_overflow);
390 
391 	sfix->section->acount = 0;
392 
393 	return ptu_passed();
394 }
395 
396 static struct ptunit_result attach_bad_ucount(struct section_fixture *sfix)
397 {
398 	struct pt_image_section_cache iscache;
399 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
400 	int errcode;
401 
402 	sfix_write(sfix, bytes);
403 
404 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
405 	ptu_ptr(sfix->section);
406 
407 	sfix->section->acount = 2;
408 
409 	errcode = pt_section_attach(sfix->section, &iscache);
410 	ptu_int_eq(errcode, -pte_internal);
411 
412 	sfix->section->acount = 0;
413 
414 	return ptu_passed();
415 }
416 
417 static struct ptunit_result map_change(struct section_fixture *sfix)
418 {
419 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
420 	int errcode;
421 
422 	sfix_write(sfix, bytes);
423 
424 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
425 	ptu_ptr(sfix->section);
426 
427 	sfix_write(sfix, bytes);
428 
429 	errcode = pt_section_map(sfix->section);
430 	ptu_int_eq(errcode, -pte_bad_image);
431 
432 	return ptu_passed();
433 }
434 
435 static struct ptunit_result map_put(struct section_fixture *sfix)
436 {
437 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
438 	int errcode;
439 
440 	sfix_write(sfix, bytes);
441 
442 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
443 	ptu_ptr(sfix->section);
444 
445 	errcode = pt_section_map(sfix->section);
446 	ptu_int_eq(errcode, 0);
447 
448 	errcode = pt_section_put(sfix->section);
449 	ptu_int_eq(errcode, -pte_internal);
450 
451 	errcode = pt_section_unmap(sfix->section);
452 	ptu_int_eq(errcode, 0);
453 
454 	return ptu_passed();
455 }
456 
457 static struct ptunit_result unmap_nomap(struct section_fixture *sfix)
458 {
459 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
460 	int errcode;
461 
462 	sfix_write(sfix, bytes);
463 
464 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
465 	ptu_ptr(sfix->section);
466 
467 	errcode = pt_section_unmap(sfix->section);
468 	ptu_int_eq(errcode, -pte_nomap);
469 
470 	return ptu_passed();
471 }
472 
473 static struct ptunit_result map_overflow(struct section_fixture *sfix)
474 {
475 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
476 	int errcode;
477 
478 	sfix_write(sfix, bytes);
479 
480 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
481 	ptu_ptr(sfix->section);
482 
483 	sfix->section->mcount = UINT16_MAX;
484 
485 	errcode = pt_section_map(sfix->section);
486 	ptu_int_eq(errcode, -pte_overflow);
487 
488 	sfix->section->mcount = 0;
489 
490 	return ptu_passed();
491 }
492 
493 static struct ptunit_result get_put(struct section_fixture *sfix)
494 {
495 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
496 	int errcode;
497 
498 	sfix_write(sfix, bytes);
499 
500 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
501 	ptu_ptr(sfix->section);
502 
503 	errcode = pt_section_get(sfix->section);
504 	ptu_int_eq(errcode, 0);
505 
506 	errcode = pt_section_get(sfix->section);
507 	ptu_int_eq(errcode, 0);
508 
509 	errcode = pt_section_put(sfix->section);
510 	ptu_int_eq(errcode, 0);
511 
512 	errcode = pt_section_put(sfix->section);
513 	ptu_int_eq(errcode, 0);
514 
515 	return ptu_passed();
516 }
517 
518 static struct ptunit_result attach_detach(struct section_fixture *sfix)
519 {
520 	struct pt_image_section_cache iscache;
521 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
522 	int errcode;
523 
524 	sfix_write(sfix, bytes);
525 
526 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
527 	ptu_ptr(sfix->section);
528 
529 	sfix->section->ucount += 2;
530 
531 	errcode = pt_section_attach(sfix->section, &iscache);
532 	ptu_int_eq(errcode, 0);
533 
534 	errcode = pt_section_attach(sfix->section, &iscache);
535 	ptu_int_eq(errcode, 0);
536 
537 	errcode = pt_section_detach(sfix->section, &iscache);
538 	ptu_int_eq(errcode, 0);
539 
540 	errcode = pt_section_detach(sfix->section, &iscache);
541 	ptu_int_eq(errcode, 0);
542 
543 	sfix->section->ucount -= 2;
544 
545 	return ptu_passed();
546 }
547 
548 static struct ptunit_result attach_bad_iscache(struct section_fixture *sfix)
549 {
550 	struct pt_image_section_cache iscache, bad;
551 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
552 	int errcode;
553 
554 	sfix_write(sfix, bytes);
555 
556 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
557 	ptu_ptr(sfix->section);
558 
559 	sfix->section->ucount += 2;
560 
561 	errcode = pt_section_attach(sfix->section, &iscache);
562 	ptu_int_eq(errcode, 0);
563 
564 	errcode = pt_section_attach(sfix->section, &bad);
565 	ptu_int_eq(errcode, -pte_internal);
566 
567 	errcode = pt_section_detach(sfix->section, &iscache);
568 	ptu_int_eq(errcode, 0);
569 
570 	sfix->section->ucount -= 2;
571 
572 	return ptu_passed();
573 }
574 
575 static struct ptunit_result detach_bad_iscache(struct section_fixture *sfix)
576 {
577 	struct pt_image_section_cache iscache, bad;
578 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
579 	int errcode;
580 
581 	sfix_write(sfix, bytes);
582 
583 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
584 	ptu_ptr(sfix->section);
585 
586 	errcode = pt_section_attach(sfix->section, &iscache);
587 	ptu_int_eq(errcode, 0);
588 
589 	errcode = pt_section_detach(sfix->section, &bad);
590 	ptu_int_eq(errcode, -pte_internal);
591 
592 	errcode = pt_section_detach(sfix->section, &iscache);
593 	ptu_int_eq(errcode, 0);
594 
595 	return ptu_passed();
596 }
597 
598 static struct ptunit_result map_unmap(struct section_fixture *sfix)
599 {
600 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
601 	int errcode;
602 
603 	sfix_write(sfix, bytes);
604 
605 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
606 	ptu_ptr(sfix->section);
607 
608 	errcode = pt_section_map(sfix->section);
609 	ptu_int_eq(errcode, 0);
610 
611 	errcode = pt_section_map(sfix->section);
612 	ptu_int_eq(errcode, 0);
613 
614 	errcode = pt_section_unmap(sfix->section);
615 	ptu_int_eq(errcode, 0);
616 
617 	errcode = pt_section_unmap(sfix->section);
618 	ptu_int_eq(errcode, 0);
619 
620 	return ptu_passed();
621 }
622 
623 static struct ptunit_result attach_map(struct section_fixture *sfix)
624 {
625 	struct pt_image_section_cache iscache;
626 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
627 	int errcode;
628 
629 	iscache.map = 0;
630 
631 	sfix_write(sfix, bytes);
632 
633 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
634 	ptu_ptr(sfix->section);
635 
636 	errcode = pt_section_attach(sfix->section, &iscache);
637 	ptu_int_eq(errcode, 0);
638 
639 	errcode = pt_section_map(sfix->section);
640 	ptu_int_eq(errcode, 0);
641 
642 	errcode = pt_section_map(sfix->section);
643 	ptu_int_eq(errcode, 0);
644 
645 	ptu_uint_eq(sfix->section->mcount, 2);
646 
647 	errcode = pt_section_unmap(sfix->section);
648 	ptu_int_eq(errcode, 0);
649 
650 	errcode = pt_section_unmap(sfix->section);
651 	ptu_int_eq(errcode, 0);
652 
653 	errcode = pt_section_detach(sfix->section, &iscache);
654 	ptu_int_eq(errcode, 0);
655 
656 	return ptu_passed();
657 }
658 
659 static struct ptunit_result attach_bad_map(struct section_fixture *sfix)
660 {
661 	struct pt_image_section_cache iscache;
662 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
663 	int errcode;
664 
665 	iscache.map = -pte_eos;
666 
667 	sfix_write(sfix, bytes);
668 
669 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
670 	ptu_ptr(sfix->section);
671 
672 	errcode = pt_section_attach(sfix->section, &iscache);
673 	ptu_int_eq(errcode, 0);
674 
675 	errcode = pt_section_map(sfix->section);
676 	ptu_int_eq(errcode, -pte_eos);
677 
678 	errcode = pt_section_detach(sfix->section, &iscache);
679 	ptu_int_eq(errcode, 0);
680 
681 	return ptu_passed();
682 }
683 
684 static struct ptunit_result attach_map_overflow(struct section_fixture *sfix)
685 {
686 	struct pt_image_section_cache iscache;
687 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
688 	int errcode;
689 
690 	iscache.map = 1;
691 
692 	sfix_write(sfix, bytes);
693 
694 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
695 	ptu_ptr(sfix->section);
696 
697 	errcode = pt_section_attach(sfix->section, &iscache);
698 	ptu_int_eq(errcode, 0);
699 
700 	sfix->section->mcount = UINT16_MAX - 1;
701 
702 	errcode = pt_section_map(sfix->section);
703 	ptu_int_eq(errcode, -pte_overflow);
704 
705 	errcode = pt_section_detach(sfix->section, &iscache);
706 	ptu_int_eq(errcode, 0);
707 
708 	return ptu_passed();
709 }
710 
711 static struct ptunit_result read(struct section_fixture *sfix)
712 {
713 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
714 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
715 	int status;
716 
717 	sfix_write(sfix, bytes);
718 
719 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
720 	ptu_ptr(sfix->section);
721 
722 	status = pt_section_map(sfix->section);
723 	ptu_int_eq(status, 0);
724 
725 	status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
726 	ptu_int_eq(status, 2);
727 	ptu_uint_eq(buffer[0], bytes[1]);
728 	ptu_uint_eq(buffer[1], bytes[2]);
729 	ptu_uint_eq(buffer[2], 0xcc);
730 
731 	status = pt_section_unmap(sfix->section);
732 	ptu_int_eq(status, 0);
733 
734 	return ptu_passed();
735 }
736 
737 static struct ptunit_result read_null(struct section_fixture *sfix)
738 {
739 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
740 	uint8_t buffer[] = { 0xcc };
741 	int status;
742 
743 	sfix_write(sfix, bytes);
744 
745 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
746 	ptu_ptr(sfix->section);
747 
748 	status = pt_section_map(sfix->section);
749 	ptu_int_eq(status, 0);
750 
751 	status = pt_section_read(sfix->section, NULL, 1, 0x0ull);
752 	ptu_int_eq(status, -pte_internal);
753 	ptu_uint_eq(buffer[0], 0xcc);
754 
755 	status = pt_section_read(NULL, buffer, 1, 0x0ull);
756 	ptu_int_eq(status, -pte_internal);
757 	ptu_uint_eq(buffer[0], 0xcc);
758 
759 	status = pt_section_unmap(sfix->section);
760 	ptu_int_eq(status, 0);
761 
762 	return ptu_passed();
763 }
764 
765 static struct ptunit_result read_offset(struct section_fixture *sfix)
766 {
767 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
768 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
769 	int status;
770 
771 	sfix_write(sfix, bytes);
772 
773 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
774 	ptu_ptr(sfix->section);
775 
776 	status = pt_section_map(sfix->section);
777 	ptu_int_eq(status, 0);
778 
779 	status = pt_section_read(sfix->section, buffer, 2, 0x1ull);
780 	ptu_int_eq(status, 2);
781 	ptu_uint_eq(buffer[0], bytes[2]);
782 	ptu_uint_eq(buffer[1], bytes[3]);
783 	ptu_uint_eq(buffer[2], 0xcc);
784 
785 	status = pt_section_unmap(sfix->section);
786 	ptu_int_eq(status, 0);
787 
788 	return ptu_passed();
789 }
790 
791 static struct ptunit_result read_truncated(struct section_fixture *sfix)
792 {
793 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc, 0xcc };
794 	int status;
795 
796 	sfix_write(sfix, bytes);
797 
798 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
799 	ptu_ptr(sfix->section);
800 
801 	status = pt_section_map(sfix->section);
802 	ptu_int_eq(status, 0);
803 
804 	status = pt_section_read(sfix->section, buffer, 2, 0x2ull);
805 	ptu_int_eq(status, 1);
806 	ptu_uint_eq(buffer[0], bytes[3]);
807 	ptu_uint_eq(buffer[1], 0xcc);
808 
809 	status = pt_section_unmap(sfix->section);
810 	ptu_int_eq(status, 0);
811 
812 	return ptu_passed();
813 }
814 
815 static struct ptunit_result read_from_truncated(struct section_fixture *sfix)
816 {
817 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc, 0xcc };
818 	int status;
819 
820 	sfix_write(sfix, bytes);
821 
822 	sfix->section = pt_mk_section(sfix->name, 0x2ull, 0x10ull);
823 	ptu_ptr(sfix->section);
824 
825 	status = pt_section_map(sfix->section);
826 	ptu_int_eq(status, 0);
827 
828 	status = pt_section_read(sfix->section, buffer, 2, 0x1ull);
829 	ptu_int_eq(status, 1);
830 	ptu_uint_eq(buffer[0], bytes[3]);
831 	ptu_uint_eq(buffer[1], 0xcc);
832 
833 	status = pt_section_unmap(sfix->section);
834 	ptu_int_eq(status, 0);
835 
836 	return ptu_passed();
837 }
838 
839 static struct ptunit_result read_nomem(struct section_fixture *sfix)
840 {
841 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
842 	int status;
843 
844 	sfix_write(sfix, bytes);
845 
846 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
847 	ptu_ptr(sfix->section);
848 
849 	status = pt_section_map(sfix->section);
850 	ptu_int_eq(status, 0);
851 
852 	status = pt_section_read(sfix->section, buffer, 1, 0x3ull);
853 	ptu_int_eq(status, -pte_nomap);
854 	ptu_uint_eq(buffer[0], 0xcc);
855 
856 	status = pt_section_unmap(sfix->section);
857 	ptu_int_eq(status, 0);
858 
859 	return ptu_passed();
860 }
861 
862 static struct ptunit_result read_overflow(struct section_fixture *sfix)
863 {
864 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
865 	int status;
866 
867 	sfix_write(sfix, bytes);
868 
869 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
870 	ptu_ptr(sfix->section);
871 
872 	status = pt_section_map(sfix->section);
873 	ptu_int_eq(status, 0);
874 
875 	status = pt_section_read(sfix->section, buffer, 1,
876 				 0xffffffffffff0000ull);
877 	ptu_int_eq(status, -pte_nomap);
878 	ptu_uint_eq(buffer[0], 0xcc);
879 
880 	status = pt_section_unmap(sfix->section);
881 	ptu_int_eq(status, 0);
882 
883 	return ptu_passed();
884 }
885 
886 static struct ptunit_result read_overflow_32bit(struct section_fixture *sfix)
887 {
888 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
889 	int status;
890 
891 	sfix_write(sfix, bytes);
892 
893 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
894 	ptu_ptr(sfix->section);
895 
896 	status = pt_section_map(sfix->section);
897 	ptu_int_eq(status, 0);
898 
899 	status = pt_section_read(sfix->section, buffer, 1,
900 				 0xff00000000ull);
901 	ptu_int_eq(status, -pte_nomap);
902 	ptu_uint_eq(buffer[0], 0xcc);
903 
904 	status = pt_section_unmap(sfix->section);
905 	ptu_int_eq(status, 0);
906 
907 	return ptu_passed();
908 }
909 
910 static struct ptunit_result read_nomap(struct section_fixture *sfix)
911 {
912 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
913 	int status;
914 
915 	sfix_write(sfix, bytes);
916 
917 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
918 	ptu_ptr(sfix->section);
919 
920 	status = pt_section_read(sfix->section, buffer, 1, 0x0ull);
921 	ptu_int_eq(status, -pte_nomap);
922 	ptu_uint_eq(buffer[0], 0xcc);
923 
924 	return ptu_passed();
925 }
926 
927 static struct ptunit_result read_unmap_map(struct section_fixture *sfix)
928 {
929 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
930 	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
931 	int status;
932 
933 	sfix_write(sfix, bytes);
934 
935 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
936 	ptu_ptr(sfix->section);
937 
938 	status = pt_section_map(sfix->section);
939 	ptu_int_eq(status, 0);
940 
941 	status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
942 	ptu_int_eq(status, 2);
943 	ptu_uint_eq(buffer[0], bytes[1]);
944 	ptu_uint_eq(buffer[1], bytes[2]);
945 	ptu_uint_eq(buffer[2], 0xcc);
946 
947 	memset(buffer, 0xcc, sizeof(buffer));
948 
949 	status = pt_section_unmap(sfix->section);
950 	ptu_int_eq(status, 0);
951 
952 	status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
953 	ptu_int_eq(status, -pte_nomap);
954 	ptu_uint_eq(buffer[0], 0xcc);
955 	ptu_uint_eq(buffer[1], 0xcc);
956 	ptu_uint_eq(buffer[2], 0xcc);
957 
958 	status = pt_section_map(sfix->section);
959 	ptu_int_eq(status, 0);
960 
961 	status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
962 	ptu_int_eq(status, 2);
963 	ptu_uint_eq(buffer[0], bytes[1]);
964 	ptu_uint_eq(buffer[1], bytes[2]);
965 	ptu_uint_eq(buffer[2], 0xcc);
966 
967 	status = pt_section_unmap(sfix->section);
968 	ptu_int_eq(status, 0);
969 
970 	return ptu_passed();
971 }
972 
973 static int worker_read(void *arg)
974 {
975 	struct section_fixture *sfix;
976 	int it, errcode;
977 
978 	sfix = arg;
979 	if (!sfix)
980 		return -pte_internal;
981 
982 	for (it = 0; it < num_work; ++it) {
983 		uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
984 		int read;
985 
986 		errcode = pt_section_get(sfix->section);
987 		if (errcode < 0)
988 			return errcode;
989 
990 		errcode = pt_section_map(sfix->section);
991 		if (errcode < 0)
992 			goto out_put;
993 
994 		read = pt_section_read(sfix->section, buffer, 2, 0x0ull);
995 		if (read < 0)
996 			goto out_unmap;
997 
998 		errcode = -pte_invalid;
999 		if ((read != 2) || (buffer[0] != 0x2) || (buffer[1] != 0x4))
1000 			goto out_unmap;
1001 
1002 		errcode = pt_section_unmap(sfix->section);
1003 		if (errcode < 0)
1004 			goto out_put;
1005 
1006 		errcode = pt_section_put(sfix->section);
1007 		if (errcode < 0)
1008 			return errcode;
1009 	}
1010 
1011 	return 0;
1012 
1013 out_unmap:
1014 	(void) pt_section_unmap(sfix->section);
1015 
1016 out_put:
1017 	(void) pt_section_put(sfix->section);
1018 	return errcode;
1019 }
1020 
1021 static int worker_bcache(void *arg)
1022 {
1023 	struct section_fixture *sfix;
1024 	int it, errcode;
1025 
1026 	sfix = arg;
1027 	if (!sfix)
1028 		return -pte_internal;
1029 
1030 	errcode = pt_section_get(sfix->section);
1031 	if (errcode < 0)
1032 		return errcode;
1033 
1034 	for (it = 0; it < num_work; ++it) {
1035 		struct pt_block_cache *bcache;
1036 
1037 		errcode = pt_section_map(sfix->section);
1038 		if (errcode < 0)
1039 			goto out_put;
1040 
1041 		errcode = pt_section_request_bcache(sfix->section);
1042 		if (errcode < 0)
1043 			goto out_unmap;
1044 
1045 		bcache = pt_section_bcache(sfix->section);
1046 		if (!bcache) {
1047 			errcode = -pte_nomem;
1048 			goto out_unmap;
1049 		}
1050 
1051 		errcode = pt_section_unmap(sfix->section);
1052 		if (errcode < 0)
1053 			goto out_put;
1054 	}
1055 
1056 	return pt_section_put(sfix->section);
1057 
1058 out_unmap:
1059 	(void) pt_section_unmap(sfix->section);
1060 
1061 out_put:
1062 	(void) pt_section_put(sfix->section);
1063 	return errcode;
1064 }
1065 
1066 static struct ptunit_result stress(struct section_fixture *sfix,
1067 				   int (*worker)(void *))
1068 {
1069 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1070 	int errcode;
1071 
1072 	sfix_write(sfix, bytes);
1073 
1074 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1075 	ptu_ptr(sfix->section);
1076 
1077 #if defined(FEATURE_THREADS)
1078 	{
1079 		int thrd;
1080 
1081 		for (thrd = 0; thrd < num_threads; ++thrd)
1082 			ptu_test(ptunit_thrd_create, &sfix->thrd, worker, sfix);
1083 	}
1084 #endif /* defined(FEATURE_THREADS) */
1085 
1086 	errcode = worker(sfix);
1087 	ptu_int_eq(errcode, 0);
1088 
1089 	return ptu_passed();
1090 }
1091 
1092 static struct ptunit_result init_no_bcache(struct section_fixture *sfix)
1093 {
1094 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1095 	struct pt_block_cache *bcache;
1096 	int errcode;
1097 
1098 	sfix_write(sfix, bytes);
1099 
1100 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1101 	ptu_ptr(sfix->section);
1102 
1103 	errcode = pt_section_map(sfix->section);
1104 	ptu_int_eq(errcode, 0);
1105 
1106 	bcache = pt_section_bcache(sfix->section);
1107 	ptu_null(bcache);
1108 
1109 	errcode = pt_section_unmap(sfix->section);
1110 	ptu_int_eq(errcode, 0);
1111 
1112 	return ptu_passed();
1113 }
1114 
1115 static struct ptunit_result bcache_alloc_free(struct section_fixture *sfix)
1116 {
1117 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1118 	struct pt_block_cache *bcache;
1119 	int errcode;
1120 
1121 	sfix_write(sfix, bytes);
1122 
1123 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1124 	ptu_ptr(sfix->section);
1125 
1126 	errcode = pt_section_map(sfix->section);
1127 	ptu_int_eq(errcode, 0);
1128 
1129 	errcode = pt_section_alloc_bcache(sfix->section);
1130 	ptu_int_eq(errcode, 0);
1131 
1132 	bcache = pt_section_bcache(sfix->section);
1133 	ptu_ptr(bcache);
1134 	ptu_uint_eq(bcache->nentries, sfix->section->size);
1135 
1136 	errcode = pt_section_unmap(sfix->section);
1137 	ptu_int_eq(errcode, 0);
1138 
1139 	bcache = pt_section_bcache(sfix->section);
1140 	ptu_null(bcache);
1141 
1142 	return ptu_passed();
1143 }
1144 
1145 static struct ptunit_result bcache_alloc_twice(struct section_fixture *sfix)
1146 {
1147 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1148 	int errcode;
1149 
1150 	sfix_write(sfix, bytes);
1151 
1152 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1153 	ptu_ptr(sfix->section);
1154 
1155 	errcode = pt_section_map(sfix->section);
1156 	ptu_int_eq(errcode, 0);
1157 
1158 	errcode = pt_section_alloc_bcache(sfix->section);
1159 	ptu_int_eq(errcode, 0);
1160 
1161 	errcode = pt_section_alloc_bcache(sfix->section);
1162 	ptu_int_eq(errcode, 0);
1163 
1164 	errcode = pt_section_unmap(sfix->section);
1165 	ptu_int_eq(errcode, 0);
1166 
1167 	return ptu_passed();
1168 }
1169 
1170 static struct ptunit_result bcache_alloc_nomap(struct section_fixture *sfix)
1171 {
1172 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1173 	int errcode;
1174 
1175 	sfix_write(sfix, bytes);
1176 
1177 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1178 	ptu_ptr(sfix->section);
1179 
1180 	errcode = pt_section_alloc_bcache(sfix->section);
1181 	ptu_int_eq(errcode, -pte_internal);
1182 
1183 	return ptu_passed();
1184 }
1185 
1186 static struct ptunit_result memsize_nomap(struct section_fixture *sfix)
1187 {
1188 	uint64_t memsize;
1189 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1190 	int errcode;
1191 
1192 	sfix_write(sfix, bytes);
1193 
1194 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1195 	ptu_ptr(sfix->section);
1196 
1197 	errcode = pt_section_memsize(sfix->section, &memsize);
1198 	ptu_int_eq(errcode, 0);
1199 	ptu_uint_eq(memsize, 0ull);
1200 
1201 	return ptu_passed();
1202 }
1203 
1204 static struct ptunit_result memsize_unmap(struct section_fixture *sfix)
1205 {
1206 	uint64_t memsize;
1207 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1208 	int errcode;
1209 
1210 	sfix_write(sfix, bytes);
1211 
1212 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1213 	ptu_ptr(sfix->section);
1214 
1215 	errcode = pt_section_map(sfix->section);
1216 	ptu_int_eq(errcode, 0);
1217 
1218 	errcode = pt_section_unmap(sfix->section);
1219 	ptu_int_eq(errcode, 0);
1220 
1221 	errcode = pt_section_memsize(sfix->section, &memsize);
1222 	ptu_int_eq(errcode, 0);
1223 	ptu_uint_eq(memsize, 0ull);
1224 
1225 	return ptu_passed();
1226 }
1227 
1228 static struct ptunit_result memsize_map_nobcache(struct section_fixture *sfix)
1229 {
1230 	uint64_t memsize;
1231 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1232 	int errcode;
1233 
1234 	sfix_write(sfix, bytes);
1235 
1236 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1237 	ptu_ptr(sfix->section);
1238 
1239 	errcode = pt_section_map(sfix->section);
1240 	ptu_int_eq(errcode, 0);
1241 
1242 	memsize = 0xfefefefefefefefeull;
1243 
1244 	errcode = pt_section_memsize(sfix->section, &memsize);
1245 	ptu_int_eq(errcode, 0);
1246 	ptu_uint_ge(memsize, 0ull);
1247 	ptu_uint_le(memsize, 0x2000ull);
1248 
1249 	errcode = pt_section_unmap(sfix->section);
1250 	ptu_int_eq(errcode, 0);
1251 
1252 	return ptu_passed();
1253 }
1254 
1255 static struct ptunit_result memsize_map_bcache(struct section_fixture *sfix)
1256 {
1257 	uint64_t memsize;
1258 	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1259 	int errcode;
1260 
1261 	sfix_write(sfix, bytes);
1262 
1263 	sfix->section = pt_mk_section(sfix->name, 0x1ull, 0x3ull);
1264 	ptu_ptr(sfix->section);
1265 
1266 	errcode = pt_section_map(sfix->section);
1267 	ptu_int_eq(errcode, 0);
1268 
1269 	errcode = pt_section_alloc_bcache(sfix->section);
1270 	ptu_int_eq(errcode, 0);
1271 
1272 	errcode = pt_section_memsize(sfix->section, &memsize);
1273 	ptu_int_eq(errcode, 0);
1274 	ptu_uint_ge(memsize,
1275 		    sfix->section->size * sizeof(struct pt_bcache_entry));
1276 
1277 	errcode = pt_section_unmap(sfix->section);
1278 	ptu_int_eq(errcode, 0);
1279 
1280 	return ptu_passed();
1281 }
1282 
1283 static struct ptunit_result sfix_init(struct section_fixture *sfix)
1284 {
1285 	int errcode;
1286 
1287 	sfix->section = NULL;
1288 	sfix->file = NULL;
1289 	sfix->name = NULL;
1290 
1291 	errcode = ptunit_mkfile(&sfix->file, &sfix->name, "wb");
1292 	ptu_int_eq(errcode, 0);
1293 
1294 	ptu_test(ptunit_thrd_init, &sfix->thrd);
1295 
1296 	return ptu_passed();
1297 }
1298 
1299 static struct ptunit_result sfix_fini(struct section_fixture *sfix)
1300 {
1301 	int thrd;
1302 
1303 	ptu_test(ptunit_thrd_fini, &sfix->thrd);
1304 
1305 	for (thrd = 0; thrd < sfix->thrd.nthreads; ++thrd)
1306 		ptu_int_eq(sfix->thrd.result[thrd], 0);
1307 
1308 	if (sfix->section) {
1309 		pt_section_put(sfix->section);
1310 		sfix->section = NULL;
1311 	}
1312 
1313 	if (sfix->file) {
1314 		fclose(sfix->file);
1315 		sfix->file = NULL;
1316 
1317 		if (sfix->name)
1318 			remove(sfix->name);
1319 	}
1320 
1321 	if (sfix->name) {
1322 		free(sfix->name);
1323 		sfix->name = NULL;
1324 	}
1325 
1326 	return ptu_passed();
1327 }
1328 
1329 int main(int argc, char **argv)
1330 {
1331 	struct section_fixture sfix;
1332 	struct ptunit_suite suite;
1333 
1334 	sfix.init = sfix_init;
1335 	sfix.fini = sfix_fini;
1336 
1337 	suite = ptunit_mk_suite(argc, argv);
1338 
1339 	ptu_run_f(suite, create, sfix);
1340 	ptu_run_f(suite, create_bad_offset, sfix);
1341 	ptu_run_f(suite, create_truncated, sfix);
1342 	ptu_run_f(suite, create_empty, sfix);
1343 
1344 	ptu_run(suite, filename_null);
1345 	ptu_run(suite, offset_null);
1346 	ptu_run(suite, size_null);
1347 	ptu_run(suite, get_null);
1348 	ptu_run(suite, put_null);
1349 	ptu_run(suite, attach_null);
1350 	ptu_run(suite, detach_null);
1351 	ptu_run(suite, map_null);
1352 	ptu_run(suite, unmap_null);
1353 	ptu_run(suite, cache_null);
1354 
1355 	ptu_run_f(suite, get_overflow, sfix);
1356 	ptu_run_f(suite, attach_overflow, sfix);
1357 	ptu_run_f(suite, attach_bad_ucount, sfix);
1358 	ptu_run_f(suite, map_change, sfix);
1359 	ptu_run_f(suite, map_put, sfix);
1360 	ptu_run_f(suite, unmap_nomap, sfix);
1361 	ptu_run_f(suite, map_overflow, sfix);
1362 	ptu_run_f(suite, get_put, sfix);
1363 	ptu_run_f(suite, attach_detach, sfix);
1364 	ptu_run_f(suite, attach_bad_iscache, sfix);
1365 	ptu_run_f(suite, detach_bad_iscache, sfix);
1366 	ptu_run_f(suite, map_unmap, sfix);
1367 	ptu_run_f(suite, attach_map, sfix);
1368 	ptu_run_f(suite, attach_bad_map, sfix);
1369 	ptu_run_f(suite, attach_map_overflow, sfix);
1370 	ptu_run_f(suite, read, sfix);
1371 	ptu_run_f(suite, read_null, sfix);
1372 	ptu_run_f(suite, read_offset, sfix);
1373 	ptu_run_f(suite, read_truncated, sfix);
1374 	ptu_run_f(suite, read_from_truncated, sfix);
1375 	ptu_run_f(suite, read_nomem, sfix);
1376 	ptu_run_f(suite, read_overflow, sfix);
1377 	ptu_run_f(suite, read_overflow_32bit, sfix);
1378 	ptu_run_f(suite, read_nomap, sfix);
1379 	ptu_run_f(suite, read_unmap_map, sfix);
1380 
1381 	ptu_run_f(suite, init_no_bcache, sfix);
1382 	ptu_run_f(suite, bcache_alloc_free, sfix);
1383 	ptu_run_f(suite, bcache_alloc_twice, sfix);
1384 	ptu_run_f(suite, bcache_alloc_nomap, sfix);
1385 
1386 	ptu_run_f(suite, memsize_null, sfix);
1387 	ptu_run_f(suite, memsize_nomap, sfix);
1388 	ptu_run_f(suite, memsize_unmap, sfix);
1389 	ptu_run_f(suite, memsize_map_nobcache, sfix);
1390 	ptu_run_f(suite, memsize_map_bcache, sfix);
1391 
1392 	ptu_run_fp(suite, stress, sfix, worker_bcache);
1393 	ptu_run_fp(suite, stress, sfix, worker_read);
1394 
1395 	return ptunit_report(&suite);
1396 }
1397