Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1509082 > unrolled thread
| Started by | wei.guo.simon@gmail.com |
|---|---|
| First post | 2016-10-26 13:20 +0200 |
| Last post | 2016-10-26 13:20 +0200 |
| Articles | 6 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH v16 00/15] selftests/powerpc: Add ptrace tests for ppc registers wei.guo.simon@gmail.com - 2016-10-26 13:20 +0200
[PATCH v16 13/15] selftests/powerpc: Add ptrace tests for TM SPR registers wei.guo.simon@gmail.com - 2016-10-26 13:20 +0200
[PATCH v16 03/15] selftests/powerpc: Add ptrace tests for EBB wei.guo.simon@gmail.com - 2016-10-26 13:20 +0200
[PATCH v16 01/15] selftests/powerpc: Add more SPR numbers, TM & VMX instructions to 'reg.h'/'instructions.h' wei.guo.simon@gmail.com - 2016-10-26 13:20 +0200
[PATCH v16 10/15] selftests/powerpc: Add ptrace tests for VSX, VMX registers wei.guo.simon@gmail.com - 2016-10-26 13:20 +0200
[PATCH v16 08/15] selftests/powerpc: Add ptrace tests for TAR, PPR, DSCR in TM wei.guo.simon@gmail.com - 2016-10-26 13:20 +0200
| From | wei.guo.simon@gmail.com |
|---|---|
| Date | 2016-10-26 13:20 +0200 |
| Subject | [PATCH v16 00/15] selftests/powerpc: Add ptrace tests for ppc registers |
| Message-ID | <swupr-2Sj-5@gated-at.bofh.it> |
From: Simon Guo <wei.guo.simon@gmail.com>
This selftest suite is for PPC register ptrace functionality. It
is also useful for Transaction Memory functionality verification.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
Signed-off-by: Simon Guo <wei.guo.simon@gmail.com>
Test Result (All tests pass on both BE and LE)
----------------------------------------------
ptrace-ebb PASS
ptrace-gpr PASS
ptrace-tm-gpr PASS
ptrace-tm-spd-gpr PASS
ptrace-tar PASS
ptrace-tm-tar PASS
ptrace-tm-spd-tar PASS
ptrace-vsx PASS
ptrace-tm-vsx PASS
ptrace-tm-spd-vsx PASS
ptrace-tm-spr PASS
Previous versions:
==================
RFC: https://lkml.org/lkml/2014/4/1/292
V1: https://lkml.org/lkml/2014/4/2/43
V2: https://lkml.org/lkml/2014/5/5/88
V3: https://lkml.org/lkml/2014/5/23/486
V4: https://lkml.org/lkml/2014/11/11/6
V5: https://lkml.org/lkml/2014/11/25/134
V6: https://lkml.org/lkml/2014/12/2/98
V7: https://lkml.org/lkml/2015/1/14/19
V8: https://lkml.org/lkml/2015/5/19/700
V9: https://lkml.org/lkml/2015/10/8/522
V10: https://lkml.org/lkml/2016/2/16/219
V11: https://lkml.org/lkml/2016/7/16/231
V12: https://lkml.org/lkml/2016/7/27/134
V13: https://lkml.org/lkml/2016/7/27/656
V14: https://lkml.org/lkml/2016/9/12/57
V15: https://lkml.org/lkml/2016/9/29/722
Changes in V16:
---------------
- Correct expected SIER value in HV mode.
- rebased to latest ppc tree.
Changes in V15:
---------------
- Squash patch 1 and 2 to avoid compile error after patch 1.
- Reorganize some code across patch 3 and 4 to avoid compile error
- Created a new directory utility under tools/testing/selftesting/powerpc
to organize common APIs across selftests.
- Use "tbegin." instead of TBEGIN macro. The same for other TM instructions.
- Correct while(ptr); loop without memory barrier.
- Remove an invalid checking on TEXASR in tm-spd-spr.c.
- Use FAIL_IF() as possible to indicate failure line conveniently.
- Consolidate some asm code on GPR/FPR load/save into reg.h/reg.S
- rebased to recent ppc git tree.
Changes in V14:
---------------
- Remove duplicated NT_PPC_xxx register macro in
tools/testing/selftests/powerpc/ptrace/ptrace.h
- Clean some coding style warning
Changes in V13:
---------------
- Remove Cc lines from changelog
- Add more Signed-off-by lines of Simon Guo
Changes in V12:
---------------
- Revert change which is trying to incoporate following patch:
[PATCH 3/5] powerpc: tm: Always use fp_state and vr_state to store live registers
- Release share memory resource in all self test cases
- Optimize tfhar usage in ptrace-tm-spr.c
Changes in V11:
---------------
- Rework based on following patch:
[PATCH 3/5] powerpc: tm: Always use fp_state and vr_state to store live registers
- Split EBB/PMU register ptrace implementation.
- Clean some coding style warning
- Added more shared memory based sync between parent and child during TM tests
- Re worded some of the commit messages and cleaned them up
- selftests/powerpc/ebb/reg.h has already moved as selftests/powerpc/reg.h
Dropped the previous patch doing the same thing
- Combined the definitions of SPRN_DSCR from dscr/ test cases
- Fixed dscr/ test cases for new SPRN_DSCR_PRIV definition available
Changes in V10:
---------------
- Rebased against the latest mainline
- Fixed couple of build failures in the test cases related to aux vector
Changes in V9:
--------------
- Fixed static build check failure after tm_orig_msr got dropped
- Fixed asm volatile construct for used registers set
- Fixed EBB, VSX, VMX tests for LE
- Fixed TAR test which was failing because of system calls
- Added checks for PPC_FEATURE2_HTM aux feature in the tests
- Fixed copyright statements
Changes in V8:
--------------
- Split the misc register set into individual ELF core notes
- Implemented support for VSX register set (on and off TM)
- Implemented support for EBB register set
- Implemented review comments on previous versions
- Some code re-arrangements, re-writes and documentation
- Added comprehensive list of test cases into selftests
Changes in V7:
--------------
- Fixed a config directive in the MISC code
- Merged the two gitignore patches into a single one
Changes in V6:
--------------
- Added two git ignore patches for powerpc selftests
- Re-formatted all in-code function definitions in kernel-doc format
Changes in V5:
--------------
- Changed flush_tmregs_to_thread, so not to take into account self tracing
- Dropped the 3rd patch in the series which had merged two functions
- Fixed one build problem for the misc debug register patch
- Accommodated almost all the review comments from Suka on the 6th patch
- Minor changes to the self test program
- Changed commit messages for some of the patches
Changes in V4:
--------------
- Added one test program into the powerpc selftest bucket in this regard
- Split the 2nd patch in the previous series into four different patches
- Accommodated most of the review comments on the previous patch series
- Added a patch to merge functions __switch_to_tm and tm_reclaim_task
Changes in V3:
--------------
- Added two new error paths in every TM related get/set functions when regset
support is not present on the system (ENODEV) or when the process does not
have any transaction active (ENODATA) in the context
- Installed the active hooks for all the newly added regset core note
types
Changes in V2:
--------------
- Removed all the power specific ptrace requests corresponding to new
NT_PPC_*
elf core note types. Now all the register sets can be accessed from
ptrace
through PTRACE_GETREGSET/PTRACE_SETREGSET using the individual
NT_PPC* core
note type instead
- Fixed couple of attribute values for REGSET_TM_CGPR register set
- Renamed flush_tmreg_to_thread as flush_tmregs_to_thread
- Fixed 32 bit checkpointed GPR support
- Changed commit messages accordingly
-------------
Anshuman Khandual (14):
selftests/powerpc: Add more SPR numbers, TM & VMX instructions to
'reg.h'/'instructions.h'
selftests/powerpc: Add ptrace tests for EBB
selftests/powerpc: Add ptrace tests for GPR/FPR registers
selftests/powerpc: Add ptrace tests for GPR/FPR registers in TM
selftests/powerpc: Add ptrace tests for GPR/FPR registers in suspended
TM
selftests/powerpc: Add ptrace tests for TAR, PPR, DSCR registers
selftests/powerpc: Add ptrace tests for TAR, PPR, DSCR in TM
selftests/powerpc: Add ptrace tests for TAR, PPR, DSCR in suspended TM
selftests/powerpc: Add ptrace tests for VSX, VMX registers
selftests/powerpc: Add ptrace tests for VSX, VMX registers in TM
selftests/powerpc: Add ptrace tests for VSX, VMX registers in
suspended TM
selftests/powerpc: Add ptrace tests for TM SPR registers
selftests/powerpc: Add .gitignore file for ptrace executables
selftests/powerpc: Fix a build issue
Simon Guo (1):
selftests/powerpc: move shared utility files into new utility/ dir
tools/testing/selftests/powerpc/Makefile | 5 +-
tools/testing/selftests/powerpc/alignment/Makefile | 2 +-
tools/testing/selftests/powerpc/basic_asm.h | 70 --
.../testing/selftests/powerpc/benchmarks/Makefile | 2 +-
.../selftests/powerpc/benchmarks/context_switch.c | 2 +-
.../selftests/powerpc/context_switch/Makefile | 2 +-
.../selftests/powerpc/context_switch/cp_abort.c | 6 +-
.../testing/selftests/powerpc/copyloops/validate.c | 2 +-
tools/testing/selftests/powerpc/dscr/dscr.h | 10 +-
tools/testing/selftests/powerpc/fpu_asm.h | 80 ---
tools/testing/selftests/powerpc/gpr_asm.h | 96 ---
tools/testing/selftests/powerpc/instructions.h | 68 --
tools/testing/selftests/powerpc/math/fpu_asm.S | 4 +-
tools/testing/selftests/powerpc/math/vmx_asm.S | 4 +-
tools/testing/selftests/powerpc/math/vsx_asm.S | 4 +-
tools/testing/selftests/powerpc/mm/Makefile | 2 +-
tools/testing/selftests/powerpc/pmu/Makefile | 4 +-
tools/testing/selftests/powerpc/pmu/ebb/Makefile | 2 +-
tools/testing/selftests/powerpc/ptrace/.gitignore | 11 +
tools/testing/selftests/powerpc/ptrace/Makefile | 14 +
.../testing/selftests/powerpc/ptrace/ptrace-ebb.c | 188 +++++
.../testing/selftests/powerpc/ptrace/ptrace-ebb.h | 100 +++
.../testing/selftests/powerpc/ptrace/ptrace-gpr.c | 123 ++++
.../testing/selftests/powerpc/ptrace/ptrace-gpr.h | 74 ++
.../testing/selftests/powerpc/ptrace/ptrace-tar.c | 135 ++++
.../testing/selftests/powerpc/ptrace/ptrace-tar.h | 50 ++
.../selftests/powerpc/ptrace/ptrace-tm-gpr.c | 158 +++++
.../selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c | 169 +++++
.../selftests/powerpc/ptrace/ptrace-tm-spd-tar.c | 174 +++++
.../selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c | 185 +++++
.../selftests/powerpc/ptrace/ptrace-tm-spr.c | 168 +++++
.../selftests/powerpc/ptrace/ptrace-tm-tar.c | 160 +++++
.../selftests/powerpc/ptrace/ptrace-tm-vsx.c | 168 +++++
.../testing/selftests/powerpc/ptrace/ptrace-vsx.c | 117 ++++
.../testing/selftests/powerpc/ptrace/ptrace-vsx.h | 127 ++++
tools/testing/selftests/powerpc/ptrace/ptrace.h | 771 +++++++++++++++++++++
tools/testing/selftests/powerpc/reg.h | 60 --
tools/testing/selftests/powerpc/signal/Makefile | 2 +-
tools/testing/selftests/powerpc/signal/signal.S | 2 +-
.../testing/selftests/powerpc/stringloops/memcmp.c | 2 +-
tools/testing/selftests/powerpc/tm/Makefile | 2 +-
tools/testing/selftests/powerpc/tm/tm-signal.S | 10 +-
tools/testing/selftests/powerpc/tm/tm.h | 2 +-
.../testing/selftests/powerpc/utility/basic_asm.h | 73 ++
tools/testing/selftests/powerpc/utility/fpu_asm.h | 80 +++
tools/testing/selftests/powerpc/utility/gpr_asm.h | 96 +++
.../selftests/powerpc/utility/instructions.h | 68 ++
tools/testing/selftests/powerpc/utility/reg.S | 397 +++++++++++
tools/testing/selftests/powerpc/utility/reg.h | 150 ++++
tools/testing/selftests/powerpc/utility/utils.c | 87 +++
tools/testing/selftests/powerpc/utility/utils.h | 77 ++
tools/testing/selftests/powerpc/utility/vmx_asm.h | 96 +++
tools/testing/selftests/powerpc/utility/vsx_asm.h | 71 ++
tools/testing/selftests/powerpc/utils.c | 87 ---
tools/testing/selftests/powerpc/utils.h | 77 --
tools/testing/selftests/powerpc/vmx_asm.h | 96 ---
tools/testing/selftests/powerpc/vsx_asm.h | 71 --
57 files changed, 4122 insertions(+), 741 deletions(-)
delete mode 100644 tools/testing/selftests/powerpc/basic_asm.h
delete mode 100644 tools/testing/selftests/powerpc/fpu_asm.h
delete mode 100644 tools/testing/selftests/powerpc/gpr_asm.h
delete mode 100644 tools/testing/selftests/powerpc/instructions.h
create mode 100644 tools/testing/selftests/powerpc/ptrace/.gitignore
create mode 100644 tools/testing/selftests/powerpc/ptrace/Makefile
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-ebb.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-ebb.h
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-gpr.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-gpr.h
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tar.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tar.h
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-gpr.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-tar.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-vsx.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-vsx.h
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace.h
delete mode 100644 tools/testing/selftests/powerpc/reg.h
create mode 100644 tools/testing/selftests/powerpc/utility/basic_asm.h
create mode 100644 tools/testing/selftests/powerpc/utility/fpu_asm.h
create mode 100644 tools/testing/selftests/powerpc/utility/gpr_asm.h
create mode 100644 tools/testing/selftests/powerpc/utility/instructions.h
create mode 100644 tools/testing/selftests/powerpc/utility/reg.S
create mode 100644 tools/testing/selftests/powerpc/utility/reg.h
create mode 100644 tools/testing/selftests/powerpc/utility/utils.c
create mode 100644 tools/testing/selftests/powerpc/utility/utils.h
create mode 100644 tools/testing/selftests/powerpc/utility/vmx_asm.h
create mode 100644 tools/testing/selftests/powerpc/utility/vsx_asm.h
delete mode 100644 tools/testing/selftests/powerpc/utils.c
delete mode 100644 tools/testing/selftests/powerpc/utils.h
delete mode 100644 tools/testing/selftests/powerpc/vmx_asm.h
delete mode 100644 tools/testing/selftests/powerpc/vsx_asm.h
--
1.8.3.1
[toc] | [next] | [standalone]
| From | wei.guo.simon@gmail.com |
|---|---|
| Date | 2016-10-26 13:20 +0200 |
| Subject | [PATCH v16 13/15] selftests/powerpc: Add ptrace tests for TM SPR registers |
| Message-ID | <swups-2Sj-47@gated-at.bofh.it> |
| In reply to | #1509082 |
From: Anshuman Khandual <khandual@linux.vnet.ibm.com>
This patch adds ptrace interface test for TM SPR registers. This
also adds ptrace interface based helper functions related to TM
SPR registers access.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
Signed-off-by: Simon Guo <wei.guo.simon@gmail.com>
---
tools/testing/selftests/powerpc/ptrace/Makefile | 3 +-
.../selftests/powerpc/ptrace/ptrace-tm-spr.c | 168 +++++++++++++++++++++
tools/testing/selftests/powerpc/ptrace/ptrace.h | 35 +++++
3 files changed, 204 insertions(+), 2 deletions(-)
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c
diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile b/tools/testing/selftests/powerpc/ptrace/Makefile
index b5b097a..ec2a9b0 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,7 +1,6 @@
TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx ptrace-tm-vsx \
-ptrace-tm-spd-vsx
-
+ptrace-tm-spd-vsx ptrace-tm-spr
include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c
new file mode 100644
index 0000000..94e57cb
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c
@@ -0,0 +1,168 @@
+/*
+ * Ptrace test TM SPR registers
+ *
+ * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "ptrace.h"
+#include "tm.h"
+
+/* Tracee and tracer shared data */
+struct shared {
+ int flag;
+ struct tm_spr_regs regs;
+};
+unsigned long tfhar;
+
+int shm_id;
+struct shared *cptr, *pptr;
+
+int shm_id1;
+int *cptr1, *pptr1;
+
+#define TM_KVM_SCHED 0xe0000001ac000001
+int validate_tm_spr(struct tm_spr_regs *regs)
+{
+ FAIL_IF(regs->tm_tfhar != tfhar);
+ FAIL_IF((regs->tm_texasr == TM_KVM_SCHED) && (regs->tm_tfiar != 0));
+
+ return TEST_PASS;
+}
+
+void tm_spr(void)
+{
+ unsigned long result, texasr;
+ int ret;
+
+ cptr = (struct shared *)shmat(shm_id, NULL, 0);
+ cptr1 = (int *)shmat(shm_id1, NULL, 0);
+
+trans:
+ cptr1[0] = 0;
+ asm __volatile__(
+ "1: ;"
+ /* TM failover handler should follow "tbegin.;" */
+ "mflr 31;"
+ "bl 4f;" /* $ = TFHAR - 12 */
+ "4: ;"
+ "mflr %[tfhar];"
+ "mtlr 31;"
+
+ "tbegin.;"
+ "beq 2f;"
+
+ "tsuspend.;"
+ "li 8, 1;"
+ "sth 8, 0(%[cptr1]);"
+ "tresume.;"
+ "b .;"
+
+ "tend.;"
+ "li 0, 0;"
+ "ori %[res], 0, 0;"
+ "b 3f;"
+
+ "2: ;"
+
+ "li 0, 1;"
+ "ori %[res], 0, 0;"
+ "mfspr %[texasr], %[sprn_texasr];"
+
+ "3: ;"
+ : [tfhar] "=r" (tfhar), [res] "=r" (result),
+ [texasr] "=r" (texasr), [cptr1] "=r" (cptr1)
+ : [sprn_texasr] "i" (SPRN_TEXASR)
+ : "memory", "r0", "r1", "r2", "r3", "r4",
+ "r8", "r9", "r10", "r11", "r31"
+ );
+
+ /* There are 2 32bit instructions before tbegin. */
+ tfhar += 12;
+
+ if (result) {
+ if (!cptr->flag)
+ goto trans;
+
+ ret = validate_tm_spr((struct tm_spr_regs *)&cptr->regs);
+ shmdt((void *)cptr);
+ shmdt((void *)cptr1);
+ if (ret)
+ exit(1);
+ exit(0);
+ }
+ shmdt((void *)cptr);
+ shmdt((void *)cptr1);
+ exit(1);
+}
+
+int trace_tm_spr(pid_t child)
+{
+ FAIL_IF(start_trace(child));
+ FAIL_IF(show_tm_spr(child, (struct tm_spr_regs *)&pptr->regs));
+
+ printf("TFHAR: %lx TEXASR: %lx TFIAR: %lx\n", pptr->regs.tm_tfhar,
+ pptr->regs.tm_texasr, pptr->regs.tm_tfiar);
+
+ pptr->flag = 1;
+ FAIL_IF(stop_trace(child));
+
+ return TEST_PASS;
+}
+
+int ptrace_tm_spr(void)
+{
+ pid_t pid;
+ int ret, status;
+
+ SKIP_IF(!have_htm());
+ shm_id = shmget(IPC_PRIVATE, sizeof(struct shared), 0777|IPC_CREAT);
+ shm_id1 = shmget(IPC_PRIVATE, sizeof(int), 0777|IPC_CREAT);
+ pid = fork();
+ if (pid < 0) {
+ perror("fork() failed");
+ return TEST_FAIL;
+ }
+
+ if (pid == 0)
+ tm_spr();
+
+ if (pid) {
+ pptr = (struct shared *)shmat(shm_id, NULL, 0);
+ pptr1 = (int *)shmat(shm_id1, NULL, 0);
+
+ while (!pptr1[0])
+ asm volatile("" : : : "memory");
+ ret = trace_tm_spr(pid);
+ if (ret) {
+ kill(pid, SIGKILL);
+ shmdt((void *)pptr);
+ shmdt((void *)pptr1);
+ shmctl(shm_id, IPC_RMID, NULL);
+ shmctl(shm_id1, IPC_RMID, NULL);
+ return TEST_FAIL;
+ }
+
+ shmdt((void *)pptr);
+ shmdt((void *)pptr1);
+ ret = wait(&status);
+ shmctl(shm_id, IPC_RMID, NULL);
+ shmctl(shm_id1, IPC_RMID, NULL);
+ if (ret != pid) {
+ printf("Child's exit status not captured\n");
+ return TEST_FAIL;
+ }
+
+ return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
+ TEST_PASS;
+ }
+ return TEST_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_harness(ptrace_tm_spr, "ptrace_tm_spr");
+}
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace.h b/tools/testing/selftests/powerpc/ptrace/ptrace.h
index 7dea180..ed7a199 100644
--- a/tools/testing/selftests/powerpc/ptrace/ptrace.h
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace.h
@@ -52,6 +52,11 @@ struct fpr_regs {
unsigned long fpscr;
};
+struct tm_spr_regs {
+ unsigned long tm_tfhar;
+ unsigned long tm_texasr;
+ unsigned long tm_tfiar;
+};
/* Basic ptrace operations */
int start_trace(pid_t child)
@@ -665,6 +670,36 @@ int write_vsx_ckpt(pid_t child, unsigned long *vsx)
return TEST_PASS;
}
+/* TM SPR */
+int show_tm_spr(pid_t child, struct tm_spr_regs *out)
+{
+ struct tm_spr_regs *regs;
+ struct iovec iov;
+ int ret;
+
+ regs = (struct tm_spr_regs *) malloc(sizeof(struct tm_spr_regs));
+ if (!regs) {
+ perror("malloc() failed");
+ return TEST_FAIL;
+ }
+
+ iov.iov_base = (u64 *) regs;
+ iov.iov_len = sizeof(struct tm_spr_regs);
+
+ ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_SPR, &iov);
+ if (ret) {
+ perror("ptrace(PTRACE_GETREGSET) failed");
+ return TEST_FAIL;
+ }
+
+ if (out)
+ memcpy(out, regs, sizeof(struct tm_spr_regs));
+
+ return TEST_PASS;
+}
+
+
+
/* Analyse TEXASR after TM failure */
inline unsigned long get_tfiar(void)
{
--
1.8.3.1
[toc] | [prev] | [next] | [standalone]
| From | wei.guo.simon@gmail.com |
|---|---|
| Date | 2016-10-26 13:20 +0200 |
| Subject | [PATCH v16 03/15] selftests/powerpc: Add ptrace tests for EBB |
| Message-ID | <swups-2Sj-49@gated-at.bofh.it> |
| In reply to | #1509082 |
From: Anshuman Khandual <khandual@linux.vnet.ibm.com>
This patch adds ptrace interface test for EBB/PMU specific
registers. This also adds some generic ptrace interface
based helper functions to be used by other patches later
on in the series.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
Signed-off-by: Simon Guo <wei.guo.simon@gmail.com>
---
tools/testing/selftests/powerpc/Makefile | 3 +-
tools/testing/selftests/powerpc/ptrace/Makefile | 11 +
.../testing/selftests/powerpc/ptrace/ptrace-ebb.c | 188 +++++++++++++++++
.../testing/selftests/powerpc/ptrace/ptrace-ebb.h | 100 +++++++++
tools/testing/selftests/powerpc/ptrace/ptrace.h | 225 +++++++++++++++++++++
5 files changed, 526 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/ptrace/Makefile
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-ebb.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-ebb.h
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace.h
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index cd65cb5..c46bc3a 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -26,7 +26,8 @@ SUB_DIRS = alignment \
syscalls \
tm \
vphn \
- math
+ math \
+ ptrace
endif
diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile b/tools/testing/selftests/powerpc/ptrace/Makefile
new file mode 100644
index 0000000..84c1c01
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -0,0 +1,11 @@
+TEST_PROGS := ptrace-ebb
+
+include ../../lib.mk
+
+all: $(TEST_PROGS)
+CFLAGS += -m64
+$(TEST_PROGS): ../harness.c ../utility/utils.c ptrace.h
+ptrace-ebb: ../pmu/event.c ../pmu/lib.c ../pmu/ebb/ebb_handler.S ../pmu/ebb/busy_loop.S
+ptrace-ebb: CFLAGS += -I../pmu/ebb
+clean:
+ rm -f $(TEST_PROGS) *.o
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-ebb.c b/tools/testing/selftests/powerpc/ptrace/ptrace-ebb.c
new file mode 100644
index 0000000..3649ddd
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-ebb.c
@@ -0,0 +1,188 @@
+/*
+ * Ptrace interface test for EBB
+ *
+ * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "ebb.h"
+#include "ptrace.h"
+#include "ptrace-ebb.h"
+
+/* Tracer and Tracee Shared Data */
+int shm_id;
+int *cptr, *pptr;
+
+void ebb(void)
+{
+ struct event event;
+
+ cptr = (int *)shmat(shm_id, NULL, 0);
+
+ event_init_named(&event, 0x1001e, "cycles");
+ event.attr.config |= (1ull << 63);
+ event.attr.exclusive = 1;
+ event.attr.pinned = 1;
+ event.attr.exclude_kernel = 1;
+ event.attr.exclude_hv = 1;
+ event.attr.exclude_idle = 1;
+
+ if (event_open(&event)) {
+ perror("event_open() failed");
+ exit(1);
+ }
+
+ setup_ebb_handler(standard_ebb_callee);
+ mtspr(SPRN_BESCR, 0x8000000100000000ull);
+
+ /*
+ * make sure BESCR has been set before continue
+ */
+ mb();
+
+ if (ebb_event_enable(&event)) {
+ perror("ebb_event_handler() failed");
+ exit(1);
+ }
+
+ mtspr(SPRN_PMC1, pmc_sample_period(SAMPLE_PERIOD));
+ core_busy_loop();
+ cptr[0] = 1;
+ while (1)
+ asm volatile("" : : : "memory");
+
+ exit(0);
+}
+
+int validate_ebb(struct ebb_regs *regs)
+{
+ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ struct opd *opd = (struct opd *) ebb_handler;
+ #endif
+
+ printf("EBBRR: %lx\n", regs->ebbrr);
+ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ printf("EBBHR: %lx; expected: %lx\n",
+ regs->ebbhr, (unsigned long)opd->entry);
+ #else
+ printf("EBBHR: %lx; expected: %lx\n",
+ regs->ebbhr, (unsigned long)ebb_handler);
+ #endif
+ printf("BESCR: %lx\n", regs->bescr);
+
+ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ if (regs->ebbhr != opd->entry)
+ return TEST_FAIL;
+ #else
+ if (regs->ebbhr != (unsigned long) ebb_handler)
+ return TEST_FAIL;
+ #endif
+
+ return TEST_PASS;
+}
+
+int validate_pmu(struct pmu_regs *regs)
+{
+ printf("SIAR: %lx\n", regs->siar);
+ printf("SDAR: %lx\n", regs->sdar);
+ printf("SIER: %lx; expected: %lx or %lx\n",
+ regs->sier, (unsigned long)SIER_EXP_HV,
+ (unsigned long)SIER_EXP);
+ printf("MMCR2: %lx; expected: %lx\n",
+ regs->mmcr2, (unsigned long)MMCR2_EXP);
+ printf("MMCR0: %lx; expected: %lx\n",
+ regs->mmcr0, (unsigned long)MMCR0_EXP);
+
+ /* Validate SIER */
+ if ((regs->sier != SIER_EXP_HV) && (regs->sier != SIER_EXP))
+ return TEST_FAIL;
+
+ /* Validate MMCR2 */
+ if (regs->mmcr2 != MMCR2_EXP)
+ return TEST_FAIL;
+
+ /* Validate MMCR0 */
+ if (regs->mmcr0 != MMCR0_EXP)
+ return TEST_FAIL;
+
+ return TEST_PASS;
+}
+
+int trace_ebb_pmu(pid_t child)
+{
+ struct ebb_regs ebb_regs;
+ struct pmu_regs pmu_regs;
+ int ret;
+
+ ret = start_trace(child);
+ if (ret)
+ return TEST_FAIL;
+
+ ret = show_ebb_registers(child, &ebb_regs);
+ if (ret)
+ return TEST_FAIL;
+
+ ret = validate_ebb(&ebb_regs);
+ if (ret)
+ return TEST_FAIL;
+
+ ret = show_pmu_registers(child, &pmu_regs);
+ if (ret)
+ return TEST_FAIL;
+
+ ret = validate_pmu(&pmu_regs);
+ if (ret)
+ return TEST_FAIL;
+
+ ret = stop_trace(child);
+ if (ret)
+ return TEST_FAIL;
+
+ return TEST_PASS;
+}
+
+int ptrace_ebb_pmu(void)
+{
+ pid_t pid;
+ int ret, status;
+
+ shm_id = shmget(IPC_PRIVATE, sizeof(int) * 1, 0777|IPC_CREAT);
+ pid = fork();
+ if (pid < 0) {
+ perror("fork() failed");
+ return TEST_FAIL;
+ }
+
+ if (pid == 0)
+ ebb();
+
+ if (pid) {
+ pptr = (int *)shmat(shm_id, NULL, 0);
+ while (!pptr[0])
+ asm volatile("" : : : "memory");
+
+ ret = trace_ebb_pmu(pid);
+ if (ret)
+ return TEST_FAIL;
+
+ shmctl(shm_id, IPC_RMID, NULL);
+ kill(pid, SIGKILL);
+ ret = wait(&status);
+ if (ret != pid) {
+ printf("Child's exit status not captured\n");
+ return TEST_FAIL;
+ }
+
+ return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
+ TEST_PASS;
+ }
+ return TEST_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_harness(ptrace_ebb_pmu, "ptrace_ebb_pmu");
+}
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-ebb.h b/tools/testing/selftests/powerpc/ptrace/ptrace-ebb.h
new file mode 100644
index 0000000..faaf6b8
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-ebb.h
@@ -0,0 +1,100 @@
+/*
+ * Inspired mostly from the EBB selftest
+ *
+ * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#define SAMPLE_PERIOD 100 /* EBB event sample persiod */
+
+/* Standard expected values */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define MMCR0_EXP 0x8000008000000001
+#else
+#define MMCR0_EXP 0x180000080
+#endif
+
+#define MMCR2_EXP 0
+#define SIER_EXP 0x2000000
+#define SIER_EXP_HV 0x3000000
+
+struct opd {
+ u64 entry;
+ u64 toc;
+};
+
+void (*ebb_user_func)(void);
+extern void ebb_handler(void); /* Defined in ebb_handle.S */
+
+void ebb_hook(void) /* Called by ebb_handler */
+{
+ if (ebb_user_func)
+ ebb_user_func();
+}
+
+void setup_ebb_handler(void (*callee)(void))
+{
+ u64 entry;
+
+#if defined(_CALL_ELF) && _CALL_ELF == 2
+ entry = (u64)ebb_handler;
+#else
+ struct opd *opd;
+
+ opd = (struct opd *)ebb_handler;
+ entry = opd->entry;
+#endif
+ ebb_user_func = callee;
+
+ /* Ensure ebb_user_func is set before we set the handler */
+ mb();
+ mtspr(SPRN_EBBHR, entry);
+
+ /* Make sure the handler is set before we return */
+ mb();
+}
+
+void reset_ebb_with_clear_mask(unsigned long mmcr0_clear_mask)
+{
+ u64 val;
+
+ /* 2) clear MMCR0[PMAO] - docs say BESCR[PMEO] should do this */
+ /* 3) set MMCR0[PMAE] - docs say BESCR[PME] should do this */
+ val = mfspr(SPRN_MMCR0);
+ mtspr(SPRN_MMCR0, (val & ~mmcr0_clear_mask) | MMCR0_PMAE);
+
+ /* 4) clear BESCR[PMEO] */
+ mtspr(SPRN_BESCRR, BESCR_PMEO);
+
+ /* 5) set BESCR[PME] */
+ mtspr(SPRN_BESCRS, BESCR_PME);
+
+ /* 6) rfebb 1 - done in our caller */
+}
+
+void standard_ebb_callee(void)
+{
+ u64 val;
+
+ val = mfspr(SPRN_BESCR);
+ if (!(val & BESCR_PMEO))
+ printf("Spurious interrupt\n");
+
+ mtspr(SPRN_PMC1, pmc_sample_period(SAMPLE_PERIOD));
+ reset_ebb_with_clear_mask(MMCR0_PMAO | MMCR0_FC);
+}
+
+int ebb_event_enable(struct event *e)
+{
+ int rc;
+
+ rc = ioctl(e->fd, PERF_EVENT_IOC_ENABLE);
+ if (rc)
+ return rc;
+ rc = event_read(e);
+
+ return rc;
+}
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace.h b/tools/testing/selftests/powerpc/ptrace/ptrace.h
new file mode 100644
index 0000000..96d2179
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace.h
@@ -0,0 +1,225 @@
+/*
+ * Ptrace interface test helper functions
+ *
+ * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include <inttypes.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/ptrace.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/signal.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/user.h>
+#include <linux/elf.h>
+#include <linux/types.h>
+#include <linux/auxvec.h>
+#include "reg.h"
+#include "utils.h"
+
+#define TEST_PASS 0
+#define TEST_FAIL 1
+
+struct ebb_regs {
+ unsigned long ebbrr;
+ unsigned long ebbhr;
+ unsigned long bescr;
+};
+
+struct pmu_regs {
+ unsigned long siar;
+ unsigned long sdar;
+ unsigned long sier;
+ unsigned long mmcr2;
+ unsigned long mmcr0;
+};
+
+struct fpr_regs {
+ unsigned long fpr[32];
+ unsigned long fpscr;
+};
+
+
+/* Basic ptrace operations */
+int start_trace(pid_t child)
+{
+ int ret;
+
+ ret = ptrace(PTRACE_ATTACH, child, NULL, NULL);
+ if (ret) {
+ perror("ptrace(PTRACE_ATTACH) failed");
+ return TEST_FAIL;
+ }
+ ret = waitpid(child, NULL, 0);
+ if (ret != child) {
+ perror("waitpid() failed");
+ return TEST_FAIL;
+ }
+ return TEST_PASS;
+}
+
+int stop_trace(pid_t child)
+{
+ int ret;
+
+ ret = ptrace(PTRACE_DETACH, child, NULL, NULL);
+ if (ret) {
+ perror("ptrace(PTRACE_DETACH) failed");
+ return TEST_FAIL;
+ }
+ return TEST_PASS;
+}
+
+int cont_trace(pid_t child)
+{
+ int ret;
+
+ ret = ptrace(PTRACE_CONT, child, NULL, NULL);
+ if (ret) {
+ perror("ptrace(PTRACE_CONT) failed");
+ return TEST_FAIL;
+ }
+ return TEST_PASS;
+}
+
+/* PMU */
+int show_pmu_registers(pid_t child, struct pmu_regs *regs)
+{
+ struct pmu_regs *pmu;
+ struct iovec iov;
+ int ret;
+
+ pmu = malloc(sizeof(struct pmu_regs));
+ if (!pmu) {
+ perror("malloc() failed");
+ return TEST_FAIL;
+ }
+
+ iov.iov_base = (struct pmu_regs *) pmu;
+ iov.iov_len = sizeof(struct pmu_regs);
+ ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_PMU, &iov);
+ if (ret) {
+ perror("ptrace(PTRACE_GETREGSET) failed");
+ goto fail;
+ }
+
+ if (regs)
+ memcpy(regs, pmu, sizeof(struct pmu_regs));
+
+ free(pmu);
+ return TEST_PASS;
+fail:
+ free(pmu);
+ return TEST_FAIL;
+}
+
+/* EBB */
+int show_ebb_registers(pid_t child, struct ebb_regs *regs)
+{
+ struct ebb_regs *ebb;
+ struct iovec iov;
+ int ret;
+
+ ebb = malloc(sizeof(struct ebb_regs));
+ if (!ebb) {
+ perror("malloc() failed");
+ return TEST_FAIL;
+ }
+
+ iov.iov_base = (struct ebb_regs *) ebb;
+ iov.iov_len = sizeof(struct ebb_regs);
+ ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_EBB, &iov);
+ if (ret) {
+ perror("ptrace(PTRACE_GETREGSET) failed");
+ goto fail;
+ }
+
+ if (regs)
+ memcpy(regs, ebb, sizeof(struct ebb_regs));
+
+ free(ebb);
+ return TEST_PASS;
+fail:
+ free(ebb);
+ return TEST_FAIL;
+}
+
+/* Analyse TEXASR after TM failure */
+inline unsigned long get_tfiar(void)
+{
+ unsigned long ret;
+
+ asm volatile("mfspr %0,%1" : "=r" (ret) : "i" (SPRN_TFIAR));
+ return ret;
+}
+
+void analyse_texasr(unsigned long texasr)
+{
+ printf("TEXASR: %16lx\t", texasr);
+
+ if (texasr & TEXASR_FP)
+ printf("TEXASR_FP ");
+
+ if (texasr & TEXASR_DA)
+ printf("TEXASR_DA ");
+
+ if (texasr & TEXASR_NO)
+ printf("TEXASR_NO ");
+
+ if (texasr & TEXASR_FO)
+ printf("TEXASR_FO ");
+
+ if (texasr & TEXASR_SIC)
+ printf("TEXASR_SIC ");
+
+ if (texasr & TEXASR_NTC)
+ printf("TEXASR_NTC ");
+
+ if (texasr & TEXASR_TC)
+ printf("TEXASR_TC ");
+
+ if (texasr & TEXASR_TIC)
+ printf("TEXASR_TIC ");
+
+ if (texasr & TEXASR_IC)
+ printf("TEXASR_IC ");
+
+ if (texasr & TEXASR_IFC)
+ printf("TEXASR_IFC ");
+
+ if (texasr & TEXASR_ABT)
+ printf("TEXASR_ABT ");
+
+ if (texasr & TEXASR_SPD)
+ printf("TEXASR_SPD ");
+
+ if (texasr & TEXASR_HV)
+ printf("TEXASR_HV ");
+
+ if (texasr & TEXASR_PR)
+ printf("TEXASR_PR ");
+
+ if (texasr & TEXASR_FS)
+ printf("TEXASR_FS ");
+
+ if (texasr & TEXASR_TE)
+ printf("TEXASR_TE ");
+
+ if (texasr & TEXASR_ROT)
+ printf("TEXASR_ROT ");
+
+ printf("TFIAR :%lx\n", get_tfiar());
+}
--
1.8.3.1
[toc] | [prev] | [next] | [standalone]
| From | wei.guo.simon@gmail.com |
|---|---|
| Date | 2016-10-26 13:20 +0200 |
| Subject | [PATCH v16 01/15] selftests/powerpc: Add more SPR numbers, TM & VMX instructions to 'reg.h'/'instructions.h' |
| Message-ID | <swups-2Sj-41@gated-at.bofh.it> |
| In reply to | #1509082 |
From: Anshuman Khandual <khandual@linux.vnet.ibm.com>
This patch adds SPR number for TAR, PPR, DSCR special
purpose registers. It also adds TM, VSX, VMX related
instructions which will then be used by patches later
in the series.
Now that the new DSCR register definitions (SPRN_DSCR_PRIV and
SPRN_DSCR) are defined outside this directory, use them instead.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
Signed-off-by: Simon Guo <wei.guo.simon@gmail.com>
---
tools/testing/selftests/powerpc/dscr/dscr.h | 10 ++++-----
tools/testing/selftests/powerpc/reg.h | 35 ++++++++++++++++++++++++++---
2 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/powerpc/dscr/dscr.h b/tools/testing/selftests/powerpc/dscr/dscr.h
index a36af1b..18ea223b 100644
--- a/tools/testing/selftests/powerpc/dscr/dscr.h
+++ b/tools/testing/selftests/powerpc/dscr/dscr.h
@@ -28,8 +28,6 @@
#include "utils.h"
-#define SPRN_DSCR 0x11 /* Privilege state SPR */
-#define SPRN_DSCR_USR 0x03 /* Problem state SPR */
#define THREADS 100 /* Max threads */
#define COUNT 100 /* Max iterations */
#define DSCR_MAX 16 /* Max DSCR value */
@@ -48,14 +46,14 @@ inline unsigned long get_dscr(void)
{
unsigned long ret;
- asm volatile("mfspr %0,%1" : "=r" (ret): "i" (SPRN_DSCR));
+ asm volatile("mfspr %0,%1" : "=r" (ret) : "i" (SPRN_DSCR_PRIV));
return ret;
}
inline void set_dscr(unsigned long val)
{
- asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR));
+ asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR_PRIV));
}
/* Problem state DSCR access */
@@ -63,14 +61,14 @@ inline unsigned long get_dscr_usr(void)
{
unsigned long ret;
- asm volatile("mfspr %0,%1" : "=r" (ret): "i" (SPRN_DSCR_USR));
+ asm volatile("mfspr %0,%1" : "=r" (ret) : "i" (SPRN_DSCR));
return ret;
}
inline void set_dscr_usr(unsigned long val)
{
- asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR_USR));
+ asm volatile("mtspr %1,%0" : : "r" (val), "i" (SPRN_DSCR));
}
/* Default DSCR access */
diff --git a/tools/testing/selftests/powerpc/reg.h b/tools/testing/selftests/powerpc/reg.h
index fddf368..f5d33db 100644
--- a/tools/testing/selftests/powerpc/reg.h
+++ b/tools/testing/selftests/powerpc/reg.h
@@ -51,10 +51,39 @@
#define SPRN_SDAR 781
#define SPRN_SIER 768
-#define SPRN_TEXASR 0x82
+#define SPRN_TEXASR 0x82 /* Transaction Exception and Status Register */
#define SPRN_TFIAR 0x81 /* Transaction Failure Inst Addr */
#define SPRN_TFHAR 0x80 /* Transaction Failure Handler Addr */
-#define TEXASR_FS 0x08000000
-#define SPRN_TAR 0x32f
+#define SPRN_TAR 0x32f /* Target Address Register */
+
+#define SPRN_DSCR_PRIV 0x11 /* Privilege State DSCR */
+#define SPRN_DSCR 0x03 /* Data Stream Control Register */
+#define SPRN_PPR 896 /* Program Priority Register */
+
+/* TEXASR register bits */
+#define TEXASR_FC 0xFE00000000000000
+#define TEXASR_FP 0x0100000000000000
+#define TEXASR_DA 0x0080000000000000
+#define TEXASR_NO 0x0040000000000000
+#define TEXASR_FO 0x0020000000000000
+#define TEXASR_SIC 0x0010000000000000
+#define TEXASR_NTC 0x0008000000000000
+#define TEXASR_TC 0x0004000000000000
+#define TEXASR_TIC 0x0002000000000000
+#define TEXASR_IC 0x0001000000000000
+#define TEXASR_IFC 0x0000800000000000
+#define TEXASR_ABT 0x0000000100000000
+#define TEXASR_SPD 0x0000000080000000
+#define TEXASR_HV 0x0000000020000000
+#define TEXASR_PR 0x0000000010000000
+#define TEXASR_FS 0x0000000008000000
+#define TEXASR_TE 0x0000000004000000
+#define TEXASR_ROT 0x0000000002000000
+
+/* Vector Instructions */
+#define VSX_XX1(xs, ra, rb) (((xs) & 0x1f) << 21 | ((ra) << 16) | \
+ ((rb) << 11) | (((xs) >> 5)))
+#define STXVD2X(xs, ra, rb) .long (0x7c000798 | VSX_XX1((xs), (ra), (rb)))
+#define LXVD2X(xs, ra, rb) .long (0x7c000698 | VSX_XX1((xs), (ra), (rb)))
#endif /* _SELFTESTS_POWERPC_REG_H */
--
1.8.3.1
[toc] | [prev] | [next] | [standalone]
| From | wei.guo.simon@gmail.com |
|---|---|
| Date | 2016-10-26 13:20 +0200 |
| Subject | [PATCH v16 10/15] selftests/powerpc: Add ptrace tests for VSX, VMX registers |
| Message-ID | <swups-2Sj-45@gated-at.bofh.it> |
| In reply to | #1509082 |
From: Anshuman Khandual <khandual@linux.vnet.ibm.com>
This patch adds ptrace interface test for VSX, VMX registers.
This also adds ptrace interface based helper functions related
to VSX, VMX registers access. This also adds some assembly
helper functions related to VSX and VMX registers.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
Signed-off-by: Simon Guo <wei.guo.simon@gmail.com>
---
tools/testing/selftests/powerpc/ptrace/Makefile | 2 +-
.../testing/selftests/powerpc/ptrace/ptrace-vsx.c | 117 +++++++++
.../testing/selftests/powerpc/ptrace/ptrace-vsx.h | 127 ++++++++++
tools/testing/selftests/powerpc/ptrace/ptrace.h | 119 +++++++++
tools/testing/selftests/powerpc/utility/reg.S | 265 +++++++++++++++++++++
5 files changed, 629 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-vsx.c
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-vsx.h
diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile b/tools/testing/selftests/powerpc/ptrace/Makefile
index 19e4a7c..9d9f658 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,5 +1,5 @@
TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
-ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar
+ptrace-tar ptrace-tm-tar ptrace-tm-spd-tar ptrace-vsx
include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-vsx.c b/tools/testing/selftests/powerpc/ptrace/ptrace-vsx.c
new file mode 100644
index 0000000..04084ee
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-vsx.c
@@ -0,0 +1,117 @@
+/*
+ * Ptrace test for VMX/VSX registers
+ *
+ * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "ptrace.h"
+#include "ptrace-vsx.h"
+
+/* Tracer and Tracee Shared Data */
+int shm_id;
+int *cptr, *pptr;
+
+unsigned long fp_load[VEC_MAX];
+unsigned long fp_load_new[VEC_MAX];
+unsigned long fp_store[VEC_MAX];
+
+void vsx(void)
+{
+ int ret;
+
+ cptr = (int *)shmat(shm_id, NULL, 0);
+ loadvsx(fp_load, 0);
+ cptr[1] = 1;
+
+ while (!cptr[0])
+ asm volatile("" : : : "memory");
+ shmdt((void *) cptr);
+
+ storevsx(fp_store, 0);
+ ret = compare_vsx_vmx(fp_store, fp_load_new);
+ if (ret)
+ exit(1);
+ exit(0);
+}
+
+int trace_vsx(pid_t child)
+{
+ unsigned long vsx[VSX_MAX];
+ unsigned long vmx[VMX_MAX + 2][2];
+
+ FAIL_IF(start_trace(child));
+ FAIL_IF(show_vsx(child, vsx));
+ FAIL_IF(validate_vsx(vsx, fp_load));
+ FAIL_IF(show_vmx(child, vmx));
+ FAIL_IF(validate_vmx(vmx, fp_load));
+
+ memset(vsx, 0, sizeof(vsx));
+ memset(vmx, 0, sizeof(vmx));
+ load_vsx_vmx(fp_load_new, vsx, vmx);
+
+ FAIL_IF(write_vsx(child, vsx));
+ FAIL_IF(write_vmx(child, vmx));
+ FAIL_IF(stop_trace(child));
+
+ return TEST_PASS;
+}
+
+int ptrace_vsx(void)
+{
+ pid_t pid;
+ int ret, status, i;
+
+ shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
+
+ for (i = 0; i < VEC_MAX; i++)
+ fp_load[i] = i + rand();
+
+ for (i = 0; i < VEC_MAX; i++)
+ fp_load_new[i] = i + 2 * rand();
+
+ pid = fork();
+ if (pid < 0) {
+ perror("fork() failed");
+ return TEST_FAIL;
+ }
+
+ if (pid == 0)
+ vsx();
+
+ if (pid) {
+ pptr = (int *)shmat(shm_id, NULL, 0);
+ while (!pptr[1])
+ asm volatile("" : : : "memory");
+
+ ret = trace_vsx(pid);
+ if (ret) {
+ kill(pid, SIGTERM);
+ shmdt((void *)pptr);
+ shmctl(shm_id, IPC_RMID, NULL);
+ return TEST_FAIL;
+ }
+
+ pptr[0] = 1;
+ shmdt((void *)pptr);
+
+ ret = wait(&status);
+ shmctl(shm_id, IPC_RMID, NULL);
+ if (ret != pid) {
+ printf("Child's exit status not captured\n");
+ return TEST_FAIL;
+ }
+
+ return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
+ TEST_PASS;
+ }
+ return TEST_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_harness(ptrace_vsx, "ptrace_vsx");
+}
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-vsx.h b/tools/testing/selftests/powerpc/ptrace/ptrace-vsx.h
new file mode 100644
index 0000000..f4e4b42
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-vsx.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#define VEC_MAX 128
+#define VSX_MAX 32
+#define VMX_MAX 32
+
+/*
+ * unsigned long vsx[32]
+ * unsigned long load[128]
+ */
+int validate_vsx(unsigned long *vsx, unsigned long *load)
+{
+ int i;
+
+ for (i = 0; i < VSX_MAX; i++) {
+ if (vsx[i] != load[2 * i + 1]) {
+ printf("vsx[%d]: %lx load[%d] %lx\n",
+ i, vsx[i], 2 * i + 1, load[2 * i + 1]);
+ return TEST_FAIL;
+ }
+ }
+ return TEST_PASS;
+}
+
+/*
+ * unsigned long vmx[32][2]
+ * unsigned long load[128]
+ */
+int validate_vmx(unsigned long vmx[][2], unsigned long *load)
+{
+ int i;
+
+ for (i = 0; i < VMX_MAX; i++) {
+ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ if ((vmx[i][0] != load[64 + 2 * i]) ||
+ (vmx[i][1] != load[65 + 2 * i])) {
+ printf("vmx[%d][0]: %lx load[%d] %lx\n",
+ i, vmx[i][0], 64 + 2 * i,
+ load[64 + 2 * i]);
+ printf("vmx[%d][1]: %lx load[%d] %lx\n",
+ i, vmx[i][1], 65 + 2 * i,
+ load[65 + 2 * i]);
+ return TEST_FAIL;
+ }
+ #else /*
+ * In LE each value pair is stored in an
+ * alternate manner.
+ */
+ if ((vmx[i][0] != load[65 + 2 * i]) ||
+ (vmx[i][1] != load[64 + 2 * i])) {
+ printf("vmx[%d][0]: %lx load[%d] %lx\n",
+ i, vmx[i][0], 65 + 2 * i,
+ load[65 + 2 * i]);
+ printf("vmx[%d][1]: %lx load[%d] %lx\n",
+ i, vmx[i][1], 64 + 2 * i,
+ load[64 + 2 * i]);
+ return TEST_FAIL;
+ }
+ #endif
+ }
+ return TEST_PASS;
+}
+
+/*
+ * unsigned long store[128]
+ * unsigned long load[128]
+ */
+int compare_vsx_vmx(unsigned long *store, unsigned long *load)
+{
+ int i;
+
+ for (i = 0; i < VSX_MAX; i++) {
+ if (store[1 + 2 * i] != load[1 + 2 * i]) {
+ printf("store[%d]: %lx load[%d] %lx\n",
+ 1 + 2 * i, store[i],
+ 1 + 2 * i, load[i]);
+ return TEST_FAIL;
+ }
+ }
+
+ #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ for (i = 64; i < VEC_MAX; i++) {
+ if (store[i] != load[i]) {
+ printf("store[%d]: %lx load[%d] %lx\n",
+ i, store[i], i, load[i]);
+ return TEST_FAIL;
+ }
+ }
+ #else /* In LE each value pair is stored in an alternate manner */
+ for (i = 64; i < VEC_MAX; i++) {
+ if (!(i % 2) && (store[i] != load[i+1])) {
+ printf("store[%d]: %lx load[%d] %lx\n",
+ i, store[i], i+1, load[i+1]);
+ return TEST_FAIL;
+ }
+ if ((i % 2) && (store[i] != load[i-1])) {
+ printf("here store[%d]: %lx load[%d] %lx\n",
+ i, store[i], i-1, load[i-1]);
+ return TEST_FAIL;
+ }
+ }
+ #endif
+ return TEST_PASS;
+}
+
+void load_vsx_vmx(unsigned long *load, unsigned long *vsx,
+ unsigned long vmx[][2])
+{
+ int i;
+
+ for (i = 0; i < VSX_MAX; i++)
+ vsx[i] = load[1 + 2 * i];
+
+ for (i = 0; i < VMX_MAX; i++) {
+ vmx[i][0] = load[64 + 2 * i];
+ vmx[i][1] = load[65 + 2 * i];
+ }
+}
+
+void loadvsx(void *p, int tmp);
+void storevsx(void *p, int tmp);
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace.h b/tools/testing/selftests/powerpc/ptrace/ptrace.h
index babf8695f2..7dea180 100644
--- a/tools/testing/selftests/powerpc/ptrace/ptrace.h
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace.h
@@ -546,6 +546,125 @@ int write_ckpt_gpr(pid_t child, unsigned long val)
return TEST_PASS;
}
+/* VMX */
+int show_vmx(pid_t child, unsigned long vmx[][2])
+{
+ int ret;
+
+ ret = ptrace(PTRACE_GETVRREGS, child, 0, vmx);
+ if (ret) {
+ perror("ptrace(PTRACE_GETVRREGS) failed");
+ return TEST_FAIL;
+ }
+ return TEST_PASS;
+}
+
+int show_vmx_ckpt(pid_t child, unsigned long vmx[][2])
+{
+ unsigned long regs[34][2];
+ struct iovec iov;
+ int ret;
+
+ iov.iov_base = (u64 *) regs;
+ iov.iov_len = sizeof(regs);
+ ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVMX, &iov);
+ if (ret) {
+ perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVMX) failed");
+ return TEST_FAIL;
+ }
+ memcpy(vmx, regs, sizeof(regs));
+ return TEST_PASS;
+}
+
+
+int write_vmx(pid_t child, unsigned long vmx[][2])
+{
+ int ret;
+
+ ret = ptrace(PTRACE_SETVRREGS, child, 0, vmx);
+ if (ret) {
+ perror("ptrace(PTRACE_SETVRREGS) failed");
+ return TEST_FAIL;
+ }
+ return TEST_PASS;
+}
+
+int write_vmx_ckpt(pid_t child, unsigned long vmx[][2])
+{
+ unsigned long regs[34][2];
+ struct iovec iov;
+ int ret;
+
+ memcpy(regs, vmx, sizeof(regs));
+ iov.iov_base = (u64 *) regs;
+ iov.iov_len = sizeof(regs);
+ ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVMX, &iov);
+ if (ret) {
+ perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVMX) failed");
+ return TEST_FAIL;
+ }
+ return TEST_PASS;
+}
+
+/* VSX */
+int show_vsx(pid_t child, unsigned long *vsx)
+{
+ int ret;
+
+ ret = ptrace(PTRACE_GETVSRREGS, child, 0, vsx);
+ if (ret) {
+ perror("ptrace(PTRACE_GETVSRREGS) failed");
+ return TEST_FAIL;
+ }
+ return TEST_PASS;
+}
+
+int show_vsx_ckpt(pid_t child, unsigned long *vsx)
+{
+ unsigned long regs[32];
+ struct iovec iov;
+ int ret;
+
+ iov.iov_base = (u64 *) regs;
+ iov.iov_len = sizeof(regs);
+ ret = ptrace(PTRACE_GETREGSET, child, NT_PPC_TM_CVSX, &iov);
+ if (ret) {
+ perror("ptrace(PTRACE_GETREGSET, NT_PPC_TM_CVSX) failed");
+ return TEST_FAIL;
+ }
+ memcpy(vsx, regs, sizeof(regs));
+ return TEST_PASS;
+}
+
+int write_vsx(pid_t child, unsigned long *vsx)
+{
+ int ret;
+
+ ret = ptrace(PTRACE_SETVSRREGS, child, 0, vsx);
+ if (ret) {
+ perror("ptrace(PTRACE_SETVSRREGS) failed");
+ return TEST_FAIL;
+ }
+ return TEST_PASS;
+}
+
+int write_vsx_ckpt(pid_t child, unsigned long *vsx)
+{
+ unsigned long regs[32];
+ struct iovec iov;
+ int ret;
+
+ memcpy(regs, vsx, sizeof(regs));
+ iov.iov_base = (u64 *) regs;
+ iov.iov_len = sizeof(regs);
+ ret = ptrace(PTRACE_SETREGSET, child, NT_PPC_TM_CVSX, &iov);
+ if (ret) {
+ perror("ptrace(PTRACE_SETREGSET, NT_PPC_TM_CVSX) failed");
+ return TEST_FAIL;
+ }
+ return TEST_PASS;
+}
+
/* Analyse TEXASR after TM failure */
inline unsigned long get_tfiar(void)
{
diff --git a/tools/testing/selftests/powerpc/utility/reg.S b/tools/testing/selftests/powerpc/utility/reg.S
index b6aee2f..0dc44f0d 100644
--- a/tools/testing/selftests/powerpc/utility/reg.S
+++ b/tools/testing/selftests/powerpc/utility/reg.S
@@ -130,3 +130,268 @@ FUNC_START(store_fpr_single_precision)
stfs 31, 31*4(3)
blr
FUNC_END(store_fpr_single_precision)
+
+/* VMX/VSX registers - unsigned long buf[128] */
+FUNC_START(loadvsx)
+ lis 4, 0
+ LXVD2X (0,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (1,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (2,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (3,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (4,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (5,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (6,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (7,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (8,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (9,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (10,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (11,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (12,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (13,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (14,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (15,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (16,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (17,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (18,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (19,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (20,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (21,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (22,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (23,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (24,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (25,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (26,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (27,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (28,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (29,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (30,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (31,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (32,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (33,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (34,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (35,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (36,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (37,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (38,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (39,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (40,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (41,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (42,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (43,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (44,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (45,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (46,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (47,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (48,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (49,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (50,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (51,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (52,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (53,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (54,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (55,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (56,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (57,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (58,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (59,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (60,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (61,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (62,(4),(3))
+ addi 4, 4, 16
+ LXVD2X (63,(4),(3))
+ blr
+FUNC_END(loadvsx)
+
+FUNC_START(storevsx)
+ lis 4, 0
+ STXVD2X (0,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (1,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (2,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (3,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (4,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (5,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (6,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (7,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (8,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (9,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (10,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (11,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (12,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (13,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (14,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (15,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (16,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (17,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (18,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (19,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (20,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (21,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (22,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (23,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (24,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (25,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (26,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (27,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (28,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (29,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (30,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (31,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (32,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (33,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (34,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (35,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (36,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (37,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (38,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (39,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (40,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (41,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (42,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (43,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (44,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (45,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (46,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (47,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (48,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (49,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (50,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (51,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (52,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (53,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (54,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (55,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (56,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (57,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (58,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (59,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (60,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (61,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (62,(4),(3))
+ addi 4, 4, 16
+ STXVD2X (63,(4),(3))
+ blr
+FUNC_END(storevsx)
--
1.8.3.1
[toc] | [prev] | [next] | [standalone]
| From | wei.guo.simon@gmail.com |
|---|---|
| Date | 2016-10-26 13:20 +0200 |
| Subject | [PATCH v16 08/15] selftests/powerpc: Add ptrace tests for TAR, PPR, DSCR in TM |
| Message-ID | <swups-2Sj-55@gated-at.bofh.it> |
| In reply to | #1509082 |
From: Anshuman Khandual <khandual@linux.vnet.ibm.com>
This patch adds ptrace interface test for TAR, PPR, DSCR
registers inside TM context. This also adds ptrace
interface based helper functions related to checkpointed
TAR, PPR, DSCR register access.
Signed-off-by: Anshuman Khandual <khandual@linux.vnet.ibm.com>
Signed-off-by: Simon Guo <wei.guo.simon@gmail.com>
---
tools/testing/selftests/powerpc/ptrace/Makefile | 2 +-
.../selftests/powerpc/ptrace/ptrace-tm-tar.c | 160 +++++++++++++++++++++
2 files changed, 161 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c
diff --git a/tools/testing/selftests/powerpc/ptrace/Makefile b/tools/testing/selftests/powerpc/ptrace/Makefile
index dfb0847..9af9ad5 100644
--- a/tools/testing/selftests/powerpc/ptrace/Makefile
+++ b/tools/testing/selftests/powerpc/ptrace/Makefile
@@ -1,5 +1,5 @@
TEST_PROGS := ptrace-ebb ptrace-gpr ptrace-tm-gpr ptrace-tm-spd-gpr \
-ptrace-tar
+ptrace-tar ptrace-tm-tar
include ../../lib.mk
diff --git a/tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c
new file mode 100644
index 0000000..48b462f
--- /dev/null
+++ b/tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c
@@ -0,0 +1,160 @@
+/*
+ * Ptrace test for TAR, PPR, DSCR registers in the TM context
+ *
+ * Copyright (C) 2015 Anshuman Khandual, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "ptrace.h"
+#include "tm.h"
+#include "ptrace-tar.h"
+
+int shm_id;
+unsigned long *cptr, *pptr;
+
+
+void tm_tar(void)
+{
+ unsigned long result, texasr;
+ unsigned long regs[3];
+ int ret;
+
+ cptr = (unsigned long *)shmat(shm_id, NULL, 0);
+
+trans:
+ cptr[1] = 0;
+ asm __volatile__(
+ "li 4, %[tar_1];"
+ "mtspr %[sprn_tar], 4;" /* TAR_1 */
+ "li 4, %[dscr_1];"
+ "mtspr %[sprn_dscr], 4;" /* DSCR_1 */
+ "or 31,31,31;" /* PPR_1*/
+
+ "1: ;"
+ "tbegin.;"
+ "beq 2f;"
+
+ "li 4, %[tar_2];"
+ "mtspr %[sprn_tar], 4;" /* TAR_2 */
+ "li 4, %[dscr_2];"
+ "mtspr %[sprn_dscr], 4;" /* DSCR_2 */
+ "or 1,1,1;" /* PPR_2 */
+ "tsuspend.;"
+ "li 0, 1;"
+ "stw 0, 0(%[cptr1]);"
+ "tresume.;"
+ "b .;"
+
+ "tend.;"
+ "li 0, 0;"
+ "ori %[res], 0, 0;"
+ "b 3f;"
+
+ /* Transaction abort handler */
+ "2: ;"
+ "li 0, 1;"
+ "ori %[res], 0, 0;"
+ "mfspr %[texasr], %[sprn_texasr];"
+
+ "3: ;"
+
+ : [res] "=r" (result), [texasr] "=r" (texasr)
+ : [sprn_dscr]"i"(SPRN_DSCR), [sprn_tar]"i"(SPRN_TAR),
+ [sprn_ppr]"i"(SPRN_PPR), [sprn_texasr]"i"(SPRN_TEXASR),
+ [tar_1]"i"(TAR_1), [dscr_1]"i"(DSCR_1), [tar_2]"i"(TAR_2),
+ [dscr_2]"i"(DSCR_2), [cptr1] "r" (&cptr[1])
+ : "memory", "r0", "r1", "r3", "r4", "r5", "r6"
+ );
+
+ /* TM failed, analyse */
+ if (result) {
+ if (!cptr[0])
+ goto trans;
+
+ regs[0] = mfspr(SPRN_TAR);
+ regs[1] = mfspr(SPRN_PPR);
+ regs[2] = mfspr(SPRN_DSCR);
+
+ shmdt(&cptr);
+ printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
+ user_read, regs[0], regs[1], regs[2]);
+
+ ret = validate_tar_registers(regs, TAR_4, PPR_4, DSCR_4);
+ if (ret)
+ exit(1);
+ exit(0);
+ }
+ shmdt(&cptr);
+ exit(1);
+}
+
+int trace_tm_tar(pid_t child)
+{
+ unsigned long regs[3];
+
+ FAIL_IF(start_trace(child));
+ FAIL_IF(show_tar_registers(child, regs));
+ printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
+ ptrace_read_running, regs[0], regs[1], regs[2]);
+
+ FAIL_IF(validate_tar_registers(regs, TAR_2, PPR_2, DSCR_2));
+ FAIL_IF(show_tm_checkpointed_state(child, regs));
+ printf("%-30s TAR: %lu PPR: %lx DSCR: %lu\n",
+ ptrace_read_ckpt, regs[0], regs[1], regs[2]);
+
+ FAIL_IF(validate_tar_registers(regs, TAR_1, PPR_1, DSCR_1));
+ FAIL_IF(write_ckpt_tar_registers(child, TAR_4, PPR_4, DSCR_4));
+ printf("%-30s TAR: %u PPR: %lx DSCR: %u\n",
+ ptrace_write_ckpt, TAR_4, PPR_4, DSCR_4);
+
+ pptr[0] = 1;
+ FAIL_IF(stop_trace(child));
+ return TEST_PASS;
+}
+
+int ptrace_tm_tar(void)
+{
+ pid_t pid;
+ int ret, status;
+
+ SKIP_IF(!have_htm());
+ shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
+ pid = fork();
+ if (pid == 0)
+ tm_tar();
+
+ pptr = (unsigned long *)shmat(shm_id, NULL, 0);
+ pptr[0] = 0;
+
+ if (pid) {
+ while (!pptr[1])
+ asm volatile("" : : : "memory");
+ ret = trace_tm_tar(pid);
+ if (ret) {
+ kill(pid, SIGTERM);
+ shmdt(&pptr);
+ shmctl(shm_id, IPC_RMID, NULL);
+ return TEST_FAIL;
+ }
+ shmdt(&pptr);
+
+ ret = wait(&status);
+ shmctl(shm_id, IPC_RMID, NULL);
+ if (ret != pid) {
+ printf("Child's exit status not captured\n");
+ return TEST_FAIL;
+ }
+
+ return (WIFEXITED(status) && WEXITSTATUS(status)) ? TEST_FAIL :
+ TEST_PASS;
+ }
+ return TEST_PASS;
+}
+
+int main(int argc, char *argv[])
+{
+ return test_harness(ptrace_tm_tar, "ptrace_tm_tar");
+}
--
1.8.3.1
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web