xref: /linux/tools/testing/selftests/powerpc/tm/tm-exec.c (revision 7340c6df49df1b261892d287444c255d0a378063)
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 	SKIP_IF(htm_is_synthetic());
31 
32 	asm __volatile__(
33 		"tbegin.;"
34 		"blt    1f; "
35 		"tsuspend.;"
36 		"1: ;"
37 		: : : "memory");
38 
39 	execl(path, "tm-exec", "--child", NULL);
40 
41 	/* Shouldn't get here */
42 	perror("execl() failed");
43 	return 1;
44 }
45 
46 static int after_exec(void)
47 {
48 	asm __volatile__(
49 		"tbegin.;"
50 		"blt    1f;"
51 		"tsuspend.;"
52 		"1: ;"
53 		: : : "memory");
54 
55 	FAIL_IF(failure_is_nesting());
56 	return 0;
57 }
58 
59 int main(int argc, char *argv[])
60 {
61 	path = argv[0];
62 
63 	if (argc > 1 && strcmp(argv[1], "--child") == 0)
64 		return after_exec();
65 
66 	return test_harness(test_exec, "tm_exec");
67 }
68