test.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2019,2021 Arm Limited
  4. * Original author: Dave Martin <Dave.Martin@arm.com>
  5. */
  6. #include "system.h"
  7. #include <stdbool.h>
  8. #include <stddef.h>
  9. #include <linux/errno.h>
  10. #include <linux/auxvec.h>
  11. #include <linux/signal.h>
  12. #include <asm/sigcontext.h>
  13. #include <asm/ucontext.h>
  14. typedef struct ucontext ucontext_t;
  15. #include "btitest.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. /* Does the system have BTI? */
  85. static bool have_bti;
  86. static void __do_test(void (*trampoline)(void (*)(void)),
  87. void (*fn)(void),
  88. const char *trampoline_name,
  89. const char *name,
  90. int expect_sigill)
  91. {
  92. /*
  93. * Branch Target exceptions should only happen for BTI
  94. * binaries running on a system with BTI:
  95. */
  96. if (!BTI || !have_bti)
  97. expect_sigill = 0;
  98. sigill_expected = expect_sigill;
  99. sigill_received = 0;
  100. current_test_name = name;
  101. current_trampoline_name = trampoline_name;
  102. trampoline(fn);
  103. if (expect_sigill && !sigill_received) {
  104. putstr("not ok ");
  105. test_failed++;
  106. } else {
  107. putstr("ok ");
  108. test_passed++;
  109. }
  110. putnum(test_num++);
  111. putstr(" ");
  112. puttestname(name, trampoline_name);
  113. putstr("\n");
  114. }
  115. #define do_test(expect_sigill_br_x0, \
  116. expect_sigill_br_x16, \
  117. expect_sigill_blr, \
  118. name) \
  119. do { \
  120. __do_test(call_using_br_x0, name, "call_using_br_x0", #name, \
  121. expect_sigill_br_x0); \
  122. __do_test(call_using_br_x16, name, "call_using_br_x16", #name, \
  123. expect_sigill_br_x16); \
  124. __do_test(call_using_blr, name, "call_using_blr", #name, \
  125. expect_sigill_blr); \
  126. } while (0)
  127. void start(int *argcp)
  128. {
  129. struct sigaction sa;
  130. void *const *p;
  131. const struct auxv_entry {
  132. unsigned long type;
  133. unsigned long val;
  134. } *auxv;
  135. unsigned long hwcap = 0, hwcap2 = 0;
  136. putstr("TAP version 13\n");
  137. putstr("1..");
  138. putnum(EXPECTED_TESTS);
  139. putstr("\n");
  140. /* Gross hack for finding AT_HWCAP2 from the initial process stack: */
  141. p = (void *const *)argcp + 1 + *argcp + 1; /* start of environment */
  142. /* step over environment */
  143. while (*p++)
  144. ;
  145. for (auxv = (const struct auxv_entry *)p; auxv->type != AT_NULL; ++auxv) {
  146. switch (auxv->type) {
  147. case AT_HWCAP:
  148. hwcap = auxv->val;
  149. break;
  150. case AT_HWCAP2:
  151. hwcap2 = auxv->val;
  152. break;
  153. default:
  154. break;
  155. }
  156. }
  157. if (hwcap & HWCAP_PACA)
  158. putstr("# HWCAP_PACA present\n");
  159. else
  160. putstr("# HWCAP_PACA not present\n");
  161. if (hwcap2 & HWCAP2_BTI) {
  162. putstr("# HWCAP2_BTI present\n");
  163. if (!(hwcap & HWCAP_PACA))
  164. putstr("# Bad hardware? Expect problems.\n");
  165. have_bti = true;
  166. } else {
  167. putstr("# HWCAP2_BTI not present\n");
  168. have_bti = false;
  169. }
  170. putstr("# Test binary");
  171. if (!BTI)
  172. putstr(" not");
  173. putstr(" built for BTI\n");
  174. sa.sa_handler = (sighandler_t)(void *)handler;
  175. sa.sa_flags = SA_SIGINFO;
  176. sigemptyset(&sa.sa_mask);
  177. sigaction(SIGILL, &sa, NULL);
  178. sigaddset(&sa.sa_mask, SIGILL);
  179. sigprocmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
  180. do_test(1, 1, 1, nohint_func);
  181. do_test(1, 1, 1, bti_none_func);
  182. do_test(1, 0, 0, bti_c_func);
  183. do_test(0, 0, 1, bti_j_func);
  184. do_test(0, 0, 0, bti_jc_func);
  185. do_test(1, 0, 0, paciasp_func);
  186. print_summary();
  187. if (test_num - 1 != EXPECTED_TESTS)
  188. putstr("# WARNING - EXPECTED TEST COUNT WRONG\n");
  189. if (test_failed)
  190. exit(1);
  191. else
  192. exit(0);
  193. }