167 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Ptrace test for GPR/FPR registers in TM Suspend context4 *5 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.6 */7#include "ptrace.h"8#include "ptrace-gpr.h"9#include "tm.h"10 11/* Tracer and Tracee Shared Data */12int shm_id;13int *cptr, *pptr;14 15double a = FPR_1;16double b = FPR_2;17double c = FPR_3;18double d = FPR_4;19 20__attribute__((used)) void wait_parent(void)21{22 cptr[2] = 1;23 while (!cptr[1])24 asm volatile("" : : : "memory");25}26 27void tm_spd_gpr(void)28{29 unsigned long gpr_buf[18];30 unsigned long result, texasr;31 double fpr_buf[32];32 33 cptr = (int *)shmat(shm_id, NULL, 0);34 35trans:36 cptr[2] = 0;37 asm __volatile__(38 ASM_LOAD_GPR_IMMED(gpr_1)39 ASM_LOAD_FPR(flt_1)40 41 "1: ;"42 "tbegin.;"43 "beq 2f;"44 45 ASM_LOAD_GPR_IMMED(gpr_2)46 "tsuspend.;"47 ASM_LOAD_GPR_IMMED(gpr_4)48 ASM_LOAD_FPR(flt_4)49 50 "bl wait_parent;"51 "tresume.;"52 "tend.;"53 "li 0, 0;"54 "ori %[res], 0, 0;"55 "b 3f;"56 57 /* Transaction abort handler */58 "2: ;"59 "li 0, 1;"60 "ori %[res], 0, 0;"61 "mfspr %[texasr], %[sprn_texasr];"62 63 "3: ;"64 : [res] "=r" (result), [texasr] "=r" (texasr)65 : [gpr_1]"i"(GPR_1), [gpr_2]"i"(GPR_2), [gpr_4]"i"(GPR_4),66 [sprn_texasr] "i" (SPRN_TEXASR), [flt_1] "b" (&a),67 [flt_4] "b" (&d)68 : "memory", "r0", "r5", "r6", "r7",69 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",70 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",71 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"72 );73 74 if (result) {75 if (!cptr[0])76 goto trans;77 78 shmdt((void *)cptr);79 store_gpr(gpr_buf);80 store_fpr(fpr_buf);81 82 if (validate_gpr(gpr_buf, GPR_3))83 exit(1);84 85 if (validate_fpr_double(fpr_buf, c))86 exit(1);87 exit(0);88 }89 shmdt((void *)cptr);90 exit(1);91}92 93int trace_tm_spd_gpr(pid_t child)94{95 unsigned long gpr[18];96 __u64 fpr[32];97 98 FAIL_IF(start_trace(child));99 FAIL_IF(show_gpr(child, gpr));100 FAIL_IF(validate_gpr(gpr, GPR_4));101 FAIL_IF(show_fpr(child, fpr));102 FAIL_IF(validate_fpr(fpr, FPR_4_REP));103 FAIL_IF(show_ckpt_fpr(child, fpr));104 FAIL_IF(validate_fpr(fpr, FPR_1_REP));105 FAIL_IF(show_ckpt_gpr(child, gpr));106 FAIL_IF(validate_gpr(gpr, GPR_1));107 FAIL_IF(write_ckpt_gpr(child, GPR_3));108 FAIL_IF(write_ckpt_fpr(child, FPR_3_REP));109 110 pptr[0] = 1;111 pptr[1] = 1;112 FAIL_IF(stop_trace(child));113 return TEST_PASS;114}115 116int ptrace_tm_spd_gpr(void)117{118 pid_t pid;119 int ret, status;120 121 SKIP_IF_MSG(!have_htm(), "Don't have transactional memory");122 SKIP_IF_MSG(htm_is_synthetic(), "Transactional memory is synthetic");123 shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT);124 pid = fork();125 if (pid < 0) {126 perror("fork() failed");127 return TEST_FAIL;128 }129 130 if (pid == 0)131 tm_spd_gpr();132 133 if (pid) {134 pptr = (int *)shmat(shm_id, NULL, 0);135 pptr[0] = 0;136 pptr[1] = 0;137 138 while (!pptr[2])139 asm volatile("" : : : "memory");140 ret = trace_tm_spd_gpr(pid);141 if (ret) {142 kill(pid, SIGTERM);143 shmdt((void *)pptr);144 shmctl(shm_id, IPC_RMID, NULL);145 return TEST_FAIL;146 }147 148 shmdt((void *)pptr);149 150 ret = wait(&status);151 shmctl(shm_id, IPC_RMID, NULL);152 if (ret != pid) {153 printf("Child's exit status not captured\n");154 return TEST_FAIL;155 }156 157 return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :158 TEST_PASS;159 }160 return TEST_PASS;161}162 163int main(int argc, char *argv[])164{165 return test_harness(ptrace_tm_spd_gpr, "ptrace_tm_spd_gpr");166}167