Date: Thu, 22 Apr 2021 11:08:11 GMT From: Alex Richardson <arichardson@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: b20f358a2de4 - stable/13 - tests/sys/kern/crc32: Check for SSE4.2 before using it Message-ID: <202104221108.13MB8B0Y088272@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by arichardson: URL: https://cgit.FreeBSD.org/src/commit/?id=b20f358a2de4fa442e8650f78187ad19764c7db8 commit b20f358a2de4fa442e8650f78187ad19764c7db8 Author: Alex Richardson <arichardson@FreeBSD.org> AuthorDate: 2021-02-02 09:52:52 +0000 Commit: Alex Richardson <arichardson@FreeBSD.org> CommitDate: 2021-04-22 09:41:09 +0000 tests/sys/kern/crc32: Check for SSE4.2 before using it This avoids a SIGILL when running these tests on QEMU (which defaults to a basic amd64 CPU without SSE4.2). This commit also tests the table-based implementations in addition to testing the hw-accelerated crc32 versions. Reviewed By: cem, kib, markj Differential Revision: https://reviews.freebsd.org/D28395 (cherry picked from commit 83c20b8a2da04937cf4af127366b3dc92c855784) --- sys/libkern/gsb_crc32.c | 16 ++++++--- sys/sys/gsb_crc32.h | 7 +++- tests/sys/kern/Makefile | 14 ++++---- tests/sys/kern/libkern_crc32.c | 73 ++++++++++++++++++++++++------------------ 4 files changed, 65 insertions(+), 45 deletions(-) diff --git a/sys/libkern/gsb_crc32.c b/sys/libkern/gsb_crc32.c index b2f7421c20eb..170ceb3aa710 100644 --- a/sys/libkern/gsb_crc32.c +++ b/sys/libkern/gsb_crc32.c @@ -46,11 +46,11 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> +#include <sys/gsb_crc32.h> #ifdef _KERNEL #include <sys/libkern.h> #include <sys/systm.h> -#include <sys/gsb_crc32.h> #if defined(__amd64__) || defined(__i386__) #include <machine/md_var.h> @@ -216,7 +216,10 @@ static const uint32_t crc32Table[256] = { 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L }; -static uint32_t +#ifndef TESTING +static +#endif +uint32_t singletable_crc32c(uint32_t crc, const void *buf, size_t size) { const uint8_t *p = buf; @@ -730,10 +733,13 @@ crc32c_sb8_64_bit(uint32_t crc, return crc; } -static uint32_t +#ifndef TESTING +static +#endif +uint32_t multitable_crc32c(uint32_t crc32c, - const unsigned char *buffer, - unsigned int length) + const void *buffer, + size_t length) { uint32_t to_even_word; diff --git a/sys/sys/gsb_crc32.h b/sys/sys/gsb_crc32.h index c5a42d3d3152..dc126a5258fb 100644 --- a/sys/sys/gsb_crc32.h +++ b/sys/sys/gsb_crc32.h @@ -32,10 +32,10 @@ crc32(const void *buf, size_t size) crc = crc32_raw(buf, size, ~0U); return (crc ^ ~0U); } +#endif uint32_t calculate_crc32c(uint32_t crc32c, const unsigned char *buffer, unsigned int length); -#endif #if defined(__amd64__) || defined(__i386__) uint32_t sse42_crc32c(uint32_t, const unsigned char *, unsigned); @@ -44,4 +44,9 @@ uint32_t sse42_crc32c(uint32_t, const unsigned char *, unsigned); uint32_t armv8_crc32c(uint32_t, const unsigned char *, unsigned int); #endif +#ifdef TESTING +uint32_t singletable_crc32c(uint32_t, const void *, size_t); +uint32_t multitable_crc32c(uint32_t, const void *, size_t); +#endif + #endif /* !_SYS_GSB_CRC32_H_ */ diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile index 1806d7ce8597..f350b740b7ea 100644 --- a/tests/sys/kern/Makefile +++ b/tests/sys/kern/Makefile @@ -56,15 +56,15 @@ NETBSD_ATF_TESTS_C+= sysv_test CFLAGS.mqueue_test+= -I${SRCTOP}/tests LIBADD.mqueue_test+= rt -.if ${MACHINE_ARCH} == "amd64" || \ - ${MACHINE_ARCH} == "i386" || \ - ${MACHINE_CPUARCH} == "aarch64" ATF_TESTS_C+= libkern_crc32 +SRCS.libkern_crc32+= libkern_crc32.c +.PATH: ${SRCTOP}/sys/libkern +SRCS.libkern_crc32+= gsb_crc32.c +CFLAGS.libkern_crc32+= -DTESTING .if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" -LDADD.libkern_crc32+= ${SRCTOP}/sys/libkern/x86/crc32_sse42.c -.else -LDADD.libkern_crc32+= ${SRCTOP}/sys/libkern/arm64/crc32c_armv8.S -.endif +SRCS.libkern_crc32+= ${SRCTOP}/sys/libkern/x86/crc32_sse42.c +.elif ${MACHINE_CPUARCH} == "aarch64" +SRCS.libkern_crc32+= ${SRCTOP}/sys/libkern/arm64/crc32c_armv8.S .endif # subr_unit.c contains functions whose prototypes lie in headers that cannot be diff --git a/tests/sys/kern/libkern_crc32.c b/tests/sys/kern/libkern_crc32.c index 39cb8ca5aeeb..dd9508e1ebd6 100644 --- a/tests/sys/kern/libkern_crc32.c +++ b/tests/sys/kern/libkern_crc32.c @@ -33,10 +33,46 @@ #include <atf-c.h> -#if !defined(__amd64__) && !defined(__i386__) && !defined(__aarch64__) -#error These tests are not supported on this platform +#if defined(__amd64__) || defined(__i386__) +#include <machine/cpufunc.h> +#include <machine/specialreg.h> + +static bool +have_sse42(void) +{ + u_int cpu_registers[4]; + + do_cpuid(1, cpu_registers); + + return ((cpu_registers[2] & CPUID2_SSE42) != 0); +} #endif +static void +check_crc32c(uint32_t expected, uint32_t crc32c, const void *buffer, + size_t length) +{ + uint32_t act; + +#if defined(__amd64__) || defined(__i386__) + if (have_sse42()) { + act = sse42_crc32c(crc32c, buffer, length); + ATF_CHECK_EQ_MSG(expected, act, + "sse42_crc32c expected 0x%08x, got 0x%08x", expected, act); + } +#elif defined(__aarch64__) + act = armv8_crc32c(crc32c, buffer, length); + ATF_CHECK_EQ_MSG(expected, act, + "armv8_crc32c expected 0x%08x, got 0x%08x", expected, act); +#endif + act = singletable_crc32c(crc32c, buffer, length); + ATF_CHECK_EQ_MSG(expected, act, + "singletable_crc32c expected 0x%08x, got 0x%08x", expected, act); + act = multitable_crc32c(crc32c, buffer, length); + ATF_CHECK_EQ_MSG(expected, act, + "multitable_crc32c expected 0x%08x, got 0x%08x", expected, act); +} + ATF_TC_WITHOUT_HEAD(crc32c_basic_correctness); ATF_TC_BODY(crc32c_basic_correctness, tc) { @@ -77,21 +113,11 @@ ATF_TC_BODY(crc32c_basic_correctness, tc) 0xfd562dc3, }; size_t i; - uint32_t act; ATF_REQUIRE(nitems(inputs) == nitems(results)); for (i = 0; i < nitems(inputs); i++) { -#if defined(__amd64__) || defined(__i386__) - act = sse42_crc32c(~0, (const void *)&inputs[i], - sizeof(inputs[0])); -#else - act = armv8_crc32c(~0, (const void *)&inputs[i], - sizeof(inputs[0])); -#endif - ATF_REQUIRE_MSG(act == results[i], - "crc32c(0x%jx) = 0x%08x, got 0x%08x", (uintmax_t)inputs[i], - results[i], act); + check_crc32c(results[i], ~0u, &inputs[i], sizeof(inputs[0])); } } @@ -102,20 +128,10 @@ ATF_TC_BODY(crc32c_alignment, tc) const uint32_t result = 0x2ce33ede; unsigned char buf[15]; size_t i; - uint32_t act; - for (i = 1; i < 8; i++) { memcpy(&buf[i], &input, sizeof(input)); - -#if defined(__amd64__) || defined(__i386__) - act = sse42_crc32c(~0, (const void *)&buf[i], sizeof(input)); -#else - act = armv8_crc32c(~0, (const void *)&buf[i], sizeof(input)); -#endif - ATF_REQUIRE_MSG(act == result, - "crc32c(0x%jx) = 0x%08x, got 0x%08x", (uintmax_t)input, - result, act); + check_crc32c(result, ~0u, &buf[i], sizeof(input)); } } @@ -127,15 +143,8 @@ ATF_TC_BODY(crc32c_trailing_bytes, tc) 0xd4, 0x4, 0x5e, 0xa9, 0xb3 }; const uint32_t result = 0xec638d62; - uint32_t act; -#if defined(__amd64__) || defined(__i386__) - act = sse42_crc32c(~0, input, sizeof(input)); -#else - act = armv8_crc32c(~0, input, sizeof(input)); -#endif - ATF_REQUIRE_MSG(act == result, "expected 0x%08x, got 0x%08x", result, - act); + check_crc32c(result, ~0u, input, sizeof(input)); } ATF_TP_ADD_TCS(tp)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202104221108.13MB8B0Y088272>