1/*
2 * Copyright (c) 2013-2019, 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
42struct pt_image_section_cache {
43	int map;
44};
45
46extern int pt_iscache_notify_map(struct pt_image_section_cache *iscache,
47				 struct pt_section *section);
48extern int pt_iscache_notify_resize(struct pt_image_section_cache *iscache,
49				    struct pt_section *section, uint64_t size);
50
51int 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
66int 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
91struct 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
110void 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. */
116struct 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
134enum {
135#if defined(FEATURE_THREADS)
136
137	num_threads	= 4,
138
139#endif /* defined(FEATURE_THREADS) */
140
141	num_work	= 0x4000
142};
143
144static 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
160static 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	int errcode;
166
167	sfix_write(sfix, bytes);
168
169	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
170	ptu_int_eq(errcode, 0);
171	ptu_ptr(sfix->section);
172
173	name = pt_section_filename(sfix->section);
174	ptu_str_eq(name, sfix->name);
175
176	offset = pt_section_offset(sfix->section);
177	ptu_uint_eq(offset, 0x1ull);
178
179	size = pt_section_size(sfix->section);
180	ptu_uint_eq(size, 0x3ull);
181
182	return ptu_passed();
183}
184
185static struct ptunit_result create_bad_offset(struct section_fixture *sfix)
186{
187	int errcode;
188
189	errcode = pt_mk_section(&sfix->section, sfix->name, 0x10ull, 0x0ull);
190	ptu_int_eq(errcode, -pte_invalid);
191
192	return ptu_passed();
193}
194
195static struct ptunit_result create_truncated(struct section_fixture *sfix)
196{
197	const char *name;
198	uint8_t bytes[] = { 0xcc, 0xcc, 0xcc, 0xcc, 0xcc };
199	uint64_t offset, size;
200	int errcode;
201
202	sfix_write(sfix, bytes);
203
204	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, UINT64_MAX);
205	ptu_int_eq(errcode, 0);
206	ptu_ptr(sfix->section);
207
208	name = pt_section_filename(sfix->section);
209	ptu_str_eq(name, sfix->name);
210
211	offset = pt_section_offset(sfix->section);
212	ptu_uint_eq(offset, 0x1ull);
213
214	size = pt_section_size(sfix->section);
215	ptu_uint_eq(size, sizeof(bytes) - 1);
216
217	return ptu_passed();
218}
219
220static struct ptunit_result create_empty(struct section_fixture *sfix)
221{
222	int errcode;
223
224	errcode = pt_mk_section(&sfix->section, sfix->name, 0x0ull, 0x10ull);
225	ptu_int_eq(errcode, -pte_invalid);
226	ptu_null(sfix->section);
227
228	return ptu_passed();
229}
230
231static struct ptunit_result filename_null(void)
232{
233	const char *name;
234
235	name = pt_section_filename(NULL);
236	ptu_null(name);
237
238	return ptu_passed();
239}
240
241static struct ptunit_result size_null(void)
242{
243	uint64_t size;
244
245	size = pt_section_size(NULL);
246	ptu_uint_eq(size, 0ull);
247
248	return ptu_passed();
249}
250
251static struct ptunit_result memsize_null(struct section_fixture *sfix)
252{
253	uint64_t size;
254	int errcode;
255
256	errcode = pt_section_memsize(NULL, &size);
257	ptu_int_eq(errcode, -pte_internal);
258
259	errcode = pt_section_memsize(sfix->section, NULL);
260	ptu_int_eq(errcode, -pte_internal);
261
262	errcode = pt_section_memsize(NULL, NULL);
263	ptu_int_eq(errcode, -pte_internal);
264
265	return ptu_passed();
266}
267
268static struct ptunit_result offset_null(void)
269{
270	uint64_t offset;
271
272	offset = pt_section_offset(NULL);
273	ptu_uint_eq(offset, 0ull);
274
275	return ptu_passed();
276}
277
278static struct ptunit_result get_null(void)
279{
280	int errcode;
281
282	errcode = pt_section_get(NULL);
283	ptu_int_eq(errcode, -pte_internal);
284
285	return ptu_passed();
286}
287
288static struct ptunit_result put_null(void)
289{
290	int errcode;
291
292	errcode = pt_section_put(NULL);
293	ptu_int_eq(errcode, -pte_internal);
294
295	return ptu_passed();
296}
297
298static struct ptunit_result attach_null(void)
299{
300	struct pt_image_section_cache iscache;
301	struct pt_section section;
302	int errcode;
303
304	errcode = pt_section_attach(NULL, &iscache);
305	ptu_int_eq(errcode, -pte_internal);
306
307	errcode = pt_section_attach(&section, NULL);
308	ptu_int_eq(errcode, -pte_internal);
309
310	errcode = pt_section_attach(NULL, NULL);
311	ptu_int_eq(errcode, -pte_internal);
312
313	return ptu_passed();
314}
315
316static struct ptunit_result detach_null(void)
317{
318	struct pt_image_section_cache iscache;
319	struct pt_section section;
320	int errcode;
321
322	errcode = pt_section_detach(NULL, &iscache);
323	ptu_int_eq(errcode, -pte_internal);
324
325	errcode = pt_section_detach(&section, NULL);
326	ptu_int_eq(errcode, -pte_internal);
327
328	errcode = pt_section_detach(NULL, NULL);
329	ptu_int_eq(errcode, -pte_internal);
330
331	return ptu_passed();
332}
333
334static struct ptunit_result map_null(void)
335{
336	int errcode;
337
338	errcode = pt_section_map(NULL);
339	ptu_int_eq(errcode, -pte_internal);
340
341	return ptu_passed();
342}
343
344static struct ptunit_result unmap_null(void)
345{
346	int errcode;
347
348	errcode = pt_section_unmap(NULL);
349	ptu_int_eq(errcode, -pte_internal);
350
351	return ptu_passed();
352}
353
354static struct ptunit_result cache_null(void)
355{
356	struct pt_block_cache *bcache;
357
358	bcache = pt_section_bcache(NULL);
359	ptu_null(bcache);
360
361	return ptu_passed();
362}
363
364static struct ptunit_result get_overflow(struct section_fixture *sfix)
365{
366	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
367	int errcode;
368
369	sfix_write(sfix, bytes);
370
371	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
372	ptu_int_eq(errcode, 0);
373	ptu_ptr(sfix->section);
374
375	sfix->section->ucount = UINT16_MAX;
376
377	errcode = pt_section_get(sfix->section);
378	ptu_int_eq(errcode, -pte_overflow);
379
380	sfix->section->ucount = 1;
381
382	return ptu_passed();
383}
384
385static struct ptunit_result attach_overflow(struct section_fixture *sfix)
386{
387	struct pt_image_section_cache iscache;
388	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
389	int errcode;
390
391	sfix_write(sfix, bytes);
392
393	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
394	ptu_int_eq(errcode, 0);
395	ptu_ptr(sfix->section);
396
397	sfix->section->acount = UINT16_MAX;
398
399	errcode = pt_section_attach(sfix->section, &iscache);
400	ptu_int_eq(errcode, -pte_overflow);
401
402	sfix->section->acount = 0;
403
404	return ptu_passed();
405}
406
407static struct ptunit_result attach_bad_ucount(struct section_fixture *sfix)
408{
409	struct pt_image_section_cache iscache;
410	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
411	int errcode;
412
413	sfix_write(sfix, bytes);
414
415	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
416	ptu_int_eq(errcode, 0);
417	ptu_ptr(sfix->section);
418
419	sfix->section->acount = 2;
420
421	errcode = pt_section_attach(sfix->section, &iscache);
422	ptu_int_eq(errcode, -pte_internal);
423
424	sfix->section->acount = 0;
425
426	return ptu_passed();
427}
428
429static struct ptunit_result map_change(struct section_fixture *sfix)
430{
431	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
432	int errcode;
433
434	sfix_write(sfix, bytes);
435
436	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
437	ptu_int_eq(errcode, 0);
438	ptu_ptr(sfix->section);
439
440	sfix_write(sfix, bytes);
441
442	errcode = pt_section_map(sfix->section);
443	ptu_int_eq(errcode, -pte_bad_image);
444
445	return ptu_passed();
446}
447
448static struct ptunit_result map_put(struct section_fixture *sfix)
449{
450	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
451	int errcode;
452
453	sfix_write(sfix, bytes);
454
455	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
456	ptu_int_eq(errcode, 0);
457	ptu_ptr(sfix->section);
458
459	errcode = pt_section_map(sfix->section);
460	ptu_int_eq(errcode, 0);
461
462	errcode = pt_section_put(sfix->section);
463	ptu_int_eq(errcode, -pte_internal);
464
465	errcode = pt_section_unmap(sfix->section);
466	ptu_int_eq(errcode, 0);
467
468	return ptu_passed();
469}
470
471static struct ptunit_result unmap_nomap(struct section_fixture *sfix)
472{
473	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
474	int errcode;
475
476	sfix_write(sfix, bytes);
477
478	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
479	ptu_int_eq(errcode, 0);
480	ptu_ptr(sfix->section);
481
482	errcode = pt_section_unmap(sfix->section);
483	ptu_int_eq(errcode, -pte_nomap);
484
485	return ptu_passed();
486}
487
488static struct ptunit_result map_overflow(struct section_fixture *sfix)
489{
490	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
491	int errcode;
492
493	sfix_write(sfix, bytes);
494
495	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
496	ptu_int_eq(errcode, 0);
497	ptu_ptr(sfix->section);
498
499	sfix->section->mcount = UINT16_MAX;
500
501	errcode = pt_section_map(sfix->section);
502	ptu_int_eq(errcode, -pte_overflow);
503
504	sfix->section->mcount = 0;
505
506	return ptu_passed();
507}
508
509static struct ptunit_result get_put(struct section_fixture *sfix)
510{
511	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
512	int errcode;
513
514	sfix_write(sfix, bytes);
515
516	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
517	ptu_int_eq(errcode, 0);
518	ptu_ptr(sfix->section);
519
520	errcode = pt_section_get(sfix->section);
521	ptu_int_eq(errcode, 0);
522
523	errcode = pt_section_get(sfix->section);
524	ptu_int_eq(errcode, 0);
525
526	errcode = pt_section_put(sfix->section);
527	ptu_int_eq(errcode, 0);
528
529	errcode = pt_section_put(sfix->section);
530	ptu_int_eq(errcode, 0);
531
532	return ptu_passed();
533}
534
535static struct ptunit_result attach_detach(struct section_fixture *sfix)
536{
537	struct pt_image_section_cache iscache;
538	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
539	int errcode;
540
541	sfix_write(sfix, bytes);
542
543	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
544	ptu_int_eq(errcode, 0);
545	ptu_ptr(sfix->section);
546
547	sfix->section->ucount += 2;
548
549	errcode = pt_section_attach(sfix->section, &iscache);
550	ptu_int_eq(errcode, 0);
551
552	errcode = pt_section_attach(sfix->section, &iscache);
553	ptu_int_eq(errcode, 0);
554
555	errcode = pt_section_detach(sfix->section, &iscache);
556	ptu_int_eq(errcode, 0);
557
558	errcode = pt_section_detach(sfix->section, &iscache);
559	ptu_int_eq(errcode, 0);
560
561	sfix->section->ucount -= 2;
562
563	return ptu_passed();
564}
565
566static struct ptunit_result attach_bad_iscache(struct section_fixture *sfix)
567{
568	struct pt_image_section_cache iscache, bad;
569	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
570	int errcode;
571
572	sfix_write(sfix, bytes);
573
574	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
575	ptu_int_eq(errcode, 0);
576	ptu_ptr(sfix->section);
577
578	sfix->section->ucount += 2;
579
580	errcode = pt_section_attach(sfix->section, &iscache);
581	ptu_int_eq(errcode, 0);
582
583	errcode = pt_section_attach(sfix->section, &bad);
584	ptu_int_eq(errcode, -pte_internal);
585
586	errcode = pt_section_detach(sfix->section, &iscache);
587	ptu_int_eq(errcode, 0);
588
589	sfix->section->ucount -= 2;
590
591	return ptu_passed();
592}
593
594static struct ptunit_result detach_bad_iscache(struct section_fixture *sfix)
595{
596	struct pt_image_section_cache iscache, bad;
597	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
598	int errcode;
599
600	sfix_write(sfix, bytes);
601
602	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
603	ptu_int_eq(errcode, 0);
604	ptu_ptr(sfix->section);
605
606	errcode = pt_section_attach(sfix->section, &iscache);
607	ptu_int_eq(errcode, 0);
608
609	errcode = pt_section_detach(sfix->section, &bad);
610	ptu_int_eq(errcode, -pte_internal);
611
612	errcode = pt_section_detach(sfix->section, &iscache);
613	ptu_int_eq(errcode, 0);
614
615	return ptu_passed();
616}
617
618static struct ptunit_result map_unmap(struct section_fixture *sfix)
619{
620	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
621	int errcode;
622
623	sfix_write(sfix, bytes);
624
625	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
626	ptu_int_eq(errcode, 0);
627	ptu_ptr(sfix->section);
628
629	errcode = pt_section_map(sfix->section);
630	ptu_int_eq(errcode, 0);
631
632	errcode = pt_section_map(sfix->section);
633	ptu_int_eq(errcode, 0);
634
635	errcode = pt_section_unmap(sfix->section);
636	ptu_int_eq(errcode, 0);
637
638	errcode = pt_section_unmap(sfix->section);
639	ptu_int_eq(errcode, 0);
640
641	return ptu_passed();
642}
643
644static struct ptunit_result attach_map(struct section_fixture *sfix)
645{
646	struct pt_image_section_cache iscache;
647	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
648	int errcode;
649
650	iscache.map = 0;
651
652	sfix_write(sfix, bytes);
653
654	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
655	ptu_int_eq(errcode, 0);
656	ptu_ptr(sfix->section);
657
658	errcode = pt_section_attach(sfix->section, &iscache);
659	ptu_int_eq(errcode, 0);
660
661	errcode = pt_section_map(sfix->section);
662	ptu_int_eq(errcode, 0);
663
664	errcode = pt_section_map(sfix->section);
665	ptu_int_eq(errcode, 0);
666
667	ptu_uint_eq(sfix->section->mcount, 2);
668
669	errcode = pt_section_unmap(sfix->section);
670	ptu_int_eq(errcode, 0);
671
672	errcode = pt_section_unmap(sfix->section);
673	ptu_int_eq(errcode, 0);
674
675	errcode = pt_section_detach(sfix->section, &iscache);
676	ptu_int_eq(errcode, 0);
677
678	return ptu_passed();
679}
680
681static struct ptunit_result attach_bad_map(struct section_fixture *sfix)
682{
683	struct pt_image_section_cache iscache;
684	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
685	int errcode;
686
687	iscache.map = -pte_eos;
688
689	sfix_write(sfix, bytes);
690
691	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
692	ptu_int_eq(errcode, 0);
693	ptu_ptr(sfix->section);
694
695	errcode = pt_section_attach(sfix->section, &iscache);
696	ptu_int_eq(errcode, 0);
697
698	errcode = pt_section_map(sfix->section);
699	ptu_int_eq(errcode, -pte_eos);
700
701	errcode = pt_section_detach(sfix->section, &iscache);
702	ptu_int_eq(errcode, 0);
703
704	return ptu_passed();
705}
706
707static struct ptunit_result attach_map_overflow(struct section_fixture *sfix)
708{
709	struct pt_image_section_cache iscache;
710	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
711	int errcode;
712
713	iscache.map = 1;
714
715	sfix_write(sfix, bytes);
716
717	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
718	ptu_int_eq(errcode, 0);
719	ptu_ptr(sfix->section);
720
721	errcode = pt_section_attach(sfix->section, &iscache);
722	ptu_int_eq(errcode, 0);
723
724	sfix->section->mcount = UINT16_MAX - 1;
725
726	errcode = pt_section_map(sfix->section);
727	ptu_int_eq(errcode, -pte_overflow);
728
729	errcode = pt_section_detach(sfix->section, &iscache);
730	ptu_int_eq(errcode, 0);
731
732	return ptu_passed();
733}
734
735static struct ptunit_result read(struct section_fixture *sfix)
736{
737	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
738	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
739	int status;
740
741	sfix_write(sfix, bytes);
742
743	status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
744	ptu_int_eq(status, 0);
745	ptu_ptr(sfix->section);
746
747	status = pt_section_map(sfix->section);
748	ptu_int_eq(status, 0);
749
750	status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
751	ptu_int_eq(status, 2);
752	ptu_uint_eq(buffer[0], bytes[1]);
753	ptu_uint_eq(buffer[1], bytes[2]);
754	ptu_uint_eq(buffer[2], 0xcc);
755
756	status = pt_section_unmap(sfix->section);
757	ptu_int_eq(status, 0);
758
759	return ptu_passed();
760}
761
762static struct ptunit_result read_null(struct section_fixture *sfix)
763{
764	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
765	uint8_t buffer[] = { 0xcc };
766	int status;
767
768	sfix_write(sfix, bytes);
769
770	status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
771	ptu_int_eq(status, 0);
772	ptu_ptr(sfix->section);
773
774	status = pt_section_map(sfix->section);
775	ptu_int_eq(status, 0);
776
777	status = pt_section_read(sfix->section, NULL, 1, 0x0ull);
778	ptu_int_eq(status, -pte_internal);
779	ptu_uint_eq(buffer[0], 0xcc);
780
781	status = pt_section_read(NULL, buffer, 1, 0x0ull);
782	ptu_int_eq(status, -pte_internal);
783	ptu_uint_eq(buffer[0], 0xcc);
784
785	status = pt_section_unmap(sfix->section);
786	ptu_int_eq(status, 0);
787
788	return ptu_passed();
789}
790
791static struct ptunit_result read_offset(struct section_fixture *sfix)
792{
793	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
794	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
795	int status;
796
797	sfix_write(sfix, bytes);
798
799	status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
800	ptu_int_eq(status, 0);
801	ptu_ptr(sfix->section);
802
803	status = pt_section_map(sfix->section);
804	ptu_int_eq(status, 0);
805
806	status = pt_section_read(sfix->section, buffer, 2, 0x1ull);
807	ptu_int_eq(status, 2);
808	ptu_uint_eq(buffer[0], bytes[2]);
809	ptu_uint_eq(buffer[1], bytes[3]);
810	ptu_uint_eq(buffer[2], 0xcc);
811
812	status = pt_section_unmap(sfix->section);
813	ptu_int_eq(status, 0);
814
815	return ptu_passed();
816}
817
818static struct ptunit_result read_truncated(struct section_fixture *sfix)
819{
820	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc, 0xcc };
821	int status;
822
823	sfix_write(sfix, bytes);
824
825	status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
826	ptu_int_eq(status, 0);
827	ptu_ptr(sfix->section);
828
829	status = pt_section_map(sfix->section);
830	ptu_int_eq(status, 0);
831
832	status = pt_section_read(sfix->section, buffer, 2, 0x2ull);
833	ptu_int_eq(status, 1);
834	ptu_uint_eq(buffer[0], bytes[3]);
835	ptu_uint_eq(buffer[1], 0xcc);
836
837	status = pt_section_unmap(sfix->section);
838	ptu_int_eq(status, 0);
839
840	return ptu_passed();
841}
842
843static struct ptunit_result read_from_truncated(struct section_fixture *sfix)
844{
845	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc, 0xcc };
846	int status;
847
848	sfix_write(sfix, bytes);
849
850	status = pt_mk_section(&sfix->section, sfix->name, 0x2ull, 0x10ull);
851	ptu_int_eq(status, 0);
852	ptu_ptr(sfix->section);
853
854	status = pt_section_map(sfix->section);
855	ptu_int_eq(status, 0);
856
857	status = pt_section_read(sfix->section, buffer, 2, 0x1ull);
858	ptu_int_eq(status, 1);
859	ptu_uint_eq(buffer[0], bytes[3]);
860	ptu_uint_eq(buffer[1], 0xcc);
861
862	status = pt_section_unmap(sfix->section);
863	ptu_int_eq(status, 0);
864
865	return ptu_passed();
866}
867
868static struct ptunit_result read_nomem(struct section_fixture *sfix)
869{
870	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
871	int status;
872
873	sfix_write(sfix, bytes);
874
875	status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
876	ptu_int_eq(status, 0);
877	ptu_ptr(sfix->section);
878
879	status = pt_section_map(sfix->section);
880	ptu_int_eq(status, 0);
881
882	status = pt_section_read(sfix->section, buffer, 1, 0x3ull);
883	ptu_int_eq(status, -pte_nomap);
884	ptu_uint_eq(buffer[0], 0xcc);
885
886	status = pt_section_unmap(sfix->section);
887	ptu_int_eq(status, 0);
888
889	return ptu_passed();
890}
891
892static struct ptunit_result read_overflow(struct section_fixture *sfix)
893{
894	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
895	int status;
896
897	sfix_write(sfix, bytes);
898
899	status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
900	ptu_int_eq(status, 0);
901	ptu_ptr(sfix->section);
902
903	status = pt_section_map(sfix->section);
904	ptu_int_eq(status, 0);
905
906	status = pt_section_read(sfix->section, buffer, 1,
907				 0xffffffffffff0000ull);
908	ptu_int_eq(status, -pte_nomap);
909	ptu_uint_eq(buffer[0], 0xcc);
910
911	status = pt_section_unmap(sfix->section);
912	ptu_int_eq(status, 0);
913
914	return ptu_passed();
915}
916
917static struct ptunit_result read_overflow_32bit(struct section_fixture *sfix)
918{
919	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
920	int status;
921
922	sfix_write(sfix, bytes);
923
924	status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
925	ptu_int_eq(status, 0);
926	ptu_ptr(sfix->section);
927
928	status = pt_section_map(sfix->section);
929	ptu_int_eq(status, 0);
930
931	status = pt_section_read(sfix->section, buffer, 1,
932				 0xff00000000ull);
933	ptu_int_eq(status, -pte_nomap);
934	ptu_uint_eq(buffer[0], 0xcc);
935
936	status = pt_section_unmap(sfix->section);
937	ptu_int_eq(status, 0);
938
939	return ptu_passed();
940}
941
942static struct ptunit_result read_nomap(struct section_fixture *sfix)
943{
944	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 }, buffer[] = { 0xcc };
945	int status;
946
947	sfix_write(sfix, bytes);
948
949	status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
950	ptu_int_eq(status, 0);
951	ptu_ptr(sfix->section);
952
953	status = pt_section_read(sfix->section, buffer, 1, 0x0ull);
954	ptu_int_eq(status, -pte_nomap);
955	ptu_uint_eq(buffer[0], 0xcc);
956
957	return ptu_passed();
958}
959
960static struct ptunit_result read_unmap_map(struct section_fixture *sfix)
961{
962	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
963	uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
964	int status;
965
966	sfix_write(sfix, bytes);
967
968	status = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
969	ptu_int_eq(status, 0);
970	ptu_ptr(sfix->section);
971
972	status = pt_section_map(sfix->section);
973	ptu_int_eq(status, 0);
974
975	status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
976	ptu_int_eq(status, 2);
977	ptu_uint_eq(buffer[0], bytes[1]);
978	ptu_uint_eq(buffer[1], bytes[2]);
979	ptu_uint_eq(buffer[2], 0xcc);
980
981	memset(buffer, 0xcc, sizeof(buffer));
982
983	status = pt_section_unmap(sfix->section);
984	ptu_int_eq(status, 0);
985
986	status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
987	ptu_int_eq(status, -pte_nomap);
988	ptu_uint_eq(buffer[0], 0xcc);
989	ptu_uint_eq(buffer[1], 0xcc);
990	ptu_uint_eq(buffer[2], 0xcc);
991
992	status = pt_section_map(sfix->section);
993	ptu_int_eq(status, 0);
994
995	status = pt_section_read(sfix->section, buffer, 2, 0x0ull);
996	ptu_int_eq(status, 2);
997	ptu_uint_eq(buffer[0], bytes[1]);
998	ptu_uint_eq(buffer[1], bytes[2]);
999	ptu_uint_eq(buffer[2], 0xcc);
1000
1001	status = pt_section_unmap(sfix->section);
1002	ptu_int_eq(status, 0);
1003
1004	return ptu_passed();
1005}
1006
1007static int worker_read(void *arg)
1008{
1009	struct section_fixture *sfix;
1010	int it, errcode;
1011
1012	sfix = arg;
1013	if (!sfix)
1014		return -pte_internal;
1015
1016	for (it = 0; it < num_work; ++it) {
1017		uint8_t buffer[] = { 0xcc, 0xcc, 0xcc };
1018		int read;
1019
1020		errcode = pt_section_get(sfix->section);
1021		if (errcode < 0)
1022			return errcode;
1023
1024		errcode = pt_section_map(sfix->section);
1025		if (errcode < 0)
1026			goto out_put;
1027
1028		read = pt_section_read(sfix->section, buffer, 2, 0x0ull);
1029		if (read < 0)
1030			goto out_unmap;
1031
1032		errcode = -pte_invalid;
1033		if ((read != 2) || (buffer[0] != 0x2) || (buffer[1] != 0x4))
1034			goto out_unmap;
1035
1036		errcode = pt_section_unmap(sfix->section);
1037		if (errcode < 0)
1038			goto out_put;
1039
1040		errcode = pt_section_put(sfix->section);
1041		if (errcode < 0)
1042			return errcode;
1043	}
1044
1045	return 0;
1046
1047out_unmap:
1048	(void) pt_section_unmap(sfix->section);
1049
1050out_put:
1051	(void) pt_section_put(sfix->section);
1052	return errcode;
1053}
1054
1055static int worker_bcache(void *arg)
1056{
1057	struct section_fixture *sfix;
1058	int it, errcode;
1059
1060	sfix = arg;
1061	if (!sfix)
1062		return -pte_internal;
1063
1064	errcode = pt_section_get(sfix->section);
1065	if (errcode < 0)
1066		return errcode;
1067
1068	for (it = 0; it < num_work; ++it) {
1069		struct pt_block_cache *bcache;
1070
1071		errcode = pt_section_map(sfix->section);
1072		if (errcode < 0)
1073			goto out_put;
1074
1075		errcode = pt_section_request_bcache(sfix->section);
1076		if (errcode < 0)
1077			goto out_unmap;
1078
1079		bcache = pt_section_bcache(sfix->section);
1080		if (!bcache) {
1081			errcode = -pte_nomem;
1082			goto out_unmap;
1083		}
1084
1085		errcode = pt_section_unmap(sfix->section);
1086		if (errcode < 0)
1087			goto out_put;
1088	}
1089
1090	return pt_section_put(sfix->section);
1091
1092out_unmap:
1093	(void) pt_section_unmap(sfix->section);
1094
1095out_put:
1096	(void) pt_section_put(sfix->section);
1097	return errcode;
1098}
1099
1100static struct ptunit_result stress(struct section_fixture *sfix,
1101				   int (*worker)(void *))
1102{
1103	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1104	int errcode;
1105
1106	sfix_write(sfix, bytes);
1107
1108	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1109	ptu_int_eq(errcode, 0);
1110	ptu_ptr(sfix->section);
1111
1112#if defined(FEATURE_THREADS)
1113	{
1114		int thrd;
1115
1116		for (thrd = 0; thrd < num_threads; ++thrd)
1117			ptu_test(ptunit_thrd_create, &sfix->thrd, worker, sfix);
1118	}
1119#endif /* defined(FEATURE_THREADS) */
1120
1121	errcode = worker(sfix);
1122	ptu_int_eq(errcode, 0);
1123
1124	return ptu_passed();
1125}
1126
1127static struct ptunit_result init_no_bcache(struct section_fixture *sfix)
1128{
1129	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1130	struct pt_block_cache *bcache;
1131	int errcode;
1132
1133	sfix_write(sfix, bytes);
1134
1135	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1136	ptu_int_eq(errcode, 0);
1137	ptu_ptr(sfix->section);
1138
1139	errcode = pt_section_map(sfix->section);
1140	ptu_int_eq(errcode, 0);
1141
1142	bcache = pt_section_bcache(sfix->section);
1143	ptu_null(bcache);
1144
1145	errcode = pt_section_unmap(sfix->section);
1146	ptu_int_eq(errcode, 0);
1147
1148	return ptu_passed();
1149}
1150
1151static struct ptunit_result bcache_alloc_free(struct section_fixture *sfix)
1152{
1153	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1154	struct pt_block_cache *bcache;
1155	int errcode;
1156
1157	sfix_write(sfix, bytes);
1158
1159	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1160	ptu_int_eq(errcode, 0);
1161	ptu_ptr(sfix->section);
1162
1163	errcode = pt_section_map(sfix->section);
1164	ptu_int_eq(errcode, 0);
1165
1166	errcode = pt_section_alloc_bcache(sfix->section);
1167	ptu_int_eq(errcode, 0);
1168
1169	bcache = pt_section_bcache(sfix->section);
1170	ptu_ptr(bcache);
1171	ptu_uint_eq(bcache->nentries, sfix->section->size);
1172
1173	errcode = pt_section_unmap(sfix->section);
1174	ptu_int_eq(errcode, 0);
1175
1176	bcache = pt_section_bcache(sfix->section);
1177	ptu_null(bcache);
1178
1179	return ptu_passed();
1180}
1181
1182static struct ptunit_result bcache_alloc_twice(struct section_fixture *sfix)
1183{
1184	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1185	int errcode;
1186
1187	sfix_write(sfix, bytes);
1188
1189	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1190	ptu_int_eq(errcode, 0);
1191	ptu_ptr(sfix->section);
1192
1193	errcode = pt_section_map(sfix->section);
1194	ptu_int_eq(errcode, 0);
1195
1196	errcode = pt_section_alloc_bcache(sfix->section);
1197	ptu_int_eq(errcode, 0);
1198
1199	errcode = pt_section_alloc_bcache(sfix->section);
1200	ptu_int_eq(errcode, 0);
1201
1202	errcode = pt_section_unmap(sfix->section);
1203	ptu_int_eq(errcode, 0);
1204
1205	return ptu_passed();
1206}
1207
1208static struct ptunit_result bcache_alloc_nomap(struct section_fixture *sfix)
1209{
1210	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1211	int errcode;
1212
1213	sfix_write(sfix, bytes);
1214
1215	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1216	ptu_int_eq(errcode, 0);
1217	ptu_ptr(sfix->section);
1218
1219	errcode = pt_section_alloc_bcache(sfix->section);
1220	ptu_int_eq(errcode, -pte_internal);
1221
1222	return ptu_passed();
1223}
1224
1225static struct ptunit_result memsize_nomap(struct section_fixture *sfix)
1226{
1227	uint64_t memsize;
1228	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1229	int errcode;
1230
1231	sfix_write(sfix, bytes);
1232
1233	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1234	ptu_int_eq(errcode, 0);
1235	ptu_ptr(sfix->section);
1236
1237	errcode = pt_section_memsize(sfix->section, &memsize);
1238	ptu_int_eq(errcode, 0);
1239	ptu_uint_eq(memsize, 0ull);
1240
1241	return ptu_passed();
1242}
1243
1244static struct ptunit_result memsize_unmap(struct section_fixture *sfix)
1245{
1246	uint64_t memsize;
1247	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1248	int errcode;
1249
1250	sfix_write(sfix, bytes);
1251
1252	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1253	ptu_int_eq(errcode, 0);
1254	ptu_ptr(sfix->section);
1255
1256	errcode = pt_section_map(sfix->section);
1257	ptu_int_eq(errcode, 0);
1258
1259	errcode = pt_section_unmap(sfix->section);
1260	ptu_int_eq(errcode, 0);
1261
1262	errcode = pt_section_memsize(sfix->section, &memsize);
1263	ptu_int_eq(errcode, 0);
1264	ptu_uint_eq(memsize, 0ull);
1265
1266	return ptu_passed();
1267}
1268
1269static struct ptunit_result memsize_map_nobcache(struct section_fixture *sfix)
1270{
1271	uint64_t memsize;
1272	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1273	int errcode;
1274
1275	sfix_write(sfix, bytes);
1276
1277	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1278	ptu_int_eq(errcode, 0);
1279	ptu_ptr(sfix->section);
1280
1281	errcode = pt_section_map(sfix->section);
1282	ptu_int_eq(errcode, 0);
1283
1284	memsize = 0xfefefefefefefefeull;
1285
1286	errcode = pt_section_memsize(sfix->section, &memsize);
1287	ptu_int_eq(errcode, 0);
1288	ptu_uint_ge(memsize, 0ull);
1289	ptu_uint_le(memsize, 0x2000ull);
1290
1291	errcode = pt_section_unmap(sfix->section);
1292	ptu_int_eq(errcode, 0);
1293
1294	return ptu_passed();
1295}
1296
1297static struct ptunit_result memsize_map_bcache(struct section_fixture *sfix)
1298{
1299	uint64_t memsize;
1300	uint8_t bytes[] = { 0xcc, 0x2, 0x4, 0x6 };
1301	int errcode;
1302
1303	sfix_write(sfix, bytes);
1304
1305	errcode = pt_mk_section(&sfix->section, sfix->name, 0x1ull, 0x3ull);
1306	ptu_int_eq(errcode, 0);
1307	ptu_ptr(sfix->section);
1308
1309	errcode = pt_section_map(sfix->section);
1310	ptu_int_eq(errcode, 0);
1311
1312	errcode = pt_section_alloc_bcache(sfix->section);
1313	ptu_int_eq(errcode, 0);
1314
1315	errcode = pt_section_memsize(sfix->section, &memsize);
1316	ptu_int_eq(errcode, 0);
1317	ptu_uint_ge(memsize,
1318		    sfix->section->size * sizeof(struct pt_bcache_entry));
1319
1320	errcode = pt_section_unmap(sfix->section);
1321	ptu_int_eq(errcode, 0);
1322
1323	return ptu_passed();
1324}
1325
1326static struct ptunit_result sfix_init(struct section_fixture *sfix)
1327{
1328	int errcode;
1329
1330	sfix->section = NULL;
1331	sfix->file = NULL;
1332	sfix->name = NULL;
1333
1334	errcode = ptunit_mkfile(&sfix->file, &sfix->name, "wb");
1335	ptu_int_eq(errcode, 0);
1336
1337	ptu_test(ptunit_thrd_init, &sfix->thrd);
1338
1339	return ptu_passed();
1340}
1341
1342static struct ptunit_result sfix_fini(struct section_fixture *sfix)
1343{
1344	char *filename;
1345	FILE *file;
1346	int thrd, errcode;
1347
1348	ptu_test(ptunit_thrd_fini, &sfix->thrd);
1349
1350	if (sfix->section) {
1351		pt_section_put(sfix->section);
1352		sfix->section = NULL;
1353	}
1354
1355	filename = sfix->name;
1356	file = sfix->file;
1357	sfix->name = NULL;
1358	sfix->file = NULL;
1359
1360	/* Try removing the file while we still have it open to avoid races
1361	 * with others re-using the temporary filename.
1362	 *
1363	 * On some systems that may not be possible and we can choose between:
1364	 *
1365	 *   - guaranteed leaking files or
1366	 *   - running the risk of removing someone elses file
1367	 *
1368	 * We choose the latter.  Assuming those systems behave consistently,
1369	 * removing someone elses file should only succeed if it isn't open at
1370	 * the moment we try removing it.  Given that this is a temporary file,
1371	 * we should be able to rule out accidental name clashes with
1372	 * non-termporary files.
1373	 */
1374	if (filename && file) {
1375		errcode = remove(filename);
1376		if (!errcode) {
1377			free(filename);
1378			filename = NULL;
1379		}
1380	}
1381
1382	if (file)
1383		fclose(file);
1384
1385	if (filename) {
1386		(void) remove(filename);
1387		free(filename);
1388	}
1389
1390	for (thrd = 0; thrd < sfix->thrd.nthreads; ++thrd)
1391		ptu_int_eq(sfix->thrd.result[thrd], 0);
1392
1393	return ptu_passed();
1394}
1395
1396int main(int argc, char **argv)
1397{
1398	struct section_fixture sfix;
1399	struct ptunit_suite suite;
1400
1401	sfix.init = sfix_init;
1402	sfix.fini = sfix_fini;
1403
1404	suite = ptunit_mk_suite(argc, argv);
1405
1406	ptu_run_f(suite, create, sfix);
1407	ptu_run_f(suite, create_bad_offset, sfix);
1408	ptu_run_f(suite, create_truncated, sfix);
1409	ptu_run_f(suite, create_empty, sfix);
1410
1411	ptu_run(suite, filename_null);
1412	ptu_run(suite, offset_null);
1413	ptu_run(suite, size_null);
1414	ptu_run(suite, get_null);
1415	ptu_run(suite, put_null);
1416	ptu_run(suite, attach_null);
1417	ptu_run(suite, detach_null);
1418	ptu_run(suite, map_null);
1419	ptu_run(suite, unmap_null);
1420	ptu_run(suite, cache_null);
1421
1422	ptu_run_f(suite, get_overflow, sfix);
1423	ptu_run_f(suite, attach_overflow, sfix);
1424	ptu_run_f(suite, attach_bad_ucount, sfix);
1425	ptu_run_f(suite, map_change, sfix);
1426	ptu_run_f(suite, map_put, sfix);
1427	ptu_run_f(suite, unmap_nomap, sfix);
1428	ptu_run_f(suite, map_overflow, sfix);
1429	ptu_run_f(suite, get_put, sfix);
1430	ptu_run_f(suite, attach_detach, sfix);
1431	ptu_run_f(suite, attach_bad_iscache, sfix);
1432	ptu_run_f(suite, detach_bad_iscache, sfix);
1433	ptu_run_f(suite, map_unmap, sfix);
1434	ptu_run_f(suite, attach_map, sfix);
1435	ptu_run_f(suite, attach_bad_map, sfix);
1436	ptu_run_f(suite, attach_map_overflow, sfix);
1437	ptu_run_f(suite, read, sfix);
1438	ptu_run_f(suite, read_null, sfix);
1439	ptu_run_f(suite, read_offset, sfix);
1440	ptu_run_f(suite, read_truncated, sfix);
1441	ptu_run_f(suite, read_from_truncated, sfix);
1442	ptu_run_f(suite, read_nomem, sfix);
1443	ptu_run_f(suite, read_overflow, sfix);
1444	ptu_run_f(suite, read_overflow_32bit, sfix);
1445	ptu_run_f(suite, read_nomap, sfix);
1446	ptu_run_f(suite, read_unmap_map, sfix);
1447
1448	ptu_run_f(suite, init_no_bcache, sfix);
1449	ptu_run_f(suite, bcache_alloc_free, sfix);
1450	ptu_run_f(suite, bcache_alloc_twice, sfix);
1451	ptu_run_f(suite, bcache_alloc_nomap, sfix);
1452
1453	ptu_run_f(suite, memsize_null, sfix);
1454	ptu_run_f(suite, memsize_nomap, sfix);
1455	ptu_run_f(suite, memsize_unmap, sfix);
1456	ptu_run_f(suite, memsize_map_nobcache, sfix);
1457	ptu_run_f(suite, memsize_map_bcache, sfix);
1458
1459	ptu_run_fp(suite, stress, sfix, worker_bcache);
1460	ptu_run_fp(suite, stress, sfix, worker_read);
1461
1462	return ptunit_report(&suite);
1463}
1464