Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Ptrace test for TAR, PPR, DSCR registers in the TM context
0004  *
0005  * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
0006  */
0007 #include "ptrace.h"
0008 #include "tm.h"
0009 #include "ptrace-tar.h"
0010 
0011 int shm_id;
0012 unsigned long *cptr, *pptr;
0013 
0014 
0015 void tm_tar(void)
0016 {
0017     unsigned long result, texasr;
0018     unsigned long regs[3];
0019     int ret;
0020 
0021     cptr = (unsigned long *)shmat(shm_id, NULL, 0);
0022 
0023 trans:
0024     cptr[1] = 0;
0025     asm __volatile__(
0026         "li 4, %[tar_1];"
0027         "mtspr %[sprn_tar],  4;"    /* TAR_1 */
0028         "li 4, %[dscr_1];"
0029         "mtspr %[sprn_dscr], 4;"    /* DSCR_1 */
0030         "or     31,31,31;"      /* PPR_1*/
0031 
0032         "1: ;"
0033         "tbegin.;"
0034         "beq 2f;"
0035 
0036         "li 4, %[tar_2];"
0037         "mtspr %[sprn_tar],  4;"    /* TAR_2 */
0038         "li 4, %[dscr_2];"
0039         "mtspr %[sprn_dscr], 4;"    /* DSCR_2 */
0040         "or     1,1,1;"         /* PPR_2 */
0041         "tsuspend.;"
0042         "li 0, 1;"
0043         "stw 0, 0(%[cptr1]);"
0044         "tresume.;"
0045         "b .;"
0046 
0047         "tend.;"
0048         "li 0, 0;"
0049         "ori %[res], 0, 0;"
0050         "b 3f;"
0051 
0052         /* Transaction abort handler */
0053         "2: ;"
0054         "li 0, 1;"
0055         "ori %[res], 0, 0;"
0056         "mfspr %[texasr], %[sprn_texasr];"
0057 
0058         "3: ;"
0059 
0060         : [res] "=r" (result), [texasr] "=r" (texasr)
0061         : [sprn_dscr]"i"(SPRN_DSCR), [sprn_tar]"i"(SPRN_TAR),
0062         [sprn_ppr]"i"(SPRN_PPR), [sprn_texasr]"i"(SPRN_TEXASR),
0063         [tar_1]"i"(TAR_1), [dscr_1]"i"(DSCR_1), [tar_2]"i"(TAR_2),
0064         [dscr_2]"i"(DSCR_2), [cptr1] "b" (&cptr[1])
0065         : "memory", "r0", "r3", "r4", "r5", "r6"
0066         );
0067 
0068     /* TM failed, analyse */
0069     if (result) {
0070         if (!cptr[0])
0071             goto trans;
0072 
0073         regs[0] = mfspr(SPRN_TAR);
0074         regs[1] = mfspr(SPRN_PPR);
0075         regs[2] = mfspr(SPRN_DSCR);
0076 
0077         shmdt(&cptr);
0078         printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
0079                 user_read, regs[0], regs[1], regs[2]);
0080 
0081         ret = validate_tar_registers(regs, TAR_4, PPR_4, DSCR_4);
0082         if (ret)
0083             exit(1);
0084         exit(0);
0085     }
0086     shmdt(&cptr);
0087     exit(1);
0088 }
0089 
0090 int trace_tm_tar(pid_t child)
0091 {
0092     unsigned long regs[3];
0093 
0094     FAIL_IF(start_trace(child));
0095     FAIL_IF(show_tar_registers(child, regs));
0096     printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
0097             ptrace_read_running, regs[0], regs[1], regs[2]);
0098 
0099     FAIL_IF(validate_tar_registers(regs, TAR_2, PPR_2, DSCR_2));
0100     FAIL_IF(show_tm_checkpointed_state(child, regs));
0101     printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
0102             ptrace_read_ckpt, regs[0], regs[1], regs[2]);
0103 
0104     FAIL_IF(validate_tar_registers(regs, TAR_1, PPR_1, DSCR_1));
0105     FAIL_IF(write_ckpt_tar_registers(child, TAR_4, PPR_4, DSCR_4));
0106     printf("%-30s TAR: %u PPR: %lx DSCR: %u\n",
0107             ptrace_write_ckpt, TAR_4, PPR_4, DSCR_4);
0108 
0109     pptr[0] = 1;
0110     FAIL_IF(stop_trace(child));
0111     return TEST_PASS;
0112 }
0113 
0114 int ptrace_tm_tar(void)
0115 {
0116     pid_t pid;
0117     int ret, status;
0118 
0119     SKIP_IF(!have_htm());
0120     SKIP_IF(htm_is_synthetic());
0121     shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
0122     pid = fork();
0123     if (pid == 0)
0124         tm_tar();
0125 
0126     pptr = (unsigned long *)shmat(shm_id, NULL, 0);
0127     pptr[0] = 0;
0128 
0129     if (pid) {
0130         while (!pptr[1])
0131             asm volatile("" : : : "memory");
0132         ret = trace_tm_tar(pid);
0133         if (ret) {
0134             kill(pid, SIGTERM);
0135             shmdt(&pptr);
0136             shmctl(shm_id, IPC_RMID, NULL);
0137             return TEST_FAIL;
0138         }
0139         shmdt(&pptr);
0140 
0141         ret = wait(&status);
0142         shmctl(shm_id, IPC_RMID, NULL);
0143         if (ret != pid) {
0144             printf("Child's exit status not captured\n");
0145             return TEST_FAIL;
0146         }
0147 
0148         return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
0149             TEST_PASS;
0150     }
0151     return TEST_PASS;
0152 }
0153 
0154 int main(int argc, char *argv[])
0155 {
0156     return test_harness(ptrace_tm_tar, "ptrace_tm_tar");
0157 }