Commit 4b95dc87 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'linux_kselftest-next-6.10-rc1' of...

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

Pull kselftest updates from Shuah Khan:

 - make framework and tests reporting KTAP compliant

 - make ktap_helpers and power_supply test POSIX compliant

 - add ksft_exit_fail_perror() to include errono in string form

 - avoid clang reporting false positive static analysis errors about
   functions that exit and never return. ksft_exit* functions are marked
   __noreturn to address this problem

 - add mechanism for reporting a KSFT_ result code

 - fix build warnings related missing headers and unused variables

 - fix clang build failures

 - cleanups to resctrl test

 - add host arch for LLVM builds

* tag 'linux_kselftest-next-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (44 commits)
  selftests/sgx: Include KHDR_INCLUDES in Makefile
  selftests: Compile kselftest headers with -D_GNU_SOURCE
  selftests/resctrl: fix clang build warnings related to abs(), labs() calls
  selftests/ftrace: Fix checkbashisms errors
  selftests/ftrace: Fix BTFARG testcase to check fprobe is enabled correctly
  selftests/capabilities: fix warn_unused_result build warnings
  selftests: filesystems: add missing stddef header
  selftests: kselftest_deps: fix l5_test() empty variable
  selftests: default to host arch for LLVM builds
  selftests/resctrl: fix clang build failure: use LOCAL_HDRS
  selftests/binderfs: use the Makefile's rules, not Make's implicit rules
  Documentation: kselftest: fix codeblock
  selftests: kselftest: Make ksft_exit functions return void instead of int
  selftests: x86: ksft_exit_pass() does not return
  selftests: timers: ksft_exit functions do not return
  selftests: sync: ksft_exit_pass() does not return
  selftests/resctrl: ksft_exit_skip() does not return
  selftests: pidfd: ksft_exit functions do not return
  selftests/mm: ksft_exit functions do not return
  selftests: membarrier: ksft_exit_pass() does not return
  ...
parents 896d3fce 2c3b8f8f
......@@ -183,7 +183,7 @@ expected time it takes to run a test. If you have control over the systems
which will run the tests you can configure a test runner on those systems to
use a greater or lower timeout on the command line as with the `-o` or
the `--override-timeout` argument. For example to use 165 seconds instead
one would use:
one would use::
$ ./run_kselftest.sh --override-timeout 165
......
......@@ -161,11 +161,11 @@ ifneq ($(KBUILD_OUTPUT),)
# $(realpath ...) resolves symlinks
abs_objtree := $(realpath $(abs_objtree))
BUILD := $(abs_objtree)/kselftest
KHDR_INCLUDES := -isystem ${abs_objtree}/usr/include
KHDR_INCLUDES := -D_GNU_SOURCE -isystem ${abs_objtree}/usr/include
else
BUILD := $(CURDIR)
abs_srctree := $(shell cd $(top_srcdir) && pwd)
KHDR_INCLUDES := -isystem ${abs_srctree}/usr/include
KHDR_INCLUDES := -D_GNU_SOURCE -isystem ${abs_srctree}/usr/include
DEFAULT_INSTALL_HDR_PATH := 1
endif
......
......@@ -82,7 +82,7 @@ static bool create_and_enter_ns(uid_t inner_uid)
{
uid_t outer_uid;
gid_t outer_gid;
int i;
int i, ret;
bool have_outer_privilege;
outer_uid = getuid();
......@@ -97,7 +97,10 @@ static bool create_and_enter_ns(uid_t inner_uid)
ksft_exit_fail_msg("setresuid - %s\n", strerror(errno));
// Re-enable effective caps
capng_get_caps_process();
ret = capng_get_caps_process();
if (ret == -1)
ksft_exit_fail_msg("capng_get_caps_process failed\n");
for (i = 0; i < CAP_LAST_CAP; i++)
if (capng_have_capability(CAPNG_PERMITTED, i))
capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, i);
......@@ -207,6 +210,7 @@ static void exec_validate_cap(bool eff, bool perm, bool inh, bool ambient)
static int do_tests(int uid, const char *our_path)
{
int ret;
bool have_outer_privilege = create_and_enter_ns(uid);
int ourpath_fd = open(our_path, O_RDONLY | O_DIRECTORY);
......@@ -250,7 +254,9 @@ static int do_tests(int uid, const char *our_path)
ksft_exit_fail_msg("chmod - %s\n", strerror(errno));
}
capng_get_caps_process();
ret = capng_get_caps_process();
if (ret == -1)
ksft_exit_fail_msg("capng_get_caps_process failed\n");
/* Make sure that i starts out clear */
capng_update(CAPNG_DROP, CAPNG_INHERITABLE, CAP_NET_BIND_SERVICE);
......
......@@ -28,6 +28,7 @@ static bool bool_arg(char **argv, int i)
int main(int argc, char **argv)
{
const char *atsec = "";
int ret;
/*
* Be careful just in case a setgid or setcapped copy of this
......@@ -44,7 +45,11 @@ int main(int argc, char **argv)
atsec = " (AT_SECURE is not set)";
#endif
capng_get_caps_process();
ret = capng_get_caps_process();
if (ret == -1) {
ksft_print_msg("capng_get_caps_process failed\n");
return 1;
}
if (capng_have_capability(CAPNG_EFFECTIVE, CAP_NET_BIND_SERVICE) != bool_arg(argv, 1)) {
ksft_print_msg("Wrong effective state%s\n", atsec);
......
......@@ -95,9 +95,14 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode)
getpid(), pid);
if (waitpid(-1, &status, __WALL) < 0) {
ksft_print_msg("Child returned %s\n", strerror(errno));
ksft_print_msg("waitpid() returned %s\n", strerror(errno));
return -errno;
}
if (!WIFEXITED(status)) {
ksft_print_msg("Child did not exit normally, status 0x%x\n",
status);
return EXIT_FAILURE;
}
if (WEXITSTATUS(status))
return WEXITSTATUS(status);
......
......@@ -120,5 +120,5 @@ int main(int argc, char **argv)
test_clone3_clear_sighand();
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -114,7 +114,8 @@ static int call_clone3_set_tid(pid_t *set_tid,
return WEXITSTATUS(status);
}
static void test_clone3_set_tid(pid_t *set_tid,
static void test_clone3_set_tid(const char *desc,
pid_t *set_tid,
size_t set_tid_size,
int flags,
int expected,
......@@ -129,17 +130,13 @@ static void test_clone3_set_tid(pid_t *set_tid,
ret = call_clone3_set_tid(set_tid, set_tid_size, flags, expected_pid,
wait_for_it);
ksft_print_msg(
"[%d] clone3() with CLONE_SET_TID %d says :%d - expected %d\n",
"[%d] clone3() with CLONE_SET_TID %d says: %d - expected %d\n",
getpid(), set_tid[0], ret, expected);
if (ret != expected)
ksft_test_result_fail(
"[%d] Result (%d) is different than expected (%d)\n",
getpid(), ret, expected);
else
ksft_test_result_pass(
"[%d] Result (%d) matches expectation (%d)\n",
getpid(), ret, expected);
ksft_test_result(ret == expected, "%s with %zu TIDs and flags 0x%x\n",
desc, set_tid_size, flags);
}
int main(int argc, char *argv[])
{
FILE *f;
......@@ -172,73 +169,91 @@ int main(int argc, char *argv[])
/* Try invalid settings */
memset(&set_tid, 0, sizeof(set_tid));
test_clone3_set_tid(set_tid, MAX_PID_NS_LEVEL + 1, 0, -EINVAL, 0, 0);
test_clone3_set_tid("invalid size, 0 TID",
set_tid, MAX_PID_NS_LEVEL + 1, 0, -EINVAL, 0, 0);
test_clone3_set_tid(set_tid, MAX_PID_NS_LEVEL * 2, 0, -EINVAL, 0, 0);
test_clone3_set_tid("invalid size, 0 TID",
set_tid, MAX_PID_NS_LEVEL * 2, 0, -EINVAL, 0, 0);
test_clone3_set_tid(set_tid, MAX_PID_NS_LEVEL * 2 + 1, 0,
-EINVAL, 0, 0);
test_clone3_set_tid("invalid size, 0 TID",
set_tid, MAX_PID_NS_LEVEL * 2 + 1, 0,
-EINVAL, 0, 0);
test_clone3_set_tid(set_tid, MAX_PID_NS_LEVEL * 42, 0, -EINVAL, 0, 0);
test_clone3_set_tid("invalid size, 0 TID",
set_tid, MAX_PID_NS_LEVEL * 42, 0, -EINVAL, 0, 0);
/*
* This can actually work if this test running in a MAX_PID_NS_LEVEL - 1
* nested PID namespace.
*/
test_clone3_set_tid(set_tid, MAX_PID_NS_LEVEL - 1, 0, -EINVAL, 0, 0);
test_clone3_set_tid("invalid size, 0 TID",
set_tid, MAX_PID_NS_LEVEL - 1, 0, -EINVAL, 0, 0);
memset(&set_tid, 0xff, sizeof(set_tid));
test_clone3_set_tid(set_tid, MAX_PID_NS_LEVEL + 1, 0, -EINVAL, 0, 0);
test_clone3_set_tid("invalid size, TID all 1s",
set_tid, MAX_PID_NS_LEVEL + 1, 0, -EINVAL, 0, 0);
test_clone3_set_tid(set_tid, MAX_PID_NS_LEVEL * 2, 0, -EINVAL, 0, 0);
test_clone3_set_tid("invalid size, TID all 1s",
set_tid, MAX_PID_NS_LEVEL * 2, 0, -EINVAL, 0, 0);
test_clone3_set_tid(set_tid, MAX_PID_NS_LEVEL * 2 + 1, 0,
-EINVAL, 0, 0);
test_clone3_set_tid("invalid size, TID all 1s",
set_tid, MAX_PID_NS_LEVEL * 2 + 1, 0,
-EINVAL, 0, 0);
test_clone3_set_tid(set_tid, MAX_PID_NS_LEVEL * 42, 0, -EINVAL, 0, 0);
test_clone3_set_tid("invalid size, TID all 1s",
set_tid, MAX_PID_NS_LEVEL * 42, 0, -EINVAL, 0, 0);
/*
* This can actually work if this test running in a MAX_PID_NS_LEVEL - 1
* nested PID namespace.
*/
test_clone3_set_tid(set_tid, MAX_PID_NS_LEVEL - 1, 0, -EINVAL, 0, 0);
test_clone3_set_tid("invalid size, TID all 1s",
set_tid, MAX_PID_NS_LEVEL - 1, 0, -EINVAL, 0, 0);
memset(&set_tid, 0, sizeof(set_tid));
/* Try with an invalid PID */
set_tid[0] = 0;
test_clone3_set_tid(set_tid, 1, 0, -EINVAL, 0, 0);
test_clone3_set_tid("valid size, 0 TID",
set_tid, 1, 0, -EINVAL, 0, 0);
set_tid[0] = -1;
test_clone3_set_tid(set_tid, 1, 0, -EINVAL, 0, 0);
test_clone3_set_tid("valid size, -1 TID",
set_tid, 1, 0, -EINVAL, 0, 0);
/* Claim that the set_tid array actually contains 2 elements. */
test_clone3_set_tid(set_tid, 2, 0, -EINVAL, 0, 0);
test_clone3_set_tid("2 TIDs, -1 and 0",
set_tid, 2, 0, -EINVAL, 0, 0);
/* Try it in a new PID namespace */
if (uid == 0)
test_clone3_set_tid(set_tid, 1, CLONE_NEWPID, -EINVAL, 0, 0);
test_clone3_set_tid("valid size, -1 TID",
set_tid, 1, CLONE_NEWPID, -EINVAL, 0, 0);
else
ksft_test_result_skip("Clone3() with set_tid requires root\n");
/* Try with a valid PID (1) this should return -EEXIST. */
set_tid[0] = 1;
if (uid == 0)
test_clone3_set_tid(set_tid, 1, 0, -EEXIST, 0, 0);
test_clone3_set_tid("duplicate PID 1",
set_tid, 1, 0, -EEXIST, 0, 0);
else
ksft_test_result_skip("Clone3() with set_tid requires root\n");
/* Try it in a new PID namespace */
if (uid == 0)
test_clone3_set_tid(set_tid, 1, CLONE_NEWPID, 0, 0, 0);
test_clone3_set_tid("duplicate PID 1",
set_tid, 1, CLONE_NEWPID, 0, 0, 0);
else
ksft_test_result_skip("Clone3() with set_tid requires root\n");
/* pid_max should fail everywhere */
set_tid[0] = pid_max;
test_clone3_set_tid(set_tid, 1, 0, -EINVAL, 0, 0);
test_clone3_set_tid("set TID to maximum",
set_tid, 1, 0, -EINVAL, 0, 0);
if (uid == 0)
test_clone3_set_tid(set_tid, 1, CLONE_NEWPID, -EINVAL, 0, 0);
test_clone3_set_tid("set TID to maximum",
set_tid, 1, CLONE_NEWPID, -EINVAL, 0, 0);
else
ksft_test_result_skip("Clone3() with set_tid requires root\n");
......@@ -262,10 +277,12 @@ int main(int argc, char *argv[])
/* After the child has finished, its PID should be free. */
set_tid[0] = pid;
test_clone3_set_tid(set_tid, 1, 0, 0, 0, 0);
test_clone3_set_tid("reallocate child TID",
set_tid, 1, 0, 0, 0, 0);
/* This should fail as there is no PID 1 in that namespace */
test_clone3_set_tid(set_tid, 1, CLONE_NEWPID, -EINVAL, 0, 0);
test_clone3_set_tid("duplicate child TID",
set_tid, 1, CLONE_NEWPID, -EINVAL, 0, 0);
/*
* Creating a process with PID 1 in the newly created most nested
......@@ -274,7 +291,8 @@ int main(int argc, char *argv[])
*/
set_tid[0] = 1;
set_tid[1] = pid;
test_clone3_set_tid(set_tid, 2, CLONE_NEWPID, 0, pid, 0);
test_clone3_set_tid("create PID 1 in new NS",
set_tid, 2, CLONE_NEWPID, 0, pid, 0);
ksft_print_msg("unshare PID namespace\n");
if (unshare(CLONE_NEWPID) == -1)
......@@ -284,7 +302,8 @@ int main(int argc, char *argv[])
set_tid[0] = pid;
/* This should fail as there is no PID 1 in that namespace */
test_clone3_set_tid(set_tid, 1, 0, -EINVAL, 0, 0);
test_clone3_set_tid("duplicate PID 1",
set_tid, 1, 0, -EINVAL, 0, 0);
/* Let's create a PID 1 */
ns_pid = fork();
......@@ -295,21 +314,25 @@ int main(int argc, char *argv[])
*/
set_tid[0] = 43;
set_tid[1] = -1;
test_clone3_set_tid(set_tid, 2, 0, -EINVAL, 0, 0);
test_clone3_set_tid("check leak on invalid TID -1",
set_tid, 2, 0, -EINVAL, 0, 0);
set_tid[0] = 43;
set_tid[1] = pid;
test_clone3_set_tid(set_tid, 2, 0, 0, 43, 0);
test_clone3_set_tid("check leak on invalid specific TID",
set_tid, 2, 0, 0, 43, 0);
ksft_print_msg("Child in PID namespace has PID %d\n", getpid());
set_tid[0] = 2;
test_clone3_set_tid(set_tid, 1, 0, 0, 2, 0);
test_clone3_set_tid("create PID 2 in child NS",
set_tid, 1, 0, 0, 2, 0);
set_tid[0] = 1;
set_tid[1] = -1;
set_tid[2] = pid;
/* This should fail as there is invalid PID at level '1'. */
test_clone3_set_tid(set_tid, 3, CLONE_NEWPID, -EINVAL, 0, 0);
test_clone3_set_tid("fail due to invalid TID at level 1",
set_tid, 3, CLONE_NEWPID, -EINVAL, 0, 0);
set_tid[0] = 1;
set_tid[1] = 42;
......@@ -319,13 +342,15 @@ int main(int argc, char *argv[])
* namespaces. Again assuming this is running in the host's
* PID namespace. Not yet nested.
*/
test_clone3_set_tid(set_tid, 4, CLONE_NEWPID, -EINVAL, 0, 0);
test_clone3_set_tid("fail due to too few active PID NSs",
set_tid, 4, CLONE_NEWPID, -EINVAL, 0, 0);
/*
* This should work and from the parent we should see
* something like 'NSpid: pid 42 1'.
*/
test_clone3_set_tid(set_tid, 3, CLONE_NEWPID, 0, 42, true);
test_clone3_set_tid("verify that we have 3 PID NSs",
set_tid, 3, CLONE_NEWPID, 0, 42, true);
child_exit(ksft_cnt.ksft_fail);
}
......@@ -380,16 +405,14 @@ int main(int argc, char *argv[])
ksft_cnt.ksft_pass += 6 - (ksft_cnt.ksft_fail - WEXITSTATUS(status));
ksft_cnt.ksft_fail = WEXITSTATUS(status);
if (ns3 == pid && ns2 == 42 && ns1 == 1)
ksft_test_result_pass(
"PIDs in all namespaces as expected (%d,%d,%d)\n",
ns3, ns2, ns1);
else
ksft_test_result_fail(
"PIDs in all namespaces not as expected (%d,%d,%d)\n",
ns3, ns2, ns1);
ksft_print_msg("Expecting PIDs %d, 42, 1\n", pid);
ksft_print_msg("Have PIDs in namespaces: %d, %d, %d\n", ns3, ns2, ns1);
ksft_test_result(ns3 == pid && ns2 == 42 && ns1 == 1,
"PIDs in all namespaces as expected\n");
out:
ret = 0;
return !ret ? ksft_exit_pass() : ksft_exit_fail();
if (ret)
ksft_exit_fail();
ksft_exit_pass();
}
......@@ -178,8 +178,7 @@ cpufreq_basic_tests()
count=$(count_cpufreq_managed_cpus)
if [ $count = 0 ]; then
printf "No cpu is managed by cpufreq core, exiting\n"
exit;
ktap_exit_fail_msg "No cpu is managed by cpufreq core, exiting\n"
else
printf "CPUFreq manages: $count CPUs\n\n"
fi
......
......@@ -7,15 +7,15 @@ source governor.sh
source module.sh
source special-tests.sh
DIR="$(dirname $(readlink -f "$0"))"
source "${DIR}"/../kselftest/ktap_helpers.sh
FUNC=basic # do basic tests by default
OUTFILE=cpufreq_selftest
SYSFS=
CPUROOT=
CPUFREQROOT=
# Kselftest framework requirement - SKIP code is 4.
ksft_skip=4
helpme()
{
printf "Usage: $0 [-h] [-todg args]
......@@ -32,7 +32,7 @@ helpme()
[-d <driver's module name: only with \"-t modtest>\"]
[-g <governor's module name: only with \"-t modtest>\"]
\n"
exit 2
exit "${KSFT_FAIL}"
}
prerequisite()
......@@ -40,8 +40,8 @@ prerequisite()
msg="skip all tests:"
if [ $UID != 0 ]; then
echo $msg must be run as root >&2
exit $ksft_skip
ktap_skip_all "$msg must be run as root"
exit "${KSFT_SKIP}"
fi
taskset -p 01 $$
......@@ -49,21 +49,21 @@ prerequisite()
SYSFS=`mount -t sysfs | head -1 | awk '{ print $3 }'`
if [ ! -d "$SYSFS" ]; then
echo $msg sysfs is not mounted >&2
exit 2
ktap_skip_all "$msg sysfs is not mounted"
exit "${KSFT_SKIP}"
fi
CPUROOT=$SYSFS/devices/system/cpu
CPUFREQROOT="$CPUROOT/cpufreq"
if ! ls $CPUROOT/cpu* > /dev/null 2>&1; then
echo $msg cpus not available in sysfs >&2
exit 2
ktap_skip_all "$msg cpus not available in sysfs"
exit "${KSFT_SKIP}"
fi
if ! ls $CPUROOT/cpufreq > /dev/null 2>&1; then
echo $msg cpufreq directory not available in sysfs >&2
exit 2
ktap_skip_all "$msg cpufreq directory not available in sysfs"
exit "${KSFT_SKIP}"
fi
}
......@@ -105,8 +105,7 @@ do_test()
count=$(count_cpufreq_managed_cpus)
if [ $count = 0 -a $FUNC != "modtest" ]; then
echo "No cpu is managed by cpufreq core, exiting"
exit 2;
ktap_exit_fail_msg "No cpu is managed by cpufreq core, exiting"
fi
case "$FUNC" in
......@@ -125,8 +124,7 @@ do_test()
"modtest")
# Do we have modules in place?
if [ -z $DRIVER_MOD ] && [ -z $GOVERNOR_MOD ]; then
echo "No driver or governor module passed with -d or -g"
exit 2;
ktap_exit_fail_msg "No driver or governor module passed with -d or -g"
fi
if [ $DRIVER_MOD ]; then
......@@ -137,8 +135,7 @@ do_test()
fi
else
if [ $count = 0 ]; then
echo "No cpu is managed by cpufreq core, exiting"
exit 2;
ktap_exit_fail_msg "No cpu is managed by cpufreq core, exiting"
fi
module_governor_test $GOVERNOR_MOD
......@@ -162,7 +159,7 @@ do_test()
;;
*)
echo "Invalid [-f] function type"
ktap_print_msg "Invalid [-f] function type"
helpme
;;
esac
......@@ -186,13 +183,25 @@ dmesg_dumps()
dmesg >> $1.dmesg_full.txt
}
ktap_print_header
# Parse arguments
parse_arguments $@
ktap_set_plan 1
# Make sure all requirements are met
prerequisite
# Run requested functions
clear_dumps $OUTFILE
do_test | tee -a $OUTFILE.txt
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
exit ${PIPESTATUS[0]};
fi
dmesg_dumps $OUTFILE
ktap_test_pass "Completed successfully"
ktap_print_totals
exit "${KSFT_PASS}"
......@@ -24,16 +24,14 @@ test_basic_insmod_rmmod()
# insert module
insmod $1
if [ $? != 0 ]; then
printf "Insmod $1 failed\n"
exit;
ktap_exit_fail_msg "Insmod $1 failed\n"
fi
printf "Removing $1 module\n"
# remove module
rmmod $1
if [ $? != 0 ]; then
printf "rmmod $1 failed\n"
exit;
ktap_exit_fail_msg "rmmod $1 failed\n"
fi
printf "\n"
......
......@@ -15,6 +15,7 @@
#include <linux/dma-buf.h>
#include <linux/dma-heap.h>
#include <drm/drm.h>
#include "../kselftest.h"
#define DEVPATH "/dev/dma_heap"
......@@ -90,14 +91,13 @@ static int dmabuf_heap_open(char *name)
char buf[256];
ret = snprintf(buf, 256, "%s/%s", DEVPATH, name);
if (ret < 0) {
printf("snprintf failed!\n");
return ret;
}
if (ret < 0)
ksft_exit_fail_msg("snprintf failed! %d\n", ret);
fd = open(buf, O_RDWR);
if (fd < 0)
printf("open %s failed!\n", buf);
ksft_exit_fail_msg("open %s failed: %s\n", buf, strerror(errno));
return fd;
}
......@@ -140,7 +140,7 @@ static int dmabuf_sync(int fd, int start_stop)
#define ONE_MEG (1024 * 1024)
static int test_alloc_and_import(char *heap_name)
static void test_alloc_and_import(char *heap_name)
{
int heap_fd = -1, dmabuf_fd = -1, importer_fd = -1;
uint32_t handle = 0;
......@@ -148,27 +148,19 @@ static int test_alloc_and_import(char *heap_name)
int ret;
heap_fd = dmabuf_heap_open(heap_name);
if (heap_fd < 0)
return -1;
printf(" Testing allocation and importing: ");
ksft_print_msg("Testing allocation and importing:\n");
ret = dmabuf_heap_alloc(heap_fd, ONE_MEG, 0, &dmabuf_fd);
if (ret) {
printf("FAIL (Allocation Failed!)\n");
ret = -1;
goto out;
ksft_test_result_fail("FAIL (Allocation Failed!) %d\n", ret);
return;
}
/* mmap and write a simple pattern */
p = mmap(NULL,
ONE_MEG,
PROT_READ | PROT_WRITE,
MAP_SHARED,
dmabuf_fd,
0);
p = mmap(NULL, ONE_MEG, PROT_READ | PROT_WRITE, MAP_SHARED, dmabuf_fd, 0);
if (p == MAP_FAILED) {
printf("FAIL (mmap() failed)\n");
ret = -1;
goto out;
ksft_test_result_fail("FAIL (mmap() failed): %s\n", strerror(errno));
goto close_and_return;
}
dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_START);
......@@ -178,71 +170,64 @@ static int test_alloc_and_import(char *heap_name)
importer_fd = open_vgem();
if (importer_fd < 0) {
ret = importer_fd;
printf("(Could not open vgem - skipping): ");
ksft_test_result_skip("Could not open vgem %d\n", importer_fd);
} else {
ret = import_vgem_fd(importer_fd, dmabuf_fd, &handle);
if (ret < 0) {
printf("FAIL (Failed to import buffer)\n");
goto out;
}
ksft_test_result(ret >= 0, "Import buffer %d\n", ret);
}
ret = dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_START);
if (ret < 0) {
printf("FAIL (DMA_BUF_SYNC_START failed!)\n");
ksft_print_msg("FAIL (DMA_BUF_SYNC_START failed!) %d\n", ret);
goto out;
}
memset(p, 0xff, ONE_MEG);
ret = dmabuf_sync(dmabuf_fd, DMA_BUF_SYNC_END);
if (ret < 0) {
printf("FAIL (DMA_BUF_SYNC_END failed!)\n");
ksft_print_msg("FAIL (DMA_BUF_SYNC_END failed!) %d\n", ret);
goto out;
}
close_handle(importer_fd, handle);
ret = 0;
printf(" OK\n");
ksft_test_result_pass("%s dmabuf sync succeeded\n", __func__);
return;
out:
if (p)
munmap(p, ONE_MEG);
if (importer_fd >= 0)
close(importer_fd);
if (dmabuf_fd >= 0)
close(dmabuf_fd);
if (heap_fd >= 0)
close(heap_fd);
ksft_test_result_fail("%s dmabuf sync failed\n", __func__);
munmap(p, ONE_MEG);
close(importer_fd);
return ret;
close_and_return:
close(dmabuf_fd);
close(heap_fd);
}
static int test_alloc_zeroed(char *heap_name, size_t size)
static void test_alloc_zeroed(char *heap_name, size_t size)
{
int heap_fd = -1, dmabuf_fd[32];
int i, j, ret;
int i, j, k, ret;
void *p = NULL;
char *c;
printf(" Testing alloced %ldk buffers are zeroed: ", size / 1024);
ksft_print_msg("Testing alloced %ldk buffers are zeroed:\n", size / 1024);
heap_fd = dmabuf_heap_open(heap_name);
if (heap_fd < 0)
return -1;
/* Allocate and fill a bunch of buffers */
for (i = 0; i < 32; i++) {
ret = dmabuf_heap_alloc(heap_fd, size, 0, &dmabuf_fd[i]);
if (ret < 0) {
printf("FAIL (Allocation (%i) failed)\n", i);
goto out;
if (ret) {
ksft_test_result_fail("FAIL (Allocation (%i) failed) %d\n", i, ret);
goto close_and_return;
}
/* mmap and fill with simple pattern */
p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, dmabuf_fd[i], 0);
if (p == MAP_FAILED) {
printf("FAIL (mmap() failed!)\n");
ret = -1;
goto out;
ksft_test_result_fail("FAIL (mmap() failed!): %s\n", strerror(errno));
goto close_and_return;
}
dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_START);
memset(p, 0xff, size);
dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_END);
......@@ -251,48 +236,47 @@ static int test_alloc_zeroed(char *heap_name, size_t size)
/* close them all */
for (i = 0; i < 32; i++)
close(dmabuf_fd[i]);
ksft_test_result_pass("Allocate and fill a bunch of buffers\n");
/* Allocate and validate all buffers are zeroed */
for (i = 0; i < 32; i++) {
ret = dmabuf_heap_alloc(heap_fd, size, 0, &dmabuf_fd[i]);
if (ret < 0) {
printf("FAIL (Allocation (%i) failed)\n", i);
goto out;
ksft_test_result_fail("FAIL (Allocation (%i) failed) %d\n", i, ret);
goto close_and_return;
}
/* mmap and validate everything is zero */
p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, dmabuf_fd[i], 0);
if (p == MAP_FAILED) {
printf("FAIL (mmap() failed!)\n");
ret = -1;
goto out;
ksft_test_result_fail("FAIL (mmap() failed!): %s\n", strerror(errno));
goto close_and_return;
}
dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_START);
c = (char *)p;
for (j = 0; j < size; j++) {
if (c[j] != 0) {
printf("FAIL (Allocated buffer not zeroed @ %i)\n", j);
break;
ksft_print_msg("FAIL (Allocated buffer not zeroed @ %i)\n", j);
dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_END);
munmap(p, size);
goto out;
}
}
dmabuf_sync(dmabuf_fd[i], DMA_BUF_SYNC_END);
munmap(p, size);
}
/* close them all */
for (i = 0; i < 32; i++)
close(dmabuf_fd[i]);
close(heap_fd);
printf("OK\n");
return 0;
out:
while (i > 0) {
close(dmabuf_fd[i]);
i--;
}
ksft_test_result(i == 32, "Allocate and validate all buffers are zeroed\n");
close_and_return:
/* close them all */
for (k = 0; k < i; k++)
close(dmabuf_fd[k]);
close(heap_fd);
return ret;
return;
}
/* Test the ioctl version compatibility w/ a smaller structure then expected */
......@@ -360,126 +344,97 @@ static int dmabuf_heap_alloc_newer(int fd, size_t len, unsigned int flags,
return ret;
}
static int test_alloc_compat(char *heap_name)
static void test_alloc_compat(char *heap_name)
{
int heap_fd = -1, dmabuf_fd = -1;
int ret;
int ret, heap_fd = -1, dmabuf_fd = -1;
heap_fd = dmabuf_heap_open(heap_name);
if (heap_fd < 0)
return -1;
printf(" Testing (theoretical)older alloc compat: ");
ksft_print_msg("Testing (theoretical) older alloc compat:\n");
ret = dmabuf_heap_alloc_older(heap_fd, ONE_MEG, 0, &dmabuf_fd);
if (ret) {
printf("FAIL (Older compat allocation failed!)\n");
ret = -1;
goto out;
}
close(dmabuf_fd);
printf("OK\n");
if (dmabuf_fd >= 0)
close(dmabuf_fd);
ksft_test_result(!ret, "dmabuf_heap_alloc_older\n");
printf(" Testing (theoretical)newer alloc compat: ");
ksft_print_msg("Testing (theoretical) newer alloc compat:\n");
ret = dmabuf_heap_alloc_newer(heap_fd, ONE_MEG, 0, &dmabuf_fd);
if (ret) {
printf("FAIL (Newer compat allocation failed!)\n");
ret = -1;
goto out;
}
printf("OK\n");
out:
if (dmabuf_fd >= 0)
close(dmabuf_fd);
if (heap_fd >= 0)
close(heap_fd);
ksft_test_result(!ret, "dmabuf_heap_alloc_newer\n");
return ret;
close(heap_fd);
}
static int test_alloc_errors(char *heap_name)
static void test_alloc_errors(char *heap_name)
{
int heap_fd = -1, dmabuf_fd = -1;
int ret;
heap_fd = dmabuf_heap_open(heap_name);
if (heap_fd < 0)
return -1;
printf(" Testing expected error cases: ");
ksft_print_msg("Testing expected error cases:\n");
ret = dmabuf_heap_alloc(0, ONE_MEG, 0x111111, &dmabuf_fd);
if (!ret) {
printf("FAIL (Did not see expected error (invalid fd)!)\n");
ret = -1;
goto out;
}
ksft_test_result(ret, "Error expected on invalid fd %d\n", ret);
ret = dmabuf_heap_alloc(heap_fd, ONE_MEG, 0x111111, &dmabuf_fd);
if (!ret) {
printf("FAIL (Did not see expected error (invalid heap flags)!)\n");
ret = -1;
goto out;
}
ksft_test_result(ret, "Error expected on invalid heap flags %d\n", ret);
ret = dmabuf_heap_alloc_fdflags(heap_fd, ONE_MEG,
~(O_RDWR | O_CLOEXEC), 0, &dmabuf_fd);
if (!ret) {
printf("FAIL (Did not see expected error (invalid fd flags)!)\n");
ret = -1;
goto out;
}
ksft_test_result(ret, "Error expected on invalid heap flags %d\n", ret);
printf("OK\n");
ret = 0;
out:
if (dmabuf_fd >= 0)
close(dmabuf_fd);
if (heap_fd >= 0)
close(heap_fd);
close(heap_fd);
}
return ret;
static int numer_of_heaps(void)
{
DIR *d = opendir(DEVPATH);
struct dirent *dir;
int heaps = 0;
while ((dir = readdir(d))) {
if (!strncmp(dir->d_name, ".", 2))
continue;
if (!strncmp(dir->d_name, "..", 3))
continue;
heaps++;
}
return heaps;
}
int main(void)
{
DIR *d;
struct dirent *dir;
int ret = -1;
DIR *d;
ksft_print_header();
d = opendir(DEVPATH);
if (!d) {
printf("No %s directory?\n", DEVPATH);
return -1;
ksft_print_msg("No %s directory?\n", DEVPATH);
return KSFT_SKIP;
}
while ((dir = readdir(d)) != NULL) {
ksft_set_plan(11 * numer_of_heaps());
while ((dir = readdir(d))) {
if (!strncmp(dir->d_name, ".", 2))
continue;
if (!strncmp(dir->d_name, "..", 3))
continue;
printf("Testing heap: %s\n", dir->d_name);
printf("=======================================\n");
ret = test_alloc_and_import(dir->d_name);
if (ret)
break;
ret = test_alloc_zeroed(dir->d_name, 4 * 1024);
if (ret)
break;
ret = test_alloc_zeroed(dir->d_name, ONE_MEG);
if (ret)
break;
ret = test_alloc_compat(dir->d_name);
if (ret)
break;
ret = test_alloc_errors(dir->d_name);
if (ret)
break;
ksft_print_msg("Testing heap: %s\n", dir->d_name);
ksft_print_msg("=======================================\n");
test_alloc_and_import(dir->d_name);
test_alloc_zeroed(dir->d_name, 4 * 1024);
test_alloc_zeroed(dir->d_name, ONE_MEG);
test_alloc_compat(dir->d_name);
test_alloc_errors(dir->d_name);
}
closedir(d);
return ret;
ksft_finished();
}
......@@ -37,25 +37,25 @@ int main(void)
ksft_test_result_skip("error: unshare, errno %d\n", errno);
ksft_finished();
}
ksft_exit_fail_msg("error: unshare, errno %d\n", errno);
ksft_exit_fail_perror("error: unshare");
}
if (mount(NULL, "/", NULL, MS_PRIVATE | MS_REC, NULL) == -1)
ksft_exit_fail_msg("error: mount '/', errno %d\n", errno);
ksft_exit_fail_perror("error: mount '/'");
/* Require "exec" filesystem. */
if (mount(NULL, "/tmp", "ramfs", 0, NULL) == -1)
ksft_exit_fail_msg("error: mount ramfs, errno %d\n", errno);
ksft_exit_fail_perror("error: mount ramfs");
#define FILENAME "/tmp/1"
fd = creat(FILENAME, 0700);
if (fd == -1)
ksft_exit_fail_msg("error: creat, errno %d\n", errno);
ksft_exit_fail_perror("error: creat");
#define S "#!" FILENAME "\n"
if (write(fd, S, strlen(S)) != strlen(S))
ksft_exit_fail_msg("error: write, errno %d\n", errno);
ksft_exit_fail_perror("error: write");
close(fd);
......
......@@ -3,6 +3,4 @@
CFLAGS += $(KHDR_INCLUDES) -pthread
TEST_GEN_PROGS := binderfs_test
binderfs_test: binderfs_test.c ../../kselftest.h ../../kselftest_harness.h
include ../../lib.mk
......@@ -3,6 +3,7 @@
#define _GNU_SOURCE
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <sched.h>
#include <fcntl.h>
......
......@@ -255,7 +255,13 @@ prlog() { # messages
[ "$LOG_FILE" ] && printf "$*$newline" | strip_esc >> $LOG_FILE
}
catlog() { #file
cat $1
if [ "${KTAP}" = "1" ]; then
cat $1 | while read line ; do
echo "# $line"
done
else
cat $1
fi
[ "$LOG_FILE" ] && cat $1 | strip_esc >> $LOG_FILE
}
prlog "=== Ftrace unit tests ==="
......
......@@ -5,4 +5,4 @@
#
# Copyright (C) Arm Ltd., 2023
./ftracetest -K
./ftracetest -K -v
......@@ -53,7 +53,7 @@ fi
echo > dynamic_events
if [ "$FIELDS" ] ; then
if [ "$FIELDS" -a "$FPROBES" ] ; then
echo "t:tpevent ${TP2} obj_size=s->object_size" >> dynamic_events
echo "f:fpevent ${TP3}%return path=\$retval->name:string" >> dynamic_events
echo "t:tpevent2 ${TP4} p->se.group_node.next->prev" >> dynamic_events
......
......@@ -11,7 +11,7 @@ echo 1 > events/tests/enable
echo > trace
cat trace > /dev/null
function streq() {
streq() {
test $1 = $2
}
......
......@@ -11,7 +11,7 @@ echo 1 > events/kprobes/enable
echo > trace
cat trace > /dev/null
function streq() {
streq() {
test $1 = $2
}
......
......@@ -198,13 +198,12 @@ int main(int argc, char **argv)
struct msgque_data msgque;
if (getuid() != 0)
return ksft_exit_skip(
"Please run the test as root - Exiting.\n");
ksft_exit_skip("Please run the test as root - Exiting.\n");
msgque.key = ftok(argv[0], 822155650);
if (msgque.key == -1) {
printf("Can't make key: %d\n", -errno);
return ksft_exit_fail();
ksft_exit_fail();
}
msgque.msq_id = msgget(msgque.key, IPC_CREAT | IPC_EXCL | 0666);
......@@ -243,13 +242,13 @@ int main(int argc, char **argv)
printf("Failed to test queue: %d\n", err);
goto err_out;
}
return ksft_exit_pass();
ksft_exit_pass();
err_destroy:
if (msgctl(msgque.msq_id, IPC_RMID, NULL)) {
printf("Failed to destroy queue: %d\n", -errno);
return ksft_exit_fail();
ksft_exit_fail();
}
err_out:
return ksft_exit_fail();
ksft_exit_fail();
}
......@@ -16,10 +16,12 @@
* For each test, report any progress, debugging, etc with:
*
* ksft_print_msg(fmt, ...);
* ksft_perror(msg);
*
* and finally report the pass/fail/skip/xfail state of the test with one of:
*
* ksft_test_result(condition, fmt, ...);
* ksft_test_result_report(result, fmt, ...);
* ksft_test_result_pass(fmt, ...);
* ksft_test_result_fail(fmt, ...);
* ksft_test_result_skip(fmt, ...);
......@@ -39,6 +41,7 @@
* the program is aborting before finishing all tests):
*
* ksft_exit_fail_msg(fmt, ...);
* ksft_exit_fail_perror(msg);
*
*/
#ifndef __KSELFTEST_H
......@@ -305,13 +308,34 @@ void ksft_test_result_code(int exit_code, const char *test_name,
printf("\n");
}
static inline __noreturn int ksft_exit_pass(void)
/**
* ksft_test_result() - Report test success based on truth of condition
*
* @condition: if true, report test success, otherwise failure.
*/
#define ksft_test_result_report(result, fmt, ...) do { \
switch (result) { \
case KSFT_PASS: \
ksft_test_result_pass(fmt, ##__VA_ARGS__); \
break; \
case KSFT_FAIL: \
ksft_test_result_fail(fmt, ##__VA_ARGS__); \
break; \
case KSFT_XFAIL: \
ksft_test_result_xfail(fmt, ##__VA_ARGS__); \
break; \
case KSFT_SKIP: \
ksft_test_result_skip(fmt, ##__VA_ARGS__); \
break; \
} } while (0)
static inline __noreturn void ksft_exit_pass(void)
{
ksft_print_cnts();
exit(KSFT_PASS);
}
static inline __noreturn int ksft_exit_fail(void)
static inline __noreturn void ksft_exit_fail(void)
{
ksft_print_cnts();
exit(KSFT_FAIL);
......@@ -338,7 +362,7 @@ static inline __noreturn int ksft_exit_fail(void)
ksft_cnt.ksft_xfail + \
ksft_cnt.ksft_xskip)
static inline __noreturn __printf(1, 2) int ksft_exit_fail_msg(const char *msg, ...)
static inline __noreturn __printf(1, 2) void ksft_exit_fail_msg(const char *msg, ...)
{
int saved_errno = errno;
va_list args;
......@@ -353,19 +377,32 @@ static inline __noreturn __printf(1, 2) int ksft_exit_fail_msg(const char *msg,
exit(KSFT_FAIL);
}
static inline __noreturn int ksft_exit_xfail(void)
static inline __noreturn void ksft_exit_fail_perror(const char *msg)
{
#ifndef NOLIBC
ksft_exit_fail_msg("%s: %s (%d)\n", msg, strerror(errno), errno);
#else
/*
* nolibc doesn't provide strerror() and it seems
* inappropriate to add one, just print the errno.
*/
ksft_exit_fail_msg("%s: %d)\n", msg, errno);
#endif
}
static inline __noreturn void ksft_exit_xfail(void)
{
ksft_print_cnts();
exit(KSFT_XFAIL);
}
static inline __noreturn int ksft_exit_xpass(void)
static inline __noreturn void ksft_exit_xpass(void)
{
ksft_print_cnts();
exit(KSFT_XPASS);
}
static inline __noreturn __printf(1, 2) int ksft_exit_skip(const char *msg, ...)
static inline __noreturn __printf(1, 2) void ksft_exit_skip(const char *msg, ...)
{
int saved_errno = errno;
va_list args;
......
......@@ -43,7 +43,7 @@ __ktap_test() {
directive="$3" # optional
local directive_str=
[[ ! -z "$directive" ]] && directive_str="# $directive"
[ ! -z "$directive" ] && directive_str="# $directive"
echo $result $KTAP_TESTNO $description $directive_str
......@@ -99,7 +99,7 @@ ktap_exit_fail_msg() {
ktap_finished() {
ktap_print_totals
if [ $(("$KTAP_CNT_PASS" + "$KTAP_CNT_SKIP")) -eq "$KSFT_NUM_TESTS" ]; then
if [ $((KTAP_CNT_PASS + KTAP_CNT_SKIP)) -eq "$KSFT_NUM_TESTS" ]; then
exit "$KSFT_PASS"
else
exit "$KSFT_FAIL"
......
......@@ -244,6 +244,7 @@ l4_test()
l5_test()
{
tests=$(find $(dirname "$test") -type f -name "*.mk")
[[ -z "${tests// }" ]] && return
test_libs=$(grep "^IOURING_EXTRA_LIBS +\?=" $tests | \
cut -d "=" -f 2)
......
......@@ -51,7 +51,7 @@
#define __KSELFTEST_HARNESS_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
static_assert(0, "kselftest harness requires _GNU_SOURCE to be defined");
#endif
#include <asm/types.h>
#include <ctype.h>
......
......@@ -7,6 +7,8 @@ else ifneq ($(filter -%,$(LLVM)),)
LLVM_SUFFIX := $(LLVM)
endif
CLANG := $(LLVM_PREFIX)clang$(LLVM_SUFFIX)
CLANG_TARGET_FLAGS_arm := arm-linux-gnueabi
CLANG_TARGET_FLAGS_arm64 := aarch64-linux-gnu
CLANG_TARGET_FLAGS_hexagon := hexagon-linux-musl
......@@ -18,7 +20,13 @@ CLANG_TARGET_FLAGS_riscv := riscv64-linux-gnu
CLANG_TARGET_FLAGS_s390 := s390x-linux-gnu
CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu
CLANG_TARGET_FLAGS_x86_64 := x86_64-linux-gnu
CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(ARCH))
# Default to host architecture if ARCH is not explicitly given.
ifeq ($(ARCH),)
CLANG_TARGET_FLAGS := $(shell $(CLANG) -print-target-triple)
else
CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(ARCH))
endif
ifeq ($(CROSS_COMPILE),)
ifeq ($(CLANG_TARGET_FLAGS),)
......@@ -30,7 +38,7 @@ else
CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%))
endif # CROSS_COMPILE
CC := $(LLVM_PREFIX)clang$(LLVM_SUFFIX) $(CLANG_FLAGS) -fintegrated-as
CC := $(CLANG) $(CLANG_FLAGS) -fintegrated-as
else
CC := $(CROSS_COMPILE)gcc
endif # LLVM
......@@ -45,7 +53,7 @@ selfdir = $(realpath $(dir $(filter %/lib.mk,$(MAKEFILE_LIST))))
top_srcdir = $(selfdir)/../../..
ifeq ($(KHDR_INCLUDES),)
KHDR_INCLUDES := -isystem $(top_srcdir)/usr/include
KHDR_INCLUDES := -D_GNU_SOURCE -isystem $(top_srcdir)/usr/include
endif
# The following are built by lib.mk common compile rules.
......
......@@ -69,5 +69,5 @@ int main(int argc, char **argv)
/* Multi-threaded */
test_mt_membarrier();
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -24,5 +24,5 @@ int main(int argc, char **argv)
test_membarrier_get_registrations(/*cmd=*/0);
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -177,7 +177,7 @@ int main(int argc, char **argv)
ksft_print_header();
if (prereq() || geteuid())
return ksft_exit_skip("Prerequisites unsatisfied\n");
ksft_exit_skip("Prerequisites unsatisfied\n");
ksft_set_plan(1);
......@@ -225,7 +225,7 @@ int main(int argc, char **argv)
}
if (check_compaction(mem_free, hugepage_size) == 0)
return ksft_exit_pass();
ksft_exit_pass();
return ksft_exit_fail();
ksft_exit_fail();
}
......@@ -1779,5 +1779,5 @@ int main(int argc, char **argv)
if (err)
ksft_exit_fail_msg("%d out of %d tests failed\n",
err, ksft_test_num());
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -456,5 +456,5 @@ int main(int argc, char **argv)
if (err)
ksft_exit_fail_msg("%d out of %d tests failed\n",
err, ksft_test_num());
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -228,7 +228,7 @@ int main(int argc, char **argv)
break;
}
ksft_test_result_skip("Please run this test as root\n");
return ksft_exit_pass();
ksft_exit_pass();
}
p = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, filed, 0);
......@@ -267,5 +267,5 @@ int main(int argc, char **argv)
free(tid);
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -646,5 +646,5 @@ int main(int argc, char **argv)
if (err)
ksft_exit_fail_msg("%d out of %d tests failed\n",
err, ksft_test_num());
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -307,5 +307,5 @@ int main(int argc, char **argv)
if (err)
ksft_exit_fail_msg("%d out of %d tests failed\n",
err, ksft_test_num());
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -375,5 +375,5 @@ int main(void)
if (err)
ksft_exit_fail_msg("%d out of %d tests failed\n",
err, ksft_test_num());
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -1484,7 +1484,7 @@ int main(int argc, char *argv[])
ksft_print_header();
if (init_uffd())
return ksft_exit_pass();
ksft_exit_pass();
ksft_set_plan(115);
......@@ -1660,5 +1660,5 @@ int main(int argc, char *argv[])
userfaultfd_tests();
close(pagemap_fd);
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -209,5 +209,5 @@ int main(int argc, char **argv)
close(pagemap_fd);
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -307,5 +307,5 @@ int main(int argc, char **argv)
test_pidfd_fdinfo_nspid();
test_pidfd_dead_fdinfo();
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -159,5 +159,7 @@ int main(int argc, char **argv)
if (pidfd >= 0)
close(pidfd);
return !ret ? ksft_exit_pass() : ksft_exit_fail();
if (ret)
ksft_exit_fail();
ksft_exit_pass();
}
......@@ -112,5 +112,5 @@ int main(int argc, char **argv)
}
ksft_test_result_pass("pidfd poll test: pass\n");
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -572,5 +572,5 @@ int main(int argc, char **argv)
test_pidfd_send_signal_exited_fail();
test_pidfd_send_signal_recycled_pid_fail();
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -23,7 +23,7 @@ count_tests() {
total_tests=0
for i in $SUPPLIES; do
total_tests=$(("$total_tests" + "$NUM_TESTS"))
total_tests=$((total_tests + NUM_TESTS))
done
echo "$total_tests"
......
......@@ -5,6 +5,8 @@ CFLAGS += $(KHDR_INCLUDES)
TEST_GEN_PROGS := resctrl_tests
LOCAL_HDRS += $(wildcard *.h)
include ../lib.mk
$(OUTPUT)/resctrl_tests: $(wildcard *.[ch])
$(OUTPUT)/resctrl_tests: $(wildcard *.c)
......@@ -128,7 +128,7 @@ static int check_results(struct resctrl_val_param *param, const char *cache_type
return fail;
}
void cat_test_cleanup(void)
static void cat_test_cleanup(void)
{
remove(RESULT_FILE_NAME);
}
......@@ -284,13 +284,10 @@ static int cat_run_test(const struct resctrl_test *test, const struct user_param
ret = cat_test(test, uparams, &param, span, start_mask);
if (ret)
goto out;
return ret;
ret = check_results(&param, test->resource,
cache_total_size, full_cache_mask, start_mask);
out:
cat_test_cleanup();
return ret;
}
......@@ -373,6 +370,7 @@ struct resctrl_test l3_cat_test = {
.resource = "L3",
.feature_check = test_resource_feature_check,
.run_test = cat_run_test,
.cleanup = cat_test_cleanup,
};
struct resctrl_test l3_noncont_cat_test = {
......
......@@ -40,11 +40,11 @@ static int show_results_info(unsigned long sum_llc_val, int no_of_bits,
int ret;
avg_llc_val = sum_llc_val / num_of_runs;
avg_diff = (long)abs(cache_span - avg_llc_val);
avg_diff = (long)(cache_span - avg_llc_val);
diff_percent = ((float)cache_span - avg_llc_val) / cache_span * 100;
ret = platform && abs((int)diff_percent) > max_diff_percent &&
abs(avg_diff) > max_diff;
labs(avg_diff) > max_diff;
ksft_print_msg("%s Check cache miss rate within %lu%%\n",
ret ? "Fail:" : "Pass:", max_diff_percent);
......@@ -91,7 +91,7 @@ static int check_results(struct resctrl_val_param *param, size_t span, int no_of
MAX_DIFF, MAX_DIFF_PERCENT, runs - 1, true);
}
void cmt_test_cleanup(void)
static void cmt_test_cleanup(void)
{
remove(RESULT_FILE_NAME);
}
......@@ -161,7 +161,6 @@ static int cmt_run_test(const struct resctrl_test *test, const struct user_param
ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
out:
cmt_test_cleanup();
free(span_str);
return ret;
......@@ -178,4 +177,5 @@ struct resctrl_test cmt_test = {
.resource = "L3",
.feature_check = cmt_feature_check,
.run_test = cmt_run_test,
.cleanup = cmt_test_cleanup,
};
......@@ -60,8 +60,8 @@ static bool show_mba_info(unsigned long *bw_imc, unsigned long *bw_resc)
/* Memory bandwidth from 100% down to 10% */
for (allocation = 0; allocation < ALLOCATION_MAX / ALLOCATION_STEP;
allocation++) {
unsigned long avg_bw_imc, avg_bw_resc;
unsigned long sum_bw_imc = 0, sum_bw_resc = 0;
long avg_bw_imc, avg_bw_resc;
int avg_diff_per;
float avg_diff;
......@@ -137,7 +137,7 @@ static int check_results(void)
return show_mba_info(bw_imc, bw_resc);
}
void mba_test_cleanup(void)
static void mba_test_cleanup(void)
{
remove(RESULT_FILE_NAME);
}
......@@ -158,13 +158,10 @@ static int mba_run_test(const struct resctrl_test *test, const struct user_param
ret = resctrl_val(test, uparams, uparams->benchmark_cmd, &param);
if (ret)
goto out;
return ret;
ret = check_results();
out:
mba_test_cleanup();
return ret;
}
......@@ -180,4 +177,5 @@ struct resctrl_test mba_test = {
.vendor_specific = ARCH_INTEL,
.feature_check = mba_feature_check,
.run_test = mba_run_test,
.cleanup = mba_test_cleanup,
};
......@@ -17,8 +17,8 @@
static int
show_bw_info(unsigned long *bw_imc, unsigned long *bw_resc, size_t span)
{
unsigned long avg_bw_imc = 0, avg_bw_resc = 0;
unsigned long sum_bw_imc = 0, sum_bw_resc = 0;
long avg_bw_imc = 0, avg_bw_resc = 0;
int runs, ret, avg_diff_per;
float avg_diff = 0;
......@@ -105,7 +105,7 @@ static int mbm_setup(const struct resctrl_test *test,
return ret;
}
void mbm_test_cleanup(void)
static void mbm_test_cleanup(void)
{
remove(RESULT_FILE_NAME);
}
......@@ -126,15 +126,12 @@ static int mbm_run_test(const struct resctrl_test *test, const struct user_param
ret = resctrl_val(test, uparams, uparams->benchmark_cmd, &param);
if (ret)
goto out;
return ret;
ret = check_results(DEFAULT_SPAN);
if (ret && (get_vendor() == ARCH_INTEL))
ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n");
out:
mbm_test_cleanup();
return ret;
}
......@@ -150,4 +147,5 @@ struct resctrl_test mbm_test = {
.vendor_specific = ARCH_INTEL,
.feature_check = mbm_feature_check,
.run_test = mbm_run_test,
.cleanup = mbm_test_cleanup,
};
......@@ -72,6 +72,7 @@ struct user_params {
* @disabled: Test is disabled
* @feature_check: Callback to check required resctrl features
* @run_test: Callback to run the test
* @cleanup: Callback to cleanup after the test
*/
struct resctrl_test {
const char *name;
......@@ -82,6 +83,7 @@ struct resctrl_test {
bool (*feature_check)(const struct resctrl_test *test);
int (*run_test)(const struct resctrl_test *test,
const struct user_params *uparams);
void (*cleanup)(void);
};
/*
......@@ -156,9 +158,6 @@ int resctrl_val(const struct resctrl_test *test,
const struct user_params *uparams,
const char * const *benchmark_cmd,
struct resctrl_val_param *param);
void tests_cleanup(void);
void mbm_test_cleanup(void);
void mba_test_cleanup(void);
unsigned long create_bit_mask(unsigned int start, unsigned int len);
unsigned int count_contiguous_bits(unsigned long val, unsigned int *start);
int get_full_cbm(const char *cache_type, unsigned long *mask);
......@@ -166,11 +165,9 @@ int get_mask_no_shareable(const char *cache_type, unsigned long *mask);
int get_cache_size(int cpu_no, const char *cache_type, unsigned long *cache_size);
int resource_info_unsigned_get(const char *resource, const char *filename, unsigned int *val);
void ctrlc_handler(int signum, siginfo_t *info, void *ptr);
int signal_handler_register(void);
int signal_handler_register(const struct resctrl_test *test);
void signal_handler_unregister(void);
void cat_test_cleanup(void);
unsigned int count_bits(unsigned long n);
void cmt_test_cleanup(void);
void perf_event_attr_initialize(struct perf_event_attr *pea, __u64 config);
void perf_event_initialize_read_format(struct perf_event_read *pe_read);
......
......@@ -81,19 +81,11 @@ static void cmd_help(void)
printf("\t-h: help\n");
}
void tests_cleanup(void)
{
mbm_test_cleanup();
mba_test_cleanup();
cmt_test_cleanup();
cat_test_cleanup();
}
static int test_prepare(void)
static int test_prepare(const struct resctrl_test *test)
{
int res;
res = signal_handler_register();
res = signal_handler_register(test);
if (res) {
ksft_print_msg("Failed to register signal handler\n");
return res;
......@@ -108,8 +100,10 @@ static int test_prepare(void)
return 0;
}
static void test_cleanup(void)
static void test_cleanup(const struct resctrl_test *test)
{
if (test->cleanup)
test->cleanup();
umount_resctrlfs();
signal_handler_unregister();
}
......@@ -136,7 +130,7 @@ static void run_single_test(const struct resctrl_test *test, const struct user_p
ksft_print_msg("Starting %s test ...\n", test->name);
if (test_prepare()) {
if (test_prepare(test)) {
ksft_exit_fail_msg("Abnormal failure when preparing for the test\n");
return;
}
......@@ -151,7 +145,7 @@ static void run_single_test(const struct resctrl_test *test, const struct user_p
ksft_test_result(!ret, "%s: test\n", test->name);
cleanup:
test_cleanup();
test_cleanup(test);
}
static void init_user_params(struct user_params *uparams)
......@@ -253,13 +247,13 @@ int main(int argc, char **argv)
* 2. We execute perf commands
*/
if (geteuid() != 0)
return ksft_exit_skip("Not running as root. Skipping...\n");
ksft_exit_skip("Not running as root. Skipping...\n");
if (!check_resctrlfs_support())
return ksft_exit_skip("resctrl FS does not exist. Enable X86_CPU_RESCTRL config option.\n");
ksft_exit_skip("resctrl FS does not exist. Enable X86_CPU_RESCTRL config option.\n");
if (umount_resctrlfs())
return ksft_exit_skip("resctrl FS unmount failed.\n");
ksft_exit_skip("resctrl FS unmount failed.\n");
filter_dmesg();
......
......@@ -62,6 +62,7 @@ struct imc_counter_config {
static char mbm_total_path[1024];
static int imcs;
static struct imc_counter_config imc_counters_config[MAX_IMCS][2];
static const struct resctrl_test *current_test;
void membw_initialize_perf_event_attr(int i, int j)
{
......@@ -472,7 +473,8 @@ void ctrlc_handler(int signum, siginfo_t *info, void *ptr)
if (bm_pid)
kill(bm_pid, SIGKILL);
umount_resctrlfs();
tests_cleanup();
if (current_test && current_test->cleanup)
current_test->cleanup();
ksft_print_msg("Ending\n\n");
exit(EXIT_SUCCESS);
......@@ -482,13 +484,14 @@ void ctrlc_handler(int signum, siginfo_t *info, void *ptr)
* Register CTRL-C handler for parent, as it has to kill
* child process before exiting.
*/
int signal_handler_register(void)
int signal_handler_register(const struct resctrl_test *test)
{
struct sigaction sigact = {};
int ret = 0;
bm_pid = 0;
current_test = test;
sigact.sa_sigaction = ctrlc_handler;
sigemptyset(&sigact.sa_mask);
sigact.sa_flags = SA_SIGINFO;
......@@ -510,6 +513,7 @@ void signal_handler_unregister(void)
{
struct sigaction sigact = {};
current_test = NULL;
sigact.sa_handler = SIG_DFL;
sigemptyset(&sigact.sa_mask);
if (sigaction(SIGINT, &sigact, NULL) ||
......
......@@ -12,7 +12,7 @@ OBJCOPY := $(CROSS_COMPILE)objcopy
endif
INCLUDES := -I$(top_srcdir)/tools/include
HOST_CFLAGS := -Wall -Werror -g $(INCLUDES) -fPIC
HOST_CFLAGS := -Wall -Werror $(KHDR_INCLUDES) -g $(INCLUDES) -fPIC
HOST_LDFLAGS := -z noexecstack -lcrypto
ENCL_CFLAGS += -Wall -Werror -static-pie -nostdlib -ffreestanding -fPIE \
-fno-stack-protector -mrdrnd $(INCLUDES)
......
// SPDX-License-Identifier: GPL-2.0
/* Copyright(c) 2016-20 Intel Corporation. */
#define _GNU_SOURCE
#include <assert.h>
#include <getopt.h>
#include <stdbool.h>
......
......@@ -109,6 +109,5 @@ int main(void)
ksft_exit_fail_msg("%d out of %d sync tests failed\n",
err, ksft_test_num());
/* need this return to keep gcc happy */
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -205,7 +205,7 @@ int main(int argc, char **argv)
adjtimex(&tx1);
if (err)
return ksft_exit_fail();
ksft_exit_fail();
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -173,6 +173,6 @@ int main(void)
timer_delete(tm1);
}
if (final_ret)
return ksft_exit_fail();
return ksft_exit_pass();
ksft_exit_fail();
ksft_exit_pass();
}
......@@ -89,8 +89,8 @@ int main(int argc, char **argv)
if (ret) {
printf("[FAIL]");
return ksft_exit_fail();
ksft_exit_fail();
}
printf("[OK]");
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -257,7 +257,7 @@ int main(int argc, char **argv)
set_frequency(0.0);
if (fails)
return ksft_exit_fail();
ksft_exit_fail();
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -268,7 +268,7 @@ int main(int argc, char **argv)
if (ret < 0) {
printf("Error: Problem setting STA_INS/STA_DEL!: %s\n",
time_state_str(ret));
return ksft_exit_fail();
ksft_exit_fail();
}
/* Validate STA_INS was set */
......@@ -277,7 +277,7 @@ int main(int argc, char **argv)
if (tx.status != STA_INS && tx.status != STA_DEL) {
printf("Error: STA_INS/STA_DEL not set!: %s\n",
time_state_str(ret));
return ksft_exit_fail();
ksft_exit_fail();
}
if (tai_time) {
......@@ -295,7 +295,7 @@ int main(int argc, char **argv)
se.sigev_value.sival_int = 0;
if (timer_create(CLOCK_REALTIME, &se, &tm1) == -1) {
printf("Error: timer_create failed\n");
return ksft_exit_fail();
ksft_exit_fail();
}
its1.it_value.tv_sec = next_leap;
its1.it_value.tv_nsec = 0;
......@@ -366,7 +366,7 @@ int main(int argc, char **argv)
if (error_found) {
printf("Errors observed\n");
clear_time_state();
return ksft_exit_fail();
ksft_exit_fail();
}
printf("\n");
if ((iterations != -1) && !(--iterations))
......@@ -374,5 +374,5 @@ int main(int argc, char **argv)
}
clear_time_state();
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -87,7 +87,7 @@ int main(void)
tv.tv_usec = 0;
if (settimeofday(&tv, NULL)) {
printf("Error: You're likely not running with proper (ie: root) permissions\n");
return ksft_exit_fail();
ksft_exit_fail();
}
tx.modes = 0;
adjtimex(&tx);
......@@ -104,5 +104,5 @@ int main(void)
fflush(stdout);
}
printf("[OK]\n");
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -107,8 +107,8 @@ int main(int argc, char **argv)
ret = mqueue_lat_test();
if (ret < 0) {
printf("[FAILED]\n");
return ksft_exit_fail();
ksft_exit_fail();
}
printf("[OK]\n");
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -260,16 +260,16 @@ int main(int argc, char **argv)
ksft_print_msg("based timers if other threads run on the CPU...\n");
if (check_itimer(ITIMER_VIRTUAL) < 0)
return ksft_exit_fail();
ksft_exit_fail();
if (check_itimer(ITIMER_PROF) < 0)
return ksft_exit_fail();
ksft_exit_fail();
if (check_itimer(ITIMER_REAL) < 0)
return ksft_exit_fail();
ksft_exit_fail();
if (check_timer_create(CLOCK_THREAD_CPUTIME_ID) < 0)
return ksft_exit_fail();
ksft_exit_fail();
/*
* It's unfortunately hard to reliably test a timer expiration
......@@ -281,10 +281,10 @@ int main(int argc, char **argv)
* find a better solution.
*/
if (check_timer_create(CLOCK_PROCESS_CPUTIME_ID) < 0)
return ksft_exit_fail();
ksft_exit_fail();
if (check_timer_distribution() < 0)
return ksft_exit_fail();
ksft_exit_fail();
ksft_finished();
}
......@@ -137,11 +137,11 @@ int main(int argc, char **argv)
if (tx1.offset || tx2.offset ||
tx1.freq != tx2.freq || tx1.tick != tx2.tick) {
printf(" [SKIP]\n");
return ksft_exit_skip("The clock was adjusted externally. Shutdown NTPd or other time sync daemons\n");
ksft_exit_skip("The clock was adjusted externally. Shutdown NTPd or other time sync daemons\n");
}
printf(" [FAILED]\n");
return ksft_exit_fail();
ksft_exit_fail();
}
printf(" [OK]\n");
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -128,6 +128,6 @@ int main(int argc, char *argv[])
/* restore clock */
settime(start);
if (ret)
return ksft_exit_fail();
return ksft_exit_pass();
ksft_exit_fail();
ksft_exit_pass();
}
......@@ -61,9 +61,9 @@ int main(int argc, char **argv)
ret = get_tai();
if (ret != i) {
printf("[FAILED] expected: %i got %i\n", i, ret);
return ksft_exit_fail();
ksft_exit_fail();
}
}
printf("[OK]\n");
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -278,6 +278,6 @@ int main(void)
ret |= do_timer_oneshot(clock_id, 0);
}
if (ret)
return ksft_exit_fail();
return ksft_exit_pass();
ksft_exit_fail();
ksft_exit_pass();
}
......@@ -102,9 +102,9 @@ int main(int argc, char **argv)
printf("[OK]\n");
set_tz(min, dst);
return ksft_exit_pass();
ksft_exit_pass();
err:
set_tz(min, dst);
return ksft_exit_fail();
ksft_exit_fail();
}
......@@ -70,8 +70,8 @@ int main(int argc, char **argv)
if (ret) {
printf("[FAILED]\n");
return ksft_exit_fail();
ksft_exit_fail();
}
printf("[OK]\n");
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -189,5 +189,5 @@ int main(int argc, char **argv)
/* die */
if (ret)
ksft_exit_fail();
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -320,10 +320,10 @@ int validate_set_offset(void)
int main(int argc, char **argv)
{
if (validate_freq())
return ksft_exit_fail();
ksft_exit_fail();
if (validate_set_offset())
return ksft_exit_fail();
ksft_exit_fail();
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -47,42 +47,60 @@ int main(int argc, char **argv)
int r;
char tty[PATH_MAX] = {};
struct stat st1, st2;
int result = KSFT_FAIL;
ksft_print_header();
ksft_set_plan(1);
r = readlink("/proc/self/fd/0", tty, PATH_MAX);
if (r < 0)
ksft_exit_fail_msg("readlink on /proc/self/fd/0 failed: %m\n");
if (r < 0) {
ksft_print_msg("readlink on /proc/self/fd/0 failed: %m\n");
goto out;
}
if (!tty_valid(tty)) {
ksft_print_msg("invalid tty path '%s'\n", tty);
result = KSFT_SKIP;
goto out;
if (!tty_valid(tty))
ksft_exit_skip("invalid tty path '%s'\n", tty);
}
r = stat(tty, &st1);
if (r < 0)
ksft_exit_fail_msg("stat failed on tty path '%s': %m\n", tty);
if (r < 0) {
ksft_print_msg("stat failed on tty path '%s': %m\n", tty);
goto out;
}
/* We need to wait at least 8 seconds in order to observe timestamp change */
/* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fbf47635315ab308c9b58a1ea0906e711a9228de */
sleep(10);
r = write_dev_tty();
if (r < 0)
ksft_exit_fail_msg("failed to write to /dev/tty: %s\n",
strerror(-r));
if (r < 0) {
ksft_print_msg("failed to write to /dev/tty: %s\n",
strerror(-r));
goto out;
}
r = stat(tty, &st2);
if (r < 0)
ksft_exit_fail_msg("stat failed on tty path '%s': %m\n", tty);
if (r < 0) {
ksft_print_msg("stat failed on tty path '%s': %m\n", tty);
goto out;
}
/* We wrote to the terminal so timestamps should have been updated */
if (st1.st_atim.tv_sec == st2.st_atim.tv_sec &&
st1.st_mtim.tv_sec == st2.st_mtim.tv_sec) {
ksft_test_result_fail("tty timestamps not updated\n");
ksft_exit_fail();
ksft_print_msg("tty timestamps not updated\n");
goto out;
}
ksft_test_result_pass(
ksft_print_msg(
"timestamps of terminal '%s' updated after write to /dev/tty\n", tty);
return EXIT_SUCCESS;
result = KSFT_PASS;
out:
ksft_test_result_report(result, "tty_tstamp_update\n");
ksft_finished();
}
......@@ -1237,5 +1237,5 @@ int main(int argc, char **argv)
ksft_set_plan(tests_cnt);
return ksft_exit_pass();
ksft_exit_pass();
}
......@@ -19,6 +19,7 @@
#include <sys/auxv.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include "../kselftest.h"
#define PAGE_SIZE 4096
......@@ -29,13 +30,13 @@ static int try_to_remap(void *vdso_addr, unsigned long size)
/* Searching for memory location where to remap */
dest_addr = mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (dest_addr == MAP_FAILED) {
printf("[WARN]\tmmap failed (%d): %m\n", errno);
ksft_print_msg("WARN: mmap failed (%d): %m\n", errno);
return 0;
}
printf("[NOTE]\tMoving vDSO: [%p, %#lx] -> [%p, %#lx]\n",
vdso_addr, (unsigned long)vdso_addr + size,
dest_addr, (unsigned long)dest_addr + size);
ksft_print_msg("Moving vDSO: [%p, %#lx] -> [%p, %#lx]\n",
vdso_addr, (unsigned long)vdso_addr + size,
dest_addr, (unsigned long)dest_addr + size);
fflush(stdout);
new_addr = mremap(vdso_addr, size, size,
......@@ -43,10 +44,10 @@ static int try_to_remap(void *vdso_addr, unsigned long size)
if ((unsigned long)new_addr == (unsigned long)-1) {
munmap(dest_addr, size);
if (errno == EINVAL) {
printf("[NOTE]\tvDSO partial move failed, will try with bigger size\n");
ksft_print_msg("vDSO partial move failed, will try with bigger size\n");
return -1; /* Retry with larger */
}
printf("[FAIL]\tmremap failed (%d): %m\n", errno);
ksft_print_msg("[FAIL]\tmremap failed (%d): %m\n", errno);
return 1;
}
......@@ -58,11 +59,12 @@ int main(int argc, char **argv, char **envp)
{
pid_t child;
ksft_print_header();
ksft_set_plan(1);
child = fork();
if (child == -1) {
printf("[WARN]\tfailed to fork (%d): %m\n", errno);
return 1;
}
if (child == -1)
ksft_exit_fail_msg("failed to fork (%d): %m\n", errno);
if (child == 0) {
unsigned long vdso_size = PAGE_SIZE;
......@@ -70,9 +72,9 @@ int main(int argc, char **argv, char **envp)
int ret = -1;
auxval = getauxval(AT_SYSINFO_EHDR);
printf("\tAT_SYSINFO_EHDR is %#lx\n", auxval);
ksft_print_msg("AT_SYSINFO_EHDR is %#lx\n", auxval);
if (!auxval || auxval == -ENOENT) {
printf("[WARN]\tgetauxval failed\n");
ksft_print_msg("WARN: getauxval failed\n");
return 0;
}
......@@ -92,16 +94,13 @@ int main(int argc, char **argv, char **envp)
int status;
if (waitpid(child, &status, 0) != child ||
!WIFEXITED(status)) {
printf("[FAIL]\tmremap() of the vDSO does not work on this kernel!\n");
return 1;
} else if (WEXITSTATUS(status) != 0) {
printf("[FAIL]\tChild failed with %d\n",
WEXITSTATUS(status));
return 1;
}
printf("[OK]\n");
!WIFEXITED(status))
ksft_test_result_fail("mremap() of the vDSO does not work on this kernel!\n");
else if (WEXITSTATUS(status) != 0)
ksft_test_result_fail("Child failed with %d\n", WEXITSTATUS(status));
else
ksft_test_result_pass("%s\n", __func__);
}
return 0;
ksft_finished();
}
......@@ -21,6 +21,13 @@
#include <sys/uio.h>
#include "helpers.h"
#include "../kselftest.h"
#ifdef __x86_64__
#define TOTAL_TESTS 13
#else
#define TOTAL_TESTS 8
#endif
#ifdef __x86_64__
# define VSYS(x) (x)
......@@ -39,18 +46,6 @@
/* max length of lines in /proc/self/maps - anything longer is skipped here */
#define MAPS_LINE_LEN 128
static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
err(1, "sigaction");
}
/* vsyscalls and vDSO */
bool vsyscall_map_r = false, vsyscall_map_x = false;
......@@ -75,83 +70,25 @@ static void init_vdso(void)
if (!vdso)
vdso = dlopen("linux-gate.so.1", RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
if (!vdso) {
printf("[WARN]\tfailed to find vDSO\n");
ksft_print_msg("[WARN] failed to find vDSO\n");
return;
}
vdso_gtod = (gtod_t)dlsym(vdso, "__vdso_gettimeofday");
if (!vdso_gtod)
printf("[WARN]\tfailed to find gettimeofday in vDSO\n");
ksft_print_msg("[WARN] failed to find gettimeofday in vDSO\n");
vdso_gettime = (vgettime_t)dlsym(vdso, "__vdso_clock_gettime");
if (!vdso_gettime)
printf("[WARN]\tfailed to find clock_gettime in vDSO\n");
ksft_print_msg("[WARN] failed to find clock_gettime in vDSO\n");
vdso_time = (time_func_t)dlsym(vdso, "__vdso_time");
if (!vdso_time)
printf("[WARN]\tfailed to find time in vDSO\n");
ksft_print_msg("[WARN] failed to find time in vDSO\n");
vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu");
if (!vdso_getcpu)
printf("[WARN]\tfailed to find getcpu in vDSO\n");
}
static int init_vsys(void)
{
#ifdef __x86_64__
int nerrs = 0;
FILE *maps;
char line[MAPS_LINE_LEN];
bool found = false;
maps = fopen("/proc/self/maps", "r");
if (!maps) {
printf("[WARN]\tCould not open /proc/self/maps -- assuming vsyscall is r-x\n");
vsyscall_map_r = true;
return 0;
}
while (fgets(line, MAPS_LINE_LEN, maps)) {
char r, x;
void *start, *end;
char name[MAPS_LINE_LEN];
/* sscanf() is safe here as strlen(name) >= strlen(line) */
if (sscanf(line, "%p-%p %c-%cp %*x %*x:%*x %*u %s",
&start, &end, &r, &x, name) != 5)
continue;
if (strcmp(name, "[vsyscall]"))
continue;
printf("\tvsyscall map: %s", line);
if (start != (void *)0xffffffffff600000 ||
end != (void *)0xffffffffff601000) {
printf("[FAIL]\taddress range is nonsense\n");
nerrs++;
}
printf("\tvsyscall permissions are %c-%c\n", r, x);
vsyscall_map_r = (r == 'r');
vsyscall_map_x = (x == 'x');
found = true;
break;
}
fclose(maps);
if (!found) {
printf("\tno vsyscall map in /proc/self/maps\n");
vsyscall_map_r = false;
vsyscall_map_x = false;
}
return nerrs;
#else
return 0;
#endif
ksft_print_msg("[WARN] failed to find getcpu in vDSO\n");
}
/* syscalls */
......@@ -176,98 +113,76 @@ static inline long sys_getcpu(unsigned * cpu, unsigned * node,
return syscall(SYS_getcpu, cpu, node, cache);
}
static jmp_buf jmpbuf;
static volatile unsigned long segv_err;
static void sigsegv(int sig, siginfo_t *info, void *ctx_void)
{
ucontext_t *ctx = (ucontext_t *)ctx_void;
segv_err = ctx->uc_mcontext.gregs[REG_ERR];
siglongjmp(jmpbuf, 1);
}
static double tv_diff(const struct timeval *a, const struct timeval *b)
{
return (double)(a->tv_sec - b->tv_sec) +
(double)((int)a->tv_usec - (int)b->tv_usec) * 1e-6;
}
static int check_gtod(const struct timeval *tv_sys1,
const struct timeval *tv_sys2,
const struct timezone *tz_sys,
const char *which,
const struct timeval *tv_other,
const struct timezone *tz_other)
static void check_gtod(const struct timeval *tv_sys1,
const struct timeval *tv_sys2,
const struct timezone *tz_sys,
const char *which,
const struct timeval *tv_other,
const struct timezone *tz_other)
{
int nerrs = 0;
double d1, d2;
if (tz_other && (tz_sys->tz_minuteswest != tz_other->tz_minuteswest || tz_sys->tz_dsttime != tz_other->tz_dsttime)) {
printf("[FAIL] %s tz mismatch\n", which);
nerrs++;
}
if (tz_other && (tz_sys->tz_minuteswest != tz_other->tz_minuteswest ||
tz_sys->tz_dsttime != tz_other->tz_dsttime))
ksft_print_msg("%s tz mismatch\n", which);
d1 = tv_diff(tv_other, tv_sys1);
d2 = tv_diff(tv_sys2, tv_other);
printf("\t%s time offsets: %lf %lf\n", which, d1, d2);
if (d1 < 0 || d2 < 0) {
printf("[FAIL]\t%s time was inconsistent with the syscall\n", which);
nerrs++;
} else {
printf("[OK]\t%s gettimeofday()'s timeval was okay\n", which);
}
ksft_print_msg("%s time offsets: %lf %lf\n", which, d1, d2);
return nerrs;
ksft_test_result(!(d1 < 0 || d2 < 0), "%s gettimeofday()'s timeval\n", which);
}
static int test_gtod(void)
static void test_gtod(void)
{
struct timeval tv_sys1, tv_sys2, tv_vdso, tv_vsys;
struct timezone tz_sys, tz_vdso, tz_vsys;
long ret_vdso = -1;
long ret_vsys = -1;
int nerrs = 0;
printf("[RUN]\ttest gettimeofday()\n");
ksft_print_msg("test gettimeofday()\n");
if (sys_gtod(&tv_sys1, &tz_sys) != 0)
err(1, "syscall gettimeofday");
ksft_exit_fail_msg("syscall gettimeofday: %s\n", strerror(errno));
if (vdso_gtod)
ret_vdso = vdso_gtod(&tv_vdso, &tz_vdso);
if (vsyscall_map_x)
ret_vsys = vgtod(&tv_vsys, &tz_vsys);
if (sys_gtod(&tv_sys2, &tz_sys) != 0)
err(1, "syscall gettimeofday");
ksft_exit_fail_msg("syscall gettimeofday: %s\n", strerror(errno));
if (vdso_gtod) {
if (ret_vdso == 0) {
nerrs += check_gtod(&tv_sys1, &tv_sys2, &tz_sys, "vDSO", &tv_vdso, &tz_vdso);
} else {
printf("[FAIL]\tvDSO gettimeofday() failed: %ld\n", ret_vdso);
nerrs++;
}
if (ret_vdso == 0)
check_gtod(&tv_sys1, &tv_sys2, &tz_sys, "vDSO", &tv_vdso, &tz_vdso);
else
ksft_test_result_fail("vDSO gettimeofday() failed: %ld\n", ret_vdso);
} else {
ksft_test_result_skip("vdso_gtod isn't set\n");
}
if (vsyscall_map_x) {
if (ret_vsys == 0) {
nerrs += check_gtod(&tv_sys1, &tv_sys2, &tz_sys, "vsyscall", &tv_vsys, &tz_vsys);
} else {
printf("[FAIL]\tvsys gettimeofday() failed: %ld\n", ret_vsys);
nerrs++;
}
if (ret_vsys == 0)
check_gtod(&tv_sys1, &tv_sys2, &tz_sys, "vsyscall", &tv_vsys, &tz_vsys);
else
ksft_test_result_fail("vsys gettimeofday() failed: %ld\n", ret_vsys);
} else {
ksft_test_result_skip("vsyscall_map_x isn't set\n");
}
return nerrs;
}
static int test_time(void) {
int nerrs = 0;
printf("[RUN]\ttest time()\n");
static void test_time(void)
{
long t_sys1, t_sys2, t_vdso = 0, t_vsys = 0;
long t2_sys1 = -1, t2_sys2 = -1, t2_vdso = -1, t2_vsys = -1;
ksft_print_msg("test time()\n");
t_sys1 = sys_time(&t2_sys1);
if (vdso_time)
t_vdso = vdso_time(&t2_vdso);
......@@ -275,56 +190,60 @@ static int test_time(void) {
t_vsys = vtime(&t2_vsys);
t_sys2 = sys_time(&t2_sys2);
if (t_sys1 < 0 || t_sys1 != t2_sys1 || t_sys2 < 0 || t_sys2 != t2_sys2) {
printf("[FAIL]\tsyscall failed (ret1:%ld output1:%ld ret2:%ld output2:%ld)\n", t_sys1, t2_sys1, t_sys2, t2_sys2);
nerrs++;
return nerrs;
ksft_print_msg("syscall failed (ret1:%ld output1:%ld ret2:%ld output2:%ld)\n",
t_sys1, t2_sys1, t_sys2, t2_sys2);
ksft_test_result_skip("vdso_time\n");
ksft_test_result_skip("vdso_time\n");
return;
}
if (vdso_time) {
if (t_vdso < 0 || t_vdso != t2_vdso) {
printf("[FAIL]\tvDSO failed (ret:%ld output:%ld)\n", t_vdso, t2_vdso);
nerrs++;
} else if (t_vdso < t_sys1 || t_vdso > t_sys2) {
printf("[FAIL]\tvDSO returned the wrong time (%ld %ld %ld)\n", t_sys1, t_vdso, t_sys2);
nerrs++;
} else {
printf("[OK]\tvDSO time() is okay\n");
}
if (t_vdso < 0 || t_vdso != t2_vdso)
ksft_test_result_fail("vDSO failed (ret:%ld output:%ld)\n",
t_vdso, t2_vdso);
else if (t_vdso < t_sys1 || t_vdso > t_sys2)
ksft_test_result_fail("vDSO returned the wrong time (%ld %ld %ld)\n",
t_sys1, t_vdso, t_sys2);
else
ksft_test_result_pass("vDSO time() is okay\n");
} else {
ksft_test_result_skip("vdso_time isn't set\n");
}
if (vsyscall_map_x) {
if (t_vsys < 0 || t_vsys != t2_vsys) {
printf("[FAIL]\tvsyscall failed (ret:%ld output:%ld)\n", t_vsys, t2_vsys);
nerrs++;
} else if (t_vsys < t_sys1 || t_vsys > t_sys2) {
printf("[FAIL]\tvsyscall returned the wrong time (%ld %ld %ld)\n", t_sys1, t_vsys, t_sys2);
nerrs++;
} else {
printf("[OK]\tvsyscall time() is okay\n");
}
if (t_vsys < 0 || t_vsys != t2_vsys)
ksft_test_result_fail("vsyscall failed (ret:%ld output:%ld)\n",
t_vsys, t2_vsys);
else if (t_vsys < t_sys1 || t_vsys > t_sys2)
ksft_test_result_fail("vsyscall returned the wrong time (%ld %ld %ld)\n",
t_sys1, t_vsys, t_sys2);
else
ksft_test_result_pass("vsyscall time() is okay\n");
} else {
ksft_test_result_skip("vsyscall_map_x isn't set\n");
}
return nerrs;
}
static int test_getcpu(int cpu)
static void test_getcpu(int cpu)
{
int nerrs = 0;
unsigned int cpu_sys, cpu_vdso, cpu_vsys, node_sys, node_vdso, node_vsys;
long ret_sys, ret_vdso = -1, ret_vsys = -1;
unsigned int node = 0;
bool have_node = false;
cpu_set_t cpuset;
printf("[RUN]\tgetcpu() on CPU %d\n", cpu);
ksft_print_msg("getcpu() on CPU %d\n", cpu);
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) {
printf("[SKIP]\tfailed to force CPU %d\n", cpu);
return nerrs;
ksft_print_msg("failed to force CPU %d\n", cpu);
ksft_test_result_skip("vdso_getcpu\n");
ksft_test_result_skip("vsyscall_map_x\n");
return;
}
unsigned cpu_sys, cpu_vdso, cpu_vsys, node_sys, node_vdso, node_vsys;
unsigned node = 0;
bool have_node = false;
ret_sys = sys_getcpu(&cpu_sys, &node_sys, 0);
if (vdso_getcpu)
ret_vdso = vdso_getcpu(&cpu_vdso, &node_vdso, 0);
......@@ -332,10 +251,9 @@ static int test_getcpu(int cpu)
ret_vsys = vgetcpu(&cpu_vsys, &node_vsys, 0);
if (ret_sys == 0) {
if (cpu_sys != cpu) {
printf("[FAIL]\tsyscall reported CPU %hu but should be %d\n", cpu_sys, cpu);
nerrs++;
}
if (cpu_sys != cpu)
ksft_print_msg("syscall reported CPU %hu but should be %d\n",
cpu_sys, cpu);
have_node = true;
node = node_sys;
......@@ -343,63 +261,84 @@ static int test_getcpu(int cpu)
if (vdso_getcpu) {
if (ret_vdso) {
printf("[FAIL]\tvDSO getcpu() failed\n");
nerrs++;
ksft_test_result_fail("vDSO getcpu() failed\n");
} else {
if (!have_node) {
have_node = true;
node = node_vdso;
}
if (cpu_vdso != cpu) {
printf("[FAIL]\tvDSO reported CPU %hu but should be %d\n", cpu_vdso, cpu);
nerrs++;
} else {
printf("[OK]\tvDSO reported correct CPU\n");
}
if (node_vdso != node) {
printf("[FAIL]\tvDSO reported node %hu but should be %hu\n", node_vdso, node);
nerrs++;
if (cpu_vdso != cpu || node_vdso != node) {
if (cpu_vdso != cpu)
ksft_print_msg("vDSO reported CPU %hu but should be %d\n",
cpu_vdso, cpu);
if (node_vdso != node)
ksft_print_msg("vDSO reported node %hu but should be %hu\n",
node_vdso, node);
ksft_test_result_fail("Wrong values\n");
} else {
printf("[OK]\tvDSO reported correct node\n");
ksft_test_result_pass("vDSO reported correct CPU and node\n");
}
}
} else {
ksft_test_result_skip("vdso_getcpu isn't set\n");
}
if (vsyscall_map_x) {
if (ret_vsys) {
printf("[FAIL]\tvsyscall getcpu() failed\n");
nerrs++;
ksft_test_result_fail("vsyscall getcpu() failed\n");
} else {
if (!have_node) {
have_node = true;
node = node_vsys;
}
if (cpu_vsys != cpu) {
printf("[FAIL]\tvsyscall reported CPU %hu but should be %d\n", cpu_vsys, cpu);
nerrs++;
if (cpu_vsys != cpu || node_vsys != node) {
if (cpu_vsys != cpu)
ksft_print_msg("vsyscall reported CPU %hu but should be %d\n",
cpu_vsys, cpu);
if (node_vsys != node)
ksft_print_msg("vsyscall reported node %hu but should be %hu\n",
node_vsys, node);
ksft_test_result_fail("Wrong values\n");
} else {
printf("[OK]\tvsyscall reported correct CPU\n");
}
if (node_vsys != node) {
printf("[FAIL]\tvsyscall reported node %hu but should be %hu\n", node_vsys, node);
nerrs++;
} else {
printf("[OK]\tvsyscall reported correct node\n");
ksft_test_result_pass("vsyscall reported correct CPU and node\n");
}
}
} else {
ksft_test_result_skip("vsyscall_map_x isn't set\n");
}
}
#ifdef __x86_64__
static jmp_buf jmpbuf;
static volatile unsigned long segv_err;
static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
int flags)
{
struct sigaction sa;
return nerrs;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO | flags;
sigemptyset(&sa.sa_mask);
if (sigaction(sig, &sa, 0))
ksft_exit_fail_msg("sigaction failed\n");
}
static int test_vsys_r(void)
static void sigsegv(int sig, siginfo_t *info, void *ctx_void)
{
#ifdef __x86_64__
printf("[RUN]\tChecking read access to the vsyscall page\n");
ucontext_t *ctx = (ucontext_t *)ctx_void;
segv_err = ctx->uc_mcontext.gregs[REG_ERR];
siglongjmp(jmpbuf, 1);
}
static void test_vsys_r(void)
{
ksft_print_msg("Checking read access to the vsyscall page\n");
bool can_read;
if (sigsetjmp(jmpbuf, 1) == 0) {
*(volatile int *)0xffffffffff600000;
......@@ -408,32 +347,25 @@ static int test_vsys_r(void)
can_read = false;
}
if (can_read && !vsyscall_map_r) {
printf("[FAIL]\tWe have read access, but we shouldn't\n");
return 1;
} else if (!can_read && vsyscall_map_r) {
printf("[FAIL]\tWe don't have read access, but we should\n");
return 1;
} else if (can_read) {
printf("[OK]\tWe have read access\n");
} else {
printf("[OK]\tWe do not have read access: #PF(0x%lx)\n",
segv_err);
}
#endif
return 0;
if (can_read && !vsyscall_map_r)
ksft_test_result_fail("We have read access, but we shouldn't\n");
else if (!can_read && vsyscall_map_r)
ksft_test_result_fail("We don't have read access, but we should\n");
else if (can_read)
ksft_test_result_pass("We have read access\n");
else
ksft_test_result_pass("We do not have read access: #PF(0x%lx)\n", segv_err);
}
static int test_vsys_x(void)
static void test_vsys_x(void)
{
#ifdef __x86_64__
if (vsyscall_map_x) {
/* We already tested this adequately. */
return 0;
ksft_test_result_pass("vsyscall_map_x is true\n");
return;
}
printf("[RUN]\tMake sure that vsyscalls really page fault\n");
ksft_print_msg("Make sure that vsyscalls really page fault\n");
bool can_exec;
if (sigsetjmp(jmpbuf, 1) == 0) {
......@@ -443,20 +375,14 @@ static int test_vsys_x(void)
can_exec = false;
}
if (can_exec) {
printf("[FAIL]\tExecuting the vsyscall did not page fault\n");
return 1;
} else if (segv_err & (1 << 4)) { /* INSTR */
printf("[OK]\tExecuting the vsyscall page failed: #PF(0x%lx)\n",
segv_err);
} else {
printf("[FAIL]\tExecution failed with the wrong error: #PF(0x%lx)\n",
segv_err);
return 1;
}
#endif
return 0;
if (can_exec)
ksft_test_result_fail("Executing the vsyscall did not page fault\n");
else if (segv_err & (1 << 4)) /* INSTR */
ksft_test_result_pass("Executing the vsyscall page failed: #PF(0x%lx)\n",
segv_err);
else
ksft_test_result_fail("Execution failed with the wrong error: #PF(0x%lx)\n",
segv_err);
}
/*
......@@ -470,14 +396,13 @@ static int test_vsys_x(void)
* fact that ptrace() ever worked was a nice courtesy of old kernels,
* but the code to support it is fairly gross.
*/
static int test_process_vm_readv(void)
static void test_process_vm_readv(void)
{
#ifdef __x86_64__
char buf[4096];
struct iovec local, remote;
int ret;
printf("[RUN]\tprocess_vm_readv() from vsyscall page\n");
ksft_print_msg("process_vm_readv() from vsyscall page\n");
local.iov_base = buf;
local.iov_len = 4096;
......@@ -489,27 +414,71 @@ static int test_process_vm_readv(void)
* We expect process_vm_readv() to work if and only if the
* vsyscall page is readable.
*/
printf("[%s]\tprocess_vm_readv() failed (ret = %d, errno = %d)\n", vsyscall_map_r ? "FAIL" : "OK", ret, errno);
return vsyscall_map_r ? 1 : 0;
ksft_test_result(!vsyscall_map_r,
"process_vm_readv() failed (ret = %d, errno = %d)\n", ret, errno);
return;
}
if (vsyscall_map_r) {
if (!memcmp(buf, remote.iov_base, sizeof(buf))) {
printf("[OK]\tIt worked and read correct data\n");
} else {
printf("[FAIL]\tIt worked but returned incorrect data\n");
return 1;
if (vsyscall_map_r)
ksft_test_result(!memcmp(buf, remote.iov_base, sizeof(buf)), "Read data\n");
else
ksft_test_result_fail("process_rm_readv() succeeded, but it should have failed in this configuration\n");
}
static void init_vsys(void)
{
int nerrs = 0;
FILE *maps;
char line[MAPS_LINE_LEN];
bool found = false;
maps = fopen("/proc/self/maps", "r");
if (!maps) {
ksft_test_result_skip("Could not open /proc/self/maps -- assuming vsyscall is r-x\n");
vsyscall_map_r = true;
return;
}
while (fgets(line, MAPS_LINE_LEN, maps)) {
char r, x;
void *start, *end;
char name[MAPS_LINE_LEN];
/* sscanf() is safe here as strlen(name) >= strlen(line) */
if (sscanf(line, "%p-%p %c-%cp %*x %*x:%*x %*u %s",
&start, &end, &r, &x, name) != 5)
continue;
if (strcmp(name, "[vsyscall]"))
continue;
ksft_print_msg("vsyscall map: %s", line);
if (start != (void *)0xffffffffff600000 ||
end != (void *)0xffffffffff601000) {
ksft_print_msg("address range is nonsense\n");
nerrs++;
}
} else {
printf("[FAIL]\tprocess_rm_readv() succeeded, but it should have failed in this configuration\n");
return 1;
ksft_print_msg("vsyscall permissions are %c-%c\n", r, x);
vsyscall_map_r = (r == 'r');
vsyscall_map_x = (x == 'x');
found = true;
break;
}
#endif
return 0;
fclose(maps);
if (!found) {
ksft_print_msg("no vsyscall map in /proc/self/maps\n");
vsyscall_map_r = false;
vsyscall_map_x = false;
}
ksft_test_result(!nerrs, "vsyscall map\n");
}
#ifdef __x86_64__
static volatile sig_atomic_t num_vsyscall_traps;
static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
......@@ -521,15 +490,17 @@ static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
num_vsyscall_traps++;
}
static int test_emulation(void)
static void test_emulation(void)
{
time_t tmp;
bool is_native;
if (!vsyscall_map_x)
return 0;
if (!vsyscall_map_x) {
ksft_test_result_skip("vsyscall_map_x isn't set\n");
return;
}
printf("[RUN]\tchecking that vsyscalls are emulated\n");
ksft_print_msg("checking that vsyscalls are emulated\n");
sethandler(SIGTRAP, sigtrap, 0);
set_eflags(get_eflags() | X86_EFLAGS_TF);
vtime(&tmp);
......@@ -545,36 +516,35 @@ static int test_emulation(void)
*/
is_native = (num_vsyscall_traps > 1);
printf("[%s]\tvsyscalls are %s (%d instructions in vsyscall page)\n",
(is_native ? "FAIL" : "OK"),
(is_native ? "native" : "emulated"),
(int)num_vsyscall_traps);
return is_native;
ksft_test_result(!is_native, "vsyscalls are %s (%d instructions in vsyscall page)\n",
(is_native ? "native" : "emulated"), (int)num_vsyscall_traps);
}
#endif
int main(int argc, char **argv)
{
int nerrs = 0;
int total_tests = TOTAL_TESTS;
init_vdso();
nerrs += init_vsys();
ksft_print_header();
ksft_set_plan(total_tests);
nerrs += test_gtod();
nerrs += test_time();
nerrs += test_getcpu(0);
nerrs += test_getcpu(1);
sethandler(SIGSEGV, sigsegv, 0);
nerrs += test_vsys_r();
nerrs += test_vsys_x();
init_vdso();
#ifdef __x86_64__
init_vsys();
#endif
nerrs += test_process_vm_readv();
test_gtod();
test_time();
test_getcpu(0);
test_getcpu(1);
#ifdef __x86_64__
nerrs += test_emulation();
sethandler(SIGSEGV, sigsegv, 0);
test_vsys_r();
test_vsys_x();
test_process_vm_readv();
test_emulation();
#endif
return nerrs ? 1 : 0;
ksft_finished();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment