ptrace-tar.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Ptrace test for TAR, PPR, DSCR registers
  4. *
  5. * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
  6. */
  7. #include "ptrace.h"
  8. #include "ptrace-tar.h"
  9. /* Tracer and Tracee Shared Data */
  10. int shm_id;
  11. int *cptr;
  12. int *pptr;
  13. void tar(void)
  14. {
  15. unsigned long reg[3];
  16. int ret;
  17. cptr = (int *)shmat(shm_id, NULL, 0);
  18. printf("%-30s TAR: %u PPR: %lx DSCR: %u\n",
  19. user_write, TAR_1, PPR_1, DSCR_1);
  20. mtspr(SPRN_TAR, TAR_1);
  21. mtspr(SPRN_PPR, PPR_1);
  22. mtspr(SPRN_DSCR, DSCR_1);
  23. cptr[2] = 1;
  24. /* Wait on parent */
  25. while (!cptr[0])
  26. asm volatile("" : : : "memory");
  27. reg[0] = mfspr(SPRN_TAR);
  28. reg[1] = mfspr(SPRN_PPR);
  29. reg[2] = mfspr(SPRN_DSCR);
  30. printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
  31. user_read, reg[0], reg[1], reg[2]);
  32. /* Unblock the parent now */
  33. cptr[1] = 1;
  34. shmdt((int *)cptr);
  35. ret = validate_tar_registers(reg, TAR_2, PPR_2, DSCR_2);
  36. if (ret)
  37. exit(1);
  38. exit(0);
  39. }
  40. int trace_tar(pid_t child)
  41. {
  42. unsigned long reg[3];
  43. FAIL_IF(start_trace(child));
  44. FAIL_IF(show_tar_registers(child, reg));
  45. printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
  46. ptrace_read_running, reg[0], reg[1], reg[2]);
  47. FAIL_IF(validate_tar_registers(reg, TAR_1, PPR_1, DSCR_1));
  48. FAIL_IF(stop_trace(child));
  49. return TEST_PASS;
  50. }
  51. int trace_tar_write(pid_t child)
  52. {
  53. FAIL_IF(start_trace(child));
  54. FAIL_IF(write_tar_registers(child, TAR_2, PPR_2, DSCR_2));
  55. printf("%-30s TAR: %u PPR: %lx DSCR: %u\n",
  56. ptrace_write_running, TAR_2, PPR_2, DSCR_2);
  57. FAIL_IF(stop_trace(child));
  58. return TEST_PASS;
  59. }
  60. int ptrace_tar(void)
  61. {
  62. pid_t pid;
  63. int ret, status;
  64. // TAR was added in v2.07
  65. SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07));
  66. shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT);
  67. pid = fork();
  68. if (pid < 0) {
  69. perror("fork() failed");
  70. return TEST_FAIL;
  71. }
  72. if (pid == 0)
  73. tar();
  74. if (pid) {
  75. pptr = (int *)shmat(shm_id, NULL, 0);
  76. pptr[0] = 0;
  77. pptr[1] = 0;
  78. while (!pptr[2])
  79. asm volatile("" : : : "memory");
  80. ret = trace_tar(pid);
  81. if (ret)
  82. return ret;
  83. ret = trace_tar_write(pid);
  84. if (ret)
  85. return ret;
  86. /* Unblock the child now */
  87. pptr[0] = 1;
  88. /* Wait on child */
  89. while (!pptr[1])
  90. asm volatile("" : : : "memory");
  91. shmdt((int *)pptr);
  92. ret = wait(&status);
  93. shmctl(shm_id, IPC_RMID, NULL);
  94. if (ret != pid) {
  95. printf("Child's exit status not captured\n");
  96. return TEST_PASS;
  97. }
  98. return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
  99. TEST_PASS;
  100. }
  101. return TEST_PASS;
  102. }
  103. int main(int argc, char *argv[])
  104. {
  105. return test_harness(ptrace_tar, "ptrace_tar");
  106. }