xref: /freebsd/tests/sys/kern/basic_signal.c (revision afc5ab870d8661a7dacdbd65554c2f3533aecb8d)
1*afc5ab87SWarner Losh /*-
2*afc5ab87SWarner Losh  * Copyright (c) 2021 Warner Losh <imp@bsdimp.com>
3*afc5ab87SWarner Losh  *
4*afc5ab87SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
5*afc5ab87SWarner Losh  */
6*afc5ab87SWarner Losh 
7*afc5ab87SWarner Losh #include <atf-c.h>
8*afc5ab87SWarner Losh #include <errno.h>
9*afc5ab87SWarner Losh #include <signal.h>
10*afc5ab87SWarner Losh #include <stdbool.h>
11*afc5ab87SWarner Losh #include <stdlib.h>
12*afc5ab87SWarner Losh 
13*afc5ab87SWarner Losh static volatile sig_atomic_t signal_fired = 0;
14*afc5ab87SWarner Losh 
15*afc5ab87SWarner Losh static void
16*afc5ab87SWarner Losh sig_handler(int signo, siginfo_t *info __unused, void *ucp __unused)
17*afc5ab87SWarner Losh {
18*afc5ab87SWarner Losh 	signal_fired++;
19*afc5ab87SWarner Losh }
20*afc5ab87SWarner Losh 
21*afc5ab87SWarner Losh ATF_TC(signal_test);
22*afc5ab87SWarner Losh 
23*afc5ab87SWarner Losh ATF_TC_HEAD(signal_test, tc)
24*afc5ab87SWarner Losh {
25*afc5ab87SWarner Losh 
26*afc5ab87SWarner Losh 	atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal");
27*afc5ab87SWarner Losh }
28*afc5ab87SWarner Losh 
29*afc5ab87SWarner Losh ATF_TC_BODY(signal_test, tc)
30*afc5ab87SWarner Losh {
31*afc5ab87SWarner Losh 	/*
32*afc5ab87SWarner Losh 	 * Setup the signal handlers
33*afc5ab87SWarner Losh 	 */
34*afc5ab87SWarner Losh 	struct sigaction sa = {
35*afc5ab87SWarner Losh 		.sa_sigaction = sig_handler,
36*afc5ab87SWarner Losh 		.sa_flags = SA_SIGINFO,
37*afc5ab87SWarner Losh 	};
38*afc5ab87SWarner Losh 	ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
39*afc5ab87SWarner Losh 	ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0);
40*afc5ab87SWarner Losh 	ATF_REQUIRE(sigaction(SIGUSR2, &sa, NULL) == 0);
41*afc5ab87SWarner Losh 	ATF_REQUIRE(sigaction(SIGALRM, &sa, NULL) == 0);
42*afc5ab87SWarner Losh 
43*afc5ab87SWarner Losh 	/*
44*afc5ab87SWarner Losh 	 * Fire SIGUSR1
45*afc5ab87SWarner Losh 	 */
46*afc5ab87SWarner Losh 	ATF_CHECK(signal_fired == 0);
47*afc5ab87SWarner Losh 	ATF_REQUIRE(raise(SIGUSR1) == 0);
48*afc5ab87SWarner Losh 	ATF_CHECK(signal_fired == 1);
49*afc5ab87SWarner Losh 
50*afc5ab87SWarner Losh 	/*
51*afc5ab87SWarner Losh 	 * Fire SIGUSR2
52*afc5ab87SWarner Losh 	 */
53*afc5ab87SWarner Losh 	ATF_REQUIRE(raise(SIGUSR2) == 0);
54*afc5ab87SWarner Losh 	ATF_CHECK(signal_fired == 2);
55*afc5ab87SWarner Losh 
56*afc5ab87SWarner Losh 	/*
57*afc5ab87SWarner Losh 	 * Fire SIGALRM after a timeout
58*afc5ab87SWarner Losh 	 */
59*afc5ab87SWarner Losh 	ATF_REQUIRE(alarm(1) == 0);
60*afc5ab87SWarner Losh 	ATF_REQUIRE(pause() == -1);
61*afc5ab87SWarner Losh 	ATF_REQUIRE(errno == EINTR);
62*afc5ab87SWarner Losh 	ATF_CHECK(signal_fired == 3);
63*afc5ab87SWarner Losh }
64*afc5ab87SWarner Losh 
65*afc5ab87SWarner Losh /*
66*afc5ab87SWarner Losh  * Special tests for 32-bit arm. We can call thumb code (really just t32) from
67*afc5ab87SWarner Losh  * normal (a32) mode and vice versa. Likewise, signals can interrupt a T32
68*afc5ab87SWarner Losh  * context with A32 code and vice versa. Make sure these all work with a simple
69*afc5ab87SWarner Losh  * test that raises the signal and ensures that it executed. No other platform
70*afc5ab87SWarner Losh  * has these requirements. Also note: we only support thumb2, so there's no T16
71*afc5ab87SWarner Losh  * vs T32 issues we have to test for.
72*afc5ab87SWarner Losh  */
73*afc5ab87SWarner Losh #ifdef __arm__
74*afc5ab87SWarner Losh 
75*afc5ab87SWarner Losh #define a32_isa __attribute__((target("arm")))
76*afc5ab87SWarner Losh #define t32_isa __attribute__((target("thumb")))
77*afc5ab87SWarner Losh 
78*afc5ab87SWarner Losh static volatile sig_atomic_t t32_fired = 0;
79*afc5ab87SWarner Losh static volatile sig_atomic_t a32_fired = 0;
80*afc5ab87SWarner Losh 
81*afc5ab87SWarner Losh a32_isa static void
82*afc5ab87SWarner Losh sig_a32(int signo, siginfo_t *info __unused, void *ucp __unused)
83*afc5ab87SWarner Losh {
84*afc5ab87SWarner Losh 	a32_fired++;
85*afc5ab87SWarner Losh }
86*afc5ab87SWarner Losh 
87*afc5ab87SWarner Losh t32_isa static void
88*afc5ab87SWarner Losh sig_t32(int signo, siginfo_t *info __unused, void *ucp __unused)
89*afc5ab87SWarner Losh {
90*afc5ab87SWarner Losh 	t32_fired++;
91*afc5ab87SWarner Losh }
92*afc5ab87SWarner Losh 
93*afc5ab87SWarner Losh 
94*afc5ab87SWarner Losh ATF_TC(signal_test_T32_to_A32);
95*afc5ab87SWarner Losh 
96*afc5ab87SWarner Losh ATF_TC_HEAD(signal_test_T32_to_A32, tc)
97*afc5ab87SWarner Losh {
98*afc5ab87SWarner Losh 
99*afc5ab87SWarner Losh 	atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from T32 to A32");
100*afc5ab87SWarner Losh }
101*afc5ab87SWarner Losh 
102*afc5ab87SWarner Losh t32_isa ATF_TC_BODY(signal_test_T32_to_A32, tc)
103*afc5ab87SWarner Losh {
104*afc5ab87SWarner Losh 	/*
105*afc5ab87SWarner Losh 	 * Setup the signal handlers
106*afc5ab87SWarner Losh 	 */
107*afc5ab87SWarner Losh 	struct sigaction sa = {
108*afc5ab87SWarner Losh 		.sa_sigaction = sig_a32,
109*afc5ab87SWarner Losh 		.sa_flags = SA_SIGINFO,
110*afc5ab87SWarner Losh 	};
111*afc5ab87SWarner Losh 	ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
112*afc5ab87SWarner Losh 	ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0);
113*afc5ab87SWarner Losh 
114*afc5ab87SWarner Losh 	ATF_REQUIRE((((uintptr_t)sig_a32) & 1) == 0); /* Make sure compiled as not thumb */
115*afc5ab87SWarner Losh 
116*afc5ab87SWarner Losh 	ATF_CHECK(a32_fired == 0);
117*afc5ab87SWarner Losh 	ATF_REQUIRE(raise(SIGUSR1) == 0);
118*afc5ab87SWarner Losh 	ATF_CHECK(a32_fired == 1);
119*afc5ab87SWarner Losh }
120*afc5ab87SWarner Losh 
121*afc5ab87SWarner Losh ATF_TC(signal_test_A32_to_T32);
122*afc5ab87SWarner Losh 
123*afc5ab87SWarner Losh ATF_TC_HEAD(signal_test_A32_to_T32, tc)
124*afc5ab87SWarner Losh {
125*afc5ab87SWarner Losh 
126*afc5ab87SWarner Losh 	atf_tc_set_md_var(tc, "descr", "Testing delivery of a signal from A32 to T32");
127*afc5ab87SWarner Losh }
128*afc5ab87SWarner Losh 
129*afc5ab87SWarner Losh a32_isa ATF_TC_BODY(signal_test_A32_to_T32, tc)
130*afc5ab87SWarner Losh {
131*afc5ab87SWarner Losh 	/*
132*afc5ab87SWarner Losh 	 * Setup the signal handlers
133*afc5ab87SWarner Losh 	 */
134*afc5ab87SWarner Losh 	struct sigaction sa = {
135*afc5ab87SWarner Losh 		.sa_sigaction = sig_t32,
136*afc5ab87SWarner Losh 		.sa_flags = SA_SIGINFO,
137*afc5ab87SWarner Losh 	};
138*afc5ab87SWarner Losh 	ATF_REQUIRE(sigemptyset(&sa.sa_mask) == 0);
139*afc5ab87SWarner Losh 	ATF_REQUIRE(sigaction(SIGUSR1, &sa, NULL) == 0);
140*afc5ab87SWarner Losh 
141*afc5ab87SWarner Losh 	ATF_REQUIRE((((uintptr_t)sig_t32) & 1) == 1);	/* Make sure compiled as thumb */
142*afc5ab87SWarner Losh 
143*afc5ab87SWarner Losh 	ATF_CHECK(t32_fired == 0);
144*afc5ab87SWarner Losh 	ATF_REQUIRE(raise(SIGUSR1) == 0);
145*afc5ab87SWarner Losh 	ATF_CHECK(t32_fired == 1);
146*afc5ab87SWarner Losh }
147*afc5ab87SWarner Losh #endif
148*afc5ab87SWarner Losh 
149*afc5ab87SWarner Losh ATF_TP_ADD_TCS(tp)
150*afc5ab87SWarner Losh {
151*afc5ab87SWarner Losh 
152*afc5ab87SWarner Losh 	ATF_TP_ADD_TC(tp, signal_test);
153*afc5ab87SWarner Losh #ifdef __arm__
154*afc5ab87SWarner Losh 	ATF_TP_ADD_TC(tp, signal_test_T32_to_A32);
155*afc5ab87SWarner Losh 	ATF_TP_ADD_TC(tp, signal_test_A32_to_T32);
156*afc5ab87SWarner Losh #endif
157*afc5ab87SWarner Losh 
158*afc5ab87SWarner Losh 	return (atf_no_error());
159*afc5ab87SWarner Losh }
160