// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright 2015, Cyril Bur, IBM Corp. * * This test attempts to see if the VMX registers are correctly reported in a * signal context. Each worker just spins checking its VMX registers, at some * point a signal will interrupt it and C code will check the signal context * ensuring it is also the same.
*/
/* Number of times each thread should receive the signal */ #define ITERATIONS 10 /* * Factor by which to multiply number of online CPUs for total number of * worker threads
*/ #define THREAD_FACTOR 8
/* Only the non volatiles were loaded up */ for (i = 20; i < 32; i++) { if (memcmp(mc->v_regs->vrregs[i], &varray[i - 20], 16)) { int j; /* * Shouldn't printf() in a signal handler, however, this is a * test and we've detected failure. Understanding what failed * is paramount. All that happens after this is tests exit with * failure.
*/
printf("VMX mismatch at reg %d!\n", i);
printf("Reg | Actual | Expected\n"); for (j = 20; j < 32; j++) {
printf("%d | 0x%04x%04x%04x%04x | 0x%04x%04x%04x%04x\n", j, mc->v_regs->vrregs[j][0],
mc->v_regs->vrregs[j][1], mc->v_regs->vrregs[j][2], mc->v_regs->vrregs[j][3],
varray[j - 20][0], varray[j - 20][1], varray[j - 20][2], varray[j - 20][3]);
}
bad_context = true; break;
}
}
}
void *signal_vmx_c(void *p)
{ int i, j; long rc; struct sigaction act;
act.sa_sigaction = signal_vmx_sig;
act.sa_flags = SA_SIGINFO;
rc = sigaction(SIGUSR1, &act, NULL); if (rc) return p;
srand(pthread_self()); for (i = 0; i < 12; i++) for (j = 0; j < 4; j++)
varray[i][j] = rand();
running = true;
threads_starting = threads; for (i = 0; i < threads; i++) {
rc = pthread_create(&tids[i], NULL, signal_vmx_c, NULL);
FAIL_IF(rc);
}
setbuf(stdout, NULL);
printf("\tWaiting for %d workers to start... %d", threads, threads_starting); while (threads_starting) { asmvolatile("": : :"memory");
usleep(1000);
printf(", %d", threads_starting);
}
printf(" ...done\n");
printf("\tSending signals to all threads %d times...", ITERATIONS); for (i = 0; i < ITERATIONS; i++) { for (j = 0; j < threads; j++) {
pthread_kill(tids[j], SIGUSR1);
}
sleep(1);
}
printf("done\n");
printf("\tKilling workers...");
running = 0; for (i = 0; i < threads; i++) {
pthread_join(tids[i], &rc_p);
/* * Harness will say the fail was here, look at why signal_vmx * returned
*/ if ((long) rc_p || bad_context)
printf("oops\n"); if (bad_context)
fprintf(stderr, "\t!! bad_context is true\n");
FAIL_IF((long) rc_p || bad_context);
}
printf("done\n");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.