test_signals_utils.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright (C) 2019 ARM Limited */
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <signal.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <assert.h>
  9. #include <sys/auxv.h>
  10. #include <linux/auxvec.h>
  11. #include <ucontext.h>
  12. #include <asm/unistd.h>
  13. #include <kselftest.h>
  14. #include "test_signals.h"
  15. #include "test_signals_utils.h"
  16. #include "testcases/testcases.h"
  17. extern struct tdescr *current;
  18. static int sig_copyctx = SIGTRAP;
  19. static char const *const feats_names[FMAX_END] = {
  20. " SSBS ",
  21. " SVE ",
  22. " SME ",
  23. " FA64 ",
  24. " SME2 ",
  25. };
  26. #define MAX_FEATS_SZ 128
  27. static char feats_string[MAX_FEATS_SZ];
  28. static inline char *feats_to_string(unsigned long feats)
  29. {
  30. size_t flen = MAX_FEATS_SZ - 1;
  31. feats_string[0] = '\0';
  32. for (int i = 0; i < FMAX_END; i++) {
  33. if (feats & (1UL << i)) {
  34. size_t tlen = strlen(feats_names[i]);
  35. assert(flen > tlen);
  36. flen -= tlen;
  37. strncat(feats_string, feats_names[i], flen);
  38. }
  39. }
  40. return feats_string;
  41. }
  42. static void unblock_signal(int signum)
  43. {
  44. sigset_t sset;
  45. sigemptyset(&sset);
  46. sigaddset(&sset, signum);
  47. sigprocmask(SIG_UNBLOCK, &sset, NULL);
  48. }
  49. static void default_result(struct tdescr *td, bool force_exit)
  50. {
  51. if (td->result == KSFT_SKIP) {
  52. fprintf(stderr, "==>> completed. SKIP.\n");
  53. } else if (td->pass) {
  54. fprintf(stderr, "==>> completed. PASS(1)\n");
  55. td->result = KSFT_PASS;
  56. } else {
  57. fprintf(stdout, "==>> completed. FAIL(0)\n");
  58. td->result = KSFT_FAIL;
  59. }
  60. if (force_exit)
  61. exit(td->result);
  62. }
  63. /*
  64. * The following handle_signal_* helpers are used by main default_handler
  65. * and are meant to return true when signal is handled successfully:
  66. * when false is returned instead, it means that the signal was somehow
  67. * unexpected in that context and it was NOT handled; default_handler will
  68. * take care of such unexpected situations.
  69. */
  70. static bool handle_signal_unsupported(struct tdescr *td,
  71. siginfo_t *si, void *uc)
  72. {
  73. if (feats_ok(td))
  74. return false;
  75. /* Mangling PC to avoid loops on original SIGILL */
  76. ((ucontext_t *)uc)->uc_mcontext.pc += 4;
  77. if (!td->initialized) {
  78. fprintf(stderr,
  79. "Got SIG_UNSUPP @test_init. Ignore.\n");
  80. } else {
  81. fprintf(stderr,
  82. "-- RX SIG_UNSUPP on unsupported feat...OK\n");
  83. td->pass = 1;
  84. default_result(current, 1);
  85. }
  86. return true;
  87. }
  88. static bool handle_signal_trigger(struct tdescr *td,
  89. siginfo_t *si, void *uc)
  90. {
  91. td->triggered = 1;
  92. /* ->run was asserted NON-NULL in test_setup() already */
  93. td->run(td, si, uc);
  94. return true;
  95. }
  96. static bool handle_signal_ok(struct tdescr *td,
  97. siginfo_t *si, void *uc)
  98. {
  99. /*
  100. * it's a bug in the test code when this assert fail:
  101. * if sig_trig was defined, it must have been used before getting here.
  102. */
  103. assert(!td->sig_trig || td->triggered);
  104. fprintf(stderr,
  105. "SIG_OK -- SP:0x%llX si_addr@:%p si_code:%d token@:%p offset:%ld\n",
  106. ((ucontext_t *)uc)->uc_mcontext.sp,
  107. si->si_addr, si->si_code, td->token, td->token - si->si_addr);
  108. /*
  109. * fake_sigreturn tests, which have sanity_enabled=1, set, at the very
  110. * last time, the token field to the SP address used to place the fake
  111. * sigframe: so token==0 means we never made it to the end,
  112. * segfaulting well-before, and the test is possibly broken.
  113. */
  114. if (!td->sanity_disabled && !td->token) {
  115. fprintf(stdout,
  116. "current->token ZEROED...test is probably broken!\n");
  117. abort();
  118. }
  119. /*
  120. * Trying to narrow down the SEGV to the ones generated by Kernel itself
  121. * via arm64_notify_segfault(). This is a best-effort check anyway, and
  122. * the si_code check may need to change if this aspect of the kernel
  123. * ABI changes.
  124. */
  125. if (td->sig_ok == SIGSEGV && si->si_code != SEGV_ACCERR) {
  126. fprintf(stdout,
  127. "si_code != SEGV_ACCERR...test is probably broken!\n");
  128. abort();
  129. }
  130. td->pass = 1;
  131. /*
  132. * Some tests can lead to SEGV loops: in such a case we want to
  133. * terminate immediately exiting straight away; some others are not
  134. * supposed to outlive the signal handler code, due to the content of
  135. * the fake sigframe which caused the signal itself.
  136. */
  137. default_result(current, 1);
  138. return true;
  139. }
  140. static bool handle_signal_copyctx(struct tdescr *td,
  141. siginfo_t *si, void *uc_in)
  142. {
  143. ucontext_t *uc = uc_in;
  144. struct _aarch64_ctx *head;
  145. struct extra_context *extra, *copied_extra;
  146. size_t offset = 0;
  147. size_t to_copy;
  148. ASSERT_GOOD_CONTEXT(uc);
  149. /* Mangling PC to avoid loops on original BRK instr */
  150. uc->uc_mcontext.pc += 4;
  151. /*
  152. * Check for an preserve any extra data too with fixups.
  153. */
  154. head = (struct _aarch64_ctx *)uc->uc_mcontext.__reserved;
  155. head = get_header(head, EXTRA_MAGIC, td->live_sz, &offset);
  156. if (head) {
  157. extra = (struct extra_context *)head;
  158. /*
  159. * The extra buffer must be immediately after the
  160. * extra_context and a 16 byte terminator. Include it
  161. * in the copy, this was previously validated in
  162. * ASSERT_GOOD_CONTEXT().
  163. */
  164. to_copy = __builtin_offsetof(ucontext_t,
  165. uc_mcontext.__reserved);
  166. to_copy += offset + sizeof(struct extra_context) + 16;
  167. to_copy += extra->size;
  168. copied_extra = (struct extra_context *)&(td->live_uc->uc_mcontext.__reserved[offset]);
  169. } else {
  170. copied_extra = NULL;
  171. to_copy = sizeof(ucontext_t);
  172. }
  173. if (to_copy > td->live_sz) {
  174. fprintf(stderr,
  175. "Not enough space to grab context, %lu/%lu bytes\n",
  176. td->live_sz, to_copy);
  177. return false;
  178. }
  179. memcpy(td->live_uc, uc, to_copy);
  180. /*
  181. * If there was any EXTRA_CONTEXT fix up the size to be the
  182. * struct extra_context and the following terminator record,
  183. * this means that the rest of the code does not need to have
  184. * special handling for the record and we don't need to fix up
  185. * datap for the new location.
  186. */
  187. if (copied_extra)
  188. copied_extra->head.size = sizeof(*copied_extra) + 16;
  189. td->live_uc_valid = 1;
  190. fprintf(stderr,
  191. "%lu byte GOOD CONTEXT grabbed from sig_copyctx handler\n",
  192. to_copy);
  193. return true;
  194. }
  195. static void default_handler(int signum, siginfo_t *si, void *uc)
  196. {
  197. if (current->sig_unsupp && signum == current->sig_unsupp &&
  198. handle_signal_unsupported(current, si, uc)) {
  199. fprintf(stderr, "Handled SIG_UNSUPP\n");
  200. } else if (current->sig_trig && signum == current->sig_trig &&
  201. handle_signal_trigger(current, si, uc)) {
  202. fprintf(stderr, "Handled SIG_TRIG\n");
  203. } else if (current->sig_ok && signum == current->sig_ok &&
  204. handle_signal_ok(current, si, uc)) {
  205. fprintf(stderr, "Handled SIG_OK\n");
  206. } else if (signum == sig_copyctx && current->live_uc &&
  207. handle_signal_copyctx(current, si, uc)) {
  208. fprintf(stderr, "Handled SIG_COPYCTX\n");
  209. } else {
  210. if (signum == SIGALRM && current->timeout) {
  211. fprintf(stderr, "-- Timeout !\n");
  212. } else {
  213. fprintf(stderr,
  214. "-- RX UNEXPECTED SIGNAL: %d code %d address %p\n",
  215. signum, si->si_code, si->si_addr);
  216. }
  217. default_result(current, 1);
  218. }
  219. }
  220. static int default_setup(struct tdescr *td)
  221. {
  222. struct sigaction sa;
  223. sa.sa_sigaction = default_handler;
  224. sa.sa_flags = SA_SIGINFO | SA_RESTART;
  225. sa.sa_flags |= td->sa_flags;
  226. sigemptyset(&sa.sa_mask);
  227. /* uncatchable signals naturally skipped ... */
  228. for (int sig = 1; sig < 32; sig++)
  229. sigaction(sig, &sa, NULL);
  230. /*
  231. * RT Signals default disposition is Term but they cannot be
  232. * generated by the Kernel in response to our tests; so just catch
  233. * them all and report them as UNEXPECTED signals.
  234. */
  235. for (int sig = SIGRTMIN; sig <= SIGRTMAX; sig++)
  236. sigaction(sig, &sa, NULL);
  237. /* just in case...unblock explicitly all we need */
  238. if (td->sig_trig)
  239. unblock_signal(td->sig_trig);
  240. if (td->sig_ok)
  241. unblock_signal(td->sig_ok);
  242. if (td->sig_unsupp)
  243. unblock_signal(td->sig_unsupp);
  244. if (td->timeout) {
  245. unblock_signal(SIGALRM);
  246. alarm(td->timeout);
  247. }
  248. fprintf(stderr, "Registered handlers for all signals.\n");
  249. return 1;
  250. }
  251. static inline int default_trigger(struct tdescr *td)
  252. {
  253. return !raise(td->sig_trig);
  254. }
  255. int test_init(struct tdescr *td)
  256. {
  257. if (td->sig_trig == sig_copyctx) {
  258. fprintf(stdout,
  259. "Signal %d is RESERVED, cannot be used as a trigger. Aborting\n",
  260. sig_copyctx);
  261. return 0;
  262. }
  263. /* just in case */
  264. unblock_signal(sig_copyctx);
  265. td->minsigstksz = getauxval(AT_MINSIGSTKSZ);
  266. if (!td->minsigstksz)
  267. td->minsigstksz = MINSIGSTKSZ;
  268. fprintf(stderr, "Detected MINSTKSIGSZ:%d\n", td->minsigstksz);
  269. if (td->feats_required || td->feats_incompatible) {
  270. td->feats_supported = 0;
  271. /*
  272. * Checking for CPU required features using both the
  273. * auxval and the arm64 MRS Emulation to read sysregs.
  274. */
  275. if (getauxval(AT_HWCAP) & HWCAP_SSBS)
  276. td->feats_supported |= FEAT_SSBS;
  277. if (getauxval(AT_HWCAP) & HWCAP_SVE)
  278. td->feats_supported |= FEAT_SVE;
  279. if (getauxval(AT_HWCAP2) & HWCAP2_SME)
  280. td->feats_supported |= FEAT_SME;
  281. if (getauxval(AT_HWCAP2) & HWCAP2_SME_FA64)
  282. td->feats_supported |= FEAT_SME_FA64;
  283. if (getauxval(AT_HWCAP2) & HWCAP2_SME2)
  284. td->feats_supported |= FEAT_SME2;
  285. if (feats_ok(td)) {
  286. if (td->feats_required & td->feats_supported)
  287. fprintf(stderr,
  288. "Required Features: [%s] supported\n",
  289. feats_to_string(td->feats_required &
  290. td->feats_supported));
  291. if (!(td->feats_incompatible & td->feats_supported))
  292. fprintf(stderr,
  293. "Incompatible Features: [%s] absent\n",
  294. feats_to_string(td->feats_incompatible));
  295. } else {
  296. if ((td->feats_required & td->feats_supported) !=
  297. td->feats_supported)
  298. fprintf(stderr,
  299. "Required Features: [%s] NOT supported\n",
  300. feats_to_string(td->feats_required &
  301. ~td->feats_supported));
  302. if (td->feats_incompatible & td->feats_supported)
  303. fprintf(stderr,
  304. "Incompatible Features: [%s] supported\n",
  305. feats_to_string(td->feats_incompatible &
  306. ~td->feats_supported));
  307. td->result = KSFT_SKIP;
  308. return 0;
  309. }
  310. }
  311. /* Perform test specific additional initialization */
  312. if (td->init && !td->init(td)) {
  313. fprintf(stderr, "FAILED Testcase initialization.\n");
  314. return 0;
  315. }
  316. td->initialized = 1;
  317. fprintf(stderr, "Testcase initialized.\n");
  318. return 1;
  319. }
  320. int test_setup(struct tdescr *td)
  321. {
  322. /* assert core invariants symptom of a rotten testcase */
  323. assert(current);
  324. assert(td);
  325. assert(td->name);
  326. assert(td->run);
  327. /* Default result is FAIL if test setup fails */
  328. td->result = KSFT_FAIL;
  329. if (td->setup)
  330. return td->setup(td);
  331. else
  332. return default_setup(td);
  333. }
  334. int test_run(struct tdescr *td)
  335. {
  336. if (td->trigger)
  337. return td->trigger(td);
  338. else if (td->sig_trig)
  339. return default_trigger(td);
  340. else
  341. return td->run(td, NULL, NULL);
  342. }
  343. void test_result(struct tdescr *td)
  344. {
  345. if (td->initialized && td->result != KSFT_SKIP && td->check_result)
  346. td->check_result(td);
  347. default_result(td, 0);
  348. }
  349. void test_cleanup(struct tdescr *td)
  350. {
  351. if (td->cleanup)
  352. td->cleanup(td);
  353. }