[PATCH 5/5] riscv: Test checksum functions

Charlie Jenkins charlie at rivosinc.com
Sat Aug 26 18:26:10 PDT 2023


Add Kconfig support for riscv specific testing modules. This was created
to supplement lib/checksum_kunit.c, and add tests for ip_fast_csum and
csum_ipv6_magic.

Signed-off-by: Charlie Jenkins <charlie at rivosinc.com>
---
 arch/riscv/Kconfig.debug              |   1 +
 arch/riscv/lib/Kconfig.debug          |  31 ++++++++++
 arch/riscv/lib/Makefile               |   2 +
 arch/riscv/lib/riscv_checksum_kunit.c | 111 ++++++++++++++++++++++++++++++++++
 4 files changed, 145 insertions(+)

diff --git a/arch/riscv/Kconfig.debug b/arch/riscv/Kconfig.debug
index e69de29bb2d1..53a84ec4f91f 100644
--- a/arch/riscv/Kconfig.debug
+++ b/arch/riscv/Kconfig.debug
@@ -0,0 +1 @@
+source "arch/riscv/lib/Kconfig.debug"
diff --git a/arch/riscv/lib/Kconfig.debug b/arch/riscv/lib/Kconfig.debug
new file mode 100644
index 000000000000..15fc83b68340
--- /dev/null
+++ b/arch/riscv/lib/Kconfig.debug
@@ -0,0 +1,31 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "riscv Testing and Coverage"
+
+menuconfig RUNTIME_TESTING_MENU
+	bool "Runtime Testing"
+	def_bool y
+	help
+	  Enable riscv runtime testing.
+
+if RUNTIME_TESTING_MENU
+
+config RISCV_CHECKSUM_KUNIT
+	tristate "KUnit test riscv checksum functions at runtime" if !KUNIT_ALL_TESTS
+	depends on KUNIT
+	default KUNIT_ALL_TESTS
+	help
+	  Enable this option to test the checksum functions at boot.
+
+	  KUnit tests run during boot and output the results to the debug log
+	  in TAP format (http://testanything.org/). Only useful for kernel devs
+	  running the KUnit test harness, and not intended for inclusion into a
+	  production build.
+
+	  For more information on KUnit and unit tests in general please refer
+	  to the KUnit documentation in Documentation/dev-tools/kunit/.
+
+	  If unsure, say N.
+
+endif # RUNTIME_TESTING_MENU
+
+endmenu # "riscv Testing and Coverage"
diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
index 2aa1a4ad361f..1535a8c81430 100644
--- a/arch/riscv/lib/Makefile
+++ b/arch/riscv/lib/Makefile
@@ -12,3 +12,5 @@ lib-$(CONFIG_64BIT)	+= tishift.o
 lib-$(CONFIG_RISCV_ISA_ZICBOZ)	+= clear_page.o
 
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION) += error-inject.o
+
+obj-$(CONFIG_RISCV_CHECKSUM_KUNIT) += riscv_checksum_kunit.o
diff --git a/arch/riscv/lib/riscv_checksum_kunit.c b/arch/riscv/lib/riscv_checksum_kunit.c
new file mode 100644
index 000000000000..05b4710c907f
--- /dev/null
+++ b/arch/riscv/lib/riscv_checksum_kunit.c
@@ -0,0 +1,111 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test cases for checksum
+ */
+
+#include <linux/in6.h>
+
+#include <kunit/test.h>
+#include <net/checksum.h>
+#include <net/ip6_checksum.h>
+
+#define CHECK_EQ(lhs, rhs) KUNIT_ASSERT_EQ(test, lhs, rhs)
+
+static void test_csum_fold(struct kunit *test)
+{
+	unsigned int one = 1226127848;
+	unsigned int two = 446627905;
+	unsigned int three = 3644783064;
+	unsigned int four = 361842745;
+	unsigned int five = 4281073503;
+	unsigned int max = -1;
+
+	CHECK_EQ(0x7d02, csum_fold(one));
+	CHECK_EQ(0xe51f, csum_fold(two));
+	CHECK_EQ(0x2ce8, csum_fold(three));
+	CHECK_EQ(0xa235, csum_fold(four));
+	CHECK_EQ(0x174, csum_fold(five));
+	CHECK_EQ(0x0, csum_fold(max));
+}
+
+static void test_ip_fast_csum(struct kunit *test)
+{
+	unsigned char *average = { 0x1c, 0x00, 0x00, 0x45, 0x00, 0x00, 0x68,
+				   0x74, 0x00, 0x00, 0x11, 0x80, 0x01, 0x64,
+				   0xa8, 0xc0, 0xe9, 0x9c, 0x46, 0xab };
+	unsigned char *larger = { 0xa3, 0xde, 0x43, 0x41, 0x11, 0x19,
+				  0x2f, 0x73, 0x00, 0x00, 0xf1, 0xc5,
+				  0x31, 0xbb, 0xaa, 0xc1, 0x23, 0x5f,
+				  0x32, 0xde, 0x65, 0x39, 0xfe, 0xbc };
+	unsigned char *overflow = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+				    0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+				    0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+	unsigned char *max = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff,
+			       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+			       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+			       0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff,
+			       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+			       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+			       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+	CHECK_EQ(0x598f, ip_fast_csum(average, 5));
+	CHECK_EQ(0xdd4f, ip_fast_csum(larger, 6));
+	CHECK_EQ(0xfffe, ip_fast_csum(overflow, 5));
+	CHECK_EQ(0x400, ip_fast_csum(max, 14));
+}
+
+static void test_csum_ipv6_magic(struct kunit *test)
+{
+	struct in6_addr saddr = {
+		.s6_addr = { 0xf8, 0x43, 0x43, 0xf0, 0xdc, 0xa0, 0x39, 0x92,
+			     0x43, 0x67, 0x12, 0x03, 0xe3, 0x32, 0xfe, 0xed }};
+	struct in6_addr daddr = {
+		.s6_addr = { 0xa8, 0x23, 0x46, 0xdc, 0xc8, 0x2d, 0xaa, 0xe3,
+			     0xdc, 0x66, 0x72, 0x43, 0xe2, 0x12, 0xee, 0xfd }};
+	u32 len = 1 << 10;
+	u8 proto = 17;
+	__wsum csum = 53;
+
+	CHECK_EQ(0x2fbb, csum_ipv6_magic(&saddr, &daddr, len, proto, csum));
+}
+
+static void test_do_csum(struct kunit *test)
+{
+	unsigned char *very_small = {0x32};
+	unsigned char *small = {0xd3, 0x43, 0xad, 0x46};
+	unsigned char *medium = {
+		0xa0, 0x13, 0xaa, 0xa6, 0x53, 0xac, 0xa3, 0x43
+	};
+	unsigned char *misaligned = medium + 1;
+	unsigned char *large = {
+		0xa0, 0x13, 0xaa, 0xa6, 0x53, 0xac, 0xa3, 0x43,
+		0xa0, 0x13, 0xaa, 0xa6, 0x53, 0xac, 0xa3, 0x43,
+		0xa0, 0x13, 0xaa, 0xa6, 0x53, 0xac, 0xa3, 0x43,
+		0xa0, 0x13, 0xaa, 0xa6, 0x53, 0xac, 0xa3, 0x43
+	};
+	unsigned char *large_misaligned = large + 3;
+
+	CHECK_EQ(0xffcd, ip_compute_csum(very_small, 1));
+	CHECK_EQ(0x757f, ip_compute_csum(small, 4));
+	CHECK_EQ(0x5e56, ip_compute_csum(misaligned, 7));
+	CHECK_EQ(0x469d, ip_compute_csum(large, 29));
+	CHECK_EQ(0x43ae, ip_compute_csum(large_misaligned, 28));
+}
+
+static struct kunit_case __refdata riscv_checksum_test_cases[] = {
+	KUNIT_CASE(test_csum_fold),
+	KUNIT_CASE(test_ip_fast_csum),
+	KUNIT_CASE(test_csum_ipv6_magic),
+	KUNIT_CASE(test_do_csum),
+	{}
+};
+
+static struct kunit_suite riscv_checksum_test_suite = {
+	.name = "riscv_checksum",
+	.test_cases = riscv_checksum_test_cases,
+};
+
+kunit_test_suites(&riscv_checksum_test_suite);
+
+MODULE_AUTHOR("Charlie Jenkins <charlie at rivosinc.com>");
+MODULE_LICENSE("GPL");

-- 
2.41.0




More information about the linux-riscv mailing list