2 * Copyright 2015, Cyril Bur, IBM Corp.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * This test attempts to see if the VMX registers are correctly reported in a
10 * signal context. Each worker just spins checking its VMX registers, at some
11 * point a signal will interrupt it and C code will check the signal context
12 * ensuring it is also the same.
17 #include <sys/syscall.h>
19 #include <sys/types.h>
28 /* Number of times each thread should receive the signal */
31 * Factor by which to multiply number of online CPUs for total number of
34 #define THREAD_FACTOR 8
36 __thread vector
int varray
[] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10,11,12},
37 {13,14,15,16},{17,18,19,20},{21,22,23,24},
38 {25,26,27,28},{29,30,31,32},{33,34,35,36},
39 {37,38,39,40},{41,42,43,44},{45,46,47,48}};
45 extern int preempt_vmx(vector
int *varray
, int *threads_starting
, int *sentinal
);
47 void signal_vmx_sig(int sig
, siginfo_t
*info
, void *context
)
50 ucontext_t
*uc
= context
;
51 mcontext_t
*mc
= &uc
->uc_mcontext
;
53 /* Only the non volatiles were loaded up */
54 for (i
= 20; i
< 32; i
++) {
55 if (memcmp(mc
->v_regs
->vrregs
[i
], &varray
[i
- 20], 16)) {
58 * Shouldn't printf() in a signal handler, however, this is a
59 * test and we've detected failure. Understanding what failed
60 * is paramount. All that happens after this is tests exit with
63 printf("VMX mismatch at reg %d!\n", i
);
64 printf("Reg | Actual | Expected\n");
65 for (j
= 20; j
< 32; j
++) {
66 printf("%d | 0x%04x%04x%04x%04x | 0x%04x%04x%04x%04x\n", j
, mc
->v_regs
->vrregs
[j
][0],
67 mc
->v_regs
->vrregs
[j
][1], mc
->v_regs
->vrregs
[j
][2], mc
->v_regs
->vrregs
[j
][3],
68 varray
[j
- 20][0], varray
[j
- 20][1], varray
[j
- 20][2], varray
[j
- 20][3]);
76 void *signal_vmx_c(void *p
)
81 act
.sa_sigaction
= signal_vmx_sig
;
82 act
.sa_flags
= SA_SIGINFO
;
83 rc
= sigaction(SIGUSR1
, &act
, NULL
);
87 srand(pthread_self());
88 for (i
= 0; i
< 12; i
++)
89 for (j
= 0; j
< 4; j
++)
90 varray
[i
][j
] = rand();
92 rc
= preempt_vmx(varray
, &threads_starting
, &running
);
97 int test_signal_vmx(void)
99 int i
, j
, rc
, threads
;
103 threads
= sysconf(_SC_NPROCESSORS_ONLN
) * THREAD_FACTOR
;
104 tids
= malloc(threads
* sizeof(pthread_t
));
108 threads_starting
= threads
;
109 for (i
= 0; i
< threads
; i
++) {
110 rc
= pthread_create(&tids
[i
], NULL
, signal_vmx_c
, NULL
);
114 setbuf(stdout
, NULL
);
115 printf("\tWaiting for %d workers to start... %d", threads
, threads_starting
);
116 while (threads_starting
) {
117 asm volatile("": : :"memory");
119 printf(", %d", threads_starting
);
121 printf(" ...done\n");
123 printf("\tSending signals to all threads %d times...", ITERATIONS
);
124 for (i
= 0; i
< ITERATIONS
; i
++) {
125 for (j
= 0; j
< threads
; j
++) {
126 pthread_kill(tids
[j
], SIGUSR1
);
132 printf("\tKilling workers...");
134 for (i
= 0; i
< threads
; i
++) {
135 pthread_join(tids
[i
], &rc_p
);
138 * Harness will say the fail was here, look at why signal_vmx
141 if ((long) rc_p
|| bad_context
)
144 fprintf(stderr
, "\t!! bad_context is true\n");
145 FAIL_IF((long) rc_p
|| bad_context
);
153 int main(int argc
, char *argv
[])
155 return test_harness(test_signal_vmx
, "vmx_signal");