ptrace-tm-spd-vsx.c 3.3 KB

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