ptrace-tm-vsx.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Ptrace test for VMX/VSX registers in the TM context
  4. *
  5. * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
  6. */
  7. #include "ptrace.h"
  8. #include "tm.h"
  9. #include "ptrace-vsx.h"
  10. int shm_id;
  11. unsigned long *cptr, *pptr;
  12. unsigned long fp_load[VEC_MAX];
  13. unsigned long fp_store[VEC_MAX];
  14. unsigned long fp_load_ckpt[VEC_MAX];
  15. unsigned long fp_load_ckpt_new[VEC_MAX];
  16. __attribute__((used)) void load_vsx(void)
  17. {
  18. loadvsx(fp_load, 0);
  19. }
  20. __attribute__((used)) void load_vsx_ckpt(void)
  21. {
  22. loadvsx(fp_load_ckpt, 0);
  23. }
  24. void tm_vsx(void)
  25. {
  26. unsigned long result, texasr;
  27. int ret;
  28. cptr = (unsigned long *)shmat(shm_id, NULL, 0);
  29. trans:
  30. cptr[1] = 0;
  31. asm __volatile__(
  32. "bl load_vsx_ckpt;"
  33. "1: ;"
  34. "tbegin.;"
  35. "beq 2f;"
  36. "bl load_vsx;"
  37. "tsuspend.;"
  38. "li 7, 1;"
  39. "stw 7, 0(%[cptr1]);"
  40. "tresume.;"
  41. "b .;"
  42. "tend.;"
  43. "li 0, 0;"
  44. "ori %[res], 0, 0;"
  45. "b 3f;"
  46. "2: ;"
  47. "li 0, 1;"
  48. "ori %[res], 0, 0;"
  49. "mfspr %[texasr], %[sprn_texasr];"
  50. "3: ;"
  51. : [res] "=r" (result), [texasr] "=r" (texasr)
  52. : [sprn_texasr] "i" (SPRN_TEXASR), [cptr1] "b" (&cptr[1])
  53. : "memory", "r0", "r3", "r4",
  54. "r7", "r8", "r9", "r10", "r11", "lr"
  55. );
  56. if (result) {
  57. if (!cptr[0])
  58. goto trans;
  59. shmdt((void *)cptr);
  60. storevsx(fp_store, 0);
  61. ret = compare_vsx_vmx(fp_store, fp_load_ckpt_new);
  62. if (ret)
  63. exit(1);
  64. exit(0);
  65. }
  66. shmdt((void *)cptr);
  67. exit(1);
  68. }
  69. int trace_tm_vsx(pid_t child)
  70. {
  71. unsigned long vsx[VSX_MAX];
  72. unsigned long vmx[VMX_MAX + 2][2];
  73. FAIL_IF(start_trace(child));
  74. FAIL_IF(show_vsx(child, vsx));
  75. FAIL_IF(validate_vsx(vsx, fp_load));
  76. FAIL_IF(show_vmx(child, vmx));
  77. FAIL_IF(validate_vmx(vmx, fp_load));
  78. FAIL_IF(show_vsx_ckpt(child, vsx));
  79. FAIL_IF(validate_vsx(vsx, fp_load_ckpt));
  80. FAIL_IF(show_vmx_ckpt(child, vmx));
  81. FAIL_IF(validate_vmx(vmx, fp_load_ckpt));
  82. memset(vsx, 0, sizeof(vsx));
  83. memset(vmx, 0, sizeof(vmx));
  84. load_vsx_vmx(fp_load_ckpt_new, vsx, vmx);
  85. FAIL_IF(write_vsx_ckpt(child, vsx));
  86. FAIL_IF(write_vmx_ckpt(child, vmx));
  87. pptr[0] = 1;
  88. FAIL_IF(stop_trace(child));
  89. return TEST_PASS;
  90. }
  91. int ptrace_tm_vsx(void)
  92. {
  93. pid_t pid;
  94. int ret, status, i;
  95. SKIP_IF(!have_htm());
  96. SKIP_IF(htm_is_synthetic());
  97. shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
  98. for (i = 0; i < 128; i++) {
  99. fp_load[i] = 1 + rand();
  100. fp_load_ckpt[i] = 1 + 2 * rand();
  101. fp_load_ckpt_new[i] = 1 + 3 * rand();
  102. }
  103. pid = fork();
  104. if (pid < 0) {
  105. perror("fork() failed");
  106. return TEST_FAIL;
  107. }
  108. if (pid == 0)
  109. tm_vsx();
  110. if (pid) {
  111. pptr = (unsigned long *)shmat(shm_id, NULL, 0);
  112. while (!pptr[1])
  113. asm volatile("" : : : "memory");
  114. ret = trace_tm_vsx(pid);
  115. if (ret) {
  116. kill(pid, SIGKILL);
  117. shmdt((void *)pptr);
  118. shmctl(shm_id, IPC_RMID, NULL);
  119. return TEST_FAIL;
  120. }
  121. shmdt((void *)pptr);
  122. ret = wait(&status);
  123. shmctl(shm_id, IPC_RMID, NULL);
  124. if (ret != pid) {
  125. printf("Child's exit status not captured\n");
  126. return TEST_FAIL;
  127. }
  128. return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
  129. TEST_PASS;
  130. }
  131. return TEST_PASS;
  132. }
  133. int main(int argc, char *argv[])
  134. {
  135. return test_harness(ptrace_tm_vsx, "ptrace_tm_vsx");
  136. }