]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - tools/testing/selftests/membarrier/membarrier_test.c
regmap: rbtree: When adding a reg do a bsearch for target node
[karo-tx-linux.git] / tools / testing / selftests / membarrier / membarrier_test.c
1 #define _GNU_SOURCE
2 #define __EXPORTED_HEADERS__
3
4 #include <linux/membarrier.h>
5 #include <asm-generic/unistd.h>
6 #include <sys/syscall.h>
7 #include <stdio.h>
8 #include <errno.h>
9 #include <string.h>
10
11 #include "../kselftest.h"
12
13 enum test_membarrier_status {
14         TEST_MEMBARRIER_PASS = 0,
15         TEST_MEMBARRIER_FAIL,
16         TEST_MEMBARRIER_SKIP,
17 };
18
19 static int sys_membarrier(int cmd, int flags)
20 {
21         return syscall(__NR_membarrier, cmd, flags);
22 }
23
24 static enum test_membarrier_status test_membarrier_cmd_fail(void)
25 {
26         int cmd = -1, flags = 0;
27
28         if (sys_membarrier(cmd, flags) != -1) {
29                 printf("membarrier: Wrong command should fail but passed.\n");
30                 return TEST_MEMBARRIER_FAIL;
31         }
32         return TEST_MEMBARRIER_PASS;
33 }
34
35 static enum test_membarrier_status test_membarrier_flags_fail(void)
36 {
37         int cmd = MEMBARRIER_CMD_QUERY, flags = 1;
38
39         if (sys_membarrier(cmd, flags) != -1) {
40                 printf("membarrier: Wrong flags should fail but passed.\n");
41                 return TEST_MEMBARRIER_FAIL;
42         }
43         return TEST_MEMBARRIER_PASS;
44 }
45
46 static enum test_membarrier_status test_membarrier_success(void)
47 {
48         int cmd = MEMBARRIER_CMD_SHARED, flags = 0;
49
50         if (sys_membarrier(cmd, flags) != 0) {
51                 printf("membarrier: Executing MEMBARRIER_CMD_SHARED failed. %s.\n",
52                                 strerror(errno));
53                 return TEST_MEMBARRIER_FAIL;
54         }
55
56         printf("membarrier: MEMBARRIER_CMD_SHARED success.\n");
57         return TEST_MEMBARRIER_PASS;
58 }
59
60 static enum test_membarrier_status test_membarrier(void)
61 {
62         enum test_membarrier_status status;
63
64         status = test_membarrier_cmd_fail();
65         if (status)
66                 return status;
67         status = test_membarrier_flags_fail();
68         if (status)
69                 return status;
70         status = test_membarrier_success();
71         if (status)
72                 return status;
73         return TEST_MEMBARRIER_PASS;
74 }
75
76 static enum test_membarrier_status test_membarrier_query(void)
77 {
78         int flags = 0, ret;
79
80         printf("membarrier MEMBARRIER_CMD_QUERY ");
81         ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags);
82         if (ret < 0) {
83                 printf("failed. %s.\n", strerror(errno));
84                 switch (errno) {
85                 case ENOSYS:
86                         /*
87                          * It is valid to build a kernel with
88                          * CONFIG_MEMBARRIER=n. However, this skips the tests.
89                          */
90                         return TEST_MEMBARRIER_SKIP;
91                 case EINVAL:
92                 default:
93                         return TEST_MEMBARRIER_FAIL;
94                 }
95         }
96         if (!(ret & MEMBARRIER_CMD_SHARED)) {
97                 printf("command MEMBARRIER_CMD_SHARED is not supported.\n");
98                 return TEST_MEMBARRIER_FAIL;
99         }
100         printf("syscall available.\n");
101         return TEST_MEMBARRIER_PASS;
102 }
103
104 int main(int argc, char **argv)
105 {
106         switch (test_membarrier_query()) {
107         case TEST_MEMBARRIER_FAIL:
108                 return ksft_exit_fail();
109         case TEST_MEMBARRIER_SKIP:
110                 return ksft_exit_skip();
111         }
112         switch (test_membarrier()) {
113         case TEST_MEMBARRIER_FAIL:
114                 return ksft_exit_fail();
115         case TEST_MEMBARRIER_SKIP:
116                 return ksft_exit_skip();
117         }
118
119         printf("membarrier: tests done!\n");
120         return ksft_exit_pass();
121 }