0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #define _GNU_SOURCE
0016 #include <stdio.h>
0017 #include <stdlib.h>
0018 #include <unistd.h>
0019 #include <inttypes.h>
0020 #include <sched.h>
0021 #include <sys/types.h>
0022 #include <signal.h>
0023
0024 #include "tm.h"
0025
0026 int tm_poison_test(void)
0027 {
0028 int cpu, pid;
0029 cpu_set_t cpuset;
0030 uint64_t poison = 0xdeadbeefc0dec0fe;
0031 uint64_t unknown = 0;
0032 bool fail_fp = false;
0033 bool fail_vr = false;
0034
0035 SKIP_IF(!have_htm());
0036 SKIP_IF(htm_is_synthetic());
0037
0038 cpu = pick_online_cpu();
0039 FAIL_IF(cpu < 0);
0040
0041
0042 CPU_ZERO(&cpuset);
0043 CPU_SET(cpu, &cpuset);
0044 FAIL_IF(sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0);
0045
0046 pid = fork();
0047 if (!pid) {
0048
0049
0050
0051 while (1) {
0052 sched_yield();
0053 asm (
0054 "mtvsrd 31, %[poison];"
0055 "mtvsrd 63, %[poison];"
0056
0057 : : [poison] "r" (poison) : );
0058 }
0059 }
0060
0061
0062
0063
0064 asm (
0065
0066
0067
0068
0069 " li 3, 0x1 ;"
0070 " li 4, 0x1 ;"
0071 " mtvsrd 31, 4 ;"
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 " lis 5, 14 ;"
0086 " ori 5, 5, 19996 ;"
0087 " sldi 5, 5, 16 ;"
0088
0089 " mfspr 6, 268 ;"
0090 "1: mfspr 7, 268 ;"
0091 " subf 7, 6, 7 ;"
0092 " cmpd 7, 5 ;"
0093 " bgt 3f ;"
0094
0095
0096
0097
0098 " tbegin. ;"
0099 " beq 1b ;"
0100 " mfvsrd 3, 31 ;"
0101 " cmpd 3, 4 ;"
0102 " bne 2f ;"
0103 " tabort. 3 ;"
0104 "2: tend. ;"
0105 "3: mr %[unknown], 3 ;"
0106
0107 : [unknown] "=r" (unknown)
0108 :
0109 : "cr0", "r3", "r4", "r5", "r6", "r7", "vs31"
0110
0111 );
0112
0113
0114
0115
0116
0117
0118 fail_fp = unknown != 0x1;
0119 if (fail_fp)
0120 printf("Unknown value %#"PRIx64" leaked into f31!\n", unknown);
0121 else
0122 printf("Good, no poison or leaked value into FP registers\n");
0123
0124 asm (
0125
0126
0127
0128
0129 " li 3, 0x1 ;"
0130 " li 4, 0x1 ;"
0131 " mtvsrd 63, 4 ;"
0132
0133 " lis 5, 14 ;"
0134 " ori 5, 5, 19996 ;"
0135 " sldi 5, 5, 16 ;"
0136
0137 " mfspr 6, 268 ;"
0138 "1: mfspr 7, 268 ;"
0139 " subf 7, 6, 7 ;"
0140 " cmpd 7, 5 ;"
0141 " bgt 3f ;"
0142
0143
0144
0145
0146 " tbegin. ;"
0147 " beq 1b ;"
0148 " mfvsrd 3, 63 ;"
0149 " cmpd 3, 4 ;"
0150 " bne 2f ;"
0151 " tabort. 3 ;"
0152 "2: tend. ;"
0153 "3: mr %[unknown], 3 ;"
0154
0155 : [unknown] "=r" (unknown)
0156 :
0157 : "cr0", "r3", "r4", "r5", "r6", "r7", "vs63"
0158
0159 );
0160
0161
0162
0163
0164
0165
0166 fail_vr = unknown != 0x1;
0167 if (fail_vr)
0168 printf("Unknown value %#"PRIx64" leaked into vr31!\n", unknown);
0169 else
0170 printf("Good, no poison or leaked value into VEC registers\n");
0171
0172 kill(pid, SIGKILL);
0173
0174 return (fail_fp | fail_vr);
0175 }
0176
0177 int main(int argc, char *argv[])
0178 {
0179
0180 test_harness_set_timeout(250);
0181 return test_harness(tm_poison_test, "tm_poison_test");
0182 }