aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-06 16:11:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-06 16:11:51 -0400
commitca95bf62fcf528a0d8069731d39303ba43fb9af4 (patch)
treee5d746396a7aa08efecd69bf8917c23810797efe
parent0ad39cb3d70fb4324d127aeceee7f63e3f71605c (diff)
parentfa32156921daa5c175228e2cac7679d50efd6c52 (diff)
Merge tag 'linux-kselftest-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest
Pull Kselftest update from Shuah Khan: - Work to restructure timers test suite to move PIE out of rtctest from Alexandre Belloni. - Several minor spelling and bug fixes. - New cgroup tests from Roman Gushchin and Mike Rapoport. - Kselftest framework changes to handle and report skipped tests correctly. Prior to these changes, framework treated all non-zero return codes from tests as failures. When tests are skipped with non-zero return code, due to unmet dependencies and/or unsupported configuration, reporting them as failed lead to false negatives on the tests that couldn't be run. - Fixes to test Makefiles to remove unnecessary RUN_TESTS and EMIT_TESTS overrides and use common defines from lib.mk. - Fixes to several tests to return correct Kselftest skip code. - Changes to improve test output. * tag 'linux-kselftest-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (55 commits) selftests: lib: fix prime_numbers module search and skip logic selftests: intel_pstate: notification about privilege required to run intel_pstate testing script selftests: cgroup/memcontrol: add basic test for socket accounting selftest: intel_pstate: debug support message from aperf.c and return value kselftest/cgroup: fix variable dereferenced before check warning selftests/intel_pstate: Enhance table printing selftests/intel_pstate: Improve test, minor fixes selftests: cgroup/memcontrol: add basic test for swap controls selftests: cgroup: add memory controller self-tests selftests: memfd: split regular and hugetlbfs tests selftests: net: return Kselftest Skip code for skipped tests selftests: mqueue: return Kselftest Skip code for skipped tests selftests: memory-hotplug: return Kselftest Skip code for skipped tests selftests: memfd: return Kselftest Skip code for skipped tests selftests: membarrier: return Kselftest Skip code for skipped tests selftests: media_tests: return Kselftest Skip code for skipped tests selftests: locking: return Kselftest Skip code for skipped tests selftests: locking: add Makefile for locking test selftests: lib: return Kselftest Skip code for skipped tests selftests: lib: add prime_numbers.sh test to Makefile ...
-rw-r--r--MAINTAINERS2
-rw-r--r--tools/testing/selftests/Makefile5
-rw-r--r--tools/testing/selftests/android/Makefile8
-rwxr-xr-xtools/testing/selftests/android/ion/ion_test.sh7
-rw-r--r--tools/testing/selftests/breakpoints/step_after_suspend_test.c6
-rw-r--r--tools/testing/selftests/cgroup/Makefile10
-rw-r--r--tools/testing/selftests/cgroup/cgroup_util.c331
-rw-r--r--tools/testing/selftests/cgroup/cgroup_util.h41
-rw-r--r--tools/testing/selftests/cgroup/test_memcontrol.c1015
-rwxr-xr-xtools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh14
-rwxr-xr-xtools/testing/selftests/cpufreq/main.sh5
-rwxr-xr-xtools/testing/selftests/efivarfs/efivarfs.sh7
-rw-r--r--tools/testing/selftests/exec/execveat.c6
-rw-r--r--tools/testing/selftests/filesystems/Makefile1
-rw-r--r--tools/testing/selftests/filesystems/devpts_pts.c15
-rwxr-xr-xtools/testing/selftests/firmware/fw_fallback.sh4
-rwxr-xr-xtools/testing/selftests/firmware/fw_filesystem.sh4
-rwxr-xr-xtools/testing/selftests/firmware/fw_lib.sh7
-rw-r--r--tools/testing/selftests/futex/Makefile12
-rwxr-xr-xtools/testing/selftests/gpio/gpio-mockup.sh12
-rw-r--r--tools/testing/selftests/intel_pstate/aperf.c6
-rwxr-xr-xtools/testing/selftests/intel_pstate/run.sh47
-rw-r--r--tools/testing/selftests/ipc/msgque.c7
-rwxr-xr-xtools/testing/selftests/kmod/kmod.sh13
-rw-r--r--tools/testing/selftests/kselftest.h2
-rw-r--r--tools/testing/selftests/kvm/.gitignore3
-rw-r--r--tools/testing/selftests/kvm/lib/assert.c9
-rw-r--r--tools/testing/selftests/kvm/vmx_tsc_adjust_test.c2
-rw-r--r--tools/testing/selftests/lib.mk55
-rw-r--r--tools/testing/selftests/lib/Makefile2
-rwxr-xr-xtools/testing/selftests/lib/bitmap.sh8
-rwxr-xr-xtools/testing/selftests/lib/prime_numbers.sh9
-rwxr-xr-xtools/testing/selftests/lib/printf.sh8
-rw-r--r--tools/testing/selftests/locking/Makefile10
-rwxr-xr-x[-rw-r--r--]tools/testing/selftests/locking/ww_mutex.sh8
-rw-r--r--tools/testing/selftests/media_tests/Makefile3
-rw-r--r--tools/testing/selftests/media_tests/media_device_open.c8
-rw-r--r--tools/testing/selftests/media_tests/media_device_test.c10
-rw-r--r--tools/testing/selftests/membarrier/membarrier_test.c7
-rw-r--r--tools/testing/selftests/memfd/Makefile6
-rwxr-xr-xtools/testing/selftests/memfd/run_hugetlbfs_test.sh (renamed from tools/testing/selftests/memfd/run_tests.sh)18
-rw-r--r--tools/testing/selftests/memory-hotplug/Makefile5
-rwxr-xr-xtools/testing/selftests/memory-hotplug/mem-on-off-test.sh14
-rw-r--r--tools/testing/selftests/mount/Makefile12
-rwxr-xr-xtools/testing/selftests/mount/run_tests.sh12
-rw-r--r--tools/testing/selftests/mqueue/Makefile12
-rw-r--r--tools/testing/selftests/mqueue/mq_open_tests.c37
-rw-r--r--tools/testing/selftests/mqueue/mq_perf_tests.c8
-rwxr-xr-xtools/testing/selftests/net/fib_tests.sh8
-rwxr-xr-xtools/testing/selftests/net/netdevice.sh16
-rwxr-xr-xtools/testing/selftests/net/pmtu.sh5
-rw-r--r--tools/testing/selftests/net/psock_tpacket.c4
-rwxr-xr-xtools/testing/selftests/net/rtnetlink.sh31
-rw-r--r--tools/testing/selftests/rtc/.gitignore2
-rw-r--r--tools/testing/selftests/rtc/Makefile9
-rw-r--r--tools/testing/selftests/rtc/rtctest.c238
-rw-r--r--tools/testing/selftests/rtc/setdate.c (renamed from tools/testing/selftests/timers/rtctest_setdate.c)0
-rw-r--r--tools/testing/selftests/timers/.gitignore3
-rw-r--r--tools/testing/selftests/timers/Makefile4
-rw-r--r--tools/testing/selftests/timers/rtcpie.c134
-rw-r--r--tools/testing/selftests/timers/rtctest.c403
-rw-r--r--tools/testing/selftests/x86/Makefile8
-rw-r--r--tools/testing/selftests/x86/trivial_program.c10
63 files changed, 2113 insertions, 615 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 66cd131c517d..f446443a556e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11935,7 +11935,7 @@ F: include/linux/rtc.h
11935F: include/uapi/linux/rtc.h 11935F: include/uapi/linux/rtc.h
11936F: include/linux/rtc/ 11936F: include/linux/rtc/
11937F: include/linux/platform_data/rtc-* 11937F: include/linux/platform_data/rtc-*
11938F: tools/testing/selftests/timers/rtctest.c 11938F: tools/testing/selftests/rtc/
11939 11939
11940REALTEK AUDIO CODECS 11940REALTEK AUDIO CODECS
11941M: Bard Liao <bardliao@realtek.com> 11941M: Bard Liao <bardliao@realtek.com>
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 32aafa92074c..305130de910c 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -3,6 +3,7 @@ TARGETS = android
3TARGETS += bpf 3TARGETS += bpf
4TARGETS += breakpoints 4TARGETS += breakpoints
5TARGETS += capabilities 5TARGETS += capabilities
6TARGETS += cgroup
6TARGETS += cpufreq 7TARGETS += cpufreq
7TARGETS += cpu-hotplug 8TARGETS += cpu-hotplug
8TARGETS += efivarfs 9TARGETS += efivarfs
@@ -28,6 +29,7 @@ TARGETS += powerpc
28TARGETS += proc 29TARGETS += proc
29TARGETS += pstore 30TARGETS += pstore
30TARGETS += ptrace 31TARGETS += ptrace
32TARGETS += rtc
31TARGETS += seccomp 33TARGETS += seccomp
32TARGETS += sigaltstack 34TARGETS += sigaltstack
33TARGETS += size 35TARGETS += size
@@ -134,7 +136,8 @@ ifdef INSTALL_PATH
134 echo "else" >> $(ALL_SCRIPT) 136 echo "else" >> $(ALL_SCRIPT)
135 echo " OUTPUT=/dev/stdout" >> $(ALL_SCRIPT) 137 echo " OUTPUT=/dev/stdout" >> $(ALL_SCRIPT)
136 echo "fi" >> $(ALL_SCRIPT) 138 echo "fi" >> $(ALL_SCRIPT)
137 echo "export KSFT_TAP_LEVEL=`echo 1`" >> $(ALL_SCRIPT) 139 echo "export KSFT_TAP_LEVEL=1" >> $(ALL_SCRIPT)
140 echo "export skip=4" >> $(ALL_SCRIPT)
138 141
139 for TARGET in $(TARGETS); do \ 142 for TARGET in $(TARGETS); do \
140 BUILD_TARGET=$$BUILD/$$TARGET; \ 143 BUILD_TARGET=$$BUILD/$$TARGET; \
diff --git a/tools/testing/selftests/android/Makefile b/tools/testing/selftests/android/Makefile
index f6304d2be90c..72c25a3cb658 100644
--- a/tools/testing/selftests/android/Makefile
+++ b/tools/testing/selftests/android/Makefile
@@ -18,10 +18,6 @@ all:
18 fi \ 18 fi \
19 done 19 done
20 20
21override define RUN_TESTS
22 @cd $(OUTPUT); ./run.sh
23endef
24
25override define INSTALL_RULE 21override define INSTALL_RULE
26 mkdir -p $(INSTALL_PATH) 22 mkdir -p $(INSTALL_PATH)
27 install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) 23 install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES)
@@ -33,10 +29,6 @@ override define INSTALL_RULE
33 done; 29 done;
34endef 30endef
35 31
36override define EMIT_TESTS
37 echo "./run.sh"
38endef
39
40override define CLEAN 32override define CLEAN
41 @for DIR in $(SUBDIRS); do \ 33 @for DIR in $(SUBDIRS); do \
42 BUILD_TARGET=$(OUTPUT)/$$DIR; \ 34 BUILD_TARGET=$(OUTPUT)/$$DIR; \
diff --git a/tools/testing/selftests/android/ion/ion_test.sh b/tools/testing/selftests/android/ion/ion_test.sh
index a1aff506f5e6..69e676cfc94e 100755
--- a/tools/testing/selftests/android/ion/ion_test.sh
+++ b/tools/testing/selftests/android/ion/ion_test.sh
@@ -4,6 +4,9 @@ heapsize=4096
4TCID="ion_test.sh" 4TCID="ion_test.sh"
5errcode=0 5errcode=0
6 6
7# Kselftest framework requirement - SKIP code is 4.
8ksft_skip=4
9
7run_test() 10run_test()
8{ 11{
9 heaptype=$1 12 heaptype=$1
@@ -25,7 +28,7 @@ check_root()
25 uid=$(id -u) 28 uid=$(id -u)
26 if [ $uid -ne 0 ]; then 29 if [ $uid -ne 0 ]; then
27 echo $TCID: must be run as root >&2 30 echo $TCID: must be run as root >&2
28 exit 0 31 exit $ksft_skip
29 fi 32 fi
30} 33}
31 34
@@ -35,7 +38,7 @@ check_device()
35 if [ ! -e $DEVICE ]; then 38 if [ ! -e $DEVICE ]; then
36 echo $TCID: No $DEVICE device found >&2 39 echo $TCID: No $DEVICE device found >&2
37 echo $TCID: May be CONFIG_ION is not set >&2 40 echo $TCID: May be CONFIG_ION is not set >&2
38 exit 0 41 exit $ksft_skip
39 fi 42 fi
40} 43}
41 44
diff --git a/tools/testing/selftests/breakpoints/step_after_suspend_test.c b/tools/testing/selftests/breakpoints/step_after_suspend_test.c
index 3fece06e9f64..f82dcc1f8841 100644
--- a/tools/testing/selftests/breakpoints/step_after_suspend_test.c
+++ b/tools/testing/selftests/breakpoints/step_after_suspend_test.c
@@ -143,10 +143,14 @@ void suspend(void)
143 int err; 143 int err;
144 struct itimerspec spec = {}; 144 struct itimerspec spec = {};
145 145
146 if (getuid() != 0)
147 ksft_exit_skip("Please run the test as root - Exiting.\n");
148
146 power_state_fd = open("/sys/power/state", O_RDWR); 149 power_state_fd = open("/sys/power/state", O_RDWR);
147 if (power_state_fd < 0) 150 if (power_state_fd < 0)
148 ksft_exit_fail_msg( 151 ksft_exit_fail_msg(
149 "open(\"/sys/power/state\") failed (is this test running as root?)\n"); 152 "open(\"/sys/power/state\") failed %s)\n",
153 strerror(errno));
150 154
151 timerfd = timerfd_create(CLOCK_BOOTTIME_ALARM, 0); 155 timerfd = timerfd_create(CLOCK_BOOTTIME_ALARM, 0);
152 if (timerfd < 0) 156 if (timerfd < 0)
diff --git a/tools/testing/selftests/cgroup/Makefile b/tools/testing/selftests/cgroup/Makefile
new file mode 100644
index 000000000000..f7a31392eb2f
--- /dev/null
+++ b/tools/testing/selftests/cgroup/Makefile
@@ -0,0 +1,10 @@
1# SPDX-License-Identifier: GPL-2.0
2CFLAGS += -Wall
3
4all:
5
6TEST_GEN_PROGS = test_memcontrol
7
8include ../lib.mk
9
10$(OUTPUT)/test_memcontrol: cgroup_util.c
diff --git a/tools/testing/selftests/cgroup/cgroup_util.c b/tools/testing/selftests/cgroup/cgroup_util.c
new file mode 100644
index 000000000000..b69bdeb4b9fe
--- /dev/null
+++ b/tools/testing/selftests/cgroup/cgroup_util.c
@@ -0,0 +1,331 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2
3#define _GNU_SOURCE
4
5#include <errno.h>
6#include <fcntl.h>
7#include <linux/limits.h>
8#include <signal.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <sys/stat.h>
13#include <sys/types.h>
14#include <sys/wait.h>
15#include <unistd.h>
16
17#include "cgroup_util.h"
18
19static ssize_t read_text(const char *path, char *buf, size_t max_len)
20{
21 ssize_t len;
22 int fd;
23
24 fd = open(path, O_RDONLY);
25 if (fd < 0)
26 return fd;
27
28 len = read(fd, buf, max_len - 1);
29 if (len < 0)
30 goto out;
31
32 buf[len] = 0;
33out:
34 close(fd);
35 return len;
36}
37
38static ssize_t write_text(const char *path, char *buf, size_t len)
39{
40 int fd;
41
42 fd = open(path, O_WRONLY | O_APPEND);
43 if (fd < 0)
44 return fd;
45
46 len = write(fd, buf, len);
47 if (len < 0) {
48 close(fd);
49 return len;
50 }
51
52 close(fd);
53
54 return len;
55}
56
57char *cg_name(const char *root, const char *name)
58{
59 size_t len = strlen(root) + strlen(name) + 2;
60 char *ret = malloc(len);
61
62 snprintf(ret, len, "%s/%s", root, name);
63
64 return ret;
65}
66
67char *cg_name_indexed(const char *root, const char *name, int index)
68{
69 size_t len = strlen(root) + strlen(name) + 10;
70 char *ret = malloc(len);
71
72 snprintf(ret, len, "%s/%s_%d", root, name, index);
73
74 return ret;
75}
76
77int cg_read(const char *cgroup, const char *control, char *buf, size_t len)
78{
79 char path[PATH_MAX];
80
81 snprintf(path, sizeof(path), "%s/%s", cgroup, control);
82
83 if (read_text(path, buf, len) >= 0)
84 return 0;
85
86 return -1;
87}
88
89int cg_read_strcmp(const char *cgroup, const char *control,
90 const char *expected)
91{
92 size_t size = strlen(expected) + 1;
93 char *buf;
94
95 buf = malloc(size);
96 if (!buf)
97 return -1;
98
99 if (cg_read(cgroup, control, buf, size))
100 return -1;
101
102 return strcmp(expected, buf);
103}
104
105int cg_read_strstr(const char *cgroup, const char *control, const char *needle)
106{
107 char buf[PAGE_SIZE];
108
109 if (cg_read(cgroup, control, buf, sizeof(buf)))
110 return -1;
111
112 return strstr(buf, needle) ? 0 : -1;
113}
114
115long cg_read_long(const char *cgroup, const char *control)
116{
117 char buf[128];
118
119 if (cg_read(cgroup, control, buf, sizeof(buf)))
120 return -1;
121
122 return atol(buf);
123}
124
125long cg_read_key_long(const char *cgroup, const char *control, const char *key)
126{
127 char buf[PAGE_SIZE];
128 char *ptr;
129
130 if (cg_read(cgroup, control, buf, sizeof(buf)))
131 return -1;
132
133 ptr = strstr(buf, key);
134 if (!ptr)
135 return -1;
136
137 return atol(ptr + strlen(key));
138}
139
140int cg_write(const char *cgroup, const char *control, char *buf)
141{
142 char path[PATH_MAX];
143 size_t len = strlen(buf);
144
145 snprintf(path, sizeof(path), "%s/%s", cgroup, control);
146
147 if (write_text(path, buf, len) == len)
148 return 0;
149
150 return -1;
151}
152
153int cg_find_unified_root(char *root, size_t len)
154{
155 char buf[10 * PAGE_SIZE];
156 char *fs, *mount, *type;
157 const char delim[] = "\n\t ";
158
159 if (read_text("/proc/self/mounts", buf, sizeof(buf)) <= 0)
160 return -1;
161
162 /*
163 * Example:
164 * cgroup /sys/fs/cgroup cgroup2 rw,seclabel,noexec,relatime 0 0
165 */
166 for (fs = strtok(buf, delim); fs; fs = strtok(NULL, delim)) {
167 mount = strtok(NULL, delim);
168 type = strtok(NULL, delim);
169 strtok(NULL, delim);
170 strtok(NULL, delim);
171 strtok(NULL, delim);
172
173 if (strcmp(fs, "cgroup") == 0 &&
174 strcmp(type, "cgroup2") == 0) {
175 strncpy(root, mount, len);
176 return 0;
177 }
178 }
179
180 return -1;
181}
182
183int cg_create(const char *cgroup)
184{
185 return mkdir(cgroup, 0644);
186}
187
188static int cg_killall(const char *cgroup)
189{
190 char buf[PAGE_SIZE];
191 char *ptr = buf;
192
193 if (cg_read(cgroup, "cgroup.procs", buf, sizeof(buf)))
194 return -1;
195
196 while (ptr < buf + sizeof(buf)) {
197 int pid = strtol(ptr, &ptr, 10);
198
199 if (pid == 0)
200 break;
201 if (*ptr)
202 ptr++;
203 else
204 break;
205 if (kill(pid, SIGKILL))
206 return -1;
207 }
208
209 return 0;
210}
211
212int cg_destroy(const char *cgroup)
213{
214 int ret;
215
216retry:
217 ret = rmdir(cgroup);
218 if (ret && errno == EBUSY) {
219 ret = cg_killall(cgroup);
220 if (ret)
221 return ret;
222 usleep(100);
223 goto retry;
224 }
225
226 if (ret && errno == ENOENT)
227 ret = 0;
228
229 return ret;
230}
231
232int cg_run(const char *cgroup,
233 int (*fn)(const char *cgroup, void *arg),
234 void *arg)
235{
236 int pid, retcode;
237
238 pid = fork();
239 if (pid < 0) {
240 return pid;
241 } else if (pid == 0) {
242 char buf[64];
243
244 snprintf(buf, sizeof(buf), "%d", getpid());
245 if (cg_write(cgroup, "cgroup.procs", buf))
246 exit(EXIT_FAILURE);
247 exit(fn(cgroup, arg));
248 } else {
249 waitpid(pid, &retcode, 0);
250 if (WIFEXITED(retcode))
251 return WEXITSTATUS(retcode);
252 else
253 return -1;
254 }
255}
256
257int cg_run_nowait(const char *cgroup,
258 int (*fn)(const char *cgroup, void *arg),
259 void *arg)
260{
261 int pid;
262
263 pid = fork();
264 if (pid == 0) {
265 char buf[64];
266
267 snprintf(buf, sizeof(buf), "%d", getpid());
268 if (cg_write(cgroup, "cgroup.procs", buf))
269 exit(EXIT_FAILURE);
270 exit(fn(cgroup, arg));
271 }
272
273 return pid;
274}
275
276int get_temp_fd(void)
277{
278 return open(".", O_TMPFILE | O_RDWR | O_EXCL);
279}
280
281int alloc_pagecache(int fd, size_t size)
282{
283 char buf[PAGE_SIZE];
284 struct stat st;
285 int i;
286
287 if (fstat(fd, &st))
288 goto cleanup;
289
290 size += st.st_size;
291
292 if (ftruncate(fd, size))
293 goto cleanup;
294
295 for (i = 0; i < size; i += sizeof(buf))
296 read(fd, buf, sizeof(buf));
297
298 return 0;
299
300cleanup:
301 return -1;
302}
303
304int alloc_anon(const char *cgroup, void *arg)
305{
306 size_t size = (unsigned long)arg;
307 char *buf, *ptr;
308
309 buf = malloc(size);
310 for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
311 *ptr = 0;
312
313 free(buf);
314 return 0;
315}
316
317int is_swap_enabled(void)
318{
319 char buf[PAGE_SIZE];
320 const char delim[] = "\n";
321 int cnt = 0;
322 char *line;
323
324 if (read_text("/proc/swaps", buf, sizeof(buf)) <= 0)
325 return -1;
326
327 for (line = strtok(buf, delim); line; line = strtok(NULL, delim))
328 cnt++;
329
330 return cnt > 1;
331}
diff --git a/tools/testing/selftests/cgroup/cgroup_util.h b/tools/testing/selftests/cgroup/cgroup_util.h
new file mode 100644
index 000000000000..fe82a297d4e0
--- /dev/null
+++ b/tools/testing/selftests/cgroup/cgroup_util.h
@@ -0,0 +1,41 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#include <stdlib.h>
3
4#define PAGE_SIZE 4096
5
6#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
7
8#define MB(x) (x << 20)
9
10/*
11 * Checks if two given values differ by less than err% of their sum.
12 */
13static inline int values_close(long a, long b, int err)
14{
15 return abs(a - b) <= (a + b) / 100 * err;
16}
17
18extern int cg_find_unified_root(char *root, size_t len);
19extern char *cg_name(const char *root, const char *name);
20extern char *cg_name_indexed(const char *root, const char *name, int index);
21extern int cg_create(const char *cgroup);
22extern int cg_destroy(const char *cgroup);
23extern int cg_read(const char *cgroup, const char *control,
24 char *buf, size_t len);
25extern int cg_read_strcmp(const char *cgroup, const char *control,
26 const char *expected);
27extern int cg_read_strstr(const char *cgroup, const char *control,
28 const char *needle);
29extern long cg_read_long(const char *cgroup, const char *control);
30long cg_read_key_long(const char *cgroup, const char *control, const char *key);
31extern int cg_write(const char *cgroup, const char *control, char *buf);
32extern int cg_run(const char *cgroup,
33 int (*fn)(const char *cgroup, void *arg),
34 void *arg);
35extern int cg_run_nowait(const char *cgroup,
36 int (*fn)(const char *cgroup, void *arg),
37 void *arg);
38extern int get_temp_fd(void);
39extern int alloc_pagecache(int fd, size_t size);
40extern int alloc_anon(const char *cgroup, void *arg);
41extern int is_swap_enabled(void);
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
new file mode 100644
index 000000000000..cf0bddc9d271
--- /dev/null
+++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -0,0 +1,1015 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#define _GNU_SOURCE
3
4#include <linux/limits.h>
5#include <fcntl.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9#include <sys/stat.h>
10#include <sys/types.h>
11#include <unistd.h>
12#include <sys/socket.h>
13#include <sys/wait.h>
14#include <arpa/inet.h>
15#include <netinet/in.h>
16#include <netdb.h>
17#include <errno.h>
18
19#include "../kselftest.h"
20#include "cgroup_util.h"
21
22/*
23 * This test creates two nested cgroups with and without enabling
24 * the memory controller.
25 */
26static int test_memcg_subtree_control(const char *root)
27{
28 char *parent, *child, *parent2, *child2;
29 int ret = KSFT_FAIL;
30 char buf[PAGE_SIZE];
31
32 /* Create two nested cgroups with the memory controller enabled */
33 parent = cg_name(root, "memcg_test_0");
34 child = cg_name(root, "memcg_test_0/memcg_test_1");
35 if (!parent || !child)
36 goto cleanup;
37
38 if (cg_create(parent))
39 goto cleanup;
40
41 if (cg_write(parent, "cgroup.subtree_control", "+memory"))
42 goto cleanup;
43
44 if (cg_create(child))
45 goto cleanup;
46
47 if (cg_read_strstr(child, "cgroup.controllers", "memory"))
48 goto cleanup;
49
50 /* Create two nested cgroups without enabling memory controller */
51 parent2 = cg_name(root, "memcg_test_1");
52 child2 = cg_name(root, "memcg_test_1/memcg_test_1");
53 if (!parent2 || !child2)
54 goto cleanup;
55
56 if (cg_create(parent2))
57 goto cleanup;
58
59 if (cg_create(child2))
60 goto cleanup;
61
62 if (cg_read(child2, "cgroup.controllers", buf, sizeof(buf)))
63 goto cleanup;
64
65 if (!cg_read_strstr(child2, "cgroup.controllers", "memory"))
66 goto cleanup;
67
68 ret = KSFT_PASS;
69
70cleanup:
71 cg_destroy(child);
72 cg_destroy(parent);
73 free(parent);
74 free(child);
75
76 cg_destroy(child2);
77 cg_destroy(parent2);
78 free(parent2);
79 free(child2);
80
81 return ret;
82}
83
84static int alloc_anon_50M_check(const char *cgroup, void *arg)
85{
86 size_t size = MB(50);
87 char *buf, *ptr;
88 long anon, current;
89 int ret = -1;
90
91 buf = malloc(size);
92 for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
93 *ptr = 0;
94
95 current = cg_read_long(cgroup, "memory.current");
96 if (current < size)
97 goto cleanup;
98
99 if (!values_close(size, current, 3))
100 goto cleanup;
101
102 anon = cg_read_key_long(cgroup, "memory.stat", "anon ");
103 if (anon < 0)
104 goto cleanup;
105
106 if (!values_close(anon, current, 3))
107 goto cleanup;
108
109 ret = 0;
110cleanup:
111 free(buf);
112 return ret;
113}
114
115static int alloc_pagecache_50M_check(const char *cgroup, void *arg)
116{
117 size_t size = MB(50);
118 int ret = -1;
119 long current, file;
120 int fd;
121
122 fd = get_temp_fd();
123 if (fd < 0)
124 return -1;
125
126 if (alloc_pagecache(fd, size))
127 goto cleanup;
128
129 current = cg_read_long(cgroup, "memory.current");
130 if (current < size)
131 goto cleanup;
132
133 file = cg_read_key_long(cgroup, "memory.stat", "file ");
134 if (file < 0)
135 goto cleanup;
136
137 if (!values_close(file, current, 10))
138 goto cleanup;
139
140 ret = 0;
141
142cleanup:
143 close(fd);
144 return ret;
145}
146
147/*
148 * This test create a memory cgroup, allocates
149 * some anonymous memory and some pagecache
150 * and check memory.current and some memory.stat values.
151 */
152static int test_memcg_current(const char *root)
153{
154 int ret = KSFT_FAIL;
155 long current;
156 char *memcg;
157
158 memcg = cg_name(root, "memcg_test");
159 if (!memcg)
160 goto cleanup;
161
162 if (cg_create(memcg))
163 goto cleanup;
164
165 current = cg_read_long(memcg, "memory.current");
166 if (current != 0)
167 goto cleanup;
168
169 if (cg_run(memcg, alloc_anon_50M_check, NULL))
170 goto cleanup;
171
172 if (cg_run(memcg, alloc_pagecache_50M_check, NULL))
173 goto cleanup;
174
175 ret = KSFT_PASS;
176
177cleanup:
178 cg_destroy(memcg);
179 free(memcg);
180
181 return ret;
182}
183
184static int alloc_pagecache_50M(const char *cgroup, void *arg)
185{
186 int fd = (long)arg;
187
188 return alloc_pagecache(fd, MB(50));
189}
190
191static int alloc_pagecache_50M_noexit(const char *cgroup, void *arg)
192{
193 int fd = (long)arg;
194 int ppid = getppid();
195
196 if (alloc_pagecache(fd, MB(50)))
197 return -1;
198
199 while (getppid() == ppid)
200 sleep(1);
201
202 return 0;
203}
204
205/*
206 * First, this test creates the following hierarchy:
207 * A memory.min = 50M, memory.max = 200M
208 * A/B memory.min = 50M, memory.current = 50M
209 * A/B/C memory.min = 75M, memory.current = 50M
210 * A/B/D memory.min = 25M, memory.current = 50M
211 * A/B/E memory.min = 500M, memory.current = 0
212 * A/B/F memory.min = 0, memory.current = 50M
213 *
214 * Usages are pagecache, but the test keeps a running
215 * process in every leaf cgroup.
216 * Then it creates A/G and creates a significant
217 * memory pressure in it.
218 *
219 * A/B memory.current ~= 50M
220 * A/B/C memory.current ~= 33M
221 * A/B/D memory.current ~= 17M
222 * A/B/E memory.current ~= 0
223 *
224 * After that it tries to allocate more than there is
225 * unprotected memory in A available, and checks
226 * checks that memory.min protects pagecache even
227 * in this case.
228 */
229static int test_memcg_min(const char *root)
230{
231 int ret = KSFT_FAIL;
232 char *parent[3] = {NULL};
233 char *children[4] = {NULL};
234 long c[4];
235 int i, attempts;
236 int fd;
237
238 fd = get_temp_fd();
239 if (fd < 0)
240 goto cleanup;
241
242 parent[0] = cg_name(root, "memcg_test_0");
243 if (!parent[0])
244 goto cleanup;
245
246 parent[1] = cg_name(parent[0], "memcg_test_1");
247 if (!parent[1])
248 goto cleanup;
249
250 parent[2] = cg_name(parent[0], "memcg_test_2");
251 if (!parent[2])
252 goto cleanup;
253
254 if (cg_create(parent[0]))
255 goto cleanup;
256
257 if (cg_read_long(parent[0], "memory.min")) {
258 ret = KSFT_SKIP;
259 goto cleanup;
260 }
261
262 if (cg_write(parent[0], "cgroup.subtree_control", "+memory"))
263 goto cleanup;
264
265 if (cg_write(parent[0], "memory.max", "200M"))
266 goto cleanup;
267
268 if (cg_write(parent[0], "memory.swap.max", "0"))
269 goto cleanup;
270
271 if (cg_create(parent[1]))
272 goto cleanup;
273
274 if (cg_write(parent[1], "cgroup.subtree_control", "+memory"))
275 goto cleanup;
276
277 if (cg_create(parent[2]))
278 goto cleanup;
279
280 for (i = 0; i < ARRAY_SIZE(children); i++) {
281 children[i] = cg_name_indexed(parent[1], "child_memcg", i);
282 if (!children[i])
283 goto cleanup;
284
285 if (cg_create(children[i]))
286 goto cleanup;
287
288 if (i == 2)
289 continue;
290
291 cg_run_nowait(children[i], alloc_pagecache_50M_noexit,
292 (void *)(long)fd);
293 }
294
295 if (cg_write(parent[0], "memory.min", "50M"))
296 goto cleanup;
297 if (cg_write(parent[1], "memory.min", "50M"))
298 goto cleanup;
299 if (cg_write(children[0], "memory.min", "75M"))
300 goto cleanup;
301 if (cg_write(children[1], "memory.min", "25M"))
302 goto cleanup;
303 if (cg_write(children[2], "memory.min", "500M"))
304 goto cleanup;
305 if (cg_write(children[3], "memory.min", "0"))
306 goto cleanup;
307
308 attempts = 0;
309 while (!values_close(cg_read_long(parent[1], "memory.current"),
310 MB(150), 3)) {
311 if (attempts++ > 5)
312 break;
313 sleep(1);
314 }
315
316 if (cg_run(parent[2], alloc_anon, (void *)MB(148)))
317 goto cleanup;
318
319 if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3))
320 goto cleanup;
321
322 for (i = 0; i < ARRAY_SIZE(children); i++)
323 c[i] = cg_read_long(children[i], "memory.current");
324
325 if (!values_close(c[0], MB(33), 10))
326 goto cleanup;
327
328 if (!values_close(c[1], MB(17), 10))
329 goto cleanup;
330
331 if (!values_close(c[2], 0, 1))
332 goto cleanup;
333
334 if (!cg_run(parent[2], alloc_anon, (void *)MB(170)))
335 goto cleanup;
336
337 if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3))
338 goto cleanup;
339
340 ret = KSFT_PASS;
341
342cleanup:
343 for (i = ARRAY_SIZE(children) - 1; i >= 0; i--) {
344 if (!children[i])
345 continue;
346
347 cg_destroy(children[i]);
348 free(children[i]);
349 }
350
351 for (i = ARRAY_SIZE(parent) - 1; i >= 0; i--) {
352 if (!parent[i])
353 continue;
354
355 cg_destroy(parent[i]);
356 free(parent[i]);
357 }
358 close(fd);
359 return ret;
360}
361
362/*
363 * First, this test creates the following hierarchy:
364 * A memory.low = 50M, memory.max = 200M
365 * A/B memory.low = 50M, memory.current = 50M
366 * A/B/C memory.low = 75M, memory.current = 50M
367 * A/B/D memory.low = 25M, memory.current = 50M
368 * A/B/E memory.low = 500M, memory.current = 0
369 * A/B/F memory.low = 0, memory.current = 50M
370 *
371 * Usages are pagecache.
372 * Then it creates A/G an creates a significant
373 * memory pressure in it.
374 *
375 * Then it checks actual memory usages and expects that:
376 * A/B memory.current ~= 50M
377 * A/B/ memory.current ~= 33M
378 * A/B/D memory.current ~= 17M
379 * A/B/E memory.current ~= 0
380 *
381 * After that it tries to allocate more than there is
382 * unprotected memory in A available,
383 * and checks low and oom events in memory.events.
384 */
385static int test_memcg_low(const char *root)
386{
387 int ret = KSFT_FAIL;
388 char *parent[3] = {NULL};
389 char *children[4] = {NULL};
390 long low, oom;
391 long c[4];
392 int i;
393 int fd;
394
395 fd = get_temp_fd();
396 if (fd < 0)
397 goto cleanup;
398
399 parent[0] = cg_name(root, "memcg_test_0");
400 if (!parent[0])
401 goto cleanup;
402
403 parent[1] = cg_name(parent[0], "memcg_test_1");
404 if (!parent[1])
405 goto cleanup;
406
407 parent[2] = cg_name(parent[0], "memcg_test_2");
408 if (!parent[2])
409 goto cleanup;
410
411 if (cg_create(parent[0]))
412 goto cleanup;
413
414 if (cg_read_long(parent[0], "memory.low"))
415 goto cleanup;
416
417 if (cg_write(parent[0], "cgroup.subtree_control", "+memory"))
418 goto cleanup;
419
420 if (cg_write(parent[0], "memory.max", "200M"))
421 goto cleanup;
422
423 if (cg_write(parent[0], "memory.swap.max", "0"))
424 goto cleanup;
425
426 if (cg_create(parent[1]))
427 goto cleanup;
428
429 if (cg_write(parent[1], "cgroup.subtree_control", "+memory"))
430 goto cleanup;
431
432 if (cg_create(parent[2]))
433 goto cleanup;
434
435 for (i = 0; i < ARRAY_SIZE(children); i++) {
436 children[i] = cg_name_indexed(parent[1], "child_memcg", i);
437 if (!children[i])
438 goto cleanup;
439
440 if (cg_create(children[i]))
441 goto cleanup;
442
443 if (i == 2)
444 continue;
445
446 if (cg_run(children[i], alloc_pagecache_50M, (void *)(long)fd))
447 goto cleanup;
448 }
449
450 if (cg_write(parent[0], "memory.low", "50M"))
451 goto cleanup;
452 if (cg_write(parent[1], "memory.low", "50M"))
453 goto cleanup;
454 if (cg_write(children[0], "memory.low", "75M"))
455 goto cleanup;
456 if (cg_write(children[1], "memory.low", "25M"))
457 goto cleanup;
458 if (cg_write(children[2], "memory.low", "500M"))
459 goto cleanup;
460 if (cg_write(children[3], "memory.low", "0"))
461 goto cleanup;
462
463 if (cg_run(parent[2], alloc_anon, (void *)MB(148)))
464 goto cleanup;
465
466 if (!values_close(cg_read_long(parent[1], "memory.current"), MB(50), 3))
467 goto cleanup;
468
469 for (i = 0; i < ARRAY_SIZE(children); i++)
470 c[i] = cg_read_long(children[i], "memory.current");
471
472 if (!values_close(c[0], MB(33), 10))
473 goto cleanup;
474
475 if (!values_close(c[1], MB(17), 10))
476 goto cleanup;
477
478 if (!values_close(c[2], 0, 1))
479 goto cleanup;
480
481 if (cg_run(parent[2], alloc_anon, (void *)MB(166))) {
482 fprintf(stderr,
483 "memory.low prevents from allocating anon memory\n");
484 goto cleanup;
485 }
486
487 for (i = 0; i < ARRAY_SIZE(children); i++) {
488 oom = cg_read_key_long(children[i], "memory.events", "oom ");
489 low = cg_read_key_long(children[i], "memory.events", "low ");
490
491 if (oom)
492 goto cleanup;
493 if (i < 2 && low <= 0)
494 goto cleanup;
495 if (i >= 2 && low)
496 goto cleanup;
497 }
498
499 ret = KSFT_PASS;
500
501cleanup:
502 for (i = ARRAY_SIZE(children) - 1; i >= 0; i--) {
503 if (!children[i])
504 continue;
505
506 cg_destroy(children[i]);
507 free(children[i]);
508 }
509
510 for (i = ARRAY_SIZE(parent) - 1; i >= 0; i--) {
511 if (!parent[i])
512 continue;
513
514 cg_destroy(parent[i]);
515 free(parent[i]);
516 }
517 close(fd);
518 return ret;
519}
520
521static int alloc_pagecache_max_30M(const char *cgroup, void *arg)
522{
523 size_t size = MB(50);
524 int ret = -1;
525 long current;
526 int fd;
527
528 fd = get_temp_fd();
529 if (fd < 0)
530 return -1;
531
532 if (alloc_pagecache(fd, size))
533 goto cleanup;
534
535 current = cg_read_long(cgroup, "memory.current");
536 if (current <= MB(29) || current > MB(30))
537 goto cleanup;
538
539 ret = 0;
540
541cleanup:
542 close(fd);
543 return ret;
544
545}
546
547/*
548 * This test checks that memory.high limits the amount of
549 * memory which can be consumed by either anonymous memory
550 * or pagecache.
551 */
552static int test_memcg_high(const char *root)
553{
554 int ret = KSFT_FAIL;
555 char *memcg;
556 long high;
557
558 memcg = cg_name(root, "memcg_test");
559 if (!memcg)
560 goto cleanup;
561
562 if (cg_create(memcg))
563 goto cleanup;
564
565 if (cg_read_strcmp(memcg, "memory.high", "max\n"))
566 goto cleanup;
567
568 if (cg_write(memcg, "memory.swap.max", "0"))
569 goto cleanup;
570
571 if (cg_write(memcg, "memory.high", "30M"))
572 goto cleanup;
573
574 if (cg_run(memcg, alloc_anon, (void *)MB(100)))
575 goto cleanup;
576
577 if (!cg_run(memcg, alloc_pagecache_50M_check, NULL))
578 goto cleanup;
579
580 if (cg_run(memcg, alloc_pagecache_max_30M, NULL))
581 goto cleanup;
582
583 high = cg_read_key_long(memcg, "memory.events", "high ");
584 if (high <= 0)
585 goto cleanup;
586
587 ret = KSFT_PASS;
588
589cleanup:
590 cg_destroy(memcg);
591 free(memcg);
592
593 return ret;
594}
595
596/*
597 * This test checks that memory.max limits the amount of
598 * memory which can be consumed by either anonymous memory
599 * or pagecache.
600 */
601static int test_memcg_max(const char *root)
602{
603 int ret = KSFT_FAIL;
604 char *memcg;
605 long current, max;
606
607 memcg = cg_name(root, "memcg_test");
608 if (!memcg)
609 goto cleanup;
610
611 if (cg_create(memcg))
612 goto cleanup;
613
614 if (cg_read_strcmp(memcg, "memory.max", "max\n"))
615 goto cleanup;
616
617 if (cg_write(memcg, "memory.swap.max", "0"))
618 goto cleanup;
619
620 if (cg_write(memcg, "memory.max", "30M"))
621 goto cleanup;
622
623 /* Should be killed by OOM killer */
624 if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
625 goto cleanup;
626
627 if (cg_run(memcg, alloc_pagecache_max_30M, NULL))
628 goto cleanup;
629
630 current = cg_read_long(memcg, "memory.current");
631 if (current > MB(30) || !current)
632 goto cleanup;
633
634 max = cg_read_key_long(memcg, "memory.events", "max ");
635 if (max <= 0)
636 goto cleanup;
637
638 ret = KSFT_PASS;
639
640cleanup:
641 cg_destroy(memcg);
642 free(memcg);
643
644 return ret;
645}
646
647static int alloc_anon_50M_check_swap(const char *cgroup, void *arg)
648{
649 long mem_max = (long)arg;
650 size_t size = MB(50);
651 char *buf, *ptr;
652 long mem_current, swap_current;
653 int ret = -1;
654
655 buf = malloc(size);
656 for (ptr = buf; ptr < buf + size; ptr += PAGE_SIZE)
657 *ptr = 0;
658
659 mem_current = cg_read_long(cgroup, "memory.current");
660 if (!mem_current || !values_close(mem_current, mem_max, 3))
661 goto cleanup;
662
663 swap_current = cg_read_long(cgroup, "memory.swap.current");
664 if (!swap_current ||
665 !values_close(mem_current + swap_current, size, 3))
666 goto cleanup;
667
668 ret = 0;
669cleanup:
670 free(buf);
671 return ret;
672}
673
674/*
675 * This test checks that memory.swap.max limits the amount of
676 * anonymous memory which can be swapped out.
677 */
678static int test_memcg_swap_max(const char *root)
679{
680 int ret = KSFT_FAIL;
681 char *memcg;
682 long max;
683
684 if (!is_swap_enabled())
685 return KSFT_SKIP;
686
687 memcg = cg_name(root, "memcg_test");
688 if (!memcg)
689 goto cleanup;
690
691 if (cg_create(memcg))
692 goto cleanup;
693
694 if (cg_read_long(memcg, "memory.swap.current")) {
695 ret = KSFT_SKIP;
696 goto cleanup;
697 }
698
699 if (cg_read_strcmp(memcg, "memory.max", "max\n"))
700 goto cleanup;
701
702 if (cg_read_strcmp(memcg, "memory.swap.max", "max\n"))
703 goto cleanup;
704
705 if (cg_write(memcg, "memory.swap.max", "30M"))
706 goto cleanup;
707
708 if (cg_write(memcg, "memory.max", "30M"))
709 goto cleanup;
710
711 /* Should be killed by OOM killer */
712 if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
713 goto cleanup;
714
715 if (cg_read_key_long(memcg, "memory.events", "oom ") != 1)
716 goto cleanup;
717
718 if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 1)
719 goto cleanup;
720
721 if (cg_run(memcg, alloc_anon_50M_check_swap, (void *)MB(30)))
722 goto cleanup;
723
724 max = cg_read_key_long(memcg, "memory.events", "max ");
725 if (max <= 0)
726 goto cleanup;
727
728 ret = KSFT_PASS;
729
730cleanup:
731 cg_destroy(memcg);
732 free(memcg);
733
734 return ret;
735}
736
737/*
738 * This test disables swapping and tries to allocate anonymous memory
739 * up to OOM. Then it checks for oom and oom_kill events in
740 * memory.events.
741 */
742static int test_memcg_oom_events(const char *root)
743{
744 int ret = KSFT_FAIL;
745 char *memcg;
746
747 memcg = cg_name(root, "memcg_test");
748 if (!memcg)
749 goto cleanup;
750
751 if (cg_create(memcg))
752 goto cleanup;
753
754 if (cg_write(memcg, "memory.max", "30M"))
755 goto cleanup;
756
757 if (cg_write(memcg, "memory.swap.max", "0"))
758 goto cleanup;
759
760 if (!cg_run(memcg, alloc_anon, (void *)MB(100)))
761 goto cleanup;
762
763 if (cg_read_strcmp(memcg, "cgroup.procs", ""))
764 goto cleanup;
765
766 if (cg_read_key_long(memcg, "memory.events", "oom ") != 1)
767 goto cleanup;
768
769 if (cg_read_key_long(memcg, "memory.events", "oom_kill ") != 1)
770 goto cleanup;
771
772 ret = KSFT_PASS;
773
774cleanup:
775 cg_destroy(memcg);
776 free(memcg);
777
778 return ret;
779}
780
781struct tcp_server_args {
782 unsigned short port;
783 int ctl[2];
784};
785
786static int tcp_server(const char *cgroup, void *arg)
787{
788 struct tcp_server_args *srv_args = arg;
789 struct sockaddr_in6 saddr = { 0 };
790 socklen_t slen = sizeof(saddr);
791 int sk, client_sk, ctl_fd, yes = 1, ret = -1;
792
793 close(srv_args->ctl[0]);
794 ctl_fd = srv_args->ctl[1];
795
796 saddr.sin6_family = AF_INET6;
797 saddr.sin6_addr = in6addr_any;
798 saddr.sin6_port = htons(srv_args->port);
799
800 sk = socket(AF_INET6, SOCK_STREAM, 0);
801 if (sk < 0)
802 return ret;
803
804 if (setsockopt(sk, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0)
805 goto cleanup;
806
807 if (bind(sk, (struct sockaddr *)&saddr, slen)) {
808 write(ctl_fd, &errno, sizeof(errno));
809 goto cleanup;
810 }
811
812 if (listen(sk, 1))
813 goto cleanup;
814
815 ret = 0;
816 if (write(ctl_fd, &ret, sizeof(ret)) != sizeof(ret)) {
817 ret = -1;
818 goto cleanup;
819 }
820
821 client_sk = accept(sk, NULL, NULL);
822 if (client_sk < 0)
823 goto cleanup;
824
825 ret = -1;
826 for (;;) {
827 uint8_t buf[0x100000];
828
829 if (write(client_sk, buf, sizeof(buf)) <= 0) {
830 if (errno == ECONNRESET)
831 ret = 0;
832 break;
833 }
834 }
835
836 close(client_sk);
837
838cleanup:
839 close(sk);
840 return ret;
841}
842
843static int tcp_client(const char *cgroup, unsigned short port)
844{
845 const char server[] = "localhost";
846 struct addrinfo *ai;
847 char servport[6];
848 int retries = 0x10; /* nice round number */
849 int sk, ret;
850
851 snprintf(servport, sizeof(servport), "%hd", port);
852 ret = getaddrinfo(server, servport, NULL, &ai);
853 if (ret)
854 return ret;
855
856 sk = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
857 if (sk < 0)
858 goto free_ainfo;
859
860 ret = connect(sk, ai->ai_addr, ai->ai_addrlen);
861 if (ret < 0)
862 goto close_sk;
863
864 ret = KSFT_FAIL;
865 while (retries--) {
866 uint8_t buf[0x100000];
867 long current, sock;
868
869 if (read(sk, buf, sizeof(buf)) <= 0)
870 goto close_sk;
871
872 current = cg_read_long(cgroup, "memory.current");
873 sock = cg_read_key_long(cgroup, "memory.stat", "sock ");
874
875 if (current < 0 || sock < 0)
876 goto close_sk;
877
878 if (current < sock)
879 goto close_sk;
880
881 if (values_close(current, sock, 10)) {
882 ret = KSFT_PASS;
883 break;
884 }
885 }
886
887close_sk:
888 close(sk);
889free_ainfo:
890 freeaddrinfo(ai);
891 return ret;
892}
893
894/*
895 * This test checks socket memory accounting.
896 * The test forks a TCP server listens on a random port between 1000
897 * and 61000. Once it gets a client connection, it starts writing to
898 * its socket.
899 * The TCP client interleaves reads from the socket with check whether
900 * memory.current and memory.stat.sock are similar.
901 */
902static int test_memcg_sock(const char *root)
903{
904 int bind_retries = 5, ret = KSFT_FAIL, pid, err;
905 unsigned short port;
906 char *memcg;
907
908 memcg = cg_name(root, "memcg_test");
909 if (!memcg)
910 goto cleanup;
911
912 if (cg_create(memcg))
913 goto cleanup;
914
915 while (bind_retries--) {
916 struct tcp_server_args args;
917
918 if (pipe(args.ctl))
919 goto cleanup;
920
921 port = args.port = 1000 + rand() % 60000;
922
923 pid = cg_run_nowait(memcg, tcp_server, &args);
924 if (pid < 0)
925 goto cleanup;
926
927 close(args.ctl[1]);
928 if (read(args.ctl[0], &err, sizeof(err)) != sizeof(err))
929 goto cleanup;
930 close(args.ctl[0]);
931
932 if (!err)
933 break;
934 if (err != EADDRINUSE)
935 goto cleanup;
936
937 waitpid(pid, NULL, 0);
938 }
939
940 if (err == EADDRINUSE) {
941 ret = KSFT_SKIP;
942 goto cleanup;
943 }
944
945 if (tcp_client(memcg, port) != KSFT_PASS)
946 goto cleanup;
947
948 waitpid(pid, &err, 0);
949 if (WEXITSTATUS(err))
950 goto cleanup;
951
952 if (cg_read_long(memcg, "memory.current") < 0)
953 goto cleanup;
954
955 if (cg_read_key_long(memcg, "memory.stat", "sock "))
956 goto cleanup;
957
958 ret = KSFT_PASS;
959
960cleanup:
961 cg_destroy(memcg);
962 free(memcg);
963
964 return ret;
965}
966
967#define T(x) { x, #x }
968struct memcg_test {
969 int (*fn)(const char *root);
970 const char *name;
971} tests[] = {
972 T(test_memcg_subtree_control),
973 T(test_memcg_current),
974 T(test_memcg_min),
975 T(test_memcg_low),
976 T(test_memcg_high),
977 T(test_memcg_max),
978 T(test_memcg_oom_events),
979 T(test_memcg_swap_max),
980 T(test_memcg_sock),
981};
982#undef T
983
984int main(int argc, char **argv)
985{
986 char root[PATH_MAX];
987 int i, ret = EXIT_SUCCESS;
988
989 if (cg_find_unified_root(root, sizeof(root)))
990 ksft_exit_skip("cgroup v2 isn't mounted\n");
991
992 /*
993 * Check that memory controller is available:
994 * memory is listed in cgroup.controllers
995 */
996 if (cg_read_strstr(root, "cgroup.controllers", "memory"))
997 ksft_exit_skip("memory controller isn't available\n");
998
999 for (i = 0; i < ARRAY_SIZE(tests); i++) {
1000 switch (tests[i].fn(root)) {
1001 case KSFT_PASS:
1002 ksft_test_result_pass("%s\n", tests[i].name);
1003 break;
1004 case KSFT_SKIP:
1005 ksft_test_result_skip("%s\n", tests[i].name);
1006 break;
1007 default:
1008 ret = EXIT_FAILURE;
1009 ksft_test_result_fail("%s\n", tests[i].name);
1010 break;
1011 }
1012 }
1013
1014 return ret;
1015}
diff --git a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
index f3a8933c1275..bab13dd025a6 100755
--- a/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
+++ b/tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
@@ -2,6 +2,8 @@
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3 3
4SYSFS= 4SYSFS=
5# Kselftest framework requirement - SKIP code is 4.
6ksft_skip=4
5 7
6prerequisite() 8prerequisite()
7{ 9{
@@ -9,7 +11,7 @@ prerequisite()
9 11
10 if [ $UID != 0 ]; then 12 if [ $UID != 0 ]; then
11 echo $msg must be run as root >&2 13 echo $msg must be run as root >&2
12 exit 0 14 exit $ksft_skip
13 fi 15 fi
14 16
15 taskset -p 01 $$ 17 taskset -p 01 $$
@@ -18,12 +20,12 @@ prerequisite()
18 20
19 if [ ! -d "$SYSFS" ]; then 21 if [ ! -d "$SYSFS" ]; then
20 echo $msg sysfs is not mounted >&2 22 echo $msg sysfs is not mounted >&2
21 exit 0 23 exit $ksft_skip
22 fi 24 fi
23 25
24 if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then 26 if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then
25 echo $msg cpu hotplug is not supported >&2 27 echo $msg cpu hotplug is not supported >&2
26 exit 0 28 exit $ksft_skip
27 fi 29 fi
28 30
29 echo "CPU online/offline summary:" 31 echo "CPU online/offline summary:"
@@ -32,7 +34,7 @@ prerequisite()
32 34
33 if [[ "$online_cpus" = "$online_max" ]]; then 35 if [[ "$online_cpus" = "$online_max" ]]; then
34 echo "$msg: since there is only one cpu: $online_cpus" 36 echo "$msg: since there is only one cpu: $online_cpus"
35 exit 0 37 exit $ksft_skip
36 fi 38 fi
37 39
38 echo -e "\t Cpus in online state: $online_cpus" 40 echo -e "\t Cpus in online state: $online_cpus"
@@ -237,12 +239,12 @@ prerequisite_extra()
237 239
238 if [ ! -d "$DEBUGFS" ]; then 240 if [ ! -d "$DEBUGFS" ]; then
239 echo $msg debugfs is not mounted >&2 241 echo $msg debugfs is not mounted >&2
240 exit 0 242 exit $ksft_skip
241 fi 243 fi
242 244
243 if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then 245 if [ ! -d $NOTIFIER_ERR_INJECT_DIR ]; then
244 echo $msg cpu-notifier-error-inject module is not available >&2 246 echo $msg cpu-notifier-error-inject module is not available >&2
245 exit 0 247 exit $ksft_skip
246 fi 248 fi
247} 249}
248 250
diff --git a/tools/testing/selftests/cpufreq/main.sh b/tools/testing/selftests/cpufreq/main.sh
index d83922de9d89..31f8c9a76c5f 100755
--- a/tools/testing/selftests/cpufreq/main.sh
+++ b/tools/testing/selftests/cpufreq/main.sh
@@ -13,6 +13,9 @@ SYSFS=
13CPUROOT= 13CPUROOT=
14CPUFREQROOT= 14CPUFREQROOT=
15 15
16# Kselftest framework requirement - SKIP code is 4.
17ksft_skip=4
18
16helpme() 19helpme()
17{ 20{
18 printf "Usage: $0 [-h] [-todg args] 21 printf "Usage: $0 [-h] [-todg args]
@@ -38,7 +41,7 @@ prerequisite()
38 41
39 if [ $UID != 0 ]; then 42 if [ $UID != 0 ]; then
40 echo $msg must be run as root >&2 43 echo $msg must be run as root >&2
41 exit 2 44 exit $ksft_skip
42 fi 45 fi
43 46
44 taskset -p 01 $$ 47 taskset -p 01 $$
diff --git a/tools/testing/selftests/efivarfs/efivarfs.sh b/tools/testing/selftests/efivarfs/efivarfs.sh
index c6d5790575ae..a47029a799d2 100755
--- a/tools/testing/selftests/efivarfs/efivarfs.sh
+++ b/tools/testing/selftests/efivarfs/efivarfs.sh
@@ -4,18 +4,21 @@
4efivarfs_mount=/sys/firmware/efi/efivars 4efivarfs_mount=/sys/firmware/efi/efivars
5test_guid=210be57c-9849-4fc7-a635-e6382d1aec27 5test_guid=210be57c-9849-4fc7-a635-e6382d1aec27
6 6
7# Kselftest framework requirement - SKIP code is 4.
8ksft_skip=4
9
7check_prereqs() 10check_prereqs()
8{ 11{
9 local msg="skip all tests:" 12 local msg="skip all tests:"
10 13
11 if [ $UID != 0 ]; then 14 if [ $UID != 0 ]; then
12 echo $msg must be run as root >&2 15 echo $msg must be run as root >&2
13 exit 0 16 exit $ksft_skip
14 fi 17 fi
15 18
16 if ! grep -q "^\S\+ $efivarfs_mount efivarfs" /proc/mounts; then 19 if ! grep -q "^\S\+ $efivarfs_mount efivarfs" /proc/mounts; then
17 echo $msg efivarfs is not mounted on $efivarfs_mount >&2 20 echo $msg efivarfs is not mounted on $efivarfs_mount >&2
18 exit 0 21 exit $ksft_skip
19 fi 22 fi
20} 23}
21 24
diff --git a/tools/testing/selftests/exec/execveat.c b/tools/testing/selftests/exec/execveat.c
index 67cd4597db2b..47cbf54d0801 100644
--- a/tools/testing/selftests/exec/execveat.c
+++ b/tools/testing/selftests/exec/execveat.c
@@ -20,6 +20,8 @@
20#include <string.h> 20#include <string.h>
21#include <unistd.h> 21#include <unistd.h>
22 22
23#include "../kselftest.h"
24
23static char longpath[2 * PATH_MAX] = ""; 25static char longpath[2 * PATH_MAX] = "";
24static char *envp[] = { "IN_TEST=yes", NULL, NULL }; 26static char *envp[] = { "IN_TEST=yes", NULL, NULL };
25static char *argv[] = { "execveat", "99", NULL }; 27static char *argv[] = { "execveat", "99", NULL };
@@ -249,8 +251,8 @@ static int run_tests(void)
249 errno = 0; 251 errno = 0;
250 execveat_(-1, NULL, NULL, NULL, 0); 252 execveat_(-1, NULL, NULL, NULL, 0);
251 if (errno == ENOSYS) { 253 if (errno == ENOSYS) {
252 printf("[FAIL] ENOSYS calling execveat - no kernel support?\n"); 254 ksft_exit_skip(
253 return 1; 255 "ENOSYS calling execveat - no kernel support?\n");
254 } 256 }
255 257
256 /* Change file position to confirm it doesn't affect anything */ 258 /* Change file position to confirm it doesn't affect anything */
diff --git a/tools/testing/selftests/filesystems/Makefile b/tools/testing/selftests/filesystems/Makefile
index 5c7d7001ad37..129880fb42d3 100644
--- a/tools/testing/selftests/filesystems/Makefile
+++ b/tools/testing/selftests/filesystems/Makefile
@@ -1,5 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2 2
3CFLAGS += -I../../../../usr/include/
3TEST_GEN_PROGS := devpts_pts 4TEST_GEN_PROGS := devpts_pts
4TEST_GEN_PROGS_EXTENDED := dnotify_test 5TEST_GEN_PROGS_EXTENDED := dnotify_test
5 6
diff --git a/tools/testing/selftests/filesystems/devpts_pts.c b/tools/testing/selftests/filesystems/devpts_pts.c
index b9055e974289..b1fc9b916ace 100644
--- a/tools/testing/selftests/filesystems/devpts_pts.c
+++ b/tools/testing/selftests/filesystems/devpts_pts.c
@@ -8,9 +8,10 @@
8#include <stdlib.h> 8#include <stdlib.h>
9#include <string.h> 9#include <string.h>
10#include <unistd.h> 10#include <unistd.h>
11#include <sys/ioctl.h> 11#include <asm/ioctls.h>
12#include <sys/mount.h> 12#include <sys/mount.h>
13#include <sys/wait.h> 13#include <sys/wait.h>
14#include "../kselftest.h"
14 15
15static bool terminal_dup2(int duplicate, int original) 16static bool terminal_dup2(int duplicate, int original)
16{ 17{
@@ -125,10 +126,12 @@ static int do_tiocgptpeer(char *ptmx, char *expected_procfd_contents)
125 if (errno == EINVAL) { 126 if (errno == EINVAL) {
126 fprintf(stderr, "TIOCGPTPEER is not supported. " 127 fprintf(stderr, "TIOCGPTPEER is not supported. "
127 "Skipping test.\n"); 128 "Skipping test.\n");
128 fret = EXIT_SUCCESS; 129 fret = KSFT_SKIP;
130 } else {
131 fprintf(stderr,
132 "Failed to perform TIOCGPTPEER ioctl\n");
133 fret = EXIT_FAILURE;
129 } 134 }
130
131 fprintf(stderr, "Failed to perform TIOCGPTPEER ioctl\n");
132 goto do_cleanup; 135 goto do_cleanup;
133 } 136 }
134 137
@@ -279,9 +282,9 @@ int main(int argc, char *argv[])
279 int ret; 282 int ret;
280 283
281 if (!isatty(STDIN_FILENO)) { 284 if (!isatty(STDIN_FILENO)) {
282 fprintf(stderr, "Standard input file desciptor is not attached " 285 fprintf(stderr, "Standard input file descriptor is not attached "
283 "to a terminal. Skipping test\n"); 286 "to a terminal. Skipping test\n");
284 exit(EXIT_FAILURE); 287 exit(KSFT_SKIP);
285 } 288 }
286 289
287 ret = unshare(CLONE_NEWNS); 290 ret = unshare(CLONE_NEWNS);
diff --git a/tools/testing/selftests/firmware/fw_fallback.sh b/tools/testing/selftests/firmware/fw_fallback.sh
index 8e2e34a2ca69..70d18be46af5 100755
--- a/tools/testing/selftests/firmware/fw_fallback.sh
+++ b/tools/testing/selftests/firmware/fw_fallback.sh
@@ -74,7 +74,7 @@ load_fw_custom()
74{ 74{
75 if [ ! -e "$DIR"/trigger_custom_fallback ]; then 75 if [ ! -e "$DIR"/trigger_custom_fallback ]; then
76 echo "$0: custom fallback trigger not present, ignoring test" >&2 76 echo "$0: custom fallback trigger not present, ignoring test" >&2
77 return 1 77 exit $ksft_skip
78 fi 78 fi
79 79
80 local name="$1" 80 local name="$1"
@@ -107,7 +107,7 @@ load_fw_custom_cancel()
107{ 107{
108 if [ ! -e "$DIR"/trigger_custom_fallback ]; then 108 if [ ! -e "$DIR"/trigger_custom_fallback ]; then
109 echo "$0: canceling custom fallback trigger not present, ignoring test" >&2 109 echo "$0: canceling custom fallback trigger not present, ignoring test" >&2
110 return 1 110 exit $ksft_skip
111 fi 111 fi
112 112
113 local name="$1" 113 local name="$1"
diff --git a/tools/testing/selftests/firmware/fw_filesystem.sh b/tools/testing/selftests/firmware/fw_filesystem.sh
index 6452d2129cd9..a4320c4b44dc 100755
--- a/tools/testing/selftests/firmware/fw_filesystem.sh
+++ b/tools/testing/selftests/firmware/fw_filesystem.sh
@@ -30,6 +30,7 @@ fi
30 30
31if [ ! -e "$DIR"/trigger_async_request ]; then 31if [ ! -e "$DIR"/trigger_async_request ]; then
32 echo "$0: empty filename: async trigger not present, ignoring test" >&2 32 echo "$0: empty filename: async trigger not present, ignoring test" >&2
33 exit $ksft_skip
33else 34else
34 if printf '\000' >"$DIR"/trigger_async_request 2> /dev/null; then 35 if printf '\000' >"$DIR"/trigger_async_request 2> /dev/null; then
35 echo "$0: empty filename should not succeed (async)" >&2 36 echo "$0: empty filename should not succeed (async)" >&2
@@ -69,6 +70,7 @@ fi
69# Try the asynchronous version too 70# Try the asynchronous version too
70if [ ! -e "$DIR"/trigger_async_request ]; then 71if [ ! -e "$DIR"/trigger_async_request ]; then
71 echo "$0: firmware loading: async trigger not present, ignoring test" >&2 72 echo "$0: firmware loading: async trigger not present, ignoring test" >&2
73 exit $ksft_skip
72else 74else
73 if ! echo -n "$NAME" >"$DIR"/trigger_async_request ; then 75 if ! echo -n "$NAME" >"$DIR"/trigger_async_request ; then
74 echo "$0: could not trigger async request" >&2 76 echo "$0: could not trigger async request" >&2
@@ -89,7 +91,7 @@ test_config_present()
89{ 91{
90 if [ ! -f $DIR/reset ]; then 92 if [ ! -f $DIR/reset ]; then
91 echo "Configuration triggers not present, ignoring test" 93 echo "Configuration triggers not present, ignoring test"
92 exit 0 94 exit $ksft_skip
93 fi 95 fi
94} 96}
95 97
diff --git a/tools/testing/selftests/firmware/fw_lib.sh b/tools/testing/selftests/firmware/fw_lib.sh
index 962d7f4ac627..6c5f1b2ffb74 100755
--- a/tools/testing/selftests/firmware/fw_lib.sh
+++ b/tools/testing/selftests/firmware/fw_lib.sh
@@ -9,11 +9,14 @@ DIR=/sys/devices/virtual/misc/test_firmware
9PROC_CONFIG="/proc/config.gz" 9PROC_CONFIG="/proc/config.gz"
10TEST_DIR=$(dirname $0) 10TEST_DIR=$(dirname $0)
11 11
12# Kselftest framework requirement - SKIP code is 4.
13ksft_skip=4
14
12print_reqs_exit() 15print_reqs_exit()
13{ 16{
14 echo "You must have the following enabled in your kernel:" >&2 17 echo "You must have the following enabled in your kernel:" >&2
15 cat $TEST_DIR/config >&2 18 cat $TEST_DIR/config >&2
16 exit 1 19 exit $ksft_skip
17} 20}
18 21
19test_modprobe() 22test_modprobe()
@@ -88,7 +91,7 @@ verify_reqs()
88 if [ "$TEST_REQS_FW_SYSFS_FALLBACK" = "yes" ]; then 91 if [ "$TEST_REQS_FW_SYSFS_FALLBACK" = "yes" ]; then
89 if [ ! "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 92 if [ ! "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
90 echo "usermode helper disabled so ignoring test" 93 echo "usermode helper disabled so ignoring test"
91 exit 0 94 exit $ksft_skip
92 fi 95 fi
93 fi 96 fi
94} 97}
diff --git a/tools/testing/selftests/futex/Makefile b/tools/testing/selftests/futex/Makefile
index 8497a376ef9d..12631f0076a1 100644
--- a/tools/testing/selftests/futex/Makefile
+++ b/tools/testing/selftests/futex/Makefile
@@ -17,14 +17,6 @@ all:
17 fi \ 17 fi \
18 done 18 done
19 19
20override define RUN_TESTS
21 @export KSFT_TAP_LEVEL=`echo 1`;
22 @echo "TAP version 13";
23 @echo "selftests: futex";
24 @echo "========================================";
25 @cd $(OUTPUT); ./run.sh
26endef
27
28override define INSTALL_RULE 20override define INSTALL_RULE
29 mkdir -p $(INSTALL_PATH) 21 mkdir -p $(INSTALL_PATH)
30 install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) 22 install -t $(INSTALL_PATH) $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES)
@@ -36,10 +28,6 @@ override define INSTALL_RULE
36 done; 28 done;
37endef 29endef
38 30
39override define EMIT_TESTS
40 echo "./run.sh"
41endef
42
43override define CLEAN 31override define CLEAN
44 @for DIR in $(SUBDIRS); do \ 32 @for DIR in $(SUBDIRS); do \
45 BUILD_TARGET=$(OUTPUT)/$$DIR; \ 33 BUILD_TARGET=$(OUTPUT)/$$DIR; \
diff --git a/tools/testing/selftests/gpio/gpio-mockup.sh b/tools/testing/selftests/gpio/gpio-mockup.sh
index 183fb932edbd..7f35b9880485 100755
--- a/tools/testing/selftests/gpio/gpio-mockup.sh
+++ b/tools/testing/selftests/gpio/gpio-mockup.sh
@@ -2,10 +2,11 @@
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3 3
4#exit status 4#exit status
5#1: run as non-root user 5#1: Internal error
6#2: sysfs/debugfs not mount 6#2: sysfs/debugfs not mount
7#3: insert module fail when gpio-mockup is a module. 7#3: insert module fail when gpio-mockup is a module.
8#4: other reason. 8#4: Skip test including run as non-root user.
9#5: other reason.
9 10
10SYSFS= 11SYSFS=
11GPIO_SYSFS= 12GPIO_SYSFS=
@@ -15,6 +16,9 @@ GPIO_DEBUGFS=
15dev_type= 16dev_type=
16module= 17module=
17 18
19# Kselftest framework requirement - SKIP code is 4.
20ksft_skip=4
21
18usage() 22usage()
19{ 23{
20 echo "Usage:" 24 echo "Usage:"
@@ -34,7 +38,7 @@ prerequisite()
34 msg="skip all tests:" 38 msg="skip all tests:"
35 if [ $UID != 0 ]; then 39 if [ $UID != 0 ]; then
36 echo $msg must be run as root >&2 40 echo $msg must be run as root >&2
37 exit 1 41 exit $ksft_skip
38 fi 42 fi
39 SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` 43 SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
40 if [ ! -d "$SYSFS" ]; then 44 if [ ! -d "$SYSFS" ]; then
@@ -73,7 +77,7 @@ remove_module()
73die() 77die()
74{ 78{
75 remove_module 79 remove_module
76 exit 4 80 exit 5
77} 81}
78 82
79test_chips() 83test_chips()
diff --git a/tools/testing/selftests/intel_pstate/aperf.c b/tools/testing/selftests/intel_pstate/aperf.c
index d21edea9c560..f6cd03a87493 100644
--- a/tools/testing/selftests/intel_pstate/aperf.c
+++ b/tools/testing/selftests/intel_pstate/aperf.c
@@ -9,6 +9,8 @@
9#include <sys/timeb.h> 9#include <sys/timeb.h>
10#include <sched.h> 10#include <sched.h>
11#include <errno.h> 11#include <errno.h>
12#include <string.h>
13#include "../kselftest.h"
12 14
13void usage(char *name) { 15void usage(char *name) {
14 printf ("Usage: %s cpunum\n", name); 16 printf ("Usage: %s cpunum\n", name);
@@ -41,8 +43,8 @@ int main(int argc, char **argv) {
41 fd = open(msr_file_name, O_RDONLY); 43 fd = open(msr_file_name, O_RDONLY);
42 44
43 if (fd == -1) { 45 if (fd == -1) {
44 perror("Failed to open"); 46 printf("/dev/cpu/%d/msr: %s\n", cpu, strerror(errno));
45 return 1; 47 return KSFT_SKIP;
46 } 48 }
47 49
48 CPU_ZERO(&cpuset); 50 CPU_ZERO(&cpuset);
diff --git a/tools/testing/selftests/intel_pstate/run.sh b/tools/testing/selftests/intel_pstate/run.sh
index c670359becc6..e7008f614ad7 100755
--- a/tools/testing/selftests/intel_pstate/run.sh
+++ b/tools/testing/selftests/intel_pstate/run.sh
@@ -30,9 +30,18 @@
30 30
31EVALUATE_ONLY=0 31EVALUATE_ONLY=0
32 32
33# Kselftest framework requirement - SKIP code is 4.
34ksft_skip=4
35
33if ! uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ | grep -q x86; then 36if ! uname -m | sed -e s/i.86/x86/ -e s/x86_64/x86/ | grep -q x86; then
34 echo "$0 # Skipped: Test can only run on x86 architectures." 37 echo "$0 # Skipped: Test can only run on x86 architectures."
35 exit 0 38 exit $ksft_skip
39fi
40
41msg="skip all tests:"
42if [ $UID != 0 ] && [ $EVALUATE_ONLY == 0 ]; then
43 echo $msg please run this as root >&2
44 exit $ksft_skip
36fi 45fi
37 46
38max_cpus=$(($(nproc)-1)) 47max_cpus=$(($(nproc)-1))
@@ -48,11 +57,12 @@ function run_test () {
48 57
49 echo "sleeping for 5 seconds" 58 echo "sleeping for 5 seconds"
50 sleep 5 59 sleep 5
51 num_freqs=$(cat /proc/cpuinfo | grep MHz | sort -u | wc -l) 60 grep MHz /proc/cpuinfo | sort -u > /tmp/result.freqs
52 if [ $num_freqs -le 2 ]; then 61 num_freqs=$(wc -l /tmp/result.freqs | awk ' { print $1 } ')
53 cat /proc/cpuinfo | grep MHz | sort -u | tail -1 > /tmp/result.$1 62 if [ $num_freqs -ge 2 ]; then
63 tail -n 1 /tmp/result.freqs > /tmp/result.$1
54 else 64 else
55 cat /proc/cpuinfo | grep MHz | sort -u > /tmp/result.$1 65 cp /tmp/result.freqs /tmp/result.$1
56 fi 66 fi
57 ./msr 0 >> /tmp/result.$1 67 ./msr 0 >> /tmp/result.$1
58 68
@@ -82,32 +92,37 @@ _max_freq=$(cpupower frequency-info -l | tail -1 | awk ' { print $2 } ')
82max_freq=$(($_max_freq / 1000)) 92max_freq=$(($_max_freq / 1000))
83 93
84 94
85for freq in `seq $max_freq -100 $min_freq` 95[ $EVALUATE_ONLY -eq 0 ] && for freq in `seq $max_freq -100 $min_freq`
86do 96do
87 echo "Setting maximum frequency to $freq" 97 echo "Setting maximum frequency to $freq"
88 cpupower frequency-set -g powersave --max=${freq}MHz >& /dev/null 98 cpupower frequency-set -g powersave --max=${freq}MHz >& /dev/null
89 [ $EVALUATE_ONLY -eq 0 ] && run_test $freq 99 run_test $freq
90done 100done
91 101
92echo "==============================================================================" 102[ $EVALUATE_ONLY -eq 0 ] && cpupower frequency-set -g powersave --max=${max_freq}MHz >& /dev/null
93 103
104echo "========================================================================"
94echo "The marketing frequency of the cpu is $mkt_freq MHz" 105echo "The marketing frequency of the cpu is $mkt_freq MHz"
95echo "The maximum frequency of the cpu is $max_freq MHz" 106echo "The maximum frequency of the cpu is $max_freq MHz"
96echo "The minimum frequency of the cpu is $min_freq MHz" 107echo "The minimum frequency of the cpu is $min_freq MHz"
97 108
98cpupower frequency-set -g powersave --max=${max_freq}MHz >& /dev/null
99
100# make a pretty table 109# make a pretty table
101echo "Target Actual Difference MSR(0x199) max_perf_pct" 110echo "Target Actual Difference MSR(0x199) max_perf_pct" | tr " " "\n" > /tmp/result.tab
102for freq in `seq $max_freq -100 $min_freq` 111for freq in `seq $max_freq -100 $min_freq`
103do 112do
104 result_freq=$(cat /tmp/result.${freq} | grep "cpu MHz" | awk ' { print $4 } ' | awk -F "." ' { print $1 } ') 113 result_freq=$(cat /tmp/result.${freq} | grep "cpu MHz" | awk ' { print $4 } ' | awk -F "." ' { print $1 } ')
105 msr=$(cat /tmp/result.${freq} | grep "msr" | awk ' { print $3 } ') 114 msr=$(cat /tmp/result.${freq} | grep "msr" | awk ' { print $3 } ')
106 max_perf_pct=$(cat /tmp/result.${freq} | grep "max_perf_pct" | awk ' { print $2 } ' ) 115 max_perf_pct=$(cat /tmp/result.${freq} | grep "max_perf_pct" | awk ' { print $2 } ' )
107 if [ $result_freq -eq $freq ]; then 116 cat >> /tmp/result.tab << EOF
108 echo " $freq $result_freq 0 $msr $(($max_perf_pct*3300))" 117$freq
109 else 118$result_freq
110 echo " $freq $result_freq $(($result_freq-$freq)) $msr $(($max_perf_pct*$max_freq))" 119$((result_freq - freq))
111 fi 120$msr
121$((max_perf_pct * max_freq))
122EOF
112done 123done
124
125# print the table
126pr -aTt -5 < /tmp/result.tab
127
113exit 0 128exit 0
diff --git a/tools/testing/selftests/ipc/msgque.c b/tools/testing/selftests/ipc/msgque.c
index ee9382bdfadc..dac927e82336 100644
--- a/tools/testing/selftests/ipc/msgque.c
+++ b/tools/testing/selftests/ipc/msgque.c
@@ -196,10 +196,9 @@ int main(int argc, char **argv)
196 int msg, pid, err; 196 int msg, pid, err;
197 struct msgque_data msgque; 197 struct msgque_data msgque;
198 198
199 if (getuid() != 0) { 199 if (getuid() != 0)
200 printf("Please run the test as root - Exiting.\n"); 200 return ksft_exit_skip(
201 return ksft_exit_fail(); 201 "Please run the test as root - Exiting.\n");
202 }
203 202
204 msgque.key = ftok(argv[0], 822155650); 203 msgque.key = ftok(argv[0], 822155650);
205 if (msgque.key == -1) { 204 if (msgque.key == -1) {
diff --git a/tools/testing/selftests/kmod/kmod.sh b/tools/testing/selftests/kmod/kmod.sh
index 7956ea3be667..0a76314b4414 100755
--- a/tools/testing/selftests/kmod/kmod.sh
+++ b/tools/testing/selftests/kmod/kmod.sh
@@ -62,13 +62,16 @@ ALL_TESTS="$ALL_TESTS 0007:5:1"
62ALL_TESTS="$ALL_TESTS 0008:150:1" 62ALL_TESTS="$ALL_TESTS 0008:150:1"
63ALL_TESTS="$ALL_TESTS 0009:150:1" 63ALL_TESTS="$ALL_TESTS 0009:150:1"
64 64
65# Kselftest framework requirement - SKIP code is 4.
66ksft_skip=4
67
65test_modprobe() 68test_modprobe()
66{ 69{
67 if [ ! -d $DIR ]; then 70 if [ ! -d $DIR ]; then
68 echo "$0: $DIR not present" >&2 71 echo "$0: $DIR not present" >&2
69 echo "You must have the following enabled in your kernel:" >&2 72 echo "You must have the following enabled in your kernel:" >&2
70 cat $TEST_DIR/config >&2 73 cat $TEST_DIR/config >&2
71 exit 1 74 exit $ksft_skip
72 fi 75 fi
73} 76}
74 77
@@ -105,12 +108,12 @@ test_reqs()
105{ 108{
106 if ! which modprobe 2> /dev/null > /dev/null; then 109 if ! which modprobe 2> /dev/null > /dev/null; then
107 echo "$0: You need modprobe installed" >&2 110 echo "$0: You need modprobe installed" >&2
108 exit 1 111 exit $ksft_skip
109 fi 112 fi
110 113
111 if ! which kmod 2> /dev/null > /dev/null; then 114 if ! which kmod 2> /dev/null > /dev/null; then
112 echo "$0: You need kmod installed" >&2 115 echo "$0: You need kmod installed" >&2
113 exit 1 116 exit $ksft_skip
114 fi 117 fi
115 118
116 # kmod 19 has a bad bug where it returns 0 when modprobe 119 # kmod 19 has a bad bug where it returns 0 when modprobe
@@ -124,13 +127,13 @@ test_reqs()
124 echo "$0: You need at least kmod 20" >&2 127 echo "$0: You need at least kmod 20" >&2
125 echo "kmod <= 19 is buggy, for details see:" >&2 128 echo "kmod <= 19 is buggy, for details see:" >&2
126 echo "http://git.kernel.org/cgit/utils/kernel/kmod/kmod.git/commit/libkmod/libkmod-module.c?id=fd44a98ae2eb5eb32161088954ab21e58e19dfc4" >&2 129 echo "http://git.kernel.org/cgit/utils/kernel/kmod/kmod.git/commit/libkmod/libkmod-module.c?id=fd44a98ae2eb5eb32161088954ab21e58e19dfc4" >&2
127 exit 1 130 exit $ksft_skip
128 fi 131 fi
129 132
130 uid=$(id -u) 133 uid=$(id -u)
131 if [ $uid -ne 0 ]; then 134 if [ $uid -ne 0 ]; then
132 echo $msg must be run as root >&2 135 echo $msg must be run as root >&2
133 exit 0 136 exit $ksft_skip
134 fi 137 fi
135} 138}
136 139
diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h
index 1b9d8ecdebce..15e6b75fc3a5 100644
--- a/tools/testing/selftests/kselftest.h
+++ b/tools/testing/selftests/kselftest.h
@@ -20,7 +20,7 @@
20#define KSFT_XFAIL 2 20#define KSFT_XFAIL 2
21#define KSFT_XPASS 3 21#define KSFT_XPASS 3
22/* Treat skip as pass */ 22/* Treat skip as pass */
23#define KSFT_SKIP KSFT_PASS 23#define KSFT_SKIP 4
24 24
25/* counters */ 25/* counters */
26struct ksft_count { 26struct ksft_count {
diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
new file mode 100644
index 000000000000..63fc1ab9248f
--- /dev/null
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -0,0 +1,3 @@
1set_sregs_test
2sync_regs_test
3vmx_tsc_adjust_test
diff --git a/tools/testing/selftests/kvm/lib/assert.c b/tools/testing/selftests/kvm/lib/assert.c
index c9f5b7d4ce38..cd01144d27c8 100644
--- a/tools/testing/selftests/kvm/lib/assert.c
+++ b/tools/testing/selftests/kvm/lib/assert.c
@@ -13,6 +13,8 @@
13#include <execinfo.h> 13#include <execinfo.h>
14#include <sys/syscall.h> 14#include <sys/syscall.h>
15 15
16#include "../../kselftest.h"
17
16/* Dumps the current stack trace to stderr. */ 18/* Dumps the current stack trace to stderr. */
17static void __attribute__((noinline)) test_dump_stack(void); 19static void __attribute__((noinline)) test_dump_stack(void);
18static void test_dump_stack(void) 20static void test_dump_stack(void)
@@ -70,8 +72,9 @@ test_assert(bool exp, const char *exp_str,
70 72
71 fprintf(stderr, "==== Test Assertion Failure ====\n" 73 fprintf(stderr, "==== Test Assertion Failure ====\n"
72 " %s:%u: %s\n" 74 " %s:%u: %s\n"
73 " pid=%d tid=%d\n", 75 " pid=%d tid=%d - %s\n",
74 file, line, exp_str, getpid(), gettid()); 76 file, line, exp_str, getpid(), gettid(),
77 strerror(errno));
75 test_dump_stack(); 78 test_dump_stack();
76 if (fmt) { 79 if (fmt) {
77 fputs(" ", stderr); 80 fputs(" ", stderr);
@@ -80,6 +83,8 @@ test_assert(bool exp, const char *exp_str,
80 } 83 }
81 va_end(ap); 84 va_end(ap);
82 85
86 if (errno == EACCES)
87 ksft_exit_skip("Access denied - Exiting.\n");
83 exit(254); 88 exit(254);
84 } 89 }
85 90
diff --git a/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c b/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c
index aaa633263b2c..d7cb7944a42e 100644
--- a/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c
+++ b/tools/testing/selftests/kvm/vmx_tsc_adjust_test.c
@@ -28,6 +28,8 @@
28#include <string.h> 28#include <string.h>
29#include <sys/ioctl.h> 29#include <sys/ioctl.h>
30 30
31#include "../kselftest.h"
32
31#ifndef MSR_IA32_TSC_ADJUST 33#ifndef MSR_IA32_TSC_ADJUST
32#define MSR_IA32_TSC_ADJUST 0x3b 34#define MSR_IA32_TSC_ADJUST 0x3b
33#endif 35#endif
diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk
index c1b1a4dc6a96..6466294366dc 100644
--- a/tools/testing/selftests/lib.mk
+++ b/tools/testing/selftests/lib.mk
@@ -19,25 +19,43 @@ TEST_GEN_FILES := $(patsubst %,$(OUTPUT)/%,$(TEST_GEN_FILES))
19all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) 19all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES)
20 20
21.ONESHELL: 21.ONESHELL:
22define RUN_TEST_PRINT_RESULT
23 TEST_HDR_MSG="selftests: "`basename $$PWD`:" $$BASENAME_TEST"; \
24 echo $$TEST_HDR_MSG; \
25 echo "========================================"; \
26 if [ ! -x $$TEST ]; then \
27 echo "$$TEST_HDR_MSG: Warning: file $$BASENAME_TEST is not executable, correct this.";\
28 echo "not ok 1..$$test_num $$TEST_HDR_MSG [FAIL]"; \
29 else \
30 cd `dirname $$TEST` > /dev/null; \
31 if [ "X$(summary)" != "X" ]; then \
32 (./$$BASENAME_TEST > /tmp/$$BASENAME_TEST 2>&1 && \
33 echo "ok 1..$$test_num $$TEST_HDR_MSG [PASS]") || \
34 (if [ $$? -eq $$skip ]; then \
35 echo "not ok 1..$$test_num $$TEST_HDR_MSG [SKIP]"; \
36 else echo "not ok 1..$$test_num $$TEST_HDR_MSG [FAIL]"; \
37 fi;) \
38 else \
39 (./$$BASENAME_TEST && \
40 echo "ok 1..$$test_num $$TEST_HDR_MSG [PASS]") || \
41 (if [ $$? -eq $$skip ]; then \
42 echo "not ok 1..$$test_num $$TEST_HDR_MSG [SKIP]"; \
43 else echo "not ok 1..$$test_num $$TEST_HDR_MSG [FAIL]"; \
44 fi;) \
45 fi; \
46 cd - > /dev/null; \
47 fi;
48endef
49
22define RUN_TESTS 50define RUN_TESTS
23 @export KSFT_TAP_LEVEL=`echo 1`; \ 51 @export KSFT_TAP_LEVEL=`echo 1`; \
24 test_num=`echo 0`; \ 52 test_num=`echo 0`; \
53 skip=`echo 4`; \
25 echo "TAP version 13"; \ 54 echo "TAP version 13"; \
26 for TEST in $(1); do \ 55 for TEST in $(1); do \
27 BASENAME_TEST=`basename $$TEST`; \ 56 BASENAME_TEST=`basename $$TEST`; \
28 test_num=`echo $$test_num+1 | bc`; \ 57 test_num=`echo $$test_num+1 | bc`; \
29 echo "selftests: $$BASENAME_TEST"; \ 58 $(call RUN_TEST_PRINT_RESULT,$(TEST),$(BASENAME_TEST),$(test_num),$(skip)) \
30 echo "========================================"; \
31 if [ ! -x $$TEST ]; then \
32 echo "selftests: Warning: file $$BASENAME_TEST is not executable, correct this.";\
33 echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; \
34 else \
35 if [ "X$(summary)" != "X" ]; then \
36 cd `dirname $$TEST` > /dev/null; (./$$BASENAME_TEST > /tmp/$$BASENAME_TEST 2>&1 && echo "ok 1..$$test_num selftests: $$BASENAME_TEST [PASS]") || echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; cd - > /dev/null;\
37 else \
38 cd `dirname $$TEST` > /dev/null; (./$$BASENAME_TEST && echo "ok 1..$$test_num selftests: $$BASENAME_TEST [PASS]") || echo "not ok 1..$$test_num selftests: $$BASENAME_TEST [FAIL]"; cd - > /dev/null;\
39 fi; \
40 fi; \
41 done; 59 done;
42endef 60endef
43 61
@@ -76,9 +94,18 @@ else
76endif 94endif
77 95
78define EMIT_TESTS 96define EMIT_TESTS
79 @for TEST in $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_PROGS); do \ 97 @test_num=`echo 0`; \
98 for TEST in $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) $(TEST_PROGS); do \
80 BASENAME_TEST=`basename $$TEST`; \ 99 BASENAME_TEST=`basename $$TEST`; \
81 echo "(./$$BASENAME_TEST >> \$$OUTPUT 2>&1 && echo \"selftests: $$BASENAME_TEST [PASS]\") || echo \"selftests: $$BASENAME_TEST [FAIL]\""; \ 100 test_num=`echo $$test_num+1 | bc`; \
101 TEST_HDR_MSG="selftests: "`basename $$PWD`:" $$BASENAME_TEST"; \
102 echo "echo $$TEST_HDR_MSG"; \
103 if [ ! -x $$TEST ]; then \
104 echo "echo \"$$TEST_HDR_MSG: Warning: file $$BASENAME_TEST is not executable, correct this.\""; \
105 echo "echo \"not ok 1..$$test_num $$TEST_HDR_MSG [FAIL]\""; \
106 else
107 echo "(./$$BASENAME_TEST >> \$$OUTPUT 2>&1 && echo \"ok 1..$$test_num $$TEST_HDR_MSG [PASS]\") || (if [ \$$? -eq \$$skip ]; then echo \"not ok 1..$$test_num $$TEST_HDR_MSG [SKIP]\"; else echo \"not ok 1..$$test_num $$TEST_HDR_MSG [FAIL]\"; fi;)"; \
108 fi; \
82 done; 109 done;
83endef 110endef
84 111
diff --git a/tools/testing/selftests/lib/Makefile b/tools/testing/selftests/lib/Makefile
index 08360060ab14..70d5711e3ac8 100644
--- a/tools/testing/selftests/lib/Makefile
+++ b/tools/testing/selftests/lib/Makefile
@@ -3,6 +3,6 @@
3# No binaries, but make sure arg-less "make" doesn't trigger "run_tests" 3# No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
4all: 4all:
5 5
6TEST_PROGS := printf.sh bitmap.sh 6TEST_PROGS := printf.sh bitmap.sh prime_numbers.sh
7 7
8include ../lib.mk 8include ../lib.mk
diff --git a/tools/testing/selftests/lib/bitmap.sh b/tools/testing/selftests/lib/bitmap.sh
index 4dee4d2a8bbe..5a90006d1aea 100755
--- a/tools/testing/selftests/lib/bitmap.sh
+++ b/tools/testing/selftests/lib/bitmap.sh
@@ -1,9 +1,13 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3
4# Kselftest framework requirement - SKIP code is 4.
5ksft_skip=4
6
3# Runs bitmap infrastructure tests using test_bitmap kernel module 7# Runs bitmap infrastructure tests using test_bitmap kernel module
4if ! /sbin/modprobe -q -n test_bitmap; then 8if ! /sbin/modprobe -q -n test_bitmap; then
5 echo "bitmap: [SKIP]" 9 echo "bitmap: module test_bitmap is not found [SKIP]"
6 exit 77 10 exit $ksft_skip
7fi 11fi
8 12
9if /sbin/modprobe -q test_bitmap; then 13if /sbin/modprobe -q test_bitmap; then
diff --git a/tools/testing/selftests/lib/prime_numbers.sh b/tools/testing/selftests/lib/prime_numbers.sh
index b363994e5e11..78e7483c8d60 100755
--- a/tools/testing/selftests/lib/prime_numbers.sh
+++ b/tools/testing/selftests/lib/prime_numbers.sh
@@ -2,9 +2,12 @@
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3# Checks fast/slow prime_number generation for inconsistencies 3# Checks fast/slow prime_number generation for inconsistencies
4 4
5if ! /sbin/modprobe -q -r prime_numbers; then 5# Kselftest framework requirement - SKIP code is 4.
6 echo "prime_numbers: [SKIP]" 6ksft_skip=4
7 exit 77 7
8if ! /sbin/modprobe -q -n prime_numbers; then
9 echo "prime_numbers: module prime_numbers is not found [SKIP]"
10 exit $ksft_skip
8fi 11fi
9 12
10if /sbin/modprobe -q prime_numbers selftest=65536; then 13if /sbin/modprobe -q prime_numbers selftest=65536; then
diff --git a/tools/testing/selftests/lib/printf.sh b/tools/testing/selftests/lib/printf.sh
index 0c37377fd7d4..45a23e2d64ad 100755
--- a/tools/testing/selftests/lib/printf.sh
+++ b/tools/testing/selftests/lib/printf.sh
@@ -1,9 +1,13 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3# Runs printf infrastructure using test_printf kernel module 3# Runs printf infrastructure using test_printf kernel module
4
5# Kselftest framework requirement - SKIP code is 4.
6ksft_skip=4
7
4if ! /sbin/modprobe -q -n test_printf; then 8if ! /sbin/modprobe -q -n test_printf; then
5 echo "printf: [SKIP]" 9 echo "printf: module test_printf is not found [SKIP]"
6 exit 77 10 exit $ksft_skip
7fi 11fi
8 12
9if /sbin/modprobe -q test_printf; then 13if /sbin/modprobe -q test_printf; then
diff --git a/tools/testing/selftests/locking/Makefile b/tools/testing/selftests/locking/Makefile
new file mode 100644
index 000000000000..6e7761ab3536
--- /dev/null
+++ b/tools/testing/selftests/locking/Makefile
@@ -0,0 +1,10 @@
1# SPDX-License-Identifier: GPL-2.0
2#
3# Makefile for locking/ww_mutx selftests
4
5# No binaries, but make sure arg-less "make" doesn't trigger "run_tests"
6all:
7
8TEST_PROGS := ww_mutex.sh
9
10include ../lib.mk
diff --git a/tools/testing/selftests/locking/ww_mutex.sh b/tools/testing/selftests/locking/ww_mutex.sh
index 2c3d6b1878c2..91e4ac7566af 100644..100755
--- a/tools/testing/selftests/locking/ww_mutex.sh
+++ b/tools/testing/selftests/locking/ww_mutex.sh
@@ -1,6 +1,14 @@
1#!/bin/sh 1#!/bin/sh
2# SPDX-License-Identifier: GPL-2.0 2# SPDX-License-Identifier: GPL-2.0
3
4# Kselftest framework requirement - SKIP code is 4.
5ksft_skip=4
6
3# Runs API tests for struct ww_mutex (Wait/Wound mutexes) 7# Runs API tests for struct ww_mutex (Wait/Wound mutexes)
8if ! /sbin/modprobe -q -n test-ww_mutex; then
9 echo "ww_mutex: module test-ww_mutex is not found [SKIP]"
10 exit $ksft_skip
11fi
4 12
5if /sbin/modprobe -q test-ww_mutex; then 13if /sbin/modprobe -q test-ww_mutex; then
6 /sbin/modprobe -q -r test-ww_mutex 14 /sbin/modprobe -q -r test-ww_mutex
diff --git a/tools/testing/selftests/media_tests/Makefile b/tools/testing/selftests/media_tests/Makefile
index c82cec2497de..60826d7d37d4 100644
--- a/tools/testing/selftests/media_tests/Makefile
+++ b/tools/testing/selftests/media_tests/Makefile
@@ -1,5 +1,6 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2#
3CFLAGS += -I../ -I../../../../usr/include/
2TEST_GEN_PROGS := media_device_test media_device_open video_device_test 4TEST_GEN_PROGS := media_device_test media_device_open video_device_test
3all: $(TEST_GEN_PROGS)
4 5
5include ../lib.mk 6include ../lib.mk
diff --git a/tools/testing/selftests/media_tests/media_device_open.c b/tools/testing/selftests/media_tests/media_device_open.c
index a5ce5434bafd..93183a37b133 100644
--- a/tools/testing/selftests/media_tests/media_device_open.c
+++ b/tools/testing/selftests/media_tests/media_device_open.c
@@ -34,6 +34,8 @@
34#include <sys/stat.h> 34#include <sys/stat.h>
35#include <linux/media.h> 35#include <linux/media.h>
36 36
37#include "../kselftest.h"
38
37int main(int argc, char **argv) 39int main(int argc, char **argv)
38{ 40{
39 int opt; 41 int opt;
@@ -61,10 +63,8 @@ int main(int argc, char **argv)
61 } 63 }
62 } 64 }
63 65
64 if (getuid() != 0) { 66 if (getuid() != 0)
65 printf("Please run the test as root - Exiting.\n"); 67 ksft_exit_skip("Please run the test as root - Exiting.\n");
66 exit(-1);
67 }
68 68
69 /* Open Media device and keep it open */ 69 /* Open Media device and keep it open */
70 fd = open(media_device, O_RDWR); 70 fd = open(media_device, O_RDWR);
diff --git a/tools/testing/selftests/media_tests/media_device_test.c b/tools/testing/selftests/media_tests/media_device_test.c
index 421a367e4bb3..4b9953359e40 100644
--- a/tools/testing/selftests/media_tests/media_device_test.c
+++ b/tools/testing/selftests/media_tests/media_device_test.c
@@ -39,6 +39,8 @@
39#include <time.h> 39#include <time.h>
40#include <linux/media.h> 40#include <linux/media.h>
41 41
42#include "../kselftest.h"
43
42int main(int argc, char **argv) 44int main(int argc, char **argv)
43{ 45{
44 int opt; 46 int opt;
@@ -66,10 +68,8 @@ int main(int argc, char **argv)
66 } 68 }
67 } 69 }
68 70
69 if (getuid() != 0) { 71 if (getuid() != 0)
70 printf("Please run the test as root - Exiting.\n"); 72 ksft_exit_skip("Please run the test as root - Exiting.\n");
71 exit(-1);
72 }
73 73
74 /* Generate random number of interations */ 74 /* Generate random number of interations */
75 srand((unsigned int) time(NULL)); 75 srand((unsigned int) time(NULL));
@@ -88,7 +88,7 @@ int main(int argc, char **argv)
88 "other Oops in the dmesg. Enable KaSan kernel\n" 88 "other Oops in the dmesg. Enable KaSan kernel\n"
89 "config option for use-after-free error detection.\n\n"); 89 "config option for use-after-free error detection.\n\n");
90 90
91 printf("Running test for %d iternations\n", count); 91 printf("Running test for %d iterations\n", count);
92 92
93 while (count > 0) { 93 while (count > 0) {
94 ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi); 94 ret = ioctl(fd, MEDIA_IOC_DEVICE_INFO, &mdi);
diff --git a/tools/testing/selftests/membarrier/membarrier_test.c b/tools/testing/selftests/membarrier/membarrier_test.c
index 22bffd55a523..6793f8ecc8e7 100644
--- a/tools/testing/selftests/membarrier/membarrier_test.c
+++ b/tools/testing/selftests/membarrier/membarrier_test.c
@@ -293,10 +293,9 @@ static int test_membarrier_query(void)
293 } 293 }
294 ksft_exit_fail_msg("sys_membarrier() failed\n"); 294 ksft_exit_fail_msg("sys_membarrier() failed\n");
295 } 295 }
296 if (!(ret & MEMBARRIER_CMD_GLOBAL)) { 296 if (!(ret & MEMBARRIER_CMD_GLOBAL))
297 ksft_test_result_fail("sys_membarrier() CMD_GLOBAL query failed\n"); 297 ksft_exit_skip(
298 ksft_exit_fail_msg("sys_membarrier is not supported.\n"); 298 "sys_membarrier unsupported: CMD_GLOBAL not found.\n");
299 }
300 299
301 ksft_test_result_pass("sys_membarrier available\n"); 300 ksft_test_result_pass("sys_membarrier available\n");
302 return 0; 301 return 0;
diff --git a/tools/testing/selftests/memfd/Makefile b/tools/testing/selftests/memfd/Makefile
index 0862e6f47a38..53a848109f7b 100644
--- a/tools/testing/selftests/memfd/Makefile
+++ b/tools/testing/selftests/memfd/Makefile
@@ -4,9 +4,9 @@ CFLAGS += -I../../../../include/uapi/
4CFLAGS += -I../../../../include/ 4CFLAGS += -I../../../../include/
5CFLAGS += -I../../../../usr/include/ 5CFLAGS += -I../../../../usr/include/
6 6
7TEST_PROGS := run_tests.sh 7TEST_GEN_PROGS := memfd_test
8TEST_FILES := run_fuse_test.sh 8TEST_PROGS := run_fuse_test.sh run_hugetlbfs_test.sh
9TEST_GEN_FILES := memfd_test fuse_mnt fuse_test 9TEST_GEN_FILES := fuse_mnt fuse_test
10 10
11fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags) 11fuse_mnt.o: CFLAGS += $(shell pkg-config fuse --cflags)
12 12
diff --git a/tools/testing/selftests/memfd/run_tests.sh b/tools/testing/selftests/memfd/run_hugetlbfs_test.sh
index c2d41ed81b24..fb633eeb0290 100755
--- a/tools/testing/selftests/memfd/run_tests.sh
+++ b/tools/testing/selftests/memfd/run_hugetlbfs_test.sh
@@ -1,11 +1,8 @@
1#!/bin/bash 1#!/bin/bash
2# please run as root 2# please run as root
3 3
4# 4# Kselftest framework requirement - SKIP code is 4.
5# Normal tests requiring no special resources 5ksft_skip=4
6#
7./run_fuse_test.sh
8./memfd_test
9 6
10# 7#
11# To test memfd_create with hugetlbfs, there needs to be hpages_test 8# To test memfd_create with hugetlbfs, there needs to be hpages_test
@@ -29,12 +26,13 @@ if [ -n "$freepgs" ] && [ $freepgs -lt $hpages_test ]; then
29 nr_hugepgs=`cat /proc/sys/vm/nr_hugepages` 26 nr_hugepgs=`cat /proc/sys/vm/nr_hugepages`
30 hpages_needed=`expr $hpages_test - $freepgs` 27 hpages_needed=`expr $hpages_test - $freepgs`
31 28
29 if [ $UID != 0 ]; then
30 echo "Please run memfd with hugetlbfs test as root"
31 exit $ksft_skip
32 fi
33
32 echo 3 > /proc/sys/vm/drop_caches 34 echo 3 > /proc/sys/vm/drop_caches
33 echo $(( $hpages_needed + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages 35 echo $(( $hpages_needed + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages
34 if [ $? -ne 0 ]; then
35 echo "Please run this test as root"
36 exit 1
37 fi
38 while read name size unit; do 36 while read name size unit; do
39 if [ "$name" = "HugePages_Free:" ]; then 37 if [ "$name" = "HugePages_Free:" ]; then
40 freepgs=$size 38 freepgs=$size
@@ -53,7 +51,7 @@ if [ $freepgs -lt $hpages_test ]; then
53 fi 51 fi
54 printf "Not enough huge pages available (%d < %d)\n" \ 52 printf "Not enough huge pages available (%d < %d)\n" \
55 $freepgs $needpgs 53 $freepgs $needpgs
56 exit 1 54 exit $ksft_skip
57fi 55fi
58 56
59# 57#
diff --git a/tools/testing/selftests/memory-hotplug/Makefile b/tools/testing/selftests/memory-hotplug/Makefile
index 686da510f989..e0a625e34f40 100644
--- a/tools/testing/selftests/memory-hotplug/Makefile
+++ b/tools/testing/selftests/memory-hotplug/Makefile
@@ -4,11 +4,8 @@ all:
4include ../lib.mk 4include ../lib.mk
5 5
6TEST_PROGS := mem-on-off-test.sh 6TEST_PROGS := mem-on-off-test.sh
7override RUN_TESTS := @./mem-on-off-test.sh -r 2 && echo "selftests: memory-hotplug [PASS]" || echo "selftests: memory-hotplug [FAIL]"
8
9override EMIT_TESTS := echo "$(subst @,,$(RUN_TESTS))"
10 7
11run_full_test: 8run_full_test:
12 @/bin/bash ./mem-on-off-test.sh && echo "memory-hotplug selftests: [PASS]" || echo "memory-hotplug selftests: [FAIL]" 9 @/bin/bash ./mem-on-off-test.sh -r 10 && echo "memory-hotplug selftests: [PASS]" || echo "memory-hotplug selftests: [FAIL]"
13 10
14clean: 11clean:
diff --git a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh
index ae2c790d0880..b37585e6aa38 100755
--- a/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh
+++ b/tools/testing/selftests/memory-hotplug/mem-on-off-test.sh
@@ -3,30 +3,33 @@
3 3
4SYSFS= 4SYSFS=
5 5
6# Kselftest framework requirement - SKIP code is 4.
7ksft_skip=4
8
6prerequisite() 9prerequisite()
7{ 10{
8 msg="skip all tests:" 11 msg="skip all tests:"
9 12
10 if [ $UID != 0 ]; then 13 if [ $UID != 0 ]; then
11 echo $msg must be run as root >&2 14 echo $msg must be run as root >&2
12 exit 0 15 exit $ksft_skip
13 fi 16 fi
14 17
15 SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'` 18 SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
16 19
17 if [ ! -d "$SYSFS" ]; then 20 if [ ! -d "$SYSFS" ]; then
18 echo $msg sysfs is not mounted >&2 21 echo $msg sysfs is not mounted >&2
19 exit 0 22 exit $ksft_skip
20 fi 23 fi
21 24
22 if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then 25 if ! ls $SYSFS/devices/system/memory/memory* > /dev/null 2>&1; then
23 echo $msg memory hotplug is not supported >&2 26 echo $msg memory hotplug is not supported >&2
24 exit 0 27 exit $ksft_skip
25 fi 28 fi
26 29
27 if ! grep -q 1 $SYSFS/devices/system/memory/memory*/removable; then 30 if ! grep -q 1 $SYSFS/devices/system/memory/memory*/removable; then
28 echo $msg no hot-pluggable memory >&2 31 echo $msg no hot-pluggable memory >&2
29 exit 0 32 exit $ksft_skip
30 fi 33 fi
31} 34}
32 35
@@ -133,7 +136,8 @@ offline_memory_expect_fail()
133 136
134error=-12 137error=-12
135priority=0 138priority=0
136ratio=10 139# Run with default of ratio=2 for Kselftest run
140ratio=2
137retval=0 141retval=0
138 142
139while getopts e:hp:r: opt; do 143while getopts e:hp:r: opt; do
diff --git a/tools/testing/selftests/mount/Makefile b/tools/testing/selftests/mount/Makefile
index e094f71c6dbc..026890744215 100644
--- a/tools/testing/selftests/mount/Makefile
+++ b/tools/testing/selftests/mount/Makefile
@@ -3,15 +3,7 @@
3CFLAGS = -Wall \ 3CFLAGS = -Wall \
4 -O2 4 -O2
5 5
6TEST_GEN_PROGS := unprivileged-remount-test 6TEST_PROGS := run_tests.sh
7TEST_GEN_FILES := unprivileged-remount-test
7 8
8include ../lib.mk 9include ../lib.mk
9
10override RUN_TESTS := if [ -f /proc/self/uid_map ] ; \
11 then \
12 ./unprivileged-remount-test ; \
13 else \
14 echo "WARN: No /proc/self/uid_map exist, test skipped." ; \
15 fi
16override EMIT_TESTS := echo "$(RUN_TESTS)"
17
diff --git a/tools/testing/selftests/mount/run_tests.sh b/tools/testing/selftests/mount/run_tests.sh
new file mode 100755
index 000000000000..4ab8f507dcba
--- /dev/null
+++ b/tools/testing/selftests/mount/run_tests.sh
@@ -0,0 +1,12 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3# Kselftest framework requirement - SKIP code is 4.
4ksft_skip=4
5
6# Run mount selftests
7if [ -f /proc/self/uid_map ] ; then
8 ./unprivileged-remount-test ;
9else
10 echo "WARN: No /proc/self/uid_map exist, test skipped." ;
11 exit $ksft_skip
12fi
diff --git a/tools/testing/selftests/mqueue/Makefile b/tools/testing/selftests/mqueue/Makefile
index 743d3f9e5918..8a58055fc1f5 100644
--- a/tools/testing/selftests/mqueue/Makefile
+++ b/tools/testing/selftests/mqueue/Makefile
@@ -1,17 +1,7 @@
1# SPDX-License-Identifier: GPL-2.0 1# SPDX-License-Identifier: GPL-2.0
2CFLAGS += -O2 2CFLAGS += -O2
3LDLIBS = -lrt -lpthread -lpopt 3LDLIBS = -lrt -lpthread -lpopt
4
4TEST_GEN_PROGS := mq_open_tests mq_perf_tests 5TEST_GEN_PROGS := mq_open_tests mq_perf_tests
5 6
6include ../lib.mk 7include ../lib.mk
7
8override define RUN_TESTS
9 @$(OUTPUT)/mq_open_tests /test1 || echo "selftests: mq_open_tests [FAIL]"
10 @$(OUTPUT)/mq_perf_tests || echo "selftests: mq_perf_tests [FAIL]"
11endef
12
13override define EMIT_TESTS
14 echo "./mq_open_tests /test1 || echo \"selftests: mq_open_tests [FAIL]\""
15 echo "./mq_perf_tests || echo \"selftests: mq_perf_tests [FAIL]\""
16endef
17
diff --git a/tools/testing/selftests/mqueue/mq_open_tests.c b/tools/testing/selftests/mqueue/mq_open_tests.c
index e0a74bd207a5..9403ac01ba11 100644
--- a/tools/testing/selftests/mqueue/mq_open_tests.c
+++ b/tools/testing/selftests/mqueue/mq_open_tests.c
@@ -33,6 +33,8 @@
33#include <mqueue.h> 33#include <mqueue.h>
34#include <error.h> 34#include <error.h>
35 35
36#include "../kselftest.h"
37
36static char *usage = 38static char *usage =
37"Usage:\n" 39"Usage:\n"
38" %s path\n" 40" %s path\n"
@@ -53,6 +55,7 @@ int saved_def_msgs, saved_def_msgsize, saved_max_msgs, saved_max_msgsize;
53int cur_def_msgs, cur_def_msgsize, cur_max_msgs, cur_max_msgsize; 55int cur_def_msgs, cur_def_msgsize, cur_max_msgs, cur_max_msgsize;
54FILE *def_msgs, *def_msgsize, *max_msgs, *max_msgsize; 56FILE *def_msgs, *def_msgsize, *max_msgs, *max_msgsize;
55char *queue_path; 57char *queue_path;
58char *default_queue_path = "/test1";
56mqd_t queue = -1; 59mqd_t queue = -1;
57 60
58static inline void __set(FILE *stream, int value, char *err_msg); 61static inline void __set(FILE *stream, int value, char *err_msg);
@@ -238,35 +241,33 @@ int main(int argc, char *argv[])
238 struct mq_attr attr, result; 241 struct mq_attr attr, result;
239 242
240 if (argc != 2) { 243 if (argc != 2) {
241 fprintf(stderr, "Must pass a valid queue name\n\n"); 244 printf("Using Default queue path - %s\n", default_queue_path);
242 fprintf(stderr, usage, argv[0]); 245 queue_path = default_queue_path;
243 exit(1); 246 } else {
244 }
245 247
246 /* 248 /*
247 * Although we can create a msg queue with a non-absolute path name, 249 * Although we can create a msg queue with a non-absolute path name,
248 * unlink will fail. So, if the name doesn't start with a /, add one 250 * unlink will fail. So, if the name doesn't start with a /, add one
249 * when we save it. 251 * when we save it.
250 */ 252 */
251 if (*argv[1] == '/') 253 if (*argv[1] == '/')
252 queue_path = strdup(argv[1]); 254 queue_path = strdup(argv[1]);
253 else { 255 else {
254 queue_path = malloc(strlen(argv[1]) + 2); 256 queue_path = malloc(strlen(argv[1]) + 2);
255 if (!queue_path) { 257 if (!queue_path) {
256 perror("malloc()"); 258 perror("malloc()");
257 exit(1); 259 exit(1);
260 }
261 queue_path[0] = '/';
262 queue_path[1] = 0;
263 strcat(queue_path, argv[1]);
258 } 264 }
259 queue_path[0] = '/';
260 queue_path[1] = 0;
261 strcat(queue_path, argv[1]);
262 } 265 }
263 266
264 if (getuid() != 0) { 267 if (getuid() != 0)
265 fprintf(stderr, "Not running as root, but almost all tests " 268 ksft_exit_skip("Not running as root, but almost all tests "
266 "require root in order to modify\nsystem settings. " 269 "require root in order to modify\nsystem settings. "
267 "Exiting.\n"); 270 "Exiting.\n");
268 exit(1);
269 }
270 271
271 /* Find out what files there are for us to make tweaks in */ 272 /* Find out what files there are for us to make tweaks in */
272 def_msgs = fopen(DEF_MSGS, "r+"); 273 def_msgs = fopen(DEF_MSGS, "r+");
diff --git a/tools/testing/selftests/mqueue/mq_perf_tests.c b/tools/testing/selftests/mqueue/mq_perf_tests.c
index 8188f72de93c..b019e0b8221c 100644
--- a/tools/testing/selftests/mqueue/mq_perf_tests.c
+++ b/tools/testing/selftests/mqueue/mq_perf_tests.c
@@ -39,6 +39,8 @@
39#include <popt.h> 39#include <popt.h>
40#include <error.h> 40#include <error.h>
41 41
42#include "../kselftest.h"
43
42static char *usage = 44static char *usage =
43"Usage:\n" 45"Usage:\n"
44" %s [-c #[,#..] -f] path\n" 46" %s [-c #[,#..] -f] path\n"
@@ -626,12 +628,10 @@ int main(int argc, char *argv[])
626 cpus_to_pin[0] = cpus_online - 1; 628 cpus_to_pin[0] = cpus_online - 1;
627 } 629 }
628 630
629 if (getuid() != 0) { 631 if (getuid() != 0)
630 fprintf(stderr, "Not running as root, but almost all tests " 632 ksft_exit_skip("Not running as root, but almost all tests "
631 "require root in order to modify\nsystem settings. " 633 "require root in order to modify\nsystem settings. "
632 "Exiting.\n"); 634 "Exiting.\n");
633 exit(1);
634 }
635 635
636 max_msgs = fopen(MAX_MSGS, "r+"); 636 max_msgs = fopen(MAX_MSGS, "r+");
637 max_msgsize = fopen(MAX_MSGSIZE, "r+"); 637 max_msgsize = fopen(MAX_MSGSIZE, "r+");
diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh
index 9164e60d4b66..5baac82b9287 100755
--- a/tools/testing/selftests/net/fib_tests.sh
+++ b/tools/testing/selftests/net/fib_tests.sh
@@ -5,6 +5,8 @@
5# different events. 5# different events.
6 6
7ret=0 7ret=0
8# Kselftest framework requirement - SKIP code is 4.
9ksft_skip=4
8 10
9VERBOSE=${VERBOSE:=0} 11VERBOSE=${VERBOSE:=0}
10PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} 12PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
@@ -579,18 +581,18 @@ fib_test()
579 581
580if [ "$(id -u)" -ne 0 ];then 582if [ "$(id -u)" -ne 0 ];then
581 echo "SKIP: Need root privileges" 583 echo "SKIP: Need root privileges"
582 exit 0 584 exit $ksft_skip;
583fi 585fi
584 586
585if [ ! -x "$(command -v ip)" ]; then 587if [ ! -x "$(command -v ip)" ]; then
586 echo "SKIP: Could not run test without ip tool" 588 echo "SKIP: Could not run test without ip tool"
587 exit 0 589 exit $ksft_skip
588fi 590fi
589 591
590ip route help 2>&1 | grep -q fibmatch 592ip route help 2>&1 | grep -q fibmatch
591if [ $? -ne 0 ]; then 593if [ $? -ne 0 ]; then
592 echo "SKIP: iproute2 too old, missing fibmatch" 594 echo "SKIP: iproute2 too old, missing fibmatch"
593 exit 0 595 exit $ksft_skip
594fi 596fi
595 597
596# start clean 598# start clean
diff --git a/tools/testing/selftests/net/netdevice.sh b/tools/testing/selftests/net/netdevice.sh
index 903679e0ff31..e3afcb424710 100755
--- a/tools/testing/selftests/net/netdevice.sh
+++ b/tools/testing/selftests/net/netdevice.sh
@@ -8,6 +8,9 @@
8# if not they probably have failed earlier in the boot process and their logged error will be catched by another test 8# if not they probably have failed earlier in the boot process and their logged error will be catched by another test
9# 9#
10 10
11# Kselftest framework requirement - SKIP code is 4.
12ksft_skip=4
13
11# this function will try to up the interface 14# this function will try to up the interface
12# if already up, nothing done 15# if already up, nothing done
13# arg1: network interface name 16# arg1: network interface name
@@ -18,7 +21,7 @@ kci_net_start()
18 ip link show "$netdev" |grep -q UP 21 ip link show "$netdev" |grep -q UP
19 if [ $? -eq 0 ];then 22 if [ $? -eq 0 ];then
20 echo "SKIP: $netdev: interface already up" 23 echo "SKIP: $netdev: interface already up"
21 return 0 24 return $ksft_skip
22 fi 25 fi
23 26
24 ip link set "$netdev" up 27 ip link set "$netdev" up
@@ -61,12 +64,12 @@ kci_net_setup()
61 ip address show "$netdev" |grep '^[[:space:]]*inet' 64 ip address show "$netdev" |grep '^[[:space:]]*inet'
62 if [ $? -eq 0 ];then 65 if [ $? -eq 0 ];then
63 echo "SKIP: $netdev: already have an IP" 66 echo "SKIP: $netdev: already have an IP"
64 return 0 67 return $ksft_skip
65 fi 68 fi
66 69
67 # TODO what ipaddr to set ? DHCP ? 70 # TODO what ipaddr to set ? DHCP ?
68 echo "SKIP: $netdev: set IP address" 71 echo "SKIP: $netdev: set IP address"
69 return 0 72 return $ksft_skip
70} 73}
71 74
72# test an ethtool command 75# test an ethtool command
@@ -84,6 +87,7 @@ kci_netdev_ethtool_test()
84 if [ $ret -ne 0 ];then 87 if [ $ret -ne 0 ];then
85 if [ $ret -eq "$1" ];then 88 if [ $ret -eq "$1" ];then
86 echo "SKIP: $netdev: ethtool $2 not supported" 89 echo "SKIP: $netdev: ethtool $2 not supported"
90 return $ksft_skip
87 else 91 else
88 echo "FAIL: $netdev: ethtool $2" 92 echo "FAIL: $netdev: ethtool $2"
89 return 1 93 return 1
@@ -104,7 +108,7 @@ kci_netdev_ethtool()
104 ethtool --version 2>/dev/null >/dev/null 108 ethtool --version 2>/dev/null >/dev/null
105 if [ $? -ne 0 ];then 109 if [ $? -ne 0 ];then
106 echo "SKIP: ethtool not present" 110 echo "SKIP: ethtool not present"
107 return 1 111 return $ksft_skip
108 fi 112 fi
109 113
110 TMP_ETHTOOL_FEATURES="$(mktemp)" 114 TMP_ETHTOOL_FEATURES="$(mktemp)"
@@ -176,13 +180,13 @@ kci_test_netdev()
176#check for needed privileges 180#check for needed privileges
177if [ "$(id -u)" -ne 0 ];then 181if [ "$(id -u)" -ne 0 ];then
178 echo "SKIP: Need root privileges" 182 echo "SKIP: Need root privileges"
179 exit 0 183 exit $ksft_skip
180fi 184fi
181 185
182ip link show 2>/dev/null >/dev/null 186ip link show 2>/dev/null >/dev/null
183if [ $? -ne 0 ];then 187if [ $? -ne 0 ];then
184 echo "SKIP: Could not run test without the ip tool" 188 echo "SKIP: Could not run test without the ip tool"
185 exit 0 189 exit $ksft_skip
186fi 190fi
187 191
188TMP_LIST_NETDEV="$(mktemp)" 192TMP_LIST_NETDEV="$(mktemp)"
diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh
index 1e428781a625..7514f93e1624 100755
--- a/tools/testing/selftests/net/pmtu.sh
+++ b/tools/testing/selftests/net/pmtu.sh
@@ -43,6 +43,9 @@
43# that MTU is properly calculated instead when MTU is not configured from 43# that MTU is properly calculated instead when MTU is not configured from
44# userspace 44# userspace
45 45
46# Kselftest framework requirement - SKIP code is 4.
47ksft_skip=4
48
46tests=" 49tests="
47 pmtu_vti6_exception vti6: PMTU exceptions 50 pmtu_vti6_exception vti6: PMTU exceptions
48 pmtu_vti4_exception vti4: PMTU exceptions 51 pmtu_vti4_exception vti4: PMTU exceptions
@@ -162,7 +165,7 @@ setup_xfrm6() {
162} 165}
163 166
164setup() { 167setup() {
165 [ "$(id -u)" -ne 0 ] && echo " need to run as root" && return 1 168 [ "$(id -u)" -ne 0 ] && echo " need to run as root" && return $ksft_skip
166 169
167 cleanup_done=0 170 cleanup_done=0
168 for arg do 171 for arg do
diff --git a/tools/testing/selftests/net/psock_tpacket.c b/tools/testing/selftests/net/psock_tpacket.c
index 7f6cd9fdacf3..7ec4fa4d55dc 100644
--- a/tools/testing/selftests/net/psock_tpacket.c
+++ b/tools/testing/selftests/net/psock_tpacket.c
@@ -60,6 +60,8 @@
60 60
61#include "psock_lib.h" 61#include "psock_lib.h"
62 62
63#include "../kselftest.h"
64
63#ifndef bug_on 65#ifndef bug_on
64# define bug_on(cond) assert(!(cond)) 66# define bug_on(cond) assert(!(cond))
65#endif 67#endif
@@ -825,7 +827,7 @@ static int test_tpacket(int version, int type)
825 fprintf(stderr, "test: skip %s %s since user and kernel " 827 fprintf(stderr, "test: skip %s %s since user and kernel "
826 "space have different bit width\n", 828 "space have different bit width\n",
827 tpacket_str[version], type_str[type]); 829 tpacket_str[version], type_str[type]);
828 return 0; 830 return KSFT_SKIP;
829 } 831 }
830 832
831 sock = pfsocket(version); 833 sock = pfsocket(version);
diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh
index e6f485235435..fb3767844e42 100755
--- a/tools/testing/selftests/net/rtnetlink.sh
+++ b/tools/testing/selftests/net/rtnetlink.sh
@@ -7,6 +7,9 @@
7devdummy="test-dummy0" 7devdummy="test-dummy0"
8ret=0 8ret=0
9 9
10# Kselftest framework requirement - SKIP code is 4.
11ksft_skip=4
12
10# set global exit status, but never reset nonzero one. 13# set global exit status, but never reset nonzero one.
11check_err() 14check_err()
12{ 15{
@@ -333,7 +336,7 @@ kci_test_vrf()
333 ip link show type vrf 2>/dev/null 336 ip link show type vrf 2>/dev/null
334 if [ $? -ne 0 ]; then 337 if [ $? -ne 0 ]; then
335 echo "SKIP: vrf: iproute2 too old" 338 echo "SKIP: vrf: iproute2 too old"
336 return 0 339 return $ksft_skip
337 fi 340 fi
338 341
339 ip link add "$vrfname" type vrf table 10 342 ip link add "$vrfname" type vrf table 10
@@ -409,7 +412,7 @@ kci_test_encap_fou()
409 ip fou help 2>&1 |grep -q 'Usage: ip fou' 412 ip fou help 2>&1 |grep -q 'Usage: ip fou'
410 if [ $? -ne 0 ];then 413 if [ $? -ne 0 ];then
411 echo "SKIP: fou: iproute2 too old" 414 echo "SKIP: fou: iproute2 too old"
412 return 1 415 return $ksft_skip
413 fi 416 fi
414 417
415 ip netns exec "$testns" ip fou add port 7777 ipproto 47 2>/dev/null 418 ip netns exec "$testns" ip fou add port 7777 ipproto 47 2>/dev/null
@@ -444,7 +447,7 @@ kci_test_encap()
444 ip netns add "$testns" 447 ip netns add "$testns"
445 if [ $? -ne 0 ]; then 448 if [ $? -ne 0 ]; then
446 echo "SKIP encap tests: cannot add net namespace $testns" 449 echo "SKIP encap tests: cannot add net namespace $testns"
447 return 1 450 return $ksft_skip
448 fi 451 fi
449 452
450 ip netns exec "$testns" ip link set lo up 453 ip netns exec "$testns" ip link set lo up
@@ -469,7 +472,7 @@ kci_test_macsec()
469 ip macsec help 2>&1 | grep -q "^Usage: ip macsec" 472 ip macsec help 2>&1 | grep -q "^Usage: ip macsec"
470 if [ $? -ne 0 ]; then 473 if [ $? -ne 0 ]; then
471 echo "SKIP: macsec: iproute2 too old" 474 echo "SKIP: macsec: iproute2 too old"
472 return 0 475 return $ksft_skip
473 fi 476 fi
474 477
475 ip link add link "$devdummy" "$msname" type macsec port 42 encrypt on 478 ip link add link "$devdummy" "$msname" type macsec port 42 encrypt on
@@ -511,14 +514,14 @@ kci_test_gretap()
511 ip netns add "$testns" 514 ip netns add "$testns"
512 if [ $? -ne 0 ]; then 515 if [ $? -ne 0 ]; then
513 echo "SKIP gretap tests: cannot add net namespace $testns" 516 echo "SKIP gretap tests: cannot add net namespace $testns"
514 return 1 517 return $ksft_skip
515 fi 518 fi
516 519
517 ip link help gretap 2>&1 | grep -q "^Usage:" 520 ip link help gretap 2>&1 | grep -q "^Usage:"
518 if [ $? -ne 0 ];then 521 if [ $? -ne 0 ];then
519 echo "SKIP: gretap: iproute2 too old" 522 echo "SKIP: gretap: iproute2 too old"
520 ip netns del "$testns" 523 ip netns del "$testns"
521 return 1 524 return $ksft_skip
522 fi 525 fi
523 526
524 # test native tunnel 527 # test native tunnel
@@ -561,14 +564,14 @@ kci_test_ip6gretap()
561 ip netns add "$testns" 564 ip netns add "$testns"
562 if [ $? -ne 0 ]; then 565 if [ $? -ne 0 ]; then
563 echo "SKIP ip6gretap tests: cannot add net namespace $testns" 566 echo "SKIP ip6gretap tests: cannot add net namespace $testns"
564 return 1 567 return $ksft_skip
565 fi 568 fi
566 569
567 ip link help ip6gretap 2>&1 | grep -q "^Usage:" 570 ip link help ip6gretap 2>&1 | grep -q "^Usage:"
568 if [ $? -ne 0 ];then 571 if [ $? -ne 0 ];then
569 echo "SKIP: ip6gretap: iproute2 too old" 572 echo "SKIP: ip6gretap: iproute2 too old"
570 ip netns del "$testns" 573 ip netns del "$testns"
571 return 1 574 return $ksft_skip
572 fi 575 fi
573 576
574 # test native tunnel 577 # test native tunnel
@@ -611,13 +614,13 @@ kci_test_erspan()
611 ip link help erspan 2>&1 | grep -q "^Usage:" 614 ip link help erspan 2>&1 | grep -q "^Usage:"
612 if [ $? -ne 0 ];then 615 if [ $? -ne 0 ];then
613 echo "SKIP: erspan: iproute2 too old" 616 echo "SKIP: erspan: iproute2 too old"
614 return 1 617 return $ksft_skip
615 fi 618 fi
616 619
617 ip netns add "$testns" 620 ip netns add "$testns"
618 if [ $? -ne 0 ]; then 621 if [ $? -ne 0 ]; then
619 echo "SKIP erspan tests: cannot add net namespace $testns" 622 echo "SKIP erspan tests: cannot add net namespace $testns"
620 return 1 623 return $ksft_skip
621 fi 624 fi
622 625
623 # test native tunnel erspan v1 626 # test native tunnel erspan v1
@@ -676,13 +679,13 @@ kci_test_ip6erspan()
676 ip link help ip6erspan 2>&1 | grep -q "^Usage:" 679 ip link help ip6erspan 2>&1 | grep -q "^Usage:"
677 if [ $? -ne 0 ];then 680 if [ $? -ne 0 ];then
678 echo "SKIP: ip6erspan: iproute2 too old" 681 echo "SKIP: ip6erspan: iproute2 too old"
679 return 1 682 return $ksft_skip
680 fi 683 fi
681 684
682 ip netns add "$testns" 685 ip netns add "$testns"
683 if [ $? -ne 0 ]; then 686 if [ $? -ne 0 ]; then
684 echo "SKIP ip6erspan tests: cannot add net namespace $testns" 687 echo "SKIP ip6erspan tests: cannot add net namespace $testns"
685 return 1 688 return $ksft_skip
686 fi 689 fi
687 690
688 # test native tunnel ip6erspan v1 691 # test native tunnel ip6erspan v1
@@ -762,14 +765,14 @@ kci_test_rtnl()
762#check for needed privileges 765#check for needed privileges
763if [ "$(id -u)" -ne 0 ];then 766if [ "$(id -u)" -ne 0 ];then
764 echo "SKIP: Need root privileges" 767 echo "SKIP: Need root privileges"
765 exit 0 768 exit $ksft_skip
766fi 769fi
767 770
768for x in ip tc;do 771for x in ip tc;do
769 $x -Version 2>/dev/null >/dev/null 772 $x -Version 2>/dev/null >/dev/null
770 if [ $? -ne 0 ];then 773 if [ $? -ne 0 ];then
771 echo "SKIP: Could not run test without the $x tool" 774 echo "SKIP: Could not run test without the $x tool"
772 exit 0 775 exit $ksft_skip
773 fi 776 fi
774done 777done
775 778
diff --git a/tools/testing/selftests/rtc/.gitignore b/tools/testing/selftests/rtc/.gitignore
new file mode 100644
index 000000000000..d0ad44f6294a
--- /dev/null
+++ b/tools/testing/selftests/rtc/.gitignore
@@ -0,0 +1,2 @@
1rtctest
2setdate
diff --git a/tools/testing/selftests/rtc/Makefile b/tools/testing/selftests/rtc/Makefile
new file mode 100644
index 000000000000..de9c8566672a
--- /dev/null
+++ b/tools/testing/selftests/rtc/Makefile
@@ -0,0 +1,9 @@
1# SPDX-License-Identifier: GPL-2.0
2CFLAGS += -O3 -Wl,-no-as-needed -Wall
3LDFLAGS += -lrt -lpthread -lm
4
5TEST_GEN_PROGS = rtctest
6
7TEST_GEN_PROGS_EXTENDED = setdate
8
9include ../lib.mk
diff --git a/tools/testing/selftests/rtc/rtctest.c b/tools/testing/selftests/rtc/rtctest.c
new file mode 100644
index 000000000000..e20b017e7073
--- /dev/null
+++ b/tools/testing/selftests/rtc/rtctest.c
@@ -0,0 +1,238 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Real Time Clock Driver Test Program
4 *
5 * Copyright (c) 2018 Alexandre Belloni <alexandre.belloni@bootlin.com>
6 */
7
8#include <errno.h>
9#include <fcntl.h>
10#include <linux/rtc.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <sys/ioctl.h>
14#include <sys/time.h>
15#include <sys/types.h>
16#include <time.h>
17#include <unistd.h>
18
19#include "../kselftest_harness.h"
20
21#define NUM_UIE 3
22#define ALARM_DELTA 3
23
24static char *rtc_file = "/dev/rtc0";
25
26FIXTURE(rtc) {
27 int fd;
28};
29
30FIXTURE_SETUP(rtc) {
31 self->fd = open(rtc_file, O_RDONLY);
32 ASSERT_NE(-1, self->fd);
33}
34
35FIXTURE_TEARDOWN(rtc) {
36 close(self->fd);
37}
38
39TEST_F(rtc, date_read) {
40 int rc;
41 struct rtc_time rtc_tm;
42
43 /* Read the RTC time/date */
44 rc = ioctl(self->fd, RTC_RD_TIME, &rtc_tm);
45 ASSERT_NE(-1, rc);
46
47 TH_LOG("Current RTC date/time is %02d/%02d/%02d %02d:%02d:%02d.",
48 rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,
49 rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
50}
51
52TEST_F(rtc, uie_read) {
53 int i, rc, irq = 0;
54 unsigned long data;
55
56 /* Turn on update interrupts */
57 rc = ioctl(self->fd, RTC_UIE_ON, 0);
58 if (rc == -1) {
59 ASSERT_EQ(EINVAL, errno);
60 TH_LOG("skip update IRQs not supported.");
61 return;
62 }
63
64 for (i = 0; i < NUM_UIE; i++) {
65 /* This read will block */
66 rc = read(self->fd, &data, sizeof(data));
67 ASSERT_NE(-1, rc);
68 irq++;
69 }
70
71 EXPECT_EQ(NUM_UIE, irq);
72
73 rc = ioctl(self->fd, RTC_UIE_OFF, 0);
74 ASSERT_NE(-1, rc);
75}
76
77TEST_F(rtc, uie_select) {
78 int i, rc, irq = 0;
79 unsigned long data;
80
81 /* Turn on update interrupts */
82 rc = ioctl(self->fd, RTC_UIE_ON, 0);
83 if (rc == -1) {
84 ASSERT_EQ(EINVAL, errno);
85 TH_LOG("skip update IRQs not supported.");
86 return;
87 }
88
89 for (i = 0; i < NUM_UIE; i++) {
90 struct timeval tv = { .tv_sec = 2 };
91 fd_set readfds;
92
93 FD_ZERO(&readfds);
94 FD_SET(self->fd, &readfds);
95 /* The select will wait until an RTC interrupt happens. */
96 rc = select(self->fd + 1, &readfds, NULL, NULL, &tv);
97 ASSERT_NE(-1, rc);
98 ASSERT_NE(0, rc);
99
100 /* This read won't block */
101 rc = read(self->fd, &data, sizeof(unsigned long));
102 ASSERT_NE(-1, rc);
103 irq++;
104 }
105
106 EXPECT_EQ(NUM_UIE, irq);
107
108 rc = ioctl(self->fd, RTC_UIE_OFF, 0);
109 ASSERT_NE(-1, rc);
110}
111
112TEST_F(rtc, alarm_alm_set) {
113 struct timeval tv = { .tv_sec = ALARM_DELTA + 2 };
114 unsigned long data;
115 struct rtc_time tm;
116 fd_set readfds;
117 time_t secs, new;
118 int rc;
119
120 rc = ioctl(self->fd, RTC_RD_TIME, &tm);
121 ASSERT_NE(-1, rc);
122
123 secs = timegm((struct tm *)&tm) + ALARM_DELTA;
124 gmtime_r(&secs, (struct tm *)&tm);
125
126 rc = ioctl(self->fd, RTC_ALM_SET, &tm);
127 if (rc == -1) {
128 ASSERT_EQ(EINVAL, errno);
129 TH_LOG("skip alarms are not supported.");
130 return;
131 }
132
133 rc = ioctl(self->fd, RTC_ALM_READ, &tm);
134 ASSERT_NE(-1, rc);
135
136 TH_LOG("Alarm time now set to %02d:%02d:%02d.",
137 tm.tm_hour, tm.tm_min, tm.tm_sec);
138
139 /* Enable alarm interrupts */
140 rc = ioctl(self->fd, RTC_AIE_ON, 0);
141 ASSERT_NE(-1, rc);
142
143 FD_ZERO(&readfds);
144 FD_SET(self->fd, &readfds);
145
146 rc = select(self->fd + 1, &readfds, NULL, NULL, &tv);
147 ASSERT_NE(-1, rc);
148 EXPECT_NE(0, rc);
149
150 /* Disable alarm interrupts */
151 rc = ioctl(self->fd, RTC_AIE_OFF, 0);
152 ASSERT_NE(-1, rc);
153
154 if (rc == 0)
155 return;
156
157 rc = read(self->fd, &data, sizeof(unsigned long));
158 ASSERT_NE(-1, rc);
159 TH_LOG("data: %lx", data);
160
161 rc = ioctl(self->fd, RTC_RD_TIME, &tm);
162 ASSERT_NE(-1, rc);
163
164 new = timegm((struct tm *)&tm);
165 ASSERT_EQ(new, secs);
166}
167
168TEST_F(rtc, alarm_wkalm_set) {
169 struct timeval tv = { .tv_sec = ALARM_DELTA + 2 };
170 struct rtc_wkalrm alarm = { 0 };
171 struct rtc_time tm;
172 unsigned long data;
173 fd_set readfds;
174 time_t secs, new;
175 int rc;
176
177 rc = ioctl(self->fd, RTC_RD_TIME, &alarm.time);
178 ASSERT_NE(-1, rc);
179
180 secs = timegm((struct tm *)&alarm.time) + ALARM_DELTA;
181 gmtime_r(&secs, (struct tm *)&alarm.time);
182
183 alarm.enabled = 1;
184
185 rc = ioctl(self->fd, RTC_WKALM_SET, &alarm);
186 if (rc == -1) {
187 ASSERT_EQ(EINVAL, errno);
188 TH_LOG("skip alarms are not supported.");
189 return;
190 }
191
192 rc = ioctl(self->fd, RTC_WKALM_RD, &alarm);
193 ASSERT_NE(-1, rc);
194
195 TH_LOG("Alarm time now set to %02d/%02d/%02d %02d:%02d:%02d.",
196 alarm.time.tm_mday, alarm.time.tm_mon + 1,
197 alarm.time.tm_year + 1900, alarm.time.tm_hour,
198 alarm.time.tm_min, alarm.time.tm_sec);
199
200 FD_ZERO(&readfds);
201 FD_SET(self->fd, &readfds);
202
203 rc = select(self->fd + 1, &readfds, NULL, NULL, &tv);
204 ASSERT_NE(-1, rc);
205 EXPECT_NE(0, rc);
206
207 rc = read(self->fd, &data, sizeof(unsigned long));
208 ASSERT_NE(-1, rc);
209
210 rc = ioctl(self->fd, RTC_RD_TIME, &tm);
211 ASSERT_NE(-1, rc);
212
213 new = timegm((struct tm *)&tm);
214 ASSERT_EQ(new, secs);
215}
216
217static void __attribute__((constructor))
218__constructor_order_last(void)
219{
220 if (!__constructor_order)
221 __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD;
222}
223
224int main(int argc, char **argv)
225{
226 switch (argc) {
227 case 2:
228 rtc_file = argv[1];
229 /* FALLTHROUGH */
230 case 1:
231 break;
232 default:
233 fprintf(stderr, "usage: %s [rtcdev]\n", argv[0]);
234 return 1;
235 }
236
237 return test_harness_run(argc, argv);
238}
diff --git a/tools/testing/selftests/timers/rtctest_setdate.c b/tools/testing/selftests/rtc/setdate.c
index 2cb78489eca4..2cb78489eca4 100644
--- a/tools/testing/selftests/timers/rtctest_setdate.c
+++ b/tools/testing/selftests/rtc/setdate.c
diff --git a/tools/testing/selftests/timers/.gitignore b/tools/testing/selftests/timers/.gitignore
index 2c8ac8416299..32a9eadb2d4e 100644
--- a/tools/testing/selftests/timers/.gitignore
+++ b/tools/testing/selftests/timers/.gitignore
@@ -9,7 +9,7 @@ nanosleep
9nsleep-lat 9nsleep-lat
10posix_timers 10posix_timers
11raw_skew 11raw_skew
12rtctest 12rtcpie
13set-2038 13set-2038
14set-tai 14set-tai
15set-timer-lat 15set-timer-lat
@@ -19,4 +19,3 @@ valid-adjtimex
19adjtick 19adjtick
20set-tz 20set-tz
21freq-step 21freq-step
22rtctest_setdate
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
index 3496680981f2..c02683cfb6c9 100644
--- a/tools/testing/selftests/timers/Makefile
+++ b/tools/testing/selftests/timers/Makefile
@@ -5,13 +5,13 @@ LDFLAGS += -lrt -lpthread -lm
5# these are all "safe" tests that don't modify 5# these are all "safe" tests that don't modify
6# system time or require escalated privileges 6# system time or require escalated privileges
7TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \ 7TEST_GEN_PROGS = posix_timers nanosleep nsleep-lat set-timer-lat mqueue-lat \
8 inconsistency-check raw_skew threadtest rtctest 8 inconsistency-check raw_skew threadtest rtcpie
9 9
10DESTRUCTIVE_TESTS = alarmtimer-suspend valid-adjtimex adjtick change_skew \ 10DESTRUCTIVE_TESTS = alarmtimer-suspend valid-adjtimex adjtick change_skew \
11 skew_consistency clocksource-switch freq-step leap-a-day \ 11 skew_consistency clocksource-switch freq-step leap-a-day \
12 leapcrash set-tai set-2038 set-tz 12 leapcrash set-tai set-2038 set-tz
13 13
14TEST_GEN_PROGS_EXTENDED = $(DESTRUCTIVE_TESTS) rtctest_setdate 14TEST_GEN_PROGS_EXTENDED = $(DESTRUCTIVE_TESTS)
15 15
16 16
17include ../lib.mk 17include ../lib.mk
diff --git a/tools/testing/selftests/timers/rtcpie.c b/tools/testing/selftests/timers/rtcpie.c
new file mode 100644
index 000000000000..47b5bad1b393
--- /dev/null
+++ b/tools/testing/selftests/timers/rtcpie.c
@@ -0,0 +1,134 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Real Time Clock Periodic Interrupt test program
4 *
5 * Since commit 6610e0893b8bc ("RTC: Rework RTC code to use timerqueue for
6 * events"), PIE are completely handled using hrtimers, without actually using
7 * any underlying hardware RTC.
8 *
9 */
10
11#include <stdio.h>
12#include <linux/rtc.h>
13#include <sys/ioctl.h>
14#include <sys/time.h>
15#include <sys/types.h>
16#include <fcntl.h>
17#include <unistd.h>
18#include <stdlib.h>
19#include <errno.h>
20
21/*
22 * This expects the new RTC class driver framework, working with
23 * clocks that will often not be clones of what the PC-AT had.
24 * Use the command line to specify another RTC if you need one.
25 */
26static const char default_rtc[] = "/dev/rtc0";
27
28int main(int argc, char **argv)
29{
30 int i, fd, retval, irqcount = 0;
31 unsigned long tmp, data, old_pie_rate;
32 const char *rtc = default_rtc;
33 struct timeval start, end, diff;
34
35 switch (argc) {
36 case 2:
37 rtc = argv[1];
38 /* FALLTHROUGH */
39 case 1:
40 break;
41 default:
42 fprintf(stderr, "usage: rtctest [rtcdev] [d]\n");
43 return 1;
44 }
45
46 fd = open(rtc, O_RDONLY);
47
48 if (fd == -1) {
49 perror(rtc);
50 exit(errno);
51 }
52
53 /* Read periodic IRQ rate */
54 retval = ioctl(fd, RTC_IRQP_READ, &old_pie_rate);
55 if (retval == -1) {
56 /* not all RTCs support periodic IRQs */
57 if (errno == EINVAL) {
58 fprintf(stderr, "\nNo periodic IRQ support\n");
59 goto done;
60 }
61 perror("RTC_IRQP_READ ioctl");
62 exit(errno);
63 }
64 fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", old_pie_rate);
65
66 fprintf(stderr, "Counting 20 interrupts at:");
67 fflush(stderr);
68
69 /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */
70 for (tmp=2; tmp<=64; tmp*=2) {
71
72 retval = ioctl(fd, RTC_IRQP_SET, tmp);
73 if (retval == -1) {
74 /* not all RTCs can change their periodic IRQ rate */
75 if (errno == EINVAL) {
76 fprintf(stderr,
77 "\n...Periodic IRQ rate is fixed\n");
78 goto done;
79 }
80 perror("RTC_IRQP_SET ioctl");
81 exit(errno);
82 }
83
84 fprintf(stderr, "\n%ldHz:\t", tmp);
85 fflush(stderr);
86
87 /* Enable periodic interrupts */
88 retval = ioctl(fd, RTC_PIE_ON, 0);
89 if (retval == -1) {
90 perror("RTC_PIE_ON ioctl");
91 exit(errno);
92 }
93
94 for (i=1; i<21; i++) {
95 gettimeofday(&start, NULL);
96 /* This blocks */
97 retval = read(fd, &data, sizeof(unsigned long));
98 if (retval == -1) {
99 perror("read");
100 exit(errno);
101 }
102 gettimeofday(&end, NULL);
103 timersub(&end, &start, &diff);
104 if (diff.tv_sec > 0 ||
105 diff.tv_usec > ((1000000L / tmp) * 1.10)) {
106 fprintf(stderr, "\nPIE delta error: %ld.%06ld should be close to 0.%06ld\n",
107 diff.tv_sec, diff.tv_usec,
108 (1000000L / tmp));
109 fflush(stdout);
110 exit(-1);
111 }
112
113 fprintf(stderr, " %d",i);
114 fflush(stderr);
115 irqcount++;
116 }
117
118 /* Disable periodic interrupts */
119 retval = ioctl(fd, RTC_PIE_OFF, 0);
120 if (retval == -1) {
121 perror("RTC_PIE_OFF ioctl");
122 exit(errno);
123 }
124 }
125
126done:
127 ioctl(fd, RTC_IRQP_SET, old_pie_rate);
128
129 fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n");
130
131 close(fd);
132
133 return 0;
134}
diff --git a/tools/testing/selftests/timers/rtctest.c b/tools/testing/selftests/timers/rtctest.c
deleted file mode 100644
index 411eff625e66..000000000000
--- a/tools/testing/selftests/timers/rtctest.c
+++ /dev/null
@@ -1,403 +0,0 @@
1/*
2 * Real Time Clock Driver Test/Example Program
3 *
4 * Compile with:
5 * gcc -s -Wall -Wstrict-prototypes rtctest.c -o rtctest
6 *
7 * Copyright (C) 1996, Paul Gortmaker.
8 *
9 * Released under the GNU General Public License, version 2,
10 * included herein by reference.
11 *
12 */
13
14#include <stdio.h>
15#include <linux/rtc.h>
16#include <sys/ioctl.h>
17#include <sys/time.h>
18#include <sys/types.h>
19#include <fcntl.h>
20#include <unistd.h>
21#include <stdlib.h>
22#include <errno.h>
23
24#ifndef ARRAY_SIZE
25# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
26#endif
27
28/*
29 * This expects the new RTC class driver framework, working with
30 * clocks that will often not be clones of what the PC-AT had.
31 * Use the command line to specify another RTC if you need one.
32 */
33static const char default_rtc[] = "/dev/rtc0";
34
35static struct rtc_time cutoff_dates[] = {
36 {
37 .tm_year = 70, /* 1970 -1900 */
38 .tm_mday = 1,
39 },
40 /* signed time_t 19/01/2038 3:14:08 */
41 {
42 .tm_year = 138,
43 .tm_mday = 19,
44 },
45 {
46 .tm_year = 138,
47 .tm_mday = 20,
48 },
49 {
50 .tm_year = 199, /* 2099 -1900 */
51 .tm_mday = 1,
52 },
53 {
54 .tm_year = 200, /* 2100 -1900 */
55 .tm_mday = 1,
56 },
57 /* unsigned time_t 07/02/2106 7:28:15*/
58 {
59 .tm_year = 205,
60 .tm_mon = 1,
61 .tm_mday = 7,
62 },
63 {
64 .tm_year = 206,
65 .tm_mon = 1,
66 .tm_mday = 8,
67 },
68 /* signed time on 64bit in nanoseconds 12/04/2262 01:47:16*/
69 {
70 .tm_year = 362,
71 .tm_mon = 3,
72 .tm_mday = 12,
73 },
74 {
75 .tm_year = 362, /* 2262 -1900 */
76 .tm_mon = 3,
77 .tm_mday = 13,
78 },
79};
80
81static int compare_dates(struct rtc_time *a, struct rtc_time *b)
82{
83 if (a->tm_year != b->tm_year ||
84 a->tm_mon != b->tm_mon ||
85 a->tm_mday != b->tm_mday ||
86 a->tm_hour != b->tm_hour ||
87 a->tm_min != b->tm_min ||
88 ((b->tm_sec - a->tm_sec) > 1))
89 return 1;
90
91 return 0;
92}
93
94int main(int argc, char **argv)
95{
96 int i, fd, retval, irqcount = 0, dangerous = 0;
97 unsigned long tmp, data;
98 struct rtc_time rtc_tm;
99 const char *rtc = default_rtc;
100 struct timeval start, end, diff;
101
102 switch (argc) {
103 case 3:
104 if (*argv[2] == 'd')
105 dangerous = 1;
106 case 2:
107 rtc = argv[1];
108 /* FALLTHROUGH */
109 case 1:
110 break;
111 default:
112 fprintf(stderr, "usage: rtctest [rtcdev] [d]\n");
113 return 1;
114 }
115
116 fd = open(rtc, O_RDONLY);
117
118 if (fd == -1) {
119 perror(rtc);
120 exit(errno);
121 }
122
123 fprintf(stderr, "\n\t\t\tRTC Driver Test Example.\n\n");
124
125 /* Turn on update interrupts (one per second) */
126 retval = ioctl(fd, RTC_UIE_ON, 0);
127 if (retval == -1) {
128 if (errno == EINVAL) {
129 fprintf(stderr,
130 "\n...Update IRQs not supported.\n");
131 goto test_READ;
132 }
133 perror("RTC_UIE_ON ioctl");
134 exit(errno);
135 }
136
137 fprintf(stderr, "Counting 5 update (1/sec) interrupts from reading %s:",
138 rtc);
139 fflush(stderr);
140 for (i=1; i<6; i++) {
141 /* This read will block */
142 retval = read(fd, &data, sizeof(unsigned long));
143 if (retval == -1) {
144 perror("read");
145 exit(errno);
146 }
147 fprintf(stderr, " %d",i);
148 fflush(stderr);
149 irqcount++;
150 }
151
152 fprintf(stderr, "\nAgain, from using select(2) on /dev/rtc:");
153 fflush(stderr);
154 for (i=1; i<6; i++) {
155 struct timeval tv = {5, 0}; /* 5 second timeout on select */
156 fd_set readfds;
157
158 FD_ZERO(&readfds);
159 FD_SET(fd, &readfds);
160 /* The select will wait until an RTC interrupt happens. */
161 retval = select(fd+1, &readfds, NULL, NULL, &tv);
162 if (retval == -1) {
163 perror("select");
164 exit(errno);
165 }
166 /* This read won't block unlike the select-less case above. */
167 retval = read(fd, &data, sizeof(unsigned long));
168 if (retval == -1) {
169 perror("read");
170 exit(errno);
171 }
172 fprintf(stderr, " %d",i);
173 fflush(stderr);
174 irqcount++;
175 }
176
177 /* Turn off update interrupts */
178 retval = ioctl(fd, RTC_UIE_OFF, 0);
179 if (retval == -1) {
180 perror("RTC_UIE_OFF ioctl");
181 exit(errno);
182 }
183
184test_READ:
185 /* Read the RTC time/date */
186 retval = ioctl(fd, RTC_RD_TIME, &rtc_tm);
187 if (retval == -1) {
188 perror("RTC_RD_TIME ioctl");
189 exit(errno);
190 }
191
192 fprintf(stderr, "\n\nCurrent RTC date/time is %d-%d-%d, %02d:%02d:%02d.\n",
193 rtc_tm.tm_mday, rtc_tm.tm_mon + 1, rtc_tm.tm_year + 1900,
194 rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
195
196 /* Set the alarm to 5 sec in the future, and check for rollover */
197 rtc_tm.tm_sec += 5;
198 if (rtc_tm.tm_sec >= 60) {
199 rtc_tm.tm_sec %= 60;
200 rtc_tm.tm_min++;
201 }
202 if (rtc_tm.tm_min == 60) {
203 rtc_tm.tm_min = 0;
204 rtc_tm.tm_hour++;
205 }
206 if (rtc_tm.tm_hour == 24)
207 rtc_tm.tm_hour = 0;
208
209 retval = ioctl(fd, RTC_ALM_SET, &rtc_tm);
210 if (retval == -1) {
211 if (errno == EINVAL) {
212 fprintf(stderr,
213 "\n...Alarm IRQs not supported.\n");
214 goto test_PIE;
215 }
216
217 perror("RTC_ALM_SET ioctl");
218 exit(errno);
219 }
220
221 /* Read the current alarm settings */
222 retval = ioctl(fd, RTC_ALM_READ, &rtc_tm);
223 if (retval == -1) {
224 if (errno == EINVAL) {
225 fprintf(stderr,
226 "\n...EINVAL reading current alarm setting.\n");
227 goto test_PIE;
228 }
229 perror("RTC_ALM_READ ioctl");
230 exit(errno);
231 }
232
233 fprintf(stderr, "Alarm time now set to %02d:%02d:%02d.\n",
234 rtc_tm.tm_hour, rtc_tm.tm_min, rtc_tm.tm_sec);
235
236 /* Enable alarm interrupts */
237 retval = ioctl(fd, RTC_AIE_ON, 0);
238 if (retval == -1) {
239 if (errno == EINVAL || errno == EIO) {
240 fprintf(stderr,
241 "\n...Alarm IRQs not supported.\n");
242 goto test_PIE;
243 }
244
245 perror("RTC_AIE_ON ioctl");
246 exit(errno);
247 }
248
249 fprintf(stderr, "Waiting 5 seconds for alarm...");
250 fflush(stderr);
251 /* This blocks until the alarm ring causes an interrupt */
252 retval = read(fd, &data, sizeof(unsigned long));
253 if (retval == -1) {
254 perror("read");
255 exit(errno);
256 }
257 irqcount++;
258 fprintf(stderr, " okay. Alarm rang.\n");
259
260 /* Disable alarm interrupts */
261 retval = ioctl(fd, RTC_AIE_OFF, 0);
262 if (retval == -1) {
263 perror("RTC_AIE_OFF ioctl");
264 exit(errno);
265 }
266
267test_PIE:
268 /* Read periodic IRQ rate */
269 retval = ioctl(fd, RTC_IRQP_READ, &tmp);
270 if (retval == -1) {
271 /* not all RTCs support periodic IRQs */
272 if (errno == EINVAL) {
273 fprintf(stderr, "\nNo periodic IRQ support\n");
274 goto test_DATE;
275 }
276 perror("RTC_IRQP_READ ioctl");
277 exit(errno);
278 }
279 fprintf(stderr, "\nPeriodic IRQ rate is %ldHz.\n", tmp);
280
281 fprintf(stderr, "Counting 20 interrupts at:");
282 fflush(stderr);
283
284 /* The frequencies 128Hz, 256Hz, ... 8192Hz are only allowed for root. */
285 for (tmp=2; tmp<=64; tmp*=2) {
286
287 retval = ioctl(fd, RTC_IRQP_SET, tmp);
288 if (retval == -1) {
289 /* not all RTCs can change their periodic IRQ rate */
290 if (errno == EINVAL) {
291 fprintf(stderr,
292 "\n...Periodic IRQ rate is fixed\n");
293 goto test_DATE;
294 }
295 perror("RTC_IRQP_SET ioctl");
296 exit(errno);
297 }
298
299 fprintf(stderr, "\n%ldHz:\t", tmp);
300 fflush(stderr);
301
302 /* Enable periodic interrupts */
303 retval = ioctl(fd, RTC_PIE_ON, 0);
304 if (retval == -1) {
305 perror("RTC_PIE_ON ioctl");
306 exit(errno);
307 }
308
309 for (i=1; i<21; i++) {
310 gettimeofday(&start, NULL);
311 /* This blocks */
312 retval = read(fd, &data, sizeof(unsigned long));
313 if (retval == -1) {
314 perror("read");
315 exit(errno);
316 }
317 gettimeofday(&end, NULL);
318 timersub(&end, &start, &diff);
319 if (diff.tv_sec > 0 ||
320 diff.tv_usec > ((1000000L / tmp) * 1.10)) {
321 fprintf(stderr, "\nPIE delta error: %ld.%06ld should be close to 0.%06ld\n",
322 diff.tv_sec, diff.tv_usec,
323 (1000000L / tmp));
324 fflush(stdout);
325 exit(-1);
326 }
327
328 fprintf(stderr, " %d",i);
329 fflush(stderr);
330 irqcount++;
331 }
332
333 /* Disable periodic interrupts */
334 retval = ioctl(fd, RTC_PIE_OFF, 0);
335 if (retval == -1) {
336 perror("RTC_PIE_OFF ioctl");
337 exit(errno);
338 }
339 }
340
341test_DATE:
342 if (!dangerous)
343 goto done;
344
345 fprintf(stderr, "\nTesting problematic dates\n");
346
347 for (i = 0; i < ARRAY_SIZE(cutoff_dates); i++) {
348 struct rtc_time current;
349
350 /* Write the new date in RTC */
351 retval = ioctl(fd, RTC_SET_TIME, &cutoff_dates[i]);
352 if (retval == -1) {
353 perror("RTC_SET_TIME ioctl");
354 close(fd);
355 exit(errno);
356 }
357
358 /* Read back */
359 retval = ioctl(fd, RTC_RD_TIME, &current);
360 if (retval == -1) {
361 perror("RTC_RD_TIME ioctl");
362 exit(errno);
363 }
364
365 if(compare_dates(&cutoff_dates[i], &current)) {
366 fprintf(stderr,"Setting date %d failed\n",
367 cutoff_dates[i].tm_year + 1900);
368 goto done;
369 }
370
371 cutoff_dates[i].tm_sec += 5;
372
373 /* Write the new alarm in RTC */
374 retval = ioctl(fd, RTC_ALM_SET, &cutoff_dates[i]);
375 if (retval == -1) {
376 perror("RTC_ALM_SET ioctl");
377 close(fd);
378 exit(errno);
379 }
380
381 /* Read back */
382 retval = ioctl(fd, RTC_ALM_READ, &current);
383 if (retval == -1) {
384 perror("RTC_ALM_READ ioctl");
385 exit(errno);
386 }
387
388 if(compare_dates(&cutoff_dates[i], &current)) {
389 fprintf(stderr,"Setting alarm %d failed\n",
390 cutoff_dates[i].tm_year + 1900);
391 goto done;
392 }
393
394 fprintf(stderr, "Setting year %d is OK \n",
395 cutoff_dates[i].tm_year + 1900);
396 }
397done:
398 fprintf(stderr, "\n\n\t\t\t *** Test complete ***\n");
399
400 close(fd);
401
402 return 0;
403}
diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index 39f66bc29b82..186520198de7 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -8,6 +8,7 @@ include ../lib.mk
8UNAME_M := $(shell uname -m) 8UNAME_M := $(shell uname -m)
9CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32) 9CAN_BUILD_I386 := $(shell ./check_cc.sh $(CC) trivial_32bit_program.c -m32)
10CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c) 10CAN_BUILD_X86_64 := $(shell ./check_cc.sh $(CC) trivial_64bit_program.c)
11CAN_BUILD_WITH_NOPIE := $(shell ./check_cc.sh $(CC) trivial_program.c -no-pie)
11 12
12TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \ 13TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \
13 check_initial_reg_state sigreturn iopl mpx-mini-test ioperm \ 14 check_initial_reg_state sigreturn iopl mpx-mini-test ioperm \
@@ -31,7 +32,12 @@ BINARIES_64 := $(TARGETS_C_64BIT_ALL:%=%_64)
31BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32)) 32BINARIES_32 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_32))
32BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64)) 33BINARIES_64 := $(patsubst %,$(OUTPUT)/%,$(BINARIES_64))
33 34
34CFLAGS := -O2 -g -std=gnu99 -pthread -Wall -no-pie 35CFLAGS := -O2 -g -std=gnu99 -pthread -Wall
36
37# call32_from_64 in thunks.S uses absolute addresses.
38ifeq ($(CAN_BUILD_WITH_NOPIE),1)
39CFLAGS += -no-pie
40endif
35 41
36define gen-target-rule-32 42define gen-target-rule-32
37$(1) $(1)_32: $(OUTPUT)/$(1)_32 43$(1) $(1)_32: $(OUTPUT)/$(1)_32
diff --git a/tools/testing/selftests/x86/trivial_program.c b/tools/testing/selftests/x86/trivial_program.c
new file mode 100644
index 000000000000..46a447163b93
--- /dev/null
+++ b/tools/testing/selftests/x86/trivial_program.c
@@ -0,0 +1,10 @@
1/* Trivial program to check that compilation with certain flags is working. */
2
3#include <stdio.h>
4
5int
6main(void)
7{
8 puts("");
9 return 0;
10}