test.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2019,2021 Arm Limited
  4. * Original author: Dave Martin <[email protected]>
  5. */
  6. #include "system.h"
  7. #include <stddef.h>
  8. #include <linux/errno.h>
  9. #include <linux/auxvec.h>
  10. #include <linux/signal.h>
  11. #include <asm/sigcontext.h>
  12. #include <asm/ucontext.h>
  13. typedef struct ucontext ucontext_t;
  14. #include "btitest.h"
  15. #include "compiler.h"
  16. #include "signal.h"
  17. #define EXPECTED_TESTS 18
  18. static volatile unsigned int test_num = 1;
  19. static unsigned int test_passed;
  20. static unsigned int test_failed;
  21. static unsigned int test_skipped;
  22. static void fdputs(int fd, const char *str)
  23. {
  24. size_t len = 0;
  25. const char *p = str;
  26. while (*p++)
  27. ++len;
  28. write(fd, str, len);
  29. }
  30. static void putstr(const char *str)
  31. {
  32. fdputs(1, str);
  33. }
  34. static void putnum(unsigned int num)
  35. {
  36. char c;
  37. if (num / 10)
  38. putnum(num / 10);
  39. c = '0' + (num % 10);
  40. write(1, &c, 1);
  41. }
  42. #define puttestname(test_name, trampoline_name) do { \
  43. putstr(test_name); \
  44. putstr("/"); \
  45. putstr(trampoline_name); \
  46. } while (0)
  47. void print_summary(void)
  48. {
  49. putstr("# Totals: pass:");
  50. putnum(test_passed);
  51. putstr(" fail:");
  52. putnum(test_failed);
  53. putstr(" xfail:0 xpass:0 skip:");
  54. putnum(test_skipped);
  55. putstr(" error:0\n");
  56. }
  57. static const char *volatile current_test_name;
  58. static const char *volatile current_trampoline_name;
  59. static volatile int sigill_expected, sigill_received;
  60. static void handler(int n, siginfo_t *si __always_unused,
  61. void *uc_ __always_unused)
  62. {
  63. ucontext_t *uc = uc_;
  64. putstr("# \t[SIGILL in ");
  65. puttestname(current_test_name, current_trampoline_name);
  66. putstr(", BTYPE=");
  67. write(1, &"00011011"[((uc->uc_mcontext.pstate & PSR_BTYPE_MASK)
  68. >> PSR_BTYPE_SHIFT) * 2], 2);
  69. if (!sigill_expected) {
  70. putstr("]\n");
  71. putstr("not ok ");
  72. putnum(test_num);
  73. putstr(" ");
  74. puttestname(current_test_name, current_trampoline_name);
  75. putstr("(unexpected SIGILL)\n");
  76. print_summary();
  77. exit(128 + n);
  78. }
  79. putstr(" (expected)]\n");
  80. sigill_received = 1;
  81. /* zap BTYPE so that resuming the faulting code will work */
  82. uc->uc_mcontext.pstate &= ~PSR_BTYPE_MASK;
  83. }
  84. static int skip_all;
  85. static void __do_test(void (*trampoline)(void (*)(void)),
  86. void (*fn)(void),
  87. const char *trampoline_name,
  88. const char *name,
  89. int expect_sigill)
  90. {
  91. if (skip_all) {
  92. test_skipped++;
  93. putstr("ok ");
  94. putnum(test_num);
  95. putstr(" ");
  96. puttestname(name, trampoline_name);
  97. putstr(" # SKIP\n");
  98. return;
  99. }
  100. /* Branch Target exceptions should only happen in BTI binaries: */
  101. if (!BTI)
  102. expect_sigill = 0;
  103. sigill_expected = expect_sigill;
  104. sigill_received = 0;
  105. current_test_name = name;
  106. current_trampoline_name = trampoline_name;
  107. trampoline(fn);
  108. if (expect_sigill && !sigill_received) {
  109. putstr("not ok ");
  110. test_failed++;
  111. } else {
  112. putstr("ok ");
  113. test_passed++;
  114. }
  115. putnum(test_num++);
  116. putstr(" ");
  117. puttestname(name, trampoline_name);
  118. putstr("\n");
  119. }
  120. #define do_test(expect_sigill_br_x0, \
  121. expect_sigill_br_x16, \
  122. expect_sigill_blr, \
  123. name) \
  124. do { \
  125. __do_test(call_using_br_x0, name, "call_using_br_x0", #name, \
  126. expect_sigill_br_x0); \
  127. __do_test(call_using_br_x16, name, "call_using_br_x16", #name, \
  128. expect_sigill_br_x16); \
  129. __do_test(call_using_blr, name, "call_using_blr", #name, \
  130. expect_sigill_blr); \
  131. } while (0)
  132. void start(int *argcp)
  133. {
  134. struct sigaction sa;
  135. void *const *p;
  136. const struct auxv_entry {
  137. unsigned long type;
  138. unsigned long val;
  139. } *auxv;
  140. unsigned long hwcap = 0, hwcap2 = 0;
  141. putstr("TAP version 13\n");
  142. putstr("1..");
  143. putnum(EXPECTED_TESTS);
  144. putstr("\n");
  145. /* Gross hack for finding AT_HWCAP2 from the initial process stack: */
  146. p = (void *const *)argcp + 1 + *argcp + 1; /* start of environment */
  147. /* step over environment */
  148. while (*p++)
  149. ;
  150. for (auxv = (const struct auxv_entry *)p; auxv->type != AT_NULL; ++auxv) {
  151. switch (auxv->type) {
  152. case AT_HWCAP:
  153. hwcap = auxv->val;
  154. break;
  155. case AT_HWCAP2:
  156. hwcap2 = auxv->val;
  157. break;
  158. default:
  159. break;
  160. }
  161. }
  162. if (hwcap & HWCAP_PACA)
  163. putstr("# HWCAP_PACA present\n");
  164. else
  165. putstr("# HWCAP_PACA not present\n");
  166. if (hwcap2 & HWCAP2_BTI) {
  167. putstr("# HWCAP2_BTI present\n");
  168. if (!(hwcap & HWCAP_PACA))
  169. putstr("# Bad hardware? Expect problems.\n");
  170. } else {
  171. putstr("# HWCAP2_BTI not present\n");
  172. skip_all = 1;
  173. }
  174. putstr("# Test binary");
  175. if (!BTI)
  176. putstr(" not");
  177. putstr(" built for BTI\n");
  178. sa.sa_handler = (sighandler_t)(void *)handler;
  179. sa.sa_flags = SA_SIGINFO;
  180. sigemptyset(&sa.sa_mask);
  181. sigaction(SIGILL, &sa, NULL);
  182. sigaddset(&sa.sa_mask, SIGILL);
  183. sigprocmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
  184. do_test(1, 1, 1, nohint_func);
  185. do_test(1, 1, 1, bti_none_func);
  186. do_test(1, 0, 0, bti_c_func);
  187. do_test(0, 0, 1, bti_j_func);
  188. do_test(0, 0, 0, bti_jc_func);
  189. do_test(1, 0, 0, paciasp_func);
  190. print_summary();
  191. if (test_num - 1 != EXPECTED_TESTS)
  192. putstr("# WARNING - EXPECTED TEST COUNT WRONG\n");
  193. if (test_failed)
  194. exit(1);
  195. else
  196. exit(0);
  197. }