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