xref: /linux/tools/testing/selftests/powerpc/tm/tm-exec.c (revision 0d3b051adbb72ed81956447d0d1e54d5943ee6f5)
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 }
67