From nobody Mon Dec 13 02:33:15 2021 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 65EBC18E852A; Mon, 13 Dec 2021 02:33:16 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4JC5Cb6YR4z4b9h; Mon, 13 Dec 2021 02:33:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id C184C4A6C; Mon, 13 Dec 2021 02:33:15 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 1BD2XFEw032898; Mon, 13 Dec 2021 02:33:15 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 1BD2XFTb032897; Mon, 13 Dec 2021 02:33:15 GMT (envelope-from git) Date: Mon, 13 Dec 2021 02:33:15 GMT Message-Id: <202112130233.1BD2XFTb032897@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: 4626aa7fda0a - main - Add a tool to test AVX context integrity under ctx switches and signals (amd64) List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 4626aa7fda0a677a72a791056fd2d6cad68e944f Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1639362796; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Lt8XvWBGRa5RVfZilcRKDpL3TVfHOudl+bLmKIYqNME=; b=hZeCXSfplq51LCnrheumiWQyrfmtcEl3eGqIPKakHAOQmsZI1Mp6vP3yUj2g33EufyYUOJ qFSP+YsY+gKH9vHyYPg6eQaz2Yr9NG7FaF459JUXRC+pyQ6CeH0ONPxiuC6GCKRRcOxmkN LArE64crVfNWElmdl2TtsUuDFnaGerFiDgJTyRagSyuYVaUwpAR5ap9iTCmc3TYiNRwedx 8TNhG+LM63rn0FlhVS2bM48XfDBLMextwiainwcH15z4ypBHwMuCMBqkE6bxi8Y5XxToJN 29NxXElx5ZpgwiU5JY8b8o47Q1DYypvOtE1WbaJ6P6SEgSBOQy4GTJon79LkDg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1639362796; a=rsa-sha256; cv=none; b=cz3xs+0LDhOVg2wwxAoZebqqWzkwr4uqy+uYjU4zsk9yY1LrozqWNqXjuKbhRE2Rruoxzy GMJXxl9bWyXnK1PjGjSDQF7y1yDIfjQzwdIIJe4KOVGfpUIWV4A8lSFTKAu0XYXwm4sEtX GutNqIwt9JCH86wL9VZk7AuB7/I+/StSJb6i5q1ZWiB1KUtJKKw6NyUctg9N9LP2YaaNvd x3noG1o9ddFNjqSXZF3/aDJtv6Hko6uiQODGRncizilNdRclbIH4J/xHllhmeq2dFRboik M/z6u/2W9Wqo9qqG4gk3QIRj7hS9Vnh6IeRdjdvVh18pX5Z1GvcRIyJPkSUpsA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=4626aa7fda0a677a72a791056fd2d6cad68e944f commit 4626aa7fda0a677a72a791056fd2d6cad68e944f Author: Konstantin Belousov AuthorDate: 2021-12-13 02:31:40 +0000 Commit: Konstantin Belousov CommitDate: 2021-12-13 02:31:40 +0000 Add a tool to test AVX context integrity under ctx switches and signals (amd64) Sponsored by: The FreeBSD Foundation MFC after: 1 week --- tools/test/avx_sig/avx_sig.c | 220 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) diff --git a/tools/test/avx_sig/avx_sig.c b/tools/test/avx_sig/avx_sig.c new file mode 100644 index 000000000000..711d40f2c231 --- /dev/null +++ b/tools/test/avx_sig/avx_sig.c @@ -0,0 +1,220 @@ +/* $Id: avx_sig.c,v 1.12 2021/12/11 22:47:09 kostik Exp $ */ +/* + * Naive test to check that context switches and signal delivery do + * not corrupt AVX registers file (%xmm). Run until some + * inconsistency detected, then aborts. + * + * FreeBSD: + * ${CC} -Wall -Wextra -O -g -o avx_sig avx_sig.c -lpthread + * Linux + * ${CC} -D_GNU_SOURCE -Wall -Wextra -O -g -o avx_sig avx_sig.c -lbsd -lpthread + */ + +#include +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#endif +#ifdef __linux__ +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef __unused +#define __unused __attribute__((__unused__)) +#endif +#ifndef nitems +#define nitems(x) (sizeof((x)) / sizeof((x)[0])) +#endif + +struct xmmreg { + uint8_t xmm_bytes[16]; +}; + +struct xmm { + struct xmmreg xmmreg[16]; +}; + +#define X2C(r) asm("movdqu %0, %%xmm" #r : "=m" (xmm->xmmreg[r])) +#define C2X(r) asm("movdqu %%xmm" #r ", %0" : : "m" (xmm->xmmreg[r]) : "xmm" #r) + +static void +cpu_to_xmm(struct xmm *xmm) +{ + C2X(0); C2X(1); C2X(2); C2X(3); C2X(4); C2X(5); C2X(6); C2X(7); + C2X(8); C2X(9); C2X(10); C2X(11); C2X(12); C2X(13); C2X(14); C2X(15); +} + +static void +xmm_to_cpu(struct xmm *xmm) +{ + X2C(0); X2C(1); X2C(2); X2C(3); X2C(4); X2C(5); X2C(6); X2C(7); + X2C(8); X2C(9); X2C(10); X2C(11); X2C(12); X2C(13); X2C(14); X2C(15); +} + +#undef C2X +#undef X2C + +static atomic_uint sigs; + +static void +sigusr1_handler(int sig __unused, siginfo_t *si __unused, void *m __unused) +{ + atomic_fetch_add_explicit(&sigs, 1, memory_order_relaxed); +} + +#ifdef SIGINFO +static void +siginfo_handler(int sig __unused) +{ + struct rusage r; + + if (getrusage(RUSAGE_SELF, &r) == 0) { + printf("%lu vctx %lu nvctx %lu nsigs ", + r.ru_nvcsw, r.ru_nivcsw, r.ru_nsignals); + } + printf("%u SIGUSR1\n", sigs); +} +#endif + +static struct xmm zero_xmm = {}; + +static void +fill_xmm(struct xmm *xmm) +{ + arc4random_buf(xmm, sizeof(*xmm)); +} + +static void +dump_xmm(const struct xmmreg *r) +{ + unsigned k; + + for (k = 0; k < nitems(r->xmm_bytes); k++) { + if (k != 0) + printf(" "); + printf("%02x", r->xmm_bytes[k]); + } + printf("\n"); +} + +static pthread_mutex_t show_lock; + +static void +show_diff(const struct xmm *xmm1, const struct xmm *xmm2) +{ + const struct xmmreg *r1, *r2; + unsigned i, j; + +#if defined(__FreeBSD__) + printf("thr %d\n", pthread_getthreadid_np()); +#elif defined(__linux__) + printf("thr %ld\n", syscall(SYS_gettid)); +#endif + for (i = 0; i < nitems(xmm1->xmmreg); i++) { + r1 = &xmm1->xmmreg[i]; + r2 = &xmm2->xmmreg[i]; + for (j = 0; j < nitems(r1->xmm_bytes); j++) { + if (r1->xmm_bytes[j] != r2->xmm_bytes[j]) { + printf("xmm%u\n", i); + dump_xmm(r1); + dump_xmm(r2); + break; + } + } + } +} + +static void +my_pause(void) +{ + usleep(0); +} + +static void * +worker_thread(void *arg __unused) +{ + struct xmm xmm, xmm_cpu; + + fill_xmm(&xmm); + for (;;) { + xmm_to_cpu(&xmm); + my_pause(); + cpu_to_xmm(&xmm_cpu); + if (memcmp(&xmm, &xmm_cpu, sizeof(struct xmm)) != 0) { + pthread_mutex_lock(&show_lock); + show_diff(&xmm, &xmm_cpu); + abort(); + pthread_mutex_unlock(&show_lock); + } + + xmm_to_cpu(&zero_xmm); + my_pause(); + cpu_to_xmm(&xmm_cpu); + if (memcmp(&zero_xmm, &xmm_cpu, sizeof(struct xmm)) != 0) { + pthread_mutex_lock(&show_lock); + show_diff(&zero_xmm, &xmm_cpu); + abort(); + pthread_mutex_unlock(&show_lock); + } + } + return (NULL); +} + +int +main(void) +{ + struct sigaction sa; + int error, i, ncpu; + +#ifdef SIGINFO + bzero(&sa, sizeof(sa)); + sa.sa_handler = siginfo_handler; + if (sigaction(SIGINFO, &sa, NULL) == -1) { + fprintf(stderr, "sigaction SIGINFO %s\n", strerror(errno)); + exit(1); + } +#endif + + bzero(&sa, sizeof(sa)); + sa.sa_sigaction = sigusr1_handler; + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGUSR1, &sa, NULL) == -1) { + fprintf(stderr, "sigaction SIGUSR1 %s\n", strerror(errno)); + exit(1); + } + + error = pthread_mutex_init(&show_lock, NULL); + if (error != 0) { + fprintf(stderr, "pthread_mutex_init %s\n", strerror(error)); + exit(1); + } + + ncpu = sysconf(_SC_NPROCESSORS_ONLN); + ncpu *= 2; + pthread_t wt[ncpu]; + for (i = 0; i < ncpu; i++) { + error = pthread_create(&wt[i], NULL, worker_thread, NULL); + if (error != 0) { + fprintf(stderr, "pthread_create %s\n", strerror(error)); + } + } + + for (;;) { + for (i = 0; i < ncpu; i++) { + my_pause(); + pthread_kill(wt[i], SIGUSR1); + } + } +}