root/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. load_vsx
  2. load_vsx_new
  3. load_vsx_ckpt
  4. wait_parent
  5. tm_spd_vsx
  6. trace_tm_spd_vsx
  7. ptrace_tm_spd_vsx
  8. main

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Ptrace test for VMX/VSX registers in the TM Suspend context
   4  *
   5  * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
   6  */
   7 #include "ptrace.h"
   8 #include "tm.h"
   9 #include "ptrace-vsx.h"
  10 
  11 int shm_id;
  12 int *cptr, *pptr;
  13 
  14 unsigned long fp_load[VEC_MAX];
  15 unsigned long fp_load_new[VEC_MAX];
  16 unsigned long fp_store[VEC_MAX];
  17 unsigned long fp_load_ckpt[VEC_MAX];
  18 unsigned long fp_load_ckpt_new[VEC_MAX];
  19 
  20 __attribute__((used)) void load_vsx(void)
  21 {
  22         loadvsx(fp_load, 0);
  23 }
  24 
  25 __attribute__((used)) void load_vsx_new(void)
  26 {
  27         loadvsx(fp_load_new, 0);
  28 }
  29 
  30 __attribute__((used)) void load_vsx_ckpt(void)
  31 {
  32         loadvsx(fp_load_ckpt, 0);
  33 }
  34 
  35 __attribute__((used)) void wait_parent(void)
  36 {
  37         cptr[2] = 1;
  38         while (!cptr[1])
  39                 asm volatile("" : : : "memory");
  40 }
  41 
  42 void tm_spd_vsx(void)
  43 {
  44         unsigned long result, texasr;
  45         int ret;
  46 
  47         cptr = (int *)shmat(shm_id, NULL, 0);
  48 
  49 trans:
  50         cptr[2] = 0;
  51         asm __volatile__(
  52                 "bl load_vsx_ckpt;"
  53 
  54                 "1: ;"
  55                 "tbegin.;"
  56                 "beq 2f;"
  57 
  58                 "bl load_vsx_new;"
  59                 "tsuspend.;"
  60                 "bl load_vsx;"
  61                 "bl wait_parent;"
  62                 "tresume.;"
  63 
  64                 "tend.;"
  65                 "li 0, 0;"
  66                 "ori %[res], 0, 0;"
  67                 "b 3f;"
  68 
  69                 "2: ;"
  70                 "li 0, 1;"
  71                 "ori %[res], 0, 0;"
  72                 "mfspr %[texasr], %[sprn_texasr];"
  73 
  74                 "3: ;"
  75                 : [res] "=r" (result), [texasr] "=r" (texasr)
  76                 : [sprn_texasr] "i"  (SPRN_TEXASR)
  77                 : "memory", "r0", "r3", "r4",
  78                   "r7", "r8", "r9", "r10", "r11", "lr"
  79                 );
  80 
  81         if (result) {
  82                 if (!cptr[0])
  83                         goto trans;
  84                 shmdt((void *)cptr);
  85 
  86                 storevsx(fp_store, 0);
  87                 ret = compare_vsx_vmx(fp_store, fp_load_ckpt_new);
  88                 if (ret)
  89                         exit(1);
  90                 exit(0);
  91         }
  92         shmdt((void *)cptr);
  93         exit(1);
  94 }
  95 
  96 int trace_tm_spd_vsx(pid_t child)
  97 {
  98         unsigned long vsx[VSX_MAX];
  99         unsigned long vmx[VMX_MAX + 2][2];
 100 
 101         FAIL_IF(start_trace(child));
 102         FAIL_IF(show_vsx(child, vsx));
 103         FAIL_IF(validate_vsx(vsx, fp_load));
 104         FAIL_IF(show_vmx(child, vmx));
 105         FAIL_IF(validate_vmx(vmx, fp_load));
 106         FAIL_IF(show_vsx_ckpt(child, vsx));
 107         FAIL_IF(validate_vsx(vsx, fp_load_ckpt));
 108         FAIL_IF(show_vmx_ckpt(child, vmx));
 109         FAIL_IF(validate_vmx(vmx, fp_load_ckpt));
 110 
 111         memset(vsx, 0, sizeof(vsx));
 112         memset(vmx, 0, sizeof(vmx));
 113 
 114         load_vsx_vmx(fp_load_ckpt_new, vsx, vmx);
 115 
 116         FAIL_IF(write_vsx_ckpt(child, vsx));
 117         FAIL_IF(write_vmx_ckpt(child, vmx));
 118 
 119         pptr[0] = 1;
 120         pptr[1] = 1;
 121         FAIL_IF(stop_trace(child));
 122 
 123         return TEST_PASS;
 124 }
 125 
 126 int ptrace_tm_spd_vsx(void)
 127 {
 128         pid_t pid;
 129         int ret, status, i;
 130 
 131         SKIP_IF(!have_htm());
 132         shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT);
 133 
 134         for (i = 0; i < 128; i++) {
 135                 fp_load[i] = 1 + rand();
 136                 fp_load_new[i] = 1 + 2 * rand();
 137                 fp_load_ckpt[i] = 1 + 3 * rand();
 138                 fp_load_ckpt_new[i] = 1 + 4 * rand();
 139         }
 140 
 141         pid = fork();
 142         if (pid < 0) {
 143                 perror("fork() failed");
 144                 return TEST_FAIL;
 145         }
 146 
 147         if (pid == 0)
 148                 tm_spd_vsx();
 149 
 150         if (pid) {
 151                 pptr = (int *)shmat(shm_id, NULL, 0);
 152                 while (!pptr[2])
 153                         asm volatile("" : : : "memory");
 154 
 155                 ret = trace_tm_spd_vsx(pid);
 156                 if (ret) {
 157                         kill(pid, SIGKILL);
 158                         shmdt((void *)pptr);
 159                         shmctl(shm_id, IPC_RMID, NULL);
 160                         return TEST_FAIL;
 161                 }
 162 
 163                 shmdt((void *)pptr);
 164                 ret = wait(&status);
 165                 shmctl(shm_id, IPC_RMID, NULL);
 166                 if (ret != pid) {
 167                         printf("Child's exit status not captured\n");
 168                         return TEST_FAIL;
 169                 }
 170 
 171                 return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
 172                         TEST_PASS;
 173         }
 174         return TEST_PASS;
 175 }
 176 
 177 int main(int argc, char *argv[])
 178 {
 179         return test_harness(ptrace_tm_spd_vsx, "ptrace_tm_spd_vsx");
 180 }

/* [<][>][^][v][top][bottom][index][help] */