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