0001
0002
0003
0004
0005
0006
0007 #include "ptrace.h"
0008 #include "tm.h"
0009 #include "ptrace-tar.h"
0010
0011 int shm_id;
0012 unsigned long *cptr, *pptr;
0013
0014
0015 void tm_tar(void)
0016 {
0017 unsigned long result, texasr;
0018 unsigned long regs[3];
0019 int ret;
0020
0021 cptr = (unsigned long *)shmat(shm_id, NULL, 0);
0022
0023 trans:
0024 cptr[1] = 0;
0025 asm __volatile__(
0026 "li 4, %[tar_1];"
0027 "mtspr %[sprn_tar], 4;"
0028 "li 4, %[dscr_1];"
0029 "mtspr %[sprn_dscr], 4;"
0030 "or 31,31,31;"
0031
0032 "1: ;"
0033 "tbegin.;"
0034 "beq 2f;"
0035
0036 "li 4, %[tar_2];"
0037 "mtspr %[sprn_tar], 4;"
0038 "li 4, %[dscr_2];"
0039 "mtspr %[sprn_dscr], 4;"
0040 "or 1,1,1;"
0041 "tsuspend.;"
0042 "li 0, 1;"
0043 "stw 0, 0(%[cptr1]);"
0044 "tresume.;"
0045 "b .;"
0046
0047 "tend.;"
0048 "li 0, 0;"
0049 "ori %[res], 0, 0;"
0050 "b 3f;"
0051
0052
0053 "2: ;"
0054 "li 0, 1;"
0055 "ori %[res], 0, 0;"
0056 "mfspr %[texasr], %[sprn_texasr];"
0057
0058 "3: ;"
0059
0060 : [res] "=r" (result), [texasr] "=r" (texasr)
0061 : [sprn_dscr]"i"(SPRN_DSCR), [sprn_tar]"i"(SPRN_TAR),
0062 [sprn_ppr]"i"(SPRN_PPR), [sprn_texasr]"i"(SPRN_TEXASR),
0063 [tar_1]"i"(TAR_1), [dscr_1]"i"(DSCR_1), [tar_2]"i"(TAR_2),
0064 [dscr_2]"i"(DSCR_2), [cptr1] "b" (&cptr[1])
0065 : "memory", "r0", "r3", "r4", "r5", "r6"
0066 );
0067
0068
0069 if (result) {
0070 if (!cptr[0])
0071 goto trans;
0072
0073 regs[0] = mfspr(SPRN_TAR);
0074 regs[1] = mfspr(SPRN_PPR);
0075 regs[2] = mfspr(SPRN_DSCR);
0076
0077 shmdt(&cptr);
0078 printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
0079 user_read, regs[0], regs[1], regs[2]);
0080
0081 ret = validate_tar_registers(regs, TAR_4, PPR_4, DSCR_4);
0082 if (ret)
0083 exit(1);
0084 exit(0);
0085 }
0086 shmdt(&cptr);
0087 exit(1);
0088 }
0089
0090 int trace_tm_tar(pid_t child)
0091 {
0092 unsigned long regs[3];
0093
0094 FAIL_IF(start_trace(child));
0095 FAIL_IF(show_tar_registers(child, regs));
0096 printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
0097 ptrace_read_running, regs[0], regs[1], regs[2]);
0098
0099 FAIL_IF(validate_tar_registers(regs, TAR_2, PPR_2, DSCR_2));
0100 FAIL_IF(show_tm_checkpointed_state(child, regs));
0101 printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
0102 ptrace_read_ckpt, regs[0], regs[1], regs[2]);
0103
0104 FAIL_IF(validate_tar_registers(regs, TAR_1, PPR_1, DSCR_1));
0105 FAIL_IF(write_ckpt_tar_registers(child, TAR_4, PPR_4, DSCR_4));
0106 printf("%-30s TAR: %u PPR: %lx DSCR: %u\n",
0107 ptrace_write_ckpt, TAR_4, PPR_4, DSCR_4);
0108
0109 pptr[0] = 1;
0110 FAIL_IF(stop_trace(child));
0111 return TEST_PASS;
0112 }
0113
0114 int ptrace_tm_tar(void)
0115 {
0116 pid_t pid;
0117 int ret, status;
0118
0119 SKIP_IF(!have_htm());
0120 SKIP_IF(htm_is_synthetic());
0121 shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
0122 pid = fork();
0123 if (pid == 0)
0124 tm_tar();
0125
0126 pptr = (unsigned long *)shmat(shm_id, NULL, 0);
0127 pptr[0] = 0;
0128
0129 if (pid) {
0130 while (!pptr[1])
0131 asm volatile("" : : : "memory");
0132 ret = trace_tm_tar(pid);
0133 if (ret) {
0134 kill(pid, SIGTERM);
0135 shmdt(&pptr);
0136 shmctl(shm_id, IPC_RMID, NULL);
0137 return TEST_FAIL;
0138 }
0139 shmdt(&pptr);
0140
0141 ret = wait(&status);
0142 shmctl(shm_id, IPC_RMID, NULL);
0143 if (ret != pid) {
0144 printf("Child's exit status not captured\n");
0145 return TEST_FAIL;
0146 }
0147
0148 return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
0149 TEST_PASS;
0150 }
0151 return TEST_PASS;
0152 }
0153
0154 int main(int argc, char *argv[])
0155 {
0156 return test_harness(ptrace_tm_tar, "ptrace_tm_tar");
0157 }