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