~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c

Version: ~ [ linux-5.4-rc7 ] ~ [ linux-5.3.11 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.84 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.154 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.201 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.201 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.77 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Ptrace test TM SPR registers
  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 
 14 /* Tracee and tracer shared data */
 15 struct shared {
 16         int flag;
 17         struct tm_spr_regs regs;
 18 };
 19 unsigned long tfhar;
 20 
 21 int shm_id;
 22 struct shared *cptr, *pptr;
 23 
 24 int shm_id1;
 25 int *cptr1, *pptr1;
 26 
 27 #define TM_KVM_SCHED   0xe0000001ac000001
 28 int validate_tm_spr(struct tm_spr_regs *regs)
 29 {
 30         FAIL_IF(regs->tm_tfhar != tfhar);
 31         FAIL_IF((regs->tm_texasr == TM_KVM_SCHED) && (regs->tm_tfiar != 0));
 32 
 33         return TEST_PASS;
 34 }
 35 
 36 void tm_spr(void)
 37 {
 38         unsigned long result, texasr;
 39         int ret;
 40 
 41         cptr = (struct shared *)shmat(shm_id, NULL, 0);
 42         cptr1 = (int *)shmat(shm_id1, NULL, 0);
 43 
 44 trans:
 45         cptr1[0] = 0;
 46         asm __volatile__(
 47                 "1: ;"
 48                 /* TM failover handler should follow "tbegin.;" */
 49                 "mflr 31;"
 50                 "bl 4f;"        /* $ = TFHAR - 12 */
 51                 "4: ;"
 52                 "mflr %[tfhar];"
 53                 "mtlr 31;"
 54 
 55                 "tbegin.;"
 56                 "beq 2f;"
 57 
 58                 "tsuspend.;"
 59                 "li 8, 1;"
 60                 "sth 8, 0(%[cptr1]);"
 61                 "tresume.;"
 62                 "b .;"
 63 
 64                 "tend.;"
 65                 "li 0, 0;"
 66                 "ori %[res], 0, 0;"
 67                 "b 3f;"
 68 
 69                 "2: ;"
 70 
 71                 "li 0, 1;"
 72                 "ori %[res], 0, 0;"
 73                 "mfspr %[texasr], %[sprn_texasr];"
 74 
 75                 "3: ;"
 76                 : [tfhar] "=r" (tfhar), [res] "=r" (result),
 77                 [texasr] "=r" (texasr), [cptr1] "=r" (cptr1)
 78                 : [sprn_texasr] "i"  (SPRN_TEXASR)
 79                 : "memory", "r0", "r1", "r2", "r3", "r4",
 80                 "r8", "r9", "r10", "r11", "r31"
 81                 );
 82 
 83         /* There are 2 32bit instructions before tbegin. */
 84         tfhar += 12;
 85 
 86         if (result) {
 87                 if (!cptr->flag)
 88                         goto trans;
 89 
 90                 ret = validate_tm_spr((struct tm_spr_regs *)&cptr->regs);
 91                 shmdt((void *)cptr);
 92                 shmdt((void *)cptr1);
 93                 if (ret)
 94                         exit(1);
 95                 exit(0);
 96         }
 97         shmdt((void *)cptr);
 98         shmdt((void *)cptr1);
 99         exit(1);
100 }
101 
102 int trace_tm_spr(pid_t child)
103 {
104         FAIL_IF(start_trace(child));
105         FAIL_IF(show_tm_spr(child, (struct tm_spr_regs *)&pptr->regs));
106 
107         printf("TFHAR: %lx TEXASR: %lx TFIAR: %lx\n", pptr->regs.tm_tfhar,
108                                 pptr->regs.tm_texasr, pptr->regs.tm_tfiar);
109 
110         pptr->flag = 1;
111         FAIL_IF(stop_trace(child));
112 
113         return TEST_PASS;
114 }
115 
116 int ptrace_tm_spr(void)
117 {
118         pid_t pid;
119         int ret, status;
120 
121         SKIP_IF(!have_htm());
122         shm_id = shmget(IPC_PRIVATE, sizeof(struct shared), 0777|IPC_CREAT);
123         shm_id1 = shmget(IPC_PRIVATE, sizeof(int), 0777|IPC_CREAT);
124         pid = fork();
125         if (pid < 0) {
126                 perror("fork() failed");
127                 return TEST_FAIL;
128         }
129 
130         if (pid == 0)
131                 tm_spr();
132 
133         if (pid) {
134                 pptr = (struct shared *)shmat(shm_id, NULL, 0);
135                 pptr1 = (int *)shmat(shm_id1, NULL, 0);
136 
137                 while (!pptr1[0])
138                         asm volatile("" : : : "memory");
139                 ret = trace_tm_spr(pid);
140                 if (ret) {
141                         kill(pid, SIGKILL);
142                         shmdt((void *)pptr);
143                         shmdt((void *)pptr1);
144                         shmctl(shm_id, IPC_RMID, NULL);
145                         shmctl(shm_id1, IPC_RMID, NULL);
146                         return TEST_FAIL;
147                 }
148 
149                 shmdt((void *)pptr);
150                 shmdt((void *)pptr1);
151                 ret = wait(&status);
152                 shmctl(shm_id, IPC_RMID, NULL);
153                 shmctl(shm_id1, 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 
165 int main(int argc, char *argv[])
166 {
167         return test_harness(ptrace_tm_spr, "ptrace_tm_spr");
168 }
169 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp