diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 7442dfb73b7f..f4dfee6ea8a4 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -66,6 +66,12 @@ ifndef BUILD BUILD := $(shell pwd) endif +# KSFT_TAP_LEVEL is used from KSFT framework to prevent nested TAP header +# printing from tests. Applicable to run_tests case where run_tests adds +# TAP header prior running tests and when a test program invokes another +# with system() call. Export it here to cover override RUN_TESTS defines. +export KSFT_TAP_LEVEL=`echo 1` + export BUILD all: @for TARGET in $(TARGETS); do \ @@ -125,11 +131,14 @@ ifdef INSTALL_PATH echo "else" >> $(ALL_SCRIPT) echo " OUTPUT=/dev/stdout" >> $(ALL_SCRIPT) echo "fi" >> $(ALL_SCRIPT) + echo "export KSFT_TAP_LEVEL=`echo 1`" >> $(ALL_SCRIPT) for TARGET in $(TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ - echo "echo ; echo Running tests in $$TARGET" >> $(ALL_SCRIPT); \ + echo "echo ; echo TAP version 13" >> $(ALL_SCRIPT); \ + echo "echo Running tests in $$TARGET" >> $(ALL_SCRIPT); \ echo "echo ========================================" >> $(ALL_SCRIPT); \ + echo "[ -w /dev/kmsg ] && echo \"kselftest: Running tests in $$TARGET\" >> /dev/kmsg" >> $(ALL_SCRIPT); \ echo "cd $$TARGET" >> $(ALL_SCRIPT); \ make -s --no-print-directory OUTPUT=$$BUILD_TARGET -C $$TARGET emit_tests >> $(ALL_SCRIPT); \ echo "cd \$$ROOT" >> $(ALL_SCRIPT); \ diff --git a/tools/testing/selftests/android/ion/.gitignore b/tools/testing/selftests/android/ion/.gitignore index 67e6f391b2a9..95e8f4561474 100644 --- a/tools/testing/selftests/android/ion/.gitignore +++ b/tools/testing/selftests/android/ion/.gitignore @@ -1,2 +1,3 @@ ionapp_export ionapp_import +ionmap_test diff --git a/tools/testing/selftests/android/ion/Makefile b/tools/testing/selftests/android/ion/Makefile index 96e0c448b39d..e03695287f76 100644 --- a/tools/testing/selftests/android/ion/Makefile +++ b/tools/testing/selftests/android/ion/Makefile @@ -1,8 +1,8 @@ -INCLUDEDIR := -I. -I../../../../../drivers/staging/android/uapi/ +INCLUDEDIR := -I. -I../../../../../drivers/staging/android/uapi/ -I../../../../../usr/include/ CFLAGS := $(CFLAGS) $(INCLUDEDIR) -Wall -O2 -g -TEST_GEN_FILES := ionapp_export ionapp_import +TEST_GEN_FILES := ionapp_export ionapp_import ionmap_test all: $(TEST_GEN_FILES) @@ -14,3 +14,4 @@ include ../../lib.mk $(OUTPUT)/ionapp_export: ionapp_export.c ipcsocket.c ionutils.c $(OUTPUT)/ionapp_import: ionapp_import.c ipcsocket.c ionutils.c +$(OUTPUT)/ionmap_test: ionmap_test.c ionutils.c diff --git a/tools/testing/selftests/android/ion/config b/tools/testing/selftests/android/ion/config index 19db6ca9aa2b..b4ad748a9dd9 100644 --- a/tools/testing/selftests/android/ion/config +++ b/tools/testing/selftests/android/ion/config @@ -2,3 +2,4 @@ CONFIG_ANDROID=y CONFIG_STAGING=y CONFIG_ION=y CONFIG_ION_SYSTEM_HEAP=y +CONFIG_DRM_VGEM=y diff --git a/tools/testing/selftests/android/ion/ionmap_test.c b/tools/testing/selftests/android/ion/ionmap_test.c new file mode 100644 index 000000000000..dab36b06b37d --- /dev/null +++ b/tools/testing/selftests/android/ion/ionmap_test.c @@ -0,0 +1,136 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include "ion.h" +#include "ionutils.h" + +int check_vgem(int fd) +{ + drm_version_t version = { 0 }; + char name[5]; + int ret; + + version.name_len = 4; + version.name = name; + + ret = ioctl(fd, DRM_IOCTL_VERSION, &version); + if (ret) + return 1; + + return strcmp(name, "vgem"); +} + +int open_vgem(void) +{ + int i, fd; + const char *drmstr = "/dev/dri/card"; + + fd = -1; + for (i = 0; i < 16; i++) { + char name[80]; + + sprintf(name, "%s%u", drmstr, i); + + fd = open(name, O_RDWR); + if (fd < 0) + continue; + + if (check_vgem(fd)) { + close(fd); + continue; + } else { + break; + } + + } + return fd; +} + +int import_vgem_fd(int vgem_fd, int dma_buf_fd, uint32_t *handle) +{ + struct drm_prime_handle import_handle = { 0 }; + int ret; + + import_handle.fd = dma_buf_fd; + import_handle.flags = 0; + import_handle.handle = 0; + + ret = ioctl(vgem_fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &import_handle); + if (ret == 0) + *handle = import_handle.handle; + return ret; +} + +void close_handle(int vgem_fd, uint32_t handle) +{ + struct drm_gem_close close = { 0 }; + + close.handle = handle; + ioctl(vgem_fd, DRM_IOCTL_GEM_CLOSE, &close); +} + +int main() +{ + int ret, vgem_fd; + struct ion_buffer_info info; + uint32_t handle = 0; + struct dma_buf_sync sync = { 0 }; + + info.heap_type = ION_HEAP_TYPE_SYSTEM; + info.heap_size = 4096; + info.flag_type = ION_FLAG_CACHED; + + ret = ion_export_buffer_fd(&info); + if (ret < 0) { + printf("ion buffer alloc failed\n"); + return -1; + } + + vgem_fd = open_vgem(); + if (vgem_fd < 0) { + ret = vgem_fd; + printf("Failed to open vgem\n"); + goto out_ion; + } + + ret = import_vgem_fd(vgem_fd, info.buffd, &handle); + + if (ret < 0) { + printf("Failed to import buffer\n"); + goto out_vgem; + } + + sync.flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW; + ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync); + if (ret) + printf("sync start failed %d\n", errno); + + memset(info.buffer, 0xff, 4096); + + sync.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW; + ret = ioctl(info.buffd, DMA_BUF_IOCTL_SYNC, &sync); + if (ret) + printf("sync end failed %d\n", errno); + + close_handle(vgem_fd, handle); + ret = 0; + +out_vgem: + close(vgem_fd); +out_ion: + ion_close_buffer_fd(&info); + printf("done.\n"); + return ret; +} diff --git a/tools/testing/selftests/android/ion/ionutils.c b/tools/testing/selftests/android/ion/ionutils.c index ce69c14f51fa..7d1d37c4ef6a 100644 --- a/tools/testing/selftests/android/ion/ionutils.c +++ b/tools/testing/selftests/android/ion/ionutils.c @@ -80,11 +80,6 @@ int ion_export_buffer_fd(struct ion_buffer_info *ion_info) heap_id = MAX_HEAP_COUNT + 1; for (i = 0; i < query.cnt; i++) { if (heap_data[i].type == ion_info->heap_type) { - printf("--------------------------------------\n"); - printf("heap type: %d\n", heap_data[i].type); - printf(" heap id: %d\n", heap_data[i].heap_id); - printf("heap name: %s\n", heap_data[i].name); - printf("--------------------------------------\n"); heap_id = heap_data[i].heap_id; break; } @@ -204,7 +199,6 @@ void ion_close_buffer_fd(struct ion_buffer_info *ion_info) /* Finally, close the client fd */ if (ion_info->ionfd > 0) close(ion_info->ionfd); - printf("<%s>: buffer release successfully....\n", __func__); } } diff --git a/tools/testing/selftests/futex/Makefile b/tools/testing/selftests/futex/Makefile index a63e8453984d..8497a376ef9d 100644 --- a/tools/testing/selftests/futex/Makefile +++ b/tools/testing/selftests/futex/Makefile @@ -18,6 +18,10 @@ all: done override define RUN_TESTS + @export KSFT_TAP_LEVEL=`echo 1`; + @echo "TAP version 13"; + @echo "selftests: futex"; + @echo "========================================"; @cd $(OUTPUT); ./run.sh endef diff --git a/tools/testing/selftests/intel_pstate/Makefile b/tools/testing/selftests/intel_pstate/Makefile index 5a3f7d37e912..7340fd6a9a9f 100644 --- a/tools/testing/selftests/intel_pstate/Makefile +++ b/tools/testing/selftests/intel_pstate/Makefile @@ -2,7 +2,10 @@ CFLAGS := $(CFLAGS) -Wall -D_GNU_SOURCE LDLIBS := $(LDLIBS) -lm -ifeq (,$(filter $(ARCH),x86)) +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/) + +ifeq (x86,$(ARCH)) TEST_GEN_FILES := msr aperf endif diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h index 1a52b03962a3..1b9d8ecdebce 100644 --- a/tools/testing/selftests/kselftest.h +++ b/tools/testing/selftests/kselftest.h @@ -57,7 +57,8 @@ static inline int ksft_get_error_cnt(void) { return ksft_cnt.ksft_error; } static inline void ksft_print_header(void) { - printf("TAP version 13\n"); + if (!(getenv("KSFT_TAP_LEVEL"))) + printf("TAP version 13\n"); } static inline void ksft_print_cnts(void) diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h index e81bd28bdd89..6ae3730c4ee3 100644 --- a/tools/testing/selftests/kselftest_harness.h +++ b/tools/testing/selftests/kselftest_harness.h @@ -106,6 +106,27 @@ fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \ __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__) +/** + * XFAIL(statement, fmt, ...) + * + * @statement: statement to run after reporting XFAIL + * @fmt: format string + * @...: optional arguments + * + * This forces a "pass" after reporting a failure with an XFAIL prefix, + * and runs "statement", which is usually "return" or "goto skip". + */ +#define XFAIL(statement, fmt, ...) do { \ + if (TH_LOG_ENABLED) { \ + fprintf(TH_LOG_STREAM, "[ XFAIL! ] " fmt "\n", \ + ##__VA_ARGS__); \ + } \ + /* TODO: find a way to pass xfail to test runner process. */ \ + _metadata->passed = 1; \ + _metadata->trigger = 0; \ + statement; \ +} while (0) + /** * TEST(test_name) - Defines the test function and creates the registration * stub @@ -198,7 +219,7 @@ /** * FIXTURE_SETUP(fixture_name) - Prepares the setup function for the fixture. - * *_metadata* is included so that ASSERT_* work as a convenience + * *_metadata* is included so that EXPECT_* and ASSERT_* work correctly. * * @fixture_name: fixture name * @@ -221,6 +242,7 @@ FIXTURE_DATA(fixture_name) __attribute__((unused)) *self) /** * FIXTURE_TEARDOWN(fixture_name) + * *_metadata* is included so that EXPECT_* and ASSERT_* work correctly. * * @fixture_name: fixture name * @@ -253,6 +275,8 @@ * Defines a test that depends on a fixture (e.g., is part of a test case). * Very similar to TEST() except that *self* is the setup instance of fixture's * datatype exposed for use by the implementation. + * + * Warning: use of ASSERT_* here will skip TEARDOWN. */ /* TODO(wad) register fixtures on dedicated test lists. */ #define TEST_F(fixture_name, test_name) \ diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index 7de482a0519d..195e9d4739a9 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk @@ -20,6 +20,7 @@ all: $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED) $(TEST_GEN_FILES) .ONESHELL: define RUN_TESTS + @export KSFT_TAP_LEVEL=`echo 1`; @test_num=`echo 0`; @echo "TAP version 13"; @for TEST in $(1); do \ diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 5df609950a66..168c66d74fc5 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -2860,6 +2860,7 @@ TEST(get_metadata) int pipefd[2]; char buf; struct seccomp_metadata md; + long ret; ASSERT_EQ(0, pipe(pipefd)); @@ -2893,16 +2894,26 @@ TEST(get_metadata) ASSERT_EQ(0, ptrace(PTRACE_ATTACH, pid)); ASSERT_EQ(pid, waitpid(pid, NULL, 0)); + /* Past here must not use ASSERT or child process is never killed. */ + md.filter_off = 0; - ASSERT_EQ(sizeof(md), ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md)); + errno = 0; + ret = ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md); + EXPECT_EQ(sizeof(md), ret) { + if (errno == EINVAL) + XFAIL(goto skip, "Kernel does not support PTRACE_SECCOMP_GET_METADATA (missing CONFIG_CHECKPOINT_RESTORE?)"); + } + EXPECT_EQ(md.flags, SECCOMP_FILTER_FLAG_LOG); EXPECT_EQ(md.filter_off, 0); md.filter_off = 1; - ASSERT_EQ(sizeof(md), ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md)); + ret = ptrace(PTRACE_SECCOMP_GET_METADATA, pid, sizeof(md), &md); + EXPECT_EQ(sizeof(md), ret); EXPECT_EQ(md.flags, 0); EXPECT_EQ(md.filter_off, 1); +skip: ASSERT_EQ(0, kill(pid, SIGKILL)); }