GNU Linux-libre 4.14.294-gnu1
[releases.git] / tools / testing / selftests / membarrier / membarrier_test.c
1 // SPDX-License-Identifier: GPL-2.0
2 #define _GNU_SOURCE
3 #include <linux/membarrier.h>
4 #include <syscall.h>
5 #include <stdio.h>
6 #include <errno.h>
7 #include <string.h>
8
9 #include "../kselftest.h"
10
11 static int sys_membarrier(int cmd, int flags)
12 {
13         return syscall(__NR_membarrier, cmd, flags);
14 }
15
16 static int test_membarrier_cmd_fail(void)
17 {
18         int cmd = -1, flags = 0;
19
20         if (sys_membarrier(cmd, flags) != -1) {
21                 ksft_exit_fail_msg(
22                         "sys membarrier invalid command test: command = %d, flags = %d. Should fail, but passed\n",
23                         cmd, flags);
24         }
25
26         ksft_test_result_pass(
27                 "sys membarrier invalid command test: command = %d, flags = %d. Failed as expected\n",
28                 cmd, flags);
29         return 0;
30 }
31
32 static int test_membarrier_flags_fail(void)
33 {
34         int cmd = MEMBARRIER_CMD_QUERY, flags = 1;
35
36         if (sys_membarrier(cmd, flags) != -1) {
37                 ksft_exit_fail_msg(
38                         "sys membarrier MEMBARRIER_CMD_QUERY invalid flags test: flags = %d. Should fail, but passed\n",
39                         flags);
40         }
41
42         ksft_test_result_pass(
43                 "sys membarrier MEMBARRIER_CMD_QUERY invalid flags test: flags = %d. Failed as expected\n",
44                 flags);
45         return 0;
46 }
47
48 static int test_membarrier_success(void)
49 {
50         int cmd = MEMBARRIER_CMD_SHARED, flags = 0;
51         const char *test_name = "sys membarrier MEMBARRIER_CMD_SHARED\n";
52
53         if (sys_membarrier(cmd, flags) != 0) {
54                 ksft_exit_fail_msg(
55                         "sys membarrier MEMBARRIER_CMD_SHARED test: flags = %d\n",
56                         flags);
57         }
58
59         ksft_test_result_pass(
60                 "sys membarrier MEMBARRIER_CMD_SHARED test: flags = %d\n",
61                 flags);
62         return 0;
63 }
64
65 static int test_membarrier(void)
66 {
67         int status;
68
69         status = test_membarrier_cmd_fail();
70         if (status)
71                 return status;
72         status = test_membarrier_flags_fail();
73         if (status)
74                 return status;
75         status = test_membarrier_success();
76         if (status)
77                 return status;
78         return 0;
79 }
80
81 static int test_membarrier_query(void)
82 {
83         int flags = 0, ret;
84
85         ret = sys_membarrier(MEMBARRIER_CMD_QUERY, flags);
86         if (ret < 0) {
87                 if (errno == ENOSYS) {
88                         /*
89                          * It is valid to build a kernel with
90                          * CONFIG_MEMBARRIER=n. However, this skips the tests.
91                          */
92                         ksft_exit_skip(
93                                 "sys membarrier (CONFIG_MEMBARRIER) is disabled.\n");
94                 }
95                 ksft_exit_fail_msg("sys_membarrier() failed\n");
96         }
97         if (!(ret & MEMBARRIER_CMD_SHARED))
98                 ksft_exit_fail_msg("sys_membarrier is not supported.\n");
99
100         ksft_test_result_pass("sys_membarrier available\n");
101         return 0;
102 }
103
104 int main(int argc, char **argv)
105 {
106         ksft_print_header();
107
108         test_membarrier_query();
109         test_membarrier();
110
111         ksft_exit_pass();
112 }