Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Ptrace test for VMX/VSX 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-vsx.h"
0010 
0011 int shm_id;
0012 unsigned long *cptr, *pptr;
0013 
0014 unsigned long fp_load[VEC_MAX];
0015 unsigned long fp_store[VEC_MAX];
0016 unsigned long fp_load_ckpt[VEC_MAX];
0017 unsigned long fp_load_ckpt_new[VEC_MAX];
0018 
0019 __attribute__((used)) void load_vsx(void)
0020 {
0021     loadvsx(fp_load, 0);
0022 }
0023 
0024 __attribute__((used)) void load_vsx_ckpt(void)
0025 {
0026     loadvsx(fp_load_ckpt, 0);
0027 }
0028 
0029 void tm_vsx(void)
0030 {
0031     unsigned long result, texasr;
0032     int ret;
0033 
0034     cptr = (unsigned long *)shmat(shm_id, NULL, 0);
0035 
0036 trans:
0037     cptr[1] = 0;
0038     asm __volatile__(
0039         "bl load_vsx_ckpt;"
0040 
0041         "1: ;"
0042         "tbegin.;"
0043         "beq 2f;"
0044 
0045         "bl load_vsx;"
0046         "tsuspend.;"
0047         "li 7, 1;"
0048         "stw 7, 0(%[cptr1]);"
0049         "tresume.;"
0050         "b .;"
0051 
0052         "tend.;"
0053         "li 0, 0;"
0054         "ori %[res], 0, 0;"
0055         "b 3f;"
0056 
0057         "2: ;"
0058         "li 0, 1;"
0059         "ori %[res], 0, 0;"
0060         "mfspr %[texasr], %[sprn_texasr];"
0061 
0062         "3: ;"
0063         : [res] "=r" (result), [texasr] "=r" (texasr)
0064         : [sprn_texasr] "i"  (SPRN_TEXASR), [cptr1] "b" (&cptr[1])
0065         : "memory", "r0", "r3", "r4",
0066           "r7", "r8", "r9", "r10", "r11", "lr"
0067         );
0068 
0069     if (result) {
0070         if (!cptr[0])
0071             goto trans;
0072 
0073         shmdt((void *)cptr);
0074         storevsx(fp_store, 0);
0075         ret = compare_vsx_vmx(fp_store, fp_load_ckpt_new);
0076         if (ret)
0077             exit(1);
0078         exit(0);
0079     }
0080     shmdt((void *)cptr);
0081     exit(1);
0082 }
0083 
0084 int trace_tm_vsx(pid_t child)
0085 {
0086     unsigned long vsx[VSX_MAX];
0087     unsigned long vmx[VMX_MAX + 2][2];
0088 
0089     FAIL_IF(start_trace(child));
0090     FAIL_IF(show_vsx(child, vsx));
0091     FAIL_IF(validate_vsx(vsx, fp_load));
0092     FAIL_IF(show_vmx(child, vmx));
0093     FAIL_IF(validate_vmx(vmx, fp_load));
0094     FAIL_IF(show_vsx_ckpt(child, vsx));
0095     FAIL_IF(validate_vsx(vsx, fp_load_ckpt));
0096     FAIL_IF(show_vmx_ckpt(child, vmx));
0097     FAIL_IF(validate_vmx(vmx, fp_load_ckpt));
0098     memset(vsx, 0, sizeof(vsx));
0099     memset(vmx, 0, sizeof(vmx));
0100 
0101     load_vsx_vmx(fp_load_ckpt_new, vsx, vmx);
0102 
0103     FAIL_IF(write_vsx_ckpt(child, vsx));
0104     FAIL_IF(write_vmx_ckpt(child, vmx));
0105     pptr[0] = 1;
0106     FAIL_IF(stop_trace(child));
0107     return TEST_PASS;
0108 }
0109 
0110 int ptrace_tm_vsx(void)
0111 {
0112     pid_t pid;
0113     int ret, status, i;
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 
0119     for (i = 0; i < 128; i++) {
0120         fp_load[i] = 1 + rand();
0121         fp_load_ckpt[i] = 1 + 2 * rand();
0122         fp_load_ckpt_new[i] = 1 + 3 * rand();
0123     }
0124 
0125     pid = fork();
0126     if (pid < 0) {
0127         perror("fork() failed");
0128         return TEST_FAIL;
0129     }
0130 
0131     if (pid == 0)
0132         tm_vsx();
0133 
0134     if (pid) {
0135         pptr = (unsigned long *)shmat(shm_id, NULL, 0);
0136         while (!pptr[1])
0137             asm volatile("" : : : "memory");
0138 
0139         ret = trace_tm_vsx(pid);
0140         if (ret) {
0141             kill(pid, SIGKILL);
0142             shmdt((void *)pptr);
0143             shmctl(shm_id, IPC_RMID, NULL);
0144             return TEST_FAIL;
0145         }
0146 
0147         shmdt((void *)pptr);
0148         ret = wait(&status);
0149         shmctl(shm_id, IPC_RMID, NULL);
0150         if (ret != pid) {
0151             printf("Child's exit status not captured\n");
0152             return TEST_FAIL;
0153         }
0154 
0155         return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
0156             TEST_PASS;
0157     }
0158     return TEST_PASS;
0159 }
0160 
0161 int main(int argc, char *argv[])
0162 {
0163     return test_harness(ptrace_tm_vsx, "ptrace_tm_vsx");
0164 }