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 Suspend 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 int *cptr, *pptr;
0013 
0014 __attribute__((used)) void wait_parent(void)
0015 {
0016     cptr[2] = 1;
0017     while (!cptr[1])
0018         asm volatile("" : : : "memory");
0019 }
0020 
0021 void tm_spd_tar(void)
0022 {
0023     unsigned long result, texasr;
0024     unsigned long regs[3];
0025     int ret;
0026 
0027     cptr = (int *)shmat(shm_id, NULL, 0);
0028 
0029 trans:
0030     cptr[2] = 0;
0031     asm __volatile__(
0032         "li 4, %[tar_1];"
0033         "mtspr %[sprn_tar],  4;"    /* TAR_1 */
0034         "li 4, %[dscr_1];"
0035         "mtspr %[sprn_dscr], 4;"    /* DSCR_1 */
0036         "or     31,31,31;"      /* PPR_1*/
0037 
0038         "1: ;"
0039         "tbegin.;"
0040         "beq 2f;"
0041 
0042         "li 4, %[tar_2];"
0043         "mtspr %[sprn_tar],  4;"    /* TAR_2 */
0044         "li 4, %[dscr_2];"
0045         "mtspr %[sprn_dscr], 4;"    /* DSCR_2 */
0046         "or     1,1,1;"         /* PPR_2 */
0047 
0048         "tsuspend.;"
0049         "li 4, %[tar_3];"
0050         "mtspr %[sprn_tar],  4;"    /* TAR_3 */
0051         "li 4, %[dscr_3];"
0052         "mtspr %[sprn_dscr], 4;"    /* DSCR_3 */
0053         "or     6,6,6;"         /* PPR_3 */
0054         "bl wait_parent;"
0055         "tresume.;"
0056 
0057         "tend.;"
0058         "li 0, 0;"
0059         "ori %[res], 0, 0;"
0060         "b 3f;"
0061 
0062         /* Transaction abort handler */
0063         "2: ;"
0064         "li 0, 1;"
0065         "ori %[res], 0, 0;"
0066         "mfspr %[texasr], %[sprn_texasr];"
0067 
0068         "3: ;"
0069 
0070         : [res] "=r" (result), [texasr] "=r" (texasr)
0071         : [sprn_dscr]"i"(SPRN_DSCR),
0072         [sprn_tar]"i"(SPRN_TAR), [sprn_ppr]"i"(SPRN_PPR),
0073         [sprn_texasr]"i"(SPRN_TEXASR), [tar_1]"i"(TAR_1),
0074         [dscr_1]"i"(DSCR_1), [tar_2]"i"(TAR_2), [dscr_2]"i"(DSCR_2),
0075         [tar_3]"i"(TAR_3), [dscr_3]"i"(DSCR_3)
0076         : "memory", "r0", "r3", "r4", "r5", "r6", "lr"
0077         );
0078 
0079     /* TM failed, analyse */
0080     if (result) {
0081         if (!cptr[0])
0082             goto trans;
0083 
0084         regs[0] = mfspr(SPRN_TAR);
0085         regs[1] = mfspr(SPRN_PPR);
0086         regs[2] = mfspr(SPRN_DSCR);
0087 
0088         shmdt(&cptr);
0089         printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
0090                 user_read, regs[0], regs[1], regs[2]);
0091 
0092         ret = validate_tar_registers(regs, TAR_4, PPR_4, DSCR_4);
0093         if (ret)
0094             exit(1);
0095         exit(0);
0096     }
0097     shmdt(&cptr);
0098     exit(1);
0099 }
0100 
0101 int trace_tm_spd_tar(pid_t child)
0102 {
0103     unsigned long regs[3];
0104 
0105     FAIL_IF(start_trace(child));
0106     FAIL_IF(show_tar_registers(child, regs));
0107     printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
0108             ptrace_read_running, regs[0], regs[1], regs[2]);
0109 
0110     FAIL_IF(validate_tar_registers(regs, TAR_3, PPR_3, DSCR_3));
0111     FAIL_IF(show_tm_checkpointed_state(child, regs));
0112     printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
0113             ptrace_read_ckpt, regs[0], regs[1], regs[2]);
0114 
0115     FAIL_IF(validate_tar_registers(regs, TAR_1, PPR_1, DSCR_1));
0116     FAIL_IF(write_ckpt_tar_registers(child, TAR_4, PPR_4, DSCR_4));
0117     printf("%-30s TAR: %u PPR: %lx DSCR: %u\n",
0118             ptrace_write_ckpt, TAR_4, PPR_4, DSCR_4);
0119 
0120     pptr[0] = 1;
0121     pptr[1] = 1;
0122     FAIL_IF(stop_trace(child));
0123     return TEST_PASS;
0124 }
0125 
0126 int ptrace_tm_spd_tar(void)
0127 {
0128     pid_t pid;
0129     int ret, status;
0130 
0131     SKIP_IF(!have_htm());
0132     SKIP_IF(htm_is_synthetic());
0133     shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT);
0134     pid = fork();
0135     if (pid == 0)
0136         tm_spd_tar();
0137 
0138     pptr = (int *)shmat(shm_id, NULL, 0);
0139     pptr[0] = 0;
0140     pptr[1] = 0;
0141 
0142     if (pid) {
0143         while (!pptr[2])
0144             asm volatile("" : : : "memory");
0145         ret = trace_tm_spd_tar(pid);
0146         if (ret) {
0147             kill(pid, SIGTERM);
0148             shmdt(&pptr);
0149             shmctl(shm_id, IPC_RMID, NULL);
0150             return TEST_FAIL;
0151         }
0152 
0153         shmdt(&pptr);
0154 
0155         ret = wait(&status);
0156         shmctl(shm_id, IPC_RMID, NULL);
0157         if (ret != pid) {
0158             printf("Child's exit status not captured\n");
0159             return TEST_FAIL;
0160         }
0161 
0162         return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
0163             TEST_PASS;
0164     }
0165     return TEST_PASS;
0166 }
0167 
0168 int main(int argc, char *argv[])
0169 {
0170     return test_harness(ptrace_tm_spd_tar, "ptrace_tm_spd_tar");
0171 }