Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Ptrace test for GPR/FPR registers in TM context
0004  *
0005  * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
0006  */
0007 #include "ptrace.h"
0008 #include "ptrace-gpr.h"
0009 #include "tm.h"
0010 
0011 /* Tracer and Tracee Shared Data */
0012 int shm_id;
0013 unsigned long *cptr, *pptr;
0014 
0015 double a = FPR_1;
0016 double b = FPR_2;
0017 double c = FPR_3;
0018 
0019 void tm_gpr(void)
0020 {
0021     unsigned long gpr_buf[18];
0022     unsigned long result, texasr;
0023     double fpr_buf[32];
0024 
0025     printf("Starting the child\n");
0026     cptr = (unsigned long *)shmat(shm_id, NULL, 0);
0027 
0028 trans:
0029     cptr[1] = 0;
0030     asm __volatile__(
0031         ASM_LOAD_GPR_IMMED(gpr_1)
0032         ASM_LOAD_FPR(flt_1)
0033         "1: ;"
0034         "tbegin.;"
0035         "beq 2f;"
0036         ASM_LOAD_GPR_IMMED(gpr_2)
0037         ASM_LOAD_FPR(flt_2)
0038         "tsuspend.;"
0039         "li 7, 1;"
0040         "stw 7, 0(%[cptr1]);"
0041         "tresume.;"
0042         "b .;"
0043 
0044         "tend.;"
0045         "li 0, 0;"
0046         "ori %[res], 0, 0;"
0047         "b 3f;"
0048 
0049         /* Transaction abort handler */
0050         "2: ;"
0051         "li 0, 1;"
0052         "ori %[res], 0, 0;"
0053         "mfspr %[texasr], %[sprn_texasr];"
0054 
0055         "3: ;"
0056         : [res] "=r" (result), [texasr] "=r" (texasr)
0057         : [gpr_1]"i"(GPR_1), [gpr_2]"i"(GPR_2),
0058         [sprn_texasr] "i" (SPRN_TEXASR), [flt_1] "b" (&a),
0059         [flt_2] "b" (&b), [cptr1] "b" (&cptr[1])
0060         : "memory", "r0", "r7", "r8", "r9", "r10",
0061         "r11", "r12", "r13", "r14", "r15", "r16",
0062         "r17", "r18", "r19", "r20", "r21", "r22",
0063         "r23", "r24", "r25", "r26", "r27", "r28",
0064         "r29", "r30", "r31"
0065         );
0066 
0067     if (result) {
0068         if (!cptr[0])
0069             goto trans;
0070 
0071         shmdt((void *)cptr);
0072         store_gpr(gpr_buf);
0073         store_fpr(fpr_buf);
0074 
0075         if (validate_gpr(gpr_buf, GPR_3))
0076             exit(1);
0077 
0078         if (validate_fpr_double(fpr_buf, c))
0079             exit(1);
0080 
0081         exit(0);
0082     }
0083     shmdt((void *)cptr);
0084     exit(1);
0085 }
0086 
0087 int trace_tm_gpr(pid_t child)
0088 {
0089     unsigned long gpr[18];
0090     __u64 fpr[32];
0091 
0092     FAIL_IF(start_trace(child));
0093     FAIL_IF(show_gpr(child, gpr));
0094     FAIL_IF(validate_gpr(gpr, GPR_2));
0095     FAIL_IF(show_fpr(child, fpr));
0096     FAIL_IF(validate_fpr(fpr, FPR_2_REP));
0097     FAIL_IF(show_ckpt_fpr(child, fpr));
0098     FAIL_IF(validate_fpr(fpr, FPR_1_REP));
0099     FAIL_IF(show_ckpt_gpr(child, gpr));
0100     FAIL_IF(validate_gpr(gpr, GPR_1));
0101     FAIL_IF(write_ckpt_gpr(child, GPR_3));
0102     FAIL_IF(write_ckpt_fpr(child, FPR_3_REP));
0103 
0104     pptr[0] = 1;
0105     FAIL_IF(stop_trace(child));
0106 
0107     return TEST_PASS;
0108 }
0109 
0110 int ptrace_tm_gpr(void)
0111 {
0112     pid_t pid;
0113     int ret, status;
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     pid = fork();
0119     if (pid < 0) {
0120         perror("fork() failed");
0121         return TEST_FAIL;
0122     }
0123     if (pid == 0)
0124         tm_gpr();
0125 
0126     if (pid) {
0127         pptr = (unsigned long *)shmat(shm_id, NULL, 0);
0128 
0129         while (!pptr[1])
0130             asm volatile("" : : : "memory");
0131         ret = trace_tm_gpr(pid);
0132         if (ret) {
0133             kill(pid, SIGTERM);
0134             return TEST_FAIL;
0135         }
0136 
0137         shmdt((void *)pptr);
0138 
0139         ret = wait(&status);
0140         shmctl(shm_id, IPC_RMID, NULL);
0141         if (ret != pid) {
0142             printf("Child's exit status not captured\n");
0143             return TEST_FAIL;
0144         }
0145 
0146         return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
0147             TEST_PASS;
0148     }
0149     return TEST_PASS;
0150 }
0151 
0152 int main(int argc, char *argv[])
0153 {
0154     return test_harness(ptrace_tm_gpr, "ptrace_tm_gpr");
0155 }