diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile index b0f83b97db41..b8fee0944c06 100644 --- a/tests/sys/kern/Makefile +++ b/tests/sys/kern/Makefile @@ -1,92 +1,93 @@ # $FreeBSD$ .include PACKAGE= tests TESTSRC= ${SRCTOP}/contrib/netbsd-tests/kernel .PATH: ${SRCTOP}/sys/kern TESTSDIR= ${TESTSBASE}/sys/kern +ATF_TESTS_C+= basic_signal #ATF_TESTS_C+= kcov ATF_TESTS_C+= kern_copyin ATF_TESTS_C+= kern_descrip_test ATF_TESTS_C+= fdgrowtable_test ATF_TESTS_C+= kill_zombie .if ${MK_OPENSSL} != "no" ATF_TESTS_C+= ktls_test .endif ATF_TESTS_C+= ptrace_test TEST_METADATA.ptrace_test+= timeout="15" ATF_TESTS_C+= reaper ATF_TESTS_C+= sigaltstack PLAIN_TESTS_C+= subr_unit_test ATF_TESTS_C+= sys_getrandom ATF_TESTS_C+= unix_passfd_test ATF_TESTS_C+= unix_seqpacket_test TEST_METADATA.unix_seqpacket_test+= timeout="15" ATF_TESTS_C+= unix_socketpair_test ATF_TESTS_C+= waitpid_nohang ATF_TESTS_C+= pdeathsig ATF_TESTS_SH+= coredump_phnum_test ATF_TESTS_SH+= sonewconn_overflow TEST_METADATA.sonewconn_overflow+= required_programs="python" TEST_METADATA.sonewconn_overflow+= required_user="root" ATF_TESTS_SH+= sendfile_test ${PACKAGE}FILES+= sonewconn_overflow.py ${PACKAGE}FILESMODE_sonewconn_overflow.py=0555 BINDIR= ${TESTSDIR} PROGS+= coredump_phnum_helper PROGS+= pdeathsig_helper PROGS+= sendfile_helper CFLAGS.sys_getrandom+= -I${SRCTOP}/sys/contrib/zstd/lib LIBADD.sys_getrandom+= zstd LIBADD.sys_getrandom+= c LIBADD.sys_getrandom+= pthread LIBADD.ptrace_test+= pthread LIBADD.unix_seqpacket_test+= pthread LIBADD.kcov+= pthread LIBADD.ktls_test+= crypto LIBADD.sendfile_helper+= pthread LIBADD.fdgrowtable_test+= util pthread kvm procstat NETBSD_ATF_TESTS_C+= lockf_test NETBSD_ATF_TESTS_C+= mqueue_test NETBSD_ATF_TESTS_C+= sysv_test CFLAGS.mqueue_test+= -I${SRCTOP}/tests LIBADD.mqueue_test+= rt ATF_TESTS_C+= libkern_crc32 SRCS.libkern_crc32+= libkern_crc32.c .PATH: ${SRCTOP}/sys/libkern SRCS.libkern_crc32+= gsb_crc32.c CFLAGS.libkern_crc32+= -DTESTING .if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" .PATH: ${SRCTOP}/sys/libkern/x86 SRCS.libkern_crc32+= crc32_sse42.c .elif ${MACHINE_CPUARCH} == "aarch64" .PATH: ${SRCTOP}/sys/libkern/arm64 SRCS.libkern_crc32+= crc32c_armv8.S .endif # subr_unit.c contains functions whose prototypes lie in headers that cannot be # included in userland. But as far as subr_unit_test goes, they're effectively # static. So it's ok to disable -Wmissing-prototypes for this program. CFLAGS.subr_unit.c+= -Wno-missing-prototypes SRCS.subr_unit_test+= subr_unit.c WARNS?= 3 TESTS_SUBDIRS+= acct TESTS_SUBDIRS+= execve TESTS_SUBDIRS+= pipe .include .include diff --git a/tests/sys/kern/basic_signal.c b/tests/sys/kern/basic_signal.c new file mode 100644 index 000000000000..0b3200e2b8ab --- /dev/null +++ b/tests/sys/kern/basic_signal.c @@ -0,0 +1,159 @@ +/*- + * Copyright (c) 2021 Warner Losh + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +static volatile sig_atomic_t signal_fired = 0; + +static void +sig_handler(int signo, siginfo_t *info __unused, void *ucp __unused) +{ + signal_fired++; +} + +ATF_TC(signal_test); + +ATF_TC_HEAD(signal_test, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal"); +} + +ATF_TC_BODY(signal_test, tc) +{ + /* + * Setup the signal handlers + */ + struct sigaction sa = { + .sa_sigaction = sig_handler, + .sa_flags = SA_SIGINFO, + }; + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); + ATF_REQUIRE(sigaction(SIGUSR2, &sa, NULL) == 0); + ATF_REQUIRE(sigaction(SIGALRM, &sa, NULL) == 0); + + /* + * Fire SIGUSR1 + */ + ATF_CHECK(signal_fired == 0); + ATF_REQUIRE(raise(SIGUSR1) == 0); + ATF_CHECK(signal_fired == 1); + + /* + * Fire SIGUSR2 + */ + ATF_REQUIRE(raise(SIGUSR2) == 0); + ATF_CHECK(signal_fired == 2); + + /* + * Fire SIGALRM after a timeout + */ + ATF_REQUIRE(alarm(1) == 0); + ATF_REQUIRE(pause() == -1); + ATF_REQUIRE(errno == EINTR); + ATF_CHECK(signal_fired == 3); +} + +/* + * Special tests for 32-bit arm. We can call thumb code (really just t32) from + * normal (a32) mode and vice versa. Likewise, signals can interrupt a T32 + * context with A32 code and vice versa. Make sure these all work with a simple + * test that raises the signal and ensures that it executed. No other platform + * has these requirements. Also note: we only support thumb2, so there's no T16 + * vs T32 issues we have to test for. + */ +#ifdef __arm__ + +#define a32_isa __attribute__((target("arm"))) +#define t32_isa __attribute__((target("thumb"))) + +static volatile sig_atomic_t t32_fired = 0; +static volatile sig_atomic_t a32_fired = 0; + +a32_isa static void +sig_a32(int signo, siginfo_t *info __unused, void *ucp __unused) +{ + a32_fired++; +} + +t32_isa static void +sig_t32(int signo, siginfo_t *info __unused, void *ucp __unused) +{ + t32_fired++; +} + + +ATF_TC(signal_test_T32_to_A32); + +ATF_TC_HEAD(signal_test_T32_to_A32, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from T32 to A32"); +} + +t32_isa ATF_TC_BODY(signal_test_T32_to_A32, tc) +{ + /* + * Setup the signal handlers + */ + struct sigaction sa = { + .sa_sigaction = sig_a32, + .sa_flags = SA_SIGINFO, + }; + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); + + ATF_REQUIRE((((uintptr_t)sig_a32) & 1) == 0); /* Make sure compiled as not thumb */ + + ATF_CHECK(a32_fired == 0); + ATF_REQUIRE(raise(SIGUSR1) == 0); + ATF_CHECK(a32_fired == 1); +} + +ATF_TC(signal_test_A32_to_T32); + +ATF_TC_HEAD(signal_test_A32_to_T32, tc) +{ + + atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from A32 to T32"); +} + +a32_isa ATF_TC_BODY(signal_test_A32_to_T32, tc) +{ + /* + * Setup the signal handlers + */ + struct sigaction sa = { + .sa_sigaction = sig_t32, + .sa_flags = SA_SIGINFO, + }; + ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0); + ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0); + + ATF_REQUIRE((((uintptr_t)sig_t32) & 1) == 1); /* Make sure compiled as thumb */ + + ATF_CHECK(t32_fired == 0); + ATF_REQUIRE(raise(SIGUSR1) == 0); + ATF_CHECK(t32_fired == 1); +} +#endif + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, signal_test); +#ifdef __arm__ + ATF_TP_ADD_TC(tp, signal_test_T32_to_A32); + ATF_TP_ADD_TC(tp, signal_test_A32_to_T32); +#endif + + return (atf_no_error()); +}