linux/tools/testing/selftests/powerpc/ptrace/ptrace-tar.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * Ptrace test for TAR, PPR, DSCR registers
   4 *
   5 * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
   6 */
   7#include "ptrace.h"
   8#include "ptrace-tar.h"
   9
  10/* Tracer and Tracee Shared Data */
  11int shm_id;
  12int *cptr;
  13int *pptr;
  14
  15void tar(void)
  16{
  17        unsigned long reg[3];
  18        int ret;
  19
  20        cptr = (int *)shmat(shm_id, NULL, 0);
  21        printf("%-30s TAR: %u PPR: %lx DSCR: %u\n",
  22                        user_write, TAR_1, PPR_1, DSCR_1);
  23
  24        mtspr(SPRN_TAR, TAR_1);
  25        mtspr(SPRN_PPR, PPR_1);
  26        mtspr(SPRN_DSCR, DSCR_1);
  27
  28        cptr[2] = 1;
  29
  30        /* Wait on parent */
  31        while (!cptr[0])
  32                asm volatile("" : : : "memory");
  33
  34        reg[0] = mfspr(SPRN_TAR);
  35        reg[1] = mfspr(SPRN_PPR);
  36        reg[2] = mfspr(SPRN_DSCR);
  37
  38        printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
  39                        user_read, reg[0], reg[1], reg[2]);
  40
  41        /* Unblock the parent now */
  42        cptr[1] = 1;
  43        shmdt((int *)cptr);
  44
  45        ret = validate_tar_registers(reg, TAR_2, PPR_2, DSCR_2);
  46        if (ret)
  47                exit(1);
  48        exit(0);
  49}
  50
  51int trace_tar(pid_t child)
  52{
  53        unsigned long reg[3];
  54
  55        FAIL_IF(start_trace(child));
  56        FAIL_IF(show_tar_registers(child, reg));
  57        printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
  58                        ptrace_read_running, reg[0], reg[1], reg[2]);
  59
  60        FAIL_IF(validate_tar_registers(reg, TAR_1, PPR_1, DSCR_1));
  61        FAIL_IF(stop_trace(child));
  62        return TEST_PASS;
  63}
  64
  65int trace_tar_write(pid_t child)
  66{
  67        FAIL_IF(start_trace(child));
  68        FAIL_IF(write_tar_registers(child, TAR_2, PPR_2, DSCR_2));
  69        printf("%-30s TAR: %u PPR: %lx DSCR: %u\n",
  70                        ptrace_write_running, TAR_2, PPR_2, DSCR_2);
  71
  72        FAIL_IF(stop_trace(child));
  73        return TEST_PASS;
  74}
  75
  76int ptrace_tar(void)
  77{
  78        pid_t pid;
  79        int ret, status;
  80
  81        // TAR was added in v2.07
  82        SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_2_07));
  83
  84        shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT);
  85        pid = fork();
  86        if (pid < 0) {
  87                perror("fork() failed");
  88                return TEST_FAIL;
  89        }
  90
  91        if (pid == 0)
  92                tar();
  93
  94        if (pid) {
  95                pptr = (int *)shmat(shm_id, NULL, 0);
  96                pptr[0] = 0;
  97                pptr[1] = 0;
  98
  99                while (!pptr[2])
 100                        asm volatile("" : : : "memory");
 101                ret = trace_tar(pid);
 102                if (ret)
 103                        return ret;
 104
 105                ret = trace_tar_write(pid);
 106                if (ret)
 107                        return ret;
 108
 109                /* Unblock the child now */
 110                pptr[0] = 1;
 111
 112                /* Wait on child */
 113                while (!pptr[1])
 114                        asm volatile("" : : : "memory");
 115
 116                shmdt((int *)pptr);
 117
 118                ret = wait(&status);
 119                shmctl(shm_id, IPC_RMID, NULL);
 120                if (ret != pid) {
 121                        printf("Child's exit status not captured\n");
 122                        return TEST_PASS;
 123                }
 124
 125                return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
 126                        TEST_PASS;
 127        }
 128        return TEST_PASS;
 129}
 130
 131int main(int argc, char *argv[])
 132{
 133        return test_harness(ptrace_tar, "ptrace_tar");
 134}
 135