selftests: Skip TM tests on synthetic TM implementations
authorJordan Niethe <jniethe5@gmail.com>
Thu, 29 Jul 2021 04:13:17 +0000 (14:13 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 26 Aug 2021 11:21:06 +0000 (21:21 +1000)
Transactional Memory was removed from the architecture in ISA v3.1. For
threads running in P8/P9 compatibility mode on P10 a synthetic TM
implementation is provided. In this implementation, tbegin. always sets
cr0 eq meaning the abort handler is always called. This is not an issue
as users of TM are expected to have a fallback non transactional way to
make forward progress in the abort handler.  The TEXASR indicates if a
transaction failure is due to a synthetic implementation.

Some of the TM self tests need a non-degenerate TM implementation for
their testing to be meaningful so check for a synthetic implementation
and skip the test if so.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20210729041317.366612-2-jniethe5@gmail.com
28 files changed:
tools/testing/selftests/powerpc/ptrace/ptrace-tm-gpr.c
tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-gpr.c
tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-tar.c
tools/testing/selftests/powerpc/ptrace/ptrace-tm-spd-vsx.c
tools/testing/selftests/powerpc/ptrace/ptrace-tm-spr.c
tools/testing/selftests/powerpc/ptrace/ptrace-tm-tar.c
tools/testing/selftests/powerpc/ptrace/ptrace-tm-vsx.c
tools/testing/selftests/powerpc/signal/signal_tm.c
tools/testing/selftests/powerpc/tm/tm-exec.c
tools/testing/selftests/powerpc/tm/tm-fork.c
tools/testing/selftests/powerpc/tm/tm-poison.c
tools/testing/selftests/powerpc/tm/tm-resched-dscr.c
tools/testing/selftests/powerpc/tm/tm-signal-context-chk-fpu.c
tools/testing/selftests/powerpc/tm/tm-signal-context-chk-gpr.c
tools/testing/selftests/powerpc/tm/tm-signal-context-chk-vmx.c
tools/testing/selftests/powerpc/tm/tm-signal-context-chk-vsx.c
tools/testing/selftests/powerpc/tm/tm-signal-pagefault.c
tools/testing/selftests/powerpc/tm/tm-signal-sigreturn-nt.c
tools/testing/selftests/powerpc/tm/tm-signal-stack.c
tools/testing/selftests/powerpc/tm/tm-sigreturn.c
tools/testing/selftests/powerpc/tm/tm-syscall.c
tools/testing/selftests/powerpc/tm/tm-tar.c
tools/testing/selftests/powerpc/tm/tm-tmspr.c
tools/testing/selftests/powerpc/tm/tm-trap.c
tools/testing/selftests/powerpc/tm/tm-unavailable.c
tools/testing/selftests/powerpc/tm/tm-vmx-unavail.c
tools/testing/selftests/powerpc/tm/tm-vmxcopy.c
tools/testing/selftests/powerpc/tm/tm.h

index 7df7100a29beb3e6e51a401a43461bcfdcf43e25..67ca297c5ccae33b80ea2dfacc062defa436d22a 100644 (file)
@@ -113,6 +113,7 @@ int ptrace_tm_gpr(void)
        int ret, status;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
        shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
        pid = fork();
        if (pid < 0) {
index 8706bea5d015f5e170d108e994c13dfd3ab3399b..6f2bce1b6c5dcca1934c7c7a0ea040f32add7e47 100644 (file)
@@ -119,6 +119,7 @@ int ptrace_tm_spd_gpr(void)
        int ret, status;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
        shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT);
        pid = fork();
        if (pid < 0) {
index 2ecfa1158e2bcf5e8c2c9a259f615f8de59737f0..e112a34fbe59c77ab9d2984f5c6819a68b2d454f 100644 (file)
@@ -129,6 +129,7 @@ int ptrace_tm_spd_tar(void)
        int ret, status;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
        shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT);
        pid = fork();
        if (pid == 0)
index 6f7fb51f08099ccc1f47069a78a25d3a2d8ccf1a..40133d49fe39e4b18842ceafccc80423e7098a69 100644 (file)
@@ -129,6 +129,7 @@ int ptrace_tm_spd_vsx(void)
        int ret, status, i;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
        shm_id = shmget(IPC_PRIVATE, sizeof(int) * 3, 0777|IPC_CREAT);
 
        for (i = 0; i < 128; i++) {
index 068bfed2e6064ebfbe691a1f093dc6b5a6efd8ee..880ba6a29a48317293bf311c61e3e69f62065631 100644 (file)
@@ -114,6 +114,7 @@ int ptrace_tm_spr(void)
        int ret, status;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
        shm_id = shmget(IPC_PRIVATE, sizeof(struct shared), 0777|IPC_CREAT);
        shm_id1 = shmget(IPC_PRIVATE, sizeof(int), 0777|IPC_CREAT);
        pid = fork();
index 46ef378a15ecc6c829de2f68e5a3f6d945b7c42f..d0db6df0f0eaed3681743714d0e38fdfbf6cb4e9 100644 (file)
@@ -117,6 +117,7 @@ int ptrace_tm_tar(void)
        int ret, status;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
        shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
        pid = fork();
        if (pid == 0)
index 70ca01234f79c4f54cfc41d232c701effb181b8f..4f05ce4fd28232f4fe85794d8dd1907d6692fd42 100644 (file)
@@ -113,6 +113,7 @@ int ptrace_tm_vsx(void)
        int ret, status, i;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
        shm_id = shmget(IPC_PRIVATE, sizeof(int) * 2, 0777|IPC_CREAT);
 
        for (i = 0; i < 128; i++) {
index 5bf2224ef7f2279aecf761e18fecdfd43b232036..c9cf66a3daa2e5c24c5b957da3186ecbd60e50ae 100644 (file)
@@ -56,6 +56,7 @@ static int test_signal_tm()
        }
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        for (i = 0; i < MAX_ATTEMPT; i++) {
                /*
index 260cfdb97d239f602556f1852e5cd2414233cd8f..c59919d6710db70a0098503bc92d1479cfdf7ed0 100644 (file)
@@ -27,6 +27,7 @@ static char *path;
 static int test_exec(void)
 {
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        asm __volatile__(
                "tbegin.;"
index 6efa5a685a7796793f607b5db52605de5429d119..c27b935f0e9fc016f8f8e8888078fd0daa7c199a 100644 (file)
@@ -21,6 +21,7 @@
 int test_fork(void)
 {
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        asm __volatile__(
                "tbegin.;"
index 27c083a03d1f625ce35e682cfc80d134545eea31..a7bbf034b5bb1ab7b5a47816adc6a309b94a852d 100644 (file)
@@ -33,6 +33,7 @@ int tm_poison_test(void)
        bool fail_vr = false;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        cpu = pick_online_cpu();
        FAIL_IF(cpu < 0);
index 4cdb83964bb3298c0e19d0fd16b2e4f585498049..85c940ae6ff87f621e151bd6038b4446ff19d9e4 100644 (file)
@@ -40,6 +40,7 @@ int test_body(void)
        uint64_t rv, dscr1 = 1, dscr2, texasr;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        printf("Check DSCR TM context switch: ");
        fflush(stdout);
index 254f912ad611e48d3f21b8cfc19e9a3c32a7e350..657d755b29055b3bcb80c62a0170deb2960a02e8 100644 (file)
@@ -79,6 +79,7 @@ static int tm_signal_context_chk_fpu()
        pid_t pid = getpid();
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        act.sa_sigaction = signal_usr1;
        sigemptyset(&act.sa_mask);
index 0cc680f61828bfb93b43353ed2bfab93d14d8307..400fa70ca71e4f2c49c300bdc22f1ab6c96dd777 100644 (file)
@@ -81,6 +81,7 @@ static int tm_signal_context_chk_gpr()
        pid_t pid = getpid();
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        act.sa_sigaction = signal_usr1;
        sigemptyset(&act.sa_mask);
index b6d52730a0d832a1f4aa723dfb046e47af25df43..d628fd302b2828c40badce926574533ca8eac5b5 100644 (file)
@@ -104,6 +104,7 @@ static int tm_signal_context_chk()
        pid_t pid = getpid();
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        act.sa_sigaction = signal_usr1;
        sigemptyset(&act.sa_mask);
index 8e25e2072ecda83696ad96d5da9b2dd8b491a7f9..9bd869245bade4315d037a9eb39267367692a7bb 100644 (file)
@@ -153,6 +153,7 @@ static int tm_signal_context_chk()
        pid_t pid = getpid();
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        act.sa_sigaction = signal_usr1;
        sigemptyset(&act.sa_mask);
index 5908bc6abe60c98d168a300df3017ab258b9f161..0b84c9208d629c621e0be33d25bf673d4feb53d5 100644 (file)
@@ -226,6 +226,7 @@ int tm_signal_pagefault(void)
        stack_t ss;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
        SKIP_IF(!have_userfaultfd());
 
        setup_uf_mem();
index 07c388147b75e8d395cd64a7fdda39e1fa94c6ae..06b801906f275cab1afb1c72b74da8b78e913a3e 100644 (file)
@@ -32,6 +32,7 @@ int tm_signal_sigreturn_nt(void)
        struct sigaction trap_sa;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        trap_sa.sa_flags = SA_SIGINFO;
        trap_sa.sa_sigaction = trap_signal_handler;
index cdcf8c5bbbc7ca99cdf2a7fbb36ee5ebc2374352..68807aac8dd380fc96f67d71c563911743adb0a3 100644 (file)
@@ -35,6 +35,7 @@ int tm_signal_stack()
        int pid;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        pid = fork();
        if (pid < 0)
index 9a6017a1d7690733f22e0063b5491719c0dcbc9c..ffe4e5515f33c8c5b86a5c933c358f6b19dc0f78 100644 (file)
@@ -55,6 +55,7 @@ int tm_sigreturn(void)
        uint64_t ret = 0;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
        SKIP_IF(!is_ppc64le());
 
        memset(&sa, 0, sizeof(sa));
index becb8207b4323f9db0a2c4c042e81a3d41504eff..467a6b3134b2a36341c078b92d66ddf5fe3b9189 100644 (file)
@@ -25,7 +25,6 @@ extern int getppid_tm_suspended(void);
 unsigned retries = 0;
 
 #define TEST_DURATION 10 /* seconds */
-#define TM_RETRIES 100
 
 pid_t getppid_tm(bool suspend)
 {
@@ -67,6 +66,7 @@ int tm_syscall(void)
        struct timeval end, now;
 
        SKIP_IF(!have_htm_nosc());
+       SKIP_IF(htm_is_synthetic());
 
        setbuf(stdout, NULL);
 
index 03be8c47292be5b60001a1c5504302e427ff86b6..f2a9137f3c1ec5de182a4252a75328f5da01c75b 100644 (file)
@@ -26,6 +26,7 @@ int test_tar(void)
        int i;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
        SKIP_IF(!is_ppc64le());
 
        for (i = 0; i < num_loops; i++)
index 794d574db7847f38d2e9b357052767b7b1c1487f..dd5ddffa28b77ef667041586c25fd36bbf381c04 100644 (file)
@@ -96,6 +96,7 @@ int test_tmspr()
        unsigned long   i;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        /* To cause some context switching */
        thread_num = 10 * sysconf(_SC_NPROCESSORS_ONLN);
index 11521077f91519b4fd0975a8fafd54c18f9140fa..97cb74768e30a97da0a4cd34ab38fb1db2b57b6c 100644 (file)
@@ -255,6 +255,7 @@ int tm_trap_test(void)
        struct sigaction trap_sa;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        trap_sa.sa_flags = SA_SIGINFO;
        trap_sa.sa_sigaction = trap_signal_handler;
index a1348a5f721a70f1369f4faa4296bc073a2b04a7..6bf1b65b020d10e04bee420f01d434b450e611b0 100644 (file)
@@ -344,6 +344,7 @@ int tm_unavailable_test(void)
        cpu_set_t cpuset;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        cpu = pick_online_cpu();
        FAIL_IF(cpu < 0);
index 9ef37a9836ac65a8bad245be00b4be6cf3f7bb4b..34364ed2b6b706268d28ab881e5b6e0823190cf9 100644 (file)
@@ -91,6 +91,7 @@ int tm_vmx_unavail_test()
        pthread_t *thread;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
 
        passed = 1;
 
index c1e788a6df4797a035fb8c2e5a479cc052c394a4..1640e7ead69bf450c09d8ed625a311918ef95142 100644 (file)
@@ -46,6 +46,7 @@ int test_vmxcopy()
        uint64_t aborted = 0;
 
        SKIP_IF(!have_htm());
+       SKIP_IF(htm_is_synthetic());
        SKIP_IF(!is_ppc64le());
 
        fd = mkstemp(tmpfile);
index c5a1e5c163fcdf79b9568f13d3c60bd3b7f5e6b3..c03c6e77887679dfb850a4149c6b2f5dda59de31 100644 (file)
@@ -10,6 +10,9 @@
 #include <asm/tm.h>
 
 #include "utils.h"
+#include "reg.h"
+
+#define TM_RETRIES 100
 
 static inline bool have_htm(void)
 {
@@ -31,6 +34,39 @@ static inline bool have_htm_nosc(void)
 #endif
 }
 
+/*
+ * Transactional Memory was removed in ISA 3.1. A synthetic TM implementation
+ * is provided on P10 for threads running in P8/P9 compatibility  mode. The
+ * synthetic implementation immediately fails after tbegin. This failure sets
+ * Bit 7 (Failure Persistent) and Bit 15 (Implementation-specific).
+ */
+static inline bool htm_is_synthetic(void)
+{
+       int i;
+
+       /*
+        * Per the ISA, the Failure Persistent bit may be incorrect. Try a few
+        * times in case we got an Implementation-specific failure on a non ISA
+        * v3.1 system. On these systems the Implementation-specific failure
+        * should not be persistent.
+        */
+       for (i = 0; i < TM_RETRIES; i++) {
+               asm volatile(
+               "tbegin.;"
+               "beq 1f;"
+               "tend.;"
+               "1:"
+               :
+               :
+               : "memory");
+
+               if ((__builtin_get_texasr() & (TEXASR_FP | TEXASR_IC)) !=
+                   (TEXASR_FP | TEXASR_IC))
+                       break;
+       }
+       return i == TM_RETRIES;
+}
+
 static inline long failure_code(void)
 {
        return __builtin_get_texasru() >> 24;