git: 83c20b8a2da0 - main - tests/sys/kern/crc32: Check for SSE4.2 before using it

Alex Richardson arichardson at FreeBSD.org
Tue Feb 2 10:08:27 UTC 2021


The branch main has been updated by arichardson:

URL: https://cgit.FreeBSD.org/src/commit/?id=83c20b8a2da04937cf4af127366b3dc92c855784

commit 83c20b8a2da04937cf4af127366b3dc92c855784
Author:     Alex Richardson <arichardson at FreeBSD.org>
AuthorDate: 2021-02-02 09:52:52 +0000
Commit:     Alex Richardson <arichardson at FreeBSD.org>
CommitDate: 2021-02-02 09:53:39 +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
---
 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)


More information about the dev-commits-src-all mailing list