12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 2f666ad41SAnshuman Khandual /* 3f666ad41SAnshuman Khandual * Ptrace interface test helper functions 4f666ad41SAnshuman Khandual * 5f666ad41SAnshuman Khandual * Copyright (C) 2015 Anshuman Khandual, IBM Corporation. 6f666ad41SAnshuman Khandual */ 7*53fa86e7SMichael Ellerman 8*53fa86e7SMichael Ellerman #define __SANE_USERSPACE_TYPES__ 9*53fa86e7SMichael Ellerman 10f666ad41SAnshuman Khandual #include <inttypes.h> 11f666ad41SAnshuman Khandual #include <unistd.h> 12f666ad41SAnshuman Khandual #include <stdlib.h> 13f666ad41SAnshuman Khandual #include <string.h> 14f666ad41SAnshuman Khandual #include <malloc.h> 15f666ad41SAnshuman Khandual #include <errno.h> 16f666ad41SAnshuman Khandual #include <time.h> 17f666ad41SAnshuman Khandual #include <sys/ptrace.h> 18f666ad41SAnshuman Khandual #include <sys/ioctl.h> 19f666ad41SAnshuman Khandual #include <sys/uio.h> 20f666ad41SAnshuman Khandual #include <sys/types.h> 21f666ad41SAnshuman Khandual #include <sys/wait.h> 22f666ad41SAnshuman Khandual #include <sys/signal.h> 23f666ad41SAnshuman Khandual #include <sys/ipc.h> 24f666ad41SAnshuman Khandual #include <sys/shm.h> 25f666ad41SAnshuman Khandual #include <sys/user.h> 26f666ad41SAnshuman Khandual #include <linux/elf.h> 27f666ad41SAnshuman Khandual #include <linux/types.h> 28f666ad41SAnshuman Khandual #include <linux/auxvec.h> 29f666ad41SAnshuman Khandual #include "reg.h" 30f666ad41SAnshuman Khandual #include "utils.h" 31f666ad41SAnshuman Khandual 32f666ad41SAnshuman Khandual #define TEST_PASS 0 33f666ad41SAnshuman Khandual #define TEST_FAIL 1 34f666ad41SAnshuman Khandual 35f666ad41SAnshuman Khandual struct fpr_regs { 36*53fa86e7SMichael Ellerman __u64 fpr[32]; 37*53fa86e7SMichael Ellerman __u64 fpscr; 38f666ad41SAnshuman Khandual }; 39f666ad41SAnshuman Khandual 405bdac52fSAnshuman Khandual struct tm_spr_regs { 415bdac52fSAnshuman Khandual unsigned long tm_tfhar; 425bdac52fSAnshuman Khandual unsigned long tm_texasr; 435bdac52fSAnshuman Khandual unsigned long tm_tfiar; 445bdac52fSAnshuman Khandual }; 45f666ad41SAnshuman Khandual 46f666ad41SAnshuman Khandual #ifndef NT_PPC_TAR 47f666ad41SAnshuman Khandual #define NT_PPC_TAR 0x103 48f666ad41SAnshuman Khandual #define NT_PPC_PPR 0x104 49f666ad41SAnshuman Khandual #define NT_PPC_DSCR 0x105 50f666ad41SAnshuman Khandual #define NT_PPC_EBB 0x106 51f666ad41SAnshuman Khandual #define NT_PPC_PMU 0x107 52f666ad41SAnshuman Khandual #define NT_PPC_TM_CGPR 0x108 53f666ad41SAnshuman Khandual #define NT_PPC_TM_CFPR 0x109 54f666ad41SAnshuman Khandual #define NT_PPC_TM_CVMX 0x10a 55f666ad41SAnshuman Khandual #define NT_PPC_TM_CVSX 0x10b 56f666ad41SAnshuman Khandual #define NT_PPC_TM_SPR 0x10c 57f666ad41SAnshuman Khandual #define NT_PPC_TM_CTAR 0x10d 58f666ad41SAnshuman Khandual #define NT_PPC_TM_CPPR 0x10e 59f666ad41SAnshuman Khandual #define NT_PPC_TM_CDSCR 0x10f 60f666ad41SAnshuman Khandual #endif 61f666ad41SAnshuman Khandual 62f666ad41SAnshuman Khandual /* Basic ptrace operations */ 63f666ad41SAnshuman Khandual int start_trace(pid_t child) 64f666ad41SAnshuman Khandual { 65f666ad41SAnshuman Khandual int ret; 66f666ad41SAnshuman Khandual 67f666ad41SAnshuman Khandual ret = ptrace(PTRACE_ATTACH, child, NULL, NULL); 68f666ad41SAnshuman Khandual if (ret) { 69f666ad41SAnshuman Khandual perror("ptrace(PTRACE_ATTACH) failed"); 70f666ad41SAnshuman Khandual return TEST_FAIL; 71f666ad41SAnshuman Khandual } 72f666ad41SAnshuman Khandual ret = waitpid(child, NULL, 0); 73f666ad41SAnshuman Khandual if (ret != child) { 74f666ad41SAnshuman Khandual perror("waitpid() failed"); 75f666ad41SAnshuman Khandual return TEST_FAIL; 76f666ad41SAnshuman Khandual } 77f666ad41SAnshuman Khandual return TEST_PASS; 78f666ad41SAnshuman Khandual } 79f666ad41SAnshuman Khandual 80f666ad41SAnshuman Khandual int stop_trace(pid_t child) 81f666ad41SAnshuman Khandual { 82f666ad41SAnshuman Khandual int ret; 83f666ad41SAnshuman Khandual 84f666ad41SAnshuman Khandual ret = ptrace(PTRACE_DETACH, child, NULL, NULL); 85f666ad41SAnshuman Khandual if (ret) { 86f666ad41SAnshuman Khandual perror("ptrace(PTRACE_DETACH) failed"); 87f666ad41SAnshuman Khandual return TEST_FAIL; 88f666ad41SAnshuman Khandual } 89f666ad41SAnshuman Khandual return TEST_PASS; 90f666ad41SAnshuman Khandual } 91f666ad41SAnshuman Khandual 92f666ad41SAnshuman Khandual int cont_trace(pid_t child) 93f666ad41SAnshuman Khandual { 94f666ad41SAnshuman Khandual int ret; 95f666ad41SAnshuman Khandual 96f666ad41SAnshuman Khandual ret = ptrace(PTRACE_CONT, child, NULL, NULL); 97f666ad41SAnshuman Khandual if (ret) { 98f666ad41SAnshuman Khandual perror("ptrace(PTRACE_CONT) failed"); 99f666ad41SAnshuman Khandual return TEST_FAIL; 100f666ad41SAnshuman Khandual } 101f666ad41SAnshuman Khandual return TEST_PASS; 102f666ad41SAnshuman Khandual } 103f666ad41SAnshuman Khandual 1041f7256e7SThiago Jung Bauermann int ptrace_read_regs(pid_t child, unsigned long type, unsigned long regs[], 1051f7256e7SThiago Jung Bauermann int n) 1061f7256e7SThiago Jung Bauermann { 1071f7256e7SThiago Jung Bauermann struct iovec iov; 1081f7256e7SThiago Jung Bauermann long ret; 1091f7256e7SThiago Jung Bauermann 1101f7256e7SThiago Jung Bauermann FAIL_IF(start_trace(child)); 1111f7256e7SThiago Jung Bauermann 1121f7256e7SThiago Jung Bauermann iov.iov_base = regs; 1131f7256e7SThiago Jung Bauermann iov.iov_len = n * sizeof(unsigned long); 1141f7256e7SThiago Jung Bauermann 1151f7256e7SThiago Jung Bauermann ret = ptrace(PTRACE_GETREGSET, child, type, &iov); 1161f7256e7SThiago Jung Bauermann if (ret) 1171f7256e7SThiago Jung Bauermann return ret; 1181f7256e7SThiago Jung Bauermann 1191f7256e7SThiago Jung Bauermann FAIL_IF(stop_trace(child)); 1201f7256e7SThiago Jung Bauermann 1211f7256e7SThiago Jung Bauermann return TEST_PASS; 1221f7256e7SThiago Jung Bauermann } 1231f7256e7SThiago Jung Bauermann 1241f7256e7SThiago Jung Bauermann long ptrace_write_regs(pid_t child, unsigned long type, unsigned long regs[], 1251f7256e7SThiago Jung Bauermann int n) 1261f7256e7SThiago Jung Bauermann { 1271f7256e7SThiago Jung Bauermann struct iovec iov; 1281f7256e7SThiago Jung Bauermann long ret; 1291f7256e7SThiago Jung Bauermann 1301f7256e7SThiago Jung Bauermann FAIL_IF(start_trace(child)); 1311f7256e7SThiago Jung Bauermann 1321f7256e7SThiago Jung Bauermann iov.iov_base = regs; 1331f7256e7SThiago Jung Bauermann iov.iov_len = n * sizeof(unsigned long); 1341f7256e7SThiago Jung Bauermann 1351f7256e7SThiago Jung Bauermann ret = ptrace(PTRACE_SETREGSET, child, type, &iov); 1361f7256e7SThiago Jung Bauermann 1371f7256e7SThiago Jung Bauermann FAIL_IF(stop_trace(child)); 1381f7256e7SThiago Jung Bauermann 1391f7256e7SThiago Jung Bauermann return ret; 1401f7256e7SThiago Jung Bauermann } 1411f7256e7SThiago Jung Bauermann 142254dae59SAnshuman Khandual /* TAR, PPR, DSCR */ 143254dae59SAnshuman Khandual int show_tar_registers(pid_t child, unsigned long *out) 144254dae59SAnshuman Khandual { 145254dae59SAnshuman Khandual struct iovec iov; 146254dae59SAnshuman Khandual unsigned long *reg; 147254dae59SAnshuman Khandual int ret; 148254dae59SAnshuman Khandual 149254dae59SAnshuman Khandual reg = malloc(sizeof(unsigned long)); 150254dae59SAnshuman Khandual if (!reg) { 151254dae59SAnshuman Khandual perror("malloc() failed"); 152254dae59SAnshuman Khandual return TEST_FAIL; 153254dae59SAnshuman Khandual } 154254dae59SAnshuman Khandual iov.iov_base = (u64 *) reg; 155254dae59SAnshuman Khandual iov.iov_len = sizeof(unsigned long); 156254dae59SAnshuman Khandual 157254dae59SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TAR, &iov); 158254dae59SAnshuman Khandual if (ret) { 159254dae59SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 160254dae59SAnshuman Khandual goto fail; 161254dae59SAnshuman Khandual } 162254dae59SAnshuman Khandual if (out) 163254dae59SAnshuman Khandual out[0] = *reg; 164254dae59SAnshuman Khandual 165254dae59SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PPR, &iov); 166254dae59SAnshuman Khandual if (ret) { 167254dae59SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 168254dae59SAnshuman Khandual goto fail; 169254dae59SAnshuman Khandual } 170254dae59SAnshuman Khandual if (out) 171254dae59SAnshuman Khandual out[1] = *reg; 172254dae59SAnshuman Khandual 173254dae59SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_DSCR, &iov); 174254dae59SAnshuman Khandual if (ret) { 175254dae59SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 176254dae59SAnshuman Khandual goto fail; 177254dae59SAnshuman Khandual } 178254dae59SAnshuman Khandual if (out) 179254dae59SAnshuman Khandual out[2] = *reg; 180254dae59SAnshuman Khandual 181254dae59SAnshuman Khandual free(reg); 182254dae59SAnshuman Khandual return TEST_PASS; 183254dae59SAnshuman Khandual fail: 184254dae59SAnshuman Khandual free(reg); 185254dae59SAnshuman Khandual return TEST_FAIL; 186254dae59SAnshuman Khandual } 187254dae59SAnshuman Khandual 188254dae59SAnshuman Khandual int write_tar_registers(pid_t child, unsigned long tar, 189254dae59SAnshuman Khandual unsigned long ppr, unsigned long dscr) 190254dae59SAnshuman Khandual { 191254dae59SAnshuman Khandual struct iovec iov; 192254dae59SAnshuman Khandual unsigned long *reg; 193254dae59SAnshuman Khandual int ret; 194254dae59SAnshuman Khandual 195254dae59SAnshuman Khandual reg = malloc(sizeof(unsigned long)); 196254dae59SAnshuman Khandual if (!reg) { 197254dae59SAnshuman Khandual perror("malloc() failed"); 198254dae59SAnshuman Khandual return TEST_FAIL; 199254dae59SAnshuman Khandual } 200254dae59SAnshuman Khandual 201254dae59SAnshuman Khandual iov.iov_base = (u64 *) reg; 202254dae59SAnshuman Khandual iov.iov_len = sizeof(unsigned long); 203254dae59SAnshuman Khandual 204254dae59SAnshuman Khandual *reg = tar; 205254dae59SAnshuman Khandual ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TAR, &iov); 206254dae59SAnshuman Khandual if (ret) { 207254dae59SAnshuman Khandual perror("ptrace(PTRACE_SETREGSET) failed"); 208254dae59SAnshuman Khandual goto fail; 209254dae59SAnshuman Khandual } 210254dae59SAnshuman Khandual 211254dae59SAnshuman Khandual *reg = ppr; 212254dae59SAnshuman Khandual ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_PPR, &iov); 213254dae59SAnshuman Khandual if (ret) { 214254dae59SAnshuman Khandual perror("ptrace(PTRACE_SETREGSET) failed"); 215254dae59SAnshuman Khandual goto fail; 216254dae59SAnshuman Khandual } 217254dae59SAnshuman Khandual 218254dae59SAnshuman Khandual *reg = dscr; 219254dae59SAnshuman Khandual ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_DSCR, &iov); 220254dae59SAnshuman Khandual if (ret) { 221254dae59SAnshuman Khandual perror("ptrace(PTRACE_SETREGSET) failed"); 222254dae59SAnshuman Khandual goto fail; 223254dae59SAnshuman Khandual } 224254dae59SAnshuman Khandual 225254dae59SAnshuman Khandual free(reg); 226254dae59SAnshuman Khandual return TEST_PASS; 227254dae59SAnshuman Khandual fail: 228254dae59SAnshuman Khandual free(reg); 229254dae59SAnshuman Khandual return TEST_FAIL; 230254dae59SAnshuman Khandual } 231254dae59SAnshuman Khandual 232254dae59SAnshuman Khandual int show_tm_checkpointed_state(pid_t child, unsigned long *out) 233254dae59SAnshuman Khandual { 234254dae59SAnshuman Khandual struct iovec iov; 235254dae59SAnshuman Khandual unsigned long *reg; 236254dae59SAnshuman Khandual int ret; 237254dae59SAnshuman Khandual 238254dae59SAnshuman Khandual reg = malloc(sizeof(unsigned long)); 239254dae59SAnshuman Khandual if (!reg) { 240254dae59SAnshuman Khandual perror("malloc() failed"); 241254dae59SAnshuman Khandual return TEST_FAIL; 242254dae59SAnshuman Khandual } 243254dae59SAnshuman Khandual 244254dae59SAnshuman Khandual iov.iov_base = (u64 *) reg; 245254dae59SAnshuman Khandual iov.iov_len = sizeof(unsigned long); 246254dae59SAnshuman Khandual 247254dae59SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CTAR, &iov); 248254dae59SAnshuman Khandual if (ret) { 249254dae59SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 250254dae59SAnshuman Khandual goto fail; 251254dae59SAnshuman Khandual } 252254dae59SAnshuman Khandual if (out) 253254dae59SAnshuman Khandual out[0] = *reg; 254254dae59SAnshuman Khandual 255254dae59SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CPPR, &iov); 256254dae59SAnshuman Khandual if (ret) { 257254dae59SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 258254dae59SAnshuman Khandual goto fail; 259254dae59SAnshuman Khandual } 260254dae59SAnshuman Khandual if (out) 261254dae59SAnshuman Khandual out[1] = *reg; 262254dae59SAnshuman Khandual 263254dae59SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CDSCR, &iov); 264254dae59SAnshuman Khandual if (ret) { 265254dae59SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 266254dae59SAnshuman Khandual goto fail; 267254dae59SAnshuman Khandual } 268254dae59SAnshuman Khandual if (out) 269254dae59SAnshuman Khandual out[2] = *reg; 270254dae59SAnshuman Khandual 271254dae59SAnshuman Khandual free(reg); 272254dae59SAnshuman Khandual return TEST_PASS; 273254dae59SAnshuman Khandual 274254dae59SAnshuman Khandual fail: 275254dae59SAnshuman Khandual free(reg); 276254dae59SAnshuman Khandual return TEST_FAIL; 277254dae59SAnshuman Khandual } 278254dae59SAnshuman Khandual 279254dae59SAnshuman Khandual int write_ckpt_tar_registers(pid_t child, unsigned long tar, 280254dae59SAnshuman Khandual unsigned long ppr, unsigned long dscr) 281254dae59SAnshuman Khandual { 282254dae59SAnshuman Khandual struct iovec iov; 283254dae59SAnshuman Khandual unsigned long *reg; 284254dae59SAnshuman Khandual int ret; 285254dae59SAnshuman Khandual 286254dae59SAnshuman Khandual reg = malloc(sizeof(unsigned long)); 287254dae59SAnshuman Khandual if (!reg) { 288254dae59SAnshuman Khandual perror("malloc() failed"); 289254dae59SAnshuman Khandual return TEST_FAIL; 290254dae59SAnshuman Khandual } 291254dae59SAnshuman Khandual 292254dae59SAnshuman Khandual iov.iov_base = (u64 *) reg; 293254dae59SAnshuman Khandual iov.iov_len = sizeof(unsigned long); 294254dae59SAnshuman Khandual 295254dae59SAnshuman Khandual *reg = tar; 296254dae59SAnshuman Khandual ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CTAR, &iov); 297254dae59SAnshuman Khandual if (ret) { 298254dae59SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 299254dae59SAnshuman Khandual goto fail; 300254dae59SAnshuman Khandual } 301254dae59SAnshuman Khandual 302254dae59SAnshuman Khandual *reg = ppr; 303254dae59SAnshuman Khandual ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CPPR, &iov); 304254dae59SAnshuman Khandual if (ret) { 305254dae59SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 306254dae59SAnshuman Khandual goto fail; 307254dae59SAnshuman Khandual } 308254dae59SAnshuman Khandual 309254dae59SAnshuman Khandual *reg = dscr; 310254dae59SAnshuman Khandual ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CDSCR, &iov); 311254dae59SAnshuman Khandual if (ret) { 312254dae59SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 313254dae59SAnshuman Khandual goto fail; 314254dae59SAnshuman Khandual } 315254dae59SAnshuman Khandual 316254dae59SAnshuman Khandual free(reg); 317254dae59SAnshuman Khandual return TEST_PASS; 318254dae59SAnshuman Khandual fail: 319254dae59SAnshuman Khandual free(reg); 320254dae59SAnshuman Khandual return TEST_FAIL; 321254dae59SAnshuman Khandual } 322254dae59SAnshuman Khandual 323f666ad41SAnshuman Khandual /* FPR */ 324*53fa86e7SMichael Ellerman int show_fpr(pid_t child, __u64 *fpr) 325f666ad41SAnshuman Khandual { 326f666ad41SAnshuman Khandual struct fpr_regs *regs; 327f666ad41SAnshuman Khandual int ret, i; 328f666ad41SAnshuman Khandual 329f666ad41SAnshuman Khandual regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs)); 330f666ad41SAnshuman Khandual ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs); 331f666ad41SAnshuman Khandual if (ret) { 332f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 333f666ad41SAnshuman Khandual return TEST_FAIL; 334f666ad41SAnshuman Khandual } 335f666ad41SAnshuman Khandual 336f666ad41SAnshuman Khandual if (fpr) { 337f666ad41SAnshuman Khandual for (i = 0; i < 32; i++) 338f666ad41SAnshuman Khandual fpr[i] = regs->fpr[i]; 339f666ad41SAnshuman Khandual } 340f666ad41SAnshuman Khandual return TEST_PASS; 341f666ad41SAnshuman Khandual } 342f666ad41SAnshuman Khandual 343*53fa86e7SMichael Ellerman int write_fpr(pid_t child, __u64 val) 344f666ad41SAnshuman Khandual { 345f666ad41SAnshuman Khandual struct fpr_regs *regs; 346f666ad41SAnshuman Khandual int ret, i; 347f666ad41SAnshuman Khandual 348f666ad41SAnshuman Khandual regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs)); 349f666ad41SAnshuman Khandual ret = ptrace(PTRACE_GETFPREGS, child, NULL, regs); 350f666ad41SAnshuman Khandual if (ret) { 351f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 352f666ad41SAnshuman Khandual return TEST_FAIL; 353f666ad41SAnshuman Khandual } 354f666ad41SAnshuman Khandual 355f666ad41SAnshuman Khandual for (i = 0; i < 32; i++) 356f666ad41SAnshuman Khandual regs->fpr[i] = val; 357f666ad41SAnshuman Khandual 358f666ad41SAnshuman Khandual ret = ptrace(PTRACE_SETFPREGS, child, NULL, regs); 359f666ad41SAnshuman Khandual if (ret) { 360f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 361f666ad41SAnshuman Khandual return TEST_FAIL; 362f666ad41SAnshuman Khandual } 363f666ad41SAnshuman Khandual return TEST_PASS; 364f666ad41SAnshuman Khandual } 365f666ad41SAnshuman Khandual 366*53fa86e7SMichael Ellerman int show_ckpt_fpr(pid_t child, __u64 *fpr) 367f666ad41SAnshuman Khandual { 368f666ad41SAnshuman Khandual struct fpr_regs *regs; 369f666ad41SAnshuman Khandual struct iovec iov; 370f666ad41SAnshuman Khandual int ret, i; 371f666ad41SAnshuman Khandual 372f666ad41SAnshuman Khandual regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs)); 373f666ad41SAnshuman Khandual iov.iov_base = regs; 374f666ad41SAnshuman Khandual iov.iov_len = sizeof(struct fpr_regs); 375f666ad41SAnshuman Khandual 376f666ad41SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov); 377f666ad41SAnshuman Khandual if (ret) { 378f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 379f666ad41SAnshuman Khandual return TEST_FAIL; 380f666ad41SAnshuman Khandual } 381f666ad41SAnshuman Khandual 382f666ad41SAnshuman Khandual if (fpr) { 383f666ad41SAnshuman Khandual for (i = 0; i < 32; i++) 384f666ad41SAnshuman Khandual fpr[i] = regs->fpr[i]; 385f666ad41SAnshuman Khandual } 386f666ad41SAnshuman Khandual 387f666ad41SAnshuman Khandual return TEST_PASS; 388f666ad41SAnshuman Khandual } 389f666ad41SAnshuman Khandual 390f666ad41SAnshuman Khandual int write_ckpt_fpr(pid_t child, unsigned long val) 391f666ad41SAnshuman Khandual { 392f666ad41SAnshuman Khandual struct fpr_regs *regs; 393f666ad41SAnshuman Khandual struct iovec iov; 394f666ad41SAnshuman Khandual int ret, i; 395f666ad41SAnshuman Khandual 396f666ad41SAnshuman Khandual regs = (struct fpr_regs *) malloc(sizeof(struct fpr_regs)); 397f666ad41SAnshuman Khandual iov.iov_base = regs; 398f666ad41SAnshuman Khandual iov.iov_len = sizeof(struct fpr_regs); 399f666ad41SAnshuman Khandual 400f666ad41SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CFPR, &iov); 401f666ad41SAnshuman Khandual if (ret) { 402f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 403f666ad41SAnshuman Khandual return TEST_FAIL; 404f666ad41SAnshuman Khandual } 405f666ad41SAnshuman Khandual 406f666ad41SAnshuman Khandual for (i = 0; i < 32; i++) 407f666ad41SAnshuman Khandual regs->fpr[i] = val; 408f666ad41SAnshuman Khandual 409f666ad41SAnshuman Khandual ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CFPR, &iov); 410f666ad41SAnshuman Khandual if (ret) { 411f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 412f666ad41SAnshuman Khandual return TEST_FAIL; 413f666ad41SAnshuman Khandual } 414f666ad41SAnshuman Khandual return TEST_PASS; 415f666ad41SAnshuman Khandual } 416f666ad41SAnshuman Khandual 417f666ad41SAnshuman Khandual /* GPR */ 418f666ad41SAnshuman Khandual int show_gpr(pid_t child, unsigned long *gpr) 419f666ad41SAnshuman Khandual { 420f666ad41SAnshuman Khandual struct pt_regs *regs; 421f666ad41SAnshuman Khandual int ret, i; 422f666ad41SAnshuman Khandual 423f666ad41SAnshuman Khandual regs = (struct pt_regs *) malloc(sizeof(struct pt_regs)); 424f666ad41SAnshuman Khandual if (!regs) { 425f666ad41SAnshuman Khandual perror("malloc() failed"); 426f666ad41SAnshuman Khandual return TEST_FAIL; 427f666ad41SAnshuman Khandual } 428f666ad41SAnshuman Khandual 429f666ad41SAnshuman Khandual ret = ptrace(PTRACE_GETREGS, child, NULL, regs); 430f666ad41SAnshuman Khandual if (ret) { 431f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 432f666ad41SAnshuman Khandual return TEST_FAIL; 433f666ad41SAnshuman Khandual } 434f666ad41SAnshuman Khandual 435f666ad41SAnshuman Khandual if (gpr) { 436f666ad41SAnshuman Khandual for (i = 14; i < 32; i++) 437f666ad41SAnshuman Khandual gpr[i-14] = regs->gpr[i]; 438f666ad41SAnshuman Khandual } 439f666ad41SAnshuman Khandual 440f666ad41SAnshuman Khandual return TEST_PASS; 441f666ad41SAnshuman Khandual } 442f666ad41SAnshuman Khandual 443f666ad41SAnshuman Khandual int write_gpr(pid_t child, unsigned long val) 444f666ad41SAnshuman Khandual { 445f666ad41SAnshuman Khandual struct pt_regs *regs; 446f666ad41SAnshuman Khandual int i, ret; 447f666ad41SAnshuman Khandual 448f666ad41SAnshuman Khandual regs = (struct pt_regs *) malloc(sizeof(struct pt_regs)); 449f666ad41SAnshuman Khandual if (!regs) { 450f666ad41SAnshuman Khandual perror("malloc() failed"); 451f666ad41SAnshuman Khandual return TEST_FAIL; 452f666ad41SAnshuman Khandual } 453f666ad41SAnshuman Khandual 454f666ad41SAnshuman Khandual ret = ptrace(PTRACE_GETREGS, child, NULL, regs); 455f666ad41SAnshuman Khandual if (ret) { 456f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 457f666ad41SAnshuman Khandual return TEST_FAIL; 458f666ad41SAnshuman Khandual } 459f666ad41SAnshuman Khandual 460f666ad41SAnshuman Khandual for (i = 14; i < 32; i++) 461f666ad41SAnshuman Khandual regs->gpr[i] = val; 462f666ad41SAnshuman Khandual 463f666ad41SAnshuman Khandual ret = ptrace(PTRACE_SETREGS, child, NULL, regs); 464f666ad41SAnshuman Khandual if (ret) { 465f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 466f666ad41SAnshuman Khandual return TEST_FAIL; 467f666ad41SAnshuman Khandual } 468f666ad41SAnshuman Khandual return TEST_PASS; 469f666ad41SAnshuman Khandual } 470f666ad41SAnshuman Khandual 471f666ad41SAnshuman Khandual int show_ckpt_gpr(pid_t child, unsigned long *gpr) 472f666ad41SAnshuman Khandual { 473f666ad41SAnshuman Khandual struct pt_regs *regs; 474f666ad41SAnshuman Khandual struct iovec iov; 475f666ad41SAnshuman Khandual int ret, i; 476f666ad41SAnshuman Khandual 477f666ad41SAnshuman Khandual regs = (struct pt_regs *) malloc(sizeof(struct pt_regs)); 478f666ad41SAnshuman Khandual if (!regs) { 479f666ad41SAnshuman Khandual perror("malloc() failed"); 480f666ad41SAnshuman Khandual return TEST_FAIL; 481f666ad41SAnshuman Khandual } 482f666ad41SAnshuman Khandual 483f666ad41SAnshuman Khandual iov.iov_base = (u64 *) regs; 484f666ad41SAnshuman Khandual iov.iov_len = sizeof(struct pt_regs); 485f666ad41SAnshuman Khandual 486f666ad41SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov); 487f666ad41SAnshuman Khandual if (ret) { 488f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 489f666ad41SAnshuman Khandual return TEST_FAIL; 490f666ad41SAnshuman Khandual } 491f666ad41SAnshuman Khandual 492f666ad41SAnshuman Khandual if (gpr) { 493f666ad41SAnshuman Khandual for (i = 14; i < 32; i++) 494f666ad41SAnshuman Khandual gpr[i-14] = regs->gpr[i]; 495f666ad41SAnshuman Khandual } 496f666ad41SAnshuman Khandual 497f666ad41SAnshuman Khandual return TEST_PASS; 498f666ad41SAnshuman Khandual } 499f666ad41SAnshuman Khandual 500f666ad41SAnshuman Khandual int write_ckpt_gpr(pid_t child, unsigned long val) 501f666ad41SAnshuman Khandual { 502f666ad41SAnshuman Khandual struct pt_regs *regs; 503f666ad41SAnshuman Khandual struct iovec iov; 504f666ad41SAnshuman Khandual int ret, i; 505f666ad41SAnshuman Khandual 506f666ad41SAnshuman Khandual regs = (struct pt_regs *) malloc(sizeof(struct pt_regs)); 507f666ad41SAnshuman Khandual if (!regs) { 508f666ad41SAnshuman Khandual perror("malloc() failed\n"); 509f666ad41SAnshuman Khandual return TEST_FAIL; 510f666ad41SAnshuman Khandual } 511f666ad41SAnshuman Khandual iov.iov_base = (u64 *) regs; 512f666ad41SAnshuman Khandual iov.iov_len = sizeof(struct pt_regs); 513f666ad41SAnshuman Khandual 514f666ad41SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CGPR, &iov); 515f666ad41SAnshuman Khandual if (ret) { 516f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 517f666ad41SAnshuman Khandual return TEST_FAIL; 518f666ad41SAnshuman Khandual } 519f666ad41SAnshuman Khandual 520f666ad41SAnshuman Khandual for (i = 14; i < 32; i++) 521f666ad41SAnshuman Khandual regs->gpr[i] = val; 522f666ad41SAnshuman Khandual 523f666ad41SAnshuman Khandual ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CGPR, &iov); 524f666ad41SAnshuman Khandual if (ret) { 525f666ad41SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 526f666ad41SAnshuman Khandual return TEST_FAIL; 527f666ad41SAnshuman Khandual } 528f666ad41SAnshuman Khandual return TEST_PASS; 529f666ad41SAnshuman Khandual } 530f666ad41SAnshuman Khandual 5310da535c0SAnshuman Khandual /* VMX */ 5320da535c0SAnshuman Khandual int show_vmx(pid_t child, unsigned long vmx[][2]) 5330da535c0SAnshuman Khandual { 5340da535c0SAnshuman Khandual int ret; 5350da535c0SAnshuman Khandual 5360da535c0SAnshuman Khandual ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx); 5370da535c0SAnshuman Khandual if (ret) { 5380da535c0SAnshuman Khandual perror("ptrace(PTRACE_GETVRREGS) failed"); 5390da535c0SAnshuman Khandual return TEST_FAIL; 5400da535c0SAnshuman Khandual } 5410da535c0SAnshuman Khandual return TEST_PASS; 5420da535c0SAnshuman Khandual } 5430da535c0SAnshuman Khandual 5440da535c0SAnshuman Khandual int show_vmx_ckpt(pid_t child, unsigned long vmx[][2]) 5450da535c0SAnshuman Khandual { 5460da535c0SAnshuman Khandual unsigned long regs[34][2]; 5470da535c0SAnshuman Khandual struct iovec iov; 5480da535c0SAnshuman Khandual int ret; 5490da535c0SAnshuman Khandual 5500da535c0SAnshuman Khandual iov.iov_base = (u64 *) regs; 5510da535c0SAnshuman Khandual iov.iov_len = sizeof(regs); 5520da535c0SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov); 5530da535c0SAnshuman Khandual if (ret) { 5540da535c0SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed"); 5550da535c0SAnshuman Khandual return TEST_FAIL; 5560da535c0SAnshuman Khandual } 5570da535c0SAnshuman Khandual memcpy(vmx, regs, sizeof(regs)); 5580da535c0SAnshuman Khandual return TEST_PASS; 5590da535c0SAnshuman Khandual } 5600da535c0SAnshuman Khandual 5610da535c0SAnshuman Khandual 5620da535c0SAnshuman Khandual int write_vmx(pid_t child, unsigned long vmx[][2]) 5630da535c0SAnshuman Khandual { 5640da535c0SAnshuman Khandual int ret; 5650da535c0SAnshuman Khandual 5660da535c0SAnshuman Khandual ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx); 5670da535c0SAnshuman Khandual if (ret) { 5680da535c0SAnshuman Khandual perror("ptrace(PTRACE_SETVRREGS) failed"); 5690da535c0SAnshuman Khandual return TEST_FAIL; 5700da535c0SAnshuman Khandual } 5710da535c0SAnshuman Khandual return TEST_PASS; 5720da535c0SAnshuman Khandual } 5730da535c0SAnshuman Khandual 5740da535c0SAnshuman Khandual int write_vmx_ckpt(pid_t child, unsigned long vmx[][2]) 5750da535c0SAnshuman Khandual { 5760da535c0SAnshuman Khandual unsigned long regs[34][2]; 5770da535c0SAnshuman Khandual struct iovec iov; 5780da535c0SAnshuman Khandual int ret; 5790da535c0SAnshuman Khandual 5800da535c0SAnshuman Khandual memcpy(regs, vmx, sizeof(regs)); 5810da535c0SAnshuman Khandual iov.iov_base = (u64 *) regs; 5820da535c0SAnshuman Khandual iov.iov_len = sizeof(regs); 5830da535c0SAnshuman Khandual ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVMX, &iov); 5840da535c0SAnshuman Khandual if (ret) { 5850da535c0SAnshuman Khandual perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed"); 5860da535c0SAnshuman Khandual return TEST_FAIL; 5870da535c0SAnshuman Khandual } 5880da535c0SAnshuman Khandual return TEST_PASS; 5890da535c0SAnshuman Khandual } 5900da535c0SAnshuman Khandual 5910da535c0SAnshuman Khandual /* VSX */ 5920da535c0SAnshuman Khandual int show_vsx(pid_t child, unsigned long *vsx) 5930da535c0SAnshuman Khandual { 5940da535c0SAnshuman Khandual int ret; 5950da535c0SAnshuman Khandual 5960da535c0SAnshuman Khandual ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx); 5970da535c0SAnshuman Khandual if (ret) { 5980da535c0SAnshuman Khandual perror("ptrace(PTRACE_GETVSRREGS) failed"); 5990da535c0SAnshuman Khandual return TEST_FAIL; 6000da535c0SAnshuman Khandual } 6010da535c0SAnshuman Khandual return TEST_PASS; 6020da535c0SAnshuman Khandual } 6030da535c0SAnshuman Khandual 6040da535c0SAnshuman Khandual int show_vsx_ckpt(pid_t child, unsigned long *vsx) 6050da535c0SAnshuman Khandual { 6060da535c0SAnshuman Khandual unsigned long regs[32]; 6070da535c0SAnshuman Khandual struct iovec iov; 6080da535c0SAnshuman Khandual int ret; 6090da535c0SAnshuman Khandual 6100da535c0SAnshuman Khandual iov.iov_base = (u64 *) regs; 6110da535c0SAnshuman Khandual iov.iov_len = sizeof(regs); 6120da535c0SAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov); 6130da535c0SAnshuman Khandual if (ret) { 6140da535c0SAnshuman Khandual perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed"); 6150da535c0SAnshuman Khandual return TEST_FAIL; 6160da535c0SAnshuman Khandual } 6170da535c0SAnshuman Khandual memcpy(vsx, regs, sizeof(regs)); 6180da535c0SAnshuman Khandual return TEST_PASS; 6190da535c0SAnshuman Khandual } 6200da535c0SAnshuman Khandual 6210da535c0SAnshuman Khandual int write_vsx(pid_t child, unsigned long *vsx) 6220da535c0SAnshuman Khandual { 6230da535c0SAnshuman Khandual int ret; 6240da535c0SAnshuman Khandual 6250da535c0SAnshuman Khandual ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx); 6260da535c0SAnshuman Khandual if (ret) { 6270da535c0SAnshuman Khandual perror("ptrace(PTRACE_SETVSRREGS) failed"); 6280da535c0SAnshuman Khandual return TEST_FAIL; 6290da535c0SAnshuman Khandual } 6300da535c0SAnshuman Khandual return TEST_PASS; 6310da535c0SAnshuman Khandual } 6320da535c0SAnshuman Khandual 6330da535c0SAnshuman Khandual int write_vsx_ckpt(pid_t child, unsigned long *vsx) 6340da535c0SAnshuman Khandual { 6350da535c0SAnshuman Khandual unsigned long regs[32]; 6360da535c0SAnshuman Khandual struct iovec iov; 6370da535c0SAnshuman Khandual int ret; 6380da535c0SAnshuman Khandual 6390da535c0SAnshuman Khandual memcpy(regs, vsx, sizeof(regs)); 6400da535c0SAnshuman Khandual iov.iov_base = (u64 *) regs; 6410da535c0SAnshuman Khandual iov.iov_len = sizeof(regs); 6420da535c0SAnshuman Khandual ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVSX, &iov); 6430da535c0SAnshuman Khandual if (ret) { 6440da535c0SAnshuman Khandual perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed"); 6450da535c0SAnshuman Khandual return TEST_FAIL; 6460da535c0SAnshuman Khandual } 6470da535c0SAnshuman Khandual return TEST_PASS; 6480da535c0SAnshuman Khandual } 6490da535c0SAnshuman Khandual 6505bdac52fSAnshuman Khandual /* TM SPR */ 6515bdac52fSAnshuman Khandual int show_tm_spr(pid_t child, struct tm_spr_regs *out) 6525bdac52fSAnshuman Khandual { 6535bdac52fSAnshuman Khandual struct tm_spr_regs *regs; 6545bdac52fSAnshuman Khandual struct iovec iov; 6555bdac52fSAnshuman Khandual int ret; 6565bdac52fSAnshuman Khandual 6575bdac52fSAnshuman Khandual regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs)); 6585bdac52fSAnshuman Khandual if (!regs) { 6595bdac52fSAnshuman Khandual perror("malloc() failed"); 6605bdac52fSAnshuman Khandual return TEST_FAIL; 6615bdac52fSAnshuman Khandual } 6625bdac52fSAnshuman Khandual 6635bdac52fSAnshuman Khandual iov.iov_base = (u64 *) regs; 6645bdac52fSAnshuman Khandual iov.iov_len = sizeof(struct tm_spr_regs); 6655bdac52fSAnshuman Khandual 6665bdac52fSAnshuman Khandual ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov); 6675bdac52fSAnshuman Khandual if (ret) { 6685bdac52fSAnshuman Khandual perror("ptrace(PTRACE_GETREGSET) failed"); 6695bdac52fSAnshuman Khandual return TEST_FAIL; 6705bdac52fSAnshuman Khandual } 6715bdac52fSAnshuman Khandual 6725bdac52fSAnshuman Khandual if (out) 6735bdac52fSAnshuman Khandual memcpy(out, regs, sizeof(struct tm_spr_regs)); 6745bdac52fSAnshuman Khandual 6755bdac52fSAnshuman Khandual return TEST_PASS; 6765bdac52fSAnshuman Khandual } 6775bdac52fSAnshuman Khandual 6785bdac52fSAnshuman Khandual 6795bdac52fSAnshuman Khandual 680f666ad41SAnshuman Khandual /* Analyse TEXASR after TM failure */ 681f666ad41SAnshuman Khandual inline unsigned long get_tfiar(void) 682f666ad41SAnshuman Khandual { 683f666ad41SAnshuman Khandual unsigned long ret; 684f666ad41SAnshuman Khandual 685f666ad41SAnshuman Khandual asm volatile("mfspr %0,%1" : "=r" (ret) : "i" (SPRN_TFIAR)); 686f666ad41SAnshuman Khandual return ret; 687f666ad41SAnshuman Khandual } 688f666ad41SAnshuman Khandual 689f666ad41SAnshuman Khandual void analyse_texasr(unsigned long texasr) 690f666ad41SAnshuman Khandual { 691f666ad41SAnshuman Khandual printf("TEXASR: %16lx\t", texasr); 692f666ad41SAnshuman Khandual 693f666ad41SAnshuman Khandual if (texasr & TEXASR_FP) 694f666ad41SAnshuman Khandual printf("TEXASR_FP "); 695f666ad41SAnshuman Khandual 696f666ad41SAnshuman Khandual if (texasr & TEXASR_DA) 697f666ad41SAnshuman Khandual printf("TEXASR_DA "); 698f666ad41SAnshuman Khandual 699f666ad41SAnshuman Khandual if (texasr & TEXASR_NO) 700f666ad41SAnshuman Khandual printf("TEXASR_NO "); 701f666ad41SAnshuman Khandual 702f666ad41SAnshuman Khandual if (texasr & TEXASR_FO) 703f666ad41SAnshuman Khandual printf("TEXASR_FO "); 704f666ad41SAnshuman Khandual 705f666ad41SAnshuman Khandual if (texasr & TEXASR_SIC) 706f666ad41SAnshuman Khandual printf("TEXASR_SIC "); 707f666ad41SAnshuman Khandual 708f666ad41SAnshuman Khandual if (texasr & TEXASR_NTC) 709f666ad41SAnshuman Khandual printf("TEXASR_NTC "); 710f666ad41SAnshuman Khandual 711f666ad41SAnshuman Khandual if (texasr & TEXASR_TC) 712f666ad41SAnshuman Khandual printf("TEXASR_TC "); 713f666ad41SAnshuman Khandual 714f666ad41SAnshuman Khandual if (texasr & TEXASR_TIC) 715f666ad41SAnshuman Khandual printf("TEXASR_TIC "); 716f666ad41SAnshuman Khandual 717f666ad41SAnshuman Khandual if (texasr & TEXASR_IC) 718f666ad41SAnshuman Khandual printf("TEXASR_IC "); 719f666ad41SAnshuman Khandual 720f666ad41SAnshuman Khandual if (texasr & TEXASR_IFC) 721f666ad41SAnshuman Khandual printf("TEXASR_IFC "); 722f666ad41SAnshuman Khandual 723f666ad41SAnshuman Khandual if (texasr & TEXASR_ABT) 724f666ad41SAnshuman Khandual printf("TEXASR_ABT "); 725f666ad41SAnshuman Khandual 726f666ad41SAnshuman Khandual if (texasr & TEXASR_SPD) 727f666ad41SAnshuman Khandual printf("TEXASR_SPD "); 728f666ad41SAnshuman Khandual 729f666ad41SAnshuman Khandual if (texasr & TEXASR_HV) 730f666ad41SAnshuman Khandual printf("TEXASR_HV "); 731f666ad41SAnshuman Khandual 732f666ad41SAnshuman Khandual if (texasr & TEXASR_PR) 733f666ad41SAnshuman Khandual printf("TEXASR_PR "); 734f666ad41SAnshuman Khandual 735f666ad41SAnshuman Khandual if (texasr & TEXASR_FS) 736f666ad41SAnshuman Khandual printf("TEXASR_FS "); 737f666ad41SAnshuman Khandual 738f666ad41SAnshuman Khandual if (texasr & TEXASR_TE) 739f666ad41SAnshuman Khandual printf("TEXASR_TE "); 740f666ad41SAnshuman Khandual 741f666ad41SAnshuman Khandual if (texasr & TEXASR_ROT) 742f666ad41SAnshuman Khandual printf("TEXASR_ROT "); 743f666ad41SAnshuman Khandual 744f666ad41SAnshuman Khandual printf("TFIAR :%lx\n", get_tfiar()); 745f666ad41SAnshuman Khandual } 746f666ad41SAnshuman Khandual 747f666ad41SAnshuman Khandual void store_gpr(unsigned long *addr); 748