0001
0002
0003
0004
0005
0006
0007 #include "ptrace.h"
0008 #include "tm.h"
0009 #include "ptrace-vsx.h"
0010
0011 int shm_id;
0012 unsigned long *cptr, *pptr;
0013
0014 unsigned long fp_load[VEC_MAX];
0015 unsigned long fp_store[VEC_MAX];
0016 unsigned long fp_load_ckpt[VEC_MAX];
0017 unsigned long fp_load_ckpt_new[VEC_MAX];
0018
0019 __attribute__((used)) void load_vsx(void)
0020 {
0021 loadvsx(fp_load, 0);
0022 }
0023
0024 __attribute__((used)) void load_vsx_ckpt(void)
0025 {
0026 loadvsx(fp_load_ckpt, 0);
0027 }
0028
0029 void tm_vsx(void)
0030 {
0031 unsigned long result, texasr;
0032 int ret;
0033
0034 cptr = (unsigned long *)shmat(shm_id, NULL, 0);
0035
0036 trans:
0037 cptr[1] = 0;
0038 asm __volatile__(
0039 "bl load_vsx_ckpt;"
0040
0041 "1: ;"
0042 "tbegin.;"
0043 "beq 2f;"
0044
0045 "bl load_vsx;"
0046 "tsuspend.;"
0047 "li 7, 1;"
0048 "stw 7, 0(%[cptr1]);"
0049 "tresume.;"
0050 "b .;"
0051
0052 "tend.;"
0053 "li 0, 0;"
0054 "ori %[res], 0, 0;"
0055 "b 3f;"
0056
0057 "2: ;"
0058 "li 0, 1;"
0059 "ori %[res], 0, 0;"
0060 "mfspr %[texasr], %[sprn_texasr];"
0061
0062 "3: ;"
0063 : [res] "=r" (result), [texasr] "=r" (texasr)
0064 : [sprn_texasr] "i" (SPRN_TEXASR), [cptr1] "b" (&cptr[1])
0065 : "memory", "r0", "r3", "r4",
0066 "r7", "r8", "r9", "r10", "r11", "lr"
0067 );
0068
0069 if (result) {
0070 if (!cptr[0])
0071 goto trans;
0072
0073 shmdt((void *)cptr);
0074 storevsx(fp_store, 0);
0075 ret = compare_vsx_vmx(fp_store, fp_load_ckpt_new);
0076 if (ret)
0077 exit(1);
0078 exit(0);
0079 }
0080 shmdt((void *)cptr);
0081 exit(1);
0082 }
0083
0084 int trace_tm_vsx(pid_t child)
0085 {
0086 unsigned long vsx[VSX_MAX];
0087 unsigned long vmx[VMX_MAX + 2][2];
0088
0089 FAIL_IF(start_trace(child));
0090 FAIL_IF(show_vsx(child, vsx));
0091 FAIL_IF(validate_vsx(vsx, fp_load));
0092 FAIL_IF(show_vmx(child, vmx));
0093 FAIL_IF(validate_vmx(vmx, fp_load));
0094 FAIL_IF(show_vsx_ckpt(child, vsx));
0095 FAIL_IF(validate_vsx(vsx, fp_load_ckpt));
0096 FAIL_IF(show_vmx_ckpt(child, vmx));
0097 FAIL_IF(validate_vmx(vmx, fp_load_ckpt));
0098 memset(vsx, 0, sizeof(vsx));
0099 memset(vmx, 0, sizeof(vmx));
0100
0101 load_vsx_vmx(fp_load_ckpt_new, vsx, vmx);
0102
0103 FAIL_IF(write_vsx_ckpt(child, vsx));
0104 FAIL_IF(write_vmx_ckpt(child, vmx));
0105 pptr[0] = 1;
0106 FAIL_IF(stop_trace(child));
0107 return TEST_PASS;
0108 }
0109
0110 int ptrace_tm_vsx(void)
0111 {
0112 pid_t pid;
0113 int ret, status, i;
0114
0115 SKIP_IF(!have_htm());
0116 SKIP_IF(htm_is_synthetic());
0117 shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
0118
0119 for (i = 0; i < 128; i++) {
0120 fp_load[i] = 1 + rand();
0121 fp_load_ckpt[i] = 1 + 2 * rand();
0122 fp_load_ckpt_new[i] = 1 + 3 * rand();
0123 }
0124
0125 pid = fork();
0126 if (pid < 0) {
0127 perror("fork() failed");
0128 return TEST_FAIL;
0129 }
0130
0131 if (pid == 0)
0132 tm_vsx();
0133
0134 if (pid) {
0135 pptr = (unsigned long *)shmat(shm_id, NULL, 0);
0136 while (!pptr[1])
0137 asm volatile("" : : : "memory");
0138
0139 ret = trace_tm_vsx(pid);
0140 if (ret) {
0141 kill(pid, SIGKILL);
0142 shmdt((void *)pptr);
0143 shmctl(shm_id, IPC_RMID, NULL);
0144 return TEST_FAIL;
0145 }
0146
0147 shmdt((void *)pptr);
0148 ret = wait(&status);
0149 shmctl(shm_id, IPC_RMID, NULL);
0150 if (ret != pid) {
0151 printf("Child's exit status not captured\n");
0152 return TEST_FAIL;
0153 }
0154
0155 return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
0156 TEST_PASS;
0157 }
0158 return TEST_PASS;
0159 }
0160
0161 int main(int argc, char *argv[])
0162 {
0163 return test_harness(ptrace_tm_vsx, "ptrace_tm_vsx");
0164 }