Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / tools / testing / selftests / powerpc / tm / tm-exec.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright 2016, Cyril Bur, IBM Corp.
4  *
5  * Syscalls can be performed provided the transactions are suspended.
6  * The exec() class of syscall is unique as a new process is loaded.
7  *
8  * It makes little sense for after an exec() call for the previously
9  * suspended transaction to still exist.
10  */
11
12 #define _GNU_SOURCE
13 #include <errno.h>
14 #include <inttypes.h>
15 #include <libgen.h>
16 #include <pthread.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21
22 #include "utils.h"
23 #include "tm.h"
24
25 static char *path;
26
27 static int test_exec(void)
28 {
29         SKIP_IF(!have_htm());
30
31         asm __volatile__(
32                 "tbegin.;"
33                 "blt    1f; "
34                 "tsuspend.;"
35                 "1: ;"
36                 : : : "memory");
37
38         execl(path, "tm-exec", "--child", NULL);
39
40         /* Shouldn't get here */
41         perror("execl() failed");
42         return 1;
43 }
44
45 static int after_exec(void)
46 {
47         asm __volatile__(
48                 "tbegin.;"
49                 "blt    1f;"
50                 "tsuspend.;"
51                 "1: ;"
52                 : : : "memory");
53
54         FAIL_IF(failure_is_nesting());
55         return 0;
56 }
57
58 int main(int argc, char *argv[])
59 {
60         path = argv[0];
61
62         if (argc > 1 && strcmp(argv[1], "--child") == 0)
63                 return after_exec();
64
65         return test_harness(test_exec, "tm_exec");
66 }