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