Home | History | Annotate | Line # | Download | only in modules
      1 /*
      2  * SPDX-License-Identifier: BSD-2-Clause
      3  *
      4  * Copyright (c) 2018, 2019 Andrew Turner
      5  *
      6  * This software was developed by SRI International and the University of
      7  * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
      8  * ("CTSRD"), as part of the DARPA CRASH research programme.
      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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 #include <sys/cdefs.h>
     32 
     33 #include <sys/param.h>
     34 #include <sys/ioctl.h>
     35 #include <sys/kcov.h>
     36 #include <sys/mman.h>
     37 
     38 #include <errno.h>
     39 #include <fcntl.h>
     40 #include <pthread.h>
     41 #include <semaphore.h>
     42 #include <unistd.h>
     43 
     44 #include <atf-c.h>
     45 
     46 #define PAGE_SIZE sysconf(_SC_PAGESIZE)
     47 
     48 static int
     49 open_kcov(void)
     50 {
     51 	int fd;
     52 
     53 	fd = open("/dev/kcov", O_RDWR);
     54 	if (fd == -1)
     55 		atf_tc_skip("Failed to open /dev/kcov");
     56 
     57 	return fd;
     58 }
     59 
     60 static int
     61 pick_unassigned_fd(int greater_than_fd)
     62 {
     63 	int fd2;
     64 
     65 	fd2 = greater_than_fd;
     66 	do {
     67 		++fd2;
     68 	} while (fcntl(fd2, F_GETFL) != -1 || errno != EBADF);
     69 
     70 	return fd2;
     71 }
     72 
     73 ATF_TC_WITHOUT_HEAD(kcov_dup2);
     74 ATF_TC_BODY(kcov_dup2, tc)
     75 {
     76 	int fd1, fd2;
     77 	fd1 = open_kcov();
     78 
     79 	fd2 = pick_unassigned_fd(fd1);
     80 
     81 	/* Test the dup2(2) trick used by syzkaller */
     82 	ATF_REQUIRE_EQ(dup2(fd1, fd2), fd2);
     83 
     84 	close(fd1);
     85 	close(fd2);
     86 }
     87 
     88 ATF_TC_WITHOUT_HEAD(kcov_multiopen);
     89 ATF_TC_BODY(kcov_multiopen, tc)
     90 {
     91 	int fd1, fd2;
     92 	fd1 = open_kcov();
     93 
     94 	fd2 = open("/dev/kcov", O_RDWR);
     95 	ATF_REQUIRE(fd2 != -1);
     96 
     97 	close(fd1);
     98 	close(fd2);
     99 }
    100 
    101 ATF_TC_WITHOUT_HEAD(kcov_open_close_open);
    102 ATF_TC_BODY(kcov_open_close_open, tc)
    103 {
    104 	int fd;
    105 
    106 	fd = open_kcov();
    107 	close(fd);
    108 	fd = open("/dev/kcov", O_RDWR);
    109 	ATF_REQUIRE(fd != -1);
    110 
    111 	close(fd);
    112 }
    113 
    114 ATF_TC_WITHOUT_HEAD(kcov_bufsize);
    115 ATF_TC_BODY(kcov_bufsize, tc)
    116 {
    117 	int fd;
    118 	uint64_t size;
    119 	fd = open_kcov();
    120 
    121 	size = 0;
    122 	ATF_CHECK(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == -1);
    123 	size = 2;
    124 	ATF_CHECK(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == 0);
    125 
    126 	close(fd);
    127 }
    128 
    129 ATF_TC_WITHOUT_HEAD(kcov_mmap);
    130 ATF_TC_BODY(kcov_mmap, tc)
    131 {
    132 	void *data;
    133 	int fd;
    134 	uint64_t size = 2 * PAGE_SIZE / KCOV_ENTRY_SIZE;
    135 
    136 	fd = open_kcov();
    137 
    138 	ATF_CHECK(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
    139 	    fd, 0) == MAP_FAILED);
    140 
    141 	ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == 0);
    142 
    143 	ATF_REQUIRE((data = mmap(NULL, 2 * PAGE_SIZE, PROT_READ | PROT_WRITE,
    144 	    MAP_SHARED, fd, 0)) != MAP_FAILED);
    145 
    146 	munmap(data, 2 * PAGE_SIZE);
    147 
    148 	close(fd);
    149 }
    150 
    151 /* This shouldn't panic */
    152 ATF_TC_WITHOUT_HEAD(kcov_mmap_no_munmap);
    153 ATF_TC_BODY(kcov_mmap_no_munmap, tc)
    154 {
    155 	int fd;
    156 	uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
    157 
    158 	fd = open_kcov();
    159 
    160 	ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
    161 
    162 	ATF_CHECK(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
    163 	    fd, 0) != MAP_FAILED);
    164 
    165 	close(fd);
    166 }
    167 
    168 ATF_TC_WITHOUT_HEAD(kcov_mmap_no_munmap_no_close);
    169 ATF_TC_BODY(kcov_mmap_no_munmap_no_close, tc)
    170 {
    171 	int fd;
    172 	uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
    173 
    174 	fd = open_kcov();
    175 
    176 	ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
    177 
    178 	ATF_CHECK(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
    179 	    fd, 0) != MAP_FAILED);
    180 }
    181 
    182 static sem_t sem1, sem2;
    183 
    184 static void *
    185 kcov_mmap_enable_thread(void *data)
    186 {
    187 	int fd;
    188 	uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
    189 	int mode;
    190 
    191 	fd = open_kcov();
    192 	*(int *)data = fd;
    193 
    194 	ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
    195 	ATF_CHECK(mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
    196 	    fd, 0) != MAP_FAILED);
    197 	mode = KCOV_MODE_NONE;
    198 	ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
    199 
    200 	sem_post(&sem1);
    201 	sem_wait(&sem2);
    202 
    203 	return NULL;
    204 }
    205 
    206 ATF_TC_WITHOUT_HEAD(kcov_mmap_enable_thread_close);
    207 ATF_TC_BODY(kcov_mmap_enable_thread_close, tc)
    208 {
    209 	pthread_t thread;
    210 	int fd;
    211 
    212 	sem_init(&sem1, 0, 0);
    213 	sem_init(&sem2, 0, 0);
    214 	pthread_create(&thread, NULL,
    215 	    kcov_mmap_enable_thread, &fd);
    216 	sem_wait(&sem1);
    217 	close(fd);
    218 	sem_post(&sem2);
    219 	pthread_join(thread, NULL);
    220 }
    221 
    222 ATF_TC_WITHOUT_HEAD(kcov_enable);
    223 ATF_TC_BODY(kcov_enable, tc)
    224 {
    225 	int fd;
    226 	uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
    227 	int mode;
    228 
    229 	fd = open_kcov();
    230 
    231 	mode = KCOV_MODE_NONE;
    232 	ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == -1);
    233 
    234 	ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
    235 
    236 	/* We need to enable before disable */
    237 	ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == -1);
    238 
    239 	/* Check enabling works only with a valid trace method */
    240 	ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
    241 	ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == -1);
    242 
    243 	/* Disable should only be called once */
    244 	ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0);
    245 	ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == -1);
    246 
    247 	/* Re-enabling and changing mode should also work */
    248 	mode = KCOV_MODE_NONE;
    249 	ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
    250 	ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0);
    251 	mode = KCOV_MODE_TRACE_PC;
    252 	ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
    253 	ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0);
    254 	mode = KCOV_MODE_TRACE_CMP;
    255 	ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
    256 	ATF_CHECK(ioctl(fd, KCOV_IOC_DISABLE) == 0);
    257 
    258 	close(fd);
    259 }
    260 
    261 ATF_TC_WITHOUT_HEAD(kcov_enable_no_disable);
    262 ATF_TC_BODY(kcov_enable_no_disable, tc)
    263 {
    264 	int fd;
    265 	uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
    266 	int mode;
    267 
    268 	fd = open_kcov();
    269 	ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
    270 	mode = KCOV_MODE_NONE;
    271 	ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
    272 	close(fd);
    273 }
    274 
    275 ATF_TC_WITHOUT_HEAD(kcov_enable_no_disable_no_close);
    276 ATF_TC_BODY(kcov_enable_no_disable_no_close, tc)
    277 {
    278 	int fd;
    279 	uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
    280 	int mode;
    281 
    282 	fd = open_kcov();
    283 	ATF_REQUIRE(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) ==0);
    284 	mode = KCOV_MODE_NONE;
    285 	ATF_CHECK(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0);
    286 }
    287 
    288 static void *
    289 common_head_raw(bool fd_dup, int *fdp)
    290 {
    291 	void *data;
    292 	int fd, fd2;
    293 	uint64_t size = PAGE_SIZE / KCOV_ENTRY_SIZE;
    294 
    295 	fd = open_kcov();
    296 
    297 	/* Test the dup2(2) trick used by syzkaller */
    298 	if (fd_dup) {
    299 		fd2 = pick_unassigned_fd(fd);
    300 		ATF_REQUIRE_EQ(dup2(fd, fd2), fd2);
    301 		close(fd);
    302 		fd = fd2;
    303 	}
    304 
    305 	ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_SETBUFSIZE, &size) == 0,
    306 	    "Unable to set the kcov buffer size");
    307 
    308 	data = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    309 	ATF_REQUIRE_MSG(data != MAP_FAILED, "Unable to mmap the kcov buffer");
    310 
    311 	*fdp = fd;
    312 	return data;
    313 }
    314 
    315 static void *
    316 common_head(int *fdp)
    317 {
    318 
    319 	return common_head_raw(false, fdp);
    320 }
    321 
    322 static void
    323 common_tail(int fd, kcov_int_t *data)
    324 {
    325 
    326 	ATF_REQUIRE_MSG(munmap(__UNVOLATILE(data), PAGE_SIZE) == 0,
    327 	    "Unable to unmap the kcov buffer");
    328 
    329 	close(fd);
    330 }
    331 
    332 static void
    333 kcov_basic(bool fd_dup, int mode)
    334 {
    335 	kcov_int_t *buf;
    336 	int fd;
    337 
    338 	buf = common_head_raw(fd_dup, &fd);
    339 	ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0,
    340 	    "Unable to enable kcov ");
    341 
    342 	buf[0] = 0;
    343 
    344 	sleep(0); /* XXX: Is it enough for all trace types? */
    345 	ATF_REQUIRE_MSG(buf[0] != 0, "No records found");
    346 
    347 	ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_DISABLE) == 0,
    348 	    "Unable to disable kcov");
    349 
    350 	common_tail(fd, buf);
    351 }
    352 
    353 ATF_TC_WITHOUT_HEAD(kcov_basic_pc);
    354 ATF_TC_BODY(kcov_basic_pc, tc)
    355 {
    356 
    357 	kcov_basic(false, KCOV_MODE_TRACE_PC);
    358 }
    359 
    360 ATF_TC_WITHOUT_HEAD(kcov_basic_cmp);
    361 ATF_TC_BODY(kcov_basic_cmp, tc)
    362 {
    363 
    364 	atf_tc_skip("XXX: GCC8 needed");
    365 
    366 	kcov_basic(false, KCOV_MODE_TRACE_CMP);
    367 }
    368 
    369 ATF_TC_WITHOUT_HEAD(kcov_basic_dup2_pc);
    370 ATF_TC_BODY(kcov_basic_dup2_pc, tc)
    371 {
    372 
    373 	kcov_basic(true, KCOV_MODE_TRACE_PC);
    374 }
    375 
    376 ATF_TC_WITHOUT_HEAD(kcov_basic_dup2_cmp);
    377 ATF_TC_BODY(kcov_basic_dup2_cmp, tc)
    378 {
    379 
    380 	atf_tc_skip("XXX: GCC8 needed");
    381 
    382 	kcov_basic(true, KCOV_MODE_TRACE_CMP);
    383 }
    384 
    385 ATF_TC_WITHOUT_HEAD(kcov_multienable_on_the_same_thread);
    386 ATF_TC_BODY(kcov_multienable_on_the_same_thread, tc)
    387 {
    388 	kcov_int_t *buf1, *buf2;
    389 	int fd1, fd2;
    390 	int mode;
    391 
    392 	buf1 = common_head(&fd1);
    393 	buf2 = common_head(&fd2);
    394 	mode = KCOV_MODE_NONE;
    395 	ATF_REQUIRE_MSG(ioctl(fd1, KCOV_IOC_ENABLE, &mode) == 0,
    396 	    "Unable to enable kcov");
    397 	ATF_REQUIRE_ERRNO(EBUSY, ioctl(fd2, KCOV_IOC_ENABLE, &mode) != 0);
    398 
    399 	ATF_REQUIRE_MSG(ioctl(fd1, KCOV_IOC_DISABLE) == 0,
    400 	    "Unable to disable kcov");
    401 
    402 	common_tail(fd1, buf1);
    403 	common_tail(fd2, buf2);
    404 }
    405 
    406 static void *
    407 thread_buffer_access_test_helper(void *ptr)
    408 {
    409 	kcov_int_t *buf = ptr;
    410 
    411 	/* Test mapped buffer access from a custom thread */
    412 	buf[0] = buf[0];
    413 
    414 	return NULL;
    415 }
    416 
    417 ATF_TC_WITHOUT_HEAD(kcov_buffer_access_from_custom_thread);
    418 ATF_TC_BODY(kcov_buffer_access_from_custom_thread, tc)
    419 {
    420 	pthread_t thread;
    421 	kcov_int_t *buf;
    422 	int fd;
    423 	int mode;
    424 
    425 	buf = common_head(&fd);
    426 
    427 	mode = KCOV_MODE_TRACE_PC;
    428 	ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0,
    429 	    "Unable to enable kcov ");
    430 
    431 	pthread_create(&thread, NULL, thread_buffer_access_test_helper,
    432 	    __UNVOLATILE(buf));
    433 	pthread_join(thread, NULL);
    434 
    435 	ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_DISABLE) == 0,
    436 	    "Unable to disable kcov");
    437 
    438 	common_tail(fd, buf);
    439 }
    440 
    441 static void *
    442 thread_test_helper(void *ptr)
    443 {
    444 	volatile int i;
    445 
    446 	/* It does not matter what operation is in action. */
    447 	for (i = 0; i < 1000; i++) {
    448 		if (getpid() == 0)
    449 			break;
    450 	}
    451 
    452 	return NULL;
    453 }
    454 
    455 ATF_TC_WITHOUT_HEAD(kcov_thread);
    456 ATF_TC_BODY(kcov_thread, tc)
    457 {
    458 	pthread_t thread;
    459 	kcov_int_t *buf;
    460 	int fd;
    461 	int mode;
    462 	volatile int i;
    463 
    464 	buf = common_head(&fd);
    465 
    466 	mode = KCOV_MODE_TRACE_PC;
    467 	ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0,
    468 	    "Unable to enable kcov ");
    469 
    470 	/* The thread does something, does not matter what exactly. */
    471 	pthread_create(&thread, NULL, thread_test_helper, __UNVOLATILE(buf));
    472 
    473 	buf[0] = 0;
    474 	for (i = 0; i < 10000; i++)
    475 		continue;
    476 	ATF_REQUIRE_EQ_MSG(buf[0], 0,
    477 	    "Records changed in blocked thread");
    478 
    479 	pthread_join(thread, NULL);
    480 
    481 	ATF_REQUIRE_EQ_MSG(ioctl(fd, KCOV_IOC_DISABLE), 0,
    482 	    "Unable to disable kcov");
    483 
    484 	common_tail(fd, buf);
    485 }
    486 
    487 static void *
    488 multiple_threads_helper(void *ptr __unused)
    489 {
    490 	kcov_int_t *buf;
    491 	int fd;
    492 	int mode;
    493 
    494 	buf = common_head(&fd);
    495 	mode = KCOV_MODE_TRACE_PC;
    496 	ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_ENABLE, &mode) == 0,
    497 	    "Unable to enable kcov ");
    498 
    499 	buf[0] = 0;
    500 
    501 	sleep(0);
    502 	ATF_REQUIRE_MSG(buf[0] != 0, "No records found");
    503 
    504 	ATF_REQUIRE_MSG(ioctl(fd, KCOV_IOC_DISABLE) == 0,
    505 	    "Unable to disable kcov");
    506 
    507 	common_tail(fd, buf);
    508 
    509 	return NULL;
    510 }
    511 
    512 static void
    513 kcov_multiple_threads(size_t N)
    514 {
    515 	pthread_t thread[32];
    516 	size_t i;
    517 	int fd;
    518 
    519 	/*
    520 	 * Check if /dev/kcov is available, if not bail out.
    521 	 * Verifying it on a per-thread basis is flaky.
    522 	 */
    523 	fd = open_kcov();
    524 	ATF_REQUIRE(close(fd) == 0);
    525 
    526 	ATF_REQUIRE(__arraycount(thread) >= N);
    527 
    528 	for (i = 0; i < N; i++)
    529 		pthread_create(&thread[i], NULL, multiple_threads_helper, NULL);
    530 
    531 	for (i = 0; i < N; i++)
    532 		pthread_join(thread[i], NULL);
    533 }
    534 
    535 #define KCOV_MULTIPLE_THREADS(n)		\
    536 ATF_TC_WITHOUT_HEAD(kcov_multiple_threads##n);	\
    537 ATF_TC_BODY(kcov_multiple_threads##n, tc)	\
    538 {						\
    539 						\
    540 	kcov_multiple_threads(n);		\
    541 }
    542 
    543 KCOV_MULTIPLE_THREADS(2)
    544 KCOV_MULTIPLE_THREADS(4)
    545 KCOV_MULTIPLE_THREADS(8)
    546 KCOV_MULTIPLE_THREADS(16)
    547 KCOV_MULTIPLE_THREADS(32)
    548 
    549 ATF_TP_ADD_TCS(tp)
    550 {
    551 
    552 	ATF_TP_ADD_TC(tp, kcov_dup2);
    553 	ATF_TP_ADD_TC(tp, kcov_multiopen);
    554 	ATF_TP_ADD_TC(tp, kcov_open_close_open);
    555 	ATF_TP_ADD_TC(tp, kcov_bufsize);
    556 	ATF_TP_ADD_TC(tp, kcov_mmap);
    557 	ATF_TP_ADD_TC(tp, kcov_mmap_no_munmap);
    558 	ATF_TP_ADD_TC(tp, kcov_mmap_no_munmap_no_close);
    559 	ATF_TP_ADD_TC(tp, kcov_enable);
    560 	ATF_TP_ADD_TC(tp, kcov_enable_no_disable);
    561 	ATF_TP_ADD_TC(tp, kcov_enable_no_disable_no_close);
    562 	ATF_TP_ADD_TC(tp, kcov_mmap_enable_thread_close);
    563 	ATF_TP_ADD_TC(tp, kcov_basic_pc);
    564 	ATF_TP_ADD_TC(tp, kcov_basic_cmp);
    565 	ATF_TP_ADD_TC(tp, kcov_basic_dup2_pc);
    566 	ATF_TP_ADD_TC(tp, kcov_basic_dup2_cmp);
    567 	ATF_TP_ADD_TC(tp, kcov_multienable_on_the_same_thread);
    568 	ATF_TP_ADD_TC(tp, kcov_buffer_access_from_custom_thread);
    569 	ATF_TP_ADD_TC(tp, kcov_thread);
    570 	ATF_TP_ADD_TC(tp, kcov_multiple_threads2);
    571 	ATF_TP_ADD_TC(tp, kcov_multiple_threads4);
    572 	ATF_TP_ADD_TC(tp, kcov_multiple_threads8);
    573 	ATF_TP_ADD_TC(tp, kcov_multiple_threads16);
    574 	ATF_TP_ADD_TC(tp, kcov_multiple_threads32);
    575 	return atf_no_error();
    576 }
    577