fp-ptrace.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2023 ARM Limited.
  4. * Original author: Mark Brown <broonie@kernel.org>
  5. */
  6. #define _GNU_SOURCE
  7. #include <errno.h>
  8. #include <stdbool.h>
  9. #include <stddef.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <unistd.h>
  14. #include <sys/auxv.h>
  15. #include <sys/prctl.h>
  16. #include <sys/ptrace.h>
  17. #include <sys/types.h>
  18. #include <sys/uio.h>
  19. #include <sys/wait.h>
  20. #include <linux/kernel.h>
  21. #include <asm/sigcontext.h>
  22. #include <asm/sve_context.h>
  23. #include <asm/ptrace.h>
  24. #include "../../kselftest.h"
  25. #include "fp-ptrace.h"
  26. /* <linux/elf.h> and <sys/auxv.h> don't like each other, so: */
  27. #ifndef NT_ARM_SVE
  28. #define NT_ARM_SVE 0x405
  29. #endif
  30. #ifndef NT_ARM_SSVE
  31. #define NT_ARM_SSVE 0x40b
  32. #endif
  33. #ifndef NT_ARM_ZA
  34. #define NT_ARM_ZA 0x40c
  35. #endif
  36. #ifndef NT_ARM_ZT
  37. #define NT_ARM_ZT 0x40d
  38. #endif
  39. #define ARCH_VQ_MAX 256
  40. /* VL 128..2048 in powers of 2 */
  41. #define MAX_NUM_VLS 5
  42. #define NUM_FPR 32
  43. __uint128_t v_in[NUM_FPR];
  44. __uint128_t v_expected[NUM_FPR];
  45. __uint128_t v_out[NUM_FPR];
  46. char z_in[__SVE_ZREGS_SIZE(ARCH_VQ_MAX)];
  47. char z_expected[__SVE_ZREGS_SIZE(ARCH_VQ_MAX)];
  48. char z_out[__SVE_ZREGS_SIZE(ARCH_VQ_MAX)];
  49. char p_in[__SVE_PREGS_SIZE(ARCH_VQ_MAX)];
  50. char p_expected[__SVE_PREGS_SIZE(ARCH_VQ_MAX)];
  51. char p_out[__SVE_PREGS_SIZE(ARCH_VQ_MAX)];
  52. char ffr_in[__SVE_PREG_SIZE(ARCH_VQ_MAX)];
  53. char ffr_expected[__SVE_PREG_SIZE(ARCH_VQ_MAX)];
  54. char ffr_out[__SVE_PREG_SIZE(ARCH_VQ_MAX)];
  55. char za_in[ZA_SIG_REGS_SIZE(ARCH_VQ_MAX)];
  56. char za_expected[ZA_SIG_REGS_SIZE(ARCH_VQ_MAX)];
  57. char za_out[ZA_SIG_REGS_SIZE(ARCH_VQ_MAX)];
  58. char zt_in[ZT_SIG_REG_BYTES];
  59. char zt_expected[ZT_SIG_REG_BYTES];
  60. char zt_out[ZT_SIG_REG_BYTES];
  61. uint64_t sve_vl_out;
  62. uint64_t sme_vl_out;
  63. uint64_t svcr_in, svcr_expected, svcr_out;
  64. void load_and_save(int sve, int sme, int sme2, int fa64);
  65. static bool got_alarm;
  66. static void handle_alarm(int sig, siginfo_t *info, void *context)
  67. {
  68. got_alarm = true;
  69. }
  70. #ifdef CONFIG_CPU_BIG_ENDIAN
  71. static __uint128_t arm64_cpu_to_le128(__uint128_t x)
  72. {
  73. u64 a = swab64(x);
  74. u64 b = swab64(x >> 64);
  75. return ((__uint128_t)a << 64) | b;
  76. }
  77. #else
  78. static __uint128_t arm64_cpu_to_le128(__uint128_t x)
  79. {
  80. return x;
  81. }
  82. #endif
  83. #define arm64_le128_to_cpu(x) arm64_cpu_to_le128(x)
  84. static bool sve_supported(void)
  85. {
  86. return getauxval(AT_HWCAP) & HWCAP_SVE;
  87. }
  88. static bool sme_supported(void)
  89. {
  90. return getauxval(AT_HWCAP2) & HWCAP2_SME;
  91. }
  92. static bool sme2_supported(void)
  93. {
  94. return getauxval(AT_HWCAP2) & HWCAP2_SME2;
  95. }
  96. static bool fa64_supported(void)
  97. {
  98. return getauxval(AT_HWCAP2) & HWCAP2_SME_FA64;
  99. }
  100. static bool compare_buffer(const char *name, void *out,
  101. void *expected, size_t size)
  102. {
  103. void *tmp;
  104. if (memcmp(out, expected, size) == 0)
  105. return true;
  106. ksft_print_msg("Mismatch in %s\n", name);
  107. /* Did we just get zeros back? */
  108. tmp = malloc(size);
  109. if (!tmp) {
  110. ksft_print_msg("OOM allocating %lu bytes for %s\n",
  111. size, name);
  112. ksft_exit_fail();
  113. }
  114. memset(tmp, 0, size);
  115. if (memcmp(out, tmp, size) == 0)
  116. ksft_print_msg("%s is zero\n", name);
  117. free(tmp);
  118. return false;
  119. }
  120. struct test_config {
  121. int sve_vl_in;
  122. int sve_vl_expected;
  123. int sme_vl_in;
  124. int sme_vl_expected;
  125. int svcr_in;
  126. int svcr_expected;
  127. };
  128. struct test_definition {
  129. const char *name;
  130. bool sve_vl_change;
  131. bool (*supported)(struct test_config *config);
  132. void (*set_expected_values)(struct test_config *config);
  133. void (*modify_values)(pid_t child, struct test_config *test_config);
  134. };
  135. static int vl_in(struct test_config *config)
  136. {
  137. int vl;
  138. if (config->svcr_in & SVCR_SM)
  139. vl = config->sme_vl_in;
  140. else
  141. vl = config->sve_vl_in;
  142. return vl;
  143. }
  144. static int vl_expected(struct test_config *config)
  145. {
  146. int vl;
  147. if (config->svcr_expected & SVCR_SM)
  148. vl = config->sme_vl_expected;
  149. else
  150. vl = config->sve_vl_expected;
  151. return vl;
  152. }
  153. static void run_child(struct test_config *config)
  154. {
  155. int ret;
  156. /* Let the parent attach to us */
  157. ret = ptrace(PTRACE_TRACEME, 0, 0, 0);
  158. if (ret < 0)
  159. ksft_exit_fail_msg("PTRACE_TRACEME failed: %s (%d)\n",
  160. strerror(errno), errno);
  161. /* VL setup */
  162. if (sve_supported()) {
  163. ret = prctl(PR_SVE_SET_VL, config->sve_vl_in);
  164. if (ret != config->sve_vl_in) {
  165. ksft_print_msg("Failed to set SVE VL %d: %d\n",
  166. config->sve_vl_in, ret);
  167. }
  168. }
  169. if (sme_supported()) {
  170. ret = prctl(PR_SME_SET_VL, config->sme_vl_in);
  171. if (ret != config->sme_vl_in) {
  172. ksft_print_msg("Failed to set SME VL %d: %d\n",
  173. config->sme_vl_in, ret);
  174. }
  175. }
  176. /* Load values and wait for the parent */
  177. load_and_save(sve_supported(), sme_supported(),
  178. sme2_supported(), fa64_supported());
  179. exit(0);
  180. }
  181. static void read_one_child_regs(pid_t child, char *name,
  182. struct iovec *iov_parent,
  183. struct iovec *iov_child)
  184. {
  185. int len = iov_parent->iov_len;
  186. int ret;
  187. ret = process_vm_readv(child, iov_parent, 1, iov_child, 1, 0);
  188. if (ret == -1)
  189. ksft_print_msg("%s read failed: %s (%d)\n",
  190. name, strerror(errno), errno);
  191. else if (ret != len)
  192. ksft_print_msg("Short read of %s: %d\n", name, ret);
  193. }
  194. static void read_child_regs(pid_t child)
  195. {
  196. struct iovec iov_parent, iov_child;
  197. /*
  198. * Since the child fork()ed from us the buffer addresses are
  199. * the same in parent and child.
  200. */
  201. iov_parent.iov_base = &v_out;
  202. iov_parent.iov_len = sizeof(v_out);
  203. iov_child.iov_base = &v_out;
  204. iov_child.iov_len = sizeof(v_out);
  205. read_one_child_regs(child, "FPSIMD", &iov_parent, &iov_child);
  206. if (sve_supported() || sme_supported()) {
  207. iov_parent.iov_base = &sve_vl_out;
  208. iov_parent.iov_len = sizeof(sve_vl_out);
  209. iov_child.iov_base = &sve_vl_out;
  210. iov_child.iov_len = sizeof(sve_vl_out);
  211. read_one_child_regs(child, "SVE VL", &iov_parent, &iov_child);
  212. iov_parent.iov_base = &z_out;
  213. iov_parent.iov_len = sizeof(z_out);
  214. iov_child.iov_base = &z_out;
  215. iov_child.iov_len = sizeof(z_out);
  216. read_one_child_regs(child, "Z", &iov_parent, &iov_child);
  217. iov_parent.iov_base = &p_out;
  218. iov_parent.iov_len = sizeof(p_out);
  219. iov_child.iov_base = &p_out;
  220. iov_child.iov_len = sizeof(p_out);
  221. read_one_child_regs(child, "P", &iov_parent, &iov_child);
  222. iov_parent.iov_base = &ffr_out;
  223. iov_parent.iov_len = sizeof(ffr_out);
  224. iov_child.iov_base = &ffr_out;
  225. iov_child.iov_len = sizeof(ffr_out);
  226. read_one_child_regs(child, "FFR", &iov_parent, &iov_child);
  227. }
  228. if (sme_supported()) {
  229. iov_parent.iov_base = &sme_vl_out;
  230. iov_parent.iov_len = sizeof(sme_vl_out);
  231. iov_child.iov_base = &sme_vl_out;
  232. iov_child.iov_len = sizeof(sme_vl_out);
  233. read_one_child_regs(child, "SME VL", &iov_parent, &iov_child);
  234. iov_parent.iov_base = &svcr_out;
  235. iov_parent.iov_len = sizeof(svcr_out);
  236. iov_child.iov_base = &svcr_out;
  237. iov_child.iov_len = sizeof(svcr_out);
  238. read_one_child_regs(child, "SVCR", &iov_parent, &iov_child);
  239. iov_parent.iov_base = &za_out;
  240. iov_parent.iov_len = sizeof(za_out);
  241. iov_child.iov_base = &za_out;
  242. iov_child.iov_len = sizeof(za_out);
  243. read_one_child_regs(child, "ZA", &iov_parent, &iov_child);
  244. }
  245. if (sme2_supported()) {
  246. iov_parent.iov_base = &zt_out;
  247. iov_parent.iov_len = sizeof(zt_out);
  248. iov_child.iov_base = &zt_out;
  249. iov_child.iov_len = sizeof(zt_out);
  250. read_one_child_regs(child, "ZT", &iov_parent, &iov_child);
  251. }
  252. }
  253. static bool continue_breakpoint(pid_t child,
  254. enum __ptrace_request restart_type)
  255. {
  256. struct user_pt_regs pt_regs;
  257. struct iovec iov;
  258. int ret;
  259. /* Get PC */
  260. iov.iov_base = &pt_regs;
  261. iov.iov_len = sizeof(pt_regs);
  262. ret = ptrace(PTRACE_GETREGSET, child, NT_PRSTATUS, &iov);
  263. if (ret < 0) {
  264. ksft_print_msg("Failed to get PC: %s (%d)\n",
  265. strerror(errno), errno);
  266. return false;
  267. }
  268. /* Skip over the BRK */
  269. pt_regs.pc += 4;
  270. ret = ptrace(PTRACE_SETREGSET, child, NT_PRSTATUS, &iov);
  271. if (ret < 0) {
  272. ksft_print_msg("Failed to skip BRK: %s (%d)\n",
  273. strerror(errno), errno);
  274. return false;
  275. }
  276. /* Restart */
  277. ret = ptrace(restart_type, child, 0, 0);
  278. if (ret < 0) {
  279. ksft_print_msg("Failed to restart child: %s (%d)\n",
  280. strerror(errno), errno);
  281. return false;
  282. }
  283. return true;
  284. }
  285. static bool check_ptrace_values_sve(pid_t child, struct test_config *config)
  286. {
  287. struct user_sve_header *sve;
  288. struct user_fpsimd_state *fpsimd;
  289. struct iovec iov;
  290. int ret, vq;
  291. bool pass = true;
  292. if (!sve_supported())
  293. return true;
  294. vq = __sve_vq_from_vl(config->sve_vl_in);
  295. iov.iov_len = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, SVE_PT_REGS_SVE);
  296. iov.iov_base = malloc(iov.iov_len);
  297. if (!iov.iov_base) {
  298. ksft_print_msg("OOM allocating %lu byte SVE buffer\n",
  299. iov.iov_len);
  300. return false;
  301. }
  302. ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_SVE, &iov);
  303. if (ret != 0) {
  304. ksft_print_msg("Failed to read initial SVE: %s (%d)\n",
  305. strerror(errno), errno);
  306. pass = false;
  307. goto out;
  308. }
  309. sve = iov.iov_base;
  310. if (sve->vl != config->sve_vl_in) {
  311. ksft_print_msg("Mismatch in initial SVE VL: %d != %d\n",
  312. sve->vl, config->sve_vl_in);
  313. pass = false;
  314. }
  315. /* If we are in streaming mode we should just read FPSIMD */
  316. if ((config->svcr_in & SVCR_SM) && (sve->flags & SVE_PT_REGS_SVE)) {
  317. ksft_print_msg("NT_ARM_SVE reports SVE with PSTATE.SM\n");
  318. pass = false;
  319. }
  320. if (sve->size != SVE_PT_SIZE(vq, sve->flags)) {
  321. ksft_print_msg("Mismatch in SVE header size: %d != %lu\n",
  322. sve->size, SVE_PT_SIZE(vq, sve->flags));
  323. pass = false;
  324. }
  325. /* The registers might be in completely different formats! */
  326. if (sve->flags & SVE_PT_REGS_SVE) {
  327. if (!compare_buffer("initial SVE Z",
  328. iov.iov_base + SVE_PT_SVE_ZREG_OFFSET(vq, 0),
  329. z_in, SVE_PT_SVE_ZREGS_SIZE(vq)))
  330. pass = false;
  331. if (!compare_buffer("initial SVE P",
  332. iov.iov_base + SVE_PT_SVE_PREG_OFFSET(vq, 0),
  333. p_in, SVE_PT_SVE_PREGS_SIZE(vq)))
  334. pass = false;
  335. if (!compare_buffer("initial SVE FFR",
  336. iov.iov_base + SVE_PT_SVE_FFR_OFFSET(vq),
  337. ffr_in, SVE_PT_SVE_PREG_SIZE(vq)))
  338. pass = false;
  339. } else {
  340. fpsimd = iov.iov_base + SVE_PT_FPSIMD_OFFSET;
  341. if (!compare_buffer("initial V via SVE", &fpsimd->vregs[0],
  342. v_in, sizeof(v_in)))
  343. pass = false;
  344. }
  345. out:
  346. free(iov.iov_base);
  347. return pass;
  348. }
  349. static bool check_ptrace_values_ssve(pid_t child, struct test_config *config)
  350. {
  351. struct user_sve_header *sve;
  352. struct user_fpsimd_state *fpsimd;
  353. struct iovec iov;
  354. int ret, vq;
  355. bool pass = true;
  356. if (!sme_supported())
  357. return true;
  358. vq = __sve_vq_from_vl(config->sme_vl_in);
  359. iov.iov_len = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, SVE_PT_REGS_SVE);
  360. iov.iov_base = malloc(iov.iov_len);
  361. if (!iov.iov_base) {
  362. ksft_print_msg("OOM allocating %lu byte SSVE buffer\n",
  363. iov.iov_len);
  364. return false;
  365. }
  366. ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_SSVE, &iov);
  367. if (ret != 0) {
  368. ksft_print_msg("Failed to read initial SSVE: %s (%d)\n",
  369. strerror(errno), errno);
  370. pass = false;
  371. goto out;
  372. }
  373. sve = iov.iov_base;
  374. if (sve->vl != config->sme_vl_in) {
  375. ksft_print_msg("Mismatch in initial SSVE VL: %d != %d\n",
  376. sve->vl, config->sme_vl_in);
  377. pass = false;
  378. }
  379. if ((config->svcr_in & SVCR_SM) && !(sve->flags & SVE_PT_REGS_SVE)) {
  380. ksft_print_msg("NT_ARM_SSVE reports FPSIMD with PSTATE.SM\n");
  381. pass = false;
  382. }
  383. if (sve->size != SVE_PT_SIZE(vq, sve->flags)) {
  384. ksft_print_msg("Mismatch in SSVE header size: %d != %lu\n",
  385. sve->size, SVE_PT_SIZE(vq, sve->flags));
  386. pass = false;
  387. }
  388. /* The registers might be in completely different formats! */
  389. if (sve->flags & SVE_PT_REGS_SVE) {
  390. if (!compare_buffer("initial SSVE Z",
  391. iov.iov_base + SVE_PT_SVE_ZREG_OFFSET(vq, 0),
  392. z_in, SVE_PT_SVE_ZREGS_SIZE(vq)))
  393. pass = false;
  394. if (!compare_buffer("initial SSVE P",
  395. iov.iov_base + SVE_PT_SVE_PREG_OFFSET(vq, 0),
  396. p_in, SVE_PT_SVE_PREGS_SIZE(vq)))
  397. pass = false;
  398. if (!compare_buffer("initial SSVE FFR",
  399. iov.iov_base + SVE_PT_SVE_FFR_OFFSET(vq),
  400. ffr_in, SVE_PT_SVE_PREG_SIZE(vq)))
  401. pass = false;
  402. } else {
  403. fpsimd = iov.iov_base + SVE_PT_FPSIMD_OFFSET;
  404. if (!compare_buffer("initial V via SSVE",
  405. &fpsimd->vregs[0], v_in, sizeof(v_in)))
  406. pass = false;
  407. }
  408. out:
  409. free(iov.iov_base);
  410. return pass;
  411. }
  412. static bool check_ptrace_values_za(pid_t child, struct test_config *config)
  413. {
  414. struct user_za_header *za;
  415. struct iovec iov;
  416. int ret, vq;
  417. bool pass = true;
  418. if (!sme_supported())
  419. return true;
  420. vq = __sve_vq_from_vl(config->sme_vl_in);
  421. iov.iov_len = ZA_SIG_CONTEXT_SIZE(vq);
  422. iov.iov_base = malloc(iov.iov_len);
  423. if (!iov.iov_base) {
  424. ksft_print_msg("OOM allocating %lu byte ZA buffer\n",
  425. iov.iov_len);
  426. return false;
  427. }
  428. ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_ZA, &iov);
  429. if (ret != 0) {
  430. ksft_print_msg("Failed to read initial ZA: %s (%d)\n",
  431. strerror(errno), errno);
  432. pass = false;
  433. goto out;
  434. }
  435. za = iov.iov_base;
  436. if (za->vl != config->sme_vl_in) {
  437. ksft_print_msg("Mismatch in initial SME VL: %d != %d\n",
  438. za->vl, config->sme_vl_in);
  439. pass = false;
  440. }
  441. /* If PSTATE.ZA is not set we should just read the header */
  442. if (config->svcr_in & SVCR_ZA) {
  443. if (za->size != ZA_PT_SIZE(vq)) {
  444. ksft_print_msg("Unexpected ZA ptrace read size: %d != %lu\n",
  445. za->size, ZA_PT_SIZE(vq));
  446. pass = false;
  447. }
  448. if (!compare_buffer("initial ZA",
  449. iov.iov_base + ZA_PT_ZA_OFFSET,
  450. za_in, ZA_PT_ZA_SIZE(vq)))
  451. pass = false;
  452. } else {
  453. if (za->size != sizeof(*za)) {
  454. ksft_print_msg("Unexpected ZA ptrace read size: %d != %lu\n",
  455. za->size, sizeof(*za));
  456. pass = false;
  457. }
  458. }
  459. out:
  460. free(iov.iov_base);
  461. return pass;
  462. }
  463. static bool check_ptrace_values_zt(pid_t child, struct test_config *config)
  464. {
  465. uint8_t buf[512];
  466. struct iovec iov;
  467. int ret;
  468. if (!sme2_supported())
  469. return true;
  470. iov.iov_base = &buf;
  471. iov.iov_len = ZT_SIG_REG_BYTES;
  472. ret = ptrace(PTRACE_GETREGSET, child, NT_ARM_ZT, &iov);
  473. if (ret != 0) {
  474. ksft_print_msg("Failed to read initial ZT: %s (%d)\n",
  475. strerror(errno), errno);
  476. return false;
  477. }
  478. return compare_buffer("initial ZT", buf, zt_in, ZT_SIG_REG_BYTES);
  479. }
  480. static bool check_ptrace_values(pid_t child, struct test_config *config)
  481. {
  482. bool pass = true;
  483. struct user_fpsimd_state fpsimd;
  484. struct iovec iov;
  485. int ret;
  486. iov.iov_base = &fpsimd;
  487. iov.iov_len = sizeof(fpsimd);
  488. ret = ptrace(PTRACE_GETREGSET, child, NT_PRFPREG, &iov);
  489. if (ret == 0) {
  490. if (!compare_buffer("initial V", &fpsimd.vregs, v_in,
  491. sizeof(v_in))) {
  492. pass = false;
  493. }
  494. } else {
  495. ksft_print_msg("Failed to read initial V: %s (%d)\n",
  496. strerror(errno), errno);
  497. pass = false;
  498. }
  499. if (!check_ptrace_values_sve(child, config))
  500. pass = false;
  501. if (!check_ptrace_values_ssve(child, config))
  502. pass = false;
  503. if (!check_ptrace_values_za(child, config))
  504. pass = false;
  505. if (!check_ptrace_values_zt(child, config))
  506. pass = false;
  507. return pass;
  508. }
  509. static bool run_parent(pid_t child, struct test_definition *test,
  510. struct test_config *config)
  511. {
  512. int wait_status, ret;
  513. pid_t pid;
  514. bool pass;
  515. /* Initial attach */
  516. while (1) {
  517. pid = waitpid(child, &wait_status, 0);
  518. if (pid < 0) {
  519. if (errno == EINTR)
  520. continue;
  521. ksft_exit_fail_msg("waitpid() failed: %s (%d)\n",
  522. strerror(errno), errno);
  523. }
  524. if (pid == child)
  525. break;
  526. }
  527. if (WIFEXITED(wait_status)) {
  528. ksft_print_msg("Child exited loading values with status %d\n",
  529. WEXITSTATUS(wait_status));
  530. pass = false;
  531. goto out;
  532. }
  533. if (WIFSIGNALED(wait_status)) {
  534. ksft_print_msg("Child died from signal %d loading values\n",
  535. WTERMSIG(wait_status));
  536. pass = false;
  537. goto out;
  538. }
  539. /* Read initial values via ptrace */
  540. pass = check_ptrace_values(child, config);
  541. /* Do whatever writes we want to do */
  542. if (test->modify_values)
  543. test->modify_values(child, config);
  544. if (!continue_breakpoint(child, PTRACE_CONT))
  545. goto cleanup;
  546. while (1) {
  547. pid = waitpid(child, &wait_status, 0);
  548. if (pid < 0) {
  549. if (errno == EINTR)
  550. continue;
  551. ksft_exit_fail_msg("waitpid() failed: %s (%d)\n",
  552. strerror(errno), errno);
  553. }
  554. if (pid == child)
  555. break;
  556. }
  557. if (WIFEXITED(wait_status)) {
  558. ksft_print_msg("Child exited saving values with status %d\n",
  559. WEXITSTATUS(wait_status));
  560. pass = false;
  561. goto out;
  562. }
  563. if (WIFSIGNALED(wait_status)) {
  564. ksft_print_msg("Child died from signal %d saving values\n",
  565. WTERMSIG(wait_status));
  566. pass = false;
  567. goto out;
  568. }
  569. /* See what happened as a result */
  570. read_child_regs(child);
  571. if (!continue_breakpoint(child, PTRACE_DETACH))
  572. goto cleanup;
  573. /* The child should exit cleanly */
  574. got_alarm = false;
  575. alarm(1);
  576. while (1) {
  577. if (got_alarm) {
  578. ksft_print_msg("Wait for child timed out\n");
  579. goto cleanup;
  580. }
  581. pid = waitpid(child, &wait_status, 0);
  582. if (pid < 0) {
  583. if (errno == EINTR)
  584. continue;
  585. ksft_exit_fail_msg("waitpid() failed: %s (%d)\n",
  586. strerror(errno), errno);
  587. }
  588. if (pid == child)
  589. break;
  590. }
  591. alarm(0);
  592. if (got_alarm) {
  593. ksft_print_msg("Timed out waiting for child\n");
  594. pass = false;
  595. goto cleanup;
  596. }
  597. if (pid == child && WIFSIGNALED(wait_status)) {
  598. ksft_print_msg("Child died from signal %d cleaning up\n",
  599. WTERMSIG(wait_status));
  600. pass = false;
  601. goto out;
  602. }
  603. if (pid == child && WIFEXITED(wait_status)) {
  604. if (WEXITSTATUS(wait_status) != 0) {
  605. ksft_print_msg("Child exited with error %d\n",
  606. WEXITSTATUS(wait_status));
  607. pass = false;
  608. }
  609. } else {
  610. ksft_print_msg("Child did not exit cleanly\n");
  611. pass = false;
  612. goto cleanup;
  613. }
  614. goto out;
  615. cleanup:
  616. ret = kill(child, SIGKILL);
  617. if (ret != 0) {
  618. ksft_print_msg("kill() failed: %s (%d)\n",
  619. strerror(errno), errno);
  620. return false;
  621. }
  622. while (1) {
  623. pid = waitpid(child, &wait_status, 0);
  624. if (pid < 0) {
  625. if (errno == EINTR)
  626. continue;
  627. ksft_exit_fail_msg("waitpid() failed: %s (%d)\n",
  628. strerror(errno), errno);
  629. }
  630. if (pid == child)
  631. break;
  632. }
  633. out:
  634. return pass;
  635. }
  636. static void fill_random(void *buf, size_t size)
  637. {
  638. int i;
  639. uint32_t *lbuf = buf;
  640. /* random() returns a 32 bit number regardless of the size of long */
  641. for (i = 0; i < size / sizeof(uint32_t); i++)
  642. lbuf[i] = random();
  643. }
  644. static void fill_random_ffr(void *buf, size_t vq)
  645. {
  646. uint8_t *lbuf = buf;
  647. int bits, i;
  648. /*
  649. * Only values with a continuous set of 0..n bits set are
  650. * valid for FFR, set all bits then clear a random number of
  651. * high bits.
  652. */
  653. memset(buf, 0, __SVE_FFR_SIZE(vq));
  654. bits = random() % (__SVE_FFR_SIZE(vq) * 8);
  655. for (i = 0; i < bits / 8; i++)
  656. lbuf[i] = 0xff;
  657. if (bits / 8 != __SVE_FFR_SIZE(vq))
  658. lbuf[i] = (1 << (bits % 8)) - 1;
  659. }
  660. static void fpsimd_to_sve(__uint128_t *v, char *z, int vl)
  661. {
  662. int vq = __sve_vq_from_vl(vl);
  663. int i;
  664. __uint128_t *p;
  665. if (!vl)
  666. return;
  667. for (i = 0; i < __SVE_NUM_ZREGS; i++) {
  668. p = (__uint128_t *)&z[__SVE_ZREG_OFFSET(vq, i)];
  669. *p = arm64_cpu_to_le128(v[i]);
  670. }
  671. }
  672. static void set_initial_values(struct test_config *config)
  673. {
  674. int vq = __sve_vq_from_vl(vl_in(config));
  675. int sme_vq = __sve_vq_from_vl(config->sme_vl_in);
  676. svcr_in = config->svcr_in;
  677. svcr_expected = config->svcr_expected;
  678. svcr_out = 0;
  679. fill_random(&v_in, sizeof(v_in));
  680. memcpy(v_expected, v_in, sizeof(v_in));
  681. memset(v_out, 0, sizeof(v_out));
  682. /* Changes will be handled in the test case */
  683. if (sve_supported() || (config->svcr_in & SVCR_SM)) {
  684. /* The low 128 bits of Z are shared with the V registers */
  685. fill_random(&z_in, __SVE_ZREGS_SIZE(vq));
  686. fpsimd_to_sve(v_in, z_in, vl_in(config));
  687. memcpy(z_expected, z_in, __SVE_ZREGS_SIZE(vq));
  688. memset(z_out, 0, sizeof(z_out));
  689. fill_random(&p_in, __SVE_PREGS_SIZE(vq));
  690. memcpy(p_expected, p_in, __SVE_PREGS_SIZE(vq));
  691. memset(p_out, 0, sizeof(p_out));
  692. if ((config->svcr_in & SVCR_SM) && !fa64_supported())
  693. memset(ffr_in, 0, __SVE_PREG_SIZE(vq));
  694. else
  695. fill_random_ffr(&ffr_in, vq);
  696. memcpy(ffr_expected, ffr_in, __SVE_PREG_SIZE(vq));
  697. memset(ffr_out, 0, __SVE_PREG_SIZE(vq));
  698. }
  699. if (config->svcr_in & SVCR_ZA)
  700. fill_random(za_in, ZA_SIG_REGS_SIZE(sme_vq));
  701. else
  702. memset(za_in, 0, ZA_SIG_REGS_SIZE(sme_vq));
  703. if (config->svcr_expected & SVCR_ZA)
  704. memcpy(za_expected, za_in, ZA_SIG_REGS_SIZE(sme_vq));
  705. else
  706. memset(za_expected, 0, ZA_SIG_REGS_SIZE(sme_vq));
  707. if (sme_supported())
  708. memset(za_out, 0, sizeof(za_out));
  709. if (sme2_supported()) {
  710. if (config->svcr_in & SVCR_ZA)
  711. fill_random(zt_in, ZT_SIG_REG_BYTES);
  712. else
  713. memset(zt_in, 0, ZT_SIG_REG_BYTES);
  714. if (config->svcr_expected & SVCR_ZA)
  715. memcpy(zt_expected, zt_in, ZT_SIG_REG_BYTES);
  716. else
  717. memset(zt_expected, 0, ZT_SIG_REG_BYTES);
  718. memset(zt_out, 0, sizeof(zt_out));
  719. }
  720. }
  721. static bool check_memory_values(struct test_config *config)
  722. {
  723. bool pass = true;
  724. int vq, sme_vq;
  725. if (!compare_buffer("saved V", v_out, v_expected, sizeof(v_out)))
  726. pass = false;
  727. vq = __sve_vq_from_vl(vl_expected(config));
  728. sme_vq = __sve_vq_from_vl(config->sme_vl_expected);
  729. if (svcr_out != svcr_expected) {
  730. ksft_print_msg("Mismatch in saved SVCR %lx != %lx\n",
  731. svcr_out, svcr_expected);
  732. pass = false;
  733. }
  734. if (sve_vl_out != config->sve_vl_expected) {
  735. ksft_print_msg("Mismatch in SVE VL: %ld != %d\n",
  736. sve_vl_out, config->sve_vl_expected);
  737. pass = false;
  738. }
  739. if (sme_vl_out != config->sme_vl_expected) {
  740. ksft_print_msg("Mismatch in SME VL: %ld != %d\n",
  741. sme_vl_out, config->sme_vl_expected);
  742. pass = false;
  743. }
  744. if (!compare_buffer("saved Z", z_out, z_expected,
  745. __SVE_ZREGS_SIZE(vq)))
  746. pass = false;
  747. if (!compare_buffer("saved P", p_out, p_expected,
  748. __SVE_PREGS_SIZE(vq)))
  749. pass = false;
  750. if (!compare_buffer("saved FFR", ffr_out, ffr_expected,
  751. __SVE_PREG_SIZE(vq)))
  752. pass = false;
  753. if (!compare_buffer("saved ZA", za_out, za_expected,
  754. ZA_PT_ZA_SIZE(sme_vq)))
  755. pass = false;
  756. if (!compare_buffer("saved ZT", zt_out, zt_expected, ZT_SIG_REG_BYTES))
  757. pass = false;
  758. return pass;
  759. }
  760. static bool sve_sme_same(struct test_config *config)
  761. {
  762. if (config->sve_vl_in != config->sve_vl_expected)
  763. return false;
  764. if (config->sme_vl_in != config->sme_vl_expected)
  765. return false;
  766. if (config->svcr_in != config->svcr_expected)
  767. return false;
  768. return true;
  769. }
  770. static bool sve_write_supported(struct test_config *config)
  771. {
  772. if (!sve_supported() && !sme_supported())
  773. return false;
  774. if ((config->svcr_in & SVCR_ZA) != (config->svcr_expected & SVCR_ZA))
  775. return false;
  776. if (config->svcr_expected & SVCR_SM) {
  777. if (config->sve_vl_in != config->sve_vl_expected) {
  778. return false;
  779. }
  780. /* Changing the SME VL disables ZA */
  781. if ((config->svcr_expected & SVCR_ZA) &&
  782. (config->sme_vl_in != config->sme_vl_expected)) {
  783. return false;
  784. }
  785. } else {
  786. if (config->sme_vl_in != config->sme_vl_expected) {
  787. return false;
  788. }
  789. }
  790. return true;
  791. }
  792. static void fpsimd_write_expected(struct test_config *config)
  793. {
  794. int vl;
  795. fill_random(&v_expected, sizeof(v_expected));
  796. /* The SVE registers are flushed by a FPSIMD write */
  797. vl = vl_expected(config);
  798. memset(z_expected, 0, __SVE_ZREGS_SIZE(__sve_vq_from_vl(vl)));
  799. memset(p_expected, 0, __SVE_PREGS_SIZE(__sve_vq_from_vl(vl)));
  800. memset(ffr_expected, 0, __SVE_PREG_SIZE(__sve_vq_from_vl(vl)));
  801. fpsimd_to_sve(v_expected, z_expected, vl);
  802. }
  803. static void fpsimd_write(pid_t child, struct test_config *test_config)
  804. {
  805. struct user_fpsimd_state fpsimd;
  806. struct iovec iov;
  807. int ret;
  808. memset(&fpsimd, 0, sizeof(fpsimd));
  809. memcpy(&fpsimd.vregs, v_expected, sizeof(v_expected));
  810. iov.iov_base = &fpsimd;
  811. iov.iov_len = sizeof(fpsimd);
  812. ret = ptrace(PTRACE_SETREGSET, child, NT_PRFPREG, &iov);
  813. if (ret == -1)
  814. ksft_print_msg("FPSIMD set failed: (%s) %d\n",
  815. strerror(errno), errno);
  816. }
  817. static void sve_write_expected(struct test_config *config)
  818. {
  819. int vl = vl_expected(config);
  820. int sme_vq = __sve_vq_from_vl(config->sme_vl_expected);
  821. fill_random(z_expected, __SVE_ZREGS_SIZE(__sve_vq_from_vl(vl)));
  822. fill_random(p_expected, __SVE_PREGS_SIZE(__sve_vq_from_vl(vl)));
  823. if ((svcr_expected & SVCR_SM) && !fa64_supported())
  824. memset(ffr_expected, 0, __SVE_PREG_SIZE(sme_vq));
  825. else
  826. fill_random_ffr(ffr_expected, __sve_vq_from_vl(vl));
  827. /* Share the low bits of Z with V */
  828. fill_random(&v_expected, sizeof(v_expected));
  829. fpsimd_to_sve(v_expected, z_expected, vl);
  830. if (config->sme_vl_in != config->sme_vl_expected) {
  831. memset(za_expected, 0, ZA_PT_ZA_SIZE(sme_vq));
  832. memset(zt_expected, 0, sizeof(zt_expected));
  833. }
  834. }
  835. static void sve_write(pid_t child, struct test_config *config)
  836. {
  837. struct user_sve_header *sve;
  838. struct iovec iov;
  839. int ret, vl, vq, regset;
  840. vl = vl_expected(config);
  841. vq = __sve_vq_from_vl(vl);
  842. iov.iov_len = SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, SVE_PT_REGS_SVE);
  843. iov.iov_base = malloc(iov.iov_len);
  844. if (!iov.iov_base) {
  845. ksft_print_msg("Failed allocating %lu byte SVE write buffer\n",
  846. iov.iov_len);
  847. return;
  848. }
  849. memset(iov.iov_base, 0, iov.iov_len);
  850. sve = iov.iov_base;
  851. sve->size = iov.iov_len;
  852. sve->flags = SVE_PT_REGS_SVE;
  853. sve->vl = vl;
  854. memcpy(iov.iov_base + SVE_PT_SVE_ZREG_OFFSET(vq, 0),
  855. z_expected, SVE_PT_SVE_ZREGS_SIZE(vq));
  856. memcpy(iov.iov_base + SVE_PT_SVE_PREG_OFFSET(vq, 0),
  857. p_expected, SVE_PT_SVE_PREGS_SIZE(vq));
  858. memcpy(iov.iov_base + SVE_PT_SVE_FFR_OFFSET(vq),
  859. ffr_expected, SVE_PT_SVE_PREG_SIZE(vq));
  860. if (svcr_expected & SVCR_SM)
  861. regset = NT_ARM_SSVE;
  862. else
  863. regset = NT_ARM_SVE;
  864. ret = ptrace(PTRACE_SETREGSET, child, regset, &iov);
  865. if (ret != 0)
  866. ksft_print_msg("Failed to write SVE: %s (%d)\n",
  867. strerror(errno), errno);
  868. free(iov.iov_base);
  869. }
  870. static bool za_write_supported(struct test_config *config)
  871. {
  872. if (config->svcr_expected & SVCR_SM) {
  873. if (!(config->svcr_in & SVCR_SM))
  874. return false;
  875. /* Changing the SME VL exits streaming mode */
  876. if (config->sme_vl_in != config->sme_vl_expected) {
  877. return false;
  878. }
  879. }
  880. /* Can't disable SM outside a VL change */
  881. if ((config->svcr_in & SVCR_SM) &&
  882. !(config->svcr_expected & SVCR_SM))
  883. return false;
  884. return true;
  885. }
  886. static void za_write_expected(struct test_config *config)
  887. {
  888. int sme_vq, sve_vq;
  889. sme_vq = __sve_vq_from_vl(config->sme_vl_expected);
  890. if (config->svcr_expected & SVCR_ZA) {
  891. fill_random(za_expected, ZA_PT_ZA_SIZE(sme_vq));
  892. } else {
  893. memset(za_expected, 0, ZA_PT_ZA_SIZE(sme_vq));
  894. memset(zt_expected, 0, sizeof(zt_expected));
  895. }
  896. /* Changing the SME VL flushes ZT, SVE state and exits SM */
  897. if (config->sme_vl_in != config->sme_vl_expected) {
  898. svcr_expected &= ~SVCR_SM;
  899. sve_vq = __sve_vq_from_vl(vl_expected(config));
  900. memset(z_expected, 0, __SVE_ZREGS_SIZE(sve_vq));
  901. memset(p_expected, 0, __SVE_PREGS_SIZE(sve_vq));
  902. memset(ffr_expected, 0, __SVE_PREG_SIZE(sve_vq));
  903. memset(zt_expected, 0, sizeof(zt_expected));
  904. fpsimd_to_sve(v_expected, z_expected, vl_expected(config));
  905. }
  906. }
  907. static void za_write(pid_t child, struct test_config *config)
  908. {
  909. struct user_za_header *za;
  910. struct iovec iov;
  911. int ret, vq;
  912. vq = __sve_vq_from_vl(config->sme_vl_expected);
  913. if (config->svcr_expected & SVCR_ZA)
  914. iov.iov_len = ZA_PT_SIZE(vq);
  915. else
  916. iov.iov_len = sizeof(*za);
  917. iov.iov_base = malloc(iov.iov_len);
  918. if (!iov.iov_base) {
  919. ksft_print_msg("Failed allocating %lu byte ZA write buffer\n",
  920. iov.iov_len);
  921. return;
  922. }
  923. memset(iov.iov_base, 0, iov.iov_len);
  924. za = iov.iov_base;
  925. za->size = iov.iov_len;
  926. za->vl = config->sme_vl_expected;
  927. if (config->svcr_expected & SVCR_ZA)
  928. memcpy(iov.iov_base + ZA_PT_ZA_OFFSET, za_expected,
  929. ZA_PT_ZA_SIZE(vq));
  930. ret = ptrace(PTRACE_SETREGSET, child, NT_ARM_ZA, &iov);
  931. if (ret != 0)
  932. ksft_print_msg("Failed to write ZA: %s (%d)\n",
  933. strerror(errno), errno);
  934. free(iov.iov_base);
  935. }
  936. static bool zt_write_supported(struct test_config *config)
  937. {
  938. if (!sme2_supported())
  939. return false;
  940. if (config->sme_vl_in != config->sme_vl_expected)
  941. return false;
  942. if (!(config->svcr_expected & SVCR_ZA))
  943. return false;
  944. if ((config->svcr_in & SVCR_SM) != (config->svcr_expected & SVCR_SM))
  945. return false;
  946. return true;
  947. }
  948. static void zt_write_expected(struct test_config *config)
  949. {
  950. int sme_vq;
  951. sme_vq = __sve_vq_from_vl(config->sme_vl_expected);
  952. if (config->svcr_expected & SVCR_ZA) {
  953. fill_random(zt_expected, sizeof(zt_expected));
  954. } else {
  955. memset(za_expected, 0, ZA_PT_ZA_SIZE(sme_vq));
  956. memset(zt_expected, 0, sizeof(zt_expected));
  957. }
  958. }
  959. static void zt_write(pid_t child, struct test_config *config)
  960. {
  961. struct iovec iov;
  962. int ret;
  963. iov.iov_len = ZT_SIG_REG_BYTES;
  964. iov.iov_base = zt_expected;
  965. ret = ptrace(PTRACE_SETREGSET, child, NT_ARM_ZT, &iov);
  966. if (ret != 0)
  967. ksft_print_msg("Failed to write ZT: %s (%d)\n",
  968. strerror(errno), errno);
  969. }
  970. /* Actually run a test */
  971. static void run_test(struct test_definition *test, struct test_config *config)
  972. {
  973. pid_t child;
  974. char name[1024];
  975. bool pass;
  976. if (sve_supported() && sme_supported())
  977. snprintf(name, sizeof(name), "%s, SVE %d->%d, SME %d/%x->%d/%x",
  978. test->name,
  979. config->sve_vl_in, config->sve_vl_expected,
  980. config->sme_vl_in, config->svcr_in,
  981. config->sme_vl_expected, config->svcr_expected);
  982. else if (sve_supported())
  983. snprintf(name, sizeof(name), "%s, SVE %d->%d", test->name,
  984. config->sve_vl_in, config->sve_vl_expected);
  985. else if (sme_supported())
  986. snprintf(name, sizeof(name), "%s, SME %d/%x->%d/%x",
  987. test->name,
  988. config->sme_vl_in, config->svcr_in,
  989. config->sme_vl_expected, config->svcr_expected);
  990. else
  991. snprintf(name, sizeof(name), "%s", test->name);
  992. if (test->supported && !test->supported(config)) {
  993. ksft_test_result_skip("%s\n", name);
  994. return;
  995. }
  996. set_initial_values(config);
  997. if (test->set_expected_values)
  998. test->set_expected_values(config);
  999. child = fork();
  1000. if (child < 0)
  1001. ksft_exit_fail_msg("fork() failed: %s (%d)\n",
  1002. strerror(errno), errno);
  1003. /* run_child() never returns */
  1004. if (child == 0)
  1005. run_child(config);
  1006. pass = run_parent(child, test, config);
  1007. if (!check_memory_values(config))
  1008. pass = false;
  1009. ksft_test_result(pass, "%s\n", name);
  1010. }
  1011. static void run_tests(struct test_definition defs[], int count,
  1012. struct test_config *config)
  1013. {
  1014. int i;
  1015. for (i = 0; i < count; i++)
  1016. run_test(&defs[i], config);
  1017. }
  1018. static struct test_definition base_test_defs[] = {
  1019. {
  1020. .name = "No writes",
  1021. .supported = sve_sme_same,
  1022. },
  1023. {
  1024. .name = "FPSIMD write",
  1025. .supported = sve_sme_same,
  1026. .set_expected_values = fpsimd_write_expected,
  1027. .modify_values = fpsimd_write,
  1028. },
  1029. };
  1030. static struct test_definition sve_test_defs[] = {
  1031. {
  1032. .name = "SVE write",
  1033. .supported = sve_write_supported,
  1034. .set_expected_values = sve_write_expected,
  1035. .modify_values = sve_write,
  1036. },
  1037. };
  1038. static struct test_definition za_test_defs[] = {
  1039. {
  1040. .name = "ZA write",
  1041. .supported = za_write_supported,
  1042. .set_expected_values = za_write_expected,
  1043. .modify_values = za_write,
  1044. },
  1045. };
  1046. static struct test_definition zt_test_defs[] = {
  1047. {
  1048. .name = "ZT write",
  1049. .supported = zt_write_supported,
  1050. .set_expected_values = zt_write_expected,
  1051. .modify_values = zt_write,
  1052. },
  1053. };
  1054. static int sve_vls[MAX_NUM_VLS], sme_vls[MAX_NUM_VLS];
  1055. static int sve_vl_count, sme_vl_count;
  1056. static void probe_vls(const char *name, int vls[], int *vl_count, int set_vl)
  1057. {
  1058. unsigned int vq;
  1059. int vl;
  1060. *vl_count = 0;
  1061. for (vq = ARCH_VQ_MAX; vq > 0; vq /= 2) {
  1062. vl = prctl(set_vl, vq * 16);
  1063. if (vl == -1)
  1064. ksft_exit_fail_msg("SET_VL failed: %s (%d)\n",
  1065. strerror(errno), errno);
  1066. vl &= PR_SVE_VL_LEN_MASK;
  1067. if (*vl_count && (vl == vls[*vl_count - 1]))
  1068. break;
  1069. vq = sve_vq_from_vl(vl);
  1070. vls[*vl_count] = vl;
  1071. *vl_count += 1;
  1072. }
  1073. if (*vl_count > 2) {
  1074. /* Just use the minimum and maximum */
  1075. vls[1] = vls[*vl_count - 1];
  1076. ksft_print_msg("%d %s VLs, using %d and %d\n",
  1077. *vl_count, name, vls[0], vls[1]);
  1078. *vl_count = 2;
  1079. } else {
  1080. ksft_print_msg("%d %s VLs\n", *vl_count, name);
  1081. }
  1082. }
  1083. static struct {
  1084. int svcr_in, svcr_expected;
  1085. } svcr_combinations[] = {
  1086. { .svcr_in = 0, .svcr_expected = 0, },
  1087. { .svcr_in = 0, .svcr_expected = SVCR_SM, },
  1088. { .svcr_in = 0, .svcr_expected = SVCR_ZA, },
  1089. /* Can't enable both SM and ZA with a single ptrace write */
  1090. { .svcr_in = SVCR_SM, .svcr_expected = 0, },
  1091. { .svcr_in = SVCR_SM, .svcr_expected = SVCR_SM, },
  1092. { .svcr_in = SVCR_SM, .svcr_expected = SVCR_ZA, },
  1093. { .svcr_in = SVCR_SM, .svcr_expected = SVCR_SM | SVCR_ZA, },
  1094. { .svcr_in = SVCR_ZA, .svcr_expected = 0, },
  1095. { .svcr_in = SVCR_ZA, .svcr_expected = SVCR_SM, },
  1096. { .svcr_in = SVCR_ZA, .svcr_expected = SVCR_ZA, },
  1097. { .svcr_in = SVCR_ZA, .svcr_expected = SVCR_SM | SVCR_ZA, },
  1098. { .svcr_in = SVCR_SM | SVCR_ZA, .svcr_expected = 0, },
  1099. { .svcr_in = SVCR_SM | SVCR_ZA, .svcr_expected = SVCR_SM, },
  1100. { .svcr_in = SVCR_SM | SVCR_ZA, .svcr_expected = SVCR_ZA, },
  1101. { .svcr_in = SVCR_SM | SVCR_ZA, .svcr_expected = SVCR_SM | SVCR_ZA, },
  1102. };
  1103. static void run_sve_tests(void)
  1104. {
  1105. struct test_config test_config;
  1106. int i, j;
  1107. if (!sve_supported())
  1108. return;
  1109. test_config.sme_vl_in = sme_vls[0];
  1110. test_config.sme_vl_expected = sme_vls[0];
  1111. test_config.svcr_in = 0;
  1112. test_config.svcr_expected = 0;
  1113. for (i = 0; i < sve_vl_count; i++) {
  1114. test_config.sve_vl_in = sve_vls[i];
  1115. for (j = 0; j < sve_vl_count; j++) {
  1116. test_config.sve_vl_expected = sve_vls[j];
  1117. run_tests(base_test_defs,
  1118. ARRAY_SIZE(base_test_defs),
  1119. &test_config);
  1120. if (sve_supported())
  1121. run_tests(sve_test_defs,
  1122. ARRAY_SIZE(sve_test_defs),
  1123. &test_config);
  1124. }
  1125. }
  1126. }
  1127. static void run_sme_tests(void)
  1128. {
  1129. struct test_config test_config;
  1130. int i, j, k;
  1131. if (!sme_supported())
  1132. return;
  1133. test_config.sve_vl_in = sve_vls[0];
  1134. test_config.sve_vl_expected = sve_vls[0];
  1135. /*
  1136. * Every SME VL/SVCR combination
  1137. */
  1138. for (i = 0; i < sme_vl_count; i++) {
  1139. test_config.sme_vl_in = sme_vls[i];
  1140. for (j = 0; j < sme_vl_count; j++) {
  1141. test_config.sme_vl_expected = sme_vls[j];
  1142. for (k = 0; k < ARRAY_SIZE(svcr_combinations); k++) {
  1143. test_config.svcr_in = svcr_combinations[k].svcr_in;
  1144. test_config.svcr_expected = svcr_combinations[k].svcr_expected;
  1145. run_tests(base_test_defs,
  1146. ARRAY_SIZE(base_test_defs),
  1147. &test_config);
  1148. run_tests(sve_test_defs,
  1149. ARRAY_SIZE(sve_test_defs),
  1150. &test_config);
  1151. run_tests(za_test_defs,
  1152. ARRAY_SIZE(za_test_defs),
  1153. &test_config);
  1154. if (sme2_supported())
  1155. run_tests(zt_test_defs,
  1156. ARRAY_SIZE(zt_test_defs),
  1157. &test_config);
  1158. }
  1159. }
  1160. }
  1161. }
  1162. int main(void)
  1163. {
  1164. struct test_config test_config;
  1165. struct sigaction sa;
  1166. int tests, ret, tmp;
  1167. srandom(getpid());
  1168. ksft_print_header();
  1169. if (sve_supported()) {
  1170. probe_vls("SVE", sve_vls, &sve_vl_count, PR_SVE_SET_VL);
  1171. tests = ARRAY_SIZE(base_test_defs) +
  1172. ARRAY_SIZE(sve_test_defs);
  1173. tests *= sve_vl_count * sve_vl_count;
  1174. } else {
  1175. /* Only run the FPSIMD tests */
  1176. sve_vl_count = 1;
  1177. tests = ARRAY_SIZE(base_test_defs);
  1178. }
  1179. if (sme_supported()) {
  1180. probe_vls("SME", sme_vls, &sme_vl_count, PR_SME_SET_VL);
  1181. tmp = ARRAY_SIZE(base_test_defs) + ARRAY_SIZE(sve_test_defs)
  1182. + ARRAY_SIZE(za_test_defs);
  1183. if (sme2_supported())
  1184. tmp += ARRAY_SIZE(zt_test_defs);
  1185. tmp *= sme_vl_count * sme_vl_count;
  1186. tmp *= ARRAY_SIZE(svcr_combinations);
  1187. tests += tmp;
  1188. } else {
  1189. sme_vl_count = 1;
  1190. }
  1191. if (sme2_supported())
  1192. ksft_print_msg("SME2 supported\n");
  1193. if (fa64_supported())
  1194. ksft_print_msg("FA64 supported\n");
  1195. ksft_set_plan(tests);
  1196. /* Get signal handers ready before we start any children */
  1197. memset(&sa, 0, sizeof(sa));
  1198. sa.sa_sigaction = handle_alarm;
  1199. sa.sa_flags = SA_RESTART | SA_SIGINFO;
  1200. sigemptyset(&sa.sa_mask);
  1201. ret = sigaction(SIGALRM, &sa, NULL);
  1202. if (ret < 0)
  1203. ksft_print_msg("Failed to install SIGALRM handler: %s (%d)\n",
  1204. strerror(errno), errno);
  1205. /*
  1206. * Run the test set if there is no SVE or SME, with those we
  1207. * have to pick a VL for each run.
  1208. */
  1209. if (!sve_supported()) {
  1210. test_config.sve_vl_in = 0;
  1211. test_config.sve_vl_expected = 0;
  1212. test_config.sme_vl_in = 0;
  1213. test_config.sme_vl_expected = 0;
  1214. test_config.svcr_in = 0;
  1215. test_config.svcr_expected = 0;
  1216. run_tests(base_test_defs, ARRAY_SIZE(base_test_defs),
  1217. &test_config);
  1218. }
  1219. run_sve_tests();
  1220. run_sme_tests();
  1221. ksft_finished();
  1222. }