ptrace.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * Ptrace interface test helper functions
  4. *
  5. * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
  6. */
  7. #define __SANE_USERSPACE_TYPES__
  8. #include <inttypes.h>
  9. #include <unistd.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <malloc.h>
  13. #include <errno.h>
  14. #include <time.h>
  15. #include <sys/ptrace.h>
  16. #include <sys/ioctl.h>
  17. #include <sys/uio.h>
  18. #include <sys/types.h>
  19. #include <sys/wait.h>
  20. #include <sys/signal.h>
  21. #include <sys/ipc.h>
  22. #include <sys/shm.h>
  23. #include <sys/user.h>
  24. #include <sys/syscall.h>
  25. #include <linux/elf.h>
  26. #include <linux/types.h>
  27. #include <linux/auxvec.h>
  28. #include "reg.h"
  29. #include "utils.h"
  30. #define TEST_PASS 0
  31. #define TEST_FAIL 1
  32. struct fpr_regs {
  33. __u64 fpr[32];
  34. __u64 fpscr;
  35. };
  36. struct tm_spr_regs {
  37. unsigned long tm_tfhar;
  38. unsigned long tm_texasr;
  39. unsigned long tm_tfiar;
  40. };
  41. #ifndef NT_PPC_TAR
  42. #define NT_PPC_TAR 0x103
  43. #define NT_PPC_PPR 0x104
  44. #define NT_PPC_DSCR 0x105
  45. #define NT_PPC_EBB 0x106
  46. #define NT_PPC_PMU 0x107
  47. #define NT_PPC_TM_CGPR 0x108
  48. #define NT_PPC_TM_CFPR 0x109
  49. #define NT_PPC_TM_CVMX 0x10a
  50. #define NT_PPC_TM_CVSX 0x10b
  51. #define NT_PPC_TM_SPR 0x10c
  52. #define NT_PPC_TM_CTAR 0x10d
  53. #define NT_PPC_TM_CPPR 0x10e
  54. #define NT_PPC_TM_CDSCR 0x10f
  55. #endif
  56. /* Basic ptrace operations */
  57. int start_trace(pid_t child)
  58. {
  59. int ret;
  60. ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
  61. if (ret) {
  62. perror("ptrace(PTRACE_ATTACH) failed");
  63. return TEST_FAIL;
  64. }
  65. ret = waitpid(child, NULL, 0);
  66. if (ret != child) {
  67. perror("waitpid() failed");
  68. return TEST_FAIL;
  69. }
  70. return TEST_PASS;
  71. }
  72. int stop_trace(pid_t child)
  73. {
  74. int ret;
  75. ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
  76. if (ret) {
  77. perror("ptrace(PTRACE_DETACH) failed");
  78. return TEST_FAIL;
  79. }
  80. return TEST_PASS;
  81. }
  82. int cont_trace(pid_t child)
  83. {
  84. int ret;
  85. ret = ptrace(PTRACE_CONT, child, NULL, NULL);
  86. if (ret) {
  87. perror("ptrace(PTRACE_CONT) failed");
  88. return TEST_FAIL;
  89. }
  90. return TEST_PASS;
  91. }
  92. int ptrace_read_regs(pid_t child, unsigned long type, unsigned long regs[],
  93. int n)
  94. {
  95. struct iovec iov;
  96. long ret;
  97. FAIL_IF(start_trace(child));
  98. iov.iov_base = regs;
  99. iov.iov_len = n * sizeof(unsigned long);
  100. ret = ptrace(PTRACE_GETREGSET, child, type, &iov);
  101. if (ret)
  102. return ret;
  103. FAIL_IF(stop_trace(child));
  104. return TEST_PASS;
  105. }
  106. long ptrace_write_regs(pid_t child, unsigned long type, unsigned long regs[],
  107. int n)
  108. {
  109. struct iovec iov;
  110. long ret;
  111. FAIL_IF(start_trace(child));
  112. iov.iov_base = regs;
  113. iov.iov_len = n * sizeof(unsigned long);
  114. ret = ptrace(PTRACE_SETREGSET, child, type, &iov);
  115. FAIL_IF(stop_trace(child));
  116. return ret;
  117. }
  118. /* TAR, PPR, DSCR */
  119. int show_tar_registers(pid_t child, unsigned long *out)
  120. {
  121. struct iovec iov;
  122. unsigned long *reg;
  123. int ret;
  124. reg = malloc(sizeof(unsigned long));
  125. if (!reg) {
  126. perror("malloc() failed");
  127. return TEST_FAIL;
  128. }
  129. iov.iov_base = (u64 *) reg;
  130. iov.iov_len = sizeof(unsigned long);
  131. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov);
  132. if (ret) {
  133. perror("ptrace(PTRACE_GETREGSET) failed");
  134. goto fail;
  135. }
  136. if (out)
  137. out[0] = *reg;
  138. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov);
  139. if (ret) {
  140. perror("ptrace(PTRACE_GETREGSET) failed");
  141. goto fail;
  142. }
  143. if (out)
  144. out[1] = *reg;
  145. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov);
  146. if (ret) {
  147. perror("ptrace(PTRACE_GETREGSET) failed");
  148. goto fail;
  149. }
  150. if (out)
  151. out[2] = *reg;
  152. free(reg);
  153. return TEST_PASS;
  154. fail:
  155. free(reg);
  156. return TEST_FAIL;
  157. }
  158. int write_tar_registers(pid_t child, unsigned long tar,
  159. unsigned long ppr, unsigned long dscr)
  160. {
  161. struct iovec iov;
  162. unsigned long *reg;
  163. int ret;
  164. reg = malloc(sizeof(unsigned long));
  165. if (!reg) {
  166. perror("malloc() failed");
  167. return TEST_FAIL;
  168. }
  169. iov.iov_base = (u64 *) reg;
  170. iov.iov_len = sizeof(unsigned long);
  171. *reg = tar;
  172. ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov);
  173. if (ret) {
  174. perror("ptrace(PTRACE_SETREGSET) failed");
  175. goto fail;
  176. }
  177. *reg = ppr;
  178. ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov);
  179. if (ret) {
  180. perror("ptrace(PTRACE_SETREGSET) failed");
  181. goto fail;
  182. }
  183. *reg = dscr;
  184. ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov);
  185. if (ret) {
  186. perror("ptrace(PTRACE_SETREGSET) failed");
  187. goto fail;
  188. }
  189. free(reg);
  190. return TEST_PASS;
  191. fail:
  192. free(reg);
  193. return TEST_FAIL;
  194. }
  195. int show_tm_checkpointed_state(pid_t child, unsigned long *out)
  196. {
  197. struct iovec iov;
  198. unsigned long *reg;
  199. int ret;
  200. reg = malloc(sizeof(unsigned long));
  201. if (!reg) {
  202. perror("malloc() failed");
  203. return TEST_FAIL;
  204. }
  205. iov.iov_base = (u64 *) reg;
  206. iov.iov_len = sizeof(unsigned long);
  207. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov);
  208. if (ret) {
  209. perror("ptrace(PTRACE_GETREGSET) failed");
  210. goto fail;
  211. }
  212. if (out)
  213. out[0] = *reg;
  214. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov);
  215. if (ret) {
  216. perror("ptrace(PTRACE_GETREGSET) failed");
  217. goto fail;
  218. }
  219. if (out)
  220. out[1] = *reg;
  221. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov);
  222. if (ret) {
  223. perror("ptrace(PTRACE_GETREGSET) failed");
  224. goto fail;
  225. }
  226. if (out)
  227. out[2] = *reg;
  228. free(reg);
  229. return TEST_PASS;
  230. fail:
  231. free(reg);
  232. return TEST_FAIL;
  233. }
  234. int write_ckpt_tar_registers(pid_t child, unsigned long tar,
  235. unsigned long ppr, unsigned long dscr)
  236. {
  237. struct iovec iov;
  238. unsigned long *reg;
  239. int ret;
  240. reg = malloc(sizeof(unsigned long));
  241. if (!reg) {
  242. perror("malloc() failed");
  243. return TEST_FAIL;
  244. }
  245. iov.iov_base = (u64 *) reg;
  246. iov.iov_len = sizeof(unsigned long);
  247. *reg = tar;
  248. ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov);
  249. if (ret) {
  250. perror("ptrace(PTRACE_GETREGSET) failed");
  251. goto fail;
  252. }
  253. *reg = ppr;
  254. ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov);
  255. if (ret) {
  256. perror("ptrace(PTRACE_GETREGSET) failed");
  257. goto fail;
  258. }
  259. *reg = dscr;
  260. ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov);
  261. if (ret) {
  262. perror("ptrace(PTRACE_GETREGSET) failed");
  263. goto fail;
  264. }
  265. free(reg);
  266. return TEST_PASS;
  267. fail:
  268. free(reg);
  269. return TEST_FAIL;
  270. }
  271. /* FPR */
  272. int show_fpr(pid_t child, __u64 *fpr)
  273. {
  274. struct fpr_regs *regs;
  275. int ret, i;
  276. regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
  277. ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
  278. if (ret) {
  279. perror("ptrace(PTRACE_GETREGSET) failed");
  280. return TEST_FAIL;
  281. }
  282. if (fpr) {
  283. for (i = 0; i < 32; i++)
  284. fpr[i] = regs->fpr[i];
  285. }
  286. return TEST_PASS;
  287. }
  288. int write_fpr(pid_t child, __u64 val)
  289. {
  290. struct fpr_regs *regs;
  291. int ret, i;
  292. regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
  293. ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs);
  294. if (ret) {
  295. perror("ptrace(PTRACE_GETREGSET) failed");
  296. return TEST_FAIL;
  297. }
  298. for (i = 0; i < 32; i++)
  299. regs->fpr[i] = val;
  300. ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs);
  301. if (ret) {
  302. perror("ptrace(PTRACE_GETREGSET) failed");
  303. return TEST_FAIL;
  304. }
  305. return TEST_PASS;
  306. }
  307. int show_ckpt_fpr(pid_t child, __u64 *fpr)
  308. {
  309. struct fpr_regs *regs;
  310. struct iovec iov;
  311. int ret, i;
  312. regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
  313. iov.iov_base = regs;
  314. iov.iov_len = sizeof(struct fpr_regs);
  315. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
  316. if (ret) {
  317. perror("ptrace(PTRACE_GETREGSET) failed");
  318. return TEST_FAIL;
  319. }
  320. if (fpr) {
  321. for (i = 0; i < 32; i++)
  322. fpr[i] = regs->fpr[i];
  323. }
  324. return TEST_PASS;
  325. }
  326. int write_ckpt_fpr(pid_t child, unsigned long val)
  327. {
  328. struct fpr_regs *regs;
  329. struct iovec iov;
  330. int ret, i;
  331. regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs));
  332. iov.iov_base = regs;
  333. iov.iov_len = sizeof(struct fpr_regs);
  334. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov);
  335. if (ret) {
  336. perror("ptrace(PTRACE_GETREGSET) failed");
  337. return TEST_FAIL;
  338. }
  339. for (i = 0; i < 32; i++)
  340. regs->fpr[i] = val;
  341. ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov);
  342. if (ret) {
  343. perror("ptrace(PTRACE_GETREGSET) failed");
  344. return TEST_FAIL;
  345. }
  346. return TEST_PASS;
  347. }
  348. /* GPR */
  349. int show_gpr(pid_t child, unsigned long *gpr)
  350. {
  351. struct pt_regs *regs;
  352. int ret, i;
  353. regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
  354. if (!regs) {
  355. perror("malloc() failed");
  356. return TEST_FAIL;
  357. }
  358. ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
  359. if (ret) {
  360. perror("ptrace(PTRACE_GETREGSET) failed");
  361. return TEST_FAIL;
  362. }
  363. if (gpr) {
  364. for (i = 14; i < 32; i++)
  365. gpr[i-14] = regs->gpr[i];
  366. }
  367. return TEST_PASS;
  368. }
  369. long sys_ptrace(enum __ptrace_request request, pid_t pid, unsigned long addr, unsigned long data)
  370. {
  371. return syscall(__NR_ptrace, request, pid, (void *)addr, data);
  372. }
  373. // 33 because of FPSCR
  374. #define PT_NUM_FPRS (33 * (sizeof(__u64) / sizeof(unsigned long)))
  375. __u64 *peek_fprs(pid_t child)
  376. {
  377. unsigned long *fprs, *p, addr;
  378. long ret;
  379. int i;
  380. fprs = malloc(sizeof(unsigned long) * PT_NUM_FPRS);
  381. if (!fprs) {
  382. perror("malloc() failed");
  383. return NULL;
  384. }
  385. for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) {
  386. addr = sizeof(unsigned long) * (PT_FPR0 + i);
  387. ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)p);
  388. if (ret) {
  389. perror("ptrace(PTRACE_PEEKUSR) failed");
  390. return NULL;
  391. }
  392. }
  393. addr = sizeof(unsigned long) * (PT_FPR0 + i);
  394. ret = sys_ptrace(PTRACE_PEEKUSER, child, addr, (unsigned long)&addr);
  395. if (!ret) {
  396. printf("ptrace(PTRACE_PEEKUSR) succeeded unexpectedly!\n");
  397. return NULL;
  398. }
  399. return (__u64 *)fprs;
  400. }
  401. int poke_fprs(pid_t child, unsigned long *fprs)
  402. {
  403. unsigned long *p, addr;
  404. long ret;
  405. int i;
  406. for (i = 0, p = fprs; i < PT_NUM_FPRS; i++, p++) {
  407. addr = sizeof(unsigned long) * (PT_FPR0 + i);
  408. ret = sys_ptrace(PTRACE_POKEUSER, child, addr, *p);
  409. if (ret) {
  410. perror("ptrace(PTRACE_POKEUSR) failed");
  411. return -1;
  412. }
  413. }
  414. addr = sizeof(unsigned long) * (PT_FPR0 + i);
  415. ret = sys_ptrace(PTRACE_POKEUSER, child, addr, addr);
  416. if (!ret) {
  417. printf("ptrace(PTRACE_POKEUSR) succeeded unexpectedly!\n");
  418. return -1;
  419. }
  420. return 0;
  421. }
  422. int write_gpr(pid_t child, unsigned long val)
  423. {
  424. struct pt_regs *regs;
  425. int i, ret;
  426. regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
  427. if (!regs) {
  428. perror("malloc() failed");
  429. return TEST_FAIL;
  430. }
  431. ret = ptrace(PTRACE_GETREGS, child, NULL, regs);
  432. if (ret) {
  433. perror("ptrace(PTRACE_GETREGSET) failed");
  434. return TEST_FAIL;
  435. }
  436. for (i = 14; i < 32; i++)
  437. regs->gpr[i] = val;
  438. ret = ptrace(PTRACE_SETREGS, child, NULL, regs);
  439. if (ret) {
  440. perror("ptrace(PTRACE_GETREGSET) failed");
  441. return TEST_FAIL;
  442. }
  443. return TEST_PASS;
  444. }
  445. int show_ckpt_gpr(pid_t child, unsigned long *gpr)
  446. {
  447. struct pt_regs *regs;
  448. struct iovec iov;
  449. int ret, i;
  450. regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
  451. if (!regs) {
  452. perror("malloc() failed");
  453. return TEST_FAIL;
  454. }
  455. iov.iov_base = (u64 *) regs;
  456. iov.iov_len = sizeof(struct pt_regs);
  457. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
  458. if (ret) {
  459. perror("ptrace(PTRACE_GETREGSET) failed");
  460. return TEST_FAIL;
  461. }
  462. if (gpr) {
  463. for (i = 14; i < 32; i++)
  464. gpr[i-14] = regs->gpr[i];
  465. }
  466. return TEST_PASS;
  467. }
  468. int write_ckpt_gpr(pid_t child, unsigned long val)
  469. {
  470. struct pt_regs *regs;
  471. struct iovec iov;
  472. int ret, i;
  473. regs = (struct pt_regs *) malloc(sizeof(struct pt_regs));
  474. if (!regs) {
  475. perror("malloc() failed\n");
  476. return TEST_FAIL;
  477. }
  478. iov.iov_base = (u64 *) regs;
  479. iov.iov_len = sizeof(struct pt_regs);
  480. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov);
  481. if (ret) {
  482. perror("ptrace(PTRACE_GETREGSET) failed");
  483. return TEST_FAIL;
  484. }
  485. for (i = 14; i < 32; i++)
  486. regs->gpr[i] = val;
  487. ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov);
  488. if (ret) {
  489. perror("ptrace(PTRACE_GETREGSET) failed");
  490. return TEST_FAIL;
  491. }
  492. return TEST_PASS;
  493. }
  494. /* VMX */
  495. int show_vmx(pid_t child, unsigned long vmx[][2])
  496. {
  497. int ret;
  498. ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx);
  499. if (ret) {
  500. perror("ptrace(PTRACE_GETVRREGS) failed");
  501. return TEST_FAIL;
  502. }
  503. return TEST_PASS;
  504. }
  505. int show_vmx_ckpt(pid_t child, unsigned long vmx[][2])
  506. {
  507. unsigned long regs[34][2];
  508. struct iovec iov;
  509. int ret;
  510. iov.iov_base = (u64 *) regs;
  511. iov.iov_len = sizeof(regs);
  512. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov);
  513. if (ret) {
  514. perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
  515. return TEST_FAIL;
  516. }
  517. memcpy(vmx, regs, sizeof(regs));
  518. return TEST_PASS;
  519. }
  520. int write_vmx(pid_t child, unsigned long vmx[][2])
  521. {
  522. int ret;
  523. ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx);
  524. if (ret) {
  525. perror("ptrace(PTRACE_SETVRREGS) failed");
  526. return TEST_FAIL;
  527. }
  528. return TEST_PASS;
  529. }
  530. int write_vmx_ckpt(pid_t child, unsigned long vmx[][2])
  531. {
  532. unsigned long regs[34][2];
  533. struct iovec iov;
  534. int ret;
  535. memcpy(regs, vmx, sizeof(regs));
  536. iov.iov_base = (u64 *) regs;
  537. iov.iov_len = sizeof(regs);
  538. ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVMX, &iov);
  539. if (ret) {
  540. perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
  541. return TEST_FAIL;
  542. }
  543. return TEST_PASS;
  544. }
  545. /* VSX */
  546. int show_vsx(pid_t child, unsigned long *vsx)
  547. {
  548. int ret;
  549. ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx);
  550. if (ret) {
  551. perror("ptrace(PTRACE_GETVSRREGS) failed");
  552. return TEST_FAIL;
  553. }
  554. return TEST_PASS;
  555. }
  556. int show_vsx_ckpt(pid_t child, unsigned long *vsx)
  557. {
  558. unsigned long regs[32];
  559. struct iovec iov;
  560. int ret;
  561. iov.iov_base = (u64 *) regs;
  562. iov.iov_len = sizeof(regs);
  563. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov);
  564. if (ret) {
  565. perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
  566. return TEST_FAIL;
  567. }
  568. memcpy(vsx, regs, sizeof(regs));
  569. return TEST_PASS;
  570. }
  571. int write_vsx(pid_t child, unsigned long *vsx)
  572. {
  573. int ret;
  574. ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx);
  575. if (ret) {
  576. perror("ptrace(PTRACE_SETVSRREGS) failed");
  577. return TEST_FAIL;
  578. }
  579. return TEST_PASS;
  580. }
  581. int write_vsx_ckpt(pid_t child, unsigned long *vsx)
  582. {
  583. unsigned long regs[32];
  584. struct iovec iov;
  585. int ret;
  586. memcpy(regs, vsx, sizeof(regs));
  587. iov.iov_base = (u64 *) regs;
  588. iov.iov_len = sizeof(regs);
  589. ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVSX, &iov);
  590. if (ret) {
  591. perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
  592. return TEST_FAIL;
  593. }
  594. return TEST_PASS;
  595. }
  596. /* TM SPR */
  597. int show_tm_spr(pid_t child, struct tm_spr_regs *out)
  598. {
  599. struct tm_spr_regs *regs;
  600. struct iovec iov;
  601. int ret;
  602. regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs));
  603. if (!regs) {
  604. perror("malloc() failed");
  605. return TEST_FAIL;
  606. }
  607. iov.iov_base = (u64 *) regs;
  608. iov.iov_len = sizeof(struct tm_spr_regs);
  609. ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov);
  610. if (ret) {
  611. perror("ptrace(PTRACE_GETREGSET) failed");
  612. return TEST_FAIL;
  613. }
  614. if (out)
  615. memcpy(out, regs, sizeof(struct tm_spr_regs));
  616. return TEST_PASS;
  617. }
  618. /* Analyse TEXASR after TM failure */
  619. inline unsigned long get_tfiar(void)
  620. {
  621. unsigned long ret;
  622. asm volatile("mfspr %0,%1" : "=r" (ret) : "i" (SPRN_TFIAR));
  623. return ret;
  624. }
  625. void analyse_texasr(unsigned long texasr)
  626. {
  627. printf("TEXASR: %16lx\t", texasr);
  628. if (texasr & TEXASR_FP)
  629. printf("TEXASR_FP ");
  630. if (texasr & TEXASR_DA)
  631. printf("TEXASR_DA ");
  632. if (texasr & TEXASR_NO)
  633. printf("TEXASR_NO ");
  634. if (texasr & TEXASR_FO)
  635. printf("TEXASR_FO ");
  636. if (texasr & TEXASR_SIC)
  637. printf("TEXASR_SIC ");
  638. if (texasr & TEXASR_NTC)
  639. printf("TEXASR_NTC ");
  640. if (texasr & TEXASR_TC)
  641. printf("TEXASR_TC ");
  642. if (texasr & TEXASR_TIC)
  643. printf("TEXASR_TIC ");
  644. if (texasr & TEXASR_IC)
  645. printf("TEXASR_IC ");
  646. if (texasr & TEXASR_IFC)
  647. printf("TEXASR_IFC ");
  648. if (texasr & TEXASR_ABT)
  649. printf("TEXASR_ABT ");
  650. if (texasr & TEXASR_SPD)
  651. printf("TEXASR_SPD ");
  652. if (texasr & TEXASR_HV)
  653. printf("TEXASR_HV ");
  654. if (texasr & TEXASR_PR)
  655. printf("TEXASR_PR ");
  656. if (texasr & TEXASR_FS)
  657. printf("TEXASR_FS ");
  658. if (texasr & TEXASR_TE)
  659. printf("TEXASR_TE ");
  660. if (texasr & TEXASR_ROT)
  661. printf("TEXASR_ROT ");
  662. printf("TFIAR :%lx\n", get_tfiar());
  663. }
  664. void store_gpr(unsigned long *addr);