Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'linux-kselftest-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull kselftest updates from Shuah Khan:
"This consists of:

- Several fixes from Masami Hiramatsu to improve coverage for lib and
sysctl tests.

- Clean up to vdso test and a new test for getcpu() from Mark Brown.

- Add new gen_tar selftests Makefile target generate selftest package
running "make gen_tar" in selftests directory from Veronika
Kabatova.

- Other miscellaneous fixes to timens, exec, tpm2 tests"

* tag 'linux-kselftest-5.8-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
selftests/sysctl: Make sysctl test driver as a module
selftests/sysctl: Fix to load test_sysctl module
lib: Make test_sysctl initialized as module
lib: Make prime number generator independently selectable
selftests/ftrace: Return unsupported if no error_log file
selftests/ftrace: Use printf for backslash included command
selftests/timens: handle a case when alarm clocks are not supported
Kernel selftests: Add check if TPM devices are supported
selftests: vdso: Add a selftest for vDSO getcpu()
selftests: vdso: Use a header file to prototype parse_vdso API
selftests: vdso: Rename vdso_test to vdso_test_gettimeofday
selftests/exec: Verify execve of non-regular files fail
selftests: introduce gen_tar Makefile target

+196 -57
+23
Documentation/dev-tools/kselftest.rst
··· 151 151 $ cd kselftest 152 152 $ ./run_kselftest.sh 153 153 154 + Packaging selftests 155 + =================== 156 + 157 + In some cases packaging is desired, such as when tests need to run on a 158 + different system. To package selftests, run:: 159 + 160 + $ make -C tools/testing/selftests gen_tar 161 + 162 + This generates a tarball in the `INSTALL_PATH/kselftest-packages` directory. By 163 + default, `.gz` format is used. The tar format can be overridden by specifying 164 + a `FORMAT` make variable. Any value recognized by `tar's auto-compress`_ option 165 + is supported, such as:: 166 + 167 + $ make -C tools/testing/selftests gen_tar FORMAT=.xz 168 + 169 + `make gen_tar` invokes `make install` so you can use it to package a subset of 170 + tests by using variables specified in `Running a subset of selftests`_ 171 + section:: 172 + 173 + $ make -C tools/testing/selftests gen_tar TARGETS="bpf" FORMAT=.xz 174 + 175 + .. _tar's auto-compress: https://www.gnu.org/software/tar/manual/html_node/gzip.html#auto_002dcompress 176 + 154 177 Contributing new tests 155 178 ====================== 156 179
+6 -1
lib/math/Kconfig
··· 6 6 calculations are in fixed point. Module will be called cordic. 7 7 8 8 config PRIME_NUMBERS 9 - tristate 9 + tristate "Simple prime number generator for testing" 10 + help 11 + This option provides a simple prime number generator for test 12 + modules. 13 + 14 + If unsure, say N. 10 15 11 16 config RATIONAL 12 17 bool
+1 -1
lib/test_sysctl.c
··· 162 162 } 163 163 return 0; 164 164 } 165 - late_initcall(test_sysctl_init); 165 + module_init(test_sysctl_init); 166 166 167 167 static void __exit test_sysctl_exit(void) 168 168 {
+8 -1
tools/testing/selftests/Makefile
··· 249 249 $(error Error: set INSTALL_PATH to use install) 250 250 endif 251 251 252 + FORMAT ?= .gz 253 + TAR_PATH = $(abspath ${INSTALL_PATH}/kselftest-packages/kselftest.tar${FORMAT}) 254 + gen_tar: install 255 + @mkdir -p ${INSTALL_PATH}/kselftest-packages/ 256 + @tar caf ${TAR_PATH} --exclude=kselftest-packages -C ${INSTALL_PATH} . 257 + @echo "Created ${TAR_PATH}" 258 + 252 259 clean: 253 260 @for TARGET in $(TARGETS); do \ 254 261 BUILD_TARGET=$$BUILD/$$TARGET; \ 255 262 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\ 256 263 done; 257 264 258 - .PHONY: khdr all run_tests hotplug run_hotplug clean_hotplug run_pstore_crash install clean 265 + .PHONY: khdr all run_tests hotplug run_hotplug clean_hotplug run_pstore_crash install clean gen_tar
+1
tools/testing/selftests/exec/.gitignore
··· 9 9 execveat.denatured 10 10 /recursion-depth 11 11 xxxxxxxx* 12 + pipe
+1 -1
tools/testing/selftests/exec/Makefile
··· 5 5 6 6 TEST_PROGS := binfmt_script 7 7 TEST_GEN_PROGS := execveat 8 - TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir 8 + TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir pipe 9 9 # Makefile is a run-time dependency, since it's accessed by the execveat test 10 10 TEST_FILES := Makefile 11 11
+8
tools/testing/selftests/exec/execveat.c
··· 5 5 * Selftests for execveat(2). 6 6 */ 7 7 8 + #ifndef _GNU_SOURCE 8 9 #define _GNU_SOURCE /* to get O_PATH, AT_EMPTY_PATH */ 10 + #endif 9 11 #include <sys/sendfile.h> 10 12 #include <sys/stat.h> 11 13 #include <sys/syscall.h> ··· 313 311 fail += check_execveat_fail(AT_FDCWD, fullname_symlink, 314 312 AT_SYMLINK_NOFOLLOW, ELOOP); 315 313 314 + /* Non-regular file failure */ 315 + fail += check_execveat_fail(dot_dfd, "pipe", 0, EACCES); 316 + unlink("pipe"); 317 + 316 318 /* Shell script wrapping executable file: */ 317 319 /* dfd + path */ 318 320 fail += check_execveat(subdir_dfd, "../script", 0); ··· 390 384 fd = open("subdir.ephemeral/script", O_RDWR|O_CREAT|O_TRUNC, 0755); 391 385 write(fd, script, strlen(script)); 392 386 close(fd); 387 + 388 + mkfifo("pipe", 0755); 393 389 } 394 390 395 391 int main(int argc, char **argv)
+2
tools/testing/selftests/ftrace/test.d/ftrace/tracing-error-log.tc
··· 14 14 exit_unsupported 15 15 fi 16 16 17 + [ -f error_log ] || exit_unsupported 18 + 17 19 ftrace_errlog_check 'event filter parse error' '((sig >= 10 && sig < 15) || dsig ^== 17) && comm != bash' 'events/signal/signal_generate/filter' 18 20 19 21 exit 0
+5 -3
tools/testing/selftests/ftrace/test.d/functions
··· 119 119 ping $LOCALHOST -c 1 || sleep .001 || usleep 1 || sleep 1 120 120 } 121 121 122 + # Since probe event command may include backslash, explicitly use printf "%s" 123 + # to NOT interpret it. 122 124 ftrace_errlog_check() { # err-prefix command-with-error-pos-by-^ command-file 123 - pos=$(echo -n "${2%^*}" | wc -c) # error position 124 - command=$(echo "$2" | tr -d ^) 125 + pos=$(printf "%s" "${2%^*}" | wc -c) # error position 126 + command=$(printf "%s" "$2" | tr -d ^) 125 127 echo "Test command: $command" 126 128 echo > error_log 127 - (! echo "$command" >> "$3" ) 2> /dev/null 129 + (! printf "%s" "$command" >> "$3" ) 2> /dev/null 128 130 grep "$1: error:" -A 3 error_log 129 131 N=$(tail -n 1 error_log | wc -c) 130 132 # " Command: " and "^\n" => 13
+3 -1
tools/testing/selftests/ftrace/test.d/kprobe/kprobe_syntax_errors.tc
··· 91 91 if grep -q "Create/append/" README && grep -q "imm-value" README; then 92 92 echo 'p:kprobes/testevent _do_fork' > kprobe_events 93 93 check_error '^r:kprobes/testevent do_exit' # DIFF_PROBE_TYPE 94 - echo 'p:kprobes/testevent _do_fork abcd=\1' > kprobe_events 94 + 95 + # Explicitly use printf "%s" to not interpret \1 96 + printf "%s" 'p:kprobes/testevent _do_fork abcd=\1' > kprobe_events 95 97 check_error 'p:kprobes/testevent _do_fork ^bcd=\1' # DIFF_ARG_TYPE 96 98 check_error 'p:kprobes/testevent _do_fork ^abcd=\1:u8' # DIFF_ARG_TYPE 97 99 check_error 'p:kprobes/testevent _do_fork ^abcd=\"foo"' # DIFF_ARG_TYPE
+5
tools/testing/selftests/gen_kselftest_tar.sh
··· 49 49 # directory 50 50 ./kselftest_install.sh "$install_dir" 51 51 (cd "$install_work"; tar $copts "$dest"/kselftest${ext} $install_name) 52 + 53 + # Don't put the message at the actual end as people may be parsing the 54 + # "archive created" line in their scripts. 55 + echo -e "\nConsider using 'make gen_tar' instead of this script\n" 56 + 52 57 echo "Kselftest archive kselftest${ext} created!" 53 58 54 59 # clean up top-level install work directory
+1 -1
tools/testing/selftests/sysctl/config
··· 1 - CONFIG_TEST_SYSCTL=y 1 + CONFIG_TEST_SYSCTL=m
+2 -11
tools/testing/selftests/sysctl/sysctl.sh
··· 41 41 ALL_TESTS="$ALL_TESTS 0006:50:1:bitmap_0001" 42 42 ALL_TESTS="$ALL_TESTS 0007:1:1:boot_int" 43 43 44 - test_modprobe() 45 - { 46 - if [ ! -d $DIR ]; then 47 - echo "$0: $DIR not present" >&2 48 - echo "You must have the following enabled in your kernel:" >&2 49 - cat $TEST_DIR/config >&2 50 - exit $ksft_skip 51 - fi 52 - } 53 - 54 44 function allow_user_defaults() 55 45 { 56 46 if [ -z $DIR ]; then ··· 116 126 if [ ! -d $SYSCTL ]; then 117 127 if ! modprobe -q -n $TEST_DRIVER; then 118 128 echo "$0: module $TEST_DRIVER not found [SKIP]" 129 + echo "You must set CONFIG_TEST_SYSCTL=m in your kernel" >&2 119 130 exit $ksft_skip 120 131 fi 121 132 modprobe $TEST_DRIVER 122 133 if [ $? -ne 0 ]; then 134 + echo "$0: modprobe $TEST_DRIVER failed." 123 135 exit 124 136 fi 125 137 fi ··· 963 971 allow_user_defaults 964 972 check_production_sysctl_writes_strict 965 973 load_req_mod 966 - test_modprobe 967 974 968 975 trap "test_finish" EXIT 969 976
+1 -1
tools/testing/selftests/timens/clock_nanosleep.c
··· 119 119 120 120 ksft_set_plan(4); 121 121 122 - check_config_posix_timers(); 122 + check_supported_timers(); 123 123 124 124 if (unshare_timens()) 125 125 return 1;
+1 -1
tools/testing/selftests/timens/timens.c
··· 155 155 156 156 nscheck(); 157 157 158 - check_config_posix_timers(); 158 + check_supported_timers(); 159 159 160 160 ksft_set_plan(ARRAY_SIZE(clocks) * 2); 161 161
+12 -1
tools/testing/selftests/timens/timens.h
··· 14 14 #endif 15 15 16 16 static int config_posix_timers = true; 17 + static int config_alarm_timers = true; 17 18 18 - static inline void check_config_posix_timers(void) 19 + static inline void check_supported_timers(void) 19 20 { 21 + struct timespec ts; 22 + 20 23 if (timer_create(-1, 0, 0) == -1 && errno == ENOSYS) 21 24 config_posix_timers = false; 25 + 26 + if (clock_gettime(CLOCK_BOOTTIME_ALARM, &ts) == -1 && errno == EINVAL) 27 + config_alarm_timers = false; 22 28 } 23 29 24 30 static inline bool check_skip(int clockid) 25 31 { 32 + if (!config_alarm_timers && clockid == CLOCK_BOOTTIME_ALARM) { 33 + ksft_test_result_skip("CLOCK_BOOTTIME_ALARM isn't supported\n"); 34 + return true; 35 + } 36 + 26 37 if (config_posix_timers) 27 38 return false; 28 39
+5
tools/testing/selftests/timens/timer.c
··· 22 22 timer_t fd; 23 23 int i; 24 24 25 + if (check_skip(clockid)) 26 + return 0; 27 + 25 28 for (i = 0; i < 2; i++) { 26 29 struct sigevent sevp = {.sigev_notify = SIGEV_NONE}; 27 30 int flags = 0; ··· 76 73 struct timespec btime_now, mtime_now; 77 74 78 75 nscheck(); 76 + 77 + check_supported_timers(); 79 78 80 79 ksft_set_plan(3); 81 80
+5
tools/testing/selftests/timens/timerfd.c
··· 28 28 long long elapsed; 29 29 int fd, i; 30 30 31 + if (check_skip(clockid)) 32 + return 0; 33 + 31 34 if (tclock_gettime(clockid, &now)) 32 35 return pr_perror("clock_gettime(%d)", clockid); 33 36 ··· 83 80 struct timespec btime_now, mtime_now; 84 81 85 82 nscheck(); 83 + 84 + check_supported_timers(); 86 85 87 86 ksft_set_plan(3); 88 87
+5
tools/testing/selftests/tpm2/test_smoke.sh
··· 1 1 #!/bin/bash 2 2 # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 3 3 4 + # Kselftest framework requirement - SKIP code is 4. 5 + ksft_skip=4 6 + 7 + [ -f /dev/tpm0 ] || exit $ksft_skip 8 + 4 9 python -m unittest -v tpm2_tests.SmokeTest 5 10 python -m unittest -v tpm2_tests.AsyncTest 6 11
+5
tools/testing/selftests/tpm2/test_space.sh
··· 1 1 #!/bin/bash 2 2 # SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 3 3 4 + # Kselftest framework requirement - SKIP code is 4. 5 + ksft_skip=4 6 + 7 + [ -f /dev/tpmrm0 ] || exit $ksft_skip 8 + 4 9 python -m unittest -v tpm2_tests.SpaceTest
+2
tools/testing/selftests/vDSO/.gitignore
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 vdso_test 3 + vdso_test_gettimeofday 4 + vdso_test_getcpu 3 5 vdso_standalone_test_x86
+3 -2
tools/testing/selftests/vDSO/Makefile
··· 4 4 uname_M := $(shell uname -m 2>/dev/null || echo not) 5 5 ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/) 6 6 7 - TEST_GEN_PROGS := $(OUTPUT)/vdso_test 7 + TEST_GEN_PROGS := $(OUTPUT)/vdso_test_gettimeofday $(OUTPUT)/vdso_test_getcpu 8 8 ifeq ($(ARCH),x86) 9 9 TEST_GEN_PROGS += $(OUTPUT)/vdso_standalone_test_x86 10 10 endif ··· 17 17 endif 18 18 19 19 all: $(TEST_GEN_PROGS) 20 - $(OUTPUT)/vdso_test: parse_vdso.c vdso_test.c 20 + $(OUTPUT)/vdso_test_gettimeofday: parse_vdso.c vdso_test_gettimeofday.c 21 + $(OUTPUT)/vdso_test_getcpu: parse_vdso.c vdso_test_getcpu.c 21 22 $(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c 22 23 $(CC) $(CFLAGS) $(CFLAGS_vdso_standalone_test_x86) \ 23 24 vdso_standalone_test_x86.c parse_vdso.c \
+1 -23
tools/testing/selftests/vDSO/parse_vdso.c
··· 21 21 #include <limits.h> 22 22 #include <elf.h> 23 23 24 - /* 25 - * To use this vDSO parser, first call one of the vdso_init_* functions. 26 - * If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR 27 - * to vdso_init_from_sysinfo_ehdr. Otherwise pass auxv to vdso_init_from_auxv. 28 - * Then call vdso_sym for each symbol you want. For example, to look up 29 - * gettimeofday on x86_64, use: 30 - * 31 - * <some pointer> = vdso_sym("LINUX_2.6", "gettimeofday"); 32 - * or 33 - * <some pointer> = vdso_sym("LINUX_2.6", "__vdso_gettimeofday"); 34 - * 35 - * vdso_sym will return 0 if the symbol doesn't exist or if the init function 36 - * failed or was not called. vdso_sym is a little slow, so its return value 37 - * should be cached. 38 - * 39 - * vdso_sym is threadsafe; the init functions are not. 40 - * 41 - * These are the prototypes: 42 - */ 43 - extern void vdso_init_from_auxv(void *auxv); 44 - extern void vdso_init_from_sysinfo_ehdr(uintptr_t base); 45 - extern void *vdso_sym(const char *version, const char *name); 46 - 24 + #include "parse_vdso.h" 47 25 48 26 /* And here's the code. */ 49 27 #ifndef ELF_BITS
+31
tools/testing/selftests/vDSO/parse_vdso.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + 3 + #ifndef PARSE_VDSO_H 4 + #define PARSE_VDSO_H 5 + 6 + #include <stdint.h> 7 + 8 + /* 9 + * To use this vDSO parser, first call one of the vdso_init_* functions. 10 + * If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR 11 + * to vdso_init_from_sysinfo_ehdr. Otherwise pass auxv to vdso_init_from_auxv. 12 + * Then call vdso_sym for each symbol you want. For example, to look up 13 + * gettimeofday on x86_64, use: 14 + * 15 + * <some pointer> = vdso_sym("LINUX_2.6", "gettimeofday"); 16 + * or 17 + * <some pointer> = vdso_sym("LINUX_2.6", "__vdso_gettimeofday"); 18 + * 19 + * vdso_sym will return 0 if the symbol doesn't exist or if the init function 20 + * failed or was not called. vdso_sym is a little slow, so its return value 21 + * should be cached. 22 + * 23 + * vdso_sym is threadsafe; the init functions are not. 24 + * 25 + * These are the prototypes: 26 + */ 27 + void *vdso_sym(const char *version, const char *name); 28 + void vdso_init_from_sysinfo_ehdr(uintptr_t base); 29 + void vdso_init_from_auxv(void *auxv); 30 + 31 + #endif
+1 -3
tools/testing/selftests/vDSO/vdso_standalone_test_x86.c
··· 16 16 #include <unistd.h> 17 17 #include <stdint.h> 18 18 19 - extern void *vdso_sym(const char *version, const char *name); 20 - extern void vdso_init_from_sysinfo_ehdr(uintptr_t base); 21 - extern void vdso_init_from_auxv(void *auxv); 19 + #include "parse_vdso.h" 22 20 23 21 /* We need a libc functions... */ 24 22 int strcmp(const char *a, const char *b)
+4 -6
tools/testing/selftests/vDSO/vdso_test.c tools/testing/selftests/vDSO/vdso_test_gettimeofday.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * vdso_test.c: Sample code to test parse_vdso.c 3 + * vdso_test_gettimeofday.c: Sample code to test parse_vdso.c and 4 + * vDSO gettimeofday() 4 5 * Copyright (c) 2014 Andy Lutomirski 5 6 * 6 7 * Compile with: 7 - * gcc -std=gnu99 vdso_test.c parse_vdso.c 8 + * gcc -std=gnu99 vdso_test_gettimeofday.c parse_vdso_gettimeofday.c 8 9 * 9 10 * Tested on x86, 32-bit and 64-bit. It may work on other architectures, too. 10 11 */ ··· 17 16 #include <sys/time.h> 18 17 19 18 #include "../kselftest.h" 20 - 21 - extern void *vdso_sym(const char *version, const char *name); 22 - extern void vdso_init_from_sysinfo_ehdr(uintptr_t base); 23 - extern void vdso_init_from_auxv(void *auxv); 19 + #include "parse_vdso.h" 24 20 25 21 /* 26 22 * ARM64's vDSO exports its gettimeofday() implementation with a different
+54
tools/testing/selftests/vDSO/vdso_test_getcpu.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * vdso_test_getcpu.c: Sample code to test parse_vdso.c and vDSO getcpu() 4 + * 5 + * Copyright (c) 2020 Arm Ltd 6 + */ 7 + 8 + #include <stdint.h> 9 + #include <elf.h> 10 + #include <stdio.h> 11 + #include <sys/auxv.h> 12 + #include <sys/time.h> 13 + 14 + #include "../kselftest.h" 15 + #include "parse_vdso.h" 16 + 17 + const char *version = "LINUX_2.6"; 18 + const char *name = "__vdso_getcpu"; 19 + 20 + struct getcpu_cache; 21 + typedef long (*getcpu_t)(unsigned int *, unsigned int *, 22 + struct getcpu_cache *); 23 + 24 + int main(int argc, char **argv) 25 + { 26 + unsigned long sysinfo_ehdr; 27 + unsigned int cpu, node; 28 + getcpu_t get_cpu; 29 + long ret; 30 + 31 + sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR); 32 + if (!sysinfo_ehdr) { 33 + printf("AT_SYSINFO_EHDR is not present!\n"); 34 + return KSFT_SKIP; 35 + } 36 + 37 + vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR)); 38 + 39 + get_cpu = (getcpu_t)vdso_sym(version, name); 40 + if (!get_cpu) { 41 + printf("Could not find %s\n", name); 42 + return KSFT_SKIP; 43 + } 44 + 45 + ret = get_cpu(&cpu, &node, 0); 46 + if (ret == 0) { 47 + printf("Running on CPU %u node %u\n", cpu, node); 48 + } else { 49 + printf("%s failed\n", name); 50 + return KSFT_FAIL; 51 + } 52 + 53 + return 0; 54 + }