mirror of
https://github.com/torvalds/linux.git
synced 2024-12-26 12:52:30 +00:00
linux-kselftest-5.8-rc1
This Kselftest update for Linux 5.8-rc1 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. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEPZKym/RZuOCGeA/kCwJExA0NQxwFAl7ernMACgkQCwJExA0N QxzgRg/+PYwHxTtKYX2VyQ533oTUXMdTAW8el8M72/ngRBRJMtkjYu9Jc5PfAaP9 vsyDrC8Kz6D3Nw0Gf+nH2LFJ2hJs0OooBb4HqouAyyNitXGkSiyGb6+1ICmW0Ro8 NIlwCYrIuoPUKS9ivRoKs0Vsnt0xh12asTlEwUPEEjmvE7Jf+6eoWIExu7i3nSnc symOpc3ElCXex4AlRIMI07naQqlT7rtOSQMDpjEXzMMW4rKMlgO8dFCvLkZQh/lj gUt45W9vF/Sem6a9jRMPrb8vEGkC2WURNsUVbl4JUbKp8vAXr5bYUD9CMXNdK6r2 o241nNScjr9RkZoN94DtXfcQbpwnvnhomJzqe/BgKVhfROhv4xf6fdvkxnAMYeXD J/szKvLkKkvZ5O19rBqEUCXxYdiSgFOAgHOvnUKfjKKvhMrTQ//3r8L4K6qv489A PAyoLuu8GjEVxX2dISB01ASwHeEUTZ6uF2wsu5i2dVWfTAIIpeL2Xnjsa+WmIcH7 iwBI/2RCuIeC3hViwGKuiSKaN70E/rgXcKO8jxnsF/2+hZnCuMg1D7PJLdIomJjI 6EiPukLGkZxJcHK2kdJSXIR0elEZ4pH7kweanIDPTxDiUqGwK7ZAFrA2feDJ11Iz dye9uC7sjGh27FRbVvoDvZ9659SZ1cqYS+wRcTkPx3K1wS1kuZI= =IB5c -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
fc2fb38c85
@ -151,6 +151,29 @@ note some tests will require root privileges::
|
||||
$ cd kselftest
|
||||
$ ./run_kselftest.sh
|
||||
|
||||
Packaging selftests
|
||||
===================
|
||||
|
||||
In some cases packaging is desired, such as when tests need to run on a
|
||||
different system. To package selftests, run::
|
||||
|
||||
$ make -C tools/testing/selftests gen_tar
|
||||
|
||||
This generates a tarball in the `INSTALL_PATH/kselftest-packages` directory. By
|
||||
default, `.gz` format is used. The tar format can be overridden by specifying
|
||||
a `FORMAT` make variable. Any value recognized by `tar's auto-compress`_ option
|
||||
is supported, such as::
|
||||
|
||||
$ make -C tools/testing/selftests gen_tar FORMAT=.xz
|
||||
|
||||
`make gen_tar` invokes `make install` so you can use it to package a subset of
|
||||
tests by using variables specified in `Running a subset of selftests`_
|
||||
section::
|
||||
|
||||
$ make -C tools/testing/selftests gen_tar TARGETS="bpf" FORMAT=.xz
|
||||
|
||||
.. _tar's auto-compress: https://www.gnu.org/software/tar/manual/html_node/gzip.html#auto_002dcompress
|
||||
|
||||
Contributing new tests
|
||||
======================
|
||||
|
||||
|
@ -6,7 +6,12 @@ config CORDIC
|
||||
calculations are in fixed point. Module will be called cordic.
|
||||
|
||||
config PRIME_NUMBERS
|
||||
tristate
|
||||
tristate "Simple prime number generator for testing"
|
||||
help
|
||||
This option provides a simple prime number generator for test
|
||||
modules.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config RATIONAL
|
||||
bool
|
||||
|
@ -162,7 +162,7 @@ static int __init test_sysctl_init(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
late_initcall(test_sysctl_init);
|
||||
module_init(test_sysctl_init);
|
||||
|
||||
static void __exit test_sysctl_exit(void)
|
||||
{
|
||||
|
@ -249,10 +249,17 @@ else
|
||||
$(error Error: set INSTALL_PATH to use install)
|
||||
endif
|
||||
|
||||
FORMAT ?= .gz
|
||||
TAR_PATH = $(abspath ${INSTALL_PATH}/kselftest-packages/kselftest.tar${FORMAT})
|
||||
gen_tar: install
|
||||
@mkdir -p ${INSTALL_PATH}/kselftest-packages/
|
||||
@tar caf ${TAR_PATH} --exclude=kselftest-packages -C ${INSTALL_PATH} .
|
||||
@echo "Created ${TAR_PATH}"
|
||||
|
||||
clean:
|
||||
@for TARGET in $(TARGETS); do \
|
||||
BUILD_TARGET=$$BUILD/$$TARGET; \
|
||||
$(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean;\
|
||||
done;
|
||||
|
||||
.PHONY: khdr all run_tests hotplug run_hotplug clean_hotplug run_pstore_crash install clean
|
||||
.PHONY: khdr all run_tests hotplug run_hotplug clean_hotplug run_pstore_crash install clean gen_tar
|
||||
|
1
tools/testing/selftests/exec/.gitignore
vendored
1
tools/testing/selftests/exec/.gitignore
vendored
@ -9,3 +9,4 @@ execveat.ephemeral
|
||||
execveat.denatured
|
||||
/recursion-depth
|
||||
xxxxxxxx*
|
||||
pipe
|
||||
|
@ -5,7 +5,7 @@ CFLAGS += -D_GNU_SOURCE
|
||||
|
||||
TEST_PROGS := binfmt_script
|
||||
TEST_GEN_PROGS := execveat
|
||||
TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir
|
||||
TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir pipe
|
||||
# Makefile is a run-time dependency, since it's accessed by the execveat test
|
||||
TEST_FILES := Makefile
|
||||
|
||||
|
@ -5,7 +5,9 @@
|
||||
* Selftests for execveat(2).
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE /* to get O_PATH, AT_EMPTY_PATH */
|
||||
#endif
|
||||
#include <sys/sendfile.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
@ -311,6 +313,10 @@ static int run_tests(void)
|
||||
fail += check_execveat_fail(AT_FDCWD, fullname_symlink,
|
||||
AT_SYMLINK_NOFOLLOW, ELOOP);
|
||||
|
||||
/* Non-regular file failure */
|
||||
fail += check_execveat_fail(dot_dfd, "pipe", 0, EACCES);
|
||||
unlink("pipe");
|
||||
|
||||
/* Shell script wrapping executable file: */
|
||||
/* dfd + path */
|
||||
fail += check_execveat(subdir_dfd, "../script", 0);
|
||||
@ -384,6 +390,8 @@ static void prerequisites(void)
|
||||
fd = open("subdir.ephemeral/script", O_RDWR|O_CREAT|O_TRUNC, 0755);
|
||||
write(fd, script, strlen(script));
|
||||
close(fd);
|
||||
|
||||
mkfifo("pipe", 0755);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -14,6 +14,8 @@ if [ ! -f set_event ]; then
|
||||
exit_unsupported
|
||||
fi
|
||||
|
||||
[ -f error_log ] || exit_unsupported
|
||||
|
||||
ftrace_errlog_check 'event filter parse error' '((sig >= 10 && sig < 15) || dsig ^== 17) && comm != bash' 'events/signal/signal_generate/filter'
|
||||
|
||||
exit 0
|
||||
|
@ -119,12 +119,14 @@ yield() {
|
||||
ping $LOCALHOST -c 1 || sleep .001 || usleep 1 || sleep 1
|
||||
}
|
||||
|
||||
# Since probe event command may include backslash, explicitly use printf "%s"
|
||||
# to NOT interpret it.
|
||||
ftrace_errlog_check() { # err-prefix command-with-error-pos-by-^ command-file
|
||||
pos=$(echo -n "${2%^*}" | wc -c) # error position
|
||||
command=$(echo "$2" | tr -d ^)
|
||||
pos=$(printf "%s" "${2%^*}" | wc -c) # error position
|
||||
command=$(printf "%s" "$2" | tr -d ^)
|
||||
echo "Test command: $command"
|
||||
echo > error_log
|
||||
(! echo "$command" >> "$3" ) 2> /dev/null
|
||||
(! printf "%s" "$command" >> "$3" ) 2> /dev/null
|
||||
grep "$1: error:" -A 3 error_log
|
||||
N=$(tail -n 1 error_log | wc -c)
|
||||
# " Command: " and "^\n" => 13
|
||||
|
@ -91,7 +91,9 @@ esac
|
||||
if grep -q "Create/append/" README && grep -q "imm-value" README; then
|
||||
echo 'p:kprobes/testevent _do_fork' > kprobe_events
|
||||
check_error '^r:kprobes/testevent do_exit' # DIFF_PROBE_TYPE
|
||||
echo 'p:kprobes/testevent _do_fork abcd=\1' > kprobe_events
|
||||
|
||||
# Explicitly use printf "%s" to not interpret \1
|
||||
printf "%s" 'p:kprobes/testevent _do_fork abcd=\1' > kprobe_events
|
||||
check_error 'p:kprobes/testevent _do_fork ^bcd=\1' # DIFF_ARG_TYPE
|
||||
check_error 'p:kprobes/testevent _do_fork ^abcd=\1:u8' # DIFF_ARG_TYPE
|
||||
check_error 'p:kprobes/testevent _do_fork ^abcd=\"foo"' # DIFF_ARG_TYPE
|
||||
|
@ -49,6 +49,11 @@ main()
|
||||
# directory
|
||||
./kselftest_install.sh "$install_dir"
|
||||
(cd "$install_work"; tar $copts "$dest"/kselftest${ext} $install_name)
|
||||
|
||||
# Don't put the message at the actual end as people may be parsing the
|
||||
# "archive created" line in their scripts.
|
||||
echo -e "\nConsider using 'make gen_tar' instead of this script\n"
|
||||
|
||||
echo "Kselftest archive kselftest${ext} created!"
|
||||
|
||||
# clean up top-level install work directory
|
||||
|
@ -1 +1 @@
|
||||
CONFIG_TEST_SYSCTL=y
|
||||
CONFIG_TEST_SYSCTL=m
|
||||
|
@ -41,16 +41,6 @@ ALL_TESTS="$ALL_TESTS 0005:3:1:int_0003"
|
||||
ALL_TESTS="$ALL_TESTS 0006:50:1:bitmap_0001"
|
||||
ALL_TESTS="$ALL_TESTS 0007:1:1:boot_int"
|
||||
|
||||
test_modprobe()
|
||||
{
|
||||
if [ ! -d $DIR ]; then
|
||||
echo "$0: $DIR not present" >&2
|
||||
echo "You must have the following enabled in your kernel:" >&2
|
||||
cat $TEST_DIR/config >&2
|
||||
exit $ksft_skip
|
||||
fi
|
||||
}
|
||||
|
||||
function allow_user_defaults()
|
||||
{
|
||||
if [ -z $DIR ]; then
|
||||
@ -126,10 +116,12 @@ function load_req_mod()
|
||||
if [ ! -d $SYSCTL ]; then
|
||||
if ! modprobe -q -n $TEST_DRIVER; then
|
||||
echo "$0: module $TEST_DRIVER not found [SKIP]"
|
||||
echo "You must set CONFIG_TEST_SYSCTL=m in your kernel" >&2
|
||||
exit $ksft_skip
|
||||
fi
|
||||
modprobe $TEST_DRIVER
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "$0: modprobe $TEST_DRIVER failed."
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
@ -971,7 +963,6 @@ test_reqs
|
||||
allow_user_defaults
|
||||
check_production_sysctl_writes_strict
|
||||
load_req_mod
|
||||
test_modprobe
|
||||
|
||||
trap "test_finish" EXIT
|
||||
|
||||
|
@ -119,7 +119,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
ksft_set_plan(4);
|
||||
|
||||
check_config_posix_timers();
|
||||
check_supported_timers();
|
||||
|
||||
if (unshare_timens())
|
||||
return 1;
|
||||
|
@ -155,7 +155,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
nscheck();
|
||||
|
||||
check_config_posix_timers();
|
||||
check_supported_timers();
|
||||
|
||||
ksft_set_plan(ARRAY_SIZE(clocks) * 2);
|
||||
|
||||
|
@ -14,15 +14,26 @@
|
||||
#endif
|
||||
|
||||
static int config_posix_timers = true;
|
||||
static int config_alarm_timers = true;
|
||||
|
||||
static inline void check_config_posix_timers(void)
|
||||
static inline void check_supported_timers(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (timer_create(-1, 0, 0) == -1 && errno == ENOSYS)
|
||||
config_posix_timers = false;
|
||||
|
||||
if (clock_gettime(CLOCK_BOOTTIME_ALARM, &ts) == -1 && errno == EINVAL)
|
||||
config_alarm_timers = false;
|
||||
}
|
||||
|
||||
static inline bool check_skip(int clockid)
|
||||
{
|
||||
if (!config_alarm_timers && clockid == CLOCK_BOOTTIME_ALARM) {
|
||||
ksft_test_result_skip("CLOCK_BOOTTIME_ALARM isn't supported\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (config_posix_timers)
|
||||
return false;
|
||||
|
||||
|
@ -22,6 +22,9 @@ int run_test(int clockid, struct timespec now)
|
||||
timer_t fd;
|
||||
int i;
|
||||
|
||||
if (check_skip(clockid))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
struct sigevent sevp = {.sigev_notify = SIGEV_NONE};
|
||||
int flags = 0;
|
||||
@ -74,6 +77,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
nscheck();
|
||||
|
||||
check_supported_timers();
|
||||
|
||||
ksft_set_plan(3);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &mtime_now);
|
||||
|
@ -28,6 +28,9 @@ int run_test(int clockid, struct timespec now)
|
||||
long long elapsed;
|
||||
int fd, i;
|
||||
|
||||
if (check_skip(clockid))
|
||||
return 0;
|
||||
|
||||
if (tclock_gettime(clockid, &now))
|
||||
return pr_perror("clock_gettime(%d)", clockid);
|
||||
|
||||
@ -81,6 +84,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
nscheck();
|
||||
|
||||
check_supported_timers();
|
||||
|
||||
ksft_set_plan(3);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &mtime_now);
|
||||
|
@ -1,6 +1,11 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
|
||||
|
||||
# Kselftest framework requirement - SKIP code is 4.
|
||||
ksft_skip=4
|
||||
|
||||
[ -f /dev/tpm0 ] || exit $ksft_skip
|
||||
|
||||
python -m unittest -v tpm2_tests.SmokeTest
|
||||
python -m unittest -v tpm2_tests.AsyncTest
|
||||
|
||||
|
@ -1,4 +1,9 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
|
||||
|
||||
# Kselftest framework requirement - SKIP code is 4.
|
||||
ksft_skip=4
|
||||
|
||||
[ -f /dev/tpmrm0 ] || exit $ksft_skip
|
||||
|
||||
python -m unittest -v tpm2_tests.SpaceTest
|
||||
|
2
tools/testing/selftests/vDSO/.gitignore
vendored
2
tools/testing/selftests/vDSO/.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
vdso_test
|
||||
vdso_test_gettimeofday
|
||||
vdso_test_getcpu
|
||||
vdso_standalone_test_x86
|
||||
|
@ -4,7 +4,7 @@ include ../lib.mk
|
||||
uname_M := $(shell uname -m 2>/dev/null || echo not)
|
||||
ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/x86/ -e s/x86_64/x86/)
|
||||
|
||||
TEST_GEN_PROGS := $(OUTPUT)/vdso_test
|
||||
TEST_GEN_PROGS := $(OUTPUT)/vdso_test_gettimeofday $(OUTPUT)/vdso_test_getcpu
|
||||
ifeq ($(ARCH),x86)
|
||||
TEST_GEN_PROGS += $(OUTPUT)/vdso_standalone_test_x86
|
||||
endif
|
||||
@ -17,7 +17,8 @@ LDLIBS += -lgcc_s
|
||||
endif
|
||||
|
||||
all: $(TEST_GEN_PROGS)
|
||||
$(OUTPUT)/vdso_test: parse_vdso.c vdso_test.c
|
||||
$(OUTPUT)/vdso_test_gettimeofday: parse_vdso.c vdso_test_gettimeofday.c
|
||||
$(OUTPUT)/vdso_test_getcpu: parse_vdso.c vdso_test_getcpu.c
|
||||
$(OUTPUT)/vdso_standalone_test_x86: vdso_standalone_test_x86.c parse_vdso.c
|
||||
$(CC) $(CFLAGS) $(CFLAGS_vdso_standalone_test_x86) \
|
||||
vdso_standalone_test_x86.c parse_vdso.c \
|
||||
|
@ -21,29 +21,7 @@
|
||||
#include <limits.h>
|
||||
#include <elf.h>
|
||||
|
||||
/*
|
||||
* To use this vDSO parser, first call one of the vdso_init_* functions.
|
||||
* If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR
|
||||
* to vdso_init_from_sysinfo_ehdr. Otherwise pass auxv to vdso_init_from_auxv.
|
||||
* Then call vdso_sym for each symbol you want. For example, to look up
|
||||
* gettimeofday on x86_64, use:
|
||||
*
|
||||
* <some pointer> = vdso_sym("LINUX_2.6", "gettimeofday");
|
||||
* or
|
||||
* <some pointer> = vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
|
||||
*
|
||||
* vdso_sym will return 0 if the symbol doesn't exist or if the init function
|
||||
* failed or was not called. vdso_sym is a little slow, so its return value
|
||||
* should be cached.
|
||||
*
|
||||
* vdso_sym is threadsafe; the init functions are not.
|
||||
*
|
||||
* These are the prototypes:
|
||||
*/
|
||||
extern void vdso_init_from_auxv(void *auxv);
|
||||
extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
|
||||
extern void *vdso_sym(const char *version, const char *name);
|
||||
|
||||
#include "parse_vdso.h"
|
||||
|
||||
/* And here's the code. */
|
||||
#ifndef ELF_BITS
|
||||
|
31
tools/testing/selftests/vDSO/parse_vdso.h
Normal file
31
tools/testing/selftests/vDSO/parse_vdso.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef PARSE_VDSO_H
|
||||
#define PARSE_VDSO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* To use this vDSO parser, first call one of the vdso_init_* functions.
|
||||
* If you've already parsed auxv, then pass the value of AT_SYSINFO_EHDR
|
||||
* to vdso_init_from_sysinfo_ehdr. Otherwise pass auxv to vdso_init_from_auxv.
|
||||
* Then call vdso_sym for each symbol you want. For example, to look up
|
||||
* gettimeofday on x86_64, use:
|
||||
*
|
||||
* <some pointer> = vdso_sym("LINUX_2.6", "gettimeofday");
|
||||
* or
|
||||
* <some pointer> = vdso_sym("LINUX_2.6", "__vdso_gettimeofday");
|
||||
*
|
||||
* vdso_sym will return 0 if the symbol doesn't exist or if the init function
|
||||
* failed or was not called. vdso_sym is a little slow, so its return value
|
||||
* should be cached.
|
||||
*
|
||||
* vdso_sym is threadsafe; the init functions are not.
|
||||
*
|
||||
* These are the prototypes:
|
||||
*/
|
||||
void *vdso_sym(const char *version, const char *name);
|
||||
void vdso_init_from_sysinfo_ehdr(uintptr_t base);
|
||||
void vdso_init_from_auxv(void *auxv);
|
||||
|
||||
#endif
|
@ -16,9 +16,7 @@
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern void *vdso_sym(const char *version, const char *name);
|
||||
extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
|
||||
extern void vdso_init_from_auxv(void *auxv);
|
||||
#include "parse_vdso.h"
|
||||
|
||||
/* We need a libc functions... */
|
||||
int strcmp(const char *a, const char *b)
|
||||
|
54
tools/testing/selftests/vDSO/vdso_test_getcpu.c
Normal file
54
tools/testing/selftests/vDSO/vdso_test_getcpu.c
Normal file
@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* vdso_test_getcpu.c: Sample code to test parse_vdso.c and vDSO getcpu()
|
||||
*
|
||||
* Copyright (c) 2020 Arm Ltd
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <elf.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/auxv.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "../kselftest.h"
|
||||
#include "parse_vdso.h"
|
||||
|
||||
const char *version = "LINUX_2.6";
|
||||
const char *name = "__vdso_getcpu";
|
||||
|
||||
struct getcpu_cache;
|
||||
typedef long (*getcpu_t)(unsigned int *, unsigned int *,
|
||||
struct getcpu_cache *);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
unsigned long sysinfo_ehdr;
|
||||
unsigned int cpu, node;
|
||||
getcpu_t get_cpu;
|
||||
long ret;
|
||||
|
||||
sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
|
||||
if (!sysinfo_ehdr) {
|
||||
printf("AT_SYSINFO_EHDR is not present!\n");
|
||||
return KSFT_SKIP;
|
||||
}
|
||||
|
||||
vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
|
||||
|
||||
get_cpu = (getcpu_t)vdso_sym(version, name);
|
||||
if (!get_cpu) {
|
||||
printf("Could not find %s\n", name);
|
||||
return KSFT_SKIP;
|
||||
}
|
||||
|
||||
ret = get_cpu(&cpu, &node, 0);
|
||||
if (ret == 0) {
|
||||
printf("Running on CPU %u node %u\n", cpu, node);
|
||||
} else {
|
||||
printf("%s failed\n", name);
|
||||
return KSFT_FAIL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* vdso_test.c: Sample code to test parse_vdso.c
|
||||
* vdso_test_gettimeofday.c: Sample code to test parse_vdso.c and
|
||||
* vDSO gettimeofday()
|
||||
* Copyright (c) 2014 Andy Lutomirski
|
||||
*
|
||||
* Compile with:
|
||||
* gcc -std=gnu99 vdso_test.c parse_vdso.c
|
||||
* gcc -std=gnu99 vdso_test_gettimeofday.c parse_vdso_gettimeofday.c
|
||||
*
|
||||
* Tested on x86, 32-bit and 64-bit. It may work on other architectures, too.
|
||||
*/
|
||||
@ -16,10 +17,7 @@
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "../kselftest.h"
|
||||
|
||||
extern void *vdso_sym(const char *version, const char *name);
|
||||
extern void vdso_init_from_sysinfo_ehdr(uintptr_t base);
|
||||
extern void vdso_init_from_auxv(void *auxv);
|
||||
#include "parse_vdso.h"
|
||||
|
||||
/*
|
||||
* ARM64's vDSO exports its gettimeofday() implementation with a different
|
Loading…
Reference in New Issue
Block a user