aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/Makefile1
-rw-r--r--tools/testing/selftests/membarrier/.gitignore1
-rw-r--r--tools/testing/selftests/membarrier/Makefile11
-rw-r--r--tools/testing/selftests/membarrier/membarrier_test.c121
4 files changed, 134 insertions, 0 deletions
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 050151144596..89b05e2222c9 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -6,6 +6,7 @@ TARGETS += firmware
6TARGETS += ftrace 6TARGETS += ftrace
7TARGETS += futex 7TARGETS += futex
8TARGETS += kcmp 8TARGETS += kcmp
9TARGETS += membarrier
9TARGETS += memfd 10TARGETS += memfd
10TARGETS += memory-hotplug 11TARGETS += memory-hotplug
11TARGETS += mount 12TARGETS += mount
diff --git a/tools/testing/selftests/membarrier/.gitignore b/tools/testing/selftests/membarrier/.gitignore
new file mode 100644
index 000000000000..020c44f49a9e
--- /dev/null
+++ b/tools/testing/selftests/membarrier/.gitignore
@@ -0,0 +1 @@
membarrier_test
diff --git a/tools/testing/selftests/membarrier/Makefile b/tools/testing/selftests/membarrier/Makefile
new file mode 100644
index 000000000000..877a50355d7f
--- /dev/null
+++ b/tools/testing/selftests/membarrier/Makefile
@@ -0,0 +1,11 @@
1CFLAGS += -g -I../../../../usr/include/
2
3all:
4 $(CC) $(CFLAGS) membarrier_test.c -o membarrier_test
5
6TEST_PROGS := membarrier_test
7
8include ../lib.mk
9
10clean:
11 $(RM) membarrier_test
diff --git a/tools/testing/selftests/membarrier/membarrier_test.c b/tools/testing/selftests/membarrier/membarrier_test.c
new file mode 100644
index 000000000000..dde312508007
--- /dev/null
+++ b/tools/testing/selftests/membarrier/membarrier_test.c
@@ -0,0 +1,121 @@
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
13enum test_membarrier_status {
14 TEST_MEMBARRIER_PASS = 0,
15 TEST_MEMBARRIER_FAIL,
16 TEST_MEMBARRIER_SKIP,
17};
18
19static int sys_membarrier(int cmd, int flags)
20{
21 return syscall(__NR_membarrier, cmd, flags);
22}
23
24static 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
35static 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
46static 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
60static 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
76static 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
104int 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}