0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <stdlib.h>
0021 #include <stdio.h>
0022 #include <string.h>
0023 #include <signal.h>
0024 #include <unistd.h>
0025
0026 #include <altivec.h>
0027
0028 #include "utils.h"
0029 #include "tm.h"
0030
0031 #define MAX_ATTEMPT 500000
0032
0033 #define NV_VSX_REGS 12
0034 #define VSX20 20
0035 #define FPR20 20
0036
0037 long tm_signal_self_context_load(pid_t pid, long *gprs, double *fps, vector int *vms, vector int *vss);
0038
0039 static sig_atomic_t fail, broken;
0040
0041
0042 vector int vsxs[] = {
0043
0044
0045 { 1, 2, 3, 4},{ 5, 6, 7, 8},{ 9,10,11,12},
0046 {13,14,15,16},{17,18,19,20},{21,22,23,24},
0047 {25,26,27,28},{29,30,31,32},{33,34,35,36},
0048 {37,38,39,40},{41,42,43,44},{45,46,47,48},
0049
0050
0051 {-1, -2, -3, -4 },{-5, -6, -7, -8 },{-9, -10,-11,-12},
0052 {-13,-14,-15,-16},{-17,-18,-19,-20},{-21,-22,-23,-24},
0053 {-25,-26,-27,-28},{-29,-30,-31,-32},{-33,-34,-35,-36},
0054 {-37,-38,-39,-40},{-41,-42,-43,-44},{-45,-46,-47,-48}
0055 };
0056
0057 static void signal_usr1(int signum, siginfo_t *info, void *uc)
0058 {
0059 int i, j;
0060 uint8_t vsx[sizeof(vector int)];
0061 uint8_t vsx_tm[sizeof(vector int)];
0062 ucontext_t *ucp = uc;
0063 ucontext_t *tm_ucp = ucp->uc_link;
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096 long *vsx_ptr = (long *)(ucp->uc_mcontext.v_regs + 1);
0097 long *tm_vsx_ptr = (long *)(tm_ucp->uc_mcontext.v_regs + 1);
0098
0099
0100 for (i = 0; i < NV_VSX_REGS; i++) {
0101
0102
0103
0104
0105
0106 memcpy(vsx, &ucp->uc_mcontext.fp_regs[FPR20 + i], 8);
0107 memcpy(vsx + 8, &vsx_ptr[VSX20 + i], 8);
0108
0109 fail = memcmp(vsx, &vsxs[i], sizeof(vector int));
0110
0111 if (fail) {
0112 broken = 1;
0113 printf("VSX%d (1st context) == 0x", VSX20 + i);
0114 for (j = 0; j < 16; j++)
0115 printf("%02x", vsx[j]);
0116 printf(" instead of 0x");
0117 for (j = 0; j < 4; j++)
0118 printf("%08x", vsxs[i][j]);
0119 printf(" (expected)\n");
0120 }
0121 }
0122
0123
0124 for (i = 0; i < NV_VSX_REGS; i++) {
0125
0126
0127
0128
0129
0130 memcpy(vsx_tm, &tm_ucp->uc_mcontext.fp_regs[FPR20 + i], 8);
0131 memcpy(vsx_tm + 8, &tm_vsx_ptr[VSX20 + i], 8);
0132
0133 fail = memcmp(vsx_tm, &vsxs[NV_VSX_REGS + i], sizeof(vector int));
0134
0135 if (fail) {
0136 broken = 1;
0137 printf("VSX%d (2nd context) == 0x", VSX20 + i);
0138 for (j = 0; j < 16; j++)
0139 printf("%02x", vsx_tm[j]);
0140 printf(" instead of 0x");
0141 for (j = 0; j < 4; j++)
0142 printf("%08x", vsxs[NV_VSX_REGS + i][j]);
0143 printf("(expected)\n");
0144 }
0145 }
0146 }
0147
0148 static int tm_signal_context_chk()
0149 {
0150 struct sigaction act;
0151 int i;
0152 long rc;
0153 pid_t pid = getpid();
0154
0155 SKIP_IF(!have_htm());
0156 SKIP_IF(htm_is_synthetic());
0157
0158 act.sa_sigaction = signal_usr1;
0159 sigemptyset(&act.sa_mask);
0160 act.sa_flags = SA_SIGINFO;
0161 if (sigaction(SIGUSR1, &act, NULL) < 0) {
0162 perror("sigaction sigusr1");
0163 exit(1);
0164 }
0165
0166 i = 0;
0167 while (i < MAX_ATTEMPT && !broken) {
0168
0169
0170
0171
0172
0173
0174 rc = tm_signal_self_context_load(pid, NULL, NULL, NULL, vsxs);
0175 FAIL_IF(rc != pid);
0176 i++;
0177 }
0178
0179 return (broken);
0180 }
0181
0182 int main(void)
0183 {
0184 return test_harness(tm_signal_context_chk, "tm_signal_context_chk_vsx");
0185 }