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 Suspend 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 int *cptr, *pptr;
0014 
0015 double a = FPR_1;
0016 double b = FPR_2;
0017 double c = FPR_3;
0018 double d = FPR_4;
0019 
0020 __attribute__((used)) void wait_parent(void)
0021 {
0022     cptr[2] = 1;
0023     while (!cptr[1])
0024         asm volatile("" : : : "memory");
0025 }
0026 
0027 void tm_spd_gpr(void)
0028 {
0029     unsigned long gpr_buf[18];
0030     unsigned long result, texasr;
0031     double fpr_buf[32];
0032 
0033     cptr = (int *)shmat(shm_id, NULL, 0);
0034 
0035 trans:
0036     cptr[2] = 0;
0037     asm __volatile__(
0038         ASM_LOAD_GPR_IMMED(gpr_1)
0039         ASM_LOAD_FPR(flt_1)
0040 
0041         "1: ;"
0042         "tbegin.;"
0043         "beq 2f;"
0044 
0045         ASM_LOAD_GPR_IMMED(gpr_2)
0046         "tsuspend.;"
0047         ASM_LOAD_GPR_IMMED(gpr_4)
0048         ASM_LOAD_FPR(flt_4)
0049 
0050         "bl wait_parent;"
0051         "tresume.;"
0052         "tend.;"
0053         "li 0, 0;"
0054         "ori %[res], 0, 0;"
0055         "b 3f;"
0056 
0057         /* Transaction abort handler */
0058         "2: ;"
0059         "li 0, 1;"
0060         "ori %[res], 0, 0;"
0061         "mfspr %[texasr], %[sprn_texasr];"
0062 
0063         "3: ;"
0064         : [res] "=r" (result), [texasr] "=r" (texasr)
0065         : [gpr_1]"i"(GPR_1), [gpr_2]"i"(GPR_2), [gpr_4]"i"(GPR_4),
0066         [sprn_texasr] "i" (SPRN_TEXASR), [flt_1] "b" (&a),
0067         [flt_4] "b" (&d)
0068         : "memory", "r0", "r5", "r6", "r7",
0069         "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
0070         "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
0071         "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
0072         );
0073 
0074     if (result) {
0075         if (!cptr[0])
0076             goto trans;
0077 
0078         shmdt((void *)cptr);
0079         store_gpr(gpr_buf);
0080         store_fpr(fpr_buf);
0081 
0082         if (validate_gpr(gpr_buf, GPR_3))
0083             exit(1);
0084 
0085         if (validate_fpr_double(fpr_buf, c))
0086             exit(1);
0087         exit(0);
0088     }
0089     shmdt((void *)cptr);
0090     exit(1);
0091 }
0092 
0093 int trace_tm_spd_gpr(pid_t child)
0094 {
0095     unsigned long gpr[18];
0096     __u64 fpr[32];
0097 
0098     FAIL_IF(start_trace(child));
0099     FAIL_IF(show_gpr(child, gpr));
0100     FAIL_IF(validate_gpr(gpr, GPR_4));
0101     FAIL_IF(show_fpr(child, fpr));
0102     FAIL_IF(validate_fpr(fpr, FPR_4_REP));
0103     FAIL_IF(show_ckpt_fpr(child, fpr));
0104     FAIL_IF(validate_fpr(fpr, FPR_1_REP));
0105     FAIL_IF(show_ckpt_gpr(child, gpr));
0106     FAIL_IF(validate_gpr(gpr, GPR_1));
0107     FAIL_IF(write_ckpt_gpr(child, GPR_3));
0108     FAIL_IF(write_ckpt_fpr(child, FPR_3_REP));
0109 
0110     pptr[0] = 1;
0111     pptr[1] = 1;
0112     FAIL_IF(stop_trace(child));
0113     return TEST_PASS;
0114 }
0115 
0116 int ptrace_tm_spd_gpr(void)
0117 {
0118     pid_t pid;
0119     int ret, status;
0120 
0121     SKIP_IF(!have_htm());
0122     SKIP_IF(htm_is_synthetic());
0123     shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT);
0124     pid = fork();
0125     if (pid < 0) {
0126         perror("fork() failed");
0127         return TEST_FAIL;
0128     }
0129 
0130     if (pid == 0)
0131         tm_spd_gpr();
0132 
0133     if (pid) {
0134         pptr = (int *)shmat(shm_id, NULL, 0);
0135         pptr[0] = 0;
0136         pptr[1] = 0;
0137 
0138         while (!pptr[2])
0139             asm volatile("" : : : "memory");
0140         ret = trace_tm_spd_gpr(pid);
0141         if (ret) {
0142             kill(pid, SIGTERM);
0143             shmdt((void *)pptr);
0144             shmctl(shm_id, IPC_RMID, NULL);
0145             return TEST_FAIL;
0146         }
0147 
0148         shmdt((void *)pptr);
0149 
0150         ret = wait(&status);
0151         shmctl(shm_id, IPC_RMID, NULL);
0152         if (ret != pid) {
0153             printf("Child's exit status not captured\n");
0154             return TEST_FAIL;
0155         }
0156 
0157         return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
0158             TEST_PASS;
0159     }
0160     return TEST_PASS;
0161 }
0162 
0163 int main(int argc, char *argv[])
0164 {
0165     return test_harness(ptrace_tm_spd_gpr, "ptrace_tm_spd_gpr");
0166 }