+ lib-move-kunit-tests-into-tests-subdirectory.patch added to mm-nonmm-unstable branch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The patch titled
     Subject: lib: move KUnit tests into tests/ subdirectory
has been added to the -mm mm-nonmm-unstable branch.  Its filename is
     lib-move-kunit-tests-into-tests-subdirectory.patch

This patch will shortly appear at
     https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/lib-move-kunit-tests-into-tests-subdirectory.patch

This patch will later appear in the mm-nonmm-unstable branch at
    git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Before you just go and hit "reply", please:
   a) Consider who else should be cc'ed
   b) Prefer to cc a suitable mailing list as well
   c) Ideally: find the original patch on the mailing list and do a
      reply-to-all to that, adding suitable additional cc's

*** Remember to use Documentation/process/submit-checklist.rst when testing your code ***

The -mm tree is included into linux-next via the mm-everything
branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm
and is updated there every 2-3 working days

------------------------------------------------------
From: Kees Cook <kees@xxxxxxxxxx>
Subject: lib: move KUnit tests into tests/ subdirectory
Date: Fri, 11 Oct 2024 15:25:07 +0800

Following from the recent KUnit file naming discussion[1], move all KUnit
tests in lib/ into lib/tests/.

[davidgow@xxxxxxxxxx: rebased on top of mm-nonmm-unstable]
Link: https://lore.kernel.org/lkml/20240720165441.it.320-kees@xxxxxxxxxx/ [1]
Link: https://lkml.kernel.org/r/20241011072509.3068328-5-davidgow@xxxxxxxxxx
Signed-off-by: Kees Cook <kees@xxxxxxxxxx>
Signed-off-by: David Gow <davidgow@xxxxxxxxxx>
Acked-by: "Steven Rostedt (Google)" <rostedt@xxxxxxxxxxx>
Acked-by: Jakub Kicinski <kuba@xxxxxxxxxx>
Acked-by: "Masami Hiramatsu (Google)" <mhiramat@xxxxxxxxxx>
Reviewed-by: David Gow <davidgow@xxxxxxxxxx>
Acked-by: Shuah Khan <skhan@xxxxxxxxxxxxxxxxxxx>
Cc: Andy Shevchenko <andy@xxxxxxxxxx>
Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@xxxxxxxxx>
Cc: Arnd Bergmann <arnd@xxxxxxxx>
Cc: Brendan Higgins <brendanhiggins@xxxxxxxxxx>
Cc: Bruno Sobreira Fran=C3=A7a <brunofrancadevsec@xxxxxxxxx>
Cc: Charlie Jenkins <charlie@xxxxxxxxxxxx>
Cc: Christophe Leroy <christophe.leroy@xxxxxxxxxx>
Cc: Daniel Latypov <dlatypov@xxxxxxxxxx>
Cc: Danilo Pereira <dpereira@xxxxxxxxxx>
Cc: David Howells <dhowells@xxxxxxxxxx>
Cc: David S. Miller <davem@xxxxxxxxxxxxx>
Cc: Diego Vieira <diego.daniel.professional@xxxxxxxxx>
Cc: Fangrui Song <maskray@xxxxxxxxxx>
Cc: Gabriela Bittencourt <gbittencourt@xxxxxxxxxx>
Cc: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx>
Cc: Guenter Roeck <linux@xxxxxxxxxxxx>
Cc: Gustavo A. R. Silva <gustavoars@xxxxxxxxxx>
Cc: Jason A. Donenfeld <Jason@xxxxxxxxx>
Cc: Luis Felipe Hernandez <luis.hernandez093@xxxxxxxxx>
Cc: Marco Elver <elver@xxxxxxxxxx>
Cc: Mark Brown <broonie@xxxxxxxxxx>
Cc: Mark Rutland <mark.rutland@xxxxxxx>
Cc: Mickaël Salaün <mic@xxxxxxxxxxx>
Cc: Nathan Chancellor <nathan@xxxxxxxxxx>
Cc: Naveen N. Rao <naveen.n.rao@xxxxxxxxxxxxx>
Cc: Nicolas Pitre <npitre@xxxxxxxxxxxx>
Cc: Palmer Dabbelt <palmer@xxxxxxxxxxxx>
Cc: Pedro Orlando <porlando@xxxxxxxxxx>
Cc: Rae Moar <rmoar@xxxxxxxxxx>
Cc: Rasmus Villemoes <linux@xxxxxxxxxxxxxxxxxx>
Cc: Simon Horman <horms@xxxxxxxxxx>
Cc: Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx>
Cc: Vlastimil Babka <vbabka@xxxxxxx>
Cc: Yury Norov <yury.norov@xxxxxxxxx>
Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
---

 MAINTAINERS                      |   19 
 lib/Makefile                     |   37 
 lib/bitfield_kunit.c             |  155 --
 lib/checksum_kunit.c             |  640 ------------
 lib/cmdline_kunit.c              |  157 ---
 lib/cpumask_kunit.c              |  156 ---
 lib/fortify_kunit.c              | 1096 ---------------------
 lib/hashtable_test.c             |  318 ------
 lib/is_signed_type_kunit.c       |   50 
 lib/kunit_iov_iter.c             | 1036 -------------------
 lib/list-test.c                  | 1505 -----------------------------
 lib/memcpy_kunit.c               |  514 ---------
 lib/overflow_kunit.c             | 1240 -----------------------
 lib/siphash_kunit.c              |  198 ---
 lib/slub_kunit.c                 |  227 ----
 lib/stackinit_kunit.c            |  475 ---------
 lib/string_helpers_kunit.c       |  629 ------------
 lib/string_kunit.c               |  637 ------------
 lib/test_bits.c                  |  110 --
 lib/test_fprobe.c                |  275 -----
 lib/test_hash.c                  |  239 ----
 lib/test_kprobes.c               |  404 -------
 lib/test_linear_ranges.c         |  220 ----
 lib/test_list_sort.c             |  123 --
 lib/test_sort.c                  |   61 -
 lib/tests/Makefile               |   28 
 lib/tests/bitfield_kunit.c       |  155 ++
 lib/tests/checksum_kunit.c       |  640 ++++++++++++
 lib/tests/cmdline_kunit.c        |  157 +++
 lib/tests/cpumask_kunit.c        |  156 +++
 lib/tests/fortify_kunit.c        | 1096 +++++++++++++++++++++
 lib/tests/hashtable_test.c       |  318 ++++++
 lib/tests/is_signed_type_kunit.c |   50 
 lib/tests/kunit_iov_iter.c       | 1036 +++++++++++++++++++
 lib/tests/list-test.c            | 1505 +++++++++++++++++++++++++++++
 lib/tests/memcpy_kunit.c         |  514 +++++++++
 lib/tests/overflow_kunit.c       | 1240 +++++++++++++++++++++++
 lib/tests/siphash_kunit.c        |  198 +++
 lib/tests/slub_kunit.c           |  227 ++++
 lib/tests/stackinit_kunit.c      |  475 +++++++++
 lib/tests/string_helpers_kunit.c |  629 ++++++++++++
 lib/tests/string_kunit.c         |  637 ++++++++++++
 lib/tests/test_bits.c            |  110 ++
 lib/tests/test_fprobe.c          |  275 +++++
 lib/tests/test_hash.c            |  239 ++++
 lib/tests/test_kprobes.c         |  404 +++++++
 lib/tests/test_linear_ranges.c   |  220 ++++
 lib/tests/test_list_sort.c       |  123 ++
 lib/tests/test_sort.c            |   61 +
 lib/tests/usercopy_kunit.c       |  335 ++++++
 lib/usercopy_kunit.c             |  335 ------
 51 files changed, 10839 insertions(+), 10845 deletions(-)

diff --git a/lib/bitfield_kunit.c a/lib/bitfield_kunit.c
deleted file mode 100644
--- a/lib/bitfield_kunit.c
+++ /dev/null
@@ -1,155 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Test cases for bitfield helpers.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <kunit/test.h>
-#include <linux/bitfield.h>
-
-#define CHECK_ENC_GET_U(tp, v, field, res) do {				\
-		{							\
-			u##tp _res;					\
-									\
-			_res = u##tp##_encode_bits(v, field);		\
-			KUNIT_ASSERT_FALSE_MSG(context, _res != res,	\
-				       "u" #tp "_encode_bits(" #v ", " #field ") is 0x%llx != " #res "\n",	\
-				       (u64)_res);			\
-			KUNIT_ASSERT_FALSE(context,			\
-				   u##tp##_get_bits(_res, field) != v);	\
-		}							\
-	} while (0)
-
-#define CHECK_ENC_GET_LE(tp, v, field, res) do {			\
-		{							\
-			__le##tp _res;					\
-									\
-			_res = le##tp##_encode_bits(v, field);		\
-			KUNIT_ASSERT_FALSE_MSG(context,			\
-				       _res != cpu_to_le##tp(res),	\
-				       "le" #tp "_encode_bits(" #v ", " #field ") is 0x%llx != 0x%llx",\
-				       (u64)le##tp##_to_cpu(_res),	\
-				       (u64)(res));			\
-			KUNIT_ASSERT_FALSE(context,			\
-				   le##tp##_get_bits(_res, field) != v);\
-		}							\
-	} while (0)
-
-#define CHECK_ENC_GET_BE(tp, v, field, res) do {			\
-		{							\
-			__be##tp _res;					\
-									\
-			_res = be##tp##_encode_bits(v, field);		\
-			KUNIT_ASSERT_FALSE_MSG(context,			\
-				       _res != cpu_to_be##tp(res),	\
-				       "be" #tp "_encode_bits(" #v ", " #field ") is 0x%llx != 0x%llx",	\
-				       (u64)be##tp##_to_cpu(_res),	\
-				       (u64)(res));			\
-			KUNIT_ASSERT_FALSE(context,			\
-				   be##tp##_get_bits(_res, field) != v);\
-		}							\
-	} while (0)
-
-#define CHECK_ENC_GET(tp, v, field, res) do {				\
-		CHECK_ENC_GET_U(tp, v, field, res);			\
-		CHECK_ENC_GET_LE(tp, v, field, res);			\
-		CHECK_ENC_GET_BE(tp, v, field, res);			\
-	} while (0)
-
-static void __init test_bitfields_constants(struct kunit *context)
-{
-	/*
-	 * NOTE
-	 * This whole function compiles (or at least should, if everything
-	 * is going according to plan) to nothing after optimisation.
-	 */
-
-	CHECK_ENC_GET(16,  1, 0x000f, 0x0001);
-	CHECK_ENC_GET(16,  3, 0x00f0, 0x0030);
-	CHECK_ENC_GET(16,  5, 0x0f00, 0x0500);
-	CHECK_ENC_GET(16,  7, 0xf000, 0x7000);
-	CHECK_ENC_GET(16, 14, 0x000f, 0x000e);
-	CHECK_ENC_GET(16, 15, 0x00f0, 0x00f0);
-
-	CHECK_ENC_GET_U(8,  1, 0x0f, 0x01);
-	CHECK_ENC_GET_U(8,  3, 0xf0, 0x30);
-	CHECK_ENC_GET_U(8, 14, 0x0f, 0x0e);
-	CHECK_ENC_GET_U(8, 15, 0xf0, 0xf0);
-
-	CHECK_ENC_GET(32,  1, 0x00000f00, 0x00000100);
-	CHECK_ENC_GET(32,  3, 0x0000f000, 0x00003000);
-	CHECK_ENC_GET(32,  5, 0x000f0000, 0x00050000);
-	CHECK_ENC_GET(32,  7, 0x00f00000, 0x00700000);
-	CHECK_ENC_GET(32, 14, 0x0f000000, 0x0e000000);
-	CHECK_ENC_GET(32, 15, 0xf0000000, 0xf0000000);
-
-	CHECK_ENC_GET(64,  1, 0x00000f0000000000ull, 0x0000010000000000ull);
-	CHECK_ENC_GET(64,  3, 0x0000f00000000000ull, 0x0000300000000000ull);
-	CHECK_ENC_GET(64,  5, 0x000f000000000000ull, 0x0005000000000000ull);
-	CHECK_ENC_GET(64,  7, 0x00f0000000000000ull, 0x0070000000000000ull);
-	CHECK_ENC_GET(64, 14, 0x0f00000000000000ull, 0x0e00000000000000ull);
-	CHECK_ENC_GET(64, 15, 0xf000000000000000ull, 0xf000000000000000ull);
-}
-
-#define CHECK(tp, mask) do {						\
-		u64 v;							\
-									\
-		for (v = 0; v < 1 << hweight32(mask); v++)		\
-			KUNIT_ASSERT_FALSE(context,			\
-				tp##_encode_bits(v, mask) != v << __ffs64(mask));\
-	} while (0)
-
-static void __init test_bitfields_variables(struct kunit *context)
-{
-	CHECK(u8, 0x0f);
-	CHECK(u8, 0xf0);
-	CHECK(u8, 0x38);
-
-	CHECK(u16, 0x0038);
-	CHECK(u16, 0x0380);
-	CHECK(u16, 0x3800);
-	CHECK(u16, 0x8000);
-
-	CHECK(u32, 0x80000000);
-	CHECK(u32, 0x7f000000);
-	CHECK(u32, 0x07e00000);
-	CHECK(u32, 0x00018000);
-
-	CHECK(u64, 0x8000000000000000ull);
-	CHECK(u64, 0x7f00000000000000ull);
-	CHECK(u64, 0x0001800000000000ull);
-	CHECK(u64, 0x0000000080000000ull);
-	CHECK(u64, 0x000000007f000000ull);
-	CHECK(u64, 0x0000000018000000ull);
-	CHECK(u64, 0x0000001f8000000ull);
-}
-
-#ifdef TEST_BITFIELD_COMPILE
-static void __init test_bitfields_compile(struct kunit *context)
-{
-	/* these should fail compilation */
-	CHECK_ENC_GET(16, 16, 0x0f00, 0x1000);
-	u32_encode_bits(7, 0x06000000);
-
-	/* this should at least give a warning */
-	u16_encode_bits(0, 0x60000);
-}
-#endif
-
-static struct kunit_case __refdata bitfields_test_cases[] = {
-	KUNIT_CASE(test_bitfields_constants),
-	KUNIT_CASE(test_bitfields_variables),
-	{}
-};
-
-static struct kunit_suite bitfields_test_suite = {
-	.name = "bitfields",
-	.test_cases = bitfields_test_cases,
-};
-
-kunit_test_suites(&bitfields_test_suite);
-
-MODULE_AUTHOR("Johannes Berg <johannes@xxxxxxxxxxxxxxxx>");
-MODULE_DESCRIPTION("Test cases for bitfield helpers");
-MODULE_LICENSE("GPL");
diff --git a/lib/checksum_kunit.c a/lib/checksum_kunit.c
deleted file mode 100644
--- a/lib/checksum_kunit.c
+++ /dev/null
@@ -1,640 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Test cases csum_partial, csum_fold, ip_fast_csum, csum_ipv6_magic
- */
-
-#include <kunit/test.h>
-#include <asm/checksum.h>
-#include <net/ip6_checksum.h>
-
-#define MAX_LEN 512
-#define MAX_ALIGN 64
-#define TEST_BUFLEN (MAX_LEN + MAX_ALIGN)
-
-#define IPv4_MIN_WORDS 5
-#define IPv4_MAX_WORDS 15
-#define NUM_IPv6_TESTS 200
-#define NUM_IP_FAST_CSUM_TESTS 181
-
-/* Values for a little endian CPU. Byte swap each half on big endian CPU. */
-static const u32 random_init_sum = 0x2847aab;
-static const u8 random_buf[] = {
-	0xac, 0xd7, 0x76, 0x69, 0x6e, 0xf2, 0x93, 0x2c, 0x1f, 0xe0, 0xde, 0x86,
-	0x8f, 0x54, 0x33, 0x90, 0x95, 0xbf, 0xff, 0xb9, 0xea, 0x62, 0x6e, 0xb5,
-	0xd3, 0x4f, 0xf5, 0x60, 0x50, 0x5c, 0xc7, 0xfa, 0x6d, 0x1a, 0xc7, 0xf0,
-	0xd2, 0x2c, 0x12, 0x3d, 0x88, 0xe3, 0x14, 0x21, 0xb1, 0x5e, 0x45, 0x31,
-	0xa2, 0x85, 0x36, 0x76, 0xba, 0xd8, 0xad, 0xbb, 0x9e, 0x49, 0x8f, 0xf7,
-	0xce, 0xea, 0xef, 0xca, 0x2c, 0x29, 0xf7, 0x15, 0x5c, 0x1d, 0x4d, 0x09,
-	0x1f, 0xe2, 0x14, 0x31, 0x8c, 0x07, 0x57, 0x23, 0x1f, 0x6f, 0x03, 0xe1,
-	0x93, 0x19, 0x53, 0x03, 0x45, 0x49, 0x9a, 0x3b, 0x8e, 0x0c, 0x12, 0x5d,
-	0x8a, 0xb8, 0x9b, 0x8c, 0x9a, 0x03, 0xe5, 0xa2, 0x43, 0xd2, 0x3b, 0x4e,
-	0x7e, 0x30, 0x3c, 0x22, 0x2d, 0xc5, 0xfc, 0x9e, 0xdb, 0xc6, 0xf9, 0x69,
-	0x12, 0x39, 0x1f, 0xa0, 0x11, 0x0c, 0x3f, 0xf5, 0x53, 0xc9, 0x30, 0xfb,
-	0xb0, 0xdd, 0x21, 0x1d, 0x34, 0xe2, 0x65, 0x30, 0xf1, 0xe8, 0x1b, 0xe7,
-	0x55, 0x0d, 0xeb, 0xbd, 0xcc, 0x9d, 0x24, 0xa4, 0xad, 0xa7, 0x93, 0x47,
-	0x19, 0x2e, 0xc4, 0x5c, 0x3b, 0xc7, 0x6d, 0x95, 0x0c, 0x47, 0x60, 0xaf,
-	0x5b, 0x47, 0xee, 0xdc, 0x31, 0x31, 0x14, 0x12, 0x7e, 0x9e, 0x45, 0xb1,
-	0xc1, 0x69, 0x4b, 0x84, 0xfc, 0x88, 0xc1, 0x9e, 0x46, 0xb4, 0xc2, 0x25,
-	0xc5, 0x6c, 0x4c, 0x22, 0x58, 0x5c, 0xbe, 0xff, 0xea, 0x88, 0x88, 0x7a,
-	0xcb, 0x1c, 0x5d, 0x63, 0xa1, 0xf2, 0x33, 0x0c, 0xa2, 0x16, 0x0b, 0x6e,
-	0x2b, 0x79, 0x58, 0xf7, 0xac, 0xd3, 0x6a, 0x3f, 0x81, 0x57, 0x48, 0x45,
-	0xe3, 0x7c, 0xdc, 0xd6, 0x34, 0x7e, 0xe6, 0x73, 0xfa, 0xcb, 0x31, 0x18,
-	0xa9, 0x0b, 0xee, 0x6b, 0x99, 0xb9, 0x2d, 0xde, 0x22, 0x0e, 0x71, 0x57,
-	0x0e, 0x9b, 0x11, 0xd1, 0x15, 0x41, 0xd0, 0x6b, 0x50, 0x8a, 0x23, 0x64,
-	0xe3, 0x9c, 0xb3, 0x55, 0x09, 0xe9, 0x32, 0x67, 0xf9, 0xe0, 0x73, 0xf1,
-	0x60, 0x66, 0x0b, 0x88, 0x79, 0x8d, 0x4b, 0x52, 0x83, 0x20, 0x26, 0x78,
-	0x49, 0x27, 0xe7, 0x3e, 0x29, 0xa8, 0x18, 0x82, 0x41, 0xdd, 0x1e, 0xcc,
-	0x3b, 0xc4, 0x65, 0xd1, 0x21, 0x40, 0x72, 0xb2, 0x87, 0x5e, 0x16, 0x10,
-	0x80, 0x3f, 0x4b, 0x58, 0x1c, 0xc2, 0x79, 0x20, 0xf0, 0xe0, 0x80, 0xd3,
-	0x52, 0xa5, 0x19, 0x6e, 0x47, 0x90, 0x08, 0xf5, 0x50, 0xe2, 0xd6, 0xae,
-	0xe9, 0x2e, 0xdc, 0xd5, 0xb4, 0x90, 0x1f, 0x79, 0x49, 0x82, 0x21, 0x84,
-	0xa0, 0xb5, 0x2f, 0xff, 0x30, 0x71, 0xed, 0x80, 0x68, 0xb1, 0x6d, 0xef,
-	0xf6, 0xcf, 0xb8, 0x41, 0x79, 0xf5, 0x01, 0xbc, 0x0c, 0x9b, 0x0e, 0x06,
-	0xf3, 0xb0, 0xbb, 0x97, 0xb8, 0xb1, 0xfd, 0x51, 0x4e, 0xef, 0x0a, 0x3d,
-	0x7a, 0x3d, 0xbd, 0x61, 0x00, 0xa2, 0xb3, 0xf0, 0x1d, 0x77, 0x7b, 0x6c,
-	0x01, 0x61, 0xa5, 0xa3, 0xdb, 0xd5, 0xd5, 0xf4, 0xb5, 0x28, 0x9f, 0x0a,
-	0xa3, 0x82, 0x5f, 0x4b, 0x40, 0x0f, 0x05, 0x0e, 0x78, 0xed, 0xbf, 0x17,
-	0xf6, 0x5a, 0x8a, 0x7d, 0xf9, 0x45, 0xc1, 0xd7, 0x1b, 0x9d, 0x6c, 0x07,
-	0x88, 0xf3, 0xbc, 0xf1, 0xea, 0x28, 0x1f, 0xb8, 0x7a, 0x60, 0x3c, 0xce,
-	0x3e, 0x50, 0xb2, 0x0b, 0xcf, 0xe5, 0x08, 0x1f, 0x48, 0x04, 0xf9, 0x35,
-	0x29, 0x15, 0xbe, 0x82, 0x96, 0xc2, 0x55, 0x04, 0x6c, 0x19, 0x45, 0x29,
-	0x0b, 0xb6, 0x49, 0x12, 0xfb, 0x8d, 0x1b, 0x75, 0x8b, 0xd9, 0x6a, 0x5c,
-	0xbe, 0x46, 0x2b, 0x41, 0xfe, 0x21, 0xad, 0x1f, 0x75, 0xe7, 0x90, 0x3d,
-	0xe1, 0xdf, 0x4b, 0xe1, 0x81, 0xe2, 0x17, 0x02, 0x7b, 0x58, 0x8b, 0x92,
-	0x1a, 0xac, 0x46, 0xdd, 0x2e, 0xce, 0x40, 0x09
-};
-
-/* Values for a little endian CPU. Byte swap on big endian CPU. */
-static const u16 expected_results[] = {
-	0x82d0, 0x8224, 0xab23, 0xaaad, 0x41ad, 0x413f, 0x4f3e, 0x4eab, 0x22ab,
-	0x228c, 0x428b, 0x41ad, 0xbbac, 0xbb1d, 0x671d, 0x66ea, 0xd6e9, 0xd654,
-	0x1754, 0x1655, 0x5d54, 0x5c6a, 0xfa69, 0xf9fb, 0x44fb, 0x4428, 0xf527,
-	0xf432, 0x9432, 0x93e2, 0x37e2, 0x371b, 0x3d1a, 0x3cad, 0x22ad, 0x21e6,
-	0x31e5, 0x3113, 0x0513, 0x0501, 0xc800, 0xc778, 0xe477, 0xe463, 0xc363,
-	0xc2b2, 0x64b2, 0x646d, 0x336d, 0x32cb, 0xadca, 0xad94, 0x3794, 0x36da,
-	0x5ed9, 0x5e2c, 0xa32b, 0xa28d, 0x598d, 0x58fe, 0x61fd, 0x612f, 0x772e,
-	0x763f, 0xac3e, 0xac12, 0x8312, 0x821b, 0x6d1b, 0x6cbf, 0x4fbf, 0x4f72,
-	0x4672, 0x4653, 0x6452, 0x643e, 0x333e, 0x32b2, 0x2bb2, 0x2b5b, 0x085b,
-	0x083c, 0x993b, 0x9938, 0xb837, 0xb7a4, 0x9ea4, 0x9e51, 0x9b51, 0x9b0c,
-	0x520c, 0x5172, 0x1672, 0x15e4, 0x09e4, 0x09d2, 0xacd1, 0xac47, 0xf446,
-	0xf3ab, 0x67ab, 0x6711, 0x6411, 0x632c, 0xc12b, 0xc0e8, 0xeee7, 0xeeac,
-	0xa0ac, 0xa02e, 0x702e, 0x6ff2, 0x4df2, 0x4dc5, 0x88c4, 0x87c8, 0xe9c7,
-	0xe8ec, 0x22ec, 0x21f3, 0xb8f2, 0xb8e0, 0x7fe0, 0x7fc1, 0xdfc0, 0xdfaf,
-	0xd3af, 0xd370, 0xde6f, 0xde1c, 0x151c, 0x14ec, 0x19eb, 0x193b, 0x3c3a,
-	0x3c19, 0x1f19, 0x1ee5, 0x3ce4, 0x3c7f, 0x0c7f, 0x0b8e, 0x238d, 0x2372,
-	0x3c71, 0x3c1c, 0x2f1c, 0x2e31, 0x7130, 0x7064, 0xd363, 0xd33f, 0x2f3f,
-	0x2e92, 0x8791, 0x86fe, 0x3ffe, 0x3fe5, 0x11e5, 0x1121, 0xb520, 0xb4e5,
-	0xede4, 0xed77, 0x5877, 0x586b, 0x116b, 0x110b, 0x620a, 0x61af, 0x1aaf,
-	0x19c1, 0x3dc0, 0x3d8f, 0x0c8f, 0x0c7b, 0xfa7a, 0xf9fc, 0x5bfc, 0x5bb7,
-	0xaab6, 0xa9f5, 0x40f5, 0x40aa, 0xbca9, 0xbbad, 0x33ad, 0x32ec, 0x94eb,
-	0x94a5, 0xe0a4, 0xdfe2, 0xbae2, 0xba1d, 0x4e1d, 0x4dd1, 0x2bd1, 0x2b79,
-	0xcf78, 0xceba, 0xcfb9, 0xcecf, 0x46cf, 0x4647, 0xcc46, 0xcb7b, 0xaf7b,
-	0xaf1e, 0x4c1e, 0x4b7d, 0x597c, 0x5949, 0x4d49, 0x4ca7, 0x36a7, 0x369c,
-	0xc89b, 0xc870, 0x4f70, 0x4f18, 0x5817, 0x576b, 0x846a, 0x8400, 0x4500,
-	0x447f, 0xed7e, 0xed36, 0xa836, 0xa753, 0x2b53, 0x2a77, 0x5476, 0x5442,
-	0xd641, 0xd55b, 0x625b, 0x6161, 0x9660, 0x962f, 0x7e2f, 0x7d86, 0x7286,
-	0x7198, 0x0698, 0x05ff, 0x4cfe, 0x4cd1, 0x6ed0, 0x6eae, 0x60ae, 0x603d,
-	0x093d, 0x092f, 0x6e2e, 0x6e1d, 0x9d1c, 0x9d07, 0x5c07, 0x5b37, 0xf036,
-	0xefe6, 0x65e6, 0x65c3, 0x01c3, 0x00e0, 0x64df, 0x642c, 0x0f2c, 0x0f23,
-	0x2622, 0x25f0, 0xbeef, 0xbdf6, 0xddf5, 0xdd82, 0xec81, 0xec21, 0x8621,
-	0x8616, 0xfe15, 0xfd9c, 0x709c, 0x7051, 0x1e51, 0x1dce, 0xfdcd, 0xfda7,
-	0x85a7, 0x855e, 0x5e5e, 0x5d77, 0x1f77, 0x1f4e, 0x774d, 0x7735, 0xf534,
-	0xf4f3, 0x17f3, 0x17d5, 0x4bd4, 0x4b99, 0x8798, 0x8733, 0xb632, 0xb611,
-	0x7611, 0x759f, 0xc39e, 0xc317, 0x6517, 0x6501, 0x5501, 0x5481, 0x1581,
-	0x1536, 0xbd35, 0xbd19, 0xfb18, 0xfa9f, 0xda9f, 0xd9af, 0xf9ae, 0xf92e,
-	0x262e, 0x25dc, 0x80db, 0x80c2, 0x12c2, 0x127b, 0x827a, 0x8272, 0x8d71,
-	0x8d21, 0xab20, 0xaa4a, 0xfc49, 0xfb60, 0xcd60, 0xcc84, 0xf783, 0xf6cf,
-	0x66cf, 0x66b0, 0xedaf, 0xed66, 0x6b66, 0x6b45, 0xe744, 0xe6a4, 0x31a4,
-	0x3175, 0x3274, 0x3244, 0xc143, 0xc056, 0x4056, 0x3fee, 0x8eed, 0x8e80,
-	0x9f7f, 0x9e89, 0xcf88, 0xced0, 0x8dd0, 0x8d57, 0x9856, 0x9855, 0xdc54,
-	0xdc48, 0x4148, 0x413a, 0x3b3a, 0x3a47, 0x8a46, 0x898b, 0xf28a, 0xf1d2,
-	0x40d2, 0x3fd5, 0xeed4, 0xee86, 0xff85, 0xff7b, 0xc27b, 0xc201, 0x8501,
-	0x8444, 0x2344, 0x2344, 0x8143, 0x8090, 0x908f, 0x9072, 0x1972, 0x18f7,
-	0xacf6, 0xacf5, 0x4bf5, 0x4b50, 0xa84f, 0xa774, 0xd273, 0xd19e, 0xdd9d,
-	0xdce8, 0xb4e8, 0xb449, 0xaa49, 0xa9a6, 0x27a6, 0x2747, 0xdc46, 0xdc06,
-	0xcd06, 0xcd01, 0xbf01, 0xbe89, 0xd188, 0xd0c9, 0xb9c9, 0xb8d3, 0x5ed3,
-	0x5e49, 0xe148, 0xe04f, 0x9b4f, 0x9a8e, 0xc38d, 0xc372, 0x2672, 0x2606,
-	0x1f06, 0x1e7e, 0x2b7d, 0x2ac1, 0x39c0, 0x38d6, 0x10d6, 0x10b7, 0x58b6,
-	0x583c, 0xf83b, 0xf7ff, 0x29ff, 0x29c1, 0xd9c0, 0xd90e, 0xce0e, 0xcd3f,
-	0xe83e, 0xe836, 0xc936, 0xc8ee, 0xc4ee, 0xc3f5, 0x8ef5, 0x8ecc, 0x79cc,
-	0x790e, 0xf70d, 0xf677, 0x3477, 0x3422, 0x3022, 0x2fb6, 0x16b6, 0x1671,
-	0xed70, 0xed65, 0x3765, 0x371c, 0x251c, 0x2421, 0x9720, 0x9705, 0x2205,
-	0x217a, 0x4879, 0x480f, 0xec0e, 0xeb50, 0xa550, 0xa525, 0x6425, 0x6327,
-	0x4227, 0x417a, 0x227a, 0x2205, 0x3b04, 0x3a74, 0xfd73, 0xfc92, 0x1d92,
-	0x1d47, 0x3c46, 0x3bc5, 0x59c4, 0x59ad, 0x57ad, 0x5732, 0xff31, 0xfea6,
-	0x6ca6, 0x6c8c, 0xc08b, 0xc045, 0xe344, 0xe316, 0x1516, 0x14d6,
-};
-
-/* Values for a little endian CPU. Byte swap each half on big endian CPU. */
-static const u32 init_sums_no_overflow[] = {
-	0xffffffff, 0xfffffffb, 0xfffffbfb, 0xfffffbf7, 0xfffff7f7, 0xfffff7f3,
-	0xfffff3f3, 0xfffff3ef, 0xffffefef, 0xffffefeb, 0xffffebeb, 0xffffebe7,
-	0xffffe7e7, 0xffffe7e3, 0xffffe3e3, 0xffffe3df, 0xffffdfdf, 0xffffdfdb,
-	0xffffdbdb, 0xffffdbd7, 0xffffd7d7, 0xffffd7d3, 0xffffd3d3, 0xffffd3cf,
-	0xffffcfcf, 0xffffcfcb, 0xffffcbcb, 0xffffcbc7, 0xffffc7c7, 0xffffc7c3,
-	0xffffc3c3, 0xffffc3bf, 0xffffbfbf, 0xffffbfbb, 0xffffbbbb, 0xffffbbb7,
-	0xffffb7b7, 0xffffb7b3, 0xffffb3b3, 0xffffb3af, 0xffffafaf, 0xffffafab,
-	0xffffabab, 0xffffaba7, 0xffffa7a7, 0xffffa7a3, 0xffffa3a3, 0xffffa39f,
-	0xffff9f9f, 0xffff9f9b, 0xffff9b9b, 0xffff9b97, 0xffff9797, 0xffff9793,
-	0xffff9393, 0xffff938f, 0xffff8f8f, 0xffff8f8b, 0xffff8b8b, 0xffff8b87,
-	0xffff8787, 0xffff8783, 0xffff8383, 0xffff837f, 0xffff7f7f, 0xffff7f7b,
-	0xffff7b7b, 0xffff7b77, 0xffff7777, 0xffff7773, 0xffff7373, 0xffff736f,
-	0xffff6f6f, 0xffff6f6b, 0xffff6b6b, 0xffff6b67, 0xffff6767, 0xffff6763,
-	0xffff6363, 0xffff635f, 0xffff5f5f, 0xffff5f5b, 0xffff5b5b, 0xffff5b57,
-	0xffff5757, 0xffff5753, 0xffff5353, 0xffff534f, 0xffff4f4f, 0xffff4f4b,
-	0xffff4b4b, 0xffff4b47, 0xffff4747, 0xffff4743, 0xffff4343, 0xffff433f,
-	0xffff3f3f, 0xffff3f3b, 0xffff3b3b, 0xffff3b37, 0xffff3737, 0xffff3733,
-	0xffff3333, 0xffff332f, 0xffff2f2f, 0xffff2f2b, 0xffff2b2b, 0xffff2b27,
-	0xffff2727, 0xffff2723, 0xffff2323, 0xffff231f, 0xffff1f1f, 0xffff1f1b,
-	0xffff1b1b, 0xffff1b17, 0xffff1717, 0xffff1713, 0xffff1313, 0xffff130f,
-	0xffff0f0f, 0xffff0f0b, 0xffff0b0b, 0xffff0b07, 0xffff0707, 0xffff0703,
-	0xffff0303, 0xffff02ff, 0xfffffefe, 0xfffffefa, 0xfffffafa, 0xfffffaf6,
-	0xfffff6f6, 0xfffff6f2, 0xfffff2f2, 0xfffff2ee, 0xffffeeee, 0xffffeeea,
-	0xffffeaea, 0xffffeae6, 0xffffe6e6, 0xffffe6e2, 0xffffe2e2, 0xffffe2de,
-	0xffffdede, 0xffffdeda, 0xffffdada, 0xffffdad6, 0xffffd6d6, 0xffffd6d2,
-	0xffffd2d2, 0xffffd2ce, 0xffffcece, 0xffffceca, 0xffffcaca, 0xffffcac6,
-	0xffffc6c6, 0xffffc6c2, 0xffffc2c2, 0xffffc2be, 0xffffbebe, 0xffffbeba,
-	0xffffbaba, 0xffffbab6, 0xffffb6b6, 0xffffb6b2, 0xffffb2b2, 0xffffb2ae,
-	0xffffaeae, 0xffffaeaa, 0xffffaaaa, 0xffffaaa6, 0xffffa6a6, 0xffffa6a2,
-	0xffffa2a2, 0xffffa29e, 0xffff9e9e, 0xffff9e9a, 0xffff9a9a, 0xffff9a96,
-	0xffff9696, 0xffff9692, 0xffff9292, 0xffff928e, 0xffff8e8e, 0xffff8e8a,
-	0xffff8a8a, 0xffff8a86, 0xffff8686, 0xffff8682, 0xffff8282, 0xffff827e,
-	0xffff7e7e, 0xffff7e7a, 0xffff7a7a, 0xffff7a76, 0xffff7676, 0xffff7672,
-	0xffff7272, 0xffff726e, 0xffff6e6e, 0xffff6e6a, 0xffff6a6a, 0xffff6a66,
-	0xffff6666, 0xffff6662, 0xffff6262, 0xffff625e, 0xffff5e5e, 0xffff5e5a,
-	0xffff5a5a, 0xffff5a56, 0xffff5656, 0xffff5652, 0xffff5252, 0xffff524e,
-	0xffff4e4e, 0xffff4e4a, 0xffff4a4a, 0xffff4a46, 0xffff4646, 0xffff4642,
-	0xffff4242, 0xffff423e, 0xffff3e3e, 0xffff3e3a, 0xffff3a3a, 0xffff3a36,
-	0xffff3636, 0xffff3632, 0xffff3232, 0xffff322e, 0xffff2e2e, 0xffff2e2a,
-	0xffff2a2a, 0xffff2a26, 0xffff2626, 0xffff2622, 0xffff2222, 0xffff221e,
-	0xffff1e1e, 0xffff1e1a, 0xffff1a1a, 0xffff1a16, 0xffff1616, 0xffff1612,
-	0xffff1212, 0xffff120e, 0xffff0e0e, 0xffff0e0a, 0xffff0a0a, 0xffff0a06,
-	0xffff0606, 0xffff0602, 0xffff0202, 0xffff01fe, 0xfffffdfd, 0xfffffdf9,
-	0xfffff9f9, 0xfffff9f5, 0xfffff5f5, 0xfffff5f1, 0xfffff1f1, 0xfffff1ed,
-	0xffffeded, 0xffffede9, 0xffffe9e9, 0xffffe9e5, 0xffffe5e5, 0xffffe5e1,
-	0xffffe1e1, 0xffffe1dd, 0xffffdddd, 0xffffddd9, 0xffffd9d9, 0xffffd9d5,
-	0xffffd5d5, 0xffffd5d1, 0xffffd1d1, 0xffffd1cd, 0xffffcdcd, 0xffffcdc9,
-	0xffffc9c9, 0xffffc9c5, 0xffffc5c5, 0xffffc5c1, 0xffffc1c1, 0xffffc1bd,
-	0xffffbdbd, 0xffffbdb9, 0xffffb9b9, 0xffffb9b5, 0xffffb5b5, 0xffffb5b1,
-	0xffffb1b1, 0xffffb1ad, 0xffffadad, 0xffffada9, 0xffffa9a9, 0xffffa9a5,
-	0xffffa5a5, 0xffffa5a1, 0xffffa1a1, 0xffffa19d, 0xffff9d9d, 0xffff9d99,
-	0xffff9999, 0xffff9995, 0xffff9595, 0xffff9591, 0xffff9191, 0xffff918d,
-	0xffff8d8d, 0xffff8d89, 0xffff8989, 0xffff8985, 0xffff8585, 0xffff8581,
-	0xffff8181, 0xffff817d, 0xffff7d7d, 0xffff7d79, 0xffff7979, 0xffff7975,
-	0xffff7575, 0xffff7571, 0xffff7171, 0xffff716d, 0xffff6d6d, 0xffff6d69,
-	0xffff6969, 0xffff6965, 0xffff6565, 0xffff6561, 0xffff6161, 0xffff615d,
-	0xffff5d5d, 0xffff5d59, 0xffff5959, 0xffff5955, 0xffff5555, 0xffff5551,
-	0xffff5151, 0xffff514d, 0xffff4d4d, 0xffff4d49, 0xffff4949, 0xffff4945,
-	0xffff4545, 0xffff4541, 0xffff4141, 0xffff413d, 0xffff3d3d, 0xffff3d39,
-	0xffff3939, 0xffff3935, 0xffff3535, 0xffff3531, 0xffff3131, 0xffff312d,
-	0xffff2d2d, 0xffff2d29, 0xffff2929, 0xffff2925, 0xffff2525, 0xffff2521,
-	0xffff2121, 0xffff211d, 0xffff1d1d, 0xffff1d19, 0xffff1919, 0xffff1915,
-	0xffff1515, 0xffff1511, 0xffff1111, 0xffff110d, 0xffff0d0d, 0xffff0d09,
-	0xffff0909, 0xffff0905, 0xffff0505, 0xffff0501, 0xffff0101, 0xffff00fd,
-	0xfffffcfc, 0xfffffcf8, 0xfffff8f8, 0xfffff8f4, 0xfffff4f4, 0xfffff4f0,
-	0xfffff0f0, 0xfffff0ec, 0xffffecec, 0xffffece8, 0xffffe8e8, 0xffffe8e4,
-	0xffffe4e4, 0xffffe4e0, 0xffffe0e0, 0xffffe0dc, 0xffffdcdc, 0xffffdcd8,
-	0xffffd8d8, 0xffffd8d4, 0xffffd4d4, 0xffffd4d0, 0xffffd0d0, 0xffffd0cc,
-	0xffffcccc, 0xffffccc8, 0xffffc8c8, 0xffffc8c4, 0xffffc4c4, 0xffffc4c0,
-	0xffffc0c0, 0xffffc0bc, 0xffffbcbc, 0xffffbcb8, 0xffffb8b8, 0xffffb8b4,
-	0xffffb4b4, 0xffffb4b0, 0xffffb0b0, 0xffffb0ac, 0xffffacac, 0xffffaca8,
-	0xffffa8a8, 0xffffa8a4, 0xffffa4a4, 0xffffa4a0, 0xffffa0a0, 0xffffa09c,
-	0xffff9c9c, 0xffff9c98, 0xffff9898, 0xffff9894, 0xffff9494, 0xffff9490,
-	0xffff9090, 0xffff908c, 0xffff8c8c, 0xffff8c88, 0xffff8888, 0xffff8884,
-	0xffff8484, 0xffff8480, 0xffff8080, 0xffff807c, 0xffff7c7c, 0xffff7c78,
-	0xffff7878, 0xffff7874, 0xffff7474, 0xffff7470, 0xffff7070, 0xffff706c,
-	0xffff6c6c, 0xffff6c68, 0xffff6868, 0xffff6864, 0xffff6464, 0xffff6460,
-	0xffff6060, 0xffff605c, 0xffff5c5c, 0xffff5c58, 0xffff5858, 0xffff5854,
-	0xffff5454, 0xffff5450, 0xffff5050, 0xffff504c, 0xffff4c4c, 0xffff4c48,
-	0xffff4848, 0xffff4844, 0xffff4444, 0xffff4440, 0xffff4040, 0xffff403c,
-	0xffff3c3c, 0xffff3c38, 0xffff3838, 0xffff3834, 0xffff3434, 0xffff3430,
-	0xffff3030, 0xffff302c, 0xffff2c2c, 0xffff2c28, 0xffff2828, 0xffff2824,
-	0xffff2424, 0xffff2420, 0xffff2020, 0xffff201c, 0xffff1c1c, 0xffff1c18,
-	0xffff1818, 0xffff1814, 0xffff1414, 0xffff1410, 0xffff1010, 0xffff100c,
-	0xffff0c0c, 0xffff0c08, 0xffff0808, 0xffff0804, 0xffff0404, 0xffff0400,
-	0xffff0000, 0xfffffffb,
-};
-
-static const u16 expected_csum_ipv6_magic[] = {
-	0x18d4, 0x3085, 0x2e4b, 0xd9f4, 0xbdc8, 0x78f,	0x1034, 0x8422, 0x6fc0,
-	0xd2f6, 0xbeb5, 0x9d3,	0x7e2a, 0x312e, 0x778e, 0xc1bb, 0x7cf2, 0x9d1e,
-	0xca21, 0xf3ff, 0x7569, 0xb02e, 0xca86, 0x7e76, 0x4539, 0x45e3, 0xf28d,
-	0xdf81, 0x8fd5, 0x3b5d, 0x8324, 0xf471, 0x83be, 0x1daf, 0x8c46, 0xe682,
-	0xd1fb, 0x6b2e, 0xe687, 0x2a33, 0x4833, 0x2d67, 0x660f, 0x2e79, 0xd65e,
-	0x6b62, 0x6672, 0x5dbd, 0x8680, 0xbaa5, 0x2229, 0x2125, 0x2d01, 0x1cc0,
-	0x6d36, 0x33c0, 0xee36, 0xd832, 0x9820, 0x8a31, 0x53c5, 0x2e2,	0xdb0e,
-	0x49ed, 0x17a7, 0x77a0, 0xd72e, 0x3d72, 0x7dc8, 0x5b17, 0xf55d, 0xa4d9,
-	0x1446, 0x5d56, 0x6b2e, 0x69a5, 0xadb6, 0xff2a, 0x92e,	0xe044, 0x3402,
-	0xbb60, 0xec7f, 0xe7e6, 0x1986, 0x32f4, 0x8f8,	0x5e00, 0x47c6, 0x3059,
-	0x3969, 0xe957, 0x4388, 0x2854, 0x3334, 0xea71, 0xa6de, 0x33f9, 0x83fc,
-	0x37b4, 0x5531, 0x3404, 0x1010, 0xed30, 0x610a, 0xc95,	0x9aed, 0x6ff,
-	0x5136, 0x2741, 0x660e, 0x8b80, 0xf71,	0xa263, 0x88af, 0x7a73, 0x3c37,
-	0x1908, 0x6db5, 0x2e92, 0x1cd2, 0x70c8, 0xee16, 0xe80,	0xcd55, 0x6e6,
-	0x6434, 0x127,	0x655d, 0x2ea0, 0xb4f4, 0xdc20, 0x5671, 0xe462, 0xe52b,
-	0xdb44, 0x3589, 0xc48f, 0xe60b, 0xd2d2, 0x66ad, 0x498,	0x436,	0xb917,
-	0xf0ca, 0x1a6e, 0x1cb7, 0xbf61, 0x2870, 0xc7e8, 0x5b30, 0xe4a5, 0x168,
-	0xadfc, 0xd035, 0xe690, 0xe283, 0xfb27, 0xe4ad, 0xb1a5, 0xf2d5, 0xc4b6,
-	0x8a30, 0xd7d5, 0x7df9, 0x91d5, 0x63ed, 0x2d21, 0x312b, 0xab19, 0xa632,
-	0x8d2e, 0xef06, 0x57b9, 0xc373, 0xbd1f, 0xa41f, 0x8444, 0x9975, 0x90cb,
-	0xc49c, 0xe965, 0x4eff, 0x5a,	0xef6d, 0xe81a, 0xe260, 0x853a, 0xff7a,
-	0x99aa, 0xb06b, 0xee19, 0xcc2c, 0xf34c, 0x7c49, 0xdac3, 0xa71e, 0xc988,
-	0x3845, 0x1014
-};
-
-static const u16 expected_fast_csum[] = {
-	0xda83, 0x45da, 0x4f46, 0x4e4f, 0x34e,	0xe902, 0xa5e9, 0x87a5, 0x7187,
-	0x5671, 0xf556, 0x6df5, 0x816d, 0x8f81, 0xbb8f, 0xfbba, 0x5afb, 0xbe5a,
-	0xedbe, 0xabee, 0x6aac, 0xe6b,	0xea0d, 0x67ea, 0x7e68, 0x8a7e, 0x6f8a,
-	0x3a70, 0x9f3a, 0xe89e, 0x75e8, 0x7976, 0xfa79, 0x2cfa, 0x3c2c, 0x463c,
-	0x7146, 0x7a71, 0x547a, 0xfd53, 0x99fc, 0xb699, 0x92b6, 0xdb91, 0xe8da,
-	0x5fe9, 0x1e60, 0xae1d, 0x39ae, 0xf439, 0xa1f4, 0xdda1, 0xede,	0x790f,
-	0x579,	0x1206, 0x9012, 0x2490, 0xd224, 0x5cd2, 0xa65d, 0xca7,	0x220d,
-	0xf922, 0xbf9,	0x920b, 0x1b92, 0x361c, 0x2e36, 0x4d2e, 0x24d,	0x2,
-	0xcfff, 0x90cf, 0xa591, 0x93a5, 0x7993, 0x9579, 0xc894, 0x50c8, 0x5f50,
-	0xd55e, 0xcad5, 0xf3c9, 0x8f4,	0x4409, 0x5043, 0x5b50, 0x55b,	0x2205,
-	0x1e22, 0x801e, 0x3780, 0xe137, 0x7ee0, 0xf67d, 0x3cf6, 0xa53c, 0x2ea5,
-	0x472e, 0x5147, 0xcf51, 0x1bcf, 0x951c, 0x1e95, 0xc71e, 0xe4c7, 0xc3e4,
-	0x3dc3, 0xee3d, 0xa4ed, 0xf9a4, 0xcbf8, 0x75cb, 0xb375, 0x50b4, 0x3551,
-	0xf835, 0x19f8, 0x8c1a, 0x538c, 0xad52, 0xa3ac, 0xb0a3, 0x5cb0, 0x6c5c,
-	0x5b6c, 0xc05a, 0x92c0, 0x4792, 0xbe47, 0x53be, 0x1554, 0x5715, 0x4b57,
-	0xe54a, 0x20e5, 0x21,	0xd500, 0xa1d4, 0xa8a1, 0x57a9, 0xca57, 0x5ca,
-	0x1c06, 0x4f1c, 0xe24e, 0xd9e2, 0xf0d9, 0x4af1, 0x474b, 0x8146, 0xe81,
-	0xfd0e, 0x84fd, 0x7c85, 0xba7c, 0x17ba, 0x4a17, 0x964a, 0xf595, 0xff5,
-	0x5310, 0x3253, 0x6432, 0x4263, 0x2242, 0xe121, 0x32e1, 0xf632, 0xc5f5,
-	0x21c6, 0x7d22, 0x8e7c, 0x418e, 0x5641, 0x3156, 0x7c31, 0x737c, 0x373,
-	0x2503, 0xc22a, 0x3c2,	0x4a04, 0x8549, 0x5285, 0xa352, 0xe8a3, 0x6fe8,
-	0x1a6f, 0x211a, 0xe021, 0x38e0, 0x7638, 0xf575, 0x9df5, 0x169e, 0xf116,
-	0x23f1, 0xcd23, 0xece,	0x660f, 0x4866, 0x6a48, 0x716a, 0xee71, 0xa2ee,
-	0xb8a2, 0x61b9, 0xa361, 0xf7a2, 0x26f7, 0x1127, 0x6611, 0xe065, 0x36e0,
-	0x1837, 0x3018, 0x1c30, 0x721b, 0x3e71, 0xe43d, 0x99e4, 0x9e9a, 0xb79d,
-	0xa9b7, 0xcaa,	0xeb0c, 0x4eb,	0x1305, 0x8813, 0xb687, 0xa9b6, 0xfba9,
-	0xd7fb, 0xccd8, 0x2ecd, 0x652f, 0xae65, 0x3fae, 0x3a40, 0x563a, 0x7556,
-	0x2776, 0x1228, 0xef12, 0xf9ee, 0xcef9, 0x56cf, 0xa956, 0x24a9, 0xba24,
-	0x5fba, 0x665f, 0xf465, 0x8ff4, 0x6d8f, 0x346d, 0x5f34, 0x385f, 0xd137,
-	0xb8d0, 0xacb8, 0x55ac, 0x7455, 0xe874, 0x89e8, 0xd189, 0xa0d1, 0xb2a0,
-	0xb8b2, 0x36b8, 0x5636, 0xd355, 0x8d3,	0x1908, 0x2118, 0xc21,	0x990c,
-	0x8b99, 0x158c, 0x7815, 0x9e78, 0x6f9e, 0x4470, 0x1d44, 0x341d, 0x2634,
-	0x3f26, 0x793e, 0xc79,	0xcc0b, 0x26cc, 0xd126, 0x1fd1, 0xb41f, 0xb6b4,
-	0x22b7, 0xa122, 0xa1,	0x7f01, 0x837e, 0x3b83, 0xaf3b, 0x6fae, 0x916f,
-	0xb490, 0xffb3, 0xceff, 0x50cf, 0x7550, 0x7275, 0x1272, 0x2613, 0xaa26,
-	0xd5aa, 0x7d5,	0x9607, 0x96,	0xb100, 0xf8b0, 0x4bf8, 0xdd4c, 0xeddd,
-	0x98ed, 0x2599, 0x9325, 0xeb92, 0x8feb, 0xcc8f, 0x2acd, 0x392b, 0x3b39,
-	0xcb3b, 0x6acb, 0xd46a, 0xb8d4, 0x6ab8, 0x106a, 0x2f10, 0x892f, 0x789,
-	0xc806, 0x45c8, 0x7445, 0x3c74, 0x3a3c, 0xcf39, 0xd7ce, 0x58d8, 0x6e58,
-	0x336e, 0x1034, 0xee10, 0xe9ed, 0xc2e9, 0x3fc2, 0xd53e, 0xd2d4, 0xead2,
-	0x8fea, 0x2190, 0x1162, 0xbe11, 0x8cbe, 0x6d8c, 0xfb6c, 0x6dfb, 0xd36e,
-	0x3ad3, 0xf3a,	0x870e, 0xc287, 0x53c3, 0xc54,	0x5b0c, 0x7d5a, 0x797d,
-	0xec79, 0x5dec, 0x4d5e, 0x184e, 0xd618, 0x60d6, 0xb360, 0x98b3, 0xf298,
-	0xb1f2, 0x69b1, 0xf969, 0xef9,	0xab0e, 0x21ab, 0xe321, 0x24e3, 0x8224,
-	0x5481, 0x5954, 0x7a59, 0xff7a, 0x7dff, 0x1a7d, 0xa51a, 0x46a5, 0x6b47,
-	0xe6b,	0x830e, 0xa083, 0xff9f, 0xd0ff, 0xffd0, 0xe6ff, 0x7de7, 0xc67d,
-	0xd0c6, 0x61d1, 0x3a62, 0xc3b,	0x150c, 0x1715, 0x4517, 0x5345, 0x3954,
-	0xdd39, 0xdadd, 0x32db, 0x6a33, 0xd169, 0x86d1, 0xb687, 0x3fb6, 0x883f,
-	0xa487, 0x39a4, 0x2139, 0xbe20, 0xffbe, 0xedfe, 0x8ded, 0x368e, 0xc335,
-	0x51c3, 0x9851, 0xf297, 0xd6f2, 0xb9d6, 0x95ba, 0x2096, 0xea1f, 0x76e9,
-	0x4e76, 0xe04d, 0xd0df, 0x80d0, 0xa280, 0xfca2, 0x75fc, 0xef75, 0x32ef,
-	0x6833, 0xdf68, 0xc4df, 0x76c4, 0xb77,	0xb10a, 0xbfb1, 0x58bf, 0x5258,
-	0x4d52, 0x6c4d, 0x7e6c, 0xb67e, 0xccb5, 0x8ccc, 0xbe8c, 0xc8bd, 0x9ac8,
-	0xa99b, 0x52a9, 0x2f53, 0xc30,	0x3e0c, 0xb83d, 0x83b7, 0x5383, 0x7e53,
-	0x4f7e, 0xe24e, 0xb3e1, 0x8db3, 0x618e, 0xc861, 0xfcc8, 0x34fc, 0x9b35,
-	0xaa9b, 0xb1aa, 0x5eb1, 0x395e, 0x8639, 0xd486, 0x8bd4, 0x558b, 0x2156,
-	0xf721, 0x4ef6, 0x14f,	0x7301, 0xdd72, 0x49de, 0x894a, 0x9889, 0x8898,
-	0x7788, 0x7b77, 0x637b, 0xb963, 0xabb9, 0x7cab, 0xc87b, 0x21c8, 0xcb21,
-	0xdfca, 0xbfdf, 0xf2bf, 0x6af2, 0x626b, 0xb261, 0x3cb2, 0xc63c, 0xc9c6,
-	0xc9c9, 0xb4c9, 0xf9b4, 0x91f9, 0x4091, 0x3a40, 0xcc39, 0xd1cb, 0x7ed1,
-	0x537f, 0x6753, 0xa167, 0xba49, 0x88ba, 0x7789, 0x3877, 0xf037, 0xd3ef,
-	0xb5d4, 0x55b6, 0xa555, 0xeca4, 0xa1ec, 0xb6a2, 0x7b7,	0x9507, 0xfd94,
-	0x82fd, 0x5c83, 0x765c, 0x9676, 0x3f97, 0xda3f, 0x6fda, 0x646f, 0x3064,
-	0x5e30, 0x655e, 0x6465, 0xcb64, 0xcdca, 0x4ccd, 0x3f4c, 0x243f, 0x6f24,
-	0x656f, 0x6065, 0x3560, 0x3b36, 0xac3b, 0x4aac, 0x714a, 0x7e71, 0xda7e,
-	0x7fda, 0xda7f, 0x6fda, 0xff6f, 0xc6ff, 0xedc6, 0xd4ed, 0x70d5, 0xeb70,
-	0xa3eb, 0x80a3, 0xca80, 0x3fcb, 0x2540, 0xf825, 0x7ef8, 0xf87e, 0x73f8,
-	0xb474, 0xb4b4, 0x92b5, 0x9293, 0x93,	0x3500, 0x7134, 0x9071, 0xfa8f,
-	0x51fa, 0x1452, 0xba13, 0x7ab9, 0x957a, 0x8a95, 0x6e8a, 0x6d6e, 0x7c6d,
-	0x447c, 0x9744, 0x4597, 0x8945, 0xef88, 0x8fee, 0x3190, 0x4831, 0x8447,
-	0xa183, 0x1da1, 0xd41d, 0x2dd4, 0x4f2e, 0xc94e, 0xcbc9, 0xc9cb, 0x9ec9,
-	0x319e, 0xd531, 0x20d5, 0x4021, 0xb23f, 0x29b2, 0xd828, 0xecd8, 0x5ded,
-	0xfc5d, 0x4dfc, 0xd24d, 0x6bd2, 0x5f6b, 0xb35e, 0x7fb3, 0xee7e, 0x56ee,
-	0xa657, 0x68a6, 0x8768, 0x7787, 0xb077, 0x4cb1, 0x764c, 0xb175, 0x7b1,
-	0x3d07, 0x603d, 0x3560, 0x3e35, 0xb03d, 0xd6b0, 0xc8d6, 0xd8c8, 0x8bd8,
-	0x3e8c, 0x303f, 0xd530, 0xf1d4, 0x42f1, 0xca42, 0xddca, 0x41dd, 0x3141,
-	0x132,	0xe901, 0x8e9,	0xbe09, 0xe0bd, 0x2ce0, 0x862d, 0x3986, 0x9139,
-	0x6d91, 0x6a6d, 0x8d6a, 0x1b8d, 0xac1b, 0xedab, 0x54ed, 0xc054, 0xcebf,
-	0xc1ce, 0x5c2,	0x3805, 0x6038, 0x5960, 0xd359, 0xdd3,	0xbe0d, 0xafbd,
-	0x6daf, 0x206d, 0x2c20, 0x862c, 0x8e86, 0xec8d, 0xa2ec, 0xa3a2, 0x51a3,
-	0x8051, 0xfd7f, 0x91fd, 0xa292, 0xaf14, 0xeeae, 0x59ef, 0x535a, 0x8653,
-	0x3986, 0x9539, 0xb895, 0xa0b8, 0x26a0, 0x2227, 0xc022, 0x77c0, 0xad77,
-	0x46ad, 0xaa46, 0x60aa, 0x8560, 0x4785, 0xd747, 0x45d7, 0x2346, 0x5f23,
-	0x25f,	0x1d02, 0x71d,	0x8206, 0xc82,	0x180c, 0x3018, 0x4b30, 0x4b,
-	0x3001, 0x1230, 0x2d12, 0x8c2d, 0x148d, 0x4015, 0x5f3f, 0x3d5f, 0x6b3d,
-	0x396b, 0x473a, 0xf746, 0x44f7, 0x8945, 0x3489, 0xcb34, 0x84ca, 0xd984,
-	0xf0d9, 0xbcf0, 0x63bd, 0x3264, 0xf332, 0x45f3, 0x7346, 0x5673, 0xb056,
-	0xd3b0, 0x4ad4, 0x184b, 0x7d18, 0x6c7d, 0xbb6c, 0xfeba, 0xe0fe, 0x10e1,
-	0x5410, 0x2954, 0x9f28, 0x3a9f, 0x5a3a, 0xdb59, 0xbdc,	0xb40b, 0x1ab4,
-	0x131b, 0x5d12, 0x6d5c, 0xe16c, 0xb0e0, 0x89b0, 0xba88, 0xbb,	0x3c01,
-	0xe13b, 0x6fe1, 0x446f, 0xa344, 0x81a3, 0xfe81, 0xc7fd, 0x38c8, 0xb38,
-	0x1a0b, 0x6d19, 0xf36c, 0x47f3, 0x6d48, 0xb76d, 0xd3b7, 0xd8d2, 0x52d9,
-	0x4b53, 0xa54a, 0x34a5, 0xc534, 0x9bc4, 0xed9b, 0xbeed, 0x3ebe, 0x233e,
-	0x9f22, 0x4a9f, 0x774b, 0x4577, 0xa545, 0x64a5, 0xb65,	0x870b, 0x487,
-	0x9204, 0x5f91, 0xd55f, 0x35d5, 0x1a35, 0x71a,	0x7a07, 0x4e7a, 0xfc4e,
-	0x1efc, 0x481f, 0x7448, 0xde74, 0xa7dd, 0x1ea7, 0xaa1e, 0xcfaa, 0xfbcf,
-	0xedfb, 0x6eee, 0x386f, 0x4538, 0x6e45, 0xd96d, 0x11d9, 0x7912, 0x4b79,
-	0x494b, 0x6049, 0xac5f, 0x65ac, 0x1366, 0x5913, 0xe458, 0x7ae4, 0x387a,
-	0x3c38, 0xb03c, 0x76b0, 0x9376, 0xe193, 0x42e1, 0x7742, 0x6476, 0x3564,
-	0x3c35, 0x6a3c, 0xcc69, 0x94cc, 0x5d95, 0xe5e,	0xee0d, 0x4ced, 0xce4c,
-	0x52ce, 0xaa52, 0xdaaa, 0xe4da, 0x1de5, 0x4530, 0x5445, 0x3954, 0xb639,
-	0x81b6, 0x7381, 0x1574, 0xc215, 0x10c2, 0x3f10, 0x6b3f, 0xe76b, 0x7be7,
-	0xbc7b, 0xf7bb, 0x41f7, 0xcc41, 0x38cc, 0x4239, 0xa942, 0x4a9,	0xc504,
-	0x7cc4, 0x437c, 0x6743, 0xea67, 0x8dea, 0xe88d, 0xd8e8, 0xdcd8, 0x17dd,
-	0x5718, 0x958,	0xa609, 0x41a5, 0x5842, 0x159,	0x9f01, 0x269f, 0x5a26,
-	0x405a, 0xc340, 0xb4c3, 0xd4b4, 0xf4d3, 0xf1f4, 0x39f2, 0xe439, 0x67e4,
-	0x4168, 0xa441, 0xdda3, 0xdedd, 0x9df,	0xab0a, 0xa5ab, 0x9a6,	0xba09,
-	0x9ab9, 0xad9a, 0x5ae,	0xe205, 0xece2, 0xecec, 0x14ed, 0xd614, 0x6bd5,
-	0x916c, 0x3391, 0x6f33, 0x206f, 0x8020, 0x780,	0x7207, 0x2472, 0x8a23,
-	0xb689, 0x3ab6, 0xf739, 0x97f6, 0xb097, 0xa4b0, 0xe6a4, 0x88e6, 0x2789,
-	0xb28,	0x350b, 0x1f35, 0x431e, 0x1043, 0xc30f, 0x79c3, 0x379,	0x5703,
-	0x3256, 0x4732, 0x7247, 0x9d72, 0x489d, 0xd348, 0xa4d3, 0x7ca4, 0xbf7b,
-	0x45c0, 0x7b45, 0x337b, 0x4034, 0x843f, 0xd083, 0x35d0, 0x6335, 0x4d63,
-	0xe14c, 0xcce0, 0xfecc, 0x35ff, 0x5636, 0xf856, 0xeef8, 0x2def, 0xfc2d,
-	0x4fc,	0x6e04, 0xb66d, 0x78b6, 0xbb78, 0x3dbb, 0x9a3d, 0x839a, 0x9283,
-	0x593,	0xd504, 0x23d5, 0x5424, 0xd054, 0x61d0, 0xdb61, 0x17db, 0x1f18,
-	0x381f, 0x9e37, 0x679e, 0x1d68, 0x381d, 0x8038, 0x917f, 0x491,	0xbb04,
-	0x23bb, 0x4124, 0xd41,	0xa30c, 0x8ba3, 0x8b8b, 0xc68b, 0xd2c6, 0xebd2,
-	0x93eb, 0xbd93, 0x99bd, 0x1a99, 0xea19, 0x58ea, 0xcf58, 0x73cf, 0x1073,
-	0x9e10, 0x139e, 0xea13, 0xcde9, 0x3ecd, 0x883f, 0xf89,	0x180f, 0x2a18,
-	0x212a, 0xce20, 0x73ce, 0xf373, 0x60f3, 0xad60, 0x4093, 0x8e40, 0xb98e,
-	0xbfb9, 0xf1bf, 0x8bf1, 0x5e8c, 0xe95e, 0x14e9, 0x4e14, 0x1c4e, 0x7f1c,
-	0xe77e, 0x6fe7, 0xf26f, 0x13f2, 0x8b13, 0xda8a, 0x5fda, 0xea5f, 0x4eea,
-	0xa84f, 0x88a8, 0x1f88, 0x2820, 0x9728, 0x5a97, 0x3f5b, 0xb23f, 0x70b2,
-	0x2c70, 0x232d, 0xf623, 0x4f6,	0x905,	0x7509, 0xd675, 0x28d7, 0x9428,
-	0x3794, 0xf036, 0x2bf0, 0xba2c, 0xedb9, 0xd7ed, 0x59d8, 0xed59, 0x4ed,
-	0xe304, 0x18e3, 0x5c19, 0x3d5c, 0x753d, 0x6d75, 0x956d, 0x7f95, 0xc47f,
-	0x83c4, 0xa84,	0x2e0a, 0x5f2e, 0xb95f, 0x77b9, 0x6d78, 0xf46d, 0x1bf4,
-	0xed1b, 0xd6ed, 0xe0d6, 0x5e1,	0x3905, 0x5638, 0xa355, 0x99a2, 0xbe99,
-	0xb4bd, 0x85b4, 0x2e86, 0x542e, 0x6654, 0xd765, 0x73d7, 0x3a74, 0x383a,
-	0x2638, 0x7826, 0x7677, 0x9a76, 0x7e99, 0x2e7e, 0xea2d, 0xa6ea, 0x8a7,
-	0x109,	0x3300, 0xad32, 0x5fad, 0x465f, 0x2f46, 0xc62f, 0xd4c5, 0xad5,
-	0xcb0a, 0x4cb,	0xb004, 0x7baf, 0xe47b, 0x92e4, 0x8e92, 0x638e, 0x1763,
-	0xc17,	0xf20b, 0x1ff2, 0x8920, 0x5889, 0xcb58, 0xf8cb, 0xcaf8, 0x84cb,
-	0x9f84, 0x8a9f, 0x918a, 0x4991, 0x8249, 0xff81, 0x46ff, 0x5046, 0x5f50,
-	0x725f, 0xf772, 0x8ef7, 0xe08f, 0xc1e0, 0x1fc2, 0x9e1f, 0x8b9d, 0x108b,
-	0x411,	0x2b04, 0xb02a, 0x1fb0, 0x1020, 0x7a0f, 0x587a, 0x8958, 0xb188,
-	0xb1b1, 0x49b2, 0xb949, 0x7ab9, 0x917a, 0xfc91, 0xe6fc, 0x47e7, 0xbc47,
-	0x8fbb, 0xea8e, 0x34ea, 0x2635, 0x1726, 0x9616, 0xc196, 0xa6c1, 0xf3a6,
-	0x11f3, 0x4811, 0x3e48, 0xeb3e, 0xf7ea, 0x1bf8, 0xdb1c, 0x8adb, 0xe18a,
-	0x42e1, 0x9d42, 0x5d9c, 0x6e5d, 0x286e, 0x4928, 0x9a49, 0xb09c, 0xa6b0,
-	0x2a7,	0xe702, 0xf5e6, 0x9af5, 0xf9b,	0x810f, 0x8080, 0x180,	0x1702,
-	0x5117, 0xa650, 0x11a6, 0x1011, 0x550f, 0xd554, 0xbdd5, 0x6bbe, 0xc66b,
-	0xfc7,	0x5510, 0x5555, 0x7655, 0x177,	0x2b02, 0x6f2a, 0xb70,	0x9f0b,
-	0xcf9e, 0xf3cf, 0x3ff4, 0xcb40, 0x8ecb, 0x768e, 0x5277, 0x8652, 0x9186,
-	0x9991, 0x5099, 0xd350, 0x93d3, 0x6d94, 0xe6d,	0x530e, 0x3153, 0xa531,
-	0x64a5, 0x7964, 0x7c79, 0x467c, 0x1746, 0x3017, 0x3730, 0x538,	0x5,
-	0x1e00, 0x5b1e, 0x955a, 0xae95, 0x3eaf, 0xff3e, 0xf8ff, 0xb2f9, 0xa1b3,
-	0xb2a1, 0x5b2,	0xad05, 0x7cac, 0x2d7c, 0xd32c, 0x80d2, 0x7280, 0x8d72,
-	0x1b8e, 0x831b, 0xac82, 0xfdac, 0xa7fd, 0x15a8, 0xd614, 0xe0d5, 0x7be0,
-	0xb37b, 0x61b3, 0x9661, 0x9d95, 0xc79d, 0x83c7, 0xd883, 0xead7, 0xceb,
-	0xf60c, 0xa9f5, 0x19a9, 0xa019, 0x8f9f, 0xd48f, 0x3ad5, 0x853a, 0x985,
-	0x5309, 0x6f52, 0x1370, 0x6e13, 0xa96d, 0x98a9, 0x5198, 0x9f51, 0xb69f,
-	0xa1b6, 0x2ea1, 0x672e, 0x2067, 0x6520, 0xaf65, 0x6eaf, 0x7e6f, 0xee7e,
-	0x17ef, 0xa917, 0xcea8, 0x9ace, 0xff99, 0x5dff, 0xdf5d, 0x38df, 0xa39,
-	0x1c0b, 0xe01b, 0x46e0, 0xcb46, 0x90cb, 0xba90, 0x4bb,	0x9104, 0x9d90,
-	0xc89c, 0xf6c8, 0x6cf6, 0x886c, 0x1789, 0xbd17, 0x70bc, 0x7e71, 0x17e,
-	0x1f01, 0xa01f, 0xbaa0, 0x14bb, 0xfc14, 0x7afb, 0xa07a, 0x3da0, 0xbf3d,
-	0x48bf, 0x8c48, 0x968b, 0x9d96, 0xfd9d, 0x96fd, 0x9796, 0x6b97, 0xd16b,
-	0xf4d1, 0x3bf4, 0x253c, 0x9125, 0x6691, 0xc166, 0x34c1, 0x5735, 0x1a57,
-	0xdc19, 0x77db, 0x8577, 0x4a85, 0x824a, 0x9182, 0x7f91, 0xfd7f, 0xb4c3,
-	0xb5b4, 0xb3b5, 0x7eb3, 0x617e, 0x4e61, 0xa4f,	0x530a, 0x3f52, 0xa33e,
-	0x34a3, 0x9234, 0xf091, 0xf4f0, 0x1bf5, 0x311b, 0x9631, 0x6a96, 0x386b,
-	0x1d39, 0xe91d, 0xe8e9, 0x69e8, 0x426a, 0xee42, 0x89ee, 0x368a, 0x2837,
-	0x7428, 0x5974, 0x6159, 0x1d62, 0x7b1d, 0xf77a, 0x7bf7, 0x6b7c, 0x696c,
-	0xf969, 0x4cf9, 0x714c, 0x4e71, 0x6b4e, 0x256c, 0x6e25, 0xe96d, 0x94e9,
-	0x8f94, 0x3e8f, 0x343e, 0x4634, 0xb646, 0x97b5, 0x8997, 0xe8a,	0x900e,
-	0x8090, 0xfd80, 0xa0fd, 0x16a1, 0xf416, 0xebf4, 0x95ec, 0x1196, 0x8911,
-	0x3d89, 0xda3c, 0x9fd9, 0xd79f, 0x4bd7, 0x214c, 0x3021, 0x4f30, 0x994e,
-	0x5c99, 0x6f5d, 0x326f, 0xab31, 0x6aab, 0xe969, 0x90e9, 0x1190, 0xff10,
-	0xa2fe, 0xe0a2, 0x66e1, 0x4067, 0x9e3f, 0x2d9e, 0x712d, 0x8170, 0xd180,
-	0xffd1, 0x25ff, 0x3826, 0x2538, 0x5f24, 0xc45e, 0x1cc4, 0xdf1c, 0x93df,
-	0xc793, 0x80c7, 0x2380, 0xd223, 0x7ed2, 0xfc7e, 0x22fd, 0x7422, 0x1474,
-	0xb714, 0x7db6, 0x857d, 0xa85,	0xa60a, 0x88a6, 0x4289, 0x7842, 0xc278,
-	0xf7c2, 0xcdf7, 0x84cd, 0xae84, 0x8cae, 0xb98c, 0x1aba, 0x4d1a, 0x884c,
-	0x4688, 0xcc46, 0xd8cb, 0x2bd9, 0xbe2b, 0xa2be, 0x72a2, 0xf772, 0xd2f6,
-	0x75d2, 0xc075, 0xa3c0, 0x63a3, 0xae63, 0x8fae, 0x2a90, 0x5f2a, 0xef5f,
-	0x5cef, 0xa05c, 0x89a0, 0x5e89, 0x6b5e, 0x736b, 0x773,	0x9d07, 0xe99c,
-	0x27ea, 0x2028, 0xc20,	0x980b, 0x4797, 0x2848, 0x9828, 0xc197, 0x48c2,
-	0x2449, 0x7024, 0x570,	0x3e05, 0xd3e,	0xf60c, 0xbbf5, 0x69bb, 0x3f6a,
-	0x740,	0xf006, 0xe0ef, 0xbbe0, 0xadbb, 0x56ad, 0xcf56, 0xbfce, 0xa9bf,
-	0x205b, 0x6920, 0xae69, 0x50ae, 0x2050, 0xf01f, 0x27f0, 0x9427, 0x8993,
-	0x8689, 0x4087, 0x6e40, 0xb16e, 0xa1b1, 0xe8a1, 0x87e8, 0x6f88, 0xfe6f,
-	0x4cfe, 0xe94d, 0xd5e9, 0x47d6, 0x3148, 0x5f31, 0xc35f, 0x13c4, 0xa413,
-	0x5a5,	0x2405, 0xc223, 0x66c2, 0x3667, 0x5e37, 0x5f5e, 0x2f5f, 0x8c2f,
-	0xe48c, 0xd0e4, 0x4d1,	0xd104, 0xe4d0, 0xcee4, 0xfcf,	0x480f, 0xa447,
-	0x5ea4, 0xff5e, 0xbefe, 0x8dbe, 0x1d8e, 0x411d, 0x1841, 0x6918, 0x5469,
-	0x1155, 0xc611, 0xaac6, 0x37ab, 0x2f37, 0xca2e, 0x87ca, 0xbd87, 0xabbd,
-	0xb3ab, 0xcb4,	0xce0c, 0xfccd, 0xa5fd, 0x72a5, 0xf072, 0x83f0, 0xfe83,
-	0x97fd, 0xc997, 0xb0c9, 0xadb0, 0xe6ac, 0x88e6, 0x1088, 0xbe10, 0x16be,
-	0xa916, 0xa3a8, 0x46a3, 0x5447, 0xe953, 0x84e8, 0x2085, 0xa11f, 0xfa1,
-	0xdd0f, 0xbedc, 0x5abe, 0x805a, 0xc97f, 0x6dc9, 0x826d, 0x4a82, 0x934a,
-	0x5293, 0xd852, 0xd3d8, 0xadd3, 0xf4ad, 0xf3f4, 0xfcf3, 0xfefc, 0xcafe,
-	0xb7ca, 0x3cb8, 0xa13c, 0x18a1, 0x1418, 0xea13, 0x91ea, 0xf891, 0x53f8,
-	0xa254, 0xe9a2, 0x87ea, 0x4188, 0x1c41, 0xdc1b, 0xf5db, 0xcaf5, 0x45ca,
-	0x6d45, 0x396d, 0xde39, 0x90dd, 0x1e91, 0x1e,	0x7b00, 0x6a7b, 0xa46a,
-	0xc9a3, 0x9bc9, 0x389b, 0x1139, 0x5211, 0x1f52, 0xeb1f, 0xabeb, 0x48ab,
-	0x9348, 0xb392, 0x17b3, 0x1618, 0x5b16, 0x175b, 0xdc17, 0xdedb, 0x1cdf,
-	0xeb1c, 0xd1ea, 0x4ad2, 0xd4b,	0xc20c, 0x24c2, 0x7b25, 0x137b, 0x8b13,
-	0x618b, 0xa061, 0xff9f, 0xfffe, 0x72ff, 0xf572, 0xe2f5, 0xcfe2, 0xd2cf,
-	0x75d3, 0x6a76, 0xc469, 0x1ec4, 0xfc1d, 0x59fb, 0x455a, 0x7a45, 0xa479,
-	0xb7a4
-};
-
-static u8 tmp_buf[TEST_BUFLEN];
-
-#define full_csum(buff, len, sum) csum_fold(csum_partial(buff, len, sum))
-
-#define CHECK_EQ(lhs, rhs) KUNIT_ASSERT_EQ(test, (__force u64)lhs, (__force u64)rhs)
-
-static __sum16 to_sum16(u16 x)
-{
-	return (__force __sum16)le16_to_cpu((__force __le16)x);
-}
-
-/* This function swaps the bytes inside each half of a __wsum */
-static __wsum to_wsum(u32 x)
-{
-	u16 hi = le16_to_cpu((__force __le16)(x >> 16));
-	u16 lo = le16_to_cpu((__force __le16)x);
-
-	return (__force __wsum)((hi << 16) | lo);
-}
-
-static void assert_setup_correct(struct kunit *test)
-{
-	CHECK_EQ(ARRAY_SIZE(random_buf), MAX_LEN);
-	CHECK_EQ(ARRAY_SIZE(expected_results), MAX_LEN);
-	CHECK_EQ(ARRAY_SIZE(init_sums_no_overflow), MAX_LEN);
-}
-
-/*
- * Test with randomized input (pre determined random with known results).
- */
-static void test_csum_fixed_random_inputs(struct kunit *test)
-{
-	int len, align;
-	__wsum sum;
-	__sum16 result, expec;
-
-	assert_setup_correct(test);
-	for (align = 0; align < TEST_BUFLEN; ++align) {
-		memcpy(&tmp_buf[align], random_buf,
-		       min(MAX_LEN, TEST_BUFLEN - align));
-		for (len = 0; len < MAX_LEN && (align + len) < TEST_BUFLEN;
-		     ++len) {
-			/*
-			 * Test the precomputed random input.
-			 */
-			sum = to_wsum(random_init_sum);
-			result = full_csum(&tmp_buf[align], len, sum);
-			expec = to_sum16(expected_results[len]);
-			CHECK_EQ(result, expec);
-		}
-	}
-}
-
-/*
- * All ones input test. If there are any missing carry operations, it fails.
- */
-static void test_csum_all_carry_inputs(struct kunit *test)
-{
-	int len, align;
-	__wsum sum;
-	__sum16 result, expec;
-
-	assert_setup_correct(test);
-	memset(tmp_buf, 0xff, TEST_BUFLEN);
-	for (align = 0; align < TEST_BUFLEN; ++align) {
-		for (len = 0; len < MAX_LEN && (align + len) < TEST_BUFLEN;
-		     ++len) {
-			/*
-			 * All carries from input and initial sum.
-			 */
-			sum = to_wsum(0xffffffff);
-			result = full_csum(&tmp_buf[align], len, sum);
-			expec = to_sum16((len & 1) ? 0xff00 : 0);
-			CHECK_EQ(result, expec);
-
-			/*
-			 * All carries from input.
-			 */
-			sum = 0;
-			result = full_csum(&tmp_buf[align], len, sum);
-			if (len & 1)
-				expec = to_sum16(0xff00);
-			else if (len)
-				expec = 0;
-			else
-				expec = to_sum16(0xffff);
-			CHECK_EQ(result, expec);
-		}
-	}
-}
-
-/*
- * Test with input that alone doesn't cause any carries. By selecting the
- * maximum initial sum, this allows us to test that there are no carries
- * where there shouldn't be.
- */
-static void test_csum_no_carry_inputs(struct kunit *test)
-{
-	int len, align;
-	__wsum sum;
-	__sum16 result, expec;
-
-	assert_setup_correct(test);
-	memset(tmp_buf, 0x4, TEST_BUFLEN);
-	for (align = 0; align < TEST_BUFLEN; ++align) {
-		for (len = 0; len < MAX_LEN && (align + len) < TEST_BUFLEN;
-		     ++len) {
-			/*
-			 * Expect no carries.
-			 */
-			sum = to_wsum(init_sums_no_overflow[len]);
-			result = full_csum(&tmp_buf[align], len, sum);
-			expec = 0;
-			CHECK_EQ(result, expec);
-
-			/*
-			 * Expect one carry.
-			 */
-			sum = to_wsum(init_sums_no_overflow[len] + 1);
-			result = full_csum(&tmp_buf[align], len, sum);
-			expec = to_sum16(len ? 0xfffe : 0xffff);
-			CHECK_EQ(result, expec);
-		}
-	}
-}
-
-static void test_ip_fast_csum(struct kunit *test)
-{
-	__sum16 csum_result;
-	u16 expected;
-
-	for (int len = IPv4_MIN_WORDS; len < IPv4_MAX_WORDS; len++) {
-		for (int index = 0; index < NUM_IP_FAST_CSUM_TESTS; index++) {
-			csum_result = ip_fast_csum(random_buf + index, len);
-			expected =
-				expected_fast_csum[(len - IPv4_MIN_WORDS) *
-						   NUM_IP_FAST_CSUM_TESTS +
-						   index];
-			CHECK_EQ(to_sum16(expected), csum_result);
-		}
-	}
-}
-
-static void test_csum_ipv6_magic(struct kunit *test)
-{
-	const struct in6_addr *saddr;
-	const struct in6_addr *daddr;
-	unsigned int len;
-	unsigned char proto;
-	__wsum csum;
-
-	if (!IS_ENABLED(CONFIG_NET))
-		return;
-
-	const int daddr_offset = sizeof(struct in6_addr);
-	const int len_offset = sizeof(struct in6_addr) + sizeof(struct in6_addr);
-	const int proto_offset = sizeof(struct in6_addr) + sizeof(struct in6_addr) +
-			     sizeof(int);
-	const int csum_offset = sizeof(struct in6_addr) + sizeof(struct in6_addr) +
-			    sizeof(int) + sizeof(char);
-
-	for (int i = 0; i < NUM_IPv6_TESTS; i++) {
-		saddr = (const struct in6_addr *)(random_buf + i);
-		daddr = (const struct in6_addr *)(random_buf + i +
-						  daddr_offset);
-		len = le32_to_cpu(*(__le32 *)(random_buf + i + len_offset));
-		proto = *(random_buf + i + proto_offset);
-		csum = *(__wsum *)(random_buf + i + csum_offset);
-		CHECK_EQ(to_sum16(expected_csum_ipv6_magic[i]),
-			 csum_ipv6_magic(saddr, daddr, len, proto, csum));
-	}
-}
-
-static struct kunit_case __refdata checksum_test_cases[] = {
-	KUNIT_CASE(test_csum_fixed_random_inputs),
-	KUNIT_CASE(test_csum_all_carry_inputs),
-	KUNIT_CASE(test_csum_no_carry_inputs),
-	KUNIT_CASE(test_ip_fast_csum),
-	KUNIT_CASE(test_csum_ipv6_magic),
-	{}
-};
-
-static struct kunit_suite checksum_test_suite = {
-	.name = "checksum",
-	.test_cases = checksum_test_cases,
-};
-
-kunit_test_suites(&checksum_test_suite);
-
-MODULE_AUTHOR("Noah Goldstein <goldstein.w.n@xxxxxxxxx>");
-MODULE_DESCRIPTION("Test cases csum_* APIs");
-MODULE_LICENSE("GPL");
diff --git a/lib/cmdline_kunit.c a/lib/cmdline_kunit.c
deleted file mode 100644
--- a/lib/cmdline_kunit.c
+++ /dev/null
@@ -1,157 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Test cases for API provided by cmdline.c
- */
-
-#include <kunit/test.h>
-#include <linux/kernel.h>
-#include <linux/random.h>
-#include <linux/string.h>
-
-static const char *cmdline_test_strings[] = {
-	"\"\"", ""  , "=" , "\"-", ","    , "-,"   , ",-"   , "-" ,
-	"+,"  , "--", ",,", "''" , "\"\",", "\",\"", "-\"\"", "\"",
-};
-
-static const int cmdline_test_values[] = {
-	1, 1, 1, 1, 2, 3, 2, 3,
-	1, 3, 2, 1, 1, 1, 3, 1,
-};
-
-static_assert(ARRAY_SIZE(cmdline_test_strings) == ARRAY_SIZE(cmdline_test_values));
-
-static const char *cmdline_test_range_strings[] = {
-	"-7" , "--7"  , "-1-2"    , "7--9",
-	"7-" , "-7--9", "7-9,"    , "9-7" ,
-	"5-a", "a-5"  , "5-8"     , ",8-5",
-	"+,1", "-,4"  , "-3,0-1,6", "4,-" ,
-	" +2", " -9"  , "0-1,-3,6", "- 9" ,
-};
-
-static const int cmdline_test_range_values[][16] = {
-	{ 1, -7, }, { 0, -0, }, { 4, -1, 0, +1, 2, }, { 0, 7, },
-	{ 0, +7, }, { 0, -7, }, { 3, +7, 8, +9, 0, }, { 0, 9, },
-	{ 0, +5, }, { 0, -0, }, { 4, +5, 6, +7, 8, }, { 0, 0, },
-	{ 0, +0, }, { 0, -0, }, { 4, -3, 0, +1, 6, }, { 1, 4, },
-	{ 0, +0, }, { 0, -0, }, { 4, +0, 1, -3, 6, }, { 0, 0, },
-};
-
-static_assert(ARRAY_SIZE(cmdline_test_range_strings) == ARRAY_SIZE(cmdline_test_range_values));
-
-static void cmdline_do_one_test(struct kunit *test, const char *in, int rc, int offset)
-{
-	const char *fmt = "Pattern: %s";
-	const char *out = in;
-	int dummy;
-	int ret;
-
-	ret = get_option((char **)&out, &dummy);
-
-	KUNIT_EXPECT_EQ_MSG(test, ret, rc, fmt, in);
-	KUNIT_EXPECT_PTR_EQ_MSG(test, out, in + offset, fmt, in);
-}
-
-static void cmdline_test_noint(struct kunit *test)
-{
-	unsigned int i = 0;
-
-	do {
-		const char *str = cmdline_test_strings[i];
-		int rc = 0;
-		int offset;
-
-		/* Only first and leading '-' will advance the pointer */
-		offset = !!(*str == '-');
-		cmdline_do_one_test(test, str, rc, offset);
-	} while (++i < ARRAY_SIZE(cmdline_test_strings));
-}
-
-static void cmdline_test_lead_int(struct kunit *test)
-{
-	unsigned int i = 0;
-	char in[32];
-
-	do {
-		const char *str = cmdline_test_strings[i];
-		int rc = cmdline_test_values[i];
-		int offset;
-
-		sprintf(in, "%u%s", get_random_u8(), str);
-		/* Only first '-' after the number will advance the pointer */
-		offset = strlen(in) - strlen(str) + !!(rc == 2);
-		cmdline_do_one_test(test, in, rc, offset);
-	} while (++i < ARRAY_SIZE(cmdline_test_strings));
-}
-
-static void cmdline_test_tail_int(struct kunit *test)
-{
-	unsigned int i = 0;
-	char in[32];
-
-	do {
-		const char *str = cmdline_test_strings[i];
-		/* When "" or "-" the result will be valid integer */
-		int rc = strcmp(str, "") ? (strcmp(str, "-") ? 0 : 1) : 1;
-		int offset;
-
-		sprintf(in, "%s%u", str, get_random_u8());
-		/*
-		 * Only first and leading '-' not followed by integer
-		 * will advance the pointer.
-		 */
-		offset = rc ? strlen(in) : !!(*str == '-');
-		cmdline_do_one_test(test, in, rc, offset);
-	} while (++i < ARRAY_SIZE(cmdline_test_strings));
-}
-
-static void cmdline_do_one_range_test(struct kunit *test, const char *in,
-				      unsigned int n, const int *e)
-{
-	unsigned int i;
-	int r[16];
-	int *p;
-
-	memset(r, 0, sizeof(r));
-	get_options(in, ARRAY_SIZE(r), r);
-	KUNIT_EXPECT_EQ_MSG(test, r[0], e[0], "in test %u (parsed) expected %d numbers, got %d",
-			    n, e[0], r[0]);
-	for (i = 1; i < ARRAY_SIZE(r); i++)
-		KUNIT_EXPECT_EQ_MSG(test, r[i], e[i], "in test %u at %u", n, i);
-
-	memset(r, 0, sizeof(r));
-	get_options(in, 0, r);
-	KUNIT_EXPECT_EQ_MSG(test, r[0], e[0], "in test %u (validated) expected %d numbers, got %d",
-			    n, e[0], r[0]);
-
-	p = memchr_inv(&r[1], 0, sizeof(r) - sizeof(r[0]));
-	KUNIT_EXPECT_PTR_EQ_MSG(test, p, NULL, "in test %u at %td out of bound", n, p - r);
-}
-
-static void cmdline_test_range(struct kunit *test)
-{
-	unsigned int i = 0;
-
-	do {
-		const char *str = cmdline_test_range_strings[i];
-		const int *e = cmdline_test_range_values[i];
-
-		cmdline_do_one_range_test(test, str, i, e);
-	} while (++i < ARRAY_SIZE(cmdline_test_range_strings));
-}
-
-static struct kunit_case cmdline_test_cases[] = {
-	KUNIT_CASE(cmdline_test_noint),
-	KUNIT_CASE(cmdline_test_lead_int),
-	KUNIT_CASE(cmdline_test_tail_int),
-	KUNIT_CASE(cmdline_test_range),
-	{}
-};
-
-static struct kunit_suite cmdline_test_suite = {
-	.name = "cmdline",
-	.test_cases = cmdline_test_cases,
-};
-kunit_test_suite(cmdline_test_suite);
-
-MODULE_DESCRIPTION("Test cases for API provided by cmdline.c");
-MODULE_LICENSE("GPL");
diff --git a/lib/cpumask_kunit.c a/lib/cpumask_kunit.c
deleted file mode 100644
--- a/lib/cpumask_kunit.c
+++ /dev/null
@@ -1,156 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * KUnit tests for cpumask.
- *
- * Author: Sander Vanheule <sander@xxxxxxxxxxxxx>
- */
-
-#include <kunit/test.h>
-#include <linux/cpu.h>
-#include <linux/cpumask.h>
-
-#define MASK_MSG(m) \
-	"%s contains %sCPUs %*pbl", #m, (cpumask_weight(m) ? "" : "no "), \
-	nr_cpumask_bits, cpumask_bits(m)
-
-#define EXPECT_FOR_EACH_CPU_EQ(test, mask)			\
-	do {							\
-		const cpumask_t *m = (mask);			\
-		int mask_weight = cpumask_weight(m);		\
-		int cpu, iter = 0;				\
-		for_each_cpu(cpu, m)				\
-			iter++;					\
-		KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(mask));	\
-	} while (0)
-
-#define EXPECT_FOR_EACH_CPU_OP_EQ(test, op, mask1, mask2)			\
-	do {									\
-		const cpumask_t *m1 = (mask1);					\
-		const cpumask_t *m2 = (mask2);					\
-		int weight;                                                     \
-		int cpu, iter = 0;						\
-		cpumask_##op(&mask_tmp, m1, m2);                                \
-		weight = cpumask_weight(&mask_tmp);				\
-		for_each_cpu_##op(cpu, mask1, mask2)				\
-			iter++;							\
-		KUNIT_EXPECT_EQ((test), weight, iter);				\
-	} while (0)
-
-#define EXPECT_FOR_EACH_CPU_WRAP_EQ(test, mask)			\
-	do {							\
-		const cpumask_t *m = (mask);			\
-		int mask_weight = cpumask_weight(m);		\
-		int cpu, iter = 0;				\
-		for_each_cpu_wrap(cpu, m, nr_cpu_ids / 2)	\
-			iter++;					\
-		KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(mask));	\
-	} while (0)
-
-#define EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, name)		\
-	do {							\
-		int mask_weight = num_##name##_cpus();		\
-		int cpu, iter = 0;				\
-		for_each_##name##_cpu(cpu)			\
-			iter++;					\
-		KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(cpu_##name##_mask));	\
-	} while (0)
-
-static cpumask_t mask_empty;
-static cpumask_t mask_all;
-static cpumask_t mask_tmp;
-
-static void test_cpumask_weight(struct kunit *test)
-{
-	KUNIT_EXPECT_TRUE_MSG(test, cpumask_empty(&mask_empty), MASK_MSG(&mask_empty));
-	KUNIT_EXPECT_TRUE_MSG(test, cpumask_full(&mask_all), MASK_MSG(&mask_all));
-
-	KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_weight(&mask_empty), MASK_MSG(&mask_empty));
-	KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids, cpumask_weight(cpu_possible_mask),
-			    MASK_MSG(cpu_possible_mask));
-	KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids, cpumask_weight(&mask_all), MASK_MSG(&mask_all));
-}
-
-static void test_cpumask_first(struct kunit *test)
-{
-	KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_first(&mask_empty), MASK_MSG(&mask_empty));
-	KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_first(cpu_possible_mask), MASK_MSG(cpu_possible_mask));
-
-	KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_first_zero(&mask_empty), MASK_MSG(&mask_empty));
-	KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_first_zero(cpu_possible_mask),
-			    MASK_MSG(cpu_possible_mask));
-}
-
-static void test_cpumask_last(struct kunit *test)
-{
-	KUNIT_EXPECT_LE_MSG(test, nr_cpumask_bits, cpumask_last(&mask_empty),
-			    MASK_MSG(&mask_empty));
-	KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids - 1, cpumask_last(cpu_possible_mask),
-			    MASK_MSG(cpu_possible_mask));
-}
-
-static void test_cpumask_next(struct kunit *test)
-{
-	KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_next_zero(-1, &mask_empty), MASK_MSG(&mask_empty));
-	KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_next_zero(-1, cpu_possible_mask),
-			    MASK_MSG(cpu_possible_mask));
-
-	KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_next(-1, &mask_empty),
-			    MASK_MSG(&mask_empty));
-	KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_next(-1, cpu_possible_mask),
-			    MASK_MSG(cpu_possible_mask));
-}
-
-static void test_cpumask_iterators(struct kunit *test)
-{
-	EXPECT_FOR_EACH_CPU_EQ(test, &mask_empty);
-	EXPECT_FOR_EACH_CPU_WRAP_EQ(test, &mask_empty);
-	EXPECT_FOR_EACH_CPU_OP_EQ(test, and, &mask_empty, &mask_empty);
-	EXPECT_FOR_EACH_CPU_OP_EQ(test, and, cpu_possible_mask, &mask_empty);
-	EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot, &mask_empty, &mask_empty);
-
-	EXPECT_FOR_EACH_CPU_EQ(test, cpu_possible_mask);
-	EXPECT_FOR_EACH_CPU_WRAP_EQ(test, cpu_possible_mask);
-	EXPECT_FOR_EACH_CPU_OP_EQ(test, and, cpu_possible_mask, cpu_possible_mask);
-	EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot, cpu_possible_mask, &mask_empty);
-}
-
-static void test_cpumask_iterators_builtin(struct kunit *test)
-{
-	EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, possible);
-
-	/* Ensure the dynamic masks are stable while running the tests */
-	cpu_hotplug_disable();
-
-	EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, online);
-	EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, present);
-
-	cpu_hotplug_enable();
-}
-
-static int test_cpumask_init(struct kunit *test)
-{
-	cpumask_clear(&mask_empty);
-	cpumask_setall(&mask_all);
-
-	return 0;
-}
-
-static struct kunit_case test_cpumask_cases[] = {
-	KUNIT_CASE(test_cpumask_weight),
-	KUNIT_CASE(test_cpumask_first),
-	KUNIT_CASE(test_cpumask_last),
-	KUNIT_CASE(test_cpumask_next),
-	KUNIT_CASE(test_cpumask_iterators),
-	KUNIT_CASE(test_cpumask_iterators_builtin),
-	{}
-};
-
-static struct kunit_suite test_cpumask_suite = {
-	.name = "cpumask",
-	.init = test_cpumask_init,
-	.test_cases = test_cpumask_cases,
-};
-kunit_test_suite(test_cpumask_suite);
-
-MODULE_DESCRIPTION("KUnit tests for cpumask");
-MODULE_LICENSE("GPL");
diff --git a/lib/fortify_kunit.c a/lib/fortify_kunit.c
deleted file mode 100644
--- a/lib/fortify_kunit.c
+++ /dev/null
@@ -1,1096 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Runtime test cases for CONFIG_FORTIFY_SOURCE. For additional memcpy()
- * testing see FORTIFY_MEM_* tests in LKDTM (drivers/misc/lkdtm/fortify.c).
- *
- * For corner cases with UBSAN, try testing with:
- *
- * ./tools/testing/kunit/kunit.py run --arch=x86_64 \
- *	--kconfig_add CONFIG_FORTIFY_SOURCE=y \
- *	--kconfig_add CONFIG_UBSAN=y \
- *	--kconfig_add CONFIG_UBSAN_TRAP=y \
- *	--kconfig_add CONFIG_UBSAN_BOUNDS=y \
- *	--kconfig_add CONFIG_UBSAN_LOCAL_BOUNDS=y \
- *	--make_options LLVM=1 fortify
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-/* We don't need to fill dmesg with the fortify WARNs during testing. */
-#ifdef DEBUG
-# define FORTIFY_REPORT_KUNIT(x...) __fortify_report(x)
-# define FORTIFY_WARN_KUNIT(x...)   WARN_ONCE(x)
-#else
-# define FORTIFY_REPORT_KUNIT(x...) do { } while (0)
-# define FORTIFY_WARN_KUNIT(x...)   do { } while (0)
-#endif
-
-/* Redefine fortify_panic() to track failures. */
-void fortify_add_kunit_error(int write);
-#define fortify_panic(func, write, avail, size, retfail) do {		\
-	FORTIFY_REPORT_KUNIT(FORTIFY_REASON(func, write), avail, size);	\
-	fortify_add_kunit_error(write);					\
-	return (retfail);						\
-} while (0)
-
-/* Redefine fortify_warn_once() to track memcpy() failures. */
-#define fortify_warn_once(chk_func, x...) do {				\
-	bool __result = chk_func;					\
-	FORTIFY_WARN_KUNIT(__result, x);				\
-	if (__result)							\
-		fortify_add_kunit_error(1);				\
-} while (0)
-
-#include <kunit/device.h>
-#include <kunit/test.h>
-#include <kunit/test-bug.h>
-#include <linux/device.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/vmalloc.h>
-
-/* Handle being built without CONFIG_FORTIFY_SOURCE */
-#ifndef __compiletime_strlen
-# define __compiletime_strlen __builtin_strlen
-#endif
-
-static struct kunit_resource read_resource;
-static struct kunit_resource write_resource;
-static int fortify_read_overflows;
-static int fortify_write_overflows;
-
-static const char array_of_10[] = "this is 10";
-static const char *ptr_of_11 = "this is 11!";
-static char array_unknown[] = "compiler thinks I might change";
-
-void fortify_add_kunit_error(int write)
-{
-	struct kunit_resource *resource;
-	struct kunit *current_test;
-
-	current_test = kunit_get_current_test();
-	if (!current_test)
-		return;
-
-	resource = kunit_find_named_resource(current_test,
-			write ? "fortify_write_overflows"
-			      : "fortify_read_overflows");
-	if (!resource)
-		return;
-
-	(*(int *)resource->data)++;
-	kunit_put_resource(resource);
-}
-
-static void fortify_test_known_sizes(struct kunit *test)
-{
-	KUNIT_EXPECT_EQ(test, __compiletime_strlen("88888888"), 8);
-	KUNIT_EXPECT_EQ(test, __compiletime_strlen(array_of_10), 10);
-	KUNIT_EXPECT_EQ(test, __compiletime_strlen(ptr_of_11), 11);
-
-	KUNIT_EXPECT_EQ(test, __compiletime_strlen(array_unknown), SIZE_MAX);
-	/* Externally defined and dynamically sized string pointer: */
-	KUNIT_EXPECT_EQ(test, __compiletime_strlen(test->name), SIZE_MAX);
-}
-
-/* This is volatile so the optimizer can't perform DCE below. */
-static volatile int pick;
-
-/* Not inline to keep optimizer from figuring out which string we want. */
-static noinline size_t want_minus_one(int pick)
-{
-	const char *str;
-
-	switch (pick) {
-	case 1:
-		str = "4444";
-		break;
-	case 2:
-		str = "333";
-		break;
-	default:
-		str = "1";
-		break;
-	}
-	return __compiletime_strlen(str);
-}
-
-static void fortify_test_control_flow_split(struct kunit *test)
-{
-	KUNIT_EXPECT_EQ(test, want_minus_one(pick), SIZE_MAX);
-}
-
-#define KUNIT_EXPECT_BOS(test, p, expected, name)			\
-	KUNIT_EXPECT_EQ_MSG(test, __builtin_object_size(p, 1),		\
-		expected,						\
-		"__alloc_size() not working with __bos on " name "\n")
-
-#if !__has_builtin(__builtin_dynamic_object_size)
-#define KUNIT_EXPECT_BDOS(test, p, expected, name)			\
-	/* Silence "unused variable 'expected'" warning. */		\
-	KUNIT_EXPECT_EQ(test, expected, expected)
-#else
-#define KUNIT_EXPECT_BDOS(test, p, expected, name)			\
-	KUNIT_EXPECT_EQ_MSG(test, __builtin_dynamic_object_size(p, 1),	\
-		expected,						\
-		"__alloc_size() not working with __bdos on " name "\n")
-#endif
-
-/* If the execpted size is a constant value, __bos can see it. */
-#define check_const(_expected, alloc, free)		do {		\
-	size_t expected = (_expected);					\
-	void *p = alloc;						\
-	KUNIT_EXPECT_TRUE_MSG(test, p != NULL, #alloc " failed?!\n");	\
-	KUNIT_EXPECT_BOS(test, p, expected, #alloc);			\
-	KUNIT_EXPECT_BDOS(test, p, expected, #alloc);			\
-	free;								\
-} while (0)
-
-/* If the execpted size is NOT a constant value, __bos CANNOT see it. */
-#define check_dynamic(_expected, alloc, free)		do {		\
-	size_t expected = (_expected);					\
-	void *p = alloc;						\
-	KUNIT_EXPECT_TRUE_MSG(test, p != NULL, #alloc " failed?!\n");	\
-	KUNIT_EXPECT_BOS(test, p, SIZE_MAX, #alloc);			\
-	KUNIT_EXPECT_BDOS(test, p, expected, #alloc);			\
-	free;								\
-} while (0)
-
-/* Assortment of constant-value kinda-edge cases. */
-#define CONST_TEST_BODY(TEST_alloc)	do {				\
-	/* Special-case vmalloc()-family to skip 0-sized allocs. */	\
-	if (strcmp(#TEST_alloc, "TEST_vmalloc") != 0)			\
-		TEST_alloc(check_const, 0, 0);				\
-	TEST_alloc(check_const, 1, 1);					\
-	TEST_alloc(check_const, 128, 128);				\
-	TEST_alloc(check_const, 1023, 1023);				\
-	TEST_alloc(check_const, 1025, 1025);				\
-	TEST_alloc(check_const, 4096, 4096);				\
-	TEST_alloc(check_const, 4097, 4097);				\
-} while (0)
-
-static volatile size_t zero_size;
-static volatile size_t unknown_size = 50;
-
-#if !__has_builtin(__builtin_dynamic_object_size)
-#define DYNAMIC_TEST_BODY(TEST_alloc)					\
-	kunit_skip(test, "Compiler is missing __builtin_dynamic_object_size() support\n")
-#else
-#define DYNAMIC_TEST_BODY(TEST_alloc)	do {				\
-	size_t size = unknown_size;					\
-									\
-	/*								\
-	 * Expected size is "size" in each test, before it is then	\
-	 * internally incremented in each test.	Requires we disable	\
-	 * -Wunsequenced.						\
-	 */								\
-	TEST_alloc(check_dynamic, size, size++);			\
-	/* Make sure incrementing actually happened. */			\
-	KUNIT_EXPECT_NE(test, size, unknown_size);			\
-} while (0)
-#endif
-
-#define DEFINE_ALLOC_SIZE_TEST_PAIR(allocator)				\
-static void fortify_test_alloc_size_##allocator##_const(struct kunit *test) \
-{									\
-	CONST_TEST_BODY(TEST_##allocator);				\
-}									\
-static void fortify_test_alloc_size_##allocator##_dynamic(struct kunit *test) \
-{									\
-	DYNAMIC_TEST_BODY(TEST_##allocator);				\
-}
-
-#define TEST_kmalloc(checker, expected_size, alloc_size)	do {	\
-	gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;				\
-	void *orig;							\
-	size_t len;							\
-									\
-	checker(expected_size, kmalloc(alloc_size, gfp),		\
-		kfree(p));						\
-	checker(expected_size,						\
-		kmalloc_node(alloc_size, gfp, NUMA_NO_NODE),		\
-		kfree(p));						\
-	checker(expected_size, kzalloc(alloc_size, gfp),		\
-		kfree(p));						\
-	checker(expected_size,						\
-		kzalloc_node(alloc_size, gfp, NUMA_NO_NODE),		\
-		kfree(p));						\
-	checker(expected_size, kcalloc(1, alloc_size, gfp),		\
-		kfree(p));						\
-	checker(expected_size, kcalloc(alloc_size, 1, gfp),		\
-		kfree(p));						\
-	checker(expected_size,						\
-		kcalloc_node(1, alloc_size, gfp, NUMA_NO_NODE),		\
-		kfree(p));						\
-	checker(expected_size,						\
-		kcalloc_node(alloc_size, 1, gfp, NUMA_NO_NODE),		\
-		kfree(p));						\
-	checker(expected_size, kmalloc_array(1, alloc_size, gfp),	\
-		kfree(p));						\
-	checker(expected_size, kmalloc_array(alloc_size, 1, gfp),	\
-		kfree(p));						\
-	checker(expected_size,						\
-		kmalloc_array_node(1, alloc_size, gfp, NUMA_NO_NODE),	\
-		kfree(p));						\
-	checker(expected_size,						\
-		kmalloc_array_node(alloc_size, 1, gfp, NUMA_NO_NODE),	\
-		kfree(p));						\
-									\
-	orig = kmalloc(alloc_size, gfp);				\
-	KUNIT_EXPECT_TRUE(test, orig != NULL);				\
-	checker((expected_size) * 2,					\
-		krealloc(orig, (alloc_size) * 2, gfp),			\
-		kfree(p));						\
-	orig = kmalloc(alloc_size, gfp);				\
-	KUNIT_EXPECT_TRUE(test, orig != NULL);				\
-	checker((expected_size) * 2,					\
-		krealloc_array(orig, 1, (alloc_size) * 2, gfp),		\
-		kfree(p));						\
-	orig = kmalloc(alloc_size, gfp);				\
-	KUNIT_EXPECT_TRUE(test, orig != NULL);				\
-	checker((expected_size) * 2,					\
-		krealloc_array(orig, (alloc_size) * 2, 1, gfp),		\
-		kfree(p));						\
-									\
-	len = 11;							\
-	/* Using memdup() with fixed size, so force unknown length. */	\
-	if (!__builtin_constant_p(expected_size))			\
-		len += zero_size;					\
-	checker(len, kmemdup("hello there", len, gfp), kfree(p));	\
-} while (0)
-DEFINE_ALLOC_SIZE_TEST_PAIR(kmalloc)
-
-/* Sizes are in pages, not bytes. */
-#define TEST_vmalloc(checker, expected_pages, alloc_pages)	do {	\
-	gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;				\
-	checker((expected_pages) * PAGE_SIZE,				\
-		vmalloc((alloc_pages) * PAGE_SIZE),	   vfree(p));	\
-	checker((expected_pages) * PAGE_SIZE,				\
-		vzalloc((alloc_pages) * PAGE_SIZE),	   vfree(p));	\
-	checker((expected_pages) * PAGE_SIZE,				\
-		__vmalloc((alloc_pages) * PAGE_SIZE, gfp), vfree(p));	\
-} while (0)
-DEFINE_ALLOC_SIZE_TEST_PAIR(vmalloc)
-
-/* Sizes are in pages (and open-coded for side-effects), not bytes. */
-#define TEST_kvmalloc(checker, expected_pages, alloc_pages)	do {	\
-	gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;				\
-	size_t prev_size;						\
-	void *orig;							\
-									\
-	checker((expected_pages) * PAGE_SIZE,				\
-		kvmalloc((alloc_pages) * PAGE_SIZE, gfp),		\
-		kvfree(p));						\
-	checker((expected_pages) * PAGE_SIZE,				\
-		kvmalloc_node((alloc_pages) * PAGE_SIZE, gfp, NUMA_NO_NODE), \
-		kvfree(p));						\
-	checker((expected_pages) * PAGE_SIZE,				\
-		kvzalloc((alloc_pages) * PAGE_SIZE, gfp),		\
-		kvfree(p));						\
-	checker((expected_pages) * PAGE_SIZE,				\
-		kvzalloc_node((alloc_pages) * PAGE_SIZE, gfp, NUMA_NO_NODE), \
-		kvfree(p));						\
-	checker((expected_pages) * PAGE_SIZE,				\
-		kvcalloc(1, (alloc_pages) * PAGE_SIZE, gfp),		\
-		kvfree(p));						\
-	checker((expected_pages) * PAGE_SIZE,				\
-		kvcalloc((alloc_pages) * PAGE_SIZE, 1, gfp),		\
-		kvfree(p));						\
-	checker((expected_pages) * PAGE_SIZE,				\
-		kvmalloc_array(1, (alloc_pages) * PAGE_SIZE, gfp),	\
-		kvfree(p));						\
-	checker((expected_pages) * PAGE_SIZE,				\
-		kvmalloc_array((alloc_pages) * PAGE_SIZE, 1, gfp),	\
-		kvfree(p));						\
-									\
-	prev_size = (expected_pages) * PAGE_SIZE;			\
-	orig = kvmalloc(prev_size, gfp);				\
-	KUNIT_EXPECT_TRUE(test, orig != NULL);				\
-	checker(((expected_pages) * PAGE_SIZE) * 2,			\
-		kvrealloc(orig, ((alloc_pages) * PAGE_SIZE) * 2, gfp),	\
-		kvfree(p));						\
-} while (0)
-DEFINE_ALLOC_SIZE_TEST_PAIR(kvmalloc)
-
-#define TEST_devm_kmalloc(checker, expected_size, alloc_size)	do {	\
-	gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;				\
-	const char dev_name[] = "fortify-test";				\
-	struct device *dev;						\
-	void *orig;							\
-	size_t len;							\
-									\
-	/* Create dummy device for devm_kmalloc()-family tests. */	\
-	dev = kunit_device_register(test, dev_name);			\
-	KUNIT_ASSERT_FALSE_MSG(test, IS_ERR(dev),			\
-			       "Cannot register test device\n");	\
-									\
-	checker(expected_size, devm_kmalloc(dev, alloc_size, gfp),	\
-		devm_kfree(dev, p));					\
-	checker(expected_size, devm_kzalloc(dev, alloc_size, gfp),	\
-		devm_kfree(dev, p));					\
-	checker(expected_size,						\
-		devm_kmalloc_array(dev, 1, alloc_size, gfp),		\
-		devm_kfree(dev, p));					\
-	checker(expected_size,						\
-		devm_kmalloc_array(dev, alloc_size, 1, gfp),		\
-		devm_kfree(dev, p));					\
-	checker(expected_size,						\
-		devm_kcalloc(dev, 1, alloc_size, gfp),			\
-		devm_kfree(dev, p));					\
-	checker(expected_size,						\
-		devm_kcalloc(dev, alloc_size, 1, gfp),			\
-		devm_kfree(dev, p));					\
-									\
-	orig = devm_kmalloc(dev, alloc_size, gfp);			\
-	KUNIT_EXPECT_TRUE(test, orig != NULL);				\
-	checker((expected_size) * 2,					\
-		devm_krealloc(dev, orig, (alloc_size) * 2, gfp),	\
-		devm_kfree(dev, p));					\
-									\
-	len = 4;							\
-	/* Using memdup() with fixed size, so force unknown length. */	\
-	if (!__builtin_constant_p(expected_size))			\
-		len += zero_size;					\
-	checker(len, devm_kmemdup(dev, "Ohai", len, gfp),		\
-		devm_kfree(dev, p));					\
-									\
-	kunit_device_unregister(test, dev);				\
-} while (0)
-DEFINE_ALLOC_SIZE_TEST_PAIR(devm_kmalloc)
-
-static const char * const test_strs[] = {
-	"",
-	"Hello there",
-	"A longer string, just for variety",
-};
-
-#define TEST_realloc(checker)	do {					\
-	gfp_t gfp = GFP_KERNEL;						\
-	size_t len;							\
-	int i;								\
-									\
-	for (i = 0; i < ARRAY_SIZE(test_strs); i++) {			\
-		len = strlen(test_strs[i]);				\
-		KUNIT_EXPECT_EQ(test, __builtin_constant_p(len), 0);	\
-		checker(len, kmemdup_array(test_strs[i], 1, len, gfp),	\
-			kfree(p));					\
-		checker(len, kmemdup(test_strs[i], len, gfp),		\
-			kfree(p));					\
-	}								\
-} while (0)
-static void fortify_test_realloc_size(struct kunit *test)
-{
-	TEST_realloc(check_dynamic);
-}
-
-/*
- * We can't have an array at the end of a structure or else
- * builds without -fstrict-flex-arrays=3 will report them as
- * being an unknown length. Additionally, add bytes before
- * and after the string to catch over/underflows if tests
- * fail.
- */
-struct fortify_padding {
-	unsigned long bytes_before;
-	char buf[32];
-	unsigned long bytes_after;
-};
-/* Force compiler into not being able to resolve size at compile-time. */
-static volatile int unconst;
-
-static void fortify_test_strlen(struct kunit *test)
-{
-	struct fortify_padding pad = { };
-	int i, end = sizeof(pad.buf) - 1;
-
-	/* Fill 31 bytes with valid characters. */
-	for (i = 0; i < sizeof(pad.buf) - 1; i++)
-		pad.buf[i] = i + '0';
-	/* Trailing bytes are still %NUL. */
-	KUNIT_EXPECT_EQ(test, pad.buf[end], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* String is terminated, so strlen() is valid. */
-	KUNIT_EXPECT_EQ(test, strlen(pad.buf), end);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-
-	/* Make string unterminated, and recount. */
-	pad.buf[end] = 'A';
-	end = sizeof(pad.buf);
-	KUNIT_EXPECT_EQ(test, strlen(pad.buf), end);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
-}
-
-static void fortify_test_strnlen(struct kunit *test)
-{
-	struct fortify_padding pad = { };
-	int i, end = sizeof(pad.buf) - 1;
-
-	/* Fill 31 bytes with valid characters. */
-	for (i = 0; i < sizeof(pad.buf) - 1; i++)
-		pad.buf[i] = i + '0';
-	/* Trailing bytes are still %NUL. */
-	KUNIT_EXPECT_EQ(test, pad.buf[end], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* String is terminated, so strnlen() is valid. */
-	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, sizeof(pad.buf)), end);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	/* A truncated strnlen() will be safe, too. */
-	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, sizeof(pad.buf) / 2),
-					sizeof(pad.buf) / 2);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-
-	/* Make string unterminated, and recount. */
-	pad.buf[end] = 'A';
-	end = sizeof(pad.buf);
-	/* Reading beyond with strncpy() will fail. */
-	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end + 1), end);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
-	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end + 2), end);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
-
-	/* Early-truncated is safe still, though. */
-	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end), end);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
-
-	end = sizeof(pad.buf) / 2;
-	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end), end);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
-}
-
-static void fortify_test_strcpy(struct kunit *test)
-{
-	struct fortify_padding pad = { };
-	char src[sizeof(pad.buf) + 1] = { };
-	int i;
-
-	/* Fill 31 bytes with valid characters. */
-	for (i = 0; i < sizeof(src) - 2; i++)
-		src[i] = i + '0';
-
-	/* Destination is %NUL-filled to start with. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* Legitimate strcpy() 1 less than of max size. */
-	KUNIT_ASSERT_TRUE(test, strcpy(pad.buf, src)
-				== pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Only last byte should be %NUL */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-
-	src[sizeof(src) - 2] = 'A';
-	/* But now we trip the overflow checking. */
-	KUNIT_ASSERT_TRUE(test, strcpy(pad.buf, src)
-				== pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
-	/* Trailing %NUL -- thanks to FORTIFY. */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	/* And we will not have gone beyond. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	src[sizeof(src) - 1] = 'A';
-	/* And for sure now, two bytes past. */
-	KUNIT_ASSERT_TRUE(test, strcpy(pad.buf, src)
-				== pad.buf);
-	/*
-	 * Which trips both the strlen() on the unterminated src,
-	 * and the resulting copy attempt.
-	 */
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
-	/* Trailing %NUL -- thanks to FORTIFY. */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	/* And we will not have gone beyond. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-}
-
-static void fortify_test_strncpy(struct kunit *test)
-{
-	struct fortify_padding pad = { };
-	char src[] = "Copy me fully into a small buffer and I will overflow!";
-
-	/* Destination is %NUL-filled to start with. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* Legitimate strncpy() 1 less than of max size. */
-	KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src,
-					sizeof(pad.buf) + unconst - 1)
-				== pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Only last byte should be %NUL */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-
-	/* Legitimate (though unterminated) max-size strncpy. */
-	KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src,
-					sizeof(pad.buf) + unconst)
-				== pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* No trailing %NUL -- thanks strncpy API. */
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	/* But we will not have gone beyond. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* Now verify that FORTIFY is working... */
-	KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src,
-					sizeof(pad.buf) + unconst + 1)
-				== pad.buf);
-	/* Should catch the overflow. */
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	/* And we will not have gone beyond. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* And further... */
-	KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src,
-					sizeof(pad.buf) + unconst + 2)
-				== pad.buf);
-	/* Should catch the overflow. */
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	/* And we will not have gone beyond. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-}
-
-static void fortify_test_strscpy(struct kunit *test)
-{
-	struct fortify_padding pad = { };
-	char src[] = "Copy me fully into a small buffer and I will overflow!";
-
-	/* Destination is %NUL-filled to start with. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* Legitimate strscpy() 1 less than of max size. */
-	KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src,
-				      sizeof(pad.buf) + unconst - 1),
-			-E2BIG);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Keeping space for %NUL, last two bytes should be %NUL */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-
-	/* Legitimate max-size strscpy. */
-	KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src,
-				      sizeof(pad.buf) + unconst),
-			-E2BIG);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* A trailing %NUL will exist. */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-
-	/* Now verify that FORTIFY is working... */
-	KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src,
-				      sizeof(pad.buf) + unconst + 1),
-			-E2BIG);
-	/* Should catch the overflow. */
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	/* And we will not have gone beyond. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* And much further... */
-	KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src,
-				      sizeof(src) * 2 + unconst),
-			-E2BIG);
-	/* Should catch the overflow. */
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	/* And we will not have gone beyond. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-}
-
-static void fortify_test_strcat(struct kunit *test)
-{
-	struct fortify_padding pad = { };
-	char src[sizeof(pad.buf) / 2] = { };
-	char one[] = "A";
-	char two[] = "BC";
-	int i;
-
-	/* Fill 15 bytes with valid characters. */
-	for (i = 0; i < sizeof(src) - 1; i++)
-		src[i] = i + 'A';
-
-	/* Destination is %NUL-filled to start with. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* Legitimate strcat() using less than half max size. */
-	KUNIT_ASSERT_TRUE(test, strcat(pad.buf, src) == pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Legitimate strcat() now 2 bytes shy of end. */
-	KUNIT_ASSERT_TRUE(test, strcat(pad.buf, src) == pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Last two bytes should be %NUL */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-
-	/* Add one more character to the end. */
-	KUNIT_ASSERT_TRUE(test, strcat(pad.buf, one) == pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Last byte should be %NUL */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-
-	/* And this one char will overflow. */
-	KUNIT_ASSERT_TRUE(test, strcat(pad.buf, one) == pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
-	/* Last byte should be %NUL thanks to FORTIFY. */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* And adding two will overflow more. */
-	KUNIT_ASSERT_TRUE(test, strcat(pad.buf, two) == pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
-	/* Last byte should be %NUL thanks to FORTIFY. */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-}
-
-static void fortify_test_strncat(struct kunit *test)
-{
-	struct fortify_padding pad = { };
-	char src[sizeof(pad.buf)] = { };
-	int i, partial;
-
-	/* Fill 31 bytes with valid characters. */
-	partial = sizeof(src) / 2 - 1;
-	for (i = 0; i < partial; i++)
-		src[i] = i + 'A';
-
-	/* Destination is %NUL-filled to start with. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* Legitimate strncat() using less than half max size. */
-	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, partial) == pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Legitimate strncat() now 2 bytes shy of end. */
-	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, partial) == pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Last two bytes should be %NUL */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-
-	/* Add one more character to the end. */
-	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 1) == pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Last byte should be %NUL */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-
-	/* And this one char will overflow. */
-	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 1) == pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
-	/* Last byte should be %NUL thanks to FORTIFY. */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* And adding two will overflow more. */
-	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 2) == pad.buf);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
-	/* Last byte should be %NUL thanks to FORTIFY. */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* Force an unterminated destination, and overflow. */
-	pad.buf[sizeof(pad.buf) - 1] = 'A';
-	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 1) == pad.buf);
-	/* This will have tripped both strlen() and strcat(). */
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 3);
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	/* But we should not go beyond the end. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-}
-
-static void fortify_test_strlcat(struct kunit *test)
-{
-	struct fortify_padding pad = { };
-	char src[sizeof(pad.buf)] = { };
-	int i, partial;
-	int len = sizeof(pad.buf) + unconst;
-
-	/* Fill 15 bytes with valid characters. */
-	partial = sizeof(src) / 2 - 1;
-	for (i = 0; i < partial; i++)
-		src[i] = i + 'A';
-
-	/* Destination is %NUL-filled to start with. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* Legitimate strlcat() using less than half max size. */
-	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, src, len), partial);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Legitimate strlcat() now 2 bytes shy of end. */
-	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, src, len), partial * 2);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Last two bytes should be %NUL */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-
-	/* Add one more character to the end. */
-	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "Q", len), partial * 2 + 1);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
-	/* Last byte should be %NUL */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-
-	/* And this one char will overflow. */
-	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "V", len * 2), len);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
-	/* Last byte should be %NUL thanks to FORTIFY. */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* And adding two will overflow more. */
-	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "QQ", len * 2), len + 1);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
-	/* Last byte should be %NUL thanks to FORTIFY. */
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* Force an unterminated destination, and overflow. */
-	pad.buf[sizeof(pad.buf) - 1] = 'A';
-	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "TT", len * 2), len + 2);
-	/* This will have tripped both strlen() and strlcat(). */
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
-	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
-	/* But we should not go beyond the end. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-
-	/* Force an unterminated source, and overflow. */
-	memset(src, 'B', sizeof(src));
-	pad.buf[sizeof(pad.buf) - 1] = '\0';
-	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, src, len * 3), len - 1 + sizeof(src));
-	/* This will have tripped both strlen() and strlcat(). */
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 3);
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 3);
-	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
-	/* But we should not go beyond the end. */
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
-}
-
-/* Check for 0-sized arrays... */
-struct fortify_zero_sized {
-	unsigned long bytes_before;
-	char buf[0];
-	unsigned long bytes_after;
-};
-
-#define __fortify_test(memfunc)					\
-static void fortify_test_##memfunc(struct kunit *test)		\
-{								\
-	struct fortify_zero_sized zero = { };			\
-	struct fortify_padding pad = { };			\
-	char srcA[sizeof(pad.buf) + 2];				\
-	char srcB[sizeof(pad.buf) + 2];				\
-	size_t len = sizeof(pad.buf) + unconst;			\
-								\
-	memset(srcA, 'A', sizeof(srcA));			\
-	KUNIT_ASSERT_EQ(test, srcA[0], 'A');			\
-	memset(srcB, 'B', sizeof(srcB));			\
-	KUNIT_ASSERT_EQ(test, srcB[0], 'B');			\
-								\
-	memfunc(pad.buf, srcA, 0 + unconst);			\
-	KUNIT_EXPECT_EQ(test, pad.buf[0], '\0');		\
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
-	memfunc(pad.buf + 1, srcB, 1 + unconst);		\
-	KUNIT_EXPECT_EQ(test, pad.buf[0], '\0');		\
-	KUNIT_EXPECT_EQ(test, pad.buf[1], 'B');			\
-	KUNIT_EXPECT_EQ(test, pad.buf[2], '\0');		\
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
-	memfunc(pad.buf, srcA, 1 + unconst);			\
-	KUNIT_EXPECT_EQ(test, pad.buf[0], 'A');			\
-	KUNIT_EXPECT_EQ(test, pad.buf[1], 'B');			\
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
-	memfunc(pad.buf, srcA, len - 1);			\
-	KUNIT_EXPECT_EQ(test, pad.buf[1], 'A');			\
-	KUNIT_EXPECT_EQ(test, pad.buf[len - 1], '\0');		\
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
-	memfunc(pad.buf, srcA, len);				\
-	KUNIT_EXPECT_EQ(test, pad.buf[1], 'A');			\
-	KUNIT_EXPECT_EQ(test, pad.buf[len - 1], 'A');		\
-	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);		\
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
-	memfunc(pad.buf, srcA, len + 1);			\
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);	\
-	memfunc(pad.buf + 1, srcB, len);			\
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);	\
-								\
-	/* Reset error counter. */				\
-	fortify_write_overflows = 0;				\
-	/* Copy nothing into nothing: no errors. */		\
-	memfunc(zero.buf, srcB, 0 + unconst);			\
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
-	memfunc(zero.buf, srcB, 1 + unconst);			\
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
-	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);	\
-}
-__fortify_test(memcpy)
-__fortify_test(memmove)
-
-static void fortify_test_memscan(struct kunit *test)
-{
-	char haystack[] = "Where oh where is my memory range?";
-	char *mem = haystack + strlen("Where oh where is ");
-	char needle = 'm';
-	size_t len = sizeof(haystack) + unconst;
-
-	KUNIT_ASSERT_PTR_EQ(test, memscan(haystack, needle, len),
-				  mem);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	/* Catch too-large range. */
-	KUNIT_ASSERT_PTR_EQ(test, memscan(haystack, needle, len + 1),
-				  NULL);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
-	KUNIT_ASSERT_PTR_EQ(test, memscan(haystack, needle, len * 2),
-				  NULL);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
-}
-
-static void fortify_test_memchr(struct kunit *test)
-{
-	char haystack[] = "Where oh where is my memory range?";
-	char *mem = haystack + strlen("Where oh where is ");
-	char needle = 'm';
-	size_t len = sizeof(haystack) + unconst;
-
-	KUNIT_ASSERT_PTR_EQ(test, memchr(haystack, needle, len),
-				  mem);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	/* Catch too-large range. */
-	KUNIT_ASSERT_PTR_EQ(test, memchr(haystack, needle, len + 1),
-				  NULL);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
-	KUNIT_ASSERT_PTR_EQ(test, memchr(haystack, needle, len * 2),
-				  NULL);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
-}
-
-static void fortify_test_memchr_inv(struct kunit *test)
-{
-	char haystack[] = "Where oh where is my memory range?";
-	char *mem = haystack + 1;
-	char needle = 'W';
-	size_t len = sizeof(haystack) + unconst;
-
-	/* Normal search is okay. */
-	KUNIT_ASSERT_PTR_EQ(test, memchr_inv(haystack, needle, len),
-				  mem);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	/* Catch too-large range. */
-	KUNIT_ASSERT_PTR_EQ(test, memchr_inv(haystack, needle, len + 1),
-				  NULL);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
-	KUNIT_ASSERT_PTR_EQ(test, memchr_inv(haystack, needle, len * 2),
-				  NULL);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
-}
-
-static void fortify_test_memcmp(struct kunit *test)
-{
-	char one[] = "My mind is going ...";
-	char two[] = "My mind is going ... I can feel it.";
-	size_t one_len = sizeof(one) + unconst - 1;
-	size_t two_len = sizeof(two) + unconst - 1;
-
-	/* We match the first string (ignoring the %NUL). */
-	KUNIT_ASSERT_EQ(test, memcmp(one, two, one_len), 0);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	/* Still in bounds, but no longer matching. */
-	KUNIT_ASSERT_LT(test, memcmp(one, two, one_len + 1), 0);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-
-	/* Catch too-large ranges. */
-	KUNIT_ASSERT_EQ(test, memcmp(one, two, one_len + 2), INT_MIN);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
-
-	KUNIT_ASSERT_EQ(test, memcmp(two, one, two_len + 2), INT_MIN);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
-}
-
-static void fortify_test_kmemdup(struct kunit *test)
-{
-	char src[] = "I got Doom running on it!";
-	char *copy;
-	size_t len = sizeof(src) + unconst;
-
-	/* Copy is within bounds. */
-	copy = kmemdup(src, len, GFP_KERNEL);
-	KUNIT_EXPECT_NOT_NULL(test, copy);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	kfree(copy);
-
-	/* Without %NUL. */
-	copy = kmemdup(src, len - 1, GFP_KERNEL);
-	KUNIT_EXPECT_NOT_NULL(test, copy);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	kfree(copy);
-
-	/* Tiny bounds. */
-	copy = kmemdup(src, 1, GFP_KERNEL);
-	KUNIT_EXPECT_NOT_NULL(test, copy);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
-	kfree(copy);
-
-	/* Out of bounds by 1 byte. */
-	copy = kmemdup(src, len + 1, GFP_KERNEL);
-	KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
-	kfree(copy);
-
-	/* Way out of bounds. */
-	copy = kmemdup(src, len * 2, GFP_KERNEL);
-	KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
-	kfree(copy);
-
-	/* Starting offset causing out of bounds. */
-	copy = kmemdup(src + 1, len, GFP_KERNEL);
-	KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR);
-	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 3);
-	kfree(copy);
-}
-
-static int fortify_test_init(struct kunit *test)
-{
-	if (!IS_ENABLED(CONFIG_FORTIFY_SOURCE))
-		kunit_skip(test, "Not built with CONFIG_FORTIFY_SOURCE=y");
-
-	fortify_read_overflows = 0;
-	kunit_add_named_resource(test, NULL, NULL, &read_resource,
-				 "fortify_read_overflows",
-				 &fortify_read_overflows);
-	fortify_write_overflows = 0;
-	kunit_add_named_resource(test, NULL, NULL, &write_resource,
-				 "fortify_write_overflows",
-				 &fortify_write_overflows);
-	return 0;
-}
-
-static struct kunit_case fortify_test_cases[] = {
-	KUNIT_CASE(fortify_test_known_sizes),
-	KUNIT_CASE(fortify_test_control_flow_split),
-	KUNIT_CASE(fortify_test_alloc_size_kmalloc_const),
-	KUNIT_CASE(fortify_test_alloc_size_kmalloc_dynamic),
-	KUNIT_CASE(fortify_test_alloc_size_vmalloc_const),
-	KUNIT_CASE(fortify_test_alloc_size_vmalloc_dynamic),
-	KUNIT_CASE(fortify_test_alloc_size_kvmalloc_const),
-	KUNIT_CASE(fortify_test_alloc_size_kvmalloc_dynamic),
-	KUNIT_CASE(fortify_test_alloc_size_devm_kmalloc_const),
-	KUNIT_CASE(fortify_test_alloc_size_devm_kmalloc_dynamic),
-	KUNIT_CASE(fortify_test_realloc_size),
-	KUNIT_CASE(fortify_test_strlen),
-	KUNIT_CASE(fortify_test_strnlen),
-	KUNIT_CASE(fortify_test_strcpy),
-	KUNIT_CASE(fortify_test_strncpy),
-	KUNIT_CASE(fortify_test_strscpy),
-	KUNIT_CASE(fortify_test_strcat),
-	KUNIT_CASE(fortify_test_strncat),
-	KUNIT_CASE(fortify_test_strlcat),
-	/* skip memset: performs bounds checking on whole structs */
-	KUNIT_CASE(fortify_test_memcpy),
-	KUNIT_CASE(fortify_test_memmove),
-	KUNIT_CASE(fortify_test_memscan),
-	KUNIT_CASE(fortify_test_memchr),
-	KUNIT_CASE(fortify_test_memchr_inv),
-	KUNIT_CASE(fortify_test_memcmp),
-	KUNIT_CASE(fortify_test_kmemdup),
-	{}
-};
-
-static struct kunit_suite fortify_test_suite = {
-	.name = "fortify",
-	.init = fortify_test_init,
-	.test_cases = fortify_test_cases,
-};
-
-kunit_test_suite(fortify_test_suite);
-
-MODULE_DESCRIPTION("Runtime test cases for CONFIG_FORTIFY_SOURCE");
-MODULE_LICENSE("GPL");
diff --git a/lib/hashtable_test.c a/lib/hashtable_test.c
deleted file mode 100644
--- a/lib/hashtable_test.c
+++ /dev/null
@@ -1,318 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * KUnit test for the Kernel Hashtable structures.
- *
- * Copyright (C) 2022, Google LLC.
- * Author: Rae Moar <rmoar@xxxxxxxxxx>
- */
-#include <kunit/test.h>
-
-#include <linux/hashtable.h>
-
-struct hashtable_test_entry {
-	int key;
-	int data;
-	struct hlist_node node;
-	int visited;
-};
-
-static void hashtable_test_hash_init(struct kunit *test)
-{
-	/* Test the different ways of initialising a hashtable. */
-	DEFINE_HASHTABLE(hash1, 2);
-	DECLARE_HASHTABLE(hash2, 3);
-
-	/* When using DECLARE_HASHTABLE, must use hash_init to
-	 * initialize the hashtable.
-	 */
-	hash_init(hash2);
-
-	KUNIT_EXPECT_TRUE(test, hash_empty(hash1));
-	KUNIT_EXPECT_TRUE(test, hash_empty(hash2));
-}
-
-static void hashtable_test_hash_empty(struct kunit *test)
-{
-	struct hashtable_test_entry a;
-	DEFINE_HASHTABLE(hash, 1);
-
-	KUNIT_EXPECT_TRUE(test, hash_empty(hash));
-
-	a.key = 1;
-	a.data = 13;
-	hash_add(hash, &a.node, a.key);
-
-	/* Hashtable should no longer be empty. */
-	KUNIT_EXPECT_FALSE(test, hash_empty(hash));
-}
-
-static void hashtable_test_hash_hashed(struct kunit *test)
-{
-	struct hashtable_test_entry a, b;
-	DEFINE_HASHTABLE(hash, 4);
-
-	a.key = 1;
-	a.data = 13;
-	hash_add(hash, &a.node, a.key);
-	b.key = 1;
-	b.data = 2;
-	hash_add(hash, &b.node, b.key);
-
-	KUNIT_EXPECT_TRUE(test, hash_hashed(&a.node));
-	KUNIT_EXPECT_TRUE(test, hash_hashed(&b.node));
-}
-
-static void hashtable_test_hash_add(struct kunit *test)
-{
-	struct hashtable_test_entry a, b, *x;
-	int bkt;
-	DEFINE_HASHTABLE(hash, 3);
-
-	a.key = 1;
-	a.data = 13;
-	a.visited = 0;
-	hash_add(hash, &a.node, a.key);
-	b.key = 2;
-	b.data = 10;
-	b.visited = 0;
-	hash_add(hash, &b.node, b.key);
-
-	hash_for_each(hash, bkt, x, node) {
-		x->visited++;
-		if (x->key == a.key)
-			KUNIT_EXPECT_EQ(test, x->data, 13);
-		else if (x->key == b.key)
-			KUNIT_EXPECT_EQ(test, x->data, 10);
-		else
-			KUNIT_FAIL(test, "Unexpected key in hashtable.");
-	}
-
-	/* Both entries should have been visited exactly once. */
-	KUNIT_EXPECT_EQ(test, a.visited, 1);
-	KUNIT_EXPECT_EQ(test, b.visited, 1);
-}
-
-static void hashtable_test_hash_del(struct kunit *test)
-{
-	struct hashtable_test_entry a, b, *x;
-	DEFINE_HASHTABLE(hash, 6);
-
-	a.key = 1;
-	a.data = 13;
-	hash_add(hash, &a.node, a.key);
-	b.key = 2;
-	b.data = 10;
-	b.visited = 0;
-	hash_add(hash, &b.node, b.key);
-
-	hash_del(&b.node);
-	hash_for_each_possible(hash, x, node, b.key) {
-		x->visited++;
-		KUNIT_EXPECT_NE(test, x->key, b.key);
-	}
-
-	/* The deleted entry should not have been visited. */
-	KUNIT_EXPECT_EQ(test, b.visited, 0);
-
-	hash_del(&a.node);
-
-	/* The hashtable should be empty. */
-	KUNIT_EXPECT_TRUE(test, hash_empty(hash));
-}
-
-static void hashtable_test_hash_for_each(struct kunit *test)
-{
-	struct hashtable_test_entry entries[3];
-	struct hashtable_test_entry *x;
-	int bkt, i, j, count;
-	DEFINE_HASHTABLE(hash, 3);
-
-	/* Add three entries to the hashtable. */
-	for (i = 0; i < 3; i++) {
-		entries[i].key = i;
-		entries[i].data = i + 10;
-		entries[i].visited = 0;
-		hash_add(hash, &entries[i].node, entries[i].key);
-	}
-
-	count = 0;
-	hash_for_each(hash, bkt, x, node) {
-		x->visited += 1;
-		KUNIT_ASSERT_GE_MSG(test, x->key, 0, "Unexpected key in hashtable.");
-		KUNIT_ASSERT_LT_MSG(test, x->key, 3, "Unexpected key in hashtable.");
-		count++;
-	}
-
-	/* Should have visited each entry exactly once. */
-	KUNIT_EXPECT_EQ(test, count, 3);
-	for (j = 0; j < 3; j++)
-		KUNIT_EXPECT_EQ(test, entries[j].visited, 1);
-}
-
-static void hashtable_test_hash_for_each_safe(struct kunit *test)
-{
-	struct hashtable_test_entry entries[3];
-	struct hashtable_test_entry *x;
-	struct hlist_node *tmp;
-	int bkt, i, j, count;
-	DEFINE_HASHTABLE(hash, 3);
-
-	/* Add three entries to the hashtable. */
-	for (i = 0; i < 3; i++) {
-		entries[i].key = i;
-		entries[i].data = i + 10;
-		entries[i].visited = 0;
-		hash_add(hash, &entries[i].node, entries[i].key);
-	}
-
-	count = 0;
-	hash_for_each_safe(hash, bkt, tmp, x, node) {
-		x->visited += 1;
-		KUNIT_ASSERT_GE_MSG(test, x->key, 0, "Unexpected key in hashtable.");
-		KUNIT_ASSERT_LT_MSG(test, x->key, 3, "Unexpected key in hashtable.");
-		count++;
-
-		/* Delete entry during loop. */
-		hash_del(&x->node);
-	}
-
-	/* Should have visited each entry exactly once. */
-	KUNIT_EXPECT_EQ(test, count, 3);
-	for (j = 0; j < 3; j++)
-		KUNIT_EXPECT_EQ(test, entries[j].visited, 1);
-}
-
-static void hashtable_test_hash_for_each_possible(struct kunit *test)
-{
-	struct hashtable_test_entry entries[4];
-	struct hashtable_test_entry *x, *y;
-	int buckets[2];
-	int bkt, i, j, count;
-	DEFINE_HASHTABLE(hash, 5);
-
-	/* Add three entries with key = 0 to the hashtable. */
-	for (i = 0; i < 3; i++) {
-		entries[i].key = 0;
-		entries[i].data = i;
-		entries[i].visited = 0;
-		hash_add(hash, &entries[i].node, entries[i].key);
-	}
-
-	/* Add an entry with key = 1. */
-	entries[3].key = 1;
-	entries[3].data = 3;
-	entries[3].visited = 0;
-	hash_add(hash, &entries[3].node, entries[3].key);
-
-	count = 0;
-	hash_for_each_possible(hash, x, node, 0) {
-		x->visited += 1;
-		KUNIT_ASSERT_GE_MSG(test, x->data, 0, "Unexpected data in hashtable.");
-		KUNIT_ASSERT_LT_MSG(test, x->data, 4, "Unexpected data in hashtable.");
-		count++;
-	}
-
-	/* Should have visited each entry with key = 0 exactly once. */
-	for (j = 0; j < 3; j++)
-		KUNIT_EXPECT_EQ(test, entries[j].visited, 1);
-
-	/* Save the buckets for the different keys. */
-	hash_for_each(hash, bkt, y, node) {
-		KUNIT_ASSERT_GE_MSG(test, y->key, 0, "Unexpected key in hashtable.");
-		KUNIT_ASSERT_LE_MSG(test, y->key, 1, "Unexpected key in hashtable.");
-		buckets[y->key] = bkt;
-	}
-
-	/* If entry with key = 1 is in the same bucket as the entries with
-	 * key = 0, check it was visited. Otherwise ensure that only three
-	 * entries were visited.
-	 */
-	if (buckets[0] == buckets[1]) {
-		KUNIT_EXPECT_EQ(test, count, 4);
-		KUNIT_EXPECT_EQ(test, entries[3].visited, 1);
-	} else {
-		KUNIT_EXPECT_EQ(test, count, 3);
-		KUNIT_EXPECT_EQ(test, entries[3].visited, 0);
-	}
-}
-
-static void hashtable_test_hash_for_each_possible_safe(struct kunit *test)
-{
-	struct hashtable_test_entry entries[4];
-	struct hashtable_test_entry *x, *y;
-	struct hlist_node *tmp;
-	int buckets[2];
-	int bkt, i, j, count;
-	DEFINE_HASHTABLE(hash, 5);
-
-	/* Add three entries with key = 0 to the hashtable. */
-	for (i = 0; i < 3; i++) {
-		entries[i].key = 0;
-		entries[i].data = i;
-		entries[i].visited = 0;
-		hash_add(hash, &entries[i].node, entries[i].key);
-	}
-
-	/* Add an entry with key = 1. */
-	entries[3].key = 1;
-	entries[3].data = 3;
-	entries[3].visited = 0;
-	hash_add(hash, &entries[3].node, entries[3].key);
-
-	count = 0;
-	hash_for_each_possible_safe(hash, x, tmp, node, 0) {
-		x->visited += 1;
-		KUNIT_ASSERT_GE_MSG(test, x->data, 0, "Unexpected data in hashtable.");
-		KUNIT_ASSERT_LT_MSG(test, x->data, 4, "Unexpected data in hashtable.");
-		count++;
-
-		/* Delete entry during loop. */
-		hash_del(&x->node);
-	}
-
-	/* Should have visited each entry with key = 0 exactly once. */
-	for (j = 0; j < 3; j++)
-		KUNIT_EXPECT_EQ(test, entries[j].visited, 1);
-
-	/* Save the buckets for the different keys. */
-	hash_for_each(hash, bkt, y, node) {
-		KUNIT_ASSERT_GE_MSG(test, y->key, 0, "Unexpected key in hashtable.");
-		KUNIT_ASSERT_LE_MSG(test, y->key, 1, "Unexpected key in hashtable.");
-		buckets[y->key] = bkt;
-	}
-
-	/* If entry with key = 1 is in the same bucket as the entries with
-	 * key = 0, check it was visited. Otherwise ensure that only three
-	 * entries were visited.
-	 */
-	if (buckets[0] == buckets[1]) {
-		KUNIT_EXPECT_EQ(test, count, 4);
-		KUNIT_EXPECT_EQ(test, entries[3].visited, 1);
-	} else {
-		KUNIT_EXPECT_EQ(test, count, 3);
-		KUNIT_EXPECT_EQ(test, entries[3].visited, 0);
-	}
-}
-
-static struct kunit_case hashtable_test_cases[] = {
-	KUNIT_CASE(hashtable_test_hash_init),
-	KUNIT_CASE(hashtable_test_hash_empty),
-	KUNIT_CASE(hashtable_test_hash_hashed),
-	KUNIT_CASE(hashtable_test_hash_add),
-	KUNIT_CASE(hashtable_test_hash_del),
-	KUNIT_CASE(hashtable_test_hash_for_each),
-	KUNIT_CASE(hashtable_test_hash_for_each_safe),
-	KUNIT_CASE(hashtable_test_hash_for_each_possible),
-	KUNIT_CASE(hashtable_test_hash_for_each_possible_safe),
-	{},
-};
-
-static struct kunit_suite hashtable_test_module = {
-	.name = "hashtable",
-	.test_cases = hashtable_test_cases,
-};
-
-kunit_test_suites(&hashtable_test_module);
-
-MODULE_DESCRIPTION("KUnit test for the Kernel Hashtable structures");
-MODULE_LICENSE("GPL");
diff --git a/lib/is_signed_type_kunit.c a/lib/is_signed_type_kunit.c
deleted file mode 100644
--- a/lib/is_signed_type_kunit.c
+++ /dev/null
@@ -1,50 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR MIT
-/*
- *	./tools/testing/kunit/kunit.py run is_signed_type [--raw_output]
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <kunit/test.h>
-#include <linux/compiler.h>
-
-enum unsigned_enum {
-	constant_a = 3,
-};
-
-enum signed_enum {
-	constant_b = -1,
-	constant_c = 2,
-};
-
-static void is_signed_type_test(struct kunit *test)
-{
-	KUNIT_EXPECT_EQ(test, is_signed_type(bool), false);
-	KUNIT_EXPECT_EQ(test, is_signed_type(signed char), true);
-	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned char), false);
-	KUNIT_EXPECT_EQ(test, is_signed_type(char), false);
-	KUNIT_EXPECT_EQ(test, is_signed_type(int), true);
-	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned int), false);
-	KUNIT_EXPECT_EQ(test, is_signed_type(long), true);
-	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned long), false);
-	KUNIT_EXPECT_EQ(test, is_signed_type(long long), true);
-	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned long long), false);
-	KUNIT_EXPECT_EQ(test, is_signed_type(enum unsigned_enum), false);
-	KUNIT_EXPECT_EQ(test, is_signed_type(enum signed_enum), true);
-	KUNIT_EXPECT_EQ(test, is_signed_type(void *), false);
-	KUNIT_EXPECT_EQ(test, is_signed_type(const char *), false);
-}
-
-static struct kunit_case is_signed_type_test_cases[] = {
-	KUNIT_CASE(is_signed_type_test),
-	{}
-};
-
-static struct kunit_suite is_signed_type_test_suite = {
-	.name = "is_signed_type",
-	.test_cases = is_signed_type_test_cases,
-};
-
-kunit_test_suite(is_signed_type_test_suite);
-
-MODULE_DESCRIPTION("is_signed_type() KUnit test suite");
-MODULE_LICENSE("Dual MIT/GPL");
diff --git a/lib/kunit_iov_iter.c a/lib/kunit_iov_iter.c
deleted file mode 100644
--- a/lib/kunit_iov_iter.c
+++ /dev/null
@@ -1,1036 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* I/O iterator tests.  This can only test kernel-backed iterator types.
- *
- * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@xxxxxxxxxx)
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/uio.h>
-#include <linux/bvec.h>
-#include <linux/folio_queue.h>
-#include <kunit/test.h>
-
-MODULE_DESCRIPTION("iov_iter testing");
-MODULE_AUTHOR("David Howells <dhowells@xxxxxxxxxx>");
-MODULE_LICENSE("GPL");
-
-struct kvec_test_range {
-	int	from, to;
-};
-
-static const struct kvec_test_range kvec_test_ranges[] = {
-	{ 0x00002, 0x00002 },
-	{ 0x00027, 0x03000 },
-	{ 0x05193, 0x18794 },
-	{ 0x20000, 0x20000 },
-	{ 0x20000, 0x24000 },
-	{ 0x24000, 0x27001 },
-	{ 0x29000, 0xffffb },
-	{ 0xffffd, 0xffffe },
-	{ -1 }
-};
-
-static inline u8 pattern(unsigned long x)
-{
-	return x & 0xff;
-}
-
-static void iov_kunit_unmap(void *data)
-{
-	vunmap(data);
-}
-
-static void *__init iov_kunit_create_buffer(struct kunit *test,
-					    struct page ***ppages,
-					    size_t npages)
-{
-	struct page **pages;
-	unsigned long got;
-	void *buffer;
-
-	pages = kunit_kcalloc(test, npages, sizeof(struct page *), GFP_KERNEL);
-        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pages);
-	*ppages = pages;
-
-	got = alloc_pages_bulk_array(GFP_KERNEL, npages, pages);
-	if (got != npages) {
-		release_pages(pages, got);
-		KUNIT_ASSERT_EQ(test, got, npages);
-	}
-
-	for (int i = 0; i < npages; i++)
-		pages[i]->index = i;
-
-	buffer = vmap(pages, npages, VM_MAP | VM_MAP_PUT_PAGES, PAGE_KERNEL);
-        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buffer);
-
-	kunit_add_action_or_reset(test, iov_kunit_unmap, buffer);
-	return buffer;
-}
-
-static void __init iov_kunit_load_kvec(struct kunit *test,
-				       struct iov_iter *iter, int dir,
-				       struct kvec *kvec, unsigned int kvmax,
-				       void *buffer, size_t bufsize,
-				       const struct kvec_test_range *pr)
-{
-	size_t size = 0;
-	int i;
-
-	for (i = 0; i < kvmax; i++, pr++) {
-		if (pr->from < 0)
-			break;
-		KUNIT_ASSERT_GE(test, pr->to, pr->from);
-		KUNIT_ASSERT_LE(test, pr->to, bufsize);
-		kvec[i].iov_base = buffer + pr->from;
-		kvec[i].iov_len = pr->to - pr->from;
-		size += pr->to - pr->from;
-	}
-	KUNIT_ASSERT_LE(test, size, bufsize);
-
-	iov_iter_kvec(iter, dir, kvec, i, size);
-}
-
-/*
- * Test copying to a ITER_KVEC-type iterator.
- */
-static void __init iov_kunit_copy_to_kvec(struct kunit *test)
-{
-	const struct kvec_test_range *pr;
-	struct iov_iter iter;
-	struct page **spages, **bpages;
-	struct kvec kvec[8];
-	u8 *scratch, *buffer;
-	size_t bufsize, npages, size, copied;
-	int i, patt;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	scratch = iov_kunit_create_buffer(test, &spages, npages);
-	for (i = 0; i < bufsize; i++)
-		scratch[i] = pattern(i);
-
-	buffer = iov_kunit_create_buffer(test, &bpages, npages);
-	memset(buffer, 0, bufsize);
-
-	iov_kunit_load_kvec(test, &iter, READ, kvec, ARRAY_SIZE(kvec),
-			    buffer, bufsize, kvec_test_ranges);
-	size = iter.count;
-
-	copied = copy_to_iter(scratch, size, &iter);
-
-	KUNIT_EXPECT_EQ(test, copied, size);
-	KUNIT_EXPECT_EQ(test, iter.count, 0);
-	KUNIT_EXPECT_EQ(test, iter.nr_segs, 0);
-
-	/* Build the expected image in the scratch buffer. */
-	patt = 0;
-	memset(scratch, 0, bufsize);
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++)
-		for (i = pr->from; i < pr->to; i++)
-			scratch[i] = pattern(patt++);
-
-	/* Compare the images */
-	for (i = 0; i < bufsize; i++) {
-		KUNIT_EXPECT_EQ_MSG(test, buffer[i], scratch[i], "at i=%x", i);
-		if (buffer[i] != scratch[i])
-			return;
-	}
-
-	KUNIT_SUCCEED(test);
-}
-
-/*
- * Test copying from a ITER_KVEC-type iterator.
- */
-static void __init iov_kunit_copy_from_kvec(struct kunit *test)
-{
-	const struct kvec_test_range *pr;
-	struct iov_iter iter;
-	struct page **spages, **bpages;
-	struct kvec kvec[8];
-	u8 *scratch, *buffer;
-	size_t bufsize, npages, size, copied;
-	int i, j;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	buffer = iov_kunit_create_buffer(test, &bpages, npages);
-	for (i = 0; i < bufsize; i++)
-		buffer[i] = pattern(i);
-
-	scratch = iov_kunit_create_buffer(test, &spages, npages);
-	memset(scratch, 0, bufsize);
-
-	iov_kunit_load_kvec(test, &iter, WRITE, kvec, ARRAY_SIZE(kvec),
-			    buffer, bufsize, kvec_test_ranges);
-	size = min(iter.count, bufsize);
-
-	copied = copy_from_iter(scratch, size, &iter);
-
-	KUNIT_EXPECT_EQ(test, copied, size);
-	KUNIT_EXPECT_EQ(test, iter.count, 0);
-	KUNIT_EXPECT_EQ(test, iter.nr_segs, 0);
-
-	/* Build the expected image in the main buffer. */
-	i = 0;
-	memset(buffer, 0, bufsize);
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
-		for (j = pr->from; j < pr->to; j++) {
-			buffer[i++] = pattern(j);
-			if (i >= bufsize)
-				goto stop;
-		}
-	}
-stop:
-
-	/* Compare the images */
-	for (i = 0; i < bufsize; i++) {
-		KUNIT_EXPECT_EQ_MSG(test, scratch[i], buffer[i], "at i=%x", i);
-		if (scratch[i] != buffer[i])
-			return;
-	}
-
-	KUNIT_SUCCEED(test);
-}
-
-struct bvec_test_range {
-	int	page, from, to;
-};
-
-static const struct bvec_test_range bvec_test_ranges[] = {
-	{ 0, 0x0002, 0x0002 },
-	{ 1, 0x0027, 0x0893 },
-	{ 2, 0x0193, 0x0794 },
-	{ 3, 0x0000, 0x1000 },
-	{ 4, 0x0000, 0x1000 },
-	{ 5, 0x0000, 0x1000 },
-	{ 6, 0x0000, 0x0ffb },
-	{ 6, 0x0ffd, 0x0ffe },
-	{ -1, -1, -1 }
-};
-
-static void __init iov_kunit_load_bvec(struct kunit *test,
-				       struct iov_iter *iter, int dir,
-				       struct bio_vec *bvec, unsigned int bvmax,
-				       struct page **pages, size_t npages,
-				       size_t bufsize,
-				       const struct bvec_test_range *pr)
-{
-	struct page *can_merge = NULL, *page;
-	size_t size = 0;
-	int i;
-
-	for (i = 0; i < bvmax; i++, pr++) {
-		if (pr->from < 0)
-			break;
-		KUNIT_ASSERT_LT(test, pr->page, npages);
-		KUNIT_ASSERT_LT(test, pr->page * PAGE_SIZE, bufsize);
-		KUNIT_ASSERT_GE(test, pr->from, 0);
-		KUNIT_ASSERT_GE(test, pr->to, pr->from);
-		KUNIT_ASSERT_LE(test, pr->to, PAGE_SIZE);
-
-		page = pages[pr->page];
-		if (pr->from == 0 && pr->from != pr->to && page == can_merge) {
-			i--;
-			bvec[i].bv_len += pr->to;
-		} else {
-			bvec_set_page(&bvec[i], page, pr->to - pr->from, pr->from);
-		}
-
-		size += pr->to - pr->from;
-		if ((pr->to & ~PAGE_MASK) == 0)
-			can_merge = page + pr->to / PAGE_SIZE;
-		else
-			can_merge = NULL;
-	}
-
-	iov_iter_bvec(iter, dir, bvec, i, size);
-}
-
-/*
- * Test copying to a ITER_BVEC-type iterator.
- */
-static void __init iov_kunit_copy_to_bvec(struct kunit *test)
-{
-	const struct bvec_test_range *pr;
-	struct iov_iter iter;
-	struct bio_vec bvec[8];
-	struct page **spages, **bpages;
-	u8 *scratch, *buffer;
-	size_t bufsize, npages, size, copied;
-	int i, b, patt;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	scratch = iov_kunit_create_buffer(test, &spages, npages);
-	for (i = 0; i < bufsize; i++)
-		scratch[i] = pattern(i);
-
-	buffer = iov_kunit_create_buffer(test, &bpages, npages);
-	memset(buffer, 0, bufsize);
-
-	iov_kunit_load_bvec(test, &iter, READ, bvec, ARRAY_SIZE(bvec),
-			    bpages, npages, bufsize, bvec_test_ranges);
-	size = iter.count;
-
-	copied = copy_to_iter(scratch, size, &iter);
-
-	KUNIT_EXPECT_EQ(test, copied, size);
-	KUNIT_EXPECT_EQ(test, iter.count, 0);
-	KUNIT_EXPECT_EQ(test, iter.nr_segs, 0);
-
-	/* Build the expected image in the scratch buffer. */
-	b = 0;
-	patt = 0;
-	memset(scratch, 0, bufsize);
-	for (pr = bvec_test_ranges; pr->from >= 0; pr++, b++) {
-		u8 *p = scratch + pr->page * PAGE_SIZE;
-
-		for (i = pr->from; i < pr->to; i++)
-			p[i] = pattern(patt++);
-	}
-
-	/* Compare the images */
-	for (i = 0; i < bufsize; i++) {
-		KUNIT_EXPECT_EQ_MSG(test, buffer[i], scratch[i], "at i=%x", i);
-		if (buffer[i] != scratch[i])
-			return;
-	}
-
-	KUNIT_SUCCEED(test);
-}
-
-/*
- * Test copying from a ITER_BVEC-type iterator.
- */
-static void __init iov_kunit_copy_from_bvec(struct kunit *test)
-{
-	const struct bvec_test_range *pr;
-	struct iov_iter iter;
-	struct bio_vec bvec[8];
-	struct page **spages, **bpages;
-	u8 *scratch, *buffer;
-	size_t bufsize, npages, size, copied;
-	int i, j;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	buffer = iov_kunit_create_buffer(test, &bpages, npages);
-	for (i = 0; i < bufsize; i++)
-		buffer[i] = pattern(i);
-
-	scratch = iov_kunit_create_buffer(test, &spages, npages);
-	memset(scratch, 0, bufsize);
-
-	iov_kunit_load_bvec(test, &iter, WRITE, bvec, ARRAY_SIZE(bvec),
-			    bpages, npages, bufsize, bvec_test_ranges);
-	size = iter.count;
-
-	copied = copy_from_iter(scratch, size, &iter);
-
-	KUNIT_EXPECT_EQ(test, copied, size);
-	KUNIT_EXPECT_EQ(test, iter.count, 0);
-	KUNIT_EXPECT_EQ(test, iter.nr_segs, 0);
-
-	/* Build the expected image in the main buffer. */
-	i = 0;
-	memset(buffer, 0, bufsize);
-	for (pr = bvec_test_ranges; pr->from >= 0; pr++) {
-		size_t patt = pr->page * PAGE_SIZE;
-
-		for (j = pr->from; j < pr->to; j++) {
-			buffer[i++] = pattern(patt + j);
-			if (i >= bufsize)
-				goto stop;
-		}
-	}
-stop:
-
-	/* Compare the images */
-	for (i = 0; i < bufsize; i++) {
-		KUNIT_EXPECT_EQ_MSG(test, scratch[i], buffer[i], "at i=%x", i);
-		if (scratch[i] != buffer[i])
-			return;
-	}
-
-	KUNIT_SUCCEED(test);
-}
-
-static void iov_kunit_destroy_folioq(void *data)
-{
-	struct folio_queue *folioq, *next;
-
-	for (folioq = data; folioq; folioq = next) {
-		next = folioq->next;
-		for (int i = 0; i < folioq_nr_slots(folioq); i++)
-			if (folioq_folio(folioq, i))
-				folio_put(folioq_folio(folioq, i));
-		kfree(folioq);
-	}
-}
-
-static void __init iov_kunit_load_folioq(struct kunit *test,
-					struct iov_iter *iter, int dir,
-					struct folio_queue *folioq,
-					struct page **pages, size_t npages)
-{
-	struct folio_queue *p = folioq;
-	size_t size = 0;
-	int i;
-
-	for (i = 0; i < npages; i++) {
-		if (folioq_full(p)) {
-			p->next = kzalloc(sizeof(struct folio_queue), GFP_KERNEL);
-			KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p->next);
-			folioq_init(p->next);
-			p->next->prev = p;
-			p = p->next;
-		}
-		folioq_append(p, page_folio(pages[i]));
-		size += PAGE_SIZE;
-	}
-	iov_iter_folio_queue(iter, dir, folioq, 0, 0, size);
-}
-
-static struct folio_queue *iov_kunit_create_folioq(struct kunit *test)
-{
-	struct folio_queue *folioq;
-
-	folioq = kzalloc(sizeof(struct folio_queue), GFP_KERNEL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, folioq);
-	kunit_add_action_or_reset(test, iov_kunit_destroy_folioq, folioq);
-	folioq_init(folioq);
-	return folioq;
-}
-
-/*
- * Test copying to a ITER_FOLIOQ-type iterator.
- */
-static void __init iov_kunit_copy_to_folioq(struct kunit *test)
-{
-	const struct kvec_test_range *pr;
-	struct iov_iter iter;
-	struct folio_queue *folioq;
-	struct page **spages, **bpages;
-	u8 *scratch, *buffer;
-	size_t bufsize, npages, size, copied;
-	int i, patt;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	folioq = iov_kunit_create_folioq(test);
-
-	scratch = iov_kunit_create_buffer(test, &spages, npages);
-	for (i = 0; i < bufsize; i++)
-		scratch[i] = pattern(i);
-
-	buffer = iov_kunit_create_buffer(test, &bpages, npages);
-	memset(buffer, 0, bufsize);
-
-	iov_kunit_load_folioq(test, &iter, READ, folioq, bpages, npages);
-
-	i = 0;
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
-		size = pr->to - pr->from;
-		KUNIT_ASSERT_LE(test, pr->to, bufsize);
-
-		iov_iter_folio_queue(&iter, READ, folioq, 0, 0, pr->to);
-		iov_iter_advance(&iter, pr->from);
-		copied = copy_to_iter(scratch + i, size, &iter);
-
-		KUNIT_EXPECT_EQ(test, copied, size);
-		KUNIT_EXPECT_EQ(test, iter.count, 0);
-		KUNIT_EXPECT_EQ(test, iter.iov_offset, pr->to % PAGE_SIZE);
-		i += size;
-		if (test->status == KUNIT_FAILURE)
-			goto stop;
-	}
-
-	/* Build the expected image in the scratch buffer. */
-	patt = 0;
-	memset(scratch, 0, bufsize);
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++)
-		for (i = pr->from; i < pr->to; i++)
-			scratch[i] = pattern(patt++);
-
-	/* Compare the images */
-	for (i = 0; i < bufsize; i++) {
-		KUNIT_EXPECT_EQ_MSG(test, buffer[i], scratch[i], "at i=%x", i);
-		if (buffer[i] != scratch[i])
-			return;
-	}
-
-stop:
-	KUNIT_SUCCEED(test);
-}
-
-/*
- * Test copying from a ITER_FOLIOQ-type iterator.
- */
-static void __init iov_kunit_copy_from_folioq(struct kunit *test)
-{
-	const struct kvec_test_range *pr;
-	struct iov_iter iter;
-	struct folio_queue *folioq;
-	struct page **spages, **bpages;
-	u8 *scratch, *buffer;
-	size_t bufsize, npages, size, copied;
-	int i, j;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	folioq = iov_kunit_create_folioq(test);
-
-	buffer = iov_kunit_create_buffer(test, &bpages, npages);
-	for (i = 0; i < bufsize; i++)
-		buffer[i] = pattern(i);
-
-	scratch = iov_kunit_create_buffer(test, &spages, npages);
-	memset(scratch, 0, bufsize);
-
-	iov_kunit_load_folioq(test, &iter, READ, folioq, bpages, npages);
-
-	i = 0;
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
-		size = pr->to - pr->from;
-		KUNIT_ASSERT_LE(test, pr->to, bufsize);
-
-		iov_iter_folio_queue(&iter, WRITE, folioq, 0, 0, pr->to);
-		iov_iter_advance(&iter, pr->from);
-		copied = copy_from_iter(scratch + i, size, &iter);
-
-		KUNIT_EXPECT_EQ(test, copied, size);
-		KUNIT_EXPECT_EQ(test, iter.count, 0);
-		KUNIT_EXPECT_EQ(test, iter.iov_offset, pr->to % PAGE_SIZE);
-		i += size;
-	}
-
-	/* Build the expected image in the main buffer. */
-	i = 0;
-	memset(buffer, 0, bufsize);
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
-		for (j = pr->from; j < pr->to; j++) {
-			buffer[i++] = pattern(j);
-			if (i >= bufsize)
-				goto stop;
-		}
-	}
-stop:
-
-	/* Compare the images */
-	for (i = 0; i < bufsize; i++) {
-		KUNIT_EXPECT_EQ_MSG(test, scratch[i], buffer[i], "at i=%x", i);
-		if (scratch[i] != buffer[i])
-			return;
-	}
-
-	KUNIT_SUCCEED(test);
-}
-
-static void iov_kunit_destroy_xarray(void *data)
-{
-	struct xarray *xarray = data;
-
-	xa_destroy(xarray);
-	kfree(xarray);
-}
-
-static void __init iov_kunit_load_xarray(struct kunit *test,
-					 struct iov_iter *iter, int dir,
-					 struct xarray *xarray,
-					 struct page **pages, size_t npages)
-{
-	size_t size = 0;
-	int i;
-
-	for (i = 0; i < npages; i++) {
-		void *x = xa_store(xarray, i, pages[i], GFP_KERNEL);
-
-		KUNIT_ASSERT_FALSE(test, xa_is_err(x));
-		size += PAGE_SIZE;
-	}
-	iov_iter_xarray(iter, dir, xarray, 0, size);
-}
-
-static struct xarray *iov_kunit_create_xarray(struct kunit *test)
-{
-	struct xarray *xarray;
-
-	xarray = kzalloc(sizeof(struct xarray), GFP_KERNEL);
-	xa_init(xarray);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xarray);
-	kunit_add_action_or_reset(test, iov_kunit_destroy_xarray, xarray);
-	return xarray;
-}
-
-/*
- * Test copying to a ITER_XARRAY-type iterator.
- */
-static void __init iov_kunit_copy_to_xarray(struct kunit *test)
-{
-	const struct kvec_test_range *pr;
-	struct iov_iter iter;
-	struct xarray *xarray;
-	struct page **spages, **bpages;
-	u8 *scratch, *buffer;
-	size_t bufsize, npages, size, copied;
-	int i, patt;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	xarray = iov_kunit_create_xarray(test);
-
-	scratch = iov_kunit_create_buffer(test, &spages, npages);
-	for (i = 0; i < bufsize; i++)
-		scratch[i] = pattern(i);
-
-	buffer = iov_kunit_create_buffer(test, &bpages, npages);
-	memset(buffer, 0, bufsize);
-
-	iov_kunit_load_xarray(test, &iter, READ, xarray, bpages, npages);
-
-	i = 0;
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
-		size = pr->to - pr->from;
-		KUNIT_ASSERT_LE(test, pr->to, bufsize);
-
-		iov_iter_xarray(&iter, READ, xarray, pr->from, size);
-		copied = copy_to_iter(scratch + i, size, &iter);
-
-		KUNIT_EXPECT_EQ(test, copied, size);
-		KUNIT_EXPECT_EQ(test, iter.count, 0);
-		KUNIT_EXPECT_EQ(test, iter.iov_offset, size);
-		i += size;
-	}
-
-	/* Build the expected image in the scratch buffer. */
-	patt = 0;
-	memset(scratch, 0, bufsize);
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++)
-		for (i = pr->from; i < pr->to; i++)
-			scratch[i] = pattern(patt++);
-
-	/* Compare the images */
-	for (i = 0; i < bufsize; i++) {
-		KUNIT_EXPECT_EQ_MSG(test, buffer[i], scratch[i], "at i=%x", i);
-		if (buffer[i] != scratch[i])
-			return;
-	}
-
-	KUNIT_SUCCEED(test);
-}
-
-/*
- * Test copying from a ITER_XARRAY-type iterator.
- */
-static void __init iov_kunit_copy_from_xarray(struct kunit *test)
-{
-	const struct kvec_test_range *pr;
-	struct iov_iter iter;
-	struct xarray *xarray;
-	struct page **spages, **bpages;
-	u8 *scratch, *buffer;
-	size_t bufsize, npages, size, copied;
-	int i, j;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	xarray = iov_kunit_create_xarray(test);
-
-	buffer = iov_kunit_create_buffer(test, &bpages, npages);
-	for (i = 0; i < bufsize; i++)
-		buffer[i] = pattern(i);
-
-	scratch = iov_kunit_create_buffer(test, &spages, npages);
-	memset(scratch, 0, bufsize);
-
-	iov_kunit_load_xarray(test, &iter, READ, xarray, bpages, npages);
-
-	i = 0;
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
-		size = pr->to - pr->from;
-		KUNIT_ASSERT_LE(test, pr->to, bufsize);
-
-		iov_iter_xarray(&iter, WRITE, xarray, pr->from, size);
-		copied = copy_from_iter(scratch + i, size, &iter);
-
-		KUNIT_EXPECT_EQ(test, copied, size);
-		KUNIT_EXPECT_EQ(test, iter.count, 0);
-		KUNIT_EXPECT_EQ(test, iter.iov_offset, size);
-		i += size;
-	}
-
-	/* Build the expected image in the main buffer. */
-	i = 0;
-	memset(buffer, 0, bufsize);
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
-		for (j = pr->from; j < pr->to; j++) {
-			buffer[i++] = pattern(j);
-			if (i >= bufsize)
-				goto stop;
-		}
-	}
-stop:
-
-	/* Compare the images */
-	for (i = 0; i < bufsize; i++) {
-		KUNIT_EXPECT_EQ_MSG(test, scratch[i], buffer[i], "at i=%x", i);
-		if (scratch[i] != buffer[i])
-			return;
-	}
-
-	KUNIT_SUCCEED(test);
-}
-
-/*
- * Test the extraction of ITER_KVEC-type iterators.
- */
-static void __init iov_kunit_extract_pages_kvec(struct kunit *test)
-{
-	const struct kvec_test_range *pr;
-	struct iov_iter iter;
-	struct page **bpages, *pagelist[8], **pages = pagelist;
-	struct kvec kvec[8];
-	u8 *buffer;
-	ssize_t len;
-	size_t bufsize, size = 0, npages;
-	int i, from;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	buffer = iov_kunit_create_buffer(test, &bpages, npages);
-
-	iov_kunit_load_kvec(test, &iter, READ, kvec, ARRAY_SIZE(kvec),
-			    buffer, bufsize, kvec_test_ranges);
-	size = iter.count;
-
-	pr = kvec_test_ranges;
-	from = pr->from;
-	do {
-		size_t offset0 = LONG_MAX;
-
-		for (i = 0; i < ARRAY_SIZE(pagelist); i++)
-			pagelist[i] = (void *)(unsigned long)0xaa55aa55aa55aa55ULL;
-
-		len = iov_iter_extract_pages(&iter, &pages, 100 * 1024,
-					     ARRAY_SIZE(pagelist), 0, &offset0);
-		KUNIT_EXPECT_GE(test, len, 0);
-		if (len < 0)
-			break;
-		KUNIT_EXPECT_GE(test, (ssize_t)offset0, 0);
-		KUNIT_EXPECT_LT(test, offset0, PAGE_SIZE);
-		KUNIT_EXPECT_LE(test, len, size);
-		KUNIT_EXPECT_EQ(test, iter.count, size - len);
-		size -= len;
-
-		if (len == 0)
-			break;
-
-		for (i = 0; i < ARRAY_SIZE(pagelist); i++) {
-			struct page *p;
-			ssize_t part = min_t(ssize_t, len, PAGE_SIZE - offset0);
-			int ix;
-
-			KUNIT_ASSERT_GE(test, part, 0);
-			while (from == pr->to) {
-				pr++;
-				from = pr->from;
-				if (from < 0)
-					goto stop;
-			}
-			ix = from / PAGE_SIZE;
-			KUNIT_ASSERT_LT(test, ix, npages);
-			p = bpages[ix];
-			KUNIT_EXPECT_PTR_EQ(test, pagelist[i], p);
-			KUNIT_EXPECT_EQ(test, offset0, from % PAGE_SIZE);
-			from += part;
-			len -= part;
-			KUNIT_ASSERT_GE(test, len, 0);
-			if (len == 0)
-				break;
-			offset0 = 0;
-		}
-
-		if (test->status == KUNIT_FAILURE)
-			break;
-	} while (iov_iter_count(&iter) > 0);
-
-stop:
-	KUNIT_EXPECT_EQ(test, size, 0);
-	KUNIT_EXPECT_EQ(test, iter.count, 0);
-	KUNIT_SUCCEED(test);
-}
-
-/*
- * Test the extraction of ITER_BVEC-type iterators.
- */
-static void __init iov_kunit_extract_pages_bvec(struct kunit *test)
-{
-	const struct bvec_test_range *pr;
-	struct iov_iter iter;
-	struct page **bpages, *pagelist[8], **pages = pagelist;
-	struct bio_vec bvec[8];
-	ssize_t len;
-	size_t bufsize, size = 0, npages;
-	int i, from;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	iov_kunit_create_buffer(test, &bpages, npages);
-	iov_kunit_load_bvec(test, &iter, READ, bvec, ARRAY_SIZE(bvec),
-			    bpages, npages, bufsize, bvec_test_ranges);
-	size = iter.count;
-
-	pr = bvec_test_ranges;
-	from = pr->from;
-	do {
-		size_t offset0 = LONG_MAX;
-
-		for (i = 0; i < ARRAY_SIZE(pagelist); i++)
-			pagelist[i] = (void *)(unsigned long)0xaa55aa55aa55aa55ULL;
-
-		len = iov_iter_extract_pages(&iter, &pages, 100 * 1024,
-					     ARRAY_SIZE(pagelist), 0, &offset0);
-		KUNIT_EXPECT_GE(test, len, 0);
-		if (len < 0)
-			break;
-		KUNIT_EXPECT_GE(test, (ssize_t)offset0, 0);
-		KUNIT_EXPECT_LT(test, offset0, PAGE_SIZE);
-		KUNIT_EXPECT_LE(test, len, size);
-		KUNIT_EXPECT_EQ(test, iter.count, size - len);
-		size -= len;
-
-		if (len == 0)
-			break;
-
-		for (i = 0; i < ARRAY_SIZE(pagelist); i++) {
-			struct page *p;
-			ssize_t part = min_t(ssize_t, len, PAGE_SIZE - offset0);
-			int ix;
-
-			KUNIT_ASSERT_GE(test, part, 0);
-			while (from == pr->to) {
-				pr++;
-				from = pr->from;
-				if (from < 0)
-					goto stop;
-			}
-			ix = pr->page + from / PAGE_SIZE;
-			KUNIT_ASSERT_LT(test, ix, npages);
-			p = bpages[ix];
-			KUNIT_EXPECT_PTR_EQ(test, pagelist[i], p);
-			KUNIT_EXPECT_EQ(test, offset0, from % PAGE_SIZE);
-			from += part;
-			len -= part;
-			KUNIT_ASSERT_GE(test, len, 0);
-			if (len == 0)
-				break;
-			offset0 = 0;
-		}
-
-		if (test->status == KUNIT_FAILURE)
-			break;
-	} while (iov_iter_count(&iter) > 0);
-
-stop:
-	KUNIT_EXPECT_EQ(test, size, 0);
-	KUNIT_EXPECT_EQ(test, iter.count, 0);
-	KUNIT_SUCCEED(test);
-}
-
-/*
- * Test the extraction of ITER_FOLIOQ-type iterators.
- */
-static void __init iov_kunit_extract_pages_folioq(struct kunit *test)
-{
-	const struct kvec_test_range *pr;
-	struct folio_queue *folioq;
-	struct iov_iter iter;
-	struct page **bpages, *pagelist[8], **pages = pagelist;
-	ssize_t len;
-	size_t bufsize, size = 0, npages;
-	int i, from;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	folioq = iov_kunit_create_folioq(test);
-
-	iov_kunit_create_buffer(test, &bpages, npages);
-	iov_kunit_load_folioq(test, &iter, READ, folioq, bpages, npages);
-
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
-		from = pr->from;
-		size = pr->to - from;
-		KUNIT_ASSERT_LE(test, pr->to, bufsize);
-
-		iov_iter_folio_queue(&iter, WRITE, folioq, 0, 0, pr->to);
-		iov_iter_advance(&iter, from);
-
-		do {
-			size_t offset0 = LONG_MAX;
-
-			for (i = 0; i < ARRAY_SIZE(pagelist); i++)
-				pagelist[i] = (void *)(unsigned long)0xaa55aa55aa55aa55ULL;
-
-			len = iov_iter_extract_pages(&iter, &pages, 100 * 1024,
-						     ARRAY_SIZE(pagelist), 0, &offset0);
-			KUNIT_EXPECT_GE(test, len, 0);
-			if (len < 0)
-				break;
-			KUNIT_EXPECT_LE(test, len, size);
-			KUNIT_EXPECT_EQ(test, iter.count, size - len);
-			if (len == 0)
-				break;
-			size -= len;
-			KUNIT_EXPECT_GE(test, (ssize_t)offset0, 0);
-			KUNIT_EXPECT_LT(test, offset0, PAGE_SIZE);
-
-			for (i = 0; i < ARRAY_SIZE(pagelist); i++) {
-				struct page *p;
-				ssize_t part = min_t(ssize_t, len, PAGE_SIZE - offset0);
-				int ix;
-
-				KUNIT_ASSERT_GE(test, part, 0);
-				ix = from / PAGE_SIZE;
-				KUNIT_ASSERT_LT(test, ix, npages);
-				p = bpages[ix];
-				KUNIT_EXPECT_PTR_EQ(test, pagelist[i], p);
-				KUNIT_EXPECT_EQ(test, offset0, from % PAGE_SIZE);
-				from += part;
-				len -= part;
-				KUNIT_ASSERT_GE(test, len, 0);
-				if (len == 0)
-					break;
-				offset0 = 0;
-			}
-
-			if (test->status == KUNIT_FAILURE)
-				goto stop;
-		} while (iov_iter_count(&iter) > 0);
-
-		KUNIT_EXPECT_EQ(test, size, 0);
-		KUNIT_EXPECT_EQ(test, iter.count, 0);
-	}
-
-stop:
-	KUNIT_SUCCEED(test);
-}
-
-/*
- * Test the extraction of ITER_XARRAY-type iterators.
- */
-static void __init iov_kunit_extract_pages_xarray(struct kunit *test)
-{
-	const struct kvec_test_range *pr;
-	struct iov_iter iter;
-	struct xarray *xarray;
-	struct page **bpages, *pagelist[8], **pages = pagelist;
-	ssize_t len;
-	size_t bufsize, size = 0, npages;
-	int i, from;
-
-	bufsize = 0x100000;
-	npages = bufsize / PAGE_SIZE;
-
-	xarray = iov_kunit_create_xarray(test);
-
-	iov_kunit_create_buffer(test, &bpages, npages);
-	iov_kunit_load_xarray(test, &iter, READ, xarray, bpages, npages);
-
-	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
-		from = pr->from;
-		size = pr->to - from;
-		KUNIT_ASSERT_LE(test, pr->to, bufsize);
-
-		iov_iter_xarray(&iter, WRITE, xarray, from, size);
-
-		do {
-			size_t offset0 = LONG_MAX;
-
-			for (i = 0; i < ARRAY_SIZE(pagelist); i++)
-				pagelist[i] = (void *)(unsigned long)0xaa55aa55aa55aa55ULL;
-
-			len = iov_iter_extract_pages(&iter, &pages, 100 * 1024,
-						     ARRAY_SIZE(pagelist), 0, &offset0);
-			KUNIT_EXPECT_GE(test, len, 0);
-			if (len < 0)
-				break;
-			KUNIT_EXPECT_LE(test, len, size);
-			KUNIT_EXPECT_EQ(test, iter.count, size - len);
-			if (len == 0)
-				break;
-			size -= len;
-			KUNIT_EXPECT_GE(test, (ssize_t)offset0, 0);
-			KUNIT_EXPECT_LT(test, offset0, PAGE_SIZE);
-
-			for (i = 0; i < ARRAY_SIZE(pagelist); i++) {
-				struct page *p;
-				ssize_t part = min_t(ssize_t, len, PAGE_SIZE - offset0);
-				int ix;
-
-				KUNIT_ASSERT_GE(test, part, 0);
-				ix = from / PAGE_SIZE;
-				KUNIT_ASSERT_LT(test, ix, npages);
-				p = bpages[ix];
-				KUNIT_EXPECT_PTR_EQ(test, pagelist[i], p);
-				KUNIT_EXPECT_EQ(test, offset0, from % PAGE_SIZE);
-				from += part;
-				len -= part;
-				KUNIT_ASSERT_GE(test, len, 0);
-				if (len == 0)
-					break;
-				offset0 = 0;
-			}
-
-			if (test->status == KUNIT_FAILURE)
-				goto stop;
-		} while (iov_iter_count(&iter) > 0);
-
-		KUNIT_EXPECT_EQ(test, size, 0);
-		KUNIT_EXPECT_EQ(test, iter.count, 0);
-		KUNIT_EXPECT_EQ(test, iter.iov_offset, pr->to - pr->from);
-	}
-
-stop:
-	KUNIT_SUCCEED(test);
-}
-
-static struct kunit_case __refdata iov_kunit_cases[] = {
-	KUNIT_CASE(iov_kunit_copy_to_kvec),
-	KUNIT_CASE(iov_kunit_copy_from_kvec),
-	KUNIT_CASE(iov_kunit_copy_to_bvec),
-	KUNIT_CASE(iov_kunit_copy_from_bvec),
-	KUNIT_CASE(iov_kunit_copy_to_folioq),
-	KUNIT_CASE(iov_kunit_copy_from_folioq),
-	KUNIT_CASE(iov_kunit_copy_to_xarray),
-	KUNIT_CASE(iov_kunit_copy_from_xarray),
-	KUNIT_CASE(iov_kunit_extract_pages_kvec),
-	KUNIT_CASE(iov_kunit_extract_pages_bvec),
-	KUNIT_CASE(iov_kunit_extract_pages_folioq),
-	KUNIT_CASE(iov_kunit_extract_pages_xarray),
-	{}
-};
-
-static struct kunit_suite iov_kunit_suite = {
-	.name = "iov_iter",
-	.test_cases = iov_kunit_cases,
-};
-
-kunit_test_suites(&iov_kunit_suite);
diff --git a/lib/list-test.c a/lib/list-test.c
deleted file mode 100644
--- a/lib/list-test.c
+++ /dev/null
@@ -1,1505 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * KUnit test for the Kernel Linked-list structures.
- *
- * Copyright (C) 2019, Google LLC.
- * Author: David Gow <davidgow@xxxxxxxxxx>
- */
-#include <kunit/test.h>
-
-#include <linux/list.h>
-#include <linux/klist.h>
-
-struct list_test_struct {
-	int data;
-	struct list_head list;
-};
-
-static void list_test_list_init(struct kunit *test)
-{
-	/* Test the different ways of initialising a list. */
-	struct list_head list1 = LIST_HEAD_INIT(list1);
-	struct list_head list2;
-	LIST_HEAD(list3);
-	struct list_head *list4;
-	struct list_head *list5;
-
-	INIT_LIST_HEAD(&list2);
-
-	list4 = kzalloc(sizeof(*list4), GFP_KERNEL | __GFP_NOFAIL);
-	INIT_LIST_HEAD(list4);
-
-	list5 = kmalloc(sizeof(*list5), GFP_KERNEL | __GFP_NOFAIL);
-	memset(list5, 0xFF, sizeof(*list5));
-	INIT_LIST_HEAD(list5);
-
-	/* list_empty_careful() checks both next and prev. */
-	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list1));
-	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
-	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list3));
-	KUNIT_EXPECT_TRUE(test, list_empty_careful(list4));
-	KUNIT_EXPECT_TRUE(test, list_empty_careful(list5));
-
-	kfree(list4);
-	kfree(list5);
-}
-
-static void list_test_list_add(struct kunit *test)
-{
-	struct list_head a, b;
-	LIST_HEAD(list);
-
-	list_add(&a, &list);
-	list_add(&b, &list);
-
-	/* should be [list] -> b -> a */
-	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
-	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
-	KUNIT_EXPECT_PTR_EQ(test, b.next, &a);
-}
-
-static void list_test_list_add_tail(struct kunit *test)
-{
-	struct list_head a, b;
-	LIST_HEAD(list);
-
-	list_add_tail(&a, &list);
-	list_add_tail(&b, &list);
-
-	/* should be [list] -> a -> b */
-	KUNIT_EXPECT_PTR_EQ(test, list.next, &a);
-	KUNIT_EXPECT_PTR_EQ(test, a.prev, &list);
-	KUNIT_EXPECT_PTR_EQ(test, a.next, &b);
-}
-
-static void list_test_list_del(struct kunit *test)
-{
-	struct list_head a, b;
-	LIST_HEAD(list);
-
-	list_add_tail(&a, &list);
-	list_add_tail(&b, &list);
-
-	/* before: [list] -> a -> b */
-	list_del(&a);
-
-	/* now: [list] -> b */
-	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
-	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
-}
-
-static void list_test_list_replace(struct kunit *test)
-{
-	struct list_head a_old, a_new, b;
-	LIST_HEAD(list);
-
-	list_add_tail(&a_old, &list);
-	list_add_tail(&b, &list);
-
-	/* before: [list] -> a_old -> b */
-	list_replace(&a_old, &a_new);
-
-	/* now: [list] -> a_new -> b */
-	KUNIT_EXPECT_PTR_EQ(test, list.next, &a_new);
-	KUNIT_EXPECT_PTR_EQ(test, b.prev, &a_new);
-	KUNIT_EXPECT_PTR_EQ(test, a_new.next, &b);
-	KUNIT_EXPECT_PTR_EQ(test, a_new.prev, &list);
-}
-
-static void list_test_list_replace_init(struct kunit *test)
-{
-	struct list_head a_old, a_new, b;
-	LIST_HEAD(list);
-
-	list_add_tail(&a_old, &list);
-	list_add_tail(&b, &list);
-
-	/* before: [list] -> a_old -> b */
-	list_replace_init(&a_old, &a_new);
-
-	/* now: [list] -> a_new -> b */
-	KUNIT_EXPECT_PTR_EQ(test, list.next, &a_new);
-	KUNIT_EXPECT_PTR_EQ(test, b.prev, &a_new);
-	KUNIT_EXPECT_PTR_EQ(test, a_new.next, &b);
-	KUNIT_EXPECT_PTR_EQ(test, a_new.prev, &list);
-
-	/* check a_old is empty (initialized) */
-	KUNIT_EXPECT_TRUE(test, list_empty_careful(&a_old));
-}
-
-static void list_test_list_swap(struct kunit *test)
-{
-	struct list_head a, b;
-	LIST_HEAD(list);
-
-	list_add_tail(&a, &list);
-	list_add_tail(&b, &list);
-
-	/* before: [list] -> a -> b */
-	list_swap(&a, &b);
-
-	/* after: [list] -> b -> a */
-	KUNIT_EXPECT_PTR_EQ(test, &b, list.next);
-	KUNIT_EXPECT_PTR_EQ(test, &a, list.prev);
-
-	KUNIT_EXPECT_PTR_EQ(test, &a, b.next);
-	KUNIT_EXPECT_PTR_EQ(test, &list, b.prev);
-
-	KUNIT_EXPECT_PTR_EQ(test, &list, a.next);
-	KUNIT_EXPECT_PTR_EQ(test, &b, a.prev);
-}
-
-static void list_test_list_del_init(struct kunit *test)
-{
-	struct list_head a, b;
-	LIST_HEAD(list);
-
-	list_add_tail(&a, &list);
-	list_add_tail(&b, &list);
-
-	/* before: [list] -> a -> b */
-	list_del_init(&a);
-	/* after: [list] -> b, a initialised */
-
-	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
-	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
-	KUNIT_EXPECT_TRUE(test, list_empty_careful(&a));
-}
-
-static void list_test_list_del_init_careful(struct kunit *test)
-{
-	/* NOTE: This test only checks the behaviour of this function in
-	 * isolation. It does not verify memory model guarantees.
-	 */
-	struct list_head a, b;
-	LIST_HEAD(list);
-
-	list_add_tail(&a, &list);
-	list_add_tail(&b, &list);
-
-	/* before: [list] -> a -> b */
-	list_del_init_careful(&a);
-	/* after: [list] -> b, a initialised */
-
-	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
-	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
-	KUNIT_EXPECT_TRUE(test, list_empty_careful(&a));
-}
-
-static void list_test_list_move(struct kunit *test)
-{
-	struct list_head a, b;
-	LIST_HEAD(list1);
-	LIST_HEAD(list2);
-
-	list_add_tail(&a, &list1);
-	list_add_tail(&b, &list2);
-
-	/* before: [list1] -> a, [list2] -> b */
-	list_move(&a, &list2);
-	/* after: [list1] empty, [list2] -> a -> b */
-
-	KUNIT_EXPECT_TRUE(test, list_empty(&list1));
-
-	KUNIT_EXPECT_PTR_EQ(test, &a, list2.next);
-	KUNIT_EXPECT_PTR_EQ(test, &b, a.next);
-}
-
-static void list_test_list_move_tail(struct kunit *test)
-{
-	struct list_head a, b;
-	LIST_HEAD(list1);
-	LIST_HEAD(list2);
-
-	list_add_tail(&a, &list1);
-	list_add_tail(&b, &list2);
-
-	/* before: [list1] -> a, [list2] -> b */
-	list_move_tail(&a, &list2);
-	/* after: [list1] empty, [list2] -> b -> a */
-
-	KUNIT_EXPECT_TRUE(test, list_empty(&list1));
-
-	KUNIT_EXPECT_PTR_EQ(test, &b, list2.next);
-	KUNIT_EXPECT_PTR_EQ(test, &a, b.next);
-}
-
-static void list_test_list_bulk_move_tail(struct kunit *test)
-{
-	struct list_head a, b, c, d, x, y;
-	struct list_head *list1_values[] = { &x, &b, &c, &y };
-	struct list_head *list2_values[] = { &a, &d };
-	struct list_head *ptr;
-	LIST_HEAD(list1);
-	LIST_HEAD(list2);
-	int i = 0;
-
-	list_add_tail(&x, &list1);
-	list_add_tail(&y, &list1);
-
-	list_add_tail(&a, &list2);
-	list_add_tail(&b, &list2);
-	list_add_tail(&c, &list2);
-	list_add_tail(&d, &list2);
-
-	/* before: [list1] -> x -> y, [list2] -> a -> b -> c -> d */
-	list_bulk_move_tail(&y, &b, &c);
-	/* after: [list1] -> x -> b -> c -> y, [list2] -> a -> d */
-
-	list_for_each(ptr, &list1) {
-		KUNIT_EXPECT_PTR_EQ(test, ptr, list1_values[i]);
-		i++;
-	}
-	KUNIT_EXPECT_EQ(test, i, 4);
-	i = 0;
-	list_for_each(ptr, &list2) {
-		KUNIT_EXPECT_PTR_EQ(test, ptr, list2_values[i]);
-		i++;
-	}
-	KUNIT_EXPECT_EQ(test, i, 2);
-}
-
-static void list_test_list_is_head(struct kunit *test)
-{
-	struct list_head a, b, c;
-
-	/* Two lists: [a] -> b, [c] */
-	INIT_LIST_HEAD(&a);
-	INIT_LIST_HEAD(&c);
-	list_add_tail(&b, &a);
-
-	KUNIT_EXPECT_TRUE_MSG(test, list_is_head(&a, &a),
-		"Head element of same list");
-	KUNIT_EXPECT_FALSE_MSG(test, list_is_head(&a, &b),
-		"Non-head element of same list");
-	KUNIT_EXPECT_FALSE_MSG(test, list_is_head(&a, &c),
-		"Head element of different list");
-}
-
-
-static void list_test_list_is_first(struct kunit *test)
-{
-	struct list_head a, b;
-	LIST_HEAD(list);
-
-	list_add_tail(&a, &list);
-	list_add_tail(&b, &list);
-
-	KUNIT_EXPECT_TRUE(test, list_is_first(&a, &list));
-	KUNIT_EXPECT_FALSE(test, list_is_first(&b, &list));
-}
-
-static void list_test_list_is_last(struct kunit *test)
-{
-	struct list_head a, b;
-	LIST_HEAD(list);
-
-	list_add_tail(&a, &list);
-	list_add_tail(&b, &list);
-
-	KUNIT_EXPECT_FALSE(test, list_is_last(&a, &list));
-	KUNIT_EXPECT_TRUE(test, list_is_last(&b, &list));
-}
-
-static void list_test_list_empty(struct kunit *test)
-{
-	struct list_head a;
-	LIST_HEAD(list1);
-	LIST_HEAD(list2);
-
-	list_add_tail(&a, &list1);
-
-	KUNIT_EXPECT_FALSE(test, list_empty(&list1));
-	KUNIT_EXPECT_TRUE(test, list_empty(&list2));
-}
-
-static void list_test_list_empty_careful(struct kunit *test)
-{
-	/* This test doesn't check correctness under concurrent access */
-	struct list_head a;
-	LIST_HEAD(list1);
-	LIST_HEAD(list2);
-
-	list_add_tail(&a, &list1);
-
-	KUNIT_EXPECT_FALSE(test, list_empty_careful(&list1));
-	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
-}
-
-static void list_test_list_rotate_left(struct kunit *test)
-{
-	struct list_head a, b;
-	LIST_HEAD(list);
-
-	list_add_tail(&a, &list);
-	list_add_tail(&b, &list);
-
-	/* before: [list] -> a -> b */
-	list_rotate_left(&list);
-	/* after: [list] -> b -> a */
-
-	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
-	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
-	KUNIT_EXPECT_PTR_EQ(test, b.next, &a);
-}
-
-static void list_test_list_rotate_to_front(struct kunit *test)
-{
-	struct list_head a, b, c, d;
-	struct list_head *list_values[] = { &c, &d, &a, &b };
-	struct list_head *ptr;
-	LIST_HEAD(list);
-	int i = 0;
-
-	list_add_tail(&a, &list);
-	list_add_tail(&b, &list);
-	list_add_tail(&c, &list);
-	list_add_tail(&d, &list);
-
-	/* before: [list] -> a -> b -> c -> d */
-	list_rotate_to_front(&c, &list);
-	/* after: [list] -> c -> d -> a -> b */
-
-	list_for_each(ptr, &list) {
-		KUNIT_EXPECT_PTR_EQ(test, ptr, list_values[i]);
-		i++;
-	}
-	KUNIT_EXPECT_EQ(test, i, 4);
-}
-
-static void list_test_list_is_singular(struct kunit *test)
-{
-	struct list_head a, b;
-	LIST_HEAD(list);
-
-	/* [list] empty */
-	KUNIT_EXPECT_FALSE(test, list_is_singular(&list));
-
-	list_add_tail(&a, &list);
-
-	/* [list] -> a */
-	KUNIT_EXPECT_TRUE(test, list_is_singular(&list));
-
-	list_add_tail(&b, &list);
-
-	/* [list] -> a -> b */
-	KUNIT_EXPECT_FALSE(test, list_is_singular(&list));
-}
-
-static void list_test_list_cut_position(struct kunit *test)
-{
-	struct list_head entries[3], *cur;
-	LIST_HEAD(list1);
-	LIST_HEAD(list2);
-	int i = 0;
-
-	list_add_tail(&entries[0], &list1);
-	list_add_tail(&entries[1], &list1);
-	list_add_tail(&entries[2], &list1);
-
-	/* before: [list1] -> entries[0] -> entries[1] -> entries[2] */
-	list_cut_position(&list2, &list1, &entries[1]);
-	/* after: [list2] -> entries[0] -> entries[1], [list1] -> entries[2] */
-
-	list_for_each(cur, &list2) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 2);
-
-	list_for_each(cur, &list1) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 3);
-}
-
-static void list_test_list_cut_before(struct kunit *test)
-{
-	struct list_head entries[3], *cur;
-	LIST_HEAD(list1);
-	LIST_HEAD(list2);
-	int i = 0;
-
-	list_add_tail(&entries[0], &list1);
-	list_add_tail(&entries[1], &list1);
-	list_add_tail(&entries[2], &list1);
-
-	/* before: [list1] -> entries[0] -> entries[1] -> entries[2] */
-	list_cut_before(&list2, &list1, &entries[1]);
-	/* after: [list2] -> entries[0], [list1] -> entries[1] -> entries[2] */
-
-	list_for_each(cur, &list2) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 1);
-
-	list_for_each(cur, &list1) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 3);
-}
-
-static void list_test_list_splice(struct kunit *test)
-{
-	struct list_head entries[5], *cur;
-	LIST_HEAD(list1);
-	LIST_HEAD(list2);
-	int i = 0;
-
-	list_add_tail(&entries[0], &list1);
-	list_add_tail(&entries[1], &list1);
-	list_add_tail(&entries[2], &list2);
-	list_add_tail(&entries[3], &list2);
-	list_add_tail(&entries[4], &list1);
-
-	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
-	list_splice(&list2, &entries[1]);
-	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] uninit */
-
-	list_for_each(cur, &list1) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 5);
-}
-
-static void list_test_list_splice_tail(struct kunit *test)
-{
-	struct list_head entries[5], *cur;
-	LIST_HEAD(list1);
-	LIST_HEAD(list2);
-	int i = 0;
-
-	list_add_tail(&entries[0], &list1);
-	list_add_tail(&entries[1], &list1);
-	list_add_tail(&entries[2], &list2);
-	list_add_tail(&entries[3], &list2);
-	list_add_tail(&entries[4], &list1);
-
-	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
-	list_splice_tail(&list2, &entries[4]);
-	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] uninit */
-
-	list_for_each(cur, &list1) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 5);
-}
-
-static void list_test_list_splice_init(struct kunit *test)
-{
-	struct list_head entries[5], *cur;
-	LIST_HEAD(list1);
-	LIST_HEAD(list2);
-	int i = 0;
-
-	list_add_tail(&entries[0], &list1);
-	list_add_tail(&entries[1], &list1);
-	list_add_tail(&entries[2], &list2);
-	list_add_tail(&entries[3], &list2);
-	list_add_tail(&entries[4], &list1);
-
-	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
-	list_splice_init(&list2, &entries[1]);
-	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] empty */
-
-	list_for_each(cur, &list1) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 5);
-
-	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
-}
-
-static void list_test_list_splice_tail_init(struct kunit *test)
-{
-	struct list_head entries[5], *cur;
-	LIST_HEAD(list1);
-	LIST_HEAD(list2);
-	int i = 0;
-
-	list_add_tail(&entries[0], &list1);
-	list_add_tail(&entries[1], &list1);
-	list_add_tail(&entries[2], &list2);
-	list_add_tail(&entries[3], &list2);
-	list_add_tail(&entries[4], &list1);
-
-	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
-	list_splice_tail_init(&list2, &entries[4]);
-	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] empty */
-
-	list_for_each(cur, &list1) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 5);
-
-	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
-}
-
-static void list_test_list_entry(struct kunit *test)
-{
-	struct list_test_struct test_struct;
-
-	KUNIT_EXPECT_PTR_EQ(test, &test_struct, list_entry(&(test_struct.list),
-				struct list_test_struct, list));
-}
-
-static void list_test_list_entry_is_head(struct kunit *test)
-{
-	struct list_test_struct test_struct1, test_struct2, test_struct3;
-
-	INIT_LIST_HEAD(&test_struct1.list);
-	INIT_LIST_HEAD(&test_struct3.list);
-
-	list_add_tail(&test_struct2.list, &test_struct1.list);
-
-	KUNIT_EXPECT_TRUE_MSG(test,
-		list_entry_is_head((&test_struct1), &test_struct1.list, list),
-		"Head element of same list");
-	KUNIT_EXPECT_FALSE_MSG(test,
-		list_entry_is_head((&test_struct2), &test_struct1.list, list),
-		"Non-head element of same list");
-	KUNIT_EXPECT_FALSE_MSG(test,
-		list_entry_is_head((&test_struct3), &test_struct1.list, list),
-		"Head element of different list");
-}
-
-static void list_test_list_first_entry(struct kunit *test)
-{
-	struct list_test_struct test_struct1, test_struct2;
-	LIST_HEAD(list);
-
-	list_add_tail(&test_struct1.list, &list);
-	list_add_tail(&test_struct2.list, &list);
-
-
-	KUNIT_EXPECT_PTR_EQ(test, &test_struct1, list_first_entry(&list,
-				struct list_test_struct, list));
-}
-
-static void list_test_list_last_entry(struct kunit *test)
-{
-	struct list_test_struct test_struct1, test_struct2;
-	LIST_HEAD(list);
-
-	list_add_tail(&test_struct1.list, &list);
-	list_add_tail(&test_struct2.list, &list);
-
-
-	KUNIT_EXPECT_PTR_EQ(test, &test_struct2, list_last_entry(&list,
-				struct list_test_struct, list));
-}
-
-static void list_test_list_first_entry_or_null(struct kunit *test)
-{
-	struct list_test_struct test_struct1, test_struct2;
-	LIST_HEAD(list);
-
-	KUNIT_EXPECT_FALSE(test, list_first_entry_or_null(&list,
-				struct list_test_struct, list));
-
-	list_add_tail(&test_struct1.list, &list);
-	list_add_tail(&test_struct2.list, &list);
-
-	KUNIT_EXPECT_PTR_EQ(test, &test_struct1,
-			list_first_entry_or_null(&list,
-				struct list_test_struct, list));
-}
-
-static void list_test_list_next_entry(struct kunit *test)
-{
-	struct list_test_struct test_struct1, test_struct2;
-	LIST_HEAD(list);
-
-	list_add_tail(&test_struct1.list, &list);
-	list_add_tail(&test_struct2.list, &list);
-
-
-	KUNIT_EXPECT_PTR_EQ(test, &test_struct2, list_next_entry(&test_struct1,
-				list));
-}
-
-static void list_test_list_prev_entry(struct kunit *test)
-{
-	struct list_test_struct test_struct1, test_struct2;
-	LIST_HEAD(list);
-
-	list_add_tail(&test_struct1.list, &list);
-	list_add_tail(&test_struct2.list, &list);
-
-
-	KUNIT_EXPECT_PTR_EQ(test, &test_struct1, list_prev_entry(&test_struct2,
-				list));
-}
-
-static void list_test_list_for_each(struct kunit *test)
-{
-	struct list_head entries[3], *cur;
-	LIST_HEAD(list);
-	int i = 0;
-
-	list_add_tail(&entries[0], &list);
-	list_add_tail(&entries[1], &list);
-	list_add_tail(&entries[2], &list);
-
-	list_for_each(cur, &list) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 3);
-}
-
-static void list_test_list_for_each_prev(struct kunit *test)
-{
-	struct list_head entries[3], *cur;
-	LIST_HEAD(list);
-	int i = 2;
-
-	list_add_tail(&entries[0], &list);
-	list_add_tail(&entries[1], &list);
-	list_add_tail(&entries[2], &list);
-
-	list_for_each_prev(cur, &list) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		i--;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, -1);
-}
-
-static void list_test_list_for_each_safe(struct kunit *test)
-{
-	struct list_head entries[3], *cur, *n;
-	LIST_HEAD(list);
-	int i = 0;
-
-
-	list_add_tail(&entries[0], &list);
-	list_add_tail(&entries[1], &list);
-	list_add_tail(&entries[2], &list);
-
-	list_for_each_safe(cur, n, &list) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		list_del(&entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 3);
-	KUNIT_EXPECT_TRUE(test, list_empty(&list));
-}
-
-static void list_test_list_for_each_prev_safe(struct kunit *test)
-{
-	struct list_head entries[3], *cur, *n;
-	LIST_HEAD(list);
-	int i = 2;
-
-	list_add_tail(&entries[0], &list);
-	list_add_tail(&entries[1], &list);
-	list_add_tail(&entries[2], &list);
-
-	list_for_each_prev_safe(cur, n, &list) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		list_del(&entries[i]);
-		i--;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, -1);
-	KUNIT_EXPECT_TRUE(test, list_empty(&list));
-}
-
-static void list_test_list_for_each_entry(struct kunit *test)
-{
-	struct list_test_struct entries[5], *cur;
-	LIST_HEAD(list);
-	int i = 0;
-
-	for (i = 0; i < 5; ++i) {
-		entries[i].data = i;
-		list_add_tail(&entries[i].list, &list);
-	}
-
-	i = 0;
-
-	list_for_each_entry(cur, &list, list) {
-		KUNIT_EXPECT_EQ(test, cur->data, i);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 5);
-}
-
-static void list_test_list_for_each_entry_reverse(struct kunit *test)
-{
-	struct list_test_struct entries[5], *cur;
-	LIST_HEAD(list);
-	int i = 0;
-
-	for (i = 0; i < 5; ++i) {
-		entries[i].data = i;
-		list_add_tail(&entries[i].list, &list);
-	}
-
-	i = 4;
-
-	list_for_each_entry_reverse(cur, &list, list) {
-		KUNIT_EXPECT_EQ(test, cur->data, i);
-		i--;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, -1);
-}
-
-static struct kunit_case list_test_cases[] = {
-	KUNIT_CASE(list_test_list_init),
-	KUNIT_CASE(list_test_list_add),
-	KUNIT_CASE(list_test_list_add_tail),
-	KUNIT_CASE(list_test_list_del),
-	KUNIT_CASE(list_test_list_replace),
-	KUNIT_CASE(list_test_list_replace_init),
-	KUNIT_CASE(list_test_list_swap),
-	KUNIT_CASE(list_test_list_del_init),
-	KUNIT_CASE(list_test_list_del_init_careful),
-	KUNIT_CASE(list_test_list_move),
-	KUNIT_CASE(list_test_list_move_tail),
-	KUNIT_CASE(list_test_list_bulk_move_tail),
-	KUNIT_CASE(list_test_list_is_head),
-	KUNIT_CASE(list_test_list_is_first),
-	KUNIT_CASE(list_test_list_is_last),
-	KUNIT_CASE(list_test_list_empty),
-	KUNIT_CASE(list_test_list_empty_careful),
-	KUNIT_CASE(list_test_list_rotate_left),
-	KUNIT_CASE(list_test_list_rotate_to_front),
-	KUNIT_CASE(list_test_list_is_singular),
-	KUNIT_CASE(list_test_list_cut_position),
-	KUNIT_CASE(list_test_list_cut_before),
-	KUNIT_CASE(list_test_list_splice),
-	KUNIT_CASE(list_test_list_splice_tail),
-	KUNIT_CASE(list_test_list_splice_init),
-	KUNIT_CASE(list_test_list_splice_tail_init),
-	KUNIT_CASE(list_test_list_entry),
-	KUNIT_CASE(list_test_list_entry_is_head),
-	KUNIT_CASE(list_test_list_first_entry),
-	KUNIT_CASE(list_test_list_last_entry),
-	KUNIT_CASE(list_test_list_first_entry_or_null),
-	KUNIT_CASE(list_test_list_next_entry),
-	KUNIT_CASE(list_test_list_prev_entry),
-	KUNIT_CASE(list_test_list_for_each),
-	KUNIT_CASE(list_test_list_for_each_prev),
-	KUNIT_CASE(list_test_list_for_each_safe),
-	KUNIT_CASE(list_test_list_for_each_prev_safe),
-	KUNIT_CASE(list_test_list_for_each_entry),
-	KUNIT_CASE(list_test_list_for_each_entry_reverse),
-	{},
-};
-
-static struct kunit_suite list_test_module = {
-	.name = "list-kunit-test",
-	.test_cases = list_test_cases,
-};
-
-struct hlist_test_struct {
-	int data;
-	struct hlist_node list;
-};
-
-static void hlist_test_init(struct kunit *test)
-{
-	/* Test the different ways of initialising a list. */
-	struct hlist_head list1 = HLIST_HEAD_INIT;
-	struct hlist_head list2;
-	HLIST_HEAD(list3);
-	struct hlist_head *list4;
-	struct hlist_head *list5;
-
-	INIT_HLIST_HEAD(&list2);
-
-	list4 = kzalloc(sizeof(*list4), GFP_KERNEL | __GFP_NOFAIL);
-	INIT_HLIST_HEAD(list4);
-
-	list5 = kmalloc(sizeof(*list5), GFP_KERNEL | __GFP_NOFAIL);
-	memset(list5, 0xFF, sizeof(*list5));
-	INIT_HLIST_HEAD(list5);
-
-	KUNIT_EXPECT_TRUE(test, hlist_empty(&list1));
-	KUNIT_EXPECT_TRUE(test, hlist_empty(&list2));
-	KUNIT_EXPECT_TRUE(test, hlist_empty(&list3));
-	KUNIT_EXPECT_TRUE(test, hlist_empty(list4));
-	KUNIT_EXPECT_TRUE(test, hlist_empty(list5));
-
-	kfree(list4);
-	kfree(list5);
-}
-
-static void hlist_test_unhashed(struct kunit *test)
-{
-	struct hlist_node a;
-	HLIST_HEAD(list);
-
-	INIT_HLIST_NODE(&a);
-
-	/* is unhashed by default */
-	KUNIT_EXPECT_TRUE(test, hlist_unhashed(&a));
-
-	hlist_add_head(&a, &list);
-
-	/* is hashed once added to list */
-	KUNIT_EXPECT_FALSE(test, hlist_unhashed(&a));
-
-	hlist_del_init(&a);
-
-	/* is again unhashed after del_init */
-	KUNIT_EXPECT_TRUE(test, hlist_unhashed(&a));
-}
-
-/* Doesn't test concurrency guarantees */
-static void hlist_test_unhashed_lockless(struct kunit *test)
-{
-	struct hlist_node a;
-	HLIST_HEAD(list);
-
-	INIT_HLIST_NODE(&a);
-
-	/* is unhashed by default */
-	KUNIT_EXPECT_TRUE(test, hlist_unhashed_lockless(&a));
-
-	hlist_add_head(&a, &list);
-
-	/* is hashed once added to list */
-	KUNIT_EXPECT_FALSE(test, hlist_unhashed_lockless(&a));
-
-	hlist_del_init(&a);
-
-	/* is again unhashed after del_init */
-	KUNIT_EXPECT_TRUE(test, hlist_unhashed_lockless(&a));
-}
-
-static void hlist_test_del(struct kunit *test)
-{
-	struct hlist_node a, b;
-	HLIST_HEAD(list);
-
-	hlist_add_head(&a, &list);
-	hlist_add_behind(&b, &a);
-
-	/* before: [list] -> a -> b */
-	hlist_del(&a);
-
-	/* now: [list] -> b */
-	KUNIT_EXPECT_PTR_EQ(test, list.first, &b);
-	KUNIT_EXPECT_PTR_EQ(test, b.pprev, &list.first);
-}
-
-static void hlist_test_del_init(struct kunit *test)
-{
-	struct hlist_node a, b;
-	HLIST_HEAD(list);
-
-	hlist_add_head(&a, &list);
-	hlist_add_behind(&b, &a);
-
-	/* before: [list] -> a -> b */
-	hlist_del_init(&a);
-
-	/* now: [list] -> b */
-	KUNIT_EXPECT_PTR_EQ(test, list.first, &b);
-	KUNIT_EXPECT_PTR_EQ(test, b.pprev, &list.first);
-
-	/* a is now initialised */
-	KUNIT_EXPECT_PTR_EQ(test, a.next, NULL);
-	KUNIT_EXPECT_PTR_EQ(test, a.pprev, NULL);
-}
-
-/* Tests all three hlist_add_* functions */
-static void hlist_test_add(struct kunit *test)
-{
-	struct hlist_node a, b, c, d;
-	HLIST_HEAD(list);
-
-	hlist_add_head(&a, &list);
-	hlist_add_head(&b, &list);
-	hlist_add_before(&c, &a);
-	hlist_add_behind(&d, &a);
-
-	/* should be [list] -> b -> c -> a -> d */
-	KUNIT_EXPECT_PTR_EQ(test, list.first, &b);
-
-	KUNIT_EXPECT_PTR_EQ(test, c.pprev, &(b.next));
-	KUNIT_EXPECT_PTR_EQ(test, b.next, &c);
-
-	KUNIT_EXPECT_PTR_EQ(test, a.pprev, &(c.next));
-	KUNIT_EXPECT_PTR_EQ(test, c.next, &a);
-
-	KUNIT_EXPECT_PTR_EQ(test, d.pprev, &(a.next));
-	KUNIT_EXPECT_PTR_EQ(test, a.next, &d);
-}
-
-/* Tests both hlist_fake() and hlist_add_fake() */
-static void hlist_test_fake(struct kunit *test)
-{
-	struct hlist_node a;
-
-	INIT_HLIST_NODE(&a);
-
-	/* not fake after init */
-	KUNIT_EXPECT_FALSE(test, hlist_fake(&a));
-
-	hlist_add_fake(&a);
-
-	/* is now fake */
-	KUNIT_EXPECT_TRUE(test, hlist_fake(&a));
-}
-
-static void hlist_test_is_singular_node(struct kunit *test)
-{
-	struct hlist_node a, b;
-	HLIST_HEAD(list);
-
-	INIT_HLIST_NODE(&a);
-	KUNIT_EXPECT_FALSE(test, hlist_is_singular_node(&a, &list));
-
-	hlist_add_head(&a, &list);
-	KUNIT_EXPECT_TRUE(test, hlist_is_singular_node(&a, &list));
-
-	hlist_add_head(&b, &list);
-	KUNIT_EXPECT_FALSE(test, hlist_is_singular_node(&a, &list));
-	KUNIT_EXPECT_FALSE(test, hlist_is_singular_node(&b, &list));
-}
-
-static void hlist_test_empty(struct kunit *test)
-{
-	struct hlist_node a;
-	HLIST_HEAD(list);
-
-	/* list starts off empty */
-	KUNIT_EXPECT_TRUE(test, hlist_empty(&list));
-
-	hlist_add_head(&a, &list);
-
-	/* list is no longer empty */
-	KUNIT_EXPECT_FALSE(test, hlist_empty(&list));
-}
-
-static void hlist_test_move_list(struct kunit *test)
-{
-	struct hlist_node a;
-	HLIST_HEAD(list1);
-	HLIST_HEAD(list2);
-
-	hlist_add_head(&a, &list1);
-
-	KUNIT_EXPECT_FALSE(test, hlist_empty(&list1));
-	KUNIT_EXPECT_TRUE(test, hlist_empty(&list2));
-	hlist_move_list(&list1, &list2);
-	KUNIT_EXPECT_TRUE(test, hlist_empty(&list1));
-	KUNIT_EXPECT_FALSE(test, hlist_empty(&list2));
-
-}
-
-static void hlist_test_entry(struct kunit *test)
-{
-	struct hlist_test_struct test_struct;
-
-	KUNIT_EXPECT_PTR_EQ(test, &test_struct,
-			    hlist_entry(&(test_struct.list),
-				struct hlist_test_struct, list));
-}
-
-static void hlist_test_entry_safe(struct kunit *test)
-{
-	struct hlist_test_struct test_struct;
-
-	KUNIT_EXPECT_PTR_EQ(test, &test_struct,
-			    hlist_entry_safe(&(test_struct.list),
-				struct hlist_test_struct, list));
-
-	KUNIT_EXPECT_PTR_EQ(test, NULL,
-			    hlist_entry_safe((struct hlist_node *)NULL,
-				struct hlist_test_struct, list));
-}
-
-static void hlist_test_for_each(struct kunit *test)
-{
-	struct hlist_node entries[3], *cur;
-	HLIST_HEAD(list);
-	int i = 0;
-
-	hlist_add_head(&entries[0], &list);
-	hlist_add_behind(&entries[1], &entries[0]);
-	hlist_add_behind(&entries[2], &entries[1]);
-
-	hlist_for_each(cur, &list) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 3);
-}
-
-
-static void hlist_test_for_each_safe(struct kunit *test)
-{
-	struct hlist_node entries[3], *cur, *n;
-	HLIST_HEAD(list);
-	int i = 0;
-
-	hlist_add_head(&entries[0], &list);
-	hlist_add_behind(&entries[1], &entries[0]);
-	hlist_add_behind(&entries[2], &entries[1]);
-
-	hlist_for_each_safe(cur, n, &list) {
-		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
-		hlist_del(&entries[i]);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 3);
-	KUNIT_EXPECT_TRUE(test, hlist_empty(&list));
-}
-
-static void hlist_test_for_each_entry(struct kunit *test)
-{
-	struct hlist_test_struct entries[5], *cur;
-	HLIST_HEAD(list);
-	int i = 0;
-
-	entries[0].data = 0;
-	hlist_add_head(&entries[0].list, &list);
-	for (i = 1; i < 5; ++i) {
-		entries[i].data = i;
-		hlist_add_behind(&entries[i].list, &entries[i-1].list);
-	}
-
-	i = 0;
-
-	hlist_for_each_entry(cur, &list, list) {
-		KUNIT_EXPECT_EQ(test, cur->data, i);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 5);
-}
-
-static void hlist_test_for_each_entry_continue(struct kunit *test)
-{
-	struct hlist_test_struct entries[5], *cur;
-	HLIST_HEAD(list);
-	int i = 0;
-
-	entries[0].data = 0;
-	hlist_add_head(&entries[0].list, &list);
-	for (i = 1; i < 5; ++i) {
-		entries[i].data = i;
-		hlist_add_behind(&entries[i].list, &entries[i-1].list);
-	}
-
-	/* We skip the first (zero-th) entry. */
-	i = 1;
-
-	cur = &entries[0];
-	hlist_for_each_entry_continue(cur, list) {
-		KUNIT_EXPECT_EQ(test, cur->data, i);
-		/* Stamp over the entry. */
-		cur->data = 42;
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 5);
-	/* The first entry was not visited. */
-	KUNIT_EXPECT_EQ(test, entries[0].data, 0);
-	/* The second (and presumably others), were. */
-	KUNIT_EXPECT_EQ(test, entries[1].data, 42);
-}
-
-static void hlist_test_for_each_entry_from(struct kunit *test)
-{
-	struct hlist_test_struct entries[5], *cur;
-	HLIST_HEAD(list);
-	int i = 0;
-
-	entries[0].data = 0;
-	hlist_add_head(&entries[0].list, &list);
-	for (i = 1; i < 5; ++i) {
-		entries[i].data = i;
-		hlist_add_behind(&entries[i].list, &entries[i-1].list);
-	}
-
-	i = 0;
-
-	cur = &entries[0];
-	hlist_for_each_entry_from(cur, list) {
-		KUNIT_EXPECT_EQ(test, cur->data, i);
-		/* Stamp over the entry. */
-		cur->data = 42;
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 5);
-	/* The first entry was visited. */
-	KUNIT_EXPECT_EQ(test, entries[0].data, 42);
-}
-
-static void hlist_test_for_each_entry_safe(struct kunit *test)
-{
-	struct hlist_test_struct entries[5], *cur;
-	struct hlist_node *tmp_node;
-	HLIST_HEAD(list);
-	int i = 0;
-
-	entries[0].data = 0;
-	hlist_add_head(&entries[0].list, &list);
-	for (i = 1; i < 5; ++i) {
-		entries[i].data = i;
-		hlist_add_behind(&entries[i].list, &entries[i-1].list);
-	}
-
-	i = 0;
-
-	hlist_for_each_entry_safe(cur, tmp_node, &list, list) {
-		KUNIT_EXPECT_EQ(test, cur->data, i);
-		hlist_del(&cur->list);
-		i++;
-	}
-
-	KUNIT_EXPECT_EQ(test, i, 5);
-	KUNIT_EXPECT_TRUE(test, hlist_empty(&list));
-}
-
-
-static struct kunit_case hlist_test_cases[] = {
-	KUNIT_CASE(hlist_test_init),
-	KUNIT_CASE(hlist_test_unhashed),
-	KUNIT_CASE(hlist_test_unhashed_lockless),
-	KUNIT_CASE(hlist_test_del),
-	KUNIT_CASE(hlist_test_del_init),
-	KUNIT_CASE(hlist_test_add),
-	KUNIT_CASE(hlist_test_fake),
-	KUNIT_CASE(hlist_test_is_singular_node),
-	KUNIT_CASE(hlist_test_empty),
-	KUNIT_CASE(hlist_test_move_list),
-	KUNIT_CASE(hlist_test_entry),
-	KUNIT_CASE(hlist_test_entry_safe),
-	KUNIT_CASE(hlist_test_for_each),
-	KUNIT_CASE(hlist_test_for_each_safe),
-	KUNIT_CASE(hlist_test_for_each_entry),
-	KUNIT_CASE(hlist_test_for_each_entry_continue),
-	KUNIT_CASE(hlist_test_for_each_entry_from),
-	KUNIT_CASE(hlist_test_for_each_entry_safe),
-	{},
-};
-
-static struct kunit_suite hlist_test_module = {
-	.name = "hlist",
-	.test_cases = hlist_test_cases,
-};
-
-
-static int node_count;
-static struct klist_node *last_node;
-
-static void check_node(struct klist_node *node_ptr)
-{
-	node_count++;
-	last_node = node_ptr;
-}
-
-static void check_delete_node(struct klist_node *node_ptr)
-{
-	node_count--;
-	last_node = node_ptr;
-}
-
-static void klist_test_add_tail(struct kunit *test)
-{
-	struct klist_node a, b;
-	struct klist mylist;
-	struct klist_iter i;
-
-	node_count = 0;
-	klist_init(&mylist, &check_node, NULL);
-
-	klist_add_tail(&a, &mylist);
-	KUNIT_EXPECT_EQ(test, node_count, 1);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &a);
-
-	klist_add_tail(&b, &mylist);
-	KUNIT_EXPECT_EQ(test, node_count, 2);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &b);
-
-	/* should be [list] -> a -> b */
-	klist_iter_init(&mylist, &i);
-
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
-	KUNIT_EXPECT_NULL(test, klist_next(&i));
-
-	klist_iter_exit(&i);
-
-}
-
-static void klist_test_add_head(struct kunit *test)
-{
-	struct klist_node a, b;
-	struct klist mylist;
-	struct klist_iter i;
-
-	node_count = 0;
-	klist_init(&mylist, &check_node, NULL);
-
-	klist_add_head(&a, &mylist);
-	KUNIT_EXPECT_EQ(test, node_count, 1);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &a);
-
-	klist_add_head(&b, &mylist);
-	KUNIT_EXPECT_EQ(test, node_count, 2);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &b);
-
-	/* should be [list] -> b -> a */
-	klist_iter_init(&mylist, &i);
-
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
-	KUNIT_EXPECT_NULL(test, klist_next(&i));
-
-	klist_iter_exit(&i);
-
-}
-
-static void klist_test_add_behind(struct kunit *test)
-{
-	struct klist_node a, b, c, d;
-	struct klist mylist;
-	struct klist_iter i;
-
-	node_count = 0;
-	klist_init(&mylist, &check_node, NULL);
-
-	klist_add_head(&a, &mylist);
-	klist_add_head(&b, &mylist);
-
-	klist_add_behind(&c, &a);
-	KUNIT_EXPECT_EQ(test, node_count, 3);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
-
-	klist_add_behind(&d, &b);
-	KUNIT_EXPECT_EQ(test, node_count, 4);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
-
-	klist_iter_init(&mylist, &i);
-
-	/* should be [list] -> b -> d -> a -> c*/
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
-	KUNIT_EXPECT_NULL(test, klist_next(&i));
-
-	klist_iter_exit(&i);
-
-}
-
-static void klist_test_add_before(struct kunit *test)
-{
-	struct klist_node a, b, c, d;
-	struct klist mylist;
-	struct klist_iter i;
-
-	node_count = 0;
-	klist_init(&mylist, &check_node, NULL);
-
-	klist_add_head(&a, &mylist);
-	klist_add_head(&b, &mylist);
-	klist_add_before(&c, &a);
-	KUNIT_EXPECT_EQ(test, node_count, 3);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
-
-	klist_add_before(&d, &b);
-	KUNIT_EXPECT_EQ(test, node_count, 4);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
-
-	klist_iter_init(&mylist, &i);
-
-	/* should be [list] -> b -> d -> a -> c*/
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
-	KUNIT_EXPECT_NULL(test, klist_next(&i));
-
-	klist_iter_exit(&i);
-
-}
-
-/*
- * Verify that klist_del() delays the deletion of a node until there
- * are no other references to it
- */
-static void klist_test_del_refcount_greater_than_zero(struct kunit *test)
-{
-	struct klist_node a, b, c, d;
-	struct klist mylist;
-	struct klist_iter i;
-
-	node_count = 0;
-	klist_init(&mylist, &check_node, &check_delete_node);
-
-	/* Add nodes a,b,c,d to the list*/
-	klist_add_tail(&a, &mylist);
-	klist_add_tail(&b, &mylist);
-	klist_add_tail(&c, &mylist);
-	klist_add_tail(&d, &mylist);
-
-	klist_iter_init(&mylist, &i);
-
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
-	/* Advance the iterator to point to node c*/
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
-
-	/* Try to delete node c while there is a reference to it*/
-	klist_del(&c);
-
-	/*
-	 * Verify that node c is still attached to the list even after being
-	 * deleted. Since the iterator still points to c, the reference count is not
-	 * decreased to 0
-	 */
-	KUNIT_EXPECT_TRUE(test, klist_node_attached(&c));
-
-	/* Check that node c has not been removed yet*/
-	KUNIT_EXPECT_EQ(test, node_count, 4);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
-
-	klist_iter_exit(&i);
-
-	/*
-	 * Since the iterator is no longer pointing to node c, node c is removed
-	 * from the list
-	 */
-	KUNIT_EXPECT_EQ(test, node_count, 3);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
-
-}
-
-/*
- * Verify that klist_del() deletes a node immediately when there are no
- * other references to it.
- */
-static void klist_test_del_refcount_zero(struct kunit *test)
-{
-	struct klist_node a, b, c, d;
-	struct klist mylist;
-	struct klist_iter i;
-
-	node_count = 0;
-	klist_init(&mylist, &check_node, &check_delete_node);
-
-	/* Add nodes a,b,c,d to the list*/
-	klist_add_tail(&a, &mylist);
-	klist_add_tail(&b, &mylist);
-	klist_add_tail(&c, &mylist);
-	klist_add_tail(&d, &mylist);
-	/* Delete node c*/
-	klist_del(&c);
-
-	/* Check that node c is deleted from the list*/
-	KUNIT_EXPECT_EQ(test, node_count, 3);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
-
-	/* Should be [list] -> a -> b -> d*/
-	klist_iter_init(&mylist, &i);
-
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
-	KUNIT_EXPECT_NULL(test, klist_next(&i));
-
-	klist_iter_exit(&i);
-
-}
-
-static void klist_test_remove(struct kunit *test)
-{
-	/* This test doesn't check correctness under concurrent access */
-	struct klist_node a, b, c, d;
-	struct klist mylist;
-	struct klist_iter i;
-
-	node_count = 0;
-	klist_init(&mylist, &check_node, &check_delete_node);
-
-	/* Add nodes a,b,c,d to the list*/
-	klist_add_tail(&a, &mylist);
-	klist_add_tail(&b, &mylist);
-	klist_add_tail(&c, &mylist);
-	klist_add_tail(&d, &mylist);
-	/* Delete node c*/
-	klist_remove(&c);
-
-	/* Check the nodes in the list*/
-	KUNIT_EXPECT_EQ(test, node_count, 3);
-	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
-
-	/* should be [list] -> a -> b -> d*/
-	klist_iter_init(&mylist, &i);
-
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
-	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
-	KUNIT_EXPECT_NULL(test, klist_next(&i));
-
-	klist_iter_exit(&i);
-
-}
-
-static void klist_test_node_attached(struct kunit *test)
-{
-	struct klist_node a = {};
-	struct klist mylist;
-
-	klist_init(&mylist, NULL, NULL);
-
-	KUNIT_EXPECT_FALSE(test, klist_node_attached(&a));
-	klist_add_head(&a, &mylist);
-	KUNIT_EXPECT_TRUE(test, klist_node_attached(&a));
-	klist_del(&a);
-	KUNIT_EXPECT_FALSE(test, klist_node_attached(&a));
-
-}
-
-static struct kunit_case klist_test_cases[] = {
-	KUNIT_CASE(klist_test_add_tail),
-	KUNIT_CASE(klist_test_add_head),
-	KUNIT_CASE(klist_test_add_behind),
-	KUNIT_CASE(klist_test_add_before),
-	KUNIT_CASE(klist_test_del_refcount_greater_than_zero),
-	KUNIT_CASE(klist_test_del_refcount_zero),
-	KUNIT_CASE(klist_test_remove),
-	KUNIT_CASE(klist_test_node_attached),
-	{},
-};
-
-static struct kunit_suite klist_test_module = {
-	.name = "klist",
-	.test_cases = klist_test_cases,
-};
-
-kunit_test_suites(&list_test_module, &hlist_test_module, &klist_test_module);
-
-MODULE_DESCRIPTION("KUnit test for the Kernel Linked-list structures");
-MODULE_LICENSE("GPL v2");
--- a/lib/Makefile~lib-move-kunit-tests-into-tests-subdirectory
+++ a/lib/Makefile
@@ -51,9 +51,7 @@ obj-y += bcd.o sort.o parser.o debug_loc
 	 percpu-refcount.o rhashtable.o base64.o \
 	 once.o refcount.o rcuref.o usercopy.o errseq.o bucket_locks.o \
 	 generic-radix-tree.o bitmap-str.o
-obj-$(CONFIG_STRING_KUNIT_TEST) += string_kunit.o
 obj-y += string_helpers.o
-obj-$(CONFIG_STRING_HELPERS_KUNIT_TEST) += string_helpers_kunit.o
 obj-y += hexdump.o
 obj-$(CONFIG_TEST_HEXDUMP) += test_hexdump.o
 obj-y += kstrtox.o
@@ -64,22 +62,17 @@ obj-$(CONFIG_TEST_DHRY) += test_dhry.o
 obj-$(CONFIG_TEST_FIRMWARE) += test_firmware.o
 obj-$(CONFIG_TEST_BITOPS) += test_bitops.o
 CFLAGS_test_bitops.o += -Werror
-obj-$(CONFIG_CPUMASK_KUNIT_TEST) += cpumask_kunit.o
 obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o
-obj-$(CONFIG_TEST_IOV_ITER) += kunit_iov_iter.o
-obj-$(CONFIG_HASH_KUNIT_TEST) += test_hash.o
 obj-$(CONFIG_TEST_IDA) += test_ida.o
 obj-$(CONFIG_TEST_UBSAN) += test_ubsan.o
 CFLAGS_test_ubsan.o += $(call cc-disable-warning, vla)
 CFLAGS_test_ubsan.o += $(call cc-disable-warning, unused-but-set-variable)
 UBSAN_SANITIZE_test_ubsan.o := y
 obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o
-obj-$(CONFIG_TEST_LIST_SORT) += test_list_sort.o
 obj-$(CONFIG_TEST_MIN_HEAP) += test_min_heap.o
 obj-$(CONFIG_TEST_LKM) += test_module.o
 obj-$(CONFIG_TEST_VMALLOC) += test_vmalloc.o
 obj-$(CONFIG_TEST_RHASHTABLE) += test_rhashtable.o
-obj-$(CONFIG_TEST_SORT) += test_sort.o
 obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_keys.o
 obj-$(CONFIG_TEST_STATIC_KEYS) += test_static_key_base.o
 obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o
@@ -105,10 +98,7 @@ obj-$(CONFIG_TEST_MEMINIT) += test_memin
 obj-$(CONFIG_TEST_LOCKUP) += test_lockup.o
 obj-$(CONFIG_TEST_HMM) += test_hmm.o
 obj-$(CONFIG_TEST_FREE_PAGES) += test_free_pages.o
-obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o
 obj-$(CONFIG_TEST_REF_TRACKER) += test_ref_tracker.o
-CFLAGS_test_fprobe.o += $(CC_FLAGS_FTRACE)
-obj-$(CONFIG_FPROBE_SANITY_TEST) += test_fprobe.o
 obj-$(CONFIG_TEST_OBJPOOL) += test_objpool.o
 
 obj-$(CONFIG_TEST_FPU) += test_fpu.o
@@ -130,7 +120,7 @@ endif
 obj-$(CONFIG_DEBUG_INFO_REDUCED) += debug_info.o
 CFLAGS_debug_info.o += $(call cc-option, -femit-struct-debug-detailed=any)
 
-obj-y += math/ crypto/
+obj-y += math/ crypto/ tests/
 
 obj-$(CONFIG_GENERIC_IOMAP) += iomap.o
 obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o
@@ -367,31 +357,6 @@ obj-$(CONFIG_OBJAGG) += objagg.o
 # pldmfw library
 obj-$(CONFIG_PLDMFW) += pldmfw/
 
-# KUnit tests
-CFLAGS_bitfield_kunit.o := $(DISABLE_STRUCTLEAK_PLUGIN)
-obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o
-obj-$(CONFIG_CHECKSUM_KUNIT) += checksum_kunit.o
-obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
-obj-$(CONFIG_HASHTABLE_KUNIT_TEST) += hashtable_test.o
-obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o
-obj-$(CONFIG_BITS_TEST) += test_bits.o
-obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o
-obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o
-obj-$(CONFIG_MEMCPY_KUNIT_TEST) += memcpy_kunit.o
-obj-$(CONFIG_IS_SIGNED_TYPE_KUNIT_TEST) += is_signed_type_kunit.o
-CFLAGS_overflow_kunit.o = $(call cc-disable-warning, tautological-constant-out-of-range-compare)
-obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o
-CFLAGS_stackinit_kunit.o += $(call cc-disable-warning, switch-unreachable)
-obj-$(CONFIG_STACKINIT_KUNIT_TEST) += stackinit_kunit.o
-CFLAGS_fortify_kunit.o += $(call cc-disable-warning, unsequenced)
-CFLAGS_fortify_kunit.o += $(call cc-disable-warning, stringop-overread)
-CFLAGS_fortify_kunit.o += $(call cc-disable-warning, stringop-truncation)
-CFLAGS_fortify_kunit.o += $(DISABLE_STRUCTLEAK_PLUGIN)
-obj-$(CONFIG_FORTIFY_KUNIT_TEST) += fortify_kunit.o
-obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o
-obj-$(CONFIG_USERCOPY_KUNIT_TEST) += usercopy_kunit.o
-obj-$(CONFIG_CRC16_KUNIT_TEST) += crc16_kunit.o
-
 obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
 
 obj-$(CONFIG_FIRMWARE_TABLE) += fw_table.o
diff --git a/lib/memcpy_kunit.c a/lib/memcpy_kunit.c
deleted file mode 100644
--- a/lib/memcpy_kunit.c
+++ /dev/null
@@ -1,514 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Test cases for memcpy(), memmove(), and memset().
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <kunit/test.h>
-#include <linux/device.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/overflow.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/vmalloc.h>
-
-struct some_bytes {
-	union {
-		u8 data[32];
-		struct {
-			u32 one;
-			u16 two;
-			u8  three;
-			/* 1 byte hole */
-			u32 four[4];
-		};
-	};
-};
-
-#define check(instance, v) do {	\
-	BUILD_BUG_ON(sizeof(instance.data) != 32);	\
-	for (size_t i = 0; i < sizeof(instance.data); i++) {	\
-		KUNIT_ASSERT_EQ_MSG(test, instance.data[i], v, \
-			"line %d: '%s' not initialized to 0x%02x @ %zu (saw 0x%02x)\n", \
-			__LINE__, #instance, v, i, instance.data[i]);	\
-	}	\
-} while (0)
-
-#define compare(name, one, two) do { \
-	BUILD_BUG_ON(sizeof(one) != sizeof(two)); \
-	for (size_t i = 0; i < sizeof(one); i++) {	\
-		KUNIT_EXPECT_EQ_MSG(test, one.data[i], two.data[i], \
-			"line %d: %s.data[%zu] (0x%02x) != %s.data[%zu] (0x%02x)\n", \
-			__LINE__, #one, i, one.data[i], #two, i, two.data[i]); \
-	}	\
-	kunit_info(test, "ok: " TEST_OP "() " name "\n");	\
-} while (0)
-
-static void memcpy_test(struct kunit *test)
-{
-#define TEST_OP "memcpy"
-	struct some_bytes control = {
-		.data = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-			},
-	};
-	struct some_bytes zero = { };
-	struct some_bytes middle = {
-		.data = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-			  0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
-			  0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
-			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-			},
-	};
-	struct some_bytes three = {
-		.data = { 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-			  0x20, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
-			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-			},
-	};
-	struct some_bytes dest = { };
-	int count;
-	u8 *ptr;
-
-	/* Verify static initializers. */
-	check(control, 0x20);
-	check(zero, 0);
-	compare("static initializers", dest, zero);
-
-	/* Verify assignment. */
-	dest = control;
-	compare("direct assignment", dest, control);
-
-	/* Verify complete overwrite. */
-	memcpy(dest.data, zero.data, sizeof(dest.data));
-	compare("complete overwrite", dest, zero);
-
-	/* Verify middle overwrite. */
-	dest = control;
-	memcpy(dest.data + 12, zero.data, 7);
-	compare("middle overwrite", dest, middle);
-
-	/* Verify argument side-effects aren't repeated. */
-	dest = control;
-	ptr = dest.data;
-	count = 1;
-	memcpy(ptr++, zero.data, count++);
-	ptr += 8;
-	memcpy(ptr++, zero.data, count++);
-	compare("argument side-effects", dest, three);
-#undef TEST_OP
-}
-
-static unsigned char larger_array [2048];
-
-static void memmove_test(struct kunit *test)
-{
-#define TEST_OP "memmove"
-	struct some_bytes control = {
-		.data = { 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			},
-	};
-	struct some_bytes zero = { };
-	struct some_bytes middle = {
-		.data = { 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			  0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00,
-			  0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x99,
-			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			},
-	};
-	struct some_bytes five = {
-		.data = { 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			  0x99, 0x99, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99,
-			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			},
-	};
-	struct some_bytes overlap = {
-		.data = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-			  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			},
-	};
-	struct some_bytes overlap_expected = {
-		.data = { 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x07,
-			  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
-			},
-	};
-	struct some_bytes dest = { };
-	int count;
-	u8 *ptr;
-
-	/* Verify static initializers. */
-	check(control, 0x99);
-	check(zero, 0);
-	compare("static initializers", zero, dest);
-
-	/* Verify assignment. */
-	dest = control;
-	compare("direct assignment", dest, control);
-
-	/* Verify complete overwrite. */
-	memmove(dest.data, zero.data, sizeof(dest.data));
-	compare("complete overwrite", dest, zero);
-
-	/* Verify middle overwrite. */
-	dest = control;
-	memmove(dest.data + 12, zero.data, 7);
-	compare("middle overwrite", dest, middle);
-
-	/* Verify argument side-effects aren't repeated. */
-	dest = control;
-	ptr = dest.data;
-	count = 2;
-	memmove(ptr++, zero.data, count++);
-	ptr += 9;
-	memmove(ptr++, zero.data, count++);
-	compare("argument side-effects", dest, five);
-
-	/* Verify overlapping overwrite is correct. */
-	ptr = &overlap.data[2];
-	memmove(ptr, overlap.data, 5);
-	compare("overlapping write", overlap, overlap_expected);
-
-	/* Verify larger overlapping moves. */
-	larger_array[256] = 0xAAu;
-	/*
-	 * Test a backwards overlapping memmove first. 256 and 1024 are
-	 * important for i386 to use rep movsl.
-	 */
-	memmove(larger_array, larger_array + 256, 1024);
-	KUNIT_ASSERT_EQ(test, larger_array[0], 0xAAu);
-	KUNIT_ASSERT_EQ(test, larger_array[256], 0x00);
-	KUNIT_ASSERT_NULL(test,
-		memchr(larger_array + 1, 0xaa, ARRAY_SIZE(larger_array) - 1));
-	/* Test a forwards overlapping memmove. */
-	larger_array[0] = 0xBBu;
-	memmove(larger_array + 256, larger_array, 1024);
-	KUNIT_ASSERT_EQ(test, larger_array[0], 0xBBu);
-	KUNIT_ASSERT_EQ(test, larger_array[256], 0xBBu);
-	KUNIT_ASSERT_NULL(test, memchr(larger_array + 1, 0xBBu, 256 - 1));
-	KUNIT_ASSERT_NULL(test,
-		memchr(larger_array + 257, 0xBBu, ARRAY_SIZE(larger_array) - 257));
-#undef TEST_OP
-}
-
-static void memset_test(struct kunit *test)
-{
-#define TEST_OP "memset"
-	struct some_bytes control = {
-		.data = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-			},
-	};
-	struct some_bytes complete = {
-		.data = { 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-			},
-	};
-	struct some_bytes middle = {
-		.data = { 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
-			  0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
-			  0x31, 0x31, 0x31, 0x31, 0x30, 0x30, 0x30, 0x30,
-			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-			},
-	};
-	struct some_bytes three = {
-		.data = { 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-			  0x30, 0x61, 0x61, 0x30, 0x30, 0x30, 0x30, 0x30,
-			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-			},
-	};
-	struct some_bytes after = {
-		.data = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x72,
-			  0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
-			  0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
-			  0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
-			},
-	};
-	struct some_bytes startat = {
-		.data = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-			  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-			  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-			  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
-			},
-	};
-	struct some_bytes dest = { };
-	int count, value;
-	u8 *ptr;
-
-	/* Verify static initializers. */
-	check(control, 0x30);
-	check(dest, 0);
-
-	/* Verify assignment. */
-	dest = control;
-	compare("direct assignment", dest, control);
-
-	/* Verify complete overwrite. */
-	memset(dest.data, 0xff, sizeof(dest.data));
-	compare("complete overwrite", dest, complete);
-
-	/* Verify middle overwrite. */
-	dest = control;
-	memset(dest.data + 4, 0x31, 16);
-	compare("middle overwrite", dest, middle);
-
-	/* Verify argument side-effects aren't repeated. */
-	dest = control;
-	ptr = dest.data;
-	value = 0x60;
-	count = 1;
-	memset(ptr++, value++, count++);
-	ptr += 8;
-	memset(ptr++, value++, count++);
-	compare("argument side-effects", dest, three);
-
-	/* Verify memset_after() */
-	dest = control;
-	memset_after(&dest, 0x72, three);
-	compare("memset_after()", dest, after);
-
-	/* Verify memset_startat() */
-	dest = control;
-	memset_startat(&dest, 0x79, four);
-	compare("memset_startat()", dest, startat);
-#undef TEST_OP
-}
-
-static u8 large_src[1024];
-static u8 large_dst[2048];
-static const u8 large_zero[2048];
-
-static void set_random_nonzero(struct kunit *test, u8 *byte)
-{
-	int failed_rng = 0;
-
-	while (*byte == 0) {
-		get_random_bytes(byte, 1);
-		KUNIT_ASSERT_LT_MSG(test, failed_rng++, 100,
-				    "Is the RNG broken?");
-	}
-}
-
-static void init_large(struct kunit *test)
-{
-	/* Get many bit patterns. */
-	get_random_bytes(large_src, ARRAY_SIZE(large_src));
-
-	/* Make sure we have non-zero edges. */
-	set_random_nonzero(test, &large_src[0]);
-	set_random_nonzero(test, &large_src[ARRAY_SIZE(large_src) - 1]);
-
-	/* Explicitly zero the entire destination. */
-	memset(large_dst, 0, ARRAY_SIZE(large_dst));
-}
-
-/*
- * Instead of an indirect function call for "copy" or a giant macro,
- * use a bool to pick memcpy or memmove.
- */
-static void copy_large_test(struct kunit *test, bool use_memmove)
-{
-	init_large(test);
-
-	/* Copy a growing number of non-overlapping bytes ... */
-	for (int bytes = 1; bytes <= ARRAY_SIZE(large_src); bytes++) {
-		/* Over a shifting destination window ... */
-		for (int offset = 0; offset < ARRAY_SIZE(large_src); offset++) {
-			int right_zero_pos = offset + bytes;
-			int right_zero_size = ARRAY_SIZE(large_dst) - right_zero_pos;
-
-			/* Copy! */
-			if (use_memmove)
-				memmove(large_dst + offset, large_src, bytes);
-			else
-				memcpy(large_dst + offset, large_src, bytes);
-
-			/* Did we touch anything before the copy area? */
-			KUNIT_ASSERT_EQ_MSG(test,
-				memcmp(large_dst, large_zero, offset), 0,
-				"with size %d at offset %d", bytes, offset);
-			/* Did we touch anything after the copy area? */
-			KUNIT_ASSERT_EQ_MSG(test,
-				memcmp(&large_dst[right_zero_pos], large_zero, right_zero_size), 0,
-				"with size %d at offset %d", bytes, offset);
-
-			/* Are we byte-for-byte exact across the copy? */
-			KUNIT_ASSERT_EQ_MSG(test,
-				memcmp(large_dst + offset, large_src, bytes), 0,
-				"with size %d at offset %d", bytes, offset);
-
-			/* Zero out what we copied for the next cycle. */
-			memset(large_dst + offset, 0, bytes);
-		}
-		/* Avoid stall warnings if this loop gets slow. */
-		cond_resched();
-	}
-}
-
-static void memcpy_large_test(struct kunit *test)
-{
-	copy_large_test(test, false);
-}
-
-static void memmove_large_test(struct kunit *test)
-{
-	copy_large_test(test, true);
-}
-
-/*
- * On the assumption that boundary conditions are going to be the most
- * sensitive, instead of taking a full step (inc) each iteration,
- * take single index steps for at least the first "inc"-many indexes
- * from the "start" and at least the last "inc"-many indexes before
- * the "end". When in the middle, take full "inc"-wide steps. For
- * example, calling next_step(idx, 1, 15, 3) with idx starting at 0
- * would see the following pattern: 1 2 3 4 7 10 11 12 13 14 15.
- */
-static int next_step(int idx, int start, int end, int inc)
-{
-	start += inc;
-	end -= inc;
-
-	if (idx < start || idx + inc > end)
-		inc = 1;
-	return idx + inc;
-}
-
-static void inner_loop(struct kunit *test, int bytes, int d_off, int s_off)
-{
-	int left_zero_pos, left_zero_size;
-	int right_zero_pos, right_zero_size;
-	int src_pos, src_orig_pos, src_size;
-	int pos;
-
-	/* Place the source in the destination buffer. */
-	memcpy(&large_dst[s_off], large_src, bytes);
-
-	/* Copy to destination offset. */
-	memmove(&large_dst[d_off], &large_dst[s_off], bytes);
-
-	/* Make sure destination entirely matches. */
-	KUNIT_ASSERT_EQ_MSG(test, memcmp(&large_dst[d_off], large_src, bytes), 0,
-		"with size %d at src offset %d and dest offset %d",
-		bytes, s_off, d_off);
-
-	/* Calculate the expected zero spans. */
-	if (s_off < d_off) {
-		left_zero_pos = 0;
-		left_zero_size = s_off;
-
-		right_zero_pos = d_off + bytes;
-		right_zero_size = ARRAY_SIZE(large_dst) - right_zero_pos;
-
-		src_pos = s_off;
-		src_orig_pos = 0;
-		src_size = d_off - s_off;
-	} else {
-		left_zero_pos = 0;
-		left_zero_size = d_off;
-
-		right_zero_pos = s_off + bytes;
-		right_zero_size = ARRAY_SIZE(large_dst) - right_zero_pos;
-
-		src_pos = d_off + bytes;
-		src_orig_pos = src_pos - s_off;
-		src_size = right_zero_pos - src_pos;
-	}
-
-	/* Check non-overlapping source is unchanged.*/
-	KUNIT_ASSERT_EQ_MSG(test,
-		memcmp(&large_dst[src_pos], &large_src[src_orig_pos], src_size), 0,
-		"with size %d at src offset %d and dest offset %d",
-		bytes, s_off, d_off);
-
-	/* Check leading buffer contents are zero. */
-	KUNIT_ASSERT_EQ_MSG(test,
-		memcmp(&large_dst[left_zero_pos], large_zero, left_zero_size), 0,
-		"with size %d at src offset %d and dest offset %d",
-		bytes, s_off, d_off);
-	/* Check trailing buffer contents are zero. */
-	KUNIT_ASSERT_EQ_MSG(test,
-		memcmp(&large_dst[right_zero_pos], large_zero, right_zero_size), 0,
-		"with size %d at src offset %d and dest offset %d",
-		bytes, s_off, d_off);
-
-	/* Zero out everything not already zeroed.*/
-	pos = left_zero_pos + left_zero_size;
-	memset(&large_dst[pos], 0, right_zero_pos - pos);
-}
-
-static void memmove_overlap_test(struct kunit *test)
-{
-	/*
-	 * Running all possible offset and overlap combinations takes a
-	 * very long time. Instead, only check up to 128 bytes offset
-	 * into the destination buffer (which should result in crossing
-	 * cachelines), with a step size of 1 through 7 to try to skip some
-	 * redundancy.
-	 */
-	static const int offset_max = 128; /* less than ARRAY_SIZE(large_src); */
-	static const int bytes_step = 7;
-	static const int window_step = 7;
-
-	static const int bytes_start = 1;
-	static const int bytes_end = ARRAY_SIZE(large_src) + 1;
-
-	init_large(test);
-
-	/* Copy a growing number of overlapping bytes ... */
-	for (int bytes = bytes_start; bytes < bytes_end;
-	     bytes = next_step(bytes, bytes_start, bytes_end, bytes_step)) {
-
-		/* Over a shifting destination window ... */
-		for (int d_off = 0; d_off < offset_max; d_off++) {
-			int s_start = max(d_off - bytes, 0);
-			int s_end = min_t(int, d_off + bytes, ARRAY_SIZE(large_src));
-
-			/* Over a shifting source window ... */
-			for (int s_off = s_start; s_off < s_end;
-			     s_off = next_step(s_off, s_start, s_end, window_step))
-				inner_loop(test, bytes, d_off, s_off);
-
-			/* Avoid stall warnings. */
-			cond_resched();
-		}
-	}
-}
-
-static struct kunit_case memcpy_test_cases[] = {
-	KUNIT_CASE(memset_test),
-	KUNIT_CASE(memcpy_test),
-	KUNIT_CASE_SLOW(memcpy_large_test),
-	KUNIT_CASE_SLOW(memmove_test),
-	KUNIT_CASE_SLOW(memmove_large_test),
-	KUNIT_CASE_SLOW(memmove_overlap_test),
-	{}
-};
-
-static struct kunit_suite memcpy_test_suite = {
-	.name = "memcpy",
-	.test_cases = memcpy_test_cases,
-};
-
-kunit_test_suite(memcpy_test_suite);
-
-MODULE_DESCRIPTION("test cases for memcpy(), memmove(), and memset()");
-MODULE_LICENSE("GPL");
diff --git a/lib/overflow_kunit.c a/lib/overflow_kunit.c
deleted file mode 100644
--- a/lib/overflow_kunit.c
+++ /dev/null
@@ -1,1240 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR MIT
-/*
- * Test cases for arithmetic overflow checks. See:
- * "Running tests with kunit_tool" at Documentation/dev-tools/kunit/start.rst
- *	./tools/testing/kunit/kunit.py run overflow [--raw_output]
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <kunit/device.h>
-#include <kunit/test.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/overflow.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/vmalloc.h>
-
-#define SKIP(cond, reason)		do {			\
-	if (cond) {						\
-		kunit_skip(test, reason);			\
-		return;						\
-	}							\
-} while (0)
-
-/*
- * Clang 11 and earlier generate unwanted libcalls for signed output
- * on unsigned input.
- */
-#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 11
-# define SKIP_SIGN_MISMATCH(t)	SKIP(t, "Clang 11 unwanted libcalls")
-#else
-# define SKIP_SIGN_MISMATCH(t)	do { } while (0)
-#endif
-
-/*
- * Clang 13 and earlier generate unwanted libcalls for 64-bit tests on
- * 32-bit hosts.
- */
-#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 13 &&	\
-    BITS_PER_LONG != 64
-# define SKIP_64_ON_32(t)	SKIP(t, "Clang 13 unwanted libcalls")
-#else
-# define SKIP_64_ON_32(t)	do { } while (0)
-#endif
-
-#define DEFINE_TEST_ARRAY_TYPED(t1, t2, t)			\
-	static const struct test_ ## t1 ## _ ## t2 ## __ ## t {	\
-		t1 a;						\
-		t2 b;						\
-		t sum, diff, prod;				\
-		bool s_of, d_of, p_of;				\
-	} t1 ## _ ## t2 ## __ ## t ## _tests[]
-
-#define DEFINE_TEST_ARRAY(t)	DEFINE_TEST_ARRAY_TYPED(t, t, t)
-
-DEFINE_TEST_ARRAY(u8) = {
-	{0, 0, 0, 0, 0, false, false, false},
-	{1, 1, 2, 0, 1, false, false, false},
-	{0, 1, 1, U8_MAX, 0, false, true, false},
-	{1, 0, 1, 1, 0, false, false, false},
-	{0, U8_MAX, U8_MAX, 1, 0, false, true, false},
-	{U8_MAX, 0, U8_MAX, U8_MAX, 0, false, false, false},
-	{1, U8_MAX, 0, 2, U8_MAX, true, true, false},
-	{U8_MAX, 1, 0, U8_MAX-1, U8_MAX, true, false, false},
-	{U8_MAX, U8_MAX, U8_MAX-1, 0, 1, true, false, true},
-
-	{U8_MAX, U8_MAX-1, U8_MAX-2, 1, 2, true, false, true},
-	{U8_MAX-1, U8_MAX, U8_MAX-2, U8_MAX, 2, true, true, true},
-
-	{1U << 3, 1U << 3, 1U << 4, 0, 1U << 6, false, false, false},
-	{1U << 4, 1U << 4, 1U << 5, 0, 0, false, false, true},
-	{1U << 4, 1U << 3, 3*(1U << 3), 1U << 3, 1U << 7, false, false, false},
-	{1U << 7, 1U << 7, 0, 0, 0, true, false, true},
-
-	{48, 32, 80, 16, 0, false, false, true},
-	{128, 128, 0, 0, 0, true, false, true},
-	{123, 234, 101, 145, 110, true, true, true},
-};
-DEFINE_TEST_ARRAY(u16) = {
-	{0, 0, 0, 0, 0, false, false, false},
-	{1, 1, 2, 0, 1, false, false, false},
-	{0, 1, 1, U16_MAX, 0, false, true, false},
-	{1, 0, 1, 1, 0, false, false, false},
-	{0, U16_MAX, U16_MAX, 1, 0, false, true, false},
-	{U16_MAX, 0, U16_MAX, U16_MAX, 0, false, false, false},
-	{1, U16_MAX, 0, 2, U16_MAX, true, true, false},
-	{U16_MAX, 1, 0, U16_MAX-1, U16_MAX, true, false, false},
-	{U16_MAX, U16_MAX, U16_MAX-1, 0, 1, true, false, true},
-
-	{U16_MAX, U16_MAX-1, U16_MAX-2, 1, 2, true, false, true},
-	{U16_MAX-1, U16_MAX, U16_MAX-2, U16_MAX, 2, true, true, true},
-
-	{1U << 7, 1U << 7, 1U << 8, 0, 1U << 14, false, false, false},
-	{1U << 8, 1U << 8, 1U << 9, 0, 0, false, false, true},
-	{1U << 8, 1U << 7, 3*(1U << 7), 1U << 7, 1U << 15, false, false, false},
-	{1U << 15, 1U << 15, 0, 0, 0, true, false, true},
-
-	{123, 234, 357, 65425, 28782, false, true, false},
-	{1234, 2345, 3579, 64425, 10146, false, true, true},
-};
-DEFINE_TEST_ARRAY(u32) = {
-	{0, 0, 0, 0, 0, false, false, false},
-	{1, 1, 2, 0, 1, false, false, false},
-	{0, 1, 1, U32_MAX, 0, false, true, false},
-	{1, 0, 1, 1, 0, false, false, false},
-	{0, U32_MAX, U32_MAX, 1, 0, false, true, false},
-	{U32_MAX, 0, U32_MAX, U32_MAX, 0, false, false, false},
-	{1, U32_MAX, 0, 2, U32_MAX, true, true, false},
-	{U32_MAX, 1, 0, U32_MAX-1, U32_MAX, true, false, false},
-	{U32_MAX, U32_MAX, U32_MAX-1, 0, 1, true, false, true},
-
-	{U32_MAX, U32_MAX-1, U32_MAX-2, 1, 2, true, false, true},
-	{U32_MAX-1, U32_MAX, U32_MAX-2, U32_MAX, 2, true, true, true},
-
-	{1U << 15, 1U << 15, 1U << 16, 0, 1U << 30, false, false, false},
-	{1U << 16, 1U << 16, 1U << 17, 0, 0, false, false, true},
-	{1U << 16, 1U << 15, 3*(1U << 15), 1U << 15, 1U << 31, false, false, false},
-	{1U << 31, 1U << 31, 0, 0, 0, true, false, true},
-
-	{-2U, 1U, -1U, -3U, -2U, false, false, false},
-	{-4U, 5U, 1U, -9U, -20U, true, false, true},
-};
-
-DEFINE_TEST_ARRAY(u64) = {
-	{0, 0, 0, 0, 0, false, false, false},
-	{1, 1, 2, 0, 1, false, false, false},
-	{0, 1, 1, U64_MAX, 0, false, true, false},
-	{1, 0, 1, 1, 0, false, false, false},
-	{0, U64_MAX, U64_MAX, 1, 0, false, true, false},
-	{U64_MAX, 0, U64_MAX, U64_MAX, 0, false, false, false},
-	{1, U64_MAX, 0, 2, U64_MAX, true, true, false},
-	{U64_MAX, 1, 0, U64_MAX-1, U64_MAX, true, false, false},
-	{U64_MAX, U64_MAX, U64_MAX-1, 0, 1, true, false, true},
-
-	{U64_MAX, U64_MAX-1, U64_MAX-2, 1, 2, true, false, true},
-	{U64_MAX-1, U64_MAX, U64_MAX-2, U64_MAX, 2, true, true, true},
-
-	{1ULL << 31, 1ULL << 31, 1ULL << 32, 0, 1ULL << 62, false, false, false},
-	{1ULL << 32, 1ULL << 32, 1ULL << 33, 0, 0, false, false, true},
-	{1ULL << 32, 1ULL << 31, 3*(1ULL << 31), 1ULL << 31, 1ULL << 63, false, false, false},
-	{1ULL << 63, 1ULL << 63, 0, 0, 0, true, false, true},
-	{1000000000ULL /* 10^9 */, 10000000000ULL /* 10^10 */,
-	 11000000000ULL, 18446744064709551616ULL, 10000000000000000000ULL,
-	 false, true, false},
-	{-15ULL, 10ULL, -5ULL, -25ULL, -150ULL, false, false, true},
-};
-
-DEFINE_TEST_ARRAY(s8) = {
-	{0, 0, 0, 0, 0, false, false, false},
-
-	{0, S8_MAX, S8_MAX, -S8_MAX, 0, false, false, false},
-	{S8_MAX, 0, S8_MAX, S8_MAX, 0, false, false, false},
-	{0, S8_MIN, S8_MIN, S8_MIN, 0, false, true, false},
-	{S8_MIN, 0, S8_MIN, S8_MIN, 0, false, false, false},
-
-	{-1, S8_MIN, S8_MAX, S8_MAX, S8_MIN, true, false, true},
-	{S8_MIN, -1, S8_MAX, -S8_MAX, S8_MIN, true, false, true},
-	{-1, S8_MAX, S8_MAX-1, S8_MIN, -S8_MAX, false, false, false},
-	{S8_MAX, -1, S8_MAX-1, S8_MIN, -S8_MAX, false, true, false},
-	{-1, -S8_MAX, S8_MIN, S8_MAX-1, S8_MAX, false, false, false},
-	{-S8_MAX, -1, S8_MIN, S8_MIN+2, S8_MAX, false, false, false},
-
-	{1, S8_MIN, -S8_MAX, -S8_MAX, S8_MIN, false, true, false},
-	{S8_MIN, 1, -S8_MAX, S8_MAX, S8_MIN, false, true, false},
-	{1, S8_MAX, S8_MIN, S8_MIN+2, S8_MAX, true, false, false},
-	{S8_MAX, 1, S8_MIN, S8_MAX-1, S8_MAX, true, false, false},
-
-	{S8_MIN, S8_MIN, 0, 0, 0, true, false, true},
-	{S8_MAX, S8_MAX, -2, 0, 1, true, false, true},
-
-	{-4, -32, -36, 28, -128, false, false, true},
-	{-4, 32, 28, -36, -128, false, false, false},
-};
-
-DEFINE_TEST_ARRAY(s16) = {
-	{0, 0, 0, 0, 0, false, false, false},
-
-	{0, S16_MAX, S16_MAX, -S16_MAX, 0, false, false, false},
-	{S16_MAX, 0, S16_MAX, S16_MAX, 0, false, false, false},
-	{0, S16_MIN, S16_MIN, S16_MIN, 0, false, true, false},
-	{S16_MIN, 0, S16_MIN, S16_MIN, 0, false, false, false},
-
-	{-1, S16_MIN, S16_MAX, S16_MAX, S16_MIN, true, false, true},
-	{S16_MIN, -1, S16_MAX, -S16_MAX, S16_MIN, true, false, true},
-	{-1, S16_MAX, S16_MAX-1, S16_MIN, -S16_MAX, false, false, false},
-	{S16_MAX, -1, S16_MAX-1, S16_MIN, -S16_MAX, false, true, false},
-	{-1, -S16_MAX, S16_MIN, S16_MAX-1, S16_MAX, false, false, false},
-	{-S16_MAX, -1, S16_MIN, S16_MIN+2, S16_MAX, false, false, false},
-
-	{1, S16_MIN, -S16_MAX, -S16_MAX, S16_MIN, false, true, false},
-	{S16_MIN, 1, -S16_MAX, S16_MAX, S16_MIN, false, true, false},
-	{1, S16_MAX, S16_MIN, S16_MIN+2, S16_MAX, true, false, false},
-	{S16_MAX, 1, S16_MIN, S16_MAX-1, S16_MAX, true, false, false},
-
-	{S16_MIN, S16_MIN, 0, 0, 0, true, false, true},
-	{S16_MAX, S16_MAX, -2, 0, 1, true, false, true},
-};
-DEFINE_TEST_ARRAY(s32) = {
-	{0, 0, 0, 0, 0, false, false, false},
-
-	{0, S32_MAX, S32_MAX, -S32_MAX, 0, false, false, false},
-	{S32_MAX, 0, S32_MAX, S32_MAX, 0, false, false, false},
-	{0, S32_MIN, S32_MIN, S32_MIN, 0, false, true, false},
-	{S32_MIN, 0, S32_MIN, S32_MIN, 0, false, false, false},
-
-	{-1, S32_MIN, S32_MAX, S32_MAX, S32_MIN, true, false, true},
-	{S32_MIN, -1, S32_MAX, -S32_MAX, S32_MIN, true, false, true},
-	{-1, S32_MAX, S32_MAX-1, S32_MIN, -S32_MAX, false, false, false},
-	{S32_MAX, -1, S32_MAX-1, S32_MIN, -S32_MAX, false, true, false},
-	{-1, -S32_MAX, S32_MIN, S32_MAX-1, S32_MAX, false, false, false},
-	{-S32_MAX, -1, S32_MIN, S32_MIN+2, S32_MAX, false, false, false},
-
-	{1, S32_MIN, -S32_MAX, -S32_MAX, S32_MIN, false, true, false},
-	{S32_MIN, 1, -S32_MAX, S32_MAX, S32_MIN, false, true, false},
-	{1, S32_MAX, S32_MIN, S32_MIN+2, S32_MAX, true, false, false},
-	{S32_MAX, 1, S32_MIN, S32_MAX-1, S32_MAX, true, false, false},
-
-	{S32_MIN, S32_MIN, 0, 0, 0, true, false, true},
-	{S32_MAX, S32_MAX, -2, 0, 1, true, false, true},
-};
-
-DEFINE_TEST_ARRAY(s64) = {
-	{0, 0, 0, 0, 0, false, false, false},
-
-	{0, S64_MAX, S64_MAX, -S64_MAX, 0, false, false, false},
-	{S64_MAX, 0, S64_MAX, S64_MAX, 0, false, false, false},
-	{0, S64_MIN, S64_MIN, S64_MIN, 0, false, true, false},
-	{S64_MIN, 0, S64_MIN, S64_MIN, 0, false, false, false},
-
-	{-1, S64_MIN, S64_MAX, S64_MAX, S64_MIN, true, false, true},
-	{S64_MIN, -1, S64_MAX, -S64_MAX, S64_MIN, true, false, true},
-	{-1, S64_MAX, S64_MAX-1, S64_MIN, -S64_MAX, false, false, false},
-	{S64_MAX, -1, S64_MAX-1, S64_MIN, -S64_MAX, false, true, false},
-	{-1, -S64_MAX, S64_MIN, S64_MAX-1, S64_MAX, false, false, false},
-	{-S64_MAX, -1, S64_MIN, S64_MIN+2, S64_MAX, false, false, false},
-
-	{1, S64_MIN, -S64_MAX, -S64_MAX, S64_MIN, false, true, false},
-	{S64_MIN, 1, -S64_MAX, S64_MAX, S64_MIN, false, true, false},
-	{1, S64_MAX, S64_MIN, S64_MIN+2, S64_MAX, true, false, false},
-	{S64_MAX, 1, S64_MIN, S64_MAX-1, S64_MAX, true, false, false},
-
-	{S64_MIN, S64_MIN, 0, 0, 0, true, false, true},
-	{S64_MAX, S64_MAX, -2, 0, 1, true, false, true},
-
-	{-1, -1, -2, 0, 1, false, false, false},
-	{-1, -128, -129, 127, 128, false, false, false},
-	{-128, -1, -129, -127, 128, false, false, false},
-	{0, -S64_MAX, -S64_MAX, S64_MAX, 0, false, false, false},
-};
-
-#define check_one_op(t, fmt, op, sym, a, b, r, of) do {			\
-	int _a_orig = a, _a_bump = a + 1;				\
-	int _b_orig = b, _b_bump = b + 1;				\
-	bool _of;							\
-	t _r;								\
-									\
-	_of = check_ ## op ## _overflow(a, b, &_r);			\
-	KUNIT_EXPECT_EQ_MSG(test, _of, of,				\
-		"expected check "fmt" "sym" "fmt" to%s overflow (type %s)\n",	\
-		a, b, of ? "" : " not", #t);				\
-	KUNIT_EXPECT_EQ_MSG(test, _r, r,				\
-		"expected check "fmt" "sym" "fmt" == "fmt", got "fmt" (type %s)\n", \
-		a, b, r, _r, #t);					\
-	/* Check for internal macro side-effects. */			\
-	_of = check_ ## op ## _overflow(_a_orig++, _b_orig++, &_r);	\
-	KUNIT_EXPECT_EQ_MSG(test, _a_orig, _a_bump,			\
-		"Unexpected check " #op " macro side-effect!\n");	\
-	KUNIT_EXPECT_EQ_MSG(test, _b_orig, _b_bump,			\
-		"Unexpected check " #op " macro side-effect!\n");	\
-									\
-	_r = wrapping_ ## op(t, a, b);					\
-	KUNIT_EXPECT_TRUE_MSG(test, _r == r,				\
-		"expected wrap "fmt" "sym" "fmt" == "fmt", got "fmt" (type %s)\n", \
-		a, b, r, _r, #t);					\
-	/* Check for internal macro side-effects. */			\
-	_a_orig = a;							\
-	_b_orig = b;							\
-	_r = wrapping_ ## op(t, _a_orig++, _b_orig++);			\
-	KUNIT_EXPECT_EQ_MSG(test, _a_orig, _a_bump,			\
-		"Unexpected wrap " #op " macro side-effect!\n");	\
-	KUNIT_EXPECT_EQ_MSG(test, _b_orig, _b_bump,			\
-		"Unexpected wrap " #op " macro side-effect!\n");	\
-} while (0)
-
-static int global_counter;
-static void bump_counter(void)
-{
-	global_counter++;
-}
-
-static int get_index(void)
-{
-	volatile int index = 0;
-	bump_counter();
-	return index;
-}
-
-#define check_self_op(fmt, op, sym, a, b) do {				\
-	typeof(a + 0) _a = a;						\
-	typeof(b + 0) _b = b;						\
-	typeof(a + 0) _a_sym = a;					\
-	typeof(a + 0) _a_orig[1] = { a };				\
-	typeof(b + 0) _b_orig = b;					\
-	typeof(b + 0) _b_bump = b + 1;					\
-	typeof(a + 0) _r;						\
-									\
-	_a_sym sym _b;							\
-	_r = wrapping_ ## op(_a, _b);					\
-	KUNIT_EXPECT_TRUE_MSG(test, _r == _a_sym,			\
-		"expected "fmt" "#op" "fmt" == "fmt", got "fmt"\n",	\
-		a, b, _a_sym, _r);					\
-	KUNIT_EXPECT_TRUE_MSG(test, _a == _a_sym,			\
-		"expected "fmt" "#op" "fmt" == "fmt", got "fmt"\n",	\
-		a, b, _a_sym, _a);					\
-	/* Check for internal macro side-effects. */			\
-	global_counter = 0;						\
-	wrapping_ ## op(_a_orig[get_index()], _b_orig++);		\
-	KUNIT_EXPECT_EQ_MSG(test, global_counter, 1,			\
-		"Unexpected wrapping_" #op " macro side-effect on arg1!\n"); \
-	KUNIT_EXPECT_EQ_MSG(test, _b_orig, _b_bump,			\
-		"Unexpected wrapping_" #op " macro side-effect on arg2!\n"); \
-} while (0)
-
-#define DEFINE_TEST_FUNC_TYPED(n, t, fmt)				\
-static void do_test_ ## n(struct kunit *test, const struct test_ ## n *p) \
-{									\
-	/* check_{add,sub,mul}_overflow() and wrapping_{add,sub,mul} */	\
-	check_one_op(t, fmt, add, "+", p->a, p->b, p->sum, p->s_of);	\
-	check_one_op(t, fmt, add, "+", p->b, p->a, p->sum, p->s_of);	\
-	check_one_op(t, fmt, sub, "-", p->a, p->b, p->diff, p->d_of);	\
-	check_one_op(t, fmt, mul, "*", p->a, p->b, p->prod, p->p_of);	\
-	check_one_op(t, fmt, mul, "*", p->b, p->a, p->prod, p->p_of);	\
-	/* wrapping_assign_{add,sub}() */				\
-	check_self_op(fmt, assign_add, +=, p->a, p->b);			\
-	check_self_op(fmt, assign_add, +=, p->b, p->a);			\
-	check_self_op(fmt, assign_sub, -=, p->a, p->b);			\
-}									\
-									\
-static void n ## _overflow_test(struct kunit *test) {			\
-	unsigned i;							\
-									\
-	SKIP_64_ON_32(__same_type(t, u64));				\
-	SKIP_64_ON_32(__same_type(t, s64));				\
-	SKIP_SIGN_MISMATCH(__same_type(n ## _tests[0].a, u32) &&	\
-			   __same_type(n ## _tests[0].b, u32) &&	\
-			   __same_type(n ## _tests[0].sum, int));	\
-									\
-	for (i = 0; i < ARRAY_SIZE(n ## _tests); ++i)			\
-		do_test_ ## n(test, &n ## _tests[i]);			\
-	kunit_info(test, "%zu %s arithmetic tests finished\n",		\
-		ARRAY_SIZE(n ## _tests), #n);				\
-}
-
-#define DEFINE_TEST_FUNC(t, fmt)					\
-	DEFINE_TEST_FUNC_TYPED(t ## _ ## t ## __ ## t, t, fmt)
-
-DEFINE_TEST_FUNC(u8, "%d");
-DEFINE_TEST_FUNC(s8, "%d");
-DEFINE_TEST_FUNC(u16, "%d");
-DEFINE_TEST_FUNC(s16, "%d");
-DEFINE_TEST_FUNC(u32, "%u");
-DEFINE_TEST_FUNC(s32, "%d");
-DEFINE_TEST_FUNC(u64, "%llu");
-DEFINE_TEST_FUNC(s64, "%lld");
-
-DEFINE_TEST_ARRAY_TYPED(u32, u32, u8) = {
-	{0, 0, 0, 0, 0, false, false, false},
-	{U8_MAX, 2, 1, U8_MAX - 2, U8_MAX - 1, true, false, true},
-	{U8_MAX + 1, 0, 0, 0, 0, true, true, false},
-};
-DEFINE_TEST_FUNC_TYPED(u32_u32__u8, u8, "%d");
-
-DEFINE_TEST_ARRAY_TYPED(u32, u32, int) = {
-	{0, 0, 0, 0, 0, false, false, false},
-	{U32_MAX, 0, -1, -1, 0, true, true, false},
-};
-DEFINE_TEST_FUNC_TYPED(u32_u32__int, int, "%d");
-
-DEFINE_TEST_ARRAY_TYPED(u8, u8, int) = {
-	{0, 0, 0, 0, 0, false, false, false},
-	{U8_MAX, U8_MAX, 2 * U8_MAX, 0, U8_MAX * U8_MAX, false, false, false},
-	{1, 2, 3, -1, 2, false, false, false},
-};
-DEFINE_TEST_FUNC_TYPED(u8_u8__int, int, "%d");
-
-DEFINE_TEST_ARRAY_TYPED(int, int, u8) = {
-	{0, 0, 0, 0, 0, false, false, false},
-	{1, 2, 3, U8_MAX, 2, false, true, false},
-	{-1, 0, U8_MAX, U8_MAX, 0, true, true, false},
-};
-DEFINE_TEST_FUNC_TYPED(int_int__u8, u8, "%d");
-
-/* Args are: value, shift, type, expected result, overflow expected */
-#define TEST_ONE_SHIFT(a, s, t, expect, of)	do {			\
-	typeof(a) __a = (a);						\
-	typeof(s) __s = (s);						\
-	t __e = (expect);						\
-	t __d;								\
-	bool __of = check_shl_overflow(__a, __s, &__d);			\
-	if (__of != of) {						\
-		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
-			"expected (%s)(%s << %s) to%s overflow\n",	\
-			#t, #a, #s, of ? "" : " not");			\
-	} else if (!__of && __d != __e) {				\
-		KUNIT_EXPECT_EQ_MSG(test, __d, __e,			\
-			"expected (%s)(%s << %s) == %s\n",		\
-			#t, #a, #s, #expect);				\
-		if ((t)-1 < 0)						\
-			kunit_info(test, "got %lld\n", (s64)__d);	\
-		else							\
-			kunit_info(test, "got %llu\n", (u64)__d);	\
-	}								\
-	count++;							\
-} while (0)
-
-static void shift_sane_test(struct kunit *test)
-{
-	int count = 0;
-
-	/* Sane shifts. */
-	TEST_ONE_SHIFT(1, 0, u8, 1 << 0, false);
-	TEST_ONE_SHIFT(1, 4, u8, 1 << 4, false);
-	TEST_ONE_SHIFT(1, 7, u8, 1 << 7, false);
-	TEST_ONE_SHIFT(0xF, 4, u8, 0xF << 4, false);
-	TEST_ONE_SHIFT(1, 0, u16, 1 << 0, false);
-	TEST_ONE_SHIFT(1, 10, u16, 1 << 10, false);
-	TEST_ONE_SHIFT(1, 15, u16, 1 << 15, false);
-	TEST_ONE_SHIFT(0xFF, 8, u16, 0xFF << 8, false);
-	TEST_ONE_SHIFT(1, 0, int, 1 << 0, false);
-	TEST_ONE_SHIFT(1, 16, int, 1 << 16, false);
-	TEST_ONE_SHIFT(1, 30, int, 1 << 30, false);
-	TEST_ONE_SHIFT(1, 0, s32, 1 << 0, false);
-	TEST_ONE_SHIFT(1, 16, s32, 1 << 16, false);
-	TEST_ONE_SHIFT(1, 30, s32, 1 << 30, false);
-	TEST_ONE_SHIFT(1, 0, unsigned int, 1U << 0, false);
-	TEST_ONE_SHIFT(1, 20, unsigned int, 1U << 20, false);
-	TEST_ONE_SHIFT(1, 31, unsigned int, 1U << 31, false);
-	TEST_ONE_SHIFT(0xFFFFU, 16, unsigned int, 0xFFFFU << 16, false);
-	TEST_ONE_SHIFT(1, 0, u32, 1U << 0, false);
-	TEST_ONE_SHIFT(1, 20, u32, 1U << 20, false);
-	TEST_ONE_SHIFT(1, 31, u32, 1U << 31, false);
-	TEST_ONE_SHIFT(0xFFFFU, 16, u32, 0xFFFFU << 16, false);
-	TEST_ONE_SHIFT(1, 0, u64, 1ULL << 0, false);
-	TEST_ONE_SHIFT(1, 40, u64, 1ULL << 40, false);
-	TEST_ONE_SHIFT(1, 63, u64, 1ULL << 63, false);
-	TEST_ONE_SHIFT(0xFFFFFFFFULL, 32, u64, 0xFFFFFFFFULL << 32, false);
-
-	/* Sane shift: start and end with 0, without a too-wide shift. */
-	TEST_ONE_SHIFT(0, 7, u8, 0, false);
-	TEST_ONE_SHIFT(0, 15, u16, 0, false);
-	TEST_ONE_SHIFT(0, 31, unsigned int, 0, false);
-	TEST_ONE_SHIFT(0, 31, u32, 0, false);
-	TEST_ONE_SHIFT(0, 63, u64, 0, false);
-
-	/* Sane shift: start and end with 0, without reaching signed bit. */
-	TEST_ONE_SHIFT(0, 6, s8, 0, false);
-	TEST_ONE_SHIFT(0, 14, s16, 0, false);
-	TEST_ONE_SHIFT(0, 30, int, 0, false);
-	TEST_ONE_SHIFT(0, 30, s32, 0, false);
-	TEST_ONE_SHIFT(0, 62, s64, 0, false);
-
-	kunit_info(test, "%d sane shift tests finished\n", count);
-}
-
-static void shift_overflow_test(struct kunit *test)
-{
-	int count = 0;
-
-	/* Overflow: shifted the bit off the end. */
-	TEST_ONE_SHIFT(1, 8, u8, 0, true);
-	TEST_ONE_SHIFT(1, 16, u16, 0, true);
-	TEST_ONE_SHIFT(1, 32, unsigned int, 0, true);
-	TEST_ONE_SHIFT(1, 32, u32, 0, true);
-	TEST_ONE_SHIFT(1, 64, u64, 0, true);
-
-	/* Overflow: shifted into the signed bit. */
-	TEST_ONE_SHIFT(1, 7, s8, 0, true);
-	TEST_ONE_SHIFT(1, 15, s16, 0, true);
-	TEST_ONE_SHIFT(1, 31, int, 0, true);
-	TEST_ONE_SHIFT(1, 31, s32, 0, true);
-	TEST_ONE_SHIFT(1, 63, s64, 0, true);
-
-	/* Overflow: high bit falls off unsigned types. */
-	/* 10010110 */
-	TEST_ONE_SHIFT(150, 1, u8, 0, true);
-	/* 1000100010010110 */
-	TEST_ONE_SHIFT(34966, 1, u16, 0, true);
-	/* 10000100000010001000100010010110 */
-	TEST_ONE_SHIFT(2215151766U, 1, u32, 0, true);
-	TEST_ONE_SHIFT(2215151766U, 1, unsigned int, 0, true);
-	/* 1000001000010000010000000100000010000100000010001000100010010110 */
-	TEST_ONE_SHIFT(9372061470395238550ULL, 1, u64, 0, true);
-
-	/* Overflow: bit shifted into signed bit on signed types. */
-	/* 01001011 */
-	TEST_ONE_SHIFT(75, 1, s8, 0, true);
-	/* 0100010001001011 */
-	TEST_ONE_SHIFT(17483, 1, s16, 0, true);
-	/* 01000010000001000100010001001011 */
-	TEST_ONE_SHIFT(1107575883, 1, s32, 0, true);
-	TEST_ONE_SHIFT(1107575883, 1, int, 0, true);
-	/* 0100000100001000001000000010000001000010000001000100010001001011 */
-	TEST_ONE_SHIFT(4686030735197619275LL, 1, s64, 0, true);
-
-	/* Overflow: bit shifted past signed bit on signed types. */
-	/* 01001011 */
-	TEST_ONE_SHIFT(75, 2, s8, 0, true);
-	/* 0100010001001011 */
-	TEST_ONE_SHIFT(17483, 2, s16, 0, true);
-	/* 01000010000001000100010001001011 */
-	TEST_ONE_SHIFT(1107575883, 2, s32, 0, true);
-	TEST_ONE_SHIFT(1107575883, 2, int, 0, true);
-	/* 0100000100001000001000000010000001000010000001000100010001001011 */
-	TEST_ONE_SHIFT(4686030735197619275LL, 2, s64, 0, true);
-
-	kunit_info(test, "%d overflow shift tests finished\n", count);
-}
-
-static void shift_truncate_test(struct kunit *test)
-{
-	int count = 0;
-
-	/* Overflow: values larger than destination type. */
-	TEST_ONE_SHIFT(0x100, 0, u8, 0, true);
-	TEST_ONE_SHIFT(0xFF, 0, s8, 0, true);
-	TEST_ONE_SHIFT(0x10000U, 0, u16, 0, true);
-	TEST_ONE_SHIFT(0xFFFFU, 0, s16, 0, true);
-	TEST_ONE_SHIFT(0x100000000ULL, 0, u32, 0, true);
-	TEST_ONE_SHIFT(0x100000000ULL, 0, unsigned int, 0, true);
-	TEST_ONE_SHIFT(0xFFFFFFFFUL, 0, s32, 0, true);
-	TEST_ONE_SHIFT(0xFFFFFFFFUL, 0, int, 0, true);
-	TEST_ONE_SHIFT(0xFFFFFFFFFFFFFFFFULL, 0, s64, 0, true);
-
-	/* Overflow: shifted at or beyond entire type's bit width. */
-	TEST_ONE_SHIFT(0, 8, u8, 0, true);
-	TEST_ONE_SHIFT(0, 9, u8, 0, true);
-	TEST_ONE_SHIFT(0, 8, s8, 0, true);
-	TEST_ONE_SHIFT(0, 9, s8, 0, true);
-	TEST_ONE_SHIFT(0, 16, u16, 0, true);
-	TEST_ONE_SHIFT(0, 17, u16, 0, true);
-	TEST_ONE_SHIFT(0, 16, s16, 0, true);
-	TEST_ONE_SHIFT(0, 17, s16, 0, true);
-	TEST_ONE_SHIFT(0, 32, u32, 0, true);
-	TEST_ONE_SHIFT(0, 33, u32, 0, true);
-	TEST_ONE_SHIFT(0, 32, int, 0, true);
-	TEST_ONE_SHIFT(0, 33, int, 0, true);
-	TEST_ONE_SHIFT(0, 32, s32, 0, true);
-	TEST_ONE_SHIFT(0, 33, s32, 0, true);
-	TEST_ONE_SHIFT(0, 64, u64, 0, true);
-	TEST_ONE_SHIFT(0, 65, u64, 0, true);
-	TEST_ONE_SHIFT(0, 64, s64, 0, true);
-	TEST_ONE_SHIFT(0, 65, s64, 0, true);
-
-	kunit_info(test, "%d truncate shift tests finished\n", count);
-}
-
-static void shift_nonsense_test(struct kunit *test)
-{
-	int count = 0;
-
-	/* Nonsense: negative initial value. */
-	TEST_ONE_SHIFT(-1, 0, s8, 0, true);
-	TEST_ONE_SHIFT(-1, 0, u8, 0, true);
-	TEST_ONE_SHIFT(-5, 0, s16, 0, true);
-	TEST_ONE_SHIFT(-5, 0, u16, 0, true);
-	TEST_ONE_SHIFT(-10, 0, int, 0, true);
-	TEST_ONE_SHIFT(-10, 0, unsigned int, 0, true);
-	TEST_ONE_SHIFT(-100, 0, s32, 0, true);
-	TEST_ONE_SHIFT(-100, 0, u32, 0, true);
-	TEST_ONE_SHIFT(-10000, 0, s64, 0, true);
-	TEST_ONE_SHIFT(-10000, 0, u64, 0, true);
-
-	/* Nonsense: negative shift values. */
-	TEST_ONE_SHIFT(0, -5, s8, 0, true);
-	TEST_ONE_SHIFT(0, -5, u8, 0, true);
-	TEST_ONE_SHIFT(0, -10, s16, 0, true);
-	TEST_ONE_SHIFT(0, -10, u16, 0, true);
-	TEST_ONE_SHIFT(0, -15, int, 0, true);
-	TEST_ONE_SHIFT(0, -15, unsigned int, 0, true);
-	TEST_ONE_SHIFT(0, -20, s32, 0, true);
-	TEST_ONE_SHIFT(0, -20, u32, 0, true);
-	TEST_ONE_SHIFT(0, -30, s64, 0, true);
-	TEST_ONE_SHIFT(0, -30, u64, 0, true);
-
-	/*
-	 * Corner case: for unsigned types, we fail when we've shifted
-	 * through the entire width of bits. For signed types, we might
-	 * want to match this behavior, but that would mean noticing if
-	 * we shift through all but the signed bit, and this is not
-	 * currently detected (but we'll notice an overflow into the
-	 * signed bit). So, for now, we will test this condition but
-	 * mark it as not expected to overflow.
-	 */
-	TEST_ONE_SHIFT(0, 7, s8, 0, false);
-	TEST_ONE_SHIFT(0, 15, s16, 0, false);
-	TEST_ONE_SHIFT(0, 31, int, 0, false);
-	TEST_ONE_SHIFT(0, 31, s32, 0, false);
-	TEST_ONE_SHIFT(0, 63, s64, 0, false);
-
-	kunit_info(test, "%d nonsense shift tests finished\n", count);
-}
-#undef TEST_ONE_SHIFT
-
-/*
- * Deal with the various forms of allocator arguments. See comments above
- * the DEFINE_TEST_ALLOC() instances for mapping of the "bits".
- */
-#define alloc_GFP		 (GFP_KERNEL | __GFP_NOWARN)
-#define alloc010(alloc, arg, sz) alloc(sz, alloc_GFP)
-#define alloc011(alloc, arg, sz) alloc(sz, alloc_GFP, NUMA_NO_NODE)
-#define alloc000(alloc, arg, sz) alloc(sz)
-#define alloc001(alloc, arg, sz) alloc(sz, NUMA_NO_NODE)
-#define alloc110(alloc, arg, sz) alloc(arg, sz, alloc_GFP)
-#define free0(free, arg, ptr)	 free(ptr)
-#define free1(free, arg, ptr)	 free(arg, ptr)
-
-/* Wrap around to 16K */
-#define TEST_SIZE		(5 * 4096)
-
-#define DEFINE_TEST_ALLOC(func, free_func, want_arg, want_gfp, want_node)\
-static void test_ ## func (struct kunit *test, void *arg)		\
-{									\
-	volatile size_t a = TEST_SIZE;					\
-	volatile size_t b = (SIZE_MAX / TEST_SIZE) + 1;			\
-	void *ptr;							\
-									\
-	/* Tiny allocation test. */					\
-	ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg, 1);\
-	KUNIT_ASSERT_NOT_ERR_OR_NULL_MSG(test, ptr,			\
-			    #func " failed regular allocation?!\n");	\
-	free ## want_arg (free_func, arg, ptr);				\
-									\
-	/* Wrapped allocation test. */					\
-	ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg,	\
-							  a * b);	\
-	KUNIT_ASSERT_NOT_ERR_OR_NULL_MSG(test, ptr,			\
-			    #func " unexpectedly failed bad wrapping?!\n"); \
-	free ## want_arg (free_func, arg, ptr);				\
-									\
-	/* Saturated allocation test. */				\
-	ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg,	\
-						   array_size(a, b));	\
-	if (ptr) {							\
-		KUNIT_FAIL(test, #func " missed saturation!\n");	\
-		free ## want_arg (free_func, arg, ptr);			\
-	}								\
-}
-
-/*
- * Allocator uses a trailing node argument --------+  (e.g. kmalloc_node())
- * Allocator uses the gfp_t argument -----------+  |  (e.g. kmalloc())
- * Allocator uses a special leading argument +  |  |  (e.g. devm_kmalloc())
- *                                           |  |  |
- */
-DEFINE_TEST_ALLOC(kmalloc,	 kfree,	     0, 1, 0);
-DEFINE_TEST_ALLOC(kmalloc_node,	 kfree,	     0, 1, 1);
-DEFINE_TEST_ALLOC(kzalloc,	 kfree,	     0, 1, 0);
-DEFINE_TEST_ALLOC(kzalloc_node,  kfree,	     0, 1, 1);
-DEFINE_TEST_ALLOC(__vmalloc,	 vfree,	     0, 1, 0);
-DEFINE_TEST_ALLOC(kvmalloc,	 kvfree,     0, 1, 0);
-DEFINE_TEST_ALLOC(kvmalloc_node, kvfree,     0, 1, 1);
-DEFINE_TEST_ALLOC(kvzalloc,	 kvfree,     0, 1, 0);
-DEFINE_TEST_ALLOC(kvzalloc_node, kvfree,     0, 1, 1);
-DEFINE_TEST_ALLOC(devm_kmalloc,  devm_kfree, 1, 1, 0);
-DEFINE_TEST_ALLOC(devm_kzalloc,  devm_kfree, 1, 1, 0);
-
-static void overflow_allocation_test(struct kunit *test)
-{
-	struct device *dev;
-	int count = 0;
-
-#define check_allocation_overflow(alloc)	do {	\
-	count++;					\
-	test_ ## alloc(test, dev);			\
-} while (0)
-
-	/* Create dummy device for devm_kmalloc()-family tests. */
-	dev = kunit_device_register(test, "overflow-test");
-	KUNIT_ASSERT_FALSE_MSG(test, IS_ERR(dev),
-			       "Cannot register test device\n");
-
-	check_allocation_overflow(kmalloc);
-	check_allocation_overflow(kmalloc_node);
-	check_allocation_overflow(kzalloc);
-	check_allocation_overflow(kzalloc_node);
-	check_allocation_overflow(__vmalloc);
-	check_allocation_overflow(kvmalloc);
-	check_allocation_overflow(kvmalloc_node);
-	check_allocation_overflow(kvzalloc);
-	check_allocation_overflow(kvzalloc_node);
-	check_allocation_overflow(devm_kmalloc);
-	check_allocation_overflow(devm_kzalloc);
-
-	kunit_info(test, "%d allocation overflow tests finished\n", count);
-#undef check_allocation_overflow
-}
-
-struct __test_flex_array {
-	unsigned long flags;
-	size_t count;
-	unsigned long data[];
-};
-
-static void overflow_size_helpers_test(struct kunit *test)
-{
-	/* Make sure struct_size() can be used in a constant expression. */
-	u8 ce_array[struct_size_t(struct __test_flex_array, data, 55)];
-	struct __test_flex_array *obj;
-	int count = 0;
-	int var;
-	volatile int unconst = 0;
-
-	/* Verify constant expression against runtime version. */
-	var = 55;
-	OPTIMIZER_HIDE_VAR(var);
-	KUNIT_EXPECT_EQ(test, sizeof(ce_array), struct_size(obj, data, var));
-
-#define check_one_size_helper(expected, func, args...)	do {	\
-	size_t _r = func(args);					\
-	KUNIT_EXPECT_EQ_MSG(test, _r, expected,			\
-		"expected " #func "(" #args ") to return %zu but got %zu instead\n", \
-		(size_t)(expected), _r);			\
-	count++;						\
-} while (0)
-
-	var = 4;
-	check_one_size_helper(20,	size_mul, var++, 5);
-	check_one_size_helper(20,	size_mul, 4, var++);
-	check_one_size_helper(0,	size_mul, 0, 3);
-	check_one_size_helper(0,	size_mul, 3, 0);
-	check_one_size_helper(6,	size_mul, 2, 3);
-	check_one_size_helper(SIZE_MAX,	size_mul, SIZE_MAX,  1);
-	check_one_size_helper(SIZE_MAX,	size_mul, SIZE_MAX,  3);
-	check_one_size_helper(SIZE_MAX,	size_mul, SIZE_MAX, -3);
-
-	var = 4;
-	check_one_size_helper(9,	size_add, var++, 5);
-	check_one_size_helper(9,	size_add, 4, var++);
-	check_one_size_helper(9,	size_add, 9, 0);
-	check_one_size_helper(9,	size_add, 0, 9);
-	check_one_size_helper(5,	size_add, 2, 3);
-	check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX,  1);
-	check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX,  3);
-	check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX, -3);
-
-	var = 4;
-	check_one_size_helper(1,	size_sub, var--, 3);
-	check_one_size_helper(1,	size_sub, 4, var--);
-	check_one_size_helper(1,	size_sub, 3, 2);
-	check_one_size_helper(9,	size_sub, 9, 0);
-	check_one_size_helper(SIZE_MAX, size_sub, 9, -3);
-	check_one_size_helper(SIZE_MAX, size_sub, 0, 9);
-	check_one_size_helper(SIZE_MAX, size_sub, 2, 3);
-	check_one_size_helper(SIZE_MAX, size_sub, SIZE_MAX,  0);
-	check_one_size_helper(SIZE_MAX, size_sub, SIZE_MAX, 10);
-	check_one_size_helper(SIZE_MAX, size_sub, 0,  SIZE_MAX);
-	check_one_size_helper(SIZE_MAX, size_sub, 14, SIZE_MAX);
-	check_one_size_helper(SIZE_MAX - 2, size_sub, SIZE_MAX - 1,  1);
-	check_one_size_helper(SIZE_MAX - 4, size_sub, SIZE_MAX - 1,  3);
-	check_one_size_helper(1,		size_sub, SIZE_MAX - 1, -3);
-
-	var = 4;
-	check_one_size_helper(4 * sizeof(*obj->data),
-			      flex_array_size, obj, data, var++);
-	check_one_size_helper(5 * sizeof(*obj->data),
-			      flex_array_size, obj, data, var++);
-	check_one_size_helper(0, flex_array_size, obj, data, 0 + unconst);
-	check_one_size_helper(sizeof(*obj->data),
-			      flex_array_size, obj, data, 1 + unconst);
-	check_one_size_helper(7 * sizeof(*obj->data),
-			      flex_array_size, obj, data, 7 + unconst);
-	check_one_size_helper(SIZE_MAX,
-			      flex_array_size, obj, data, -1 + unconst);
-	check_one_size_helper(SIZE_MAX,
-			      flex_array_size, obj, data, SIZE_MAX - 4 + unconst);
-
-	var = 4;
-	check_one_size_helper(sizeof(*obj) + (4 * sizeof(*obj->data)),
-			      struct_size, obj, data, var++);
-	check_one_size_helper(sizeof(*obj) + (5 * sizeof(*obj->data)),
-			      struct_size, obj, data, var++);
-	check_one_size_helper(sizeof(*obj), struct_size, obj, data, 0 + unconst);
-	check_one_size_helper(sizeof(*obj) + sizeof(*obj->data),
-			      struct_size, obj, data, 1 + unconst);
-	check_one_size_helper(SIZE_MAX,
-			      struct_size, obj, data, -3 + unconst);
-	check_one_size_helper(SIZE_MAX,
-			      struct_size, obj, data, SIZE_MAX - 3 + unconst);
-
-	kunit_info(test, "%d overflow size helper tests finished\n", count);
-#undef check_one_size_helper
-}
-
-static void overflows_type_test(struct kunit *test)
-{
-	int count = 0;
-	unsigned int var;
-
-#define __TEST_OVERFLOWS_TYPE(func, arg1, arg2, of)	do {		\
-	bool __of = func(arg1, arg2);					\
-	KUNIT_EXPECT_EQ_MSG(test, __of, of,				\
-		"expected " #func "(" #arg1 ", " #arg2 " to%s overflow\n",\
-		of ? "" : " not");					\
-	count++;							\
-} while (0)
-
-/* Args are: first type, second type, value, overflow expected */
-#define TEST_OVERFLOWS_TYPE(__t1, __t2, v, of) do {			\
-	__t1 t1 = (v);							\
-	__t2 t2;							\
-	__TEST_OVERFLOWS_TYPE(__overflows_type, t1, t2, of);		\
-	__TEST_OVERFLOWS_TYPE(__overflows_type, t1, __t2, of);		\
-	__TEST_OVERFLOWS_TYPE(__overflows_type_constexpr, t1, t2, of);	\
-	__TEST_OVERFLOWS_TYPE(__overflows_type_constexpr, t1, __t2, of);\
-} while (0)
-
-	TEST_OVERFLOWS_TYPE(u8, u8, U8_MAX, false);
-	TEST_OVERFLOWS_TYPE(u8, u16, U8_MAX, false);
-	TEST_OVERFLOWS_TYPE(u8, s8, U8_MAX, true);
-	TEST_OVERFLOWS_TYPE(u8, s8, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(u8, s8, (u8)S8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u8, s16, U8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s8, u8, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s8, u8, -1, true);
-	TEST_OVERFLOWS_TYPE(s8, u8, S8_MIN, true);
-	TEST_OVERFLOWS_TYPE(s8, u16, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s8, u16, -1, true);
-	TEST_OVERFLOWS_TYPE(s8, u16, S8_MIN, true);
-	TEST_OVERFLOWS_TYPE(s8, u32, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s8, u32, -1, true);
-	TEST_OVERFLOWS_TYPE(s8, u32, S8_MIN, true);
-#if BITS_PER_LONG == 64
-	TEST_OVERFLOWS_TYPE(s8, u64, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s8, u64, -1, true);
-	TEST_OVERFLOWS_TYPE(s8, u64, S8_MIN, true);
-#endif
-	TEST_OVERFLOWS_TYPE(s8, s8, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s8, s8, S8_MIN, false);
-	TEST_OVERFLOWS_TYPE(s8, s16, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s8, s16, S8_MIN, false);
-	TEST_OVERFLOWS_TYPE(u16, u8, U8_MAX, false);
-	TEST_OVERFLOWS_TYPE(u16, u8, (u16)U8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u16, u8, U16_MAX, true);
-	TEST_OVERFLOWS_TYPE(u16, s8, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(u16, s8, (u16)S8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u16, s8, U16_MAX, true);
-	TEST_OVERFLOWS_TYPE(u16, s16, S16_MAX, false);
-	TEST_OVERFLOWS_TYPE(u16, s16, (u16)S16_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u16, s16, U16_MAX, true);
-	TEST_OVERFLOWS_TYPE(u16, u32, U16_MAX, false);
-	TEST_OVERFLOWS_TYPE(u16, s32, U16_MAX, false);
-	TEST_OVERFLOWS_TYPE(s16, u8, U8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s16, u8, (s16)U8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s16, u8, -1, true);
-	TEST_OVERFLOWS_TYPE(s16, u8, S16_MIN, true);
-	TEST_OVERFLOWS_TYPE(s16, u16, S16_MAX, false);
-	TEST_OVERFLOWS_TYPE(s16, u16, -1, true);
-	TEST_OVERFLOWS_TYPE(s16, u16, S16_MIN, true);
-	TEST_OVERFLOWS_TYPE(s16, u32, S16_MAX, false);
-	TEST_OVERFLOWS_TYPE(s16, u32, -1, true);
-	TEST_OVERFLOWS_TYPE(s16, u32, S16_MIN, true);
-#if BITS_PER_LONG == 64
-	TEST_OVERFLOWS_TYPE(s16, u64, S16_MAX, false);
-	TEST_OVERFLOWS_TYPE(s16, u64, -1, true);
-	TEST_OVERFLOWS_TYPE(s16, u64, S16_MIN, true);
-#endif
-	TEST_OVERFLOWS_TYPE(s16, s8, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s16, s8, S8_MIN, false);
-	TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MIN - 1, true);
-	TEST_OVERFLOWS_TYPE(s16, s8, S16_MAX, true);
-	TEST_OVERFLOWS_TYPE(s16, s8, S16_MIN, true);
-	TEST_OVERFLOWS_TYPE(s16, s16, S16_MAX, false);
-	TEST_OVERFLOWS_TYPE(s16, s16, S16_MIN, false);
-	TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
-	TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
-	TEST_OVERFLOWS_TYPE(u32, u8, U8_MAX, false);
-	TEST_OVERFLOWS_TYPE(u32, u8, (u32)U8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u32, u8, U32_MAX, true);
-	TEST_OVERFLOWS_TYPE(u32, s8, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(u32, s8, (u32)S8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u32, s8, U32_MAX, true);
-	TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX, false);
-	TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u32, u16, U32_MAX, true);
-	TEST_OVERFLOWS_TYPE(u32, s16, S16_MAX, false);
-	TEST_OVERFLOWS_TYPE(u32, s16, (u32)S16_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u32, s16, U32_MAX, true);
-	TEST_OVERFLOWS_TYPE(u32, u32, U32_MAX, false);
-	TEST_OVERFLOWS_TYPE(u32, s32, S32_MAX, false);
-	TEST_OVERFLOWS_TYPE(u32, s32, U32_MAX, true);
-	TEST_OVERFLOWS_TYPE(u32, s32, (u32)S32_MAX + 1, true);
-#if BITS_PER_LONG == 64
-	TEST_OVERFLOWS_TYPE(u32, u64, U32_MAX, false);
-	TEST_OVERFLOWS_TYPE(u32, s64, U32_MAX, false);
-#endif
-	TEST_OVERFLOWS_TYPE(s32, u8, U8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s32, u8, (s32)U8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
-	TEST_OVERFLOWS_TYPE(s32, u8, -1, true);
-	TEST_OVERFLOWS_TYPE(s32, u8, S32_MIN, true);
-	TEST_OVERFLOWS_TYPE(s32, u16, U16_MAX, false);
-	TEST_OVERFLOWS_TYPE(s32, u16, (s32)U16_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
-	TEST_OVERFLOWS_TYPE(s32, u16, -1, true);
-	TEST_OVERFLOWS_TYPE(s32, u16, S32_MIN, true);
-	TEST_OVERFLOWS_TYPE(s32, u32, S32_MAX, false);
-	TEST_OVERFLOWS_TYPE(s32, u32, -1, true);
-	TEST_OVERFLOWS_TYPE(s32, u32, S32_MIN, true);
-#if BITS_PER_LONG == 64
-	TEST_OVERFLOWS_TYPE(s32, u64, S32_MAX, false);
-	TEST_OVERFLOWS_TYPE(s32, u64, -1, true);
-	TEST_OVERFLOWS_TYPE(s32, u64, S32_MIN, true);
-#endif
-	TEST_OVERFLOWS_TYPE(s32, s8, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s32, s8, S8_MIN, false);
-	TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MIN - 1, true);
-	TEST_OVERFLOWS_TYPE(s32, s8, S32_MAX, true);
-	TEST_OVERFLOWS_TYPE(s32, s8, S32_MIN, true);
-	TEST_OVERFLOWS_TYPE(s32, s16, S16_MAX, false);
-	TEST_OVERFLOWS_TYPE(s32, s16, S16_MIN, false);
-	TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MIN - 1, true);
-	TEST_OVERFLOWS_TYPE(s32, s16, S32_MAX, true);
-	TEST_OVERFLOWS_TYPE(s32, s16, S32_MIN, true);
-	TEST_OVERFLOWS_TYPE(s32, s32, S32_MAX, false);
-	TEST_OVERFLOWS_TYPE(s32, s32, S32_MIN, false);
-#if BITS_PER_LONG == 64
-	TEST_OVERFLOWS_TYPE(s32, s64, S32_MAX, false);
-	TEST_OVERFLOWS_TYPE(s32, s64, S32_MIN, false);
-	TEST_OVERFLOWS_TYPE(u64, u8, U64_MAX, true);
-	TEST_OVERFLOWS_TYPE(u64, u8, U8_MAX, false);
-	TEST_OVERFLOWS_TYPE(u64, u8, (u64)U8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u64, u16, U64_MAX, true);
-	TEST_OVERFLOWS_TYPE(u64, u16, U16_MAX, false);
-	TEST_OVERFLOWS_TYPE(u64, u16, (u64)U16_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u64, u32, U64_MAX, true);
-	TEST_OVERFLOWS_TYPE(u64, u32, U32_MAX, false);
-	TEST_OVERFLOWS_TYPE(u64, u32, (u64)U32_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u64, u64, U64_MAX, false);
-	TEST_OVERFLOWS_TYPE(u64, s8, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(u64, s8, (u64)S8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u64, s8, U64_MAX, true);
-	TEST_OVERFLOWS_TYPE(u64, s16, S16_MAX, false);
-	TEST_OVERFLOWS_TYPE(u64, s16, (u64)S16_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u64, s16, U64_MAX, true);
-	TEST_OVERFLOWS_TYPE(u64, s32, S32_MAX, false);
-	TEST_OVERFLOWS_TYPE(u64, s32, (u64)S32_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(u64, s32, U64_MAX, true);
-	TEST_OVERFLOWS_TYPE(u64, s64, S64_MAX, false);
-	TEST_OVERFLOWS_TYPE(u64, s64, U64_MAX, true);
-	TEST_OVERFLOWS_TYPE(u64, s64, (u64)S64_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s64, u8, S64_MAX, true);
-	TEST_OVERFLOWS_TYPE(s64, u8, S64_MIN, true);
-	TEST_OVERFLOWS_TYPE(s64, u8, -1, true);
-	TEST_OVERFLOWS_TYPE(s64, u8, U8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s64, u8, (s64)U8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s64, u16, S64_MAX, true);
-	TEST_OVERFLOWS_TYPE(s64, u16, S64_MIN, true);
-	TEST_OVERFLOWS_TYPE(s64, u16, -1, true);
-	TEST_OVERFLOWS_TYPE(s64, u16, U16_MAX, false);
-	TEST_OVERFLOWS_TYPE(s64, u16, (s64)U16_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s64, u32, S64_MAX, true);
-	TEST_OVERFLOWS_TYPE(s64, u32, S64_MIN, true);
-	TEST_OVERFLOWS_TYPE(s64, u32, -1, true);
-	TEST_OVERFLOWS_TYPE(s64, u32, U32_MAX, false);
-	TEST_OVERFLOWS_TYPE(s64, u32, (s64)U32_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s64, u64, S64_MAX, false);
-	TEST_OVERFLOWS_TYPE(s64, u64, S64_MIN, true);
-	TEST_OVERFLOWS_TYPE(s64, u64, -1, true);
-	TEST_OVERFLOWS_TYPE(s64, s8, S8_MAX, false);
-	TEST_OVERFLOWS_TYPE(s64, s8, S8_MIN, false);
-	TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MIN - 1, true);
-	TEST_OVERFLOWS_TYPE(s64, s8, S64_MAX, true);
-	TEST_OVERFLOWS_TYPE(s64, s16, S16_MAX, false);
-	TEST_OVERFLOWS_TYPE(s64, s16, S16_MIN, false);
-	TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MIN - 1, true);
-	TEST_OVERFLOWS_TYPE(s64, s16, S64_MAX, true);
-	TEST_OVERFLOWS_TYPE(s64, s32, S32_MAX, false);
-	TEST_OVERFLOWS_TYPE(s64, s32, S32_MIN, false);
-	TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MAX + 1, true);
-	TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MIN - 1, true);
-	TEST_OVERFLOWS_TYPE(s64, s32, S64_MAX, true);
-	TEST_OVERFLOWS_TYPE(s64, s64, S64_MAX, false);
-	TEST_OVERFLOWS_TYPE(s64, s64, S64_MIN, false);
-#endif
-
-	/* Check for macro side-effects. */
-	var = INT_MAX - 1;
-	__TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, false);
-	__TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, false);
-	__TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, true);
-	var = INT_MAX - 1;
-	__TEST_OVERFLOWS_TYPE(overflows_type, var++, int, false);
-	__TEST_OVERFLOWS_TYPE(overflows_type, var++, int, false);
-	__TEST_OVERFLOWS_TYPE(overflows_type, var++, int, true);
-
-	kunit_info(test, "%d overflows_type() tests finished\n", count);
-#undef TEST_OVERFLOWS_TYPE
-#undef __TEST_OVERFLOWS_TYPE
-}
-
-static void same_type_test(struct kunit *test)
-{
-	int count = 0;
-	int var;
-
-#define TEST_SAME_TYPE(t1, t2, same)			do {	\
-	typeof(t1) __t1h = type_max(t1);			\
-	typeof(t1) __t1l = type_min(t1);			\
-	typeof(t2) __t2h = type_max(t2);			\
-	typeof(t2) __t2l = type_min(t2);			\
-	KUNIT_EXPECT_EQ(test, true, __same_type(t1, __t1h));	\
-	KUNIT_EXPECT_EQ(test, true, __same_type(t1, __t1l));	\
-	KUNIT_EXPECT_EQ(test, true, __same_type(__t1h, t1));	\
-	KUNIT_EXPECT_EQ(test, true, __same_type(__t1l, t1));	\
-	KUNIT_EXPECT_EQ(test, true, __same_type(t2, __t2h));	\
-	KUNIT_EXPECT_EQ(test, true, __same_type(t2, __t2l));	\
-	KUNIT_EXPECT_EQ(test, true, __same_type(__t2h, t2));	\
-	KUNIT_EXPECT_EQ(test, true, __same_type(__t2l, t2));	\
-	KUNIT_EXPECT_EQ(test, same, __same_type(t1, t2));	\
-	KUNIT_EXPECT_EQ(test, same, __same_type(t2, __t1h));	\
-	KUNIT_EXPECT_EQ(test, same, __same_type(t2, __t1l));	\
-	KUNIT_EXPECT_EQ(test, same, __same_type(__t1h, t2));	\
-	KUNIT_EXPECT_EQ(test, same, __same_type(__t1l, t2));	\
-	KUNIT_EXPECT_EQ(test, same, __same_type(t1, __t2h));	\
-	KUNIT_EXPECT_EQ(test, same, __same_type(t1, __t2l));	\
-	KUNIT_EXPECT_EQ(test, same, __same_type(__t2h, t1));	\
-	KUNIT_EXPECT_EQ(test, same, __same_type(__t2l, t1));	\
-} while (0)
-
-#if BITS_PER_LONG == 64
-# define TEST_SAME_TYPE64(base, t, m)	TEST_SAME_TYPE(base, t, m)
-#else
-# define TEST_SAME_TYPE64(base, t, m)	do { } while (0)
-#endif
-
-#define TEST_TYPE_SETS(base, mu8, mu16, mu32, ms8, ms16, ms32, mu64, ms64) \
-do {									\
-	TEST_SAME_TYPE(base,  u8,  mu8);				\
-	TEST_SAME_TYPE(base, u16, mu16);				\
-	TEST_SAME_TYPE(base, u32, mu32);				\
-	TEST_SAME_TYPE(base,  s8,  ms8);				\
-	TEST_SAME_TYPE(base, s16, ms16);				\
-	TEST_SAME_TYPE(base, s32, ms32);				\
-	TEST_SAME_TYPE64(base, u64, mu64);				\
-	TEST_SAME_TYPE64(base, s64, ms64);				\
-} while (0)
-
-	TEST_TYPE_SETS(u8,   true, false, false, false, false, false, false, false);
-	TEST_TYPE_SETS(u16, false,  true, false, false, false, false, false, false);
-	TEST_TYPE_SETS(u32, false, false,  true, false, false, false, false, false);
-	TEST_TYPE_SETS(s8,  false, false, false,  true, false, false, false, false);
-	TEST_TYPE_SETS(s16, false, false, false, false,  true, false, false, false);
-	TEST_TYPE_SETS(s32, false, false, false, false, false,  true, false, false);
-#if BITS_PER_LONG == 64
-	TEST_TYPE_SETS(u64, false, false, false, false, false, false,  true, false);
-	TEST_TYPE_SETS(s64, false, false, false, false, false, false, false,  true);
-#endif
-
-	/* Check for macro side-effects. */
-	var = 4;
-	KUNIT_EXPECT_EQ(test, var, 4);
-	KUNIT_EXPECT_TRUE(test, __same_type(var++, int));
-	KUNIT_EXPECT_EQ(test, var, 4);
-	KUNIT_EXPECT_TRUE(test, __same_type(int, var++));
-	KUNIT_EXPECT_EQ(test, var, 4);
-	KUNIT_EXPECT_TRUE(test, __same_type(var++, var++));
-	KUNIT_EXPECT_EQ(test, var, 4);
-
-	kunit_info(test, "%d __same_type() tests finished\n", count);
-
-#undef TEST_TYPE_SETS
-#undef TEST_SAME_TYPE64
-#undef TEST_SAME_TYPE
-}
-
-static void castable_to_type_test(struct kunit *test)
-{
-	int count = 0;
-
-#define TEST_CASTABLE_TO_TYPE(arg1, arg2, pass)	do {	\
-	bool __pass = castable_to_type(arg1, arg2);		\
-	KUNIT_EXPECT_EQ_MSG(test, __pass, pass,			\
-		"expected castable_to_type(" #arg1 ", " #arg2 ") to%s pass\n",\
-		pass ? "" : " not");				\
-	count++;						\
-} while (0)
-
-	TEST_CASTABLE_TO_TYPE(16, u8, true);
-	TEST_CASTABLE_TO_TYPE(16, u16, true);
-	TEST_CASTABLE_TO_TYPE(16, u32, true);
-	TEST_CASTABLE_TO_TYPE(16, s8, true);
-	TEST_CASTABLE_TO_TYPE(16, s16, true);
-	TEST_CASTABLE_TO_TYPE(16, s32, true);
-	TEST_CASTABLE_TO_TYPE(-16, s8, true);
-	TEST_CASTABLE_TO_TYPE(-16, s16, true);
-	TEST_CASTABLE_TO_TYPE(-16, s32, true);
-#if BITS_PER_LONG == 64
-	TEST_CASTABLE_TO_TYPE(16, u64, true);
-	TEST_CASTABLE_TO_TYPE(-16, s64, true);
-#endif
-
-#define TEST_CASTABLE_TO_TYPE_VAR(width)	do {				\
-	u ## width u ## width ## var = 0;					\
-	s ## width s ## width ## var = 0;					\
-										\
-	/* Constant expressions that fit types. */				\
-	TEST_CASTABLE_TO_TYPE(type_max(u ## width), u ## width, true);		\
-	TEST_CASTABLE_TO_TYPE(type_min(u ## width), u ## width, true);		\
-	TEST_CASTABLE_TO_TYPE(type_max(u ## width), u ## width ## var, true);	\
-	TEST_CASTABLE_TO_TYPE(type_min(u ## width), u ## width ## var, true);	\
-	TEST_CASTABLE_TO_TYPE(type_max(s ## width), s ## width, true);		\
-	TEST_CASTABLE_TO_TYPE(type_min(s ## width), s ## width, true);		\
-	TEST_CASTABLE_TO_TYPE(type_max(s ## width), s ## width ## var, true);	\
-	TEST_CASTABLE_TO_TYPE(type_min(u ## width), s ## width ## var, true);	\
-	/* Constant expressions that do not fit types. */			\
-	TEST_CASTABLE_TO_TYPE(type_max(u ## width), s ## width, false);		\
-	TEST_CASTABLE_TO_TYPE(type_max(u ## width), s ## width ## var, false);	\
-	TEST_CASTABLE_TO_TYPE(type_min(s ## width), u ## width, false);		\
-	TEST_CASTABLE_TO_TYPE(type_min(s ## width), u ## width ## var, false);	\
-	/* Non-constant expression with mismatched type. */			\
-	TEST_CASTABLE_TO_TYPE(s ## width ## var, u ## width, false);		\
-	TEST_CASTABLE_TO_TYPE(u ## width ## var, s ## width, false);		\
-} while (0)
-
-#define TEST_CASTABLE_TO_TYPE_RANGE(width)	do {				\
-	unsigned long big = U ## width ## _MAX;					\
-	signed long small = S ## width ## _MIN;					\
-	u ## width u ## width ## var = 0;					\
-	s ## width s ## width ## var = 0;					\
-										\
-	/* Constant expression in range. */					\
-	TEST_CASTABLE_TO_TYPE(U ## width ## _MAX, u ## width, true);		\
-	TEST_CASTABLE_TO_TYPE(U ## width ## _MAX, u ## width ## var, true);	\
-	TEST_CASTABLE_TO_TYPE(S ## width ## _MIN, s ## width, true);		\
-	TEST_CASTABLE_TO_TYPE(S ## width ## _MIN, s ## width ## var, true);	\
-	/* Constant expression out of range. */					\
-	TEST_CASTABLE_TO_TYPE((unsigned long)U ## width ## _MAX + 1, u ## width, false); \
-	TEST_CASTABLE_TO_TYPE((unsigned long)U ## width ## _MAX + 1, u ## width ## var, false); \
-	TEST_CASTABLE_TO_TYPE((signed long)S ## width ## _MIN - 1, s ## width, false); \
-	TEST_CASTABLE_TO_TYPE((signed long)S ## width ## _MIN - 1, s ## width ## var, false); \
-	/* Non-constant expression with mismatched type. */			\
-	TEST_CASTABLE_TO_TYPE(big, u ## width, false);				\
-	TEST_CASTABLE_TO_TYPE(big, u ## width ## var, false);			\
-	TEST_CASTABLE_TO_TYPE(small, s ## width, false);			\
-	TEST_CASTABLE_TO_TYPE(small, s ## width ## var, false);			\
-} while (0)
-
-	TEST_CASTABLE_TO_TYPE_VAR(8);
-	TEST_CASTABLE_TO_TYPE_VAR(16);
-	TEST_CASTABLE_TO_TYPE_VAR(32);
-#if BITS_PER_LONG == 64
-	TEST_CASTABLE_TO_TYPE_VAR(64);
-#endif
-
-	TEST_CASTABLE_TO_TYPE_RANGE(8);
-	TEST_CASTABLE_TO_TYPE_RANGE(16);
-#if BITS_PER_LONG == 64
-	TEST_CASTABLE_TO_TYPE_RANGE(32);
-#endif
-	kunit_info(test, "%d castable_to_type() tests finished\n", count);
-
-#undef TEST_CASTABLE_TO_TYPE_RANGE
-#undef TEST_CASTABLE_TO_TYPE_VAR
-#undef TEST_CASTABLE_TO_TYPE
-}
-
-struct foo {
-	int a;
-	u32 counter;
-	s16 array[] __counted_by(counter);
-};
-
-struct bar {
-	int a;
-	u32 counter;
-	s16 array[];
-};
-
-static void DEFINE_FLEX_test(struct kunit *test)
-{
-	/* Using _RAW_ on a __counted_by struct will initialize "counter" to zero */
-	DEFINE_RAW_FLEX(struct foo, two_but_zero, array, 2);
-#if __has_attribute(__counted_by__)
-	int expected_raw_size = sizeof(struct foo);
-#else
-	int expected_raw_size = sizeof(struct foo) + 2 * sizeof(s16);
-#endif
-	/* Without annotation, it will always be on-stack size. */
-	DEFINE_RAW_FLEX(struct bar, two, array, 2);
-	DEFINE_FLEX(struct foo, eight, array, counter, 8);
-	DEFINE_FLEX(struct foo, empty, array, counter, 0);
-
-	KUNIT_EXPECT_EQ(test, __struct_size(two_but_zero), expected_raw_size);
-	KUNIT_EXPECT_EQ(test, __struct_size(two), sizeof(struct bar) + 2 * sizeof(s16));
-	KUNIT_EXPECT_EQ(test, __struct_size(eight), 24);
-	KUNIT_EXPECT_EQ(test, __struct_size(empty), sizeof(struct foo));
-}
-
-static struct kunit_case overflow_test_cases[] = {
-	KUNIT_CASE(u8_u8__u8_overflow_test),
-	KUNIT_CASE(s8_s8__s8_overflow_test),
-	KUNIT_CASE(u16_u16__u16_overflow_test),
-	KUNIT_CASE(s16_s16__s16_overflow_test),
-	KUNIT_CASE(u32_u32__u32_overflow_test),
-	KUNIT_CASE(s32_s32__s32_overflow_test),
-	KUNIT_CASE(u64_u64__u64_overflow_test),
-	KUNIT_CASE(s64_s64__s64_overflow_test),
-	KUNIT_CASE(u32_u32__int_overflow_test),
-	KUNIT_CASE(u32_u32__u8_overflow_test),
-	KUNIT_CASE(u8_u8__int_overflow_test),
-	KUNIT_CASE(int_int__u8_overflow_test),
-	KUNIT_CASE(shift_sane_test),
-	KUNIT_CASE(shift_overflow_test),
-	KUNIT_CASE(shift_truncate_test),
-	KUNIT_CASE(shift_nonsense_test),
-	KUNIT_CASE(overflow_allocation_test),
-	KUNIT_CASE(overflow_size_helpers_test),
-	KUNIT_CASE(overflows_type_test),
-	KUNIT_CASE(same_type_test),
-	KUNIT_CASE(castable_to_type_test),
-	KUNIT_CASE(DEFINE_FLEX_test),
-	{}
-};
-
-static struct kunit_suite overflow_test_suite = {
-	.name = "overflow",
-	.test_cases = overflow_test_cases,
-};
-
-kunit_test_suite(overflow_test_suite);
-
-MODULE_DESCRIPTION("Test cases for arithmetic overflow checks");
-MODULE_LICENSE("Dual MIT/GPL");
diff --git a/lib/siphash_kunit.c a/lib/siphash_kunit.c
deleted file mode 100644
--- a/lib/siphash_kunit.c
+++ /dev/null
@@ -1,198 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
-/* Copyright (C) 2016-2022 Jason A. Donenfeld <Jason@xxxxxxxxx>. All Rights Reserved.
- *
- * Test cases for siphash.c
- *
- * SipHash: a fast short-input PRF
- * https://131002.net/siphash/
- *
- * This implementation is specifically for SipHash2-4 for a secure PRF
- * and HalfSipHash1-3/SipHash1-3 for an insecure PRF only suitable for
- * hashtables.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <kunit/test.h>
-#include <linux/siphash.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/module.h>
-
-/* Test vectors taken from reference source available at:
- *     https://github.com/veorq/SipHash
- */
-
-static const siphash_key_t test_key_siphash =
-	{{ 0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL }};
-
-static const u64 test_vectors_siphash[64] = {
-	0x726fdb47dd0e0e31ULL, 0x74f839c593dc67fdULL, 0x0d6c8009d9a94f5aULL,
-	0x85676696d7fb7e2dULL, 0xcf2794e0277187b7ULL, 0x18765564cd99a68dULL,
-	0xcbc9466e58fee3ceULL, 0xab0200f58b01d137ULL, 0x93f5f5799a932462ULL,
-	0x9e0082df0ba9e4b0ULL, 0x7a5dbbc594ddb9f3ULL, 0xf4b32f46226bada7ULL,
-	0x751e8fbc860ee5fbULL, 0x14ea5627c0843d90ULL, 0xf723ca908e7af2eeULL,
-	0xa129ca6149be45e5ULL, 0x3f2acc7f57c29bdbULL, 0x699ae9f52cbe4794ULL,
-	0x4bc1b3f0968dd39cULL, 0xbb6dc91da77961bdULL, 0xbed65cf21aa2ee98ULL,
-	0xd0f2cbb02e3b67c7ULL, 0x93536795e3a33e88ULL, 0xa80c038ccd5ccec8ULL,
-	0xb8ad50c6f649af94ULL, 0xbce192de8a85b8eaULL, 0x17d835b85bbb15f3ULL,
-	0x2f2e6163076bcfadULL, 0xde4daaaca71dc9a5ULL, 0xa6a2506687956571ULL,
-	0xad87a3535c49ef28ULL, 0x32d892fad841c342ULL, 0x7127512f72f27cceULL,
-	0xa7f32346f95978e3ULL, 0x12e0b01abb051238ULL, 0x15e034d40fa197aeULL,
-	0x314dffbe0815a3b4ULL, 0x027990f029623981ULL, 0xcadcd4e59ef40c4dULL,
-	0x9abfd8766a33735cULL, 0x0e3ea96b5304a7d0ULL, 0xad0c42d6fc585992ULL,
-	0x187306c89bc215a9ULL, 0xd4a60abcf3792b95ULL, 0xf935451de4f21df2ULL,
-	0xa9538f0419755787ULL, 0xdb9acddff56ca510ULL, 0xd06c98cd5c0975ebULL,
-	0xe612a3cb9ecba951ULL, 0xc766e62cfcadaf96ULL, 0xee64435a9752fe72ULL,
-	0xa192d576b245165aULL, 0x0a8787bf8ecb74b2ULL, 0x81b3e73d20b49b6fULL,
-	0x7fa8220ba3b2eceaULL, 0x245731c13ca42499ULL, 0xb78dbfaf3a8d83bdULL,
-	0xea1ad565322a1a0bULL, 0x60e61c23a3795013ULL, 0x6606d7e446282b93ULL,
-	0x6ca4ecb15c5f91e1ULL, 0x9f626da15c9625f3ULL, 0xe51b38608ef25f57ULL,
-	0x958a324ceb064572ULL
-};
-
-#if BITS_PER_LONG == 64
-static const hsiphash_key_t test_key_hsiphash =
-	{{ 0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL }};
-
-static const u32 test_vectors_hsiphash[64] = {
-	0x050fc4dcU, 0x7d57ca93U, 0x4dc7d44dU,
-	0xe7ddf7fbU, 0x88d38328U, 0x49533b67U,
-	0xc59f22a7U, 0x9bb11140U, 0x8d299a8eU,
-	0x6c063de4U, 0x92ff097fU, 0xf94dc352U,
-	0x57b4d9a2U, 0x1229ffa7U, 0xc0f95d34U,
-	0x2a519956U, 0x7d908b66U, 0x63dbd80cU,
-	0xb473e63eU, 0x8d297d1cU, 0xa6cce040U,
-	0x2b45f844U, 0xa320872eU, 0xdae6c123U,
-	0x67349c8cU, 0x705b0979U, 0xca9913a5U,
-	0x4ade3b35U, 0xef6cd00dU, 0x4ab1e1f4U,
-	0x43c5e663U, 0x8c21d1bcU, 0x16a7b60dU,
-	0x7a8ff9bfU, 0x1f2a753eU, 0xbf186b91U,
-	0xada26206U, 0xa3c33057U, 0xae3a36a1U,
-	0x7b108392U, 0x99e41531U, 0x3f1ad944U,
-	0xc8138825U, 0xc28949a6U, 0xfaf8876bU,
-	0x9f042196U, 0x68b1d623U, 0x8b5114fdU,
-	0xdf074c46U, 0x12cc86b3U, 0x0a52098fU,
-	0x9d292f9aU, 0xa2f41f12U, 0x43a71ed0U,
-	0x73f0bce6U, 0x70a7e980U, 0x243c6d75U,
-	0xfdb71513U, 0xa67d8a08U, 0xb7e8f148U,
-	0xf7a644eeU, 0x0f1837f2U, 0x4b6694e0U,
-	0xb7bbb3a8U
-};
-#else
-static const hsiphash_key_t test_key_hsiphash =
-	{{ 0x03020100U, 0x07060504U }};
-
-static const u32 test_vectors_hsiphash[64] = {
-	0x5814c896U, 0xe7e864caU, 0xbc4b0e30U,
-	0x01539939U, 0x7e059ea6U, 0x88e3d89bU,
-	0xa0080b65U, 0x9d38d9d6U, 0x577999b1U,
-	0xc839caedU, 0xe4fa32cfU, 0x959246eeU,
-	0x6b28096cU, 0x66dd9cd6U, 0x16658a7cU,
-	0xd0257b04U, 0x8b31d501U, 0x2b1cd04bU,
-	0x06712339U, 0x522aca67U, 0x911bb605U,
-	0x90a65f0eU, 0xf826ef7bU, 0x62512debU,
-	0x57150ad7U, 0x5d473507U, 0x1ec47442U,
-	0xab64afd3U, 0x0a4100d0U, 0x6d2ce652U,
-	0x2331b6a3U, 0x08d8791aU, 0xbc6dda8dU,
-	0xe0f6c934U, 0xb0652033U, 0x9b9851ccU,
-	0x7c46fb7fU, 0x732ba8cbU, 0xf142997aU,
-	0xfcc9aa1bU, 0x05327eb2U, 0xe110131cU,
-	0xf9e5e7c0U, 0xa7d708a6U, 0x11795ab1U,
-	0x65671619U, 0x9f5fff91U, 0xd89c5267U,
-	0x007783ebU, 0x95766243U, 0xab639262U,
-	0x9c7e1390U, 0xc368dda6U, 0x38ddc455U,
-	0xfa13d379U, 0x979ea4e8U, 0x53ecd77eU,
-	0x2ee80657U, 0x33dbb66aU, 0xae3f0577U,
-	0x88b4c4ccU, 0x3e7f480bU, 0x74c1ebf8U,
-	0x87178304U
-};
-#endif
-
-#define chk(hash, vector, fmt...)			\
-	KUNIT_EXPECT_EQ_MSG(test, hash, vector, fmt)
-
-static void siphash_test(struct kunit *test)
-{
-	u8 in[64] __aligned(SIPHASH_ALIGNMENT);
-	u8 in_unaligned[65] __aligned(SIPHASH_ALIGNMENT);
-	u8 i;
-
-	for (i = 0; i < 64; ++i) {
-		in[i] = i;
-		in_unaligned[i + 1] = i;
-		chk(siphash(in, i, &test_key_siphash),
-		    test_vectors_siphash[i],
-		    "siphash self-test aligned %u: FAIL", i + 1);
-		chk(siphash(in_unaligned + 1, i, &test_key_siphash),
-		    test_vectors_siphash[i],
-		    "siphash self-test unaligned %u: FAIL", i + 1);
-		chk(hsiphash(in, i, &test_key_hsiphash),
-		    test_vectors_hsiphash[i],
-		    "hsiphash self-test aligned %u: FAIL", i + 1);
-		chk(hsiphash(in_unaligned + 1, i, &test_key_hsiphash),
-		    test_vectors_hsiphash[i],
-		    "hsiphash self-test unaligned %u: FAIL", i + 1);
-	}
-	chk(siphash_1u64(0x0706050403020100ULL, &test_key_siphash),
-	    test_vectors_siphash[8],
-	    "siphash self-test 1u64: FAIL");
-	chk(siphash_2u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
-			 &test_key_siphash),
-	    test_vectors_siphash[16],
-	    "siphash self-test 2u64: FAIL");
-	chk(siphash_3u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
-			 0x1716151413121110ULL, &test_key_siphash),
-	    test_vectors_siphash[24],
-	    "siphash self-test 3u64: FAIL");
-	chk(siphash_4u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
-			 0x1716151413121110ULL, 0x1f1e1d1c1b1a1918ULL,
-			 &test_key_siphash),
-	    test_vectors_siphash[32],
-	    "siphash self-test 4u64: FAIL");
-	chk(siphash_1u32(0x03020100U, &test_key_siphash),
-	    test_vectors_siphash[4],
-	    "siphash self-test 1u32: FAIL");
-	chk(siphash_2u32(0x03020100U, 0x07060504U, &test_key_siphash),
-	    test_vectors_siphash[8],
-	    "siphash self-test 2u32: FAIL");
-	chk(siphash_3u32(0x03020100U, 0x07060504U,
-			 0x0b0a0908U, &test_key_siphash),
-	    test_vectors_siphash[12],
-	    "siphash self-test 3u32: FAIL");
-	chk(siphash_4u32(0x03020100U, 0x07060504U,
-			 0x0b0a0908U, 0x0f0e0d0cU, &test_key_siphash),
-	    test_vectors_siphash[16],
-	    "siphash self-test 4u32: FAIL");
-	chk(hsiphash_1u32(0x03020100U, &test_key_hsiphash),
-	    test_vectors_hsiphash[4],
-	    "hsiphash self-test 1u32: FAIL");
-	chk(hsiphash_2u32(0x03020100U, 0x07060504U, &test_key_hsiphash),
-	    test_vectors_hsiphash[8],
-	    "hsiphash self-test 2u32: FAIL");
-	chk(hsiphash_3u32(0x03020100U, 0x07060504U,
-			  0x0b0a0908U, &test_key_hsiphash),
-	    test_vectors_hsiphash[12],
-	    "hsiphash self-test 3u32: FAIL");
-	chk(hsiphash_4u32(0x03020100U, 0x07060504U,
-			  0x0b0a0908U, 0x0f0e0d0cU, &test_key_hsiphash),
-	    test_vectors_hsiphash[16],
-	    "hsiphash self-test 4u32: FAIL");
-}
-
-static struct kunit_case siphash_test_cases[] = {
-	KUNIT_CASE(siphash_test),
-	{}
-};
-
-static struct kunit_suite siphash_test_suite = {
-	.name = "siphash",
-	.test_cases = siphash_test_cases,
-};
-
-kunit_test_suite(siphash_test_suite);
-
-MODULE_AUTHOR("Jason A. Donenfeld <Jason@xxxxxxxxx>");
-MODULE_DESCRIPTION("Test cases for siphash.c");
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/lib/slub_kunit.c a/lib/slub_kunit.c
deleted file mode 100644
--- a/lib/slub_kunit.c
+++ /dev/null
@@ -1,227 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <kunit/test.h>
-#include <kunit/test-bug.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/rcupdate.h>
-#include "../mm/slab.h"
-
-static struct kunit_resource resource;
-static int slab_errors;
-
-/*
- * Wrapper function for kmem_cache_create(), which reduces 2 parameters:
- * 'align' and 'ctor', and sets SLAB_SKIP_KFENCE flag to avoid getting an
- * object from kfence pool, where the operation could be caught by both
- * our test and kfence sanity check.
- */
-static struct kmem_cache *test_kmem_cache_create(const char *name,
-				unsigned int size, slab_flags_t flags)
-{
-	struct kmem_cache *s = kmem_cache_create(name, size, 0,
-					(flags | SLAB_NO_USER_FLAGS), NULL);
-	s->flags |= SLAB_SKIP_KFENCE;
-	return s;
-}
-
-static void test_clobber_zone(struct kunit *test)
-{
-	struct kmem_cache *s = test_kmem_cache_create("TestSlub_RZ_alloc", 64,
-							SLAB_RED_ZONE);
-	u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
-
-	kasan_disable_current();
-	p[64] = 0x12;
-
-	validate_slab_cache(s);
-	KUNIT_EXPECT_EQ(test, 2, slab_errors);
-
-	kasan_enable_current();
-	kmem_cache_free(s, p);
-	kmem_cache_destroy(s);
-}
-
-#ifndef CONFIG_KASAN
-static void test_next_pointer(struct kunit *test)
-{
-	struct kmem_cache *s = test_kmem_cache_create("TestSlub_next_ptr_free",
-							64, SLAB_POISON);
-	u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
-	unsigned long tmp;
-	unsigned long *ptr_addr;
-
-	kmem_cache_free(s, p);
-
-	ptr_addr = (unsigned long *)(p + s->offset);
-	tmp = *ptr_addr;
-	p[s->offset] = ~p[s->offset];
-
-	/*
-	 * Expecting three errors.
-	 * One for the corrupted freechain and the other one for the wrong
-	 * count of objects in use. The third error is fixing broken cache.
-	 */
-	validate_slab_cache(s);
-	KUNIT_EXPECT_EQ(test, 3, slab_errors);
-
-	/*
-	 * Try to repair corrupted freepointer.
-	 * Still expecting two errors. The first for the wrong count
-	 * of objects in use.
-	 * The second error is for fixing broken cache.
-	 */
-	*ptr_addr = tmp;
-	slab_errors = 0;
-
-	validate_slab_cache(s);
-	KUNIT_EXPECT_EQ(test, 2, slab_errors);
-
-	/*
-	 * Previous validation repaired the count of objects in use.
-	 * Now expecting no error.
-	 */
-	slab_errors = 0;
-	validate_slab_cache(s);
-	KUNIT_EXPECT_EQ(test, 0, slab_errors);
-
-	kmem_cache_destroy(s);
-}
-
-static void test_first_word(struct kunit *test)
-{
-	struct kmem_cache *s = test_kmem_cache_create("TestSlub_1th_word_free",
-							64, SLAB_POISON);
-	u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
-
-	kmem_cache_free(s, p);
-	*p = 0x78;
-
-	validate_slab_cache(s);
-	KUNIT_EXPECT_EQ(test, 2, slab_errors);
-
-	kmem_cache_destroy(s);
-}
-
-static void test_clobber_50th_byte(struct kunit *test)
-{
-	struct kmem_cache *s = test_kmem_cache_create("TestSlub_50th_word_free",
-							64, SLAB_POISON);
-	u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
-
-	kmem_cache_free(s, p);
-	p[50] = 0x9a;
-
-	validate_slab_cache(s);
-	KUNIT_EXPECT_EQ(test, 2, slab_errors);
-
-	kmem_cache_destroy(s);
-}
-#endif
-
-static void test_clobber_redzone_free(struct kunit *test)
-{
-	struct kmem_cache *s = test_kmem_cache_create("TestSlub_RZ_free", 64,
-							SLAB_RED_ZONE);
-	u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
-
-	kasan_disable_current();
-	kmem_cache_free(s, p);
-	p[64] = 0xab;
-
-	validate_slab_cache(s);
-	KUNIT_EXPECT_EQ(test, 2, slab_errors);
-
-	kasan_enable_current();
-	kmem_cache_destroy(s);
-}
-
-static void test_kmalloc_redzone_access(struct kunit *test)
-{
-	struct kmem_cache *s = test_kmem_cache_create("TestSlub_RZ_kmalloc", 32,
-				SLAB_KMALLOC|SLAB_STORE_USER|SLAB_RED_ZONE);
-	u8 *p = __kmalloc_cache_noprof(s, GFP_KERNEL, 18);
-
-	kasan_disable_current();
-
-	/* Suppress the -Warray-bounds warning */
-	OPTIMIZER_HIDE_VAR(p);
-	p[18] = 0xab;
-	p[19] = 0xab;
-
-	validate_slab_cache(s);
-	KUNIT_EXPECT_EQ(test, 2, slab_errors);
-
-	kasan_enable_current();
-	kmem_cache_free(s, p);
-	kmem_cache_destroy(s);
-}
-
-struct test_kfree_rcu_struct {
-	struct rcu_head rcu;
-};
-
-static void test_kfree_rcu(struct kunit *test)
-{
-	struct kmem_cache *s;
-	struct test_kfree_rcu_struct *p;
-
-	if (IS_BUILTIN(CONFIG_SLUB_KUNIT_TEST))
-		kunit_skip(test, "can't do kfree_rcu() when test is built-in");
-
-	s = test_kmem_cache_create("TestSlub_kfree_rcu",
-				   sizeof(struct test_kfree_rcu_struct),
-				   SLAB_NO_MERGE);
-	p = kmem_cache_alloc(s, GFP_KERNEL);
-
-	kfree_rcu(p, rcu);
-	kmem_cache_destroy(s);
-
-	KUNIT_EXPECT_EQ(test, 0, slab_errors);
-}
-
-static void test_leak_destroy(struct kunit *test)
-{
-	struct kmem_cache *s = test_kmem_cache_create("TestSlub_leak_destroy",
-							64, SLAB_NO_MERGE);
-	kmem_cache_alloc(s, GFP_KERNEL);
-
-	kmem_cache_destroy(s);
-
-	KUNIT_EXPECT_EQ(test, 2, slab_errors);
-}
-
-static int test_init(struct kunit *test)
-{
-	slab_errors = 0;
-
-	kunit_add_named_resource(test, NULL, NULL, &resource,
-					"slab_errors", &slab_errors);
-	return 0;
-}
-
-static struct kunit_case test_cases[] = {
-	KUNIT_CASE(test_clobber_zone),
-
-#ifndef CONFIG_KASAN
-	KUNIT_CASE(test_next_pointer),
-	KUNIT_CASE(test_first_word),
-	KUNIT_CASE(test_clobber_50th_byte),
-#endif
-
-	KUNIT_CASE(test_clobber_redzone_free),
-	KUNIT_CASE(test_kmalloc_redzone_access),
-	KUNIT_CASE(test_kfree_rcu),
-	KUNIT_CASE(test_leak_destroy),
-	{}
-};
-
-static struct kunit_suite test_suite = {
-	.name = "slub_test",
-	.init = test_init,
-	.test_cases = test_cases,
-};
-kunit_test_suite(test_suite);
-
-MODULE_LICENSE("GPL");
diff --git a/lib/stackinit_kunit.c a/lib/stackinit_kunit.c
deleted file mode 100644
--- a/lib/stackinit_kunit.c
+++ /dev/null
@@ -1,475 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Test cases for compiler-based stack variable zeroing via
- * -ftrivial-auto-var-init={zero,pattern} or CONFIG_GCC_PLUGIN_STRUCTLEAK*.
- * For example, see:
- * "Running tests with kunit_tool" at Documentation/dev-tools/kunit/start.rst
- *	./tools/testing/kunit/kunit.py run stackinit [--raw_output] \
- *		--make_option LLVM=1 \
- *		--kconfig_add CONFIG_INIT_STACK_ALL_ZERO=y
- *
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <kunit/test.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/string.h>
-
-/* Exfiltration buffer. */
-#define MAX_VAR_SIZE	128
-static u8 check_buf[MAX_VAR_SIZE];
-
-/* Character array to trigger stack protector in all functions. */
-#define VAR_BUFFER	 32
-
-/* Volatile mask to convince compiler to copy memory with 0xff. */
-static volatile u8 forced_mask = 0xff;
-
-/* Location and size tracking to validate fill and test are colocated. */
-static void *fill_start, *target_start;
-static size_t fill_size, target_size;
-
-static bool stackinit_range_contains(char *haystack_start, size_t haystack_size,
-				     char *needle_start, size_t needle_size)
-{
-	if (needle_start >= haystack_start &&
-	    needle_start + needle_size <= haystack_start + haystack_size)
-		return true;
-	return false;
-}
-
-/* Whether the test is expected to fail. */
-#define WANT_SUCCESS				0
-#define XFAIL					1
-
-#define DO_NOTHING_TYPE_SCALAR(var_type)	var_type
-#define DO_NOTHING_TYPE_STRING(var_type)	void
-#define DO_NOTHING_TYPE_STRUCT(var_type)	void
-
-#define DO_NOTHING_RETURN_SCALAR(ptr)		*(ptr)
-#define DO_NOTHING_RETURN_STRING(ptr)		/**/
-#define DO_NOTHING_RETURN_STRUCT(ptr)		/**/
-
-#define DO_NOTHING_CALL_SCALAR(var, name)			\
-		(var) = do_nothing_ ## name(&(var))
-#define DO_NOTHING_CALL_STRING(var, name)			\
-		do_nothing_ ## name(var)
-#define DO_NOTHING_CALL_STRUCT(var, name)			\
-		do_nothing_ ## name(&(var))
-
-#define FETCH_ARG_SCALAR(var)		&var
-#define FETCH_ARG_STRING(var)		var
-#define FETCH_ARG_STRUCT(var)		&var
-
-/*
- * On m68k, if the leaf function test variable is longer than 8 bytes,
- * the start of the stack frame moves. 8 is sufficiently large to
- * test m68k char arrays, but leave it at 16 for other architectures.
- */
-#ifdef CONFIG_M68K
-#define FILL_SIZE_STRING		8
-#else
-#define FILL_SIZE_STRING		16
-#endif
-
-#define INIT_CLONE_SCALAR		/**/
-#define INIT_CLONE_STRING		[FILL_SIZE_STRING]
-#define INIT_CLONE_STRUCT		/**/
-
-#define ZERO_CLONE_SCALAR(zero)		memset(&(zero), 0x00, sizeof(zero))
-#define ZERO_CLONE_STRING(zero)		memset(&(zero), 0x00, sizeof(zero))
-/*
- * For the struct, intentionally poison padding to see if it gets
- * copied out in direct assignments.
- * */
-#define ZERO_CLONE_STRUCT(zero)				\
-	do {						\
-		memset(&(zero), 0xFF, sizeof(zero));	\
-		zero.one = 0;				\
-		zero.two = 0;				\
-		zero.three = 0;				\
-		zero.four = 0;				\
-	} while (0)
-
-#define INIT_SCALAR_none(var_type)	/**/
-#define INIT_SCALAR_zero(var_type)	= 0
-
-#define INIT_STRING_none(var_type)	[FILL_SIZE_STRING] /**/
-#define INIT_STRING_zero(var_type)	[FILL_SIZE_STRING] = { }
-
-#define INIT_STRUCT_none(var_type)	/**/
-#define INIT_STRUCT_zero(var_type)	= { }
-
-
-#define __static_partial		{ .two = 0, }
-#define __static_all			{ .one = 0,			\
-					  .two = 0,			\
-					  .three = 0,			\
-					  .four = 0,			\
-					}
-#define __dynamic_partial		{ .two = arg->two, }
-#define __dynamic_all			{ .one = arg->one,		\
-					  .two = arg->two,		\
-					  .three = arg->three,		\
-					  .four = arg->four,		\
-					}
-#define __runtime_partial		var.two = 0
-#define __runtime_all			var.one = 0;			\
-					var.two = 0;			\
-					var.three = 0;			\
-					var.four = 0
-
-#define INIT_STRUCT_static_partial(var_type)				\
-					= __static_partial
-#define INIT_STRUCT_static_all(var_type)				\
-					= __static_all
-#define INIT_STRUCT_dynamic_partial(var_type)				\
-					= __dynamic_partial
-#define INIT_STRUCT_dynamic_all(var_type)				\
-					= __dynamic_all
-#define INIT_STRUCT_runtime_partial(var_type)				\
-					; __runtime_partial
-#define INIT_STRUCT_runtime_all(var_type)				\
-					; __runtime_all
-
-#define INIT_STRUCT_assigned_static_partial(var_type)			\
-					; var = (var_type)__static_partial
-#define INIT_STRUCT_assigned_static_all(var_type)			\
-					; var = (var_type)__static_all
-#define INIT_STRUCT_assigned_dynamic_partial(var_type)			\
-					; var = (var_type)__dynamic_partial
-#define INIT_STRUCT_assigned_dynamic_all(var_type)			\
-					; var = (var_type)__dynamic_all
-
-#define INIT_STRUCT_assigned_copy(var_type)				\
-					; var = *(arg)
-
-/*
- * @name: unique string name for the test
- * @var_type: type to be tested for zeroing initialization
- * @which: is this a SCALAR, STRING, or STRUCT type?
- * @init_level: what kind of initialization is performed
- * @xfail: is this test expected to fail?
- */
-#define DEFINE_TEST_DRIVER(name, var_type, which, xfail)	\
-/* Returns 0 on success, 1 on failure. */			\
-static noinline void test_ ## name (struct kunit *test)		\
-{								\
-	var_type zero INIT_CLONE_ ## which;			\
-	int ignored;						\
-	u8 sum = 0, i;						\
-								\
-	/* Notice when a new test is larger than expected. */	\
-	BUILD_BUG_ON(sizeof(zero) > MAX_VAR_SIZE);		\
-								\
-	/* Fill clone type with zero for per-field init. */	\
-	ZERO_CLONE_ ## which(zero);				\
-	/* Clear entire check buffer for 0xFF overlap test. */	\
-	memset(check_buf, 0x00, sizeof(check_buf));		\
-	/* Fill stack with 0xFF. */				\
-	ignored = leaf_ ##name((unsigned long)&ignored, 1,	\
-				FETCH_ARG_ ## which(zero));	\
-	/* Verify all bytes overwritten with 0xFF. */		\
-	for (sum = 0, i = 0; i < target_size; i++)		\
-		sum += (check_buf[i] != 0xFF);			\
-	/* Clear entire check buffer for later bit tests. */	\
-	memset(check_buf, 0x00, sizeof(check_buf));		\
-	/* Extract stack-defined variable contents. */		\
-	ignored = leaf_ ##name((unsigned long)&ignored, 0,	\
-				FETCH_ARG_ ## which(zero));	\
-	/*							\
-	 * Delay the sum test to here to do as little as	\
-	 * possible between the two leaf function calls.	\
-	 */							\
-	KUNIT_ASSERT_EQ_MSG(test, sum, 0,			\
-			    "leaf fill was not 0xFF!?\n");	\
-								\
-	/* Validate that compiler lined up fill and target. */	\
-	KUNIT_ASSERT_TRUE_MSG(test,				\
-		stackinit_range_contains(fill_start, fill_size,	\
-			    target_start, target_size),		\
-		"stackframe was not the same between calls!? "	\
-		"(fill %zu wide, target offset by %d)\n",	\
-		fill_size,					\
-		(int)((ssize_t)(uintptr_t)fill_start -		\
-		      (ssize_t)(uintptr_t)target_start));	\
-								\
-	/* Look for any bytes still 0xFF in check region. */	\
-	for (sum = 0, i = 0; i < target_size; i++)		\
-		sum += (check_buf[i] == 0xFF);			\
-								\
-	if (sum != 0 && xfail)					\
-		kunit_skip(test,				\
-			   "XFAIL uninit bytes: %d\n",		\
-			   sum);				\
-	KUNIT_ASSERT_EQ_MSG(test, sum, 0,			\
-		"uninit bytes: %d\n", sum);			\
-}
-#define DEFINE_TEST(name, var_type, which, init_level, xfail)	\
-/* no-op to force compiler into ignoring "uninitialized" vars */\
-static noinline DO_NOTHING_TYPE_ ## which(var_type)		\
-do_nothing_ ## name(var_type *ptr)				\
-{								\
-	/* Will always be true, but compiler doesn't know. */	\
-	if ((unsigned long)ptr > 0x2)				\
-		return DO_NOTHING_RETURN_ ## which(ptr);	\
-	else							\
-		return DO_NOTHING_RETURN_ ## which(ptr + 1);	\
-}								\
-static noinline int leaf_ ## name(unsigned long sp, bool fill,	\
-				  var_type *arg)		\
-{								\
-	char buf[VAR_BUFFER];					\
-	var_type var						\
-		INIT_ ## which ## _ ## init_level(var_type);	\
-								\
-	target_start = &var;					\
-	target_size = sizeof(var);				\
-	/*							\
-	 * Keep this buffer around to make sure we've got a	\
-	 * stack frame of SOME kind...				\
-	 */							\
-	memset(buf, (char)(sp & 0xff), sizeof(buf));		\
-	/* Fill variable with 0xFF. */				\
-	if (fill) {						\
-		fill_start = &var;				\
-		fill_size = sizeof(var);			\
-		memset(fill_start,				\
-		       (char)((sp & 0xff) | forced_mask),	\
-		       fill_size);				\
-	}							\
-								\
-	/* Silence "never initialized" warnings. */		\
-	DO_NOTHING_CALL_ ## which(var, name);			\
-								\
-	/* Exfiltrate "var". */					\
-	memcpy(check_buf, target_start, target_size);		\
-								\
-	return (int)buf[0] | (int)buf[sizeof(buf) - 1];		\
-}								\
-DEFINE_TEST_DRIVER(name, var_type, which, xfail)
-
-/* Structure with no padding. */
-struct test_packed {
-	unsigned long one;
-	unsigned long two;
-	unsigned long three;
-	unsigned long four;
-};
-
-/* Simple structure with padding likely to be covered by compiler. */
-struct test_small_hole {
-	size_t one;
-	char two;
-	/* 3 byte padding hole here. */
-	int three;
-	unsigned long four;
-};
-
-/* Trigger unhandled padding in a structure. */
-struct test_big_hole {
-	u8 one;
-	u8 two;
-	u8 three;
-	/* 61 byte padding hole here. */
-	u8 four __aligned(64);
-} __aligned(64);
-
-struct test_trailing_hole {
-	char *one;
-	char *two;
-	char *three;
-	char four;
-	/* "sizeof(unsigned long) - 1" byte padding hole here. */
-};
-
-/* Test if STRUCTLEAK is clearing structs with __user fields. */
-struct test_user {
-	u8 one;
-	unsigned long two;
-	char __user *three;
-	unsigned long four;
-};
-
-#define ALWAYS_PASS	WANT_SUCCESS
-#define ALWAYS_FAIL	XFAIL
-
-#ifdef CONFIG_INIT_STACK_NONE
-# define USER_PASS	XFAIL
-# define BYREF_PASS	XFAIL
-# define STRONG_PASS	XFAIL
-#elif defined(CONFIG_GCC_PLUGIN_STRUCTLEAK_USER)
-# define USER_PASS	WANT_SUCCESS
-# define BYREF_PASS	XFAIL
-# define STRONG_PASS	XFAIL
-#elif defined(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF)
-# define USER_PASS	WANT_SUCCESS
-# define BYREF_PASS	WANT_SUCCESS
-# define STRONG_PASS	XFAIL
-#else
-# define USER_PASS	WANT_SUCCESS
-# define BYREF_PASS	WANT_SUCCESS
-# define STRONG_PASS	WANT_SUCCESS
-#endif
-
-#define DEFINE_SCALAR_TEST(name, init, xfail)			\
-		DEFINE_TEST(name ## _ ## init, name, SCALAR,	\
-			    init, xfail)
-
-#define DEFINE_SCALAR_TESTS(init, xfail)			\
-		DEFINE_SCALAR_TEST(u8, init, xfail);		\
-		DEFINE_SCALAR_TEST(u16, init, xfail);		\
-		DEFINE_SCALAR_TEST(u32, init, xfail);		\
-		DEFINE_SCALAR_TEST(u64, init, xfail);		\
-		DEFINE_TEST(char_array_ ## init, unsigned char,	\
-			    STRING, init, xfail)
-
-#define DEFINE_STRUCT_TEST(name, init, xfail)			\
-		DEFINE_TEST(name ## _ ## init,			\
-			    struct test_ ## name, STRUCT, init, \
-			    xfail)
-
-#define DEFINE_STRUCT_TESTS(init, xfail)			\
-		DEFINE_STRUCT_TEST(small_hole, init, xfail);	\
-		DEFINE_STRUCT_TEST(big_hole, init, xfail);	\
-		DEFINE_STRUCT_TEST(trailing_hole, init, xfail);	\
-		DEFINE_STRUCT_TEST(packed, init, xfail)
-
-#define DEFINE_STRUCT_INITIALIZER_TESTS(base, xfail)		\
-		DEFINE_STRUCT_TESTS(base ## _ ## partial,	\
-				    xfail);			\
-		DEFINE_STRUCT_TESTS(base ## _ ## all, xfail)
-
-/* These should be fully initialized all the time! */
-DEFINE_SCALAR_TESTS(zero, ALWAYS_PASS);
-DEFINE_STRUCT_TESTS(zero, ALWAYS_PASS);
-/* Struct initializers: padding may be left uninitialized. */
-DEFINE_STRUCT_INITIALIZER_TESTS(static, STRONG_PASS);
-DEFINE_STRUCT_INITIALIZER_TESTS(dynamic, STRONG_PASS);
-DEFINE_STRUCT_INITIALIZER_TESTS(runtime, STRONG_PASS);
-DEFINE_STRUCT_INITIALIZER_TESTS(assigned_static, STRONG_PASS);
-DEFINE_STRUCT_INITIALIZER_TESTS(assigned_dynamic, STRONG_PASS);
-DEFINE_STRUCT_TESTS(assigned_copy, ALWAYS_FAIL);
-/* No initialization without compiler instrumentation. */
-DEFINE_SCALAR_TESTS(none, STRONG_PASS);
-DEFINE_STRUCT_TESTS(none, BYREF_PASS);
-/* Initialization of members with __user attribute. */
-DEFINE_TEST(user, struct test_user, STRUCT, none, USER_PASS);
-
-/*
- * Check two uses through a variable declaration outside either path,
- * which was noticed as a special case in porting earlier stack init
- * compiler logic.
- */
-static int noinline __leaf_switch_none(int path, bool fill)
-{
-	switch (path) {
-		/*
-		 * This is intentionally unreachable. To silence the
-		 * warning, build with -Wno-switch-unreachable
-		 */
-		uint64_t var[10];
-
-	case 1:
-		target_start = &var;
-		target_size = sizeof(var);
-		if (fill) {
-			fill_start = &var;
-			fill_size = sizeof(var);
-
-			memset(fill_start, forced_mask | 0x55, fill_size);
-		}
-		memcpy(check_buf, target_start, target_size);
-		break;
-	case 2:
-		target_start = &var;
-		target_size = sizeof(var);
-		if (fill) {
-			fill_start = &var;
-			fill_size = sizeof(var);
-
-			memset(fill_start, forced_mask | 0xaa, fill_size);
-		}
-		memcpy(check_buf, target_start, target_size);
-		break;
-	default:
-		var[1] = 5;
-		return var[1] & forced_mask;
-	}
-	return 0;
-}
-
-static noinline int leaf_switch_1_none(unsigned long sp, bool fill,
-					      uint64_t *arg)
-{
-	return __leaf_switch_none(1, fill);
-}
-
-static noinline int leaf_switch_2_none(unsigned long sp, bool fill,
-					      uint64_t *arg)
-{
-	return __leaf_switch_none(2, fill);
-}
-
-/*
- * These are expected to fail for most configurations because neither
- * GCC nor Clang have a way to perform initialization of variables in
- * non-code areas (i.e. in a switch statement before the first "case").
- * https://llvm.org/pr44916
- */
-DEFINE_TEST_DRIVER(switch_1_none, uint64_t, SCALAR, ALWAYS_FAIL);
-DEFINE_TEST_DRIVER(switch_2_none, uint64_t, SCALAR, ALWAYS_FAIL);
-
-#define KUNIT_test_scalars(init)			\
-		KUNIT_CASE(test_u8_ ## init),		\
-		KUNIT_CASE(test_u16_ ## init),		\
-		KUNIT_CASE(test_u32_ ## init),		\
-		KUNIT_CASE(test_u64_ ## init),		\
-		KUNIT_CASE(test_char_array_ ## init)
-
-#define KUNIT_test_structs(init)			\
-		KUNIT_CASE(test_small_hole_ ## init),	\
-		KUNIT_CASE(test_big_hole_ ## init),	\
-		KUNIT_CASE(test_trailing_hole_ ## init),\
-		KUNIT_CASE(test_packed_ ## init)	\
-
-static struct kunit_case stackinit_test_cases[] = {
-	/* These are explicitly initialized and should always pass. */
-	KUNIT_test_scalars(zero),
-	KUNIT_test_structs(zero),
-	/* Padding here appears to be accidentally always initialized? */
-	KUNIT_test_structs(dynamic_partial),
-	KUNIT_test_structs(assigned_dynamic_partial),
-	/* Padding initialization depends on compiler behaviors. */
-	KUNIT_test_structs(static_partial),
-	KUNIT_test_structs(static_all),
-	KUNIT_test_structs(dynamic_all),
-	KUNIT_test_structs(runtime_partial),
-	KUNIT_test_structs(runtime_all),
-	KUNIT_test_structs(assigned_static_partial),
-	KUNIT_test_structs(assigned_static_all),
-	KUNIT_test_structs(assigned_dynamic_all),
-	/* Everything fails this since it effectively performs a memcpy(). */
-	KUNIT_test_structs(assigned_copy),
-	/* STRUCTLEAK_BYREF_ALL should cover everything from here down. */
-	KUNIT_test_scalars(none),
-	KUNIT_CASE(test_switch_1_none),
-	KUNIT_CASE(test_switch_2_none),
-	/* STRUCTLEAK_BYREF should cover from here down. */
-	KUNIT_test_structs(none),
-	/* STRUCTLEAK will only cover this. */
-	KUNIT_CASE(test_user),
-	{}
-};
-
-static struct kunit_suite stackinit_test_suite = {
-	.name = "stackinit",
-	.test_cases = stackinit_test_cases,
-};
-
-kunit_test_suites(&stackinit_test_suite);
-
-MODULE_DESCRIPTION("Test cases for compiler-based stack variable zeroing");
-MODULE_LICENSE("GPL");
diff --git a/lib/string_helpers_kunit.c a/lib/string_helpers_kunit.c
deleted file mode 100644
--- a/lib/string_helpers_kunit.c
+++ /dev/null
@@ -1,629 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
-/*
- * Test cases for lib/string_helpers.c module.
- */
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <kunit/test.h>
-#include <linux/array_size.h>
-#include <linux/kernel.h>
-#include <linux/random.h>
-#include <linux/string.h>
-#include <linux/string_helpers.h>
-
-static void test_string_check_buf(struct kunit *test,
-				  const char *name, unsigned int flags,
-				  char *in, size_t p,
-				  char *out_real, size_t q_real,
-				  char *out_test, size_t q_test)
-{
-	KUNIT_ASSERT_EQ_MSG(test, q_real, q_test, "name:%s", name);
-	KUNIT_EXPECT_MEMEQ_MSG(test, out_test, out_real, q_test,
-			       "name:%s", name);
-}
-
-struct test_string {
-	const char *in;
-	const char *out;
-	unsigned int flags;
-};
-
-static const struct test_string strings[] = {
-	{
-		.in = "\\f\\ \\n\\r\\t\\v",
-		.out = "\f\\ \n\r\t\v",
-		.flags = UNESCAPE_SPACE,
-	},
-	{
-		.in = "\\40\\1\\387\\0064\\05\\040\\8a\\110\\777",
-		.out = " \001\00387\0064\005 \\8aH?7",
-		.flags = UNESCAPE_OCTAL,
-	},
-	{
-		.in = "\\xv\\xa\\x2c\\xD\\x6f2",
-		.out = "\\xv\n,\ro2",
-		.flags = UNESCAPE_HEX,
-	},
-	{
-		.in = "\\h\\\\\\\"\\a\\e\\",
-		.out = "\\h\\\"\a\e\\",
-		.flags = UNESCAPE_SPECIAL,
-	},
-};
-
-static void test_string_unescape(struct kunit *test,
-				 const char *name, unsigned int flags,
-				 bool inplace)
-{
-	int q_real = 256;
-	char *in = kunit_kzalloc(test, q_real, GFP_KERNEL);
-	char *out_test = kunit_kzalloc(test, q_real, GFP_KERNEL);
-	char *out_real = kunit_kzalloc(test, q_real, GFP_KERNEL);
-	int i, p = 0, q_test = 0;
-
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, in);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, out_test);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, out_real);
-
-	for (i = 0; i < ARRAY_SIZE(strings); i++) {
-		const char *s = strings[i].in;
-		int len = strlen(strings[i].in);
-
-		/* Copy string to in buffer */
-		memcpy(&in[p], s, len);
-		p += len;
-
-		/* Copy expected result for given flags */
-		if (flags & strings[i].flags) {
-			s = strings[i].out;
-			len = strlen(strings[i].out);
-		}
-		memcpy(&out_test[q_test], s, len);
-		q_test += len;
-	}
-	in[p++] = '\0';
-
-	/* Call string_unescape and compare result */
-	if (inplace) {
-		memcpy(out_real, in, p);
-		if (flags == UNESCAPE_ANY)
-			q_real = string_unescape_any_inplace(out_real);
-		else
-			q_real = string_unescape_inplace(out_real, flags);
-	} else if (flags == UNESCAPE_ANY) {
-		q_real = string_unescape_any(in, out_real, q_real);
-	} else {
-		q_real = string_unescape(in, out_real, q_real, flags);
-	}
-
-	test_string_check_buf(test, name, flags, in, p - 1, out_real, q_real,
-			      out_test, q_test);
-}
-
-struct test_string_1 {
-	const char *out;
-	unsigned int flags;
-};
-
-#define	TEST_STRING_2_MAX_S1		32
-struct test_string_2 {
-	const char *in;
-	struct test_string_1 s1[TEST_STRING_2_MAX_S1];
-};
-
-#define	TEST_STRING_2_DICT_0		NULL
-static const struct test_string_2 escape0[] = {{
-	.in = "\f\\ \n\r\t\v",
-	.s1 = {{
-		.out = "\\f\\ \\n\\r\\t\\v",
-		.flags = ESCAPE_SPACE,
-	},{
-		.out = "\\f\\134\\040\\n\\r\\t\\v",
-		.flags = ESCAPE_SPACE | ESCAPE_OCTAL,
-	},{
-		.out = "\\f\\x5c\\x20\\n\\r\\t\\v",
-		.flags = ESCAPE_SPACE | ESCAPE_HEX,
-	},{
-		/* terminator */
-	}}
-},{
-	.in = "\\h\\\"\a\e\\",
-	.s1 = {{
-		.out = "\\\\h\\\\\\\"\\a\\e\\\\",
-		.flags = ESCAPE_SPECIAL,
-	},{
-		.out = "\\\\\\150\\\\\\\"\\a\\e\\\\",
-		.flags = ESCAPE_SPECIAL | ESCAPE_OCTAL,
-	},{
-		.out = "\\\\\\x68\\\\\\\"\\a\\e\\\\",
-		.flags = ESCAPE_SPECIAL | ESCAPE_HEX,
-	},{
-		/* terminator */
-	}}
-},{
-	.in = "\eb \\C\007\"\x90\r]",
-	.s1 = {{
-		.out = "\eb \\C\007\"\x90\\r]",
-		.flags = ESCAPE_SPACE,
-	},{
-		.out = "\\eb \\\\C\\a\\\"\x90\r]",
-		.flags = ESCAPE_SPECIAL,
-	},{
-		.out = "\\eb \\\\C\\a\\\"\x90\\r]",
-		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL,
-	},{
-		.out = "\\033\\142\\040\\134\\103\\007\\042\\220\\015\\135",
-		.flags = ESCAPE_OCTAL,
-	},{
-		.out = "\\033\\142\\040\\134\\103\\007\\042\\220\\r\\135",
-		.flags = ESCAPE_SPACE | ESCAPE_OCTAL,
-	},{
-		.out = "\\e\\142\\040\\\\\\103\\a\\\"\\220\\015\\135",
-		.flags = ESCAPE_SPECIAL | ESCAPE_OCTAL,
-	},{
-		.out = "\\e\\142\\040\\\\\\103\\a\\\"\\220\\r\\135",
-		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_OCTAL,
-	},{
-		.out = "\eb \\C\007\"\x90\r]",
-		.flags = ESCAPE_NP,
-	},{
-		.out = "\eb \\C\007\"\x90\\r]",
-		.flags = ESCAPE_SPACE | ESCAPE_NP,
-	},{
-		.out = "\\eb \\C\\a\"\x90\r]",
-		.flags = ESCAPE_SPECIAL | ESCAPE_NP,
-	},{
-		.out = "\\eb \\C\\a\"\x90\\r]",
-		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NP,
-	},{
-		.out = "\\033b \\C\\007\"\\220\\015]",
-		.flags = ESCAPE_OCTAL | ESCAPE_NP,
-	},{
-		.out = "\\033b \\C\\007\"\\220\\r]",
-		.flags = ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_NP,
-	},{
-		.out = "\\eb \\C\\a\"\\220\\r]",
-		.flags = ESCAPE_SPECIAL | ESCAPE_SPACE | ESCAPE_OCTAL |
-			 ESCAPE_NP,
-	},{
-		.out = "\\x1bb \\C\\x07\"\\x90\\x0d]",
-		.flags = ESCAPE_NP | ESCAPE_HEX,
-	},{
-		/* terminator */
-	}}
-},{
-	.in = "\007 \eb\"\x90\xCF\r",
-	.s1 = {{
-		.out = "\007 \eb\"\\220\\317\r",
-		.flags = ESCAPE_OCTAL | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\\x90\\xcf\r",
-		.flags = ESCAPE_HEX | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\xCF\r",
-		.flags = ESCAPE_NA,
-	},{
-		/* terminator */
-	}}
-},{
-	/* terminator */
-}};
-
-#define	TEST_STRING_2_DICT_1		"b\\ \t\r\xCF"
-static const struct test_string_2 escape1[] = {{
-	.in = "\f\\ \n\r\t\v",
-	.s1 = {{
-		.out = "\f\\134\\040\n\\015\\011\v",
-		.flags = ESCAPE_OCTAL,
-	},{
-		.out = "\f\\x5c\\x20\n\\x0d\\x09\v",
-		.flags = ESCAPE_HEX,
-	},{
-		.out = "\f\\134\\040\n\\015\\011\v",
-		.flags = ESCAPE_ANY | ESCAPE_APPEND,
-	},{
-		.out = "\\014\\134\\040\\012\\015\\011\\013",
-		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NAP,
-	},{
-		.out = "\\x0c\\x5c\\x20\\x0a\\x0d\\x09\\x0b",
-		.flags = ESCAPE_HEX | ESCAPE_APPEND | ESCAPE_NAP,
-	},{
-		.out = "\f\\134\\040\n\\015\\011\v",
-		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NA,
-	},{
-		.out = "\f\\x5c\\x20\n\\x0d\\x09\v",
-		.flags = ESCAPE_HEX | ESCAPE_APPEND | ESCAPE_NA,
-	},{
-		/* terminator */
-	}}
-},{
-	.in = "\\h\\\"\a\xCF\e\\",
-	.s1 = {{
-		.out = "\\134h\\134\"\a\\317\e\\134",
-		.flags = ESCAPE_OCTAL,
-	},{
-		.out = "\\134h\\134\"\a\\317\e\\134",
-		.flags = ESCAPE_ANY | ESCAPE_APPEND,
-	},{
-		.out = "\\134h\\134\"\\007\\317\\033\\134",
-		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NAP,
-	},{
-		.out = "\\134h\\134\"\a\\317\e\\134",
-		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NA,
-	},{
-		/* terminator */
-	}}
-},{
-	.in = "\eb \\C\007\"\x90\r]",
-	.s1 = {{
-		.out = "\e\\142\\040\\134C\007\"\x90\\015]",
-		.flags = ESCAPE_OCTAL,
-	},{
-		/* terminator */
-	}}
-},{
-	.in = "\007 \eb\"\x90\xCF\r",
-	.s1 = {{
-		.out = "\007 \eb\"\x90\xCF\r",
-		.flags = ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\xCF\r",
-		.flags = ESCAPE_SPACE | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\xCF\r",
-		.flags = ESCAPE_SPECIAL | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\xCF\r",
-		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\\317\r",
-		.flags = ESCAPE_OCTAL | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\\317\r",
-		.flags = ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\\317\r",
-		.flags = ESCAPE_SPECIAL | ESCAPE_OCTAL | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\\317\r",
-		.flags = ESCAPE_ANY | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\\xcf\r",
-		.flags = ESCAPE_HEX | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\\xcf\r",
-		.flags = ESCAPE_SPACE | ESCAPE_HEX | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\\xcf\r",
-		.flags = ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NA,
-	},{
-		.out = "\007 \eb\"\x90\\xcf\r",
-		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NA,
-	},{
-		/* terminator */
-	}}
-},{
-	.in = "\007 \eb\"\x90\xCF\r",
-	.s1 = {{
-		.out = "\007 \eb\"\x90\xCF\r",
-		.flags = ESCAPE_NAP,
-	},{
-		.out = "\007 \eb\"\x90\xCF\\r",
-		.flags = ESCAPE_SPACE | ESCAPE_NAP,
-	},{
-		.out = "\007 \eb\"\x90\xCF\r",
-		.flags = ESCAPE_SPECIAL | ESCAPE_NAP,
-	},{
-		.out = "\007 \eb\"\x90\xCF\\r",
-		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NAP,
-	},{
-		.out = "\007 \eb\"\x90\\317\\015",
-		.flags = ESCAPE_OCTAL | ESCAPE_NAP,
-	},{
-		.out = "\007 \eb\"\x90\\317\\r",
-		.flags = ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_NAP,
-	},{
-		.out = "\007 \eb\"\x90\\317\\015",
-		.flags = ESCAPE_SPECIAL | ESCAPE_OCTAL | ESCAPE_NAP,
-	},{
-		.out = "\007 \eb\"\x90\\317\r",
-		.flags = ESCAPE_ANY | ESCAPE_NAP,
-	},{
-		.out = "\007 \eb\"\x90\\xcf\\x0d",
-		.flags = ESCAPE_HEX | ESCAPE_NAP,
-	},{
-		.out = "\007 \eb\"\x90\\xcf\\r",
-		.flags = ESCAPE_SPACE | ESCAPE_HEX | ESCAPE_NAP,
-	},{
-		.out = "\007 \eb\"\x90\\xcf\\x0d",
-		.flags = ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NAP,
-	},{
-		.out = "\007 \eb\"\x90\\xcf\\r",
-		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NAP,
-	},{
-		/* terminator */
-	}}
-},{
-	/* terminator */
-}};
-
-static const struct test_string strings_upper[] = {
-	{
-		.in = "abcdefgh1234567890test",
-		.out = "ABCDEFGH1234567890TEST",
-	},
-	{
-		.in = "abCdeFgH1234567890TesT",
-		.out = "ABCDEFGH1234567890TEST",
-	},
-};
-
-static const struct test_string strings_lower[] = {
-	{
-		.in = "ABCDEFGH1234567890TEST",
-		.out = "abcdefgh1234567890test",
-	},
-	{
-		.in = "abCdeFgH1234567890TesT",
-		.out = "abcdefgh1234567890test",
-	},
-};
-
-static const char *test_string_find_match(const struct test_string_2 *s2,
-					  unsigned int flags)
-{
-	const struct test_string_1 *s1 = s2->s1;
-	unsigned int i;
-
-	if (!flags)
-		return s2->in;
-
-	/* Test cases are NULL-aware */
-	flags &= ~ESCAPE_NULL;
-
-	/* ESCAPE_OCTAL has a higher priority */
-	if (flags & ESCAPE_OCTAL)
-		flags &= ~ESCAPE_HEX;
-
-	for (i = 0; i < TEST_STRING_2_MAX_S1 && s1->out; i++, s1++)
-		if (s1->flags == flags)
-			return s1->out;
-	return NULL;
-}
-
-static void
-test_string_escape_overflow(struct kunit *test,
-			    const char *in, int p, unsigned int flags, const char *esc,
-			    int q_test, const char *name)
-{
-	int q_real;
-
-	q_real = string_escape_mem(in, p, NULL, 0, flags, esc);
-	KUNIT_EXPECT_EQ_MSG(test, q_real, q_test, "name:%s: flags:%#x", name, flags);
-}
-
-static void test_string_escape(struct kunit *test, const char *name,
-			       const struct test_string_2 *s2,
-			       unsigned int flags, const char *esc)
-{
-	size_t out_size = 512;
-	char *out_test = kunit_kzalloc(test, out_size, GFP_KERNEL);
-	char *out_real = kunit_kzalloc(test, out_size, GFP_KERNEL);
-	char *in = kunit_kzalloc(test, 256, GFP_KERNEL);
-	int p = 0, q_test = 0;
-	int q_real;
-
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, out_test);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, out_real);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, in);
-
-	for (; s2->in; s2++) {
-		const char *out;
-		int len;
-
-		/* NULL injection */
-		if (flags & ESCAPE_NULL) {
-			in[p++] = '\0';
-			/* '\0' passes isascii() test */
-			if (flags & ESCAPE_NA && !(flags & ESCAPE_APPEND && esc)) {
-				out_test[q_test++] = '\0';
-			} else {
-				out_test[q_test++] = '\\';
-				out_test[q_test++] = '0';
-			}
-		}
-
-		/* Don't try strings that have no output */
-		out = test_string_find_match(s2, flags);
-		if (!out)
-			continue;
-
-		/* Copy string to in buffer */
-		len = strlen(s2->in);
-		memcpy(&in[p], s2->in, len);
-		p += len;
-
-		/* Copy expected result for given flags */
-		len = strlen(out);
-		memcpy(&out_test[q_test], out, len);
-		q_test += len;
-	}
-
-	q_real = string_escape_mem(in, p, out_real, out_size, flags, esc);
-
-	test_string_check_buf(test, name, flags, in, p, out_real, q_real, out_test,
-			      q_test);
-
-	test_string_escape_overflow(test, in, p, flags, esc, q_test, name);
-}
-
-#define string_get_size_maxbuf 16
-#define test_string_get_size_one(size, blk_size, exp_result10, exp_result2)      \
-	do {                                                                     \
-		BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf);    \
-		BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf);     \
-		__test_string_get_size(test, (size), (blk_size), (exp_result10), \
-				       (exp_result2));                           \
-	} while (0)
-
-
-static void test_string_get_size_check(struct kunit *test,
-				       const char *units,
-				       const char *exp,
-				       char *res,
-				       const u64 size,
-				       const u64 blk_size)
-{
-	KUNIT_EXPECT_MEMEQ_MSG(test, res, exp, strlen(exp) + 1,
-		"string_get_size(size = %llu, blk_size = %llu, units = %s)",
-		size, blk_size, units);
-}
-
-static void __strchrcut(char *dst, const char *src, const char *cut)
-{
-	const char *from = src;
-	size_t len;
-
-	do {
-		len = strcspn(from, cut);
-		memcpy(dst, from, len);
-		dst += len;
-		from += len;
-	} while (*from++);
-	*dst = '\0';
-}
-
-static void __test_string_get_size_one(struct kunit *test,
-				       const u64 size, const u64 blk_size,
-				       const char *exp_result10,
-				       const char *exp_result2,
-				       enum string_size_units units,
-				       const char *cut)
-{
-	char buf10[string_get_size_maxbuf];
-	char buf2[string_get_size_maxbuf];
-	char exp10[string_get_size_maxbuf];
-	char exp2[string_get_size_maxbuf];
-	char prefix10[64];
-	char prefix2[64];
-
-	sprintf(prefix10, "STRING_UNITS_10 [%s]", cut);
-	sprintf(prefix2, "STRING_UNITS_2 [%s]", cut);
-
-	__strchrcut(exp10, exp_result10, cut);
-	__strchrcut(exp2, exp_result2, cut);
-
-	string_get_size(size, blk_size, STRING_UNITS_10 | units, buf10, sizeof(buf10));
-	string_get_size(size, blk_size, STRING_UNITS_2 | units, buf2, sizeof(buf2));
-
-	test_string_get_size_check(test, prefix10, exp10, buf10, size, blk_size);
-	test_string_get_size_check(test, prefix2, exp2, buf2, size, blk_size);
-}
-
-static void __test_string_get_size(struct kunit *test,
-				   const u64 size, const u64 blk_size,
-				   const char *exp_result10,
-				   const char *exp_result2)
-{
-	struct {
-		enum string_size_units units;
-		const char *cut;
-	} get_size_test_cases[] = {
-		{ 0, "" },
-		{ STRING_UNITS_NO_SPACE, " " },
-		{ STRING_UNITS_NO_SPACE | STRING_UNITS_NO_BYTES, " B" },
-		{ STRING_UNITS_NO_BYTES, "B" },
-	};
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(get_size_test_cases); i++)
-		__test_string_get_size_one(test, size, blk_size,
-					   exp_result10, exp_result2,
-					   get_size_test_cases[i].units,
-					   get_size_test_cases[i].cut);
-}
-
-static void test_get_size(struct kunit *test)
-{
-	/* small values */
-	test_string_get_size_one(0, 512, "0 B", "0 B");
-	test_string_get_size_one(1, 512, "512 B", "512 B");
-	test_string_get_size_one(1100, 1, "1.10 kB", "1.07 KiB");
-
-	/* normal values */
-	test_string_get_size_one(16384, 512, "8.39 MB", "8.00 MiB");
-	test_string_get_size_one(500118192, 512, "256 GB", "238 GiB");
-	test_string_get_size_one(8192, 4096, "33.6 MB", "32.0 MiB");
-
-	/* weird block sizes */
-	test_string_get_size_one(3000, 1900, "5.70 MB", "5.44 MiB");
-
-	/* huge values */
-	test_string_get_size_one(U64_MAX, 4096, "75.6 ZB", "64.0 ZiB");
-	test_string_get_size_one(4096, U64_MAX, "75.6 ZB", "64.0 ZiB");
-}
-
-static void test_upper_lower(struct kunit *test)
-{
-	char *dst;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(strings_upper); i++) {
-		const char *s = strings_upper[i].in;
-		int len = strlen(strings_upper[i].in) + 1;
-
-		dst = kmalloc(len, GFP_KERNEL);
-		KUNIT_ASSERT_NOT_NULL(test, dst);
-
-		string_upper(dst, s);
-		KUNIT_EXPECT_STREQ(test, dst, strings_upper[i].out);
-		kfree(dst);
-	}
-
-	for (i = 0; i < ARRAY_SIZE(strings_lower); i++) {
-		const char *s = strings_lower[i].in;
-		int len = strlen(strings_lower[i].in) + 1;
-
-		dst = kmalloc(len, GFP_KERNEL);
-		KUNIT_ASSERT_NOT_NULL(test, dst);
-
-		string_lower(dst, s);
-		KUNIT_EXPECT_STREQ(test, dst, strings_lower[i].out);
-		kfree(dst);
-	}
-}
-
-static void test_unescape(struct kunit *test)
-{
-	unsigned int i;
-
-	for (i = 0; i < UNESCAPE_ALL_MASK + 1; i++)
-		test_string_unescape(test, "unescape", i, false);
-	test_string_unescape(test, "unescape inplace",
-			     get_random_u32_below(UNESCAPE_ALL_MASK + 1), true);
-
-	/* Without dictionary */
-	for (i = 0; i < ESCAPE_ALL_MASK + 1; i++)
-		test_string_escape(test, "escape 0", escape0, i, TEST_STRING_2_DICT_0);
-
-	/* With dictionary */
-	for (i = 0; i < ESCAPE_ALL_MASK + 1; i++)
-		test_string_escape(test, "escape 1", escape1, i, TEST_STRING_2_DICT_1);
-}
-
-static struct kunit_case string_helpers_test_cases[] = {
-	KUNIT_CASE(test_get_size),
-	KUNIT_CASE(test_upper_lower),
-	KUNIT_CASE(test_unescape),
-	{}
-};
-
-static struct kunit_suite string_helpers_test_suite = {
-	.name = "string_helpers",
-	.test_cases = string_helpers_test_cases,
-};
-
-kunit_test_suites(&string_helpers_test_suite);
-
-MODULE_DESCRIPTION("Test cases for string helpers module");
-MODULE_LICENSE("Dual BSD/GPL");
diff --git a/lib/string_kunit.c a/lib/string_kunit.c
deleted file mode 100644
--- a/lib/string_kunit.c
+++ /dev/null
@@ -1,637 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Test cases for string functions.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <kunit/test.h>
-#include <linux/module.h>
-#include <linux/printk.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#define STRCMP_LARGE_BUF_LEN 2048
-#define STRCMP_CHANGE_POINT 1337
-#define STRCMP_TEST_EXPECT_EQUAL(test, fn, ...) KUNIT_EXPECT_EQ(test, fn(__VA_ARGS__), 0)
-#define STRCMP_TEST_EXPECT_LOWER(test, fn, ...) KUNIT_EXPECT_LT(test, fn(__VA_ARGS__), 0)
-#define STRCMP_TEST_EXPECT_GREATER(test, fn, ...) KUNIT_EXPECT_GT(test, fn(__VA_ARGS__), 0)
-
-static void string_test_memset16(struct kunit *test)
-{
-	unsigned i, j, k;
-	u16 v, *p;
-
-	p = kunit_kzalloc(test, 256 * 2 * 2, GFP_KERNEL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
-
-	for (i = 0; i < 256; i++) {
-		for (j = 0; j < 256; j++) {
-			memset(p, 0xa1, 256 * 2 * sizeof(v));
-			memset16(p + i, 0xb1b2, j);
-			for (k = 0; k < 512; k++) {
-				v = p[k];
-				if (k < i) {
-					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1,
-						"i:%d j:%d k:%d", i, j, k);
-				} else if (k < i + j) {
-					KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2,
-						"i:%d j:%d k:%d", i, j, k);
-				} else {
-					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1,
-						"i:%d j:%d k:%d", i, j, k);
-				}
-			}
-		}
-	}
-}
-
-static void string_test_memset32(struct kunit *test)
-{
-	unsigned i, j, k;
-	u32 v, *p;
-
-	p = kunit_kzalloc(test, 256 * 2 * 4, GFP_KERNEL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
-
-	for (i = 0; i < 256; i++) {
-		for (j = 0; j < 256; j++) {
-			memset(p, 0xa1, 256 * 2 * sizeof(v));
-			memset32(p + i, 0xb1b2b3b4, j);
-			for (k = 0; k < 512; k++) {
-				v = p[k];
-				if (k < i) {
-					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1,
-						"i:%d j:%d k:%d", i, j, k);
-				} else if (k < i + j) {
-					KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2b3b4,
-						"i:%d j:%d k:%d", i, j, k);
-				} else {
-					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1,
-						"i:%d j:%d k:%d", i, j, k);
-				}
-			}
-		}
-	}
-}
-
-static void string_test_memset64(struct kunit *test)
-{
-	unsigned i, j, k;
-	u64 v, *p;
-
-	p = kunit_kzalloc(test, 256 * 2 * 8, GFP_KERNEL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
-
-	for (i = 0; i < 256; i++) {
-		for (j = 0; j < 256; j++) {
-			memset(p, 0xa1, 256 * 2 * sizeof(v));
-			memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j);
-			for (k = 0; k < 512; k++) {
-				v = p[k];
-				if (k < i) {
-					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1a1a1a1a1ULL,
-						"i:%d j:%d k:%d", i, j, k);
-				} else if (k < i + j) {
-					KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2b3b4b5b6b7b8ULL,
-						"i:%d j:%d k:%d", i, j, k);
-				} else {
-					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1a1a1a1a1ULL,
-						"i:%d j:%d k:%d", i, j, k);
-				}
-			}
-		}
-	}
-}
-
-static void string_test_strchr(struct kunit *test)
-{
-	const char *test_string = "abcdefghijkl";
-	const char *empty_string = "";
-	char *result;
-	int i;
-
-	for (i = 0; i < strlen(test_string) + 1; i++) {
-		result = strchr(test_string, test_string[i]);
-		KUNIT_ASSERT_EQ_MSG(test, result - test_string, i,
-				    "char:%c", 'a' + i);
-	}
-
-	result = strchr(empty_string, '\0');
-	KUNIT_ASSERT_PTR_EQ(test, result, empty_string);
-
-	result = strchr(empty_string, 'a');
-	KUNIT_ASSERT_NULL(test, result);
-
-	result = strchr(test_string, 'z');
-	KUNIT_ASSERT_NULL(test, result);
-}
-
-static void string_test_strnchr(struct kunit *test)
-{
-	const char *test_string = "abcdefghijkl";
-	const char *empty_string = "";
-	char *result;
-	int i, j;
-
-	for (i = 0; i < strlen(test_string) + 1; i++) {
-		for (j = 0; j < strlen(test_string) + 2; j++) {
-			result = strnchr(test_string, j, test_string[i]);
-			if (j <= i) {
-				KUNIT_ASSERT_NULL_MSG(test, result,
-					"char:%c i:%d j:%d", 'a' + i, i, j);
-			} else {
-				KUNIT_ASSERT_EQ_MSG(test, result - test_string, i,
-					"char:%c i:%d j:%d", 'a' + i, i, j);
-			}
-		}
-	}
-
-	result = strnchr(empty_string, 0, '\0');
-	KUNIT_ASSERT_NULL(test, result);
-
-	result = strnchr(empty_string, 1, '\0');
-	KUNIT_ASSERT_PTR_EQ(test, result, empty_string);
-
-	result = strnchr(empty_string, 1, 'a');
-	KUNIT_ASSERT_NULL(test, result);
-
-	result = strnchr(NULL, 0, '\0');
-	KUNIT_ASSERT_NULL(test, result);
-}
-
-static void string_test_strspn(struct kunit *test)
-{
-	static const struct strspn_test {
-		const char str[16];
-		const char accept[16];
-		const char reject[16];
-		unsigned a;
-		unsigned r;
-	} tests[] = {
-		{ "foobar", "", "", 0, 6 },
-		{ "abba", "abc", "ABBA", 4, 4 },
-		{ "abba", "a", "b", 1, 1 },
-		{ "", "abc", "abc", 0, 0},
-	};
-	const struct strspn_test *s = tests;
-	size_t i;
-
-	for (i = 0; i < ARRAY_SIZE(tests); ++i, ++s) {
-		KUNIT_ASSERT_EQ_MSG(test, s->a, strspn(s->str, s->accept),
-			"i:%zu", i);
-		KUNIT_ASSERT_EQ_MSG(test, s->r, strcspn(s->str, s->reject),
-			"i:%zu", i);
-	}
-}
-
-static char strcmp_buffer1[STRCMP_LARGE_BUF_LEN];
-static char strcmp_buffer2[STRCMP_LARGE_BUF_LEN];
-
-static void strcmp_fill_buffers(char fill1, char fill2)
-{
-	memset(strcmp_buffer1, fill1, STRCMP_LARGE_BUF_LEN);
-	memset(strcmp_buffer2, fill2, STRCMP_LARGE_BUF_LEN);
-	strcmp_buffer1[STRCMP_LARGE_BUF_LEN - 1] = 0;
-	strcmp_buffer2[STRCMP_LARGE_BUF_LEN - 1] = 0;
-}
-
-static void string_test_strcmp(struct kunit *test)
-{
-	/* Equal strings */
-	STRCMP_TEST_EXPECT_EQUAL(test, strcmp, "Hello, Kernel!", "Hello, Kernel!");
-	/* First string is lexicographically less than the second */
-	STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Hello, KUnit!", "Hello, Kernel!");
-	/* First string is lexicographically larger than the second */
-	STRCMP_TEST_EXPECT_GREATER(test, strcmp, "Hello, Kernel!", "Hello, KUnit!");
-	/* Empty string is always lexicographically less than any non-empty string */
-	STRCMP_TEST_EXPECT_LOWER(test, strcmp, "", "Non-empty string");
-	/* Two empty strings should be equal */
-	STRCMP_TEST_EXPECT_EQUAL(test, strcmp, "", "");
-	/* Compare two strings which have only one char difference */
-	STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Abacaba", "Abadaba");
-	/* Compare two strings which have the same prefix*/
-	STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Just a string", "Just a string and something else");
-}
-
-static void string_test_strcmp_long_strings(struct kunit *test)
-{
-	strcmp_fill_buffers('B', 'B');
-	STRCMP_TEST_EXPECT_EQUAL(test, strcmp, strcmp_buffer1, strcmp_buffer2);
-
-	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A';
-	STRCMP_TEST_EXPECT_LOWER(test, strcmp, strcmp_buffer1, strcmp_buffer2);
-
-	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
-	STRCMP_TEST_EXPECT_GREATER(test, strcmp, strcmp_buffer1, strcmp_buffer2);
-}
-
-static void string_test_strncmp(struct kunit *test)
-{
-	/* Equal strings */
-	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Hello, KUnit!", "Hello, KUnit!", 13);
-	/* First string is lexicographically less than the second */
-	STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Hello, KUnit!", "Hello, Kernel!", 13);
-	/* Result is always 'equal' when count = 0 */
-	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Hello, Kernel!", "Hello, KUnit!", 0);
-	/* Strings with common prefix are equal if count = length of prefix */
-	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Abacaba", "Abadaba", 3);
-	/* Strings with common prefix are not equal when count = length of prefix + 1 */
-	STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Abacaba", "Abadaba", 4);
-	/* If one string is a prefix of another, the shorter string is lexicographically smaller */
-	STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Just a string", "Just a string and something else",
-				 strlen("Just a string and something else"));
-	/*
-	 * If one string is a prefix of another, and we check first length
-	 * of prefix chars, the result is 'equal'
-	 */
-	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Just a string", "Just a string and something else",
-				 strlen("Just a string"));
-}
-
-static void string_test_strncmp_long_strings(struct kunit *test)
-{
-	strcmp_fill_buffers('B', 'B');
-	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, strcmp_buffer1,
-				 strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
-
-	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A';
-	STRCMP_TEST_EXPECT_LOWER(test, strncmp, strcmp_buffer1,
-				 strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
-
-	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
-	STRCMP_TEST_EXPECT_GREATER(test, strncmp, strcmp_buffer1,
-				   strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
-	/* the strings are equal up to STRCMP_CHANGE_POINT */
-	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, strcmp_buffer1,
-				 strcmp_buffer2, STRCMP_CHANGE_POINT);
-	STRCMP_TEST_EXPECT_GREATER(test, strncmp, strcmp_buffer1,
-				   strcmp_buffer2, STRCMP_CHANGE_POINT + 1);
-}
-
-static void string_test_strcasecmp(struct kunit *test)
-{
-	/* Same strings in different case should be equal */
-	STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "Hello, Kernel!", "HeLLO, KErNeL!");
-	/* Empty strings should be equal */
-	STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "", "");
-	/* Despite ascii code for 'a' is larger than ascii code for 'B', 'a' < 'B' */
-	STRCMP_TEST_EXPECT_LOWER(test, strcasecmp, "a", "B");
-	STRCMP_TEST_EXPECT_GREATER(test, strcasecmp, "B", "a");
-	/* Special symbols and numbers should be processed correctly */
-	STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "-+**.1230ghTTT~^", "-+**.1230Ghttt~^");
-}
-
-static void string_test_strcasecmp_long_strings(struct kunit *test)
-{
-	strcmp_fill_buffers('b', 'B');
-	STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, strcmp_buffer1, strcmp_buffer2);
-
-	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a';
-	STRCMP_TEST_EXPECT_LOWER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2);
-
-	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
-	STRCMP_TEST_EXPECT_GREATER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2);
-}
-
-static void string_test_strncasecmp(struct kunit *test)
-{
-	/* Same strings in different case should be equal */
-	STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "AbAcAbA", "Abacaba", strlen("Abacaba"));
-	/* strncasecmp should check 'count' chars only */
-	STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "AbaCaBa", "abaCaDa", 5);
-	STRCMP_TEST_EXPECT_LOWER(test, strncasecmp, "a", "B", 1);
-	STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, "B", "a", 1);
-	/* Result is always 'equal' when count = 0 */
-	STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "Abacaba", "Not abacaba", 0);
-}
-
-static void string_test_strncasecmp_long_strings(struct kunit *test)
-{
-	strcmp_fill_buffers('b', 'B');
-	STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, strcmp_buffer1,
-				 strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
-
-	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a';
-	STRCMP_TEST_EXPECT_LOWER(test, strncasecmp, strcmp_buffer1,
-				 strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
-
-	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
-	STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, strcmp_buffer1,
-				   strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
-
-	STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, strcmp_buffer1,
-				 strcmp_buffer2, STRCMP_CHANGE_POINT);
-	STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, strcmp_buffer1,
-				   strcmp_buffer2, STRCMP_CHANGE_POINT + 1);
-}
-
-/**
- * strscpy_check() - Run a specific test case.
- * @test: KUnit test context pointer
- * @src: Source string, argument to strscpy_pad()
- * @count: Size of destination buffer, argument to strscpy_pad()
- * @expected: Expected return value from call to strscpy_pad()
- * @chars: Number of characters from the src string expected to be
- *         written to the dst buffer.
- * @terminator: 1 if there should be a terminating null byte 0 otherwise.
- * @pad: Number of pad characters expected (in the tail of dst buffer).
- *       (@pad does not include the null terminator byte.)
- *
- * Calls strscpy_pad() and verifies the return value and state of the
- * destination buffer after the call returns.
- */
-static void strscpy_check(struct kunit *test, char *src, int count,
-			  int expected, int chars, int terminator, int pad)
-{
-	int nr_bytes_poison;
-	int max_expected;
-	int max_count;
-	int written;
-	char buf[6];
-	int index, i;
-	const char POISON = 'z';
-
-	KUNIT_ASSERT_TRUE_MSG(test, src != NULL,
-			      "null source string not supported");
-
-	memset(buf, POISON, sizeof(buf));
-	/* Future proofing test suite, validate args */
-	max_count = sizeof(buf) - 2; /* Space for null and to verify overflow */
-	max_expected = count - 1;    /* Space for the null */
-
-	KUNIT_ASSERT_LE_MSG(test, count, max_count,
-		"count (%d) is too big (%d) ... aborting", count, max_count);
-	KUNIT_EXPECT_LE_MSG(test, expected, max_expected,
-		"expected (%d) is bigger than can possibly be returned (%d)",
-		expected, max_expected);
-
-	written = strscpy_pad(buf, src, count);
-	KUNIT_ASSERT_EQ(test, written, expected);
-
-	if (count && written == -E2BIG) {
-		KUNIT_ASSERT_EQ_MSG(test, 0, strncmp(buf, src, count - 1),
-			"buffer state invalid for -E2BIG");
-		KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0',
-			"too big string is not null terminated correctly");
-	}
-
-	for (i = 0; i < chars; i++)
-		KUNIT_ASSERT_EQ_MSG(test, buf[i], src[i],
-			"buf[i]==%c != src[i]==%c", buf[i], src[i]);
-
-	if (terminator)
-		KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0',
-			"string is not null terminated correctly");
-
-	for (i = 0; i < pad; i++) {
-		index = chars + terminator + i;
-		KUNIT_ASSERT_EQ_MSG(test, buf[index], '\0',
-			"padding missing at index: %d", i);
-	}
-
-	nr_bytes_poison = sizeof(buf) - chars - terminator - pad;
-	for (i = 0; i < nr_bytes_poison; i++) {
-		index = sizeof(buf) - 1 - i; /* Check from the end back */
-		KUNIT_ASSERT_EQ_MSG(test, buf[index], POISON,
-			"poison value missing at index: %d", i);
-	}
-}
-
-static void string_test_strscpy(struct kunit *test)
-{
-	char dest[8];
-
-	/*
-	 * strscpy_check() uses a destination buffer of size 6 and needs at
-	 * least 2 characters spare (one for null and one to check for
-	 * overflow).  This means we should only call tc() with
-	 * strings up to a maximum of 4 characters long and 'count'
-	 * should not exceed 4.  To test with longer strings increase
-	 * the buffer size in tc().
-	 */
-
-	/* strscpy_check(test, src, count, expected, chars, terminator, pad) */
-	strscpy_check(test, "a", 0, -E2BIG, 0, 0, 0);
-	strscpy_check(test, "",  0, -E2BIG, 0, 0, 0);
-
-	strscpy_check(test, "a", 1, -E2BIG, 0, 1, 0);
-	strscpy_check(test, "",  1, 0,	 0, 1, 0);
-
-	strscpy_check(test, "ab", 2, -E2BIG, 1, 1, 0);
-	strscpy_check(test, "a",  2, 1,	  1, 1, 0);
-	strscpy_check(test, "",   2, 0,	  0, 1, 1);
-
-	strscpy_check(test, "abc", 3, -E2BIG, 2, 1, 0);
-	strscpy_check(test, "ab",  3, 2,	   2, 1, 0);
-	strscpy_check(test, "a",   3, 1,	   1, 1, 1);
-	strscpy_check(test, "",    3, 0,	   0, 1, 2);
-
-	strscpy_check(test, "abcd", 4, -E2BIG, 3, 1, 0);
-	strscpy_check(test, "abc",  4, 3,	    3, 1, 0);
-	strscpy_check(test, "ab",   4, 2,	    2, 1, 1);
-	strscpy_check(test, "a",    4, 1,	    1, 1, 2);
-	strscpy_check(test, "",     4, 0,	    0, 1, 3);
-
-	/* Compile-time-known source strings. */
-	KUNIT_EXPECT_EQ(test, strscpy(dest, "", ARRAY_SIZE(dest)), 0);
-	KUNIT_EXPECT_EQ(test, strscpy(dest, "", 3), 0);
-	KUNIT_EXPECT_EQ(test, strscpy(dest, "", 1), 0);
-	KUNIT_EXPECT_EQ(test, strscpy(dest, "", 0), -E2BIG);
-	KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", ARRAY_SIZE(dest)), 5);
-	KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 3), -E2BIG);
-	KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 1), -E2BIG);
-	KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 0), -E2BIG);
-	KUNIT_EXPECT_EQ(test, strscpy(dest, "This is too long", ARRAY_SIZE(dest)), -E2BIG);
-}
-
-static volatile int unconst;
-
-static void string_test_strcat(struct kunit *test)
-{
-	char dest[8];
-
-	/* Destination is terminated. */
-	memset(dest, 0, sizeof(dest));
-	KUNIT_EXPECT_EQ(test, strlen(dest), 0);
-	/* Empty copy does nothing. */
-	KUNIT_EXPECT_TRUE(test, strcat(dest, "") == dest);
-	KUNIT_EXPECT_STREQ(test, dest, "");
-	/* 4 characters copied in, stops at %NUL. */
-	KUNIT_EXPECT_TRUE(test, strcat(dest, "four\000123") == dest);
-	KUNIT_EXPECT_STREQ(test, dest, "four");
-	KUNIT_EXPECT_EQ(test, dest[5], '\0');
-	/* 2 more characters copied in okay. */
-	KUNIT_EXPECT_TRUE(test, strcat(dest, "AB") == dest);
-	KUNIT_EXPECT_STREQ(test, dest, "fourAB");
-}
-
-static void string_test_strncat(struct kunit *test)
-{
-	char dest[8];
-
-	/* Destination is terminated. */
-	memset(dest, 0, sizeof(dest));
-	KUNIT_EXPECT_EQ(test, strlen(dest), 0);
-	/* Empty copy of size 0 does nothing. */
-	KUNIT_EXPECT_TRUE(test, strncat(dest, "", 0 + unconst) == dest);
-	KUNIT_EXPECT_STREQ(test, dest, "");
-	/* Empty copy of size 1 does nothing too. */
-	KUNIT_EXPECT_TRUE(test, strncat(dest, "", 1 + unconst) == dest);
-	KUNIT_EXPECT_STREQ(test, dest, "");
-	/* Copy of max 0 characters should do nothing. */
-	KUNIT_EXPECT_TRUE(test, strncat(dest, "asdf", 0 + unconst) == dest);
-	KUNIT_EXPECT_STREQ(test, dest, "");
-
-	/* 4 characters copied in, even if max is 8. */
-	KUNIT_EXPECT_TRUE(test, strncat(dest, "four\000123", 8 + unconst) == dest);
-	KUNIT_EXPECT_STREQ(test, dest, "four");
-	KUNIT_EXPECT_EQ(test, dest[5], '\0');
-	KUNIT_EXPECT_EQ(test, dest[6], '\0');
-	/* 2 characters copied in okay, 2 ignored. */
-	KUNIT_EXPECT_TRUE(test, strncat(dest, "ABCD", 2 + unconst) == dest);
-	KUNIT_EXPECT_STREQ(test, dest, "fourAB");
-}
-
-static void string_test_strlcat(struct kunit *test)
-{
-	char dest[8] = "";
-	int len = sizeof(dest) + unconst;
-
-	/* Destination is terminated. */
-	KUNIT_EXPECT_EQ(test, strlen(dest), 0);
-	/* Empty copy is size 0. */
-	KUNIT_EXPECT_EQ(test, strlcat(dest, "", len), 0);
-	KUNIT_EXPECT_STREQ(test, dest, "");
-	/* Size 1 should keep buffer terminated, report size of source only. */
-	KUNIT_EXPECT_EQ(test, strlcat(dest, "four", 1 + unconst), 4);
-	KUNIT_EXPECT_STREQ(test, dest, "");
-
-	/* 4 characters copied in. */
-	KUNIT_EXPECT_EQ(test, strlcat(dest, "four", len), 4);
-	KUNIT_EXPECT_STREQ(test, dest, "four");
-	/* 2 characters copied in okay, gets to 6 total. */
-	KUNIT_EXPECT_EQ(test, strlcat(dest, "AB", len), 6);
-	KUNIT_EXPECT_STREQ(test, dest, "fourAB");
-	/* 2 characters ignored if max size (7) reached. */
-	KUNIT_EXPECT_EQ(test, strlcat(dest, "CD", 7 + unconst), 8);
-	KUNIT_EXPECT_STREQ(test, dest, "fourAB");
-	/* 1 of 2 characters skipped, now at true max size. */
-	KUNIT_EXPECT_EQ(test, strlcat(dest, "EFG", len), 9);
-	KUNIT_EXPECT_STREQ(test, dest, "fourABE");
-	/* Everything else ignored, now at full size. */
-	KUNIT_EXPECT_EQ(test, strlcat(dest, "1234", len), 11);
-	KUNIT_EXPECT_STREQ(test, dest, "fourABE");
-}
-
-static void string_test_strtomem(struct kunit *test)
-{
-	static const char input[sizeof(unsigned long)] = "hi";
-	static const char truncate[] = "this is too long";
-	struct {
-		unsigned long canary1;
-		unsigned char output[sizeof(unsigned long)] __nonstring;
-		unsigned long canary2;
-	} wrap;
-
-	memset(&wrap, 0xFF, sizeof(wrap));
-	KUNIT_EXPECT_EQ_MSG(test, wrap.canary1, ULONG_MAX,
-			    "bad initial canary value");
-	KUNIT_EXPECT_EQ_MSG(test, wrap.canary2, ULONG_MAX,
-			    "bad initial canary value");
-
-	/* Check unpadded copy leaves surroundings untouched. */
-	strtomem(wrap.output, input);
-	KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
-	KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]);
-	KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]);
-	for (size_t i = 2; i < sizeof(wrap.output); i++)
-		KUNIT_EXPECT_EQ(test, wrap.output[i], 0xFF);
-	KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
-
-	/* Check truncated copy leaves surroundings untouched. */
-	memset(&wrap, 0xFF, sizeof(wrap));
-	strtomem(wrap.output, truncate);
-	KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
-	for (size_t i = 0; i < sizeof(wrap.output); i++)
-		KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]);
-	KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
-
-	/* Check padded copy leaves only string padded. */
-	memset(&wrap, 0xFF, sizeof(wrap));
-	strtomem_pad(wrap.output, input, 0xAA);
-	KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
-	KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]);
-	KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]);
-	for (size_t i = 2; i < sizeof(wrap.output); i++)
-		KUNIT_EXPECT_EQ(test, wrap.output[i], 0xAA);
-	KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
-
-	/* Check truncated padded copy has no padding. */
-	memset(&wrap, 0xFF, sizeof(wrap));
-	strtomem(wrap.output, truncate);
-	KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
-	for (size_t i = 0; i < sizeof(wrap.output); i++)
-		KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]);
-	KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
-}
-
-
-static void string_test_memtostr(struct kunit *test)
-{
-	char nonstring[7] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
-	char nonstring_small[3] = { 'a', 'b', 'c' };
-	char dest[sizeof(nonstring) + 1];
-
-	/* Copy in a non-NUL-terminated string into exactly right-sized dest. */
-	KUNIT_EXPECT_EQ(test, sizeof(dest), sizeof(nonstring) + 1);
-	memset(dest, 'X', sizeof(dest));
-	memtostr(dest, nonstring);
-	KUNIT_EXPECT_STREQ(test, dest, "abcdefg");
-	memset(dest, 'X', sizeof(dest));
-	memtostr(dest, nonstring_small);
-	KUNIT_EXPECT_STREQ(test, dest, "abc");
-	KUNIT_EXPECT_EQ(test, dest[7], 'X');
-
-	memset(dest, 'X', sizeof(dest));
-	memtostr_pad(dest, nonstring);
-	KUNIT_EXPECT_STREQ(test, dest, "abcdefg");
-	memset(dest, 'X', sizeof(dest));
-	memtostr_pad(dest, nonstring_small);
-	KUNIT_EXPECT_STREQ(test, dest, "abc");
-	KUNIT_EXPECT_EQ(test, dest[7], '\0');
-}
-
-static struct kunit_case string_test_cases[] = {
-	KUNIT_CASE(string_test_memset16),
-	KUNIT_CASE(string_test_memset32),
-	KUNIT_CASE(string_test_memset64),
-	KUNIT_CASE(string_test_strchr),
-	KUNIT_CASE(string_test_strnchr),
-	KUNIT_CASE(string_test_strspn),
-	KUNIT_CASE(string_test_strcmp),
-	KUNIT_CASE(string_test_strcmp_long_strings),
-	KUNIT_CASE(string_test_strncmp),
-	KUNIT_CASE(string_test_strncmp_long_strings),
-	KUNIT_CASE(string_test_strcasecmp),
-	KUNIT_CASE(string_test_strcasecmp_long_strings),
-	KUNIT_CASE(string_test_strncasecmp),
-	KUNIT_CASE(string_test_strncasecmp_long_strings),
-	KUNIT_CASE(string_test_strscpy),
-	KUNIT_CASE(string_test_strcat),
-	KUNIT_CASE(string_test_strncat),
-	KUNIT_CASE(string_test_strlcat),
-	KUNIT_CASE(string_test_strtomem),
-	KUNIT_CASE(string_test_memtostr),
-	{}
-};
-
-static struct kunit_suite string_test_suite = {
-	.name = "string",
-	.test_cases = string_test_cases,
-};
-
-kunit_test_suites(&string_test_suite);
-
-MODULE_DESCRIPTION("Test cases for string functions");
-MODULE_LICENSE("GPL v2");
diff --git a/lib/test_bits.c a/lib/test_bits.c
deleted file mode 100644
--- a/lib/test_bits.c
+++ /dev/null
@@ -1,110 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Test cases for functions and macros in bits.h
- */
-
-#include <kunit/test.h>
-#include <linux/bits.h>
-
-
-static void genmask_test(struct kunit *test)
-{
-	KUNIT_EXPECT_EQ(test, 1ul, GENMASK(0, 0));
-	KUNIT_EXPECT_EQ(test, 3ul, GENMASK(1, 0));
-	KUNIT_EXPECT_EQ(test, 6ul, GENMASK(2, 1));
-	KUNIT_EXPECT_EQ(test, 0xFFFFFFFFul, GENMASK(31, 0));
-
-#ifdef TEST_GENMASK_FAILURES
-	/* these should fail compilation */
-	GENMASK(0, 1);
-	GENMASK(0, 10);
-	GENMASK(9, 10);
-#endif
-
-
-}
-
-static void genmask_ull_test(struct kunit *test)
-{
-	KUNIT_EXPECT_EQ(test, 1ull, GENMASK_ULL(0, 0));
-	KUNIT_EXPECT_EQ(test, 3ull, GENMASK_ULL(1, 0));
-	KUNIT_EXPECT_EQ(test, 0x000000ffffe00000ull, GENMASK_ULL(39, 21));
-	KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_ULL(63, 0));
-
-#ifdef TEST_GENMASK_FAILURES
-	/* these should fail compilation */
-	GENMASK_ULL(0, 1);
-	GENMASK_ULL(0, 10);
-	GENMASK_ULL(9, 10);
-#endif
-}
-
-static void genmask_u128_test(struct kunit *test)
-{
-#ifdef CONFIG_ARCH_SUPPORTS_INT128
-	/* Below 64 bit masks */
-	KUNIT_EXPECT_EQ(test, 0x0000000000000001ull, GENMASK_U128(0, 0));
-	KUNIT_EXPECT_EQ(test, 0x0000000000000003ull, GENMASK_U128(1, 0));
-	KUNIT_EXPECT_EQ(test, 0x0000000000000006ull, GENMASK_U128(2, 1));
-	KUNIT_EXPECT_EQ(test, 0x00000000ffffffffull, GENMASK_U128(31, 0));
-	KUNIT_EXPECT_EQ(test, 0x000000ffffe00000ull, GENMASK_U128(39, 21));
-	KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(63, 0));
-
-	/* Above 64 bit masks - only 64 bit portion can be validated once */
-	KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(64, 0) >> 1);
-	KUNIT_EXPECT_EQ(test, 0x00000000ffffffffull, GENMASK_U128(81, 50) >> 50);
-	KUNIT_EXPECT_EQ(test, 0x0000000000ffffffull, GENMASK_U128(87, 64) >> 64);
-	KUNIT_EXPECT_EQ(test, 0x0000000000ff0000ull, GENMASK_U128(87, 80) >> 64);
-
-	KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(127, 0) >> 64);
-	KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, (u64)GENMASK_U128(127, 0));
-	KUNIT_EXPECT_EQ(test, 0x0000000000000003ull, GENMASK_U128(127, 126) >> 126);
-	KUNIT_EXPECT_EQ(test, 0x0000000000000001ull, GENMASK_U128(127, 127) >> 127);
-#ifdef TEST_GENMASK_FAILURES
-	/* these should fail compilation */
-	GENMASK_U128(0, 1);
-	GENMASK_U128(0, 10);
-	GENMASK_U128(9, 10);
-#endif /* TEST_GENMASK_FAILURES */
-#endif /* CONFIG_ARCH_SUPPORTS_INT128 */
-}
-
-static void genmask_input_check_test(struct kunit *test)
-{
-	unsigned int x, y;
-	int z, w;
-
-	/* Unknown input */
-	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, 0));
-	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, x));
-	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, y));
-
-	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, 0));
-	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, z));
-	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, w));
-
-	/* Valid input */
-	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(1, 1));
-	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(39, 21));
-	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(100, 80));
-	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(110, 65));
-	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(127, 0));
-}
-
-
-static struct kunit_case bits_test_cases[] = {
-	KUNIT_CASE(genmask_test),
-	KUNIT_CASE(genmask_ull_test),
-	KUNIT_CASE(genmask_u128_test),
-	KUNIT_CASE(genmask_input_check_test),
-	{}
-};
-
-static struct kunit_suite bits_test_suite = {
-	.name = "bits-test",
-	.test_cases = bits_test_cases,
-};
-kunit_test_suite(bits_test_suite);
-
-MODULE_DESCRIPTION("Test cases for functions and macros in bits.h");
-MODULE_LICENSE("GPL");
diff --git a/lib/test_fprobe.c a/lib/test_fprobe.c
deleted file mode 100644
--- a/lib/test_fprobe.c
+++ /dev/null
@@ -1,275 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * test_fprobe.c - simple sanity test for fprobe
- */
-
-#include <linux/kernel.h>
-#include <linux/fprobe.h>
-#include <linux/random.h>
-#include <kunit/test.h>
-
-#define div_factor 3
-
-static struct kunit *current_test;
-
-static u32 rand1, entry_val, exit_val;
-
-/* Use indirect calls to avoid inlining the target functions */
-static u32 (*target)(u32 value);
-static u32 (*target2)(u32 value);
-static u32 (*target_nest)(u32 value, u32 (*nest)(u32));
-static unsigned long target_ip;
-static unsigned long target2_ip;
-static unsigned long target_nest_ip;
-static int entry_return_value;
-
-static noinline u32 fprobe_selftest_target(u32 value)
-{
-	return (value / div_factor);
-}
-
-static noinline u32 fprobe_selftest_target2(u32 value)
-{
-	return (value / div_factor) + 1;
-}
-
-static noinline u32 fprobe_selftest_nest_target(u32 value, u32 (*nest)(u32))
-{
-	return nest(value + 2);
-}
-
-static notrace int fp_entry_handler(struct fprobe *fp, unsigned long ip,
-				    unsigned long ret_ip,
-				    struct pt_regs *regs, void *data)
-{
-	KUNIT_EXPECT_FALSE(current_test, preemptible());
-	/* This can be called on the fprobe_selftest_target and the fprobe_selftest_target2 */
-	if (ip != target_ip)
-		KUNIT_EXPECT_EQ(current_test, ip, target2_ip);
-	entry_val = (rand1 / div_factor);
-	if (fp->entry_data_size) {
-		KUNIT_EXPECT_NOT_NULL(current_test, data);
-		if (data)
-			*(u32 *)data = entry_val;
-	} else
-		KUNIT_EXPECT_NULL(current_test, data);
-
-	return entry_return_value;
-}
-
-static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip,
-				    unsigned long ret_ip,
-				    struct pt_regs *regs, void *data)
-{
-	unsigned long ret = regs_return_value(regs);
-
-	KUNIT_EXPECT_FALSE(current_test, preemptible());
-	if (ip != target_ip) {
-		KUNIT_EXPECT_EQ(current_test, ip, target2_ip);
-		KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor) + 1);
-	} else
-		KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor));
-	KUNIT_EXPECT_EQ(current_test, entry_val, (rand1 / div_factor));
-	exit_val = entry_val + div_factor;
-	if (fp->entry_data_size) {
-		KUNIT_EXPECT_NOT_NULL(current_test, data);
-		if (data)
-			KUNIT_EXPECT_EQ(current_test, *(u32 *)data, entry_val);
-	} else
-		KUNIT_EXPECT_NULL(current_test, data);
-}
-
-static notrace int nest_entry_handler(struct fprobe *fp, unsigned long ip,
-				      unsigned long ret_ip,
-				      struct pt_regs *regs, void *data)
-{
-	KUNIT_EXPECT_FALSE(current_test, preemptible());
-	return 0;
-}
-
-static notrace void nest_exit_handler(struct fprobe *fp, unsigned long ip,
-				      unsigned long ret_ip,
-				      struct pt_regs *regs, void *data)
-{
-	KUNIT_EXPECT_FALSE(current_test, preemptible());
-	KUNIT_EXPECT_EQ(current_test, ip, target_nest_ip);
-}
-
-/* Test entry only (no rethook) */
-static void test_fprobe_entry(struct kunit *test)
-{
-	struct fprobe fp_entry = {
-		.entry_handler = fp_entry_handler,
-	};
-
-	current_test = test;
-
-	/* Before register, unregister should be failed. */
-	KUNIT_EXPECT_NE(test, 0, unregister_fprobe(&fp_entry));
-	KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp_entry, "fprobe_selftest_target*", NULL));
-
-	entry_val = 0;
-	exit_val = 0;
-	target(rand1);
-	KUNIT_EXPECT_NE(test, 0, entry_val);
-	KUNIT_EXPECT_EQ(test, 0, exit_val);
-
-	entry_val = 0;
-	exit_val = 0;
-	target2(rand1);
-	KUNIT_EXPECT_NE(test, 0, entry_val);
-	KUNIT_EXPECT_EQ(test, 0, exit_val);
-
-	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp_entry));
-}
-
-static void test_fprobe(struct kunit *test)
-{
-	struct fprobe fp = {
-		.entry_handler = fp_entry_handler,
-		.exit_handler = fp_exit_handler,
-	};
-
-	current_test = test;
-	KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp, "fprobe_selftest_target*", NULL));
-
-	entry_val = 0;
-	exit_val = 0;
-	target(rand1);
-	KUNIT_EXPECT_NE(test, 0, entry_val);
-	KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
-
-	entry_val = 0;
-	exit_val = 0;
-	target2(rand1);
-	KUNIT_EXPECT_NE(test, 0, entry_val);
-	KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
-
-	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
-}
-
-static void test_fprobe_syms(struct kunit *test)
-{
-	static const char *syms[] = {"fprobe_selftest_target", "fprobe_selftest_target2"};
-	struct fprobe fp = {
-		.entry_handler = fp_entry_handler,
-		.exit_handler = fp_exit_handler,
-	};
-
-	current_test = test;
-	KUNIT_EXPECT_EQ(test, 0, register_fprobe_syms(&fp, syms, 2));
-
-	entry_val = 0;
-	exit_val = 0;
-	target(rand1);
-	KUNIT_EXPECT_NE(test, 0, entry_val);
-	KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
-
-	entry_val = 0;
-	exit_val = 0;
-	target2(rand1);
-	KUNIT_EXPECT_NE(test, 0, entry_val);
-	KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
-
-	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
-}
-
-/* Test private entry_data */
-static void test_fprobe_data(struct kunit *test)
-{
-	struct fprobe fp = {
-		.entry_handler = fp_entry_handler,
-		.exit_handler = fp_exit_handler,
-		.entry_data_size = sizeof(u32),
-	};
-
-	current_test = test;
-	KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp, "fprobe_selftest_target", NULL));
-
-	target(rand1);
-
-	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
-}
-
-/* Test nr_maxactive */
-static void test_fprobe_nest(struct kunit *test)
-{
-	static const char *syms[] = {"fprobe_selftest_target", "fprobe_selftest_nest_target"};
-	struct fprobe fp = {
-		.entry_handler = nest_entry_handler,
-		.exit_handler = nest_exit_handler,
-		.nr_maxactive = 1,
-	};
-
-	current_test = test;
-	KUNIT_EXPECT_EQ(test, 0, register_fprobe_syms(&fp, syms, 2));
-
-	target_nest(rand1, target);
-	KUNIT_EXPECT_EQ(test, 1, fp.nmissed);
-
-	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
-}
-
-static void test_fprobe_skip(struct kunit *test)
-{
-	struct fprobe fp = {
-		.entry_handler = fp_entry_handler,
-		.exit_handler = fp_exit_handler,
-	};
-
-	current_test = test;
-	KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp, "fprobe_selftest_target", NULL));
-
-	entry_return_value = 1;
-	entry_val = 0;
-	exit_val = 0;
-	target(rand1);
-	KUNIT_EXPECT_NE(test, 0, entry_val);
-	KUNIT_EXPECT_EQ(test, 0, exit_val);
-	KUNIT_EXPECT_EQ(test, 0, fp.nmissed);
-	entry_return_value = 0;
-
-	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
-}
-
-static unsigned long get_ftrace_location(void *func)
-{
-	unsigned long size, addr = (unsigned long)func;
-
-	if (!kallsyms_lookup_size_offset(addr, &size, NULL) || !size)
-		return 0;
-
-	return ftrace_location_range(addr, addr + size - 1);
-}
-
-static int fprobe_test_init(struct kunit *test)
-{
-	rand1 = get_random_u32_above(div_factor);
-	target = fprobe_selftest_target;
-	target2 = fprobe_selftest_target2;
-	target_nest = fprobe_selftest_nest_target;
-	target_ip = get_ftrace_location(target);
-	target2_ip = get_ftrace_location(target2);
-	target_nest_ip = get_ftrace_location(target_nest);
-
-	return 0;
-}
-
-static struct kunit_case fprobe_testcases[] = {
-	KUNIT_CASE(test_fprobe_entry),
-	KUNIT_CASE(test_fprobe),
-	KUNIT_CASE(test_fprobe_syms),
-	KUNIT_CASE(test_fprobe_data),
-	KUNIT_CASE(test_fprobe_nest),
-	KUNIT_CASE(test_fprobe_skip),
-	{}
-};
-
-static struct kunit_suite fprobe_test_suite = {
-	.name = "fprobe_test",
-	.init = fprobe_test_init,
-	.test_cases = fprobe_testcases,
-};
-
-kunit_test_suites(&fprobe_test_suite);
-
diff --git a/lib/test_hash.c a/lib/test_hash.c
deleted file mode 100644
--- a/lib/test_hash.c
+++ /dev/null
@@ -1,239 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Test cases for <linux/hash.h> and <linux/stringhash.h>
- * This just verifies that various ways of computing a hash
- * produce the same thing and, for cases where a k-bit hash
- * value is requested, is of the requested size.
- *
- * We fill a buffer with a 255-byte null-terminated string,
- * and use both full_name_hash() and hashlen_string() to hash the
- * substrings from i to j, where 0 <= i < j < 256.
- *
- * The returned values are used to check that __hash_32() and
- * __hash_32_generic() compute the same thing.  Likewise hash_32()
- * and hash_64().
- */
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/module.h>
-#include <linux/hash.h>
-#include <linux/stringhash.h>
-#include <kunit/test.h>
-
-/* 32-bit XORSHIFT generator.  Seed must not be zero. */
-static u32 __attribute_const__
-xorshift(u32 seed)
-{
-	seed ^= seed << 13;
-	seed ^= seed >> 17;
-	seed ^= seed << 5;
-	return seed;
-}
-
-/* Given a non-zero x, returns a non-zero byte. */
-static u8 __attribute_const__
-mod255(u32 x)
-{
-	x = (x & 0xffff) + (x >> 16);	/* 1 <= x <= 0x1fffe */
-	x = (x & 0xff) + (x >> 8);	/* 1 <= x <= 0x2fd */
-	x = (x & 0xff) + (x >> 8);	/* 1 <= x <= 0x100 */
-	x = (x & 0xff) + (x >> 8);	/* 1 <= x <= 0xff */
-	return x;
-}
-
-/* Fill the buffer with non-zero bytes. */
-static void fill_buf(char *buf, size_t len, u32 seed)
-{
-	size_t i;
-
-	for (i = 0; i < len; i++) {
-		seed = xorshift(seed);
-		buf[i] = mod255(seed);
-	}
-}
-
-/* Holds most testing variables for the int test. */
-struct test_hash_params {
-        /* Pointer to integer to be hashed. */
-	unsigned long long *h64;
-        /* Low 32-bits of integer to be hashed. */
-	u32 h0;
-        /* Arch-specific hash result. */
-	u32 h1;
-        /* Generic hash result. */
-	u32 h2;
-        /* ORed hashes of given size (in bits). */
-	u32 (*hash_or)[33];
-};
-
-#ifdef HAVE_ARCH__HASH_32
-static void
-test_int__hash_32(struct kunit *test, struct test_hash_params *params)
-{
-	params->hash_or[1][0] |= params->h2 = __hash_32_generic(params->h0);
-#if HAVE_ARCH__HASH_32 == 1
-	KUNIT_EXPECT_EQ_MSG(test, params->h1, params->h2,
-			    "__hash_32(%#x) = %#x != __hash_32_generic() = %#x",
-			    params->h0, params->h1, params->h2);
-#endif
-}
-#endif
-
-#ifdef HAVE_ARCH_HASH_64
-static void
-test_int_hash_64(struct kunit *test, struct test_hash_params *params, u32 const *m, int *k)
-{
-	params->h2 = hash_64_generic(*params->h64, *k);
-#if HAVE_ARCH_HASH_64 == 1
-	KUNIT_EXPECT_EQ_MSG(test, params->h1, params->h2,
-			    "hash_64(%#llx, %d) = %#x != hash_64_generic() = %#x",
-			    *params->h64, *k, params->h1, params->h2);
-#else
-	KUNIT_EXPECT_LE_MSG(test, params->h1, params->h2,
-			    "hash_64_generic(%#llx, %d) = %#x > %#x",
-			    *params->h64, *k, params->h1, *m);
-#endif
-}
-#endif
-
-/*
- * Test the various integer hash functions.  h64 (or its low-order bits)
- * is the integer to hash.  hash_or accumulates the OR of the hash values,
- * which are later checked to see that they cover all the requested bits.
- *
- * Because these functions (as opposed to the string hashes) are all
- * inline, the code being tested is actually in the module, and you can
- * recompile and re-test the module without rebooting.
- */
-static void
-test_int_hash(struct kunit *test, unsigned long long h64, u32 hash_or[2][33])
-{
-	int k;
-	struct test_hash_params params = { &h64, (u32)h64, 0, 0, hash_or };
-
-	/* Test __hash32 */
-	hash_or[0][0] |= params.h1 = __hash_32(params.h0);
-#ifdef HAVE_ARCH__HASH_32
-	test_int__hash_32(test, &params);
-#endif
-
-	/* Test k = 1..32 bits */
-	for (k = 1; k <= 32; k++) {
-		u32 const m = ((u32)2 << (k-1)) - 1;	/* Low k bits set */
-
-		/* Test hash_32 */
-		hash_or[0][k] |= params.h1 = hash_32(params.h0, k);
-		KUNIT_EXPECT_LE_MSG(test, params.h1, m,
-				    "hash_32(%#x, %d) = %#x > %#x",
-				    params.h0, k, params.h1, m);
-
-		/* Test hash_64 */
-		hash_or[1][k] |= params.h1 = hash_64(h64, k);
-		KUNIT_EXPECT_LE_MSG(test, params.h1, m,
-				    "hash_64(%#llx, %d) = %#x > %#x",
-				    h64, k, params.h1, m);
-#ifdef HAVE_ARCH_HASH_64
-		test_int_hash_64(test, &params, &m, &k);
-#endif
-	}
-}
-
-#define SIZE 256	/* Run time is cubic in SIZE */
-
-static void test_string_or(struct kunit *test)
-{
-	char buf[SIZE+1];
-	u32 string_or = 0;
-	int i, j;
-
-	fill_buf(buf, SIZE, 1);
-
-	/* Test every possible non-empty substring in the buffer. */
-	for (j = SIZE; j > 0; --j) {
-		buf[j] = '\0';
-
-		for (i = 0; i <= j; i++) {
-			u32 h0 = full_name_hash(buf+i, buf+i, j-i);
-
-			string_or |= h0;
-		} /* i */
-	} /* j */
-
-	/* The OR of all the hash values should cover all the bits */
-	KUNIT_EXPECT_EQ_MSG(test, string_or, -1u,
-			    "OR of all string hash results = %#x != %#x",
-			    string_or, -1u);
-}
-
-static void test_hash_or(struct kunit *test)
-{
-	char buf[SIZE+1];
-	u32 hash_or[2][33] = { { 0, } };
-	unsigned long long h64 = 0;
-	int i, j;
-
-	fill_buf(buf, SIZE, 1);
-
-	/* Test every possible non-empty substring in the buffer. */
-	for (j = SIZE; j > 0; --j) {
-		buf[j] = '\0';
-
-		for (i = 0; i <= j; i++) {
-			u64 hashlen = hashlen_string(buf+i, buf+i);
-			u32 h0 = full_name_hash(buf+i, buf+i, j-i);
-
-			/* Check that hashlen_string gets the length right */
-			KUNIT_EXPECT_EQ_MSG(test, hashlen_len(hashlen), j-i,
-					    "hashlen_string(%d..%d) returned length %u, expected %d",
-					    i, j, hashlen_len(hashlen), j-i);
-			/* Check that the hashes match */
-			KUNIT_EXPECT_EQ_MSG(test, hashlen_hash(hashlen), h0,
-					    "hashlen_string(%d..%d) = %08x != full_name_hash() = %08x",
-					    i, j, hashlen_hash(hashlen), h0);
-
-			h64 = h64 << 32 | h0;	/* For use with hash_64 */
-			test_int_hash(test, h64, hash_or);
-		} /* i */
-	} /* j */
-
-	KUNIT_EXPECT_EQ_MSG(test, hash_or[0][0], -1u,
-			    "OR of all __hash_32 results = %#x != %#x",
-			    hash_or[0][0], -1u);
-#ifdef HAVE_ARCH__HASH_32
-#if HAVE_ARCH__HASH_32 != 1	/* Test is pointless if results match */
-	KUNIT_EXPECT_EQ_MSG(test, hash_or[1][0], -1u,
-			    "OR of all __hash_32_generic results = %#x != %#x",
-			    hash_or[1][0], -1u);
-#endif
-#endif
-
-	/* Likewise for all the i-bit hash values */
-	for (i = 1; i <= 32; i++) {
-		u32 const m = ((u32)2 << (i-1)) - 1;	/* Low i bits set */
-
-		KUNIT_EXPECT_EQ_MSG(test, hash_or[0][i], m,
-				    "OR of all hash_32(%d) results = %#x (%#x expected)",
-				    i, hash_or[0][i], m);
-		KUNIT_EXPECT_EQ_MSG(test, hash_or[1][i], m,
-				    "OR of all hash_64(%d) results = %#x (%#x expected)",
-				    i, hash_or[1][i], m);
-	}
-}
-
-static struct kunit_case hash_test_cases[] __refdata = {
-	KUNIT_CASE(test_string_or),
-	KUNIT_CASE(test_hash_or),
-	{}
-};
-
-static struct kunit_suite hash_test_suite = {
-	.name = "hash",
-	.test_cases = hash_test_cases,
-};
-
-
-kunit_test_suite(hash_test_suite);
-
-MODULE_DESCRIPTION("Test cases for <linux/hash.h> and <linux/stringhash.h>");
-MODULE_LICENSE("GPL");
diff --git a/lib/test_kprobes.c a/lib/test_kprobes.c
deleted file mode 100644
--- a/lib/test_kprobes.c
+++ /dev/null
@@ -1,404 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * test_kprobes.c - simple sanity test for k*probes
- *
- * Copyright IBM Corp. 2008
- */
-
-#include <linux/kernel.h>
-#include <linux/kprobes.h>
-#include <linux/random.h>
-#include <kunit/test.h>
-
-#define div_factor 3
-
-static u32 rand1, preh_val, posth_val;
-static u32 (*target)(u32 value);
-static u32 (*recursed_target)(u32 value);
-static u32 (*target2)(u32 value);
-static struct kunit *current_test;
-
-static unsigned long (*internal_target)(void);
-static unsigned long (*stacktrace_target)(void);
-static unsigned long (*stacktrace_driver)(void);
-static unsigned long target_return_address[2];
-
-static noinline u32 kprobe_target(u32 value)
-{
-	return (value / div_factor);
-}
-
-static noinline u32 kprobe_recursed_target(u32 value)
-{
-	return (value / div_factor);
-}
-
-static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
-{
-	KUNIT_EXPECT_FALSE(current_test, preemptible());
-
-	preh_val = recursed_target(rand1);
-	return 0;
-}
-
-static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
-		unsigned long flags)
-{
-	u32 expval = recursed_target(rand1);
-
-	KUNIT_EXPECT_FALSE(current_test, preemptible());
-	KUNIT_EXPECT_EQ(current_test, preh_val, expval);
-
-	posth_val = preh_val + div_factor;
-}
-
-static struct kprobe kp = {
-	.symbol_name = "kprobe_target",
-	.pre_handler = kp_pre_handler,
-	.post_handler = kp_post_handler
-};
-
-static void test_kprobe(struct kunit *test)
-{
-	current_test = test;
-	KUNIT_EXPECT_EQ(test, 0, register_kprobe(&kp));
-	target(rand1);
-	unregister_kprobe(&kp);
-	KUNIT_EXPECT_NE(test, 0, preh_val);
-	KUNIT_EXPECT_NE(test, 0, posth_val);
-}
-
-static noinline u32 kprobe_target2(u32 value)
-{
-	return (value / div_factor) + 1;
-}
-
-static noinline unsigned long kprobe_stacktrace_internal_target(void)
-{
-	if (!target_return_address[0])
-		target_return_address[0] = (unsigned long)__builtin_return_address(0);
-	return target_return_address[0];
-}
-
-static noinline unsigned long kprobe_stacktrace_target(void)
-{
-	if (!target_return_address[1])
-		target_return_address[1] = (unsigned long)__builtin_return_address(0);
-
-	if (internal_target)
-		internal_target();
-
-	return target_return_address[1];
-}
-
-static noinline unsigned long kprobe_stacktrace_driver(void)
-{
-	if (stacktrace_target)
-		stacktrace_target();
-
-	/* This is for preventing inlining the function */
-	return (unsigned long)__builtin_return_address(0);
-}
-
-static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
-{
-	preh_val = (rand1 / div_factor) + 1;
-	return 0;
-}
-
-static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
-		unsigned long flags)
-{
-	KUNIT_EXPECT_EQ(current_test, preh_val, (rand1 / div_factor) + 1);
-	posth_val = preh_val + div_factor;
-}
-
-static struct kprobe kp2 = {
-	.symbol_name = "kprobe_target2",
-	.pre_handler = kp_pre_handler2,
-	.post_handler = kp_post_handler2
-};
-
-static void test_kprobes(struct kunit *test)
-{
-	struct kprobe *kps[2] = {&kp, &kp2};
-
-	current_test = test;
-
-	/* addr and flags should be cleard for reusing kprobe. */
-	kp.addr = NULL;
-	kp.flags = 0;
-
-	KUNIT_EXPECT_EQ(test, 0, register_kprobes(kps, 2));
-	preh_val = 0;
-	posth_val = 0;
-	target(rand1);
-
-	KUNIT_EXPECT_NE(test, 0, preh_val);
-	KUNIT_EXPECT_NE(test, 0, posth_val);
-
-	preh_val = 0;
-	posth_val = 0;
-	target2(rand1);
-
-	KUNIT_EXPECT_NE(test, 0, preh_val);
-	KUNIT_EXPECT_NE(test, 0, posth_val);
-	unregister_kprobes(kps, 2);
-}
-
-static struct kprobe kp_missed = {
-	.symbol_name = "kprobe_recursed_target",
-	.pre_handler = kp_pre_handler,
-	.post_handler = kp_post_handler,
-};
-
-static void test_kprobe_missed(struct kunit *test)
-{
-	current_test = test;
-	preh_val = 0;
-	posth_val = 0;
-
-	KUNIT_EXPECT_EQ(test, 0, register_kprobe(&kp_missed));
-
-	recursed_target(rand1);
-
-	KUNIT_EXPECT_EQ(test, 2, kp_missed.nmissed);
-	KUNIT_EXPECT_NE(test, 0, preh_val);
-	KUNIT_EXPECT_NE(test, 0, posth_val);
-
-	unregister_kprobe(&kp_missed);
-}
-
-#ifdef CONFIG_KRETPROBES
-static u32 krph_val;
-
-static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
-	KUNIT_EXPECT_FALSE(current_test, preemptible());
-	krph_val = (rand1 / div_factor);
-	return 0;
-}
-
-static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
-	unsigned long ret = regs_return_value(regs);
-
-	KUNIT_EXPECT_FALSE(current_test, preemptible());
-	KUNIT_EXPECT_EQ(current_test, ret, rand1 / div_factor);
-	KUNIT_EXPECT_NE(current_test, krph_val, 0);
-	krph_val = rand1;
-	return 0;
-}
-
-static struct kretprobe rp = {
-	.handler	= return_handler,
-	.entry_handler  = entry_handler,
-	.kp.symbol_name = "kprobe_target"
-};
-
-static void test_kretprobe(struct kunit *test)
-{
-	current_test = test;
-	KUNIT_EXPECT_EQ(test, 0, register_kretprobe(&rp));
-	target(rand1);
-	unregister_kretprobe(&rp);
-	KUNIT_EXPECT_EQ(test, krph_val, rand1);
-}
-
-static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
-	unsigned long ret = regs_return_value(regs);
-
-	KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor) + 1);
-	KUNIT_EXPECT_NE(current_test, krph_val, 0);
-	krph_val = rand1;
-	return 0;
-}
-
-static struct kretprobe rp2 = {
-	.handler	= return_handler2,
-	.entry_handler  = entry_handler,
-	.kp.symbol_name = "kprobe_target2"
-};
-
-static void test_kretprobes(struct kunit *test)
-{
-	struct kretprobe *rps[2] = {&rp, &rp2};
-
-	current_test = test;
-	/* addr and flags should be cleard for reusing kprobe. */
-	rp.kp.addr = NULL;
-	rp.kp.flags = 0;
-	KUNIT_EXPECT_EQ(test, 0, register_kretprobes(rps, 2));
-
-	krph_val = 0;
-	target(rand1);
-	KUNIT_EXPECT_EQ(test, krph_val, rand1);
-
-	krph_val = 0;
-	target2(rand1);
-	KUNIT_EXPECT_EQ(test, krph_val, rand1);
-	unregister_kretprobes(rps, 2);
-}
-
-#ifdef CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
-#define STACK_BUF_SIZE 16
-static unsigned long stack_buf[STACK_BUF_SIZE];
-
-static int stacktrace_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
-	unsigned long retval = regs_return_value(regs);
-	int i, ret;
-
-	KUNIT_EXPECT_FALSE(current_test, preemptible());
-	KUNIT_EXPECT_EQ(current_test, retval, target_return_address[1]);
-
-	/*
-	 * Test stacktrace inside the kretprobe handler, this will involves
-	 * kretprobe trampoline, but must include correct return address
-	 * of the target function.
-	 */
-	ret = stack_trace_save(stack_buf, STACK_BUF_SIZE, 0);
-	KUNIT_EXPECT_NE(current_test, ret, 0);
-
-	for (i = 0; i < ret; i++) {
-		if (stack_buf[i] == target_return_address[1])
-			break;
-	}
-	KUNIT_EXPECT_NE(current_test, i, ret);
-
-#if !IS_MODULE(CONFIG_KPROBES_SANITY_TEST)
-	/*
-	 * Test stacktrace from pt_regs at the return address. Thus the stack
-	 * trace must start from the target return address.
-	 */
-	ret = stack_trace_save_regs(regs, stack_buf, STACK_BUF_SIZE, 0);
-	KUNIT_EXPECT_NE(current_test, ret, 0);
-	KUNIT_EXPECT_EQ(current_test, stack_buf[0], target_return_address[1]);
-#endif
-
-	return 0;
-}
-
-static struct kretprobe rp3 = {
-	.handler	= stacktrace_return_handler,
-	.kp.symbol_name = "kprobe_stacktrace_target"
-};
-
-static void test_stacktrace_on_kretprobe(struct kunit *test)
-{
-	unsigned long myretaddr = (unsigned long)__builtin_return_address(0);
-
-	current_test = test;
-	rp3.kp.addr = NULL;
-	rp3.kp.flags = 0;
-
-	/*
-	 * Run the stacktrace_driver() to record correct return address in
-	 * stacktrace_target() and ensure stacktrace_driver() call is not
-	 * inlined by checking the return address of stacktrace_driver()
-	 * and the return address of this function is different.
-	 */
-	KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
-
-	KUNIT_ASSERT_EQ(test, 0, register_kretprobe(&rp3));
-	KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
-	unregister_kretprobe(&rp3);
-}
-
-static int stacktrace_internal_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
-{
-	unsigned long retval = regs_return_value(regs);
-	int i, ret;
-
-	KUNIT_EXPECT_FALSE(current_test, preemptible());
-	KUNIT_EXPECT_EQ(current_test, retval, target_return_address[0]);
-
-	/*
-	 * Test stacktrace inside the kretprobe handler for nested case.
-	 * The unwinder will find the kretprobe_trampoline address on the
-	 * return address, and kretprobe must solve that.
-	 */
-	ret = stack_trace_save(stack_buf, STACK_BUF_SIZE, 0);
-	KUNIT_EXPECT_NE(current_test, ret, 0);
-
-	for (i = 0; i < ret - 1; i++) {
-		if (stack_buf[i] == target_return_address[0]) {
-			KUNIT_EXPECT_EQ(current_test, stack_buf[i + 1], target_return_address[1]);
-			break;
-		}
-	}
-	KUNIT_EXPECT_NE(current_test, i, ret);
-
-#if !IS_MODULE(CONFIG_KPROBES_SANITY_TEST)
-	/* Ditto for the regs version. */
-	ret = stack_trace_save_regs(regs, stack_buf, STACK_BUF_SIZE, 0);
-	KUNIT_EXPECT_NE(current_test, ret, 0);
-	KUNIT_EXPECT_EQ(current_test, stack_buf[0], target_return_address[0]);
-	KUNIT_EXPECT_EQ(current_test, stack_buf[1], target_return_address[1]);
-#endif
-
-	return 0;
-}
-
-static struct kretprobe rp4 = {
-	.handler	= stacktrace_internal_return_handler,
-	.kp.symbol_name = "kprobe_stacktrace_internal_target"
-};
-
-static void test_stacktrace_on_nested_kretprobe(struct kunit *test)
-{
-	unsigned long myretaddr = (unsigned long)__builtin_return_address(0);
-	struct kretprobe *rps[2] = {&rp3, &rp4};
-
-	current_test = test;
-	rp3.kp.addr = NULL;
-	rp3.kp.flags = 0;
-
-	//KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
-
-	KUNIT_ASSERT_EQ(test, 0, register_kretprobes(rps, 2));
-	KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
-	unregister_kretprobes(rps, 2);
-}
-#endif /* CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE */
-
-#endif /* CONFIG_KRETPROBES */
-
-static int kprobes_test_init(struct kunit *test)
-{
-	target = kprobe_target;
-	target2 = kprobe_target2;
-	recursed_target = kprobe_recursed_target;
-	stacktrace_target = kprobe_stacktrace_target;
-	internal_target = kprobe_stacktrace_internal_target;
-	stacktrace_driver = kprobe_stacktrace_driver;
-	rand1 = get_random_u32_above(div_factor);
-	return 0;
-}
-
-static struct kunit_case kprobes_testcases[] = {
-	KUNIT_CASE(test_kprobe),
-	KUNIT_CASE(test_kprobes),
-	KUNIT_CASE(test_kprobe_missed),
-#ifdef CONFIG_KRETPROBES
-	KUNIT_CASE(test_kretprobe),
-	KUNIT_CASE(test_kretprobes),
-#ifdef CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
-	KUNIT_CASE(test_stacktrace_on_kretprobe),
-	KUNIT_CASE(test_stacktrace_on_nested_kretprobe),
-#endif
-#endif
-	{}
-};
-
-static struct kunit_suite kprobes_test_suite = {
-	.name = "kprobes_test",
-	.init = kprobes_test_init,
-	.test_cases = kprobes_testcases,
-};
-
-kunit_test_suites(&kprobes_test_suite);
-
-MODULE_DESCRIPTION("simple sanity test for k*probes");
-MODULE_LICENSE("GPL");
diff --git a/lib/test_linear_ranges.c a/lib/test_linear_ranges.c
deleted file mode 100644
--- a/lib/test_linear_ranges.c
+++ /dev/null
@@ -1,220 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * KUnit test for the linear_ranges helper.
- *
- * Copyright (C) 2020, ROHM Semiconductors.
- * Author: Matti Vaittinen <matti.vaittien@xxxxxxxxxxxxxxxxx>
- */
-#include <kunit/test.h>
-
-#include <linux/linear_range.h>
-
-/* First things first. I deeply dislike unit-tests. I have seen all the hell
- * breaking loose when people who think the unit tests are "the silver bullet"
- * to kill bugs get to decide how a company should implement testing strategy...
- *
- * Believe me, it may get _really_ ridiculous. It is tempting to think that
- * walking through all the possible execution branches will nail down 100% of
- * bugs. This may lead to ideas about demands to get certain % of "test
- * coverage" - measured as line coverage. And that is one of the worst things
- * you can do.
- *
- * Ask people to provide line coverage and they do. I've seen clever tools
- * which generate test cases to test the existing functions - and by default
- * these tools expect code to be correct and just generate checks which are
- * passing when ran against current code-base. Run this generator and you'll get
- * tests that do not test code is correct but just verify nothing changes.
- * Problem is that testing working code is pointless. And if it is not
- * working, your test must not assume it is working. You won't catch any bugs
- * by such tests. What you can do is to generate a huge amount of tests.
- * Especially if you were are asked to proivde 100% line-coverage x_x. So what
- * does these tests - which are not finding any bugs now - do?
- *
- * They add inertia to every future development. I think it was Terry Pratchet
- * who wrote someone having same impact as thick syrup has to chronometre.
- * Excessive amount of unit-tests have this effect to development. If you do
- * actually find _any_ bug from code in such environment and try fixing it...
- * ...chances are you also need to fix the test cases. In sunny day you fix one
- * test. But I've done refactoring which resulted 500+ broken tests (which had
- * really zero value other than proving to managers that we do do "quality")...
- *
- * After this being said - there are situations where UTs can be handy. If you
- * have algorithms which take some input and should produce output - then you
- * can implement few, carefully selected simple UT-cases which test this. I've
- * previously used this for example for netlink and device-tree data parsing
- * functions. Feed some data examples to functions and verify the output is as
- * expected. I am not covering all the cases but I will see the logic should be
- * working.
- *
- * Here we also do some minor testing. I don't want to go through all branches
- * or test more or less obvious things - but I want to see the main logic is
- * working. And I definitely don't want to add 500+ test cases that break when
- * some simple fix is done x_x. So - let's only add few, well selected tests
- * which ensure as much logic is good as possible.
- */
-
-/*
- * Test Range 1:
- * selectors:	2	3	4	5	6
- * values (5):	10	20	30	40	50
- *
- * Test Range 2:
- * selectors:	7	8	9	10
- * values (4):	100	150	200	250
- */
-
-#define RANGE1_MIN 10
-#define RANGE1_MIN_SEL 2
-#define RANGE1_STEP 10
-
-/* 2, 3, 4, 5, 6 */
-static const unsigned int range1_sels[] = { RANGE1_MIN_SEL, RANGE1_MIN_SEL + 1,
-					    RANGE1_MIN_SEL + 2,
-					    RANGE1_MIN_SEL + 3,
-					    RANGE1_MIN_SEL + 4 };
-/* 10, 20, 30, 40, 50 */
-static const unsigned int range1_vals[] = { RANGE1_MIN, RANGE1_MIN +
-					    RANGE1_STEP,
-					    RANGE1_MIN + RANGE1_STEP * 2,
-					    RANGE1_MIN + RANGE1_STEP * 3,
-					    RANGE1_MIN + RANGE1_STEP * 4 };
-
-#define RANGE2_MIN 100
-#define RANGE2_MIN_SEL 7
-#define RANGE2_STEP 50
-
-/*  7, 8, 9, 10 */
-static const unsigned int range2_sels[] = { RANGE2_MIN_SEL, RANGE2_MIN_SEL + 1,
-					    RANGE2_MIN_SEL + 2,
-					    RANGE2_MIN_SEL + 3 };
-/* 100, 150, 200, 250 */
-static const unsigned int range2_vals[] = { RANGE2_MIN, RANGE2_MIN +
-					    RANGE2_STEP,
-					    RANGE2_MIN + RANGE2_STEP * 2,
-					    RANGE2_MIN + RANGE2_STEP * 3 };
-
-#define RANGE1_NUM_VALS (ARRAY_SIZE(range1_vals))
-#define RANGE2_NUM_VALS (ARRAY_SIZE(range2_vals))
-#define RANGE_NUM_VALS (RANGE1_NUM_VALS + RANGE2_NUM_VALS)
-
-#define RANGE1_MAX_SEL (RANGE1_MIN_SEL + RANGE1_NUM_VALS - 1)
-#define RANGE1_MAX_VAL (range1_vals[RANGE1_NUM_VALS - 1])
-
-#define RANGE2_MAX_SEL (RANGE2_MIN_SEL + RANGE2_NUM_VALS - 1)
-#define RANGE2_MAX_VAL (range2_vals[RANGE2_NUM_VALS - 1])
-
-#define SMALLEST_SEL RANGE1_MIN_SEL
-#define SMALLEST_VAL RANGE1_MIN
-
-static struct linear_range testr[] = {
-	LINEAR_RANGE(RANGE1_MIN, RANGE1_MIN_SEL, RANGE1_MAX_SEL, RANGE1_STEP),
-	LINEAR_RANGE(RANGE2_MIN, RANGE2_MIN_SEL, RANGE2_MAX_SEL, RANGE2_STEP),
-};
-
-static void range_test_get_value(struct kunit *test)
-{
-	int ret, i;
-	unsigned int sel, val;
-
-	for (i = 0; i < RANGE1_NUM_VALS; i++) {
-		sel = range1_sels[i];
-		ret = linear_range_get_value_array(&testr[0], 2, sel, &val);
-		KUNIT_EXPECT_EQ(test, 0, ret);
-		KUNIT_EXPECT_EQ(test, val, range1_vals[i]);
-	}
-	for (i = 0; i < RANGE2_NUM_VALS; i++) {
-		sel = range2_sels[i];
-		ret = linear_range_get_value_array(&testr[0], 2, sel, &val);
-		KUNIT_EXPECT_EQ(test, 0, ret);
-		KUNIT_EXPECT_EQ(test, val, range2_vals[i]);
-	}
-	ret = linear_range_get_value_array(&testr[0], 2, sel + 1, &val);
-	KUNIT_EXPECT_NE(test, 0, ret);
-}
-
-static void range_test_get_selector_high(struct kunit *test)
-{
-	int ret, i;
-	unsigned int sel;
-	bool found;
-
-	for (i = 0; i < RANGE1_NUM_VALS; i++) {
-		ret = linear_range_get_selector_high(&testr[0], range1_vals[i],
-						     &sel, &found);
-		KUNIT_EXPECT_EQ(test, 0, ret);
-		KUNIT_EXPECT_EQ(test, sel, range1_sels[i]);
-		KUNIT_EXPECT_TRUE(test, found);
-	}
-
-	ret = linear_range_get_selector_high(&testr[0], RANGE1_MAX_VAL + 1,
-					     &sel, &found);
-	KUNIT_EXPECT_LE(test, ret, 0);
-
-	ret = linear_range_get_selector_high(&testr[0], RANGE1_MIN - 1,
-					     &sel, &found);
-	KUNIT_EXPECT_EQ(test, 0, ret);
-	KUNIT_EXPECT_FALSE(test, found);
-	KUNIT_EXPECT_EQ(test, sel, range1_sels[0]);
-}
-
-static void range_test_get_value_amount(struct kunit *test)
-{
-	int ret;
-
-	ret = linear_range_values_in_range_array(&testr[0], 2);
-	KUNIT_EXPECT_EQ(test, (int)RANGE_NUM_VALS, ret);
-}
-
-static void range_test_get_selector_low(struct kunit *test)
-{
-	int i, ret;
-	unsigned int sel;
-	bool found;
-
-	for (i = 0; i < RANGE1_NUM_VALS; i++) {
-		ret = linear_range_get_selector_low_array(&testr[0], 2,
-							  range1_vals[i], &sel,
-							  &found);
-		KUNIT_EXPECT_EQ(test, 0, ret);
-		KUNIT_EXPECT_EQ(test, sel, range1_sels[i]);
-		KUNIT_EXPECT_TRUE(test, found);
-	}
-	for (i = 0; i < RANGE2_NUM_VALS; i++) {
-		ret = linear_range_get_selector_low_array(&testr[0], 2,
-							  range2_vals[i], &sel,
-							  &found);
-		KUNIT_EXPECT_EQ(test, 0, ret);
-		KUNIT_EXPECT_EQ(test, sel, range2_sels[i]);
-		KUNIT_EXPECT_TRUE(test, found);
-	}
-
-	/*
-	 * Seek value greater than range max => get_selector_*_low should
-	 * return Ok - but set found to false as value is not in range
-	 */
-	ret = linear_range_get_selector_low_array(&testr[0], 2,
-					range2_vals[RANGE2_NUM_VALS - 1] + 1,
-					&sel, &found);
-
-	KUNIT_EXPECT_EQ(test, 0, ret);
-	KUNIT_EXPECT_EQ(test, sel, range2_sels[RANGE2_NUM_VALS - 1]);
-	KUNIT_EXPECT_FALSE(test, found);
-}
-
-static struct kunit_case range_test_cases[] = {
-	KUNIT_CASE(range_test_get_value_amount),
-	KUNIT_CASE(range_test_get_selector_high),
-	KUNIT_CASE(range_test_get_selector_low),
-	KUNIT_CASE(range_test_get_value),
-	{},
-};
-
-static struct kunit_suite range_test_module = {
-	.name = "linear-ranges-test",
-	.test_cases = range_test_cases,
-};
-
-kunit_test_suites(&range_test_module);
-
-MODULE_DESCRIPTION("KUnit test for the linear_ranges helper");
-MODULE_LICENSE("GPL");
diff --git a/lib/test_list_sort.c a/lib/test_list_sort.c
deleted file mode 100644
--- a/lib/test_list_sort.c
+++ /dev/null
@@ -1,123 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-#include <kunit/test.h>
-
-#include <linux/kernel.h>
-#include <linux/list_sort.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/printk.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-
-/*
- * The pattern of set bits in the list length determines which cases
- * are hit in list_sort().
- */
-#define TEST_LIST_LEN (512+128+2) /* not including head */
-
-#define TEST_POISON1 0xDEADBEEF
-#define TEST_POISON2 0xA324354C
-
-struct debug_el {
-	unsigned int poison1;
-	struct list_head list;
-	unsigned int poison2;
-	int value;
-	unsigned int serial;
-};
-
-static void check(struct kunit *test, struct debug_el *ela, struct debug_el *elb)
-{
-	struct debug_el **elts = test->priv;
-
-	KUNIT_EXPECT_LT_MSG(test, ela->serial, (unsigned int)TEST_LIST_LEN, "incorrect serial");
-	KUNIT_EXPECT_LT_MSG(test, elb->serial, (unsigned int)TEST_LIST_LEN, "incorrect serial");
-
-	KUNIT_EXPECT_PTR_EQ_MSG(test, elts[ela->serial], ela, "phantom element");
-	KUNIT_EXPECT_PTR_EQ_MSG(test, elts[elb->serial], elb, "phantom element");
-
-	KUNIT_EXPECT_EQ_MSG(test, ela->poison1, TEST_POISON1, "bad poison");
-	KUNIT_EXPECT_EQ_MSG(test, ela->poison2, TEST_POISON2, "bad poison");
-
-	KUNIT_EXPECT_EQ_MSG(test, elb->poison1, TEST_POISON1, "bad poison");
-	KUNIT_EXPECT_EQ_MSG(test, elb->poison2, TEST_POISON2, "bad poison");
-}
-
-/* `priv` is the test pointer so check() can fail the test if the list is invalid. */
-static int cmp(void *priv, const struct list_head *a, const struct list_head *b)
-{
-	struct debug_el *ela, *elb;
-
-	ela = container_of(a, struct debug_el, list);
-	elb = container_of(b, struct debug_el, list);
-
-	check(priv, ela, elb);
-	return ela->value - elb->value;
-}
-
-static void list_sort_test(struct kunit *test)
-{
-	int i, count = 1;
-	struct debug_el *el, **elts;
-	struct list_head *cur;
-	LIST_HEAD(head);
-
-	elts = kunit_kcalloc(test, TEST_LIST_LEN, sizeof(*elts), GFP_KERNEL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, elts);
-	test->priv = elts;
-
-	for (i = 0; i < TEST_LIST_LEN; i++) {
-		el = kunit_kmalloc(test, sizeof(*el), GFP_KERNEL);
-		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, el);
-
-		 /* force some equivalencies */
-		el->value = get_random_u32_below(TEST_LIST_LEN / 3);
-		el->serial = i;
-		el->poison1 = TEST_POISON1;
-		el->poison2 = TEST_POISON2;
-		elts[i] = el;
-		list_add_tail(&el->list, &head);
-	}
-
-	list_sort(test, &head, cmp);
-
-	for (cur = head.next; cur->next != &head; cur = cur->next) {
-		struct debug_el *el1;
-		int cmp_result;
-
-		KUNIT_ASSERT_PTR_EQ_MSG(test, cur->next->prev, cur,
-					"list is corrupted");
-
-		cmp_result = cmp(test, cur, cur->next);
-		KUNIT_ASSERT_LE_MSG(test, cmp_result, 0, "list is not sorted");
-
-		el = container_of(cur, struct debug_el, list);
-		el1 = container_of(cur->next, struct debug_el, list);
-		if (cmp_result == 0) {
-			KUNIT_ASSERT_LE_MSG(test, el->serial, el1->serial,
-					    "order of equivalent elements not preserved");
-		}
-
-		check(test, el, el1);
-		count++;
-	}
-	KUNIT_EXPECT_PTR_EQ_MSG(test, head.prev, cur, "list is corrupted");
-
-	KUNIT_EXPECT_EQ_MSG(test, count, TEST_LIST_LEN,
-			    "list length changed after sorting!");
-}
-
-static struct kunit_case list_sort_cases[] = {
-	KUNIT_CASE(list_sort_test),
-	{}
-};
-
-static struct kunit_suite list_sort_suite = {
-	.name = "list_sort",
-	.test_cases = list_sort_cases,
-};
-
-kunit_test_suites(&list_sort_suite);
-
-MODULE_DESCRIPTION("list_sort() KUnit test suite");
-MODULE_LICENSE("GPL");
diff --git a/lib/tests/bitfield_kunit.c a/lib/tests/bitfield_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/bitfield_kunit.c
@@ -0,0 +1,155 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test cases for bitfield helpers.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <kunit/test.h>
+#include <linux/bitfield.h>
+
+#define CHECK_ENC_GET_U(tp, v, field, res) do {				\
+		{							\
+			u##tp _res;					\
+									\
+			_res = u##tp##_encode_bits(v, field);		\
+			KUNIT_ASSERT_FALSE_MSG(context, _res != res,	\
+				       "u" #tp "_encode_bits(" #v ", " #field ") is 0x%llx != " #res "\n",	\
+				       (u64)_res);			\
+			KUNIT_ASSERT_FALSE(context,			\
+				   u##tp##_get_bits(_res, field) != v);	\
+		}							\
+	} while (0)
+
+#define CHECK_ENC_GET_LE(tp, v, field, res) do {			\
+		{							\
+			__le##tp _res;					\
+									\
+			_res = le##tp##_encode_bits(v, field);		\
+			KUNIT_ASSERT_FALSE_MSG(context,			\
+				       _res != cpu_to_le##tp(res),	\
+				       "le" #tp "_encode_bits(" #v ", " #field ") is 0x%llx != 0x%llx",\
+				       (u64)le##tp##_to_cpu(_res),	\
+				       (u64)(res));			\
+			KUNIT_ASSERT_FALSE(context,			\
+				   le##tp##_get_bits(_res, field) != v);\
+		}							\
+	} while (0)
+
+#define CHECK_ENC_GET_BE(tp, v, field, res) do {			\
+		{							\
+			__be##tp _res;					\
+									\
+			_res = be##tp##_encode_bits(v, field);		\
+			KUNIT_ASSERT_FALSE_MSG(context,			\
+				       _res != cpu_to_be##tp(res),	\
+				       "be" #tp "_encode_bits(" #v ", " #field ") is 0x%llx != 0x%llx",	\
+				       (u64)be##tp##_to_cpu(_res),	\
+				       (u64)(res));			\
+			KUNIT_ASSERT_FALSE(context,			\
+				   be##tp##_get_bits(_res, field) != v);\
+		}							\
+	} while (0)
+
+#define CHECK_ENC_GET(tp, v, field, res) do {				\
+		CHECK_ENC_GET_U(tp, v, field, res);			\
+		CHECK_ENC_GET_LE(tp, v, field, res);			\
+		CHECK_ENC_GET_BE(tp, v, field, res);			\
+	} while (0)
+
+static void __init test_bitfields_constants(struct kunit *context)
+{
+	/*
+	 * NOTE
+	 * This whole function compiles (or at least should, if everything
+	 * is going according to plan) to nothing after optimisation.
+	 */
+
+	CHECK_ENC_GET(16,  1, 0x000f, 0x0001);
+	CHECK_ENC_GET(16,  3, 0x00f0, 0x0030);
+	CHECK_ENC_GET(16,  5, 0x0f00, 0x0500);
+	CHECK_ENC_GET(16,  7, 0xf000, 0x7000);
+	CHECK_ENC_GET(16, 14, 0x000f, 0x000e);
+	CHECK_ENC_GET(16, 15, 0x00f0, 0x00f0);
+
+	CHECK_ENC_GET_U(8,  1, 0x0f, 0x01);
+	CHECK_ENC_GET_U(8,  3, 0xf0, 0x30);
+	CHECK_ENC_GET_U(8, 14, 0x0f, 0x0e);
+	CHECK_ENC_GET_U(8, 15, 0xf0, 0xf0);
+
+	CHECK_ENC_GET(32,  1, 0x00000f00, 0x00000100);
+	CHECK_ENC_GET(32,  3, 0x0000f000, 0x00003000);
+	CHECK_ENC_GET(32,  5, 0x000f0000, 0x00050000);
+	CHECK_ENC_GET(32,  7, 0x00f00000, 0x00700000);
+	CHECK_ENC_GET(32, 14, 0x0f000000, 0x0e000000);
+	CHECK_ENC_GET(32, 15, 0xf0000000, 0xf0000000);
+
+	CHECK_ENC_GET(64,  1, 0x00000f0000000000ull, 0x0000010000000000ull);
+	CHECK_ENC_GET(64,  3, 0x0000f00000000000ull, 0x0000300000000000ull);
+	CHECK_ENC_GET(64,  5, 0x000f000000000000ull, 0x0005000000000000ull);
+	CHECK_ENC_GET(64,  7, 0x00f0000000000000ull, 0x0070000000000000ull);
+	CHECK_ENC_GET(64, 14, 0x0f00000000000000ull, 0x0e00000000000000ull);
+	CHECK_ENC_GET(64, 15, 0xf000000000000000ull, 0xf000000000000000ull);
+}
+
+#define CHECK(tp, mask) do {						\
+		u64 v;							\
+									\
+		for (v = 0; v < 1 << hweight32(mask); v++)		\
+			KUNIT_ASSERT_FALSE(context,			\
+				tp##_encode_bits(v, mask) != v << __ffs64(mask));\
+	} while (0)
+
+static void __init test_bitfields_variables(struct kunit *context)
+{
+	CHECK(u8, 0x0f);
+	CHECK(u8, 0xf0);
+	CHECK(u8, 0x38);
+
+	CHECK(u16, 0x0038);
+	CHECK(u16, 0x0380);
+	CHECK(u16, 0x3800);
+	CHECK(u16, 0x8000);
+
+	CHECK(u32, 0x80000000);
+	CHECK(u32, 0x7f000000);
+	CHECK(u32, 0x07e00000);
+	CHECK(u32, 0x00018000);
+
+	CHECK(u64, 0x8000000000000000ull);
+	CHECK(u64, 0x7f00000000000000ull);
+	CHECK(u64, 0x0001800000000000ull);
+	CHECK(u64, 0x0000000080000000ull);
+	CHECK(u64, 0x000000007f000000ull);
+	CHECK(u64, 0x0000000018000000ull);
+	CHECK(u64, 0x0000001f8000000ull);
+}
+
+#ifdef TEST_BITFIELD_COMPILE
+static void __init test_bitfields_compile(struct kunit *context)
+{
+	/* these should fail compilation */
+	CHECK_ENC_GET(16, 16, 0x0f00, 0x1000);
+	u32_encode_bits(7, 0x06000000);
+
+	/* this should at least give a warning */
+	u16_encode_bits(0, 0x60000);
+}
+#endif
+
+static struct kunit_case __refdata bitfields_test_cases[] = {
+	KUNIT_CASE(test_bitfields_constants),
+	KUNIT_CASE(test_bitfields_variables),
+	{}
+};
+
+static struct kunit_suite bitfields_test_suite = {
+	.name = "bitfields",
+	.test_cases = bitfields_test_cases,
+};
+
+kunit_test_suites(&bitfields_test_suite);
+
+MODULE_AUTHOR("Johannes Berg <johannes@xxxxxxxxxxxxxxxx>");
+MODULE_DESCRIPTION("Test cases for bitfield helpers");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/checksum_kunit.c a/lib/tests/checksum_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/checksum_kunit.c
@@ -0,0 +1,640 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test cases csum_partial, csum_fold, ip_fast_csum, csum_ipv6_magic
+ */
+
+#include <kunit/test.h>
+#include <asm/checksum.h>
+#include <net/ip6_checksum.h>
+
+#define MAX_LEN 512
+#define MAX_ALIGN 64
+#define TEST_BUFLEN (MAX_LEN + MAX_ALIGN)
+
+#define IPv4_MIN_WORDS 5
+#define IPv4_MAX_WORDS 15
+#define NUM_IPv6_TESTS 200
+#define NUM_IP_FAST_CSUM_TESTS 181
+
+/* Values for a little endian CPU. Byte swap each half on big endian CPU. */
+static const u32 random_init_sum = 0x2847aab;
+static const u8 random_buf[] = {
+	0xac, 0xd7, 0x76, 0x69, 0x6e, 0xf2, 0x93, 0x2c, 0x1f, 0xe0, 0xde, 0x86,
+	0x8f, 0x54, 0x33, 0x90, 0x95, 0xbf, 0xff, 0xb9, 0xea, 0x62, 0x6e, 0xb5,
+	0xd3, 0x4f, 0xf5, 0x60, 0x50, 0x5c, 0xc7, 0xfa, 0x6d, 0x1a, 0xc7, 0xf0,
+	0xd2, 0x2c, 0x12, 0x3d, 0x88, 0xe3, 0x14, 0x21, 0xb1, 0x5e, 0x45, 0x31,
+	0xa2, 0x85, 0x36, 0x76, 0xba, 0xd8, 0xad, 0xbb, 0x9e, 0x49, 0x8f, 0xf7,
+	0xce, 0xea, 0xef, 0xca, 0x2c, 0x29, 0xf7, 0x15, 0x5c, 0x1d, 0x4d, 0x09,
+	0x1f, 0xe2, 0x14, 0x31, 0x8c, 0x07, 0x57, 0x23, 0x1f, 0x6f, 0x03, 0xe1,
+	0x93, 0x19, 0x53, 0x03, 0x45, 0x49, 0x9a, 0x3b, 0x8e, 0x0c, 0x12, 0x5d,
+	0x8a, 0xb8, 0x9b, 0x8c, 0x9a, 0x03, 0xe5, 0xa2, 0x43, 0xd2, 0x3b, 0x4e,
+	0x7e, 0x30, 0x3c, 0x22, 0x2d, 0xc5, 0xfc, 0x9e, 0xdb, 0xc6, 0xf9, 0x69,
+	0x12, 0x39, 0x1f, 0xa0, 0x11, 0x0c, 0x3f, 0xf5, 0x53, 0xc9, 0x30, 0xfb,
+	0xb0, 0xdd, 0x21, 0x1d, 0x34, 0xe2, 0x65, 0x30, 0xf1, 0xe8, 0x1b, 0xe7,
+	0x55, 0x0d, 0xeb, 0xbd, 0xcc, 0x9d, 0x24, 0xa4, 0xad, 0xa7, 0x93, 0x47,
+	0x19, 0x2e, 0xc4, 0x5c, 0x3b, 0xc7, 0x6d, 0x95, 0x0c, 0x47, 0x60, 0xaf,
+	0x5b, 0x47, 0xee, 0xdc, 0x31, 0x31, 0x14, 0x12, 0x7e, 0x9e, 0x45, 0xb1,
+	0xc1, 0x69, 0x4b, 0x84, 0xfc, 0x88, 0xc1, 0x9e, 0x46, 0xb4, 0xc2, 0x25,
+	0xc5, 0x6c, 0x4c, 0x22, 0x58, 0x5c, 0xbe, 0xff, 0xea, 0x88, 0x88, 0x7a,
+	0xcb, 0x1c, 0x5d, 0x63, 0xa1, 0xf2, 0x33, 0x0c, 0xa2, 0x16, 0x0b, 0x6e,
+	0x2b, 0x79, 0x58, 0xf7, 0xac, 0xd3, 0x6a, 0x3f, 0x81, 0x57, 0x48, 0x45,
+	0xe3, 0x7c, 0xdc, 0xd6, 0x34, 0x7e, 0xe6, 0x73, 0xfa, 0xcb, 0x31, 0x18,
+	0xa9, 0x0b, 0xee, 0x6b, 0x99, 0xb9, 0x2d, 0xde, 0x22, 0x0e, 0x71, 0x57,
+	0x0e, 0x9b, 0x11, 0xd1, 0x15, 0x41, 0xd0, 0x6b, 0x50, 0x8a, 0x23, 0x64,
+	0xe3, 0x9c, 0xb3, 0x55, 0x09, 0xe9, 0x32, 0x67, 0xf9, 0xe0, 0x73, 0xf1,
+	0x60, 0x66, 0x0b, 0x88, 0x79, 0x8d, 0x4b, 0x52, 0x83, 0x20, 0x26, 0x78,
+	0x49, 0x27, 0xe7, 0x3e, 0x29, 0xa8, 0x18, 0x82, 0x41, 0xdd, 0x1e, 0xcc,
+	0x3b, 0xc4, 0x65, 0xd1, 0x21, 0x40, 0x72, 0xb2, 0x87, 0x5e, 0x16, 0x10,
+	0x80, 0x3f, 0x4b, 0x58, 0x1c, 0xc2, 0x79, 0x20, 0xf0, 0xe0, 0x80, 0xd3,
+	0x52, 0xa5, 0x19, 0x6e, 0x47, 0x90, 0x08, 0xf5, 0x50, 0xe2, 0xd6, 0xae,
+	0xe9, 0x2e, 0xdc, 0xd5, 0xb4, 0x90, 0x1f, 0x79, 0x49, 0x82, 0x21, 0x84,
+	0xa0, 0xb5, 0x2f, 0xff, 0x30, 0x71, 0xed, 0x80, 0x68, 0xb1, 0x6d, 0xef,
+	0xf6, 0xcf, 0xb8, 0x41, 0x79, 0xf5, 0x01, 0xbc, 0x0c, 0x9b, 0x0e, 0x06,
+	0xf3, 0xb0, 0xbb, 0x97, 0xb8, 0xb1, 0xfd, 0x51, 0x4e, 0xef, 0x0a, 0x3d,
+	0x7a, 0x3d, 0xbd, 0x61, 0x00, 0xa2, 0xb3, 0xf0, 0x1d, 0x77, 0x7b, 0x6c,
+	0x01, 0x61, 0xa5, 0xa3, 0xdb, 0xd5, 0xd5, 0xf4, 0xb5, 0x28, 0x9f, 0x0a,
+	0xa3, 0x82, 0x5f, 0x4b, 0x40, 0x0f, 0x05, 0x0e, 0x78, 0xed, 0xbf, 0x17,
+	0xf6, 0x5a, 0x8a, 0x7d, 0xf9, 0x45, 0xc1, 0xd7, 0x1b, 0x9d, 0x6c, 0x07,
+	0x88, 0xf3, 0xbc, 0xf1, 0xea, 0x28, 0x1f, 0xb8, 0x7a, 0x60, 0x3c, 0xce,
+	0x3e, 0x50, 0xb2, 0x0b, 0xcf, 0xe5, 0x08, 0x1f, 0x48, 0x04, 0xf9, 0x35,
+	0x29, 0x15, 0xbe, 0x82, 0x96, 0xc2, 0x55, 0x04, 0x6c, 0x19, 0x45, 0x29,
+	0x0b, 0xb6, 0x49, 0x12, 0xfb, 0x8d, 0x1b, 0x75, 0x8b, 0xd9, 0x6a, 0x5c,
+	0xbe, 0x46, 0x2b, 0x41, 0xfe, 0x21, 0xad, 0x1f, 0x75, 0xe7, 0x90, 0x3d,
+	0xe1, 0xdf, 0x4b, 0xe1, 0x81, 0xe2, 0x17, 0x02, 0x7b, 0x58, 0x8b, 0x92,
+	0x1a, 0xac, 0x46, 0xdd, 0x2e, 0xce, 0x40, 0x09
+};
+
+/* Values for a little endian CPU. Byte swap on big endian CPU. */
+static const u16 expected_results[] = {
+	0x82d0, 0x8224, 0xab23, 0xaaad, 0x41ad, 0x413f, 0x4f3e, 0x4eab, 0x22ab,
+	0x228c, 0x428b, 0x41ad, 0xbbac, 0xbb1d, 0x671d, 0x66ea, 0xd6e9, 0xd654,
+	0x1754, 0x1655, 0x5d54, 0x5c6a, 0xfa69, 0xf9fb, 0x44fb, 0x4428, 0xf527,
+	0xf432, 0x9432, 0x93e2, 0x37e2, 0x371b, 0x3d1a, 0x3cad, 0x22ad, 0x21e6,
+	0x31e5, 0x3113, 0x0513, 0x0501, 0xc800, 0xc778, 0xe477, 0xe463, 0xc363,
+	0xc2b2, 0x64b2, 0x646d, 0x336d, 0x32cb, 0xadca, 0xad94, 0x3794, 0x36da,
+	0x5ed9, 0x5e2c, 0xa32b, 0xa28d, 0x598d, 0x58fe, 0x61fd, 0x612f, 0x772e,
+	0x763f, 0xac3e, 0xac12, 0x8312, 0x821b, 0x6d1b, 0x6cbf, 0x4fbf, 0x4f72,
+	0x4672, 0x4653, 0x6452, 0x643e, 0x333e, 0x32b2, 0x2bb2, 0x2b5b, 0x085b,
+	0x083c, 0x993b, 0x9938, 0xb837, 0xb7a4, 0x9ea4, 0x9e51, 0x9b51, 0x9b0c,
+	0x520c, 0x5172, 0x1672, 0x15e4, 0x09e4, 0x09d2, 0xacd1, 0xac47, 0xf446,
+	0xf3ab, 0x67ab, 0x6711, 0x6411, 0x632c, 0xc12b, 0xc0e8, 0xeee7, 0xeeac,
+	0xa0ac, 0xa02e, 0x702e, 0x6ff2, 0x4df2, 0x4dc5, 0x88c4, 0x87c8, 0xe9c7,
+	0xe8ec, 0x22ec, 0x21f3, 0xb8f2, 0xb8e0, 0x7fe0, 0x7fc1, 0xdfc0, 0xdfaf,
+	0xd3af, 0xd370, 0xde6f, 0xde1c, 0x151c, 0x14ec, 0x19eb, 0x193b, 0x3c3a,
+	0x3c19, 0x1f19, 0x1ee5, 0x3ce4, 0x3c7f, 0x0c7f, 0x0b8e, 0x238d, 0x2372,
+	0x3c71, 0x3c1c, 0x2f1c, 0x2e31, 0x7130, 0x7064, 0xd363, 0xd33f, 0x2f3f,
+	0x2e92, 0x8791, 0x86fe, 0x3ffe, 0x3fe5, 0x11e5, 0x1121, 0xb520, 0xb4e5,
+	0xede4, 0xed77, 0x5877, 0x586b, 0x116b, 0x110b, 0x620a, 0x61af, 0x1aaf,
+	0x19c1, 0x3dc0, 0x3d8f, 0x0c8f, 0x0c7b, 0xfa7a, 0xf9fc, 0x5bfc, 0x5bb7,
+	0xaab6, 0xa9f5, 0x40f5, 0x40aa, 0xbca9, 0xbbad, 0x33ad, 0x32ec, 0x94eb,
+	0x94a5, 0xe0a4, 0xdfe2, 0xbae2, 0xba1d, 0x4e1d, 0x4dd1, 0x2bd1, 0x2b79,
+	0xcf78, 0xceba, 0xcfb9, 0xcecf, 0x46cf, 0x4647, 0xcc46, 0xcb7b, 0xaf7b,
+	0xaf1e, 0x4c1e, 0x4b7d, 0x597c, 0x5949, 0x4d49, 0x4ca7, 0x36a7, 0x369c,
+	0xc89b, 0xc870, 0x4f70, 0x4f18, 0x5817, 0x576b, 0x846a, 0x8400, 0x4500,
+	0x447f, 0xed7e, 0xed36, 0xa836, 0xa753, 0x2b53, 0x2a77, 0x5476, 0x5442,
+	0xd641, 0xd55b, 0x625b, 0x6161, 0x9660, 0x962f, 0x7e2f, 0x7d86, 0x7286,
+	0x7198, 0x0698, 0x05ff, 0x4cfe, 0x4cd1, 0x6ed0, 0x6eae, 0x60ae, 0x603d,
+	0x093d, 0x092f, 0x6e2e, 0x6e1d, 0x9d1c, 0x9d07, 0x5c07, 0x5b37, 0xf036,
+	0xefe6, 0x65e6, 0x65c3, 0x01c3, 0x00e0, 0x64df, 0x642c, 0x0f2c, 0x0f23,
+	0x2622, 0x25f0, 0xbeef, 0xbdf6, 0xddf5, 0xdd82, 0xec81, 0xec21, 0x8621,
+	0x8616, 0xfe15, 0xfd9c, 0x709c, 0x7051, 0x1e51, 0x1dce, 0xfdcd, 0xfda7,
+	0x85a7, 0x855e, 0x5e5e, 0x5d77, 0x1f77, 0x1f4e, 0x774d, 0x7735, 0xf534,
+	0xf4f3, 0x17f3, 0x17d5, 0x4bd4, 0x4b99, 0x8798, 0x8733, 0xb632, 0xb611,
+	0x7611, 0x759f, 0xc39e, 0xc317, 0x6517, 0x6501, 0x5501, 0x5481, 0x1581,
+	0x1536, 0xbd35, 0xbd19, 0xfb18, 0xfa9f, 0xda9f, 0xd9af, 0xf9ae, 0xf92e,
+	0x262e, 0x25dc, 0x80db, 0x80c2, 0x12c2, 0x127b, 0x827a, 0x8272, 0x8d71,
+	0x8d21, 0xab20, 0xaa4a, 0xfc49, 0xfb60, 0xcd60, 0xcc84, 0xf783, 0xf6cf,
+	0x66cf, 0x66b0, 0xedaf, 0xed66, 0x6b66, 0x6b45, 0xe744, 0xe6a4, 0x31a4,
+	0x3175, 0x3274, 0x3244, 0xc143, 0xc056, 0x4056, 0x3fee, 0x8eed, 0x8e80,
+	0x9f7f, 0x9e89, 0xcf88, 0xced0, 0x8dd0, 0x8d57, 0x9856, 0x9855, 0xdc54,
+	0xdc48, 0x4148, 0x413a, 0x3b3a, 0x3a47, 0x8a46, 0x898b, 0xf28a, 0xf1d2,
+	0x40d2, 0x3fd5, 0xeed4, 0xee86, 0xff85, 0xff7b, 0xc27b, 0xc201, 0x8501,
+	0x8444, 0x2344, 0x2344, 0x8143, 0x8090, 0x908f, 0x9072, 0x1972, 0x18f7,
+	0xacf6, 0xacf5, 0x4bf5, 0x4b50, 0xa84f, 0xa774, 0xd273, 0xd19e, 0xdd9d,
+	0xdce8, 0xb4e8, 0xb449, 0xaa49, 0xa9a6, 0x27a6, 0x2747, 0xdc46, 0xdc06,
+	0xcd06, 0xcd01, 0xbf01, 0xbe89, 0xd188, 0xd0c9, 0xb9c9, 0xb8d3, 0x5ed3,
+	0x5e49, 0xe148, 0xe04f, 0x9b4f, 0x9a8e, 0xc38d, 0xc372, 0x2672, 0x2606,
+	0x1f06, 0x1e7e, 0x2b7d, 0x2ac1, 0x39c0, 0x38d6, 0x10d6, 0x10b7, 0x58b6,
+	0x583c, 0xf83b, 0xf7ff, 0x29ff, 0x29c1, 0xd9c0, 0xd90e, 0xce0e, 0xcd3f,
+	0xe83e, 0xe836, 0xc936, 0xc8ee, 0xc4ee, 0xc3f5, 0x8ef5, 0x8ecc, 0x79cc,
+	0x790e, 0xf70d, 0xf677, 0x3477, 0x3422, 0x3022, 0x2fb6, 0x16b6, 0x1671,
+	0xed70, 0xed65, 0x3765, 0x371c, 0x251c, 0x2421, 0x9720, 0x9705, 0x2205,
+	0x217a, 0x4879, 0x480f, 0xec0e, 0xeb50, 0xa550, 0xa525, 0x6425, 0x6327,
+	0x4227, 0x417a, 0x227a, 0x2205, 0x3b04, 0x3a74, 0xfd73, 0xfc92, 0x1d92,
+	0x1d47, 0x3c46, 0x3bc5, 0x59c4, 0x59ad, 0x57ad, 0x5732, 0xff31, 0xfea6,
+	0x6ca6, 0x6c8c, 0xc08b, 0xc045, 0xe344, 0xe316, 0x1516, 0x14d6,
+};
+
+/* Values for a little endian CPU. Byte swap each half on big endian CPU. */
+static const u32 init_sums_no_overflow[] = {
+	0xffffffff, 0xfffffffb, 0xfffffbfb, 0xfffffbf7, 0xfffff7f7, 0xfffff7f3,
+	0xfffff3f3, 0xfffff3ef, 0xffffefef, 0xffffefeb, 0xffffebeb, 0xffffebe7,
+	0xffffe7e7, 0xffffe7e3, 0xffffe3e3, 0xffffe3df, 0xffffdfdf, 0xffffdfdb,
+	0xffffdbdb, 0xffffdbd7, 0xffffd7d7, 0xffffd7d3, 0xffffd3d3, 0xffffd3cf,
+	0xffffcfcf, 0xffffcfcb, 0xffffcbcb, 0xffffcbc7, 0xffffc7c7, 0xffffc7c3,
+	0xffffc3c3, 0xffffc3bf, 0xffffbfbf, 0xffffbfbb, 0xffffbbbb, 0xffffbbb7,
+	0xffffb7b7, 0xffffb7b3, 0xffffb3b3, 0xffffb3af, 0xffffafaf, 0xffffafab,
+	0xffffabab, 0xffffaba7, 0xffffa7a7, 0xffffa7a3, 0xffffa3a3, 0xffffa39f,
+	0xffff9f9f, 0xffff9f9b, 0xffff9b9b, 0xffff9b97, 0xffff9797, 0xffff9793,
+	0xffff9393, 0xffff938f, 0xffff8f8f, 0xffff8f8b, 0xffff8b8b, 0xffff8b87,
+	0xffff8787, 0xffff8783, 0xffff8383, 0xffff837f, 0xffff7f7f, 0xffff7f7b,
+	0xffff7b7b, 0xffff7b77, 0xffff7777, 0xffff7773, 0xffff7373, 0xffff736f,
+	0xffff6f6f, 0xffff6f6b, 0xffff6b6b, 0xffff6b67, 0xffff6767, 0xffff6763,
+	0xffff6363, 0xffff635f, 0xffff5f5f, 0xffff5f5b, 0xffff5b5b, 0xffff5b57,
+	0xffff5757, 0xffff5753, 0xffff5353, 0xffff534f, 0xffff4f4f, 0xffff4f4b,
+	0xffff4b4b, 0xffff4b47, 0xffff4747, 0xffff4743, 0xffff4343, 0xffff433f,
+	0xffff3f3f, 0xffff3f3b, 0xffff3b3b, 0xffff3b37, 0xffff3737, 0xffff3733,
+	0xffff3333, 0xffff332f, 0xffff2f2f, 0xffff2f2b, 0xffff2b2b, 0xffff2b27,
+	0xffff2727, 0xffff2723, 0xffff2323, 0xffff231f, 0xffff1f1f, 0xffff1f1b,
+	0xffff1b1b, 0xffff1b17, 0xffff1717, 0xffff1713, 0xffff1313, 0xffff130f,
+	0xffff0f0f, 0xffff0f0b, 0xffff0b0b, 0xffff0b07, 0xffff0707, 0xffff0703,
+	0xffff0303, 0xffff02ff, 0xfffffefe, 0xfffffefa, 0xfffffafa, 0xfffffaf6,
+	0xfffff6f6, 0xfffff6f2, 0xfffff2f2, 0xfffff2ee, 0xffffeeee, 0xffffeeea,
+	0xffffeaea, 0xffffeae6, 0xffffe6e6, 0xffffe6e2, 0xffffe2e2, 0xffffe2de,
+	0xffffdede, 0xffffdeda, 0xffffdada, 0xffffdad6, 0xffffd6d6, 0xffffd6d2,
+	0xffffd2d2, 0xffffd2ce, 0xffffcece, 0xffffceca, 0xffffcaca, 0xffffcac6,
+	0xffffc6c6, 0xffffc6c2, 0xffffc2c2, 0xffffc2be, 0xffffbebe, 0xffffbeba,
+	0xffffbaba, 0xffffbab6, 0xffffb6b6, 0xffffb6b2, 0xffffb2b2, 0xffffb2ae,
+	0xffffaeae, 0xffffaeaa, 0xffffaaaa, 0xffffaaa6, 0xffffa6a6, 0xffffa6a2,
+	0xffffa2a2, 0xffffa29e, 0xffff9e9e, 0xffff9e9a, 0xffff9a9a, 0xffff9a96,
+	0xffff9696, 0xffff9692, 0xffff9292, 0xffff928e, 0xffff8e8e, 0xffff8e8a,
+	0xffff8a8a, 0xffff8a86, 0xffff8686, 0xffff8682, 0xffff8282, 0xffff827e,
+	0xffff7e7e, 0xffff7e7a, 0xffff7a7a, 0xffff7a76, 0xffff7676, 0xffff7672,
+	0xffff7272, 0xffff726e, 0xffff6e6e, 0xffff6e6a, 0xffff6a6a, 0xffff6a66,
+	0xffff6666, 0xffff6662, 0xffff6262, 0xffff625e, 0xffff5e5e, 0xffff5e5a,
+	0xffff5a5a, 0xffff5a56, 0xffff5656, 0xffff5652, 0xffff5252, 0xffff524e,
+	0xffff4e4e, 0xffff4e4a, 0xffff4a4a, 0xffff4a46, 0xffff4646, 0xffff4642,
+	0xffff4242, 0xffff423e, 0xffff3e3e, 0xffff3e3a, 0xffff3a3a, 0xffff3a36,
+	0xffff3636, 0xffff3632, 0xffff3232, 0xffff322e, 0xffff2e2e, 0xffff2e2a,
+	0xffff2a2a, 0xffff2a26, 0xffff2626, 0xffff2622, 0xffff2222, 0xffff221e,
+	0xffff1e1e, 0xffff1e1a, 0xffff1a1a, 0xffff1a16, 0xffff1616, 0xffff1612,
+	0xffff1212, 0xffff120e, 0xffff0e0e, 0xffff0e0a, 0xffff0a0a, 0xffff0a06,
+	0xffff0606, 0xffff0602, 0xffff0202, 0xffff01fe, 0xfffffdfd, 0xfffffdf9,
+	0xfffff9f9, 0xfffff9f5, 0xfffff5f5, 0xfffff5f1, 0xfffff1f1, 0xfffff1ed,
+	0xffffeded, 0xffffede9, 0xffffe9e9, 0xffffe9e5, 0xffffe5e5, 0xffffe5e1,
+	0xffffe1e1, 0xffffe1dd, 0xffffdddd, 0xffffddd9, 0xffffd9d9, 0xffffd9d5,
+	0xffffd5d5, 0xffffd5d1, 0xffffd1d1, 0xffffd1cd, 0xffffcdcd, 0xffffcdc9,
+	0xffffc9c9, 0xffffc9c5, 0xffffc5c5, 0xffffc5c1, 0xffffc1c1, 0xffffc1bd,
+	0xffffbdbd, 0xffffbdb9, 0xffffb9b9, 0xffffb9b5, 0xffffb5b5, 0xffffb5b1,
+	0xffffb1b1, 0xffffb1ad, 0xffffadad, 0xffffada9, 0xffffa9a9, 0xffffa9a5,
+	0xffffa5a5, 0xffffa5a1, 0xffffa1a1, 0xffffa19d, 0xffff9d9d, 0xffff9d99,
+	0xffff9999, 0xffff9995, 0xffff9595, 0xffff9591, 0xffff9191, 0xffff918d,
+	0xffff8d8d, 0xffff8d89, 0xffff8989, 0xffff8985, 0xffff8585, 0xffff8581,
+	0xffff8181, 0xffff817d, 0xffff7d7d, 0xffff7d79, 0xffff7979, 0xffff7975,
+	0xffff7575, 0xffff7571, 0xffff7171, 0xffff716d, 0xffff6d6d, 0xffff6d69,
+	0xffff6969, 0xffff6965, 0xffff6565, 0xffff6561, 0xffff6161, 0xffff615d,
+	0xffff5d5d, 0xffff5d59, 0xffff5959, 0xffff5955, 0xffff5555, 0xffff5551,
+	0xffff5151, 0xffff514d, 0xffff4d4d, 0xffff4d49, 0xffff4949, 0xffff4945,
+	0xffff4545, 0xffff4541, 0xffff4141, 0xffff413d, 0xffff3d3d, 0xffff3d39,
+	0xffff3939, 0xffff3935, 0xffff3535, 0xffff3531, 0xffff3131, 0xffff312d,
+	0xffff2d2d, 0xffff2d29, 0xffff2929, 0xffff2925, 0xffff2525, 0xffff2521,
+	0xffff2121, 0xffff211d, 0xffff1d1d, 0xffff1d19, 0xffff1919, 0xffff1915,
+	0xffff1515, 0xffff1511, 0xffff1111, 0xffff110d, 0xffff0d0d, 0xffff0d09,
+	0xffff0909, 0xffff0905, 0xffff0505, 0xffff0501, 0xffff0101, 0xffff00fd,
+	0xfffffcfc, 0xfffffcf8, 0xfffff8f8, 0xfffff8f4, 0xfffff4f4, 0xfffff4f0,
+	0xfffff0f0, 0xfffff0ec, 0xffffecec, 0xffffece8, 0xffffe8e8, 0xffffe8e4,
+	0xffffe4e4, 0xffffe4e0, 0xffffe0e0, 0xffffe0dc, 0xffffdcdc, 0xffffdcd8,
+	0xffffd8d8, 0xffffd8d4, 0xffffd4d4, 0xffffd4d0, 0xffffd0d0, 0xffffd0cc,
+	0xffffcccc, 0xffffccc8, 0xffffc8c8, 0xffffc8c4, 0xffffc4c4, 0xffffc4c0,
+	0xffffc0c0, 0xffffc0bc, 0xffffbcbc, 0xffffbcb8, 0xffffb8b8, 0xffffb8b4,
+	0xffffb4b4, 0xffffb4b0, 0xffffb0b0, 0xffffb0ac, 0xffffacac, 0xffffaca8,
+	0xffffa8a8, 0xffffa8a4, 0xffffa4a4, 0xffffa4a0, 0xffffa0a0, 0xffffa09c,
+	0xffff9c9c, 0xffff9c98, 0xffff9898, 0xffff9894, 0xffff9494, 0xffff9490,
+	0xffff9090, 0xffff908c, 0xffff8c8c, 0xffff8c88, 0xffff8888, 0xffff8884,
+	0xffff8484, 0xffff8480, 0xffff8080, 0xffff807c, 0xffff7c7c, 0xffff7c78,
+	0xffff7878, 0xffff7874, 0xffff7474, 0xffff7470, 0xffff7070, 0xffff706c,
+	0xffff6c6c, 0xffff6c68, 0xffff6868, 0xffff6864, 0xffff6464, 0xffff6460,
+	0xffff6060, 0xffff605c, 0xffff5c5c, 0xffff5c58, 0xffff5858, 0xffff5854,
+	0xffff5454, 0xffff5450, 0xffff5050, 0xffff504c, 0xffff4c4c, 0xffff4c48,
+	0xffff4848, 0xffff4844, 0xffff4444, 0xffff4440, 0xffff4040, 0xffff403c,
+	0xffff3c3c, 0xffff3c38, 0xffff3838, 0xffff3834, 0xffff3434, 0xffff3430,
+	0xffff3030, 0xffff302c, 0xffff2c2c, 0xffff2c28, 0xffff2828, 0xffff2824,
+	0xffff2424, 0xffff2420, 0xffff2020, 0xffff201c, 0xffff1c1c, 0xffff1c18,
+	0xffff1818, 0xffff1814, 0xffff1414, 0xffff1410, 0xffff1010, 0xffff100c,
+	0xffff0c0c, 0xffff0c08, 0xffff0808, 0xffff0804, 0xffff0404, 0xffff0400,
+	0xffff0000, 0xfffffffb,
+};
+
+static const u16 expected_csum_ipv6_magic[] = {
+	0x18d4, 0x3085, 0x2e4b, 0xd9f4, 0xbdc8, 0x78f,	0x1034, 0x8422, 0x6fc0,
+	0xd2f6, 0xbeb5, 0x9d3,	0x7e2a, 0x312e, 0x778e, 0xc1bb, 0x7cf2, 0x9d1e,
+	0xca21, 0xf3ff, 0x7569, 0xb02e, 0xca86, 0x7e76, 0x4539, 0x45e3, 0xf28d,
+	0xdf81, 0x8fd5, 0x3b5d, 0x8324, 0xf471, 0x83be, 0x1daf, 0x8c46, 0xe682,
+	0xd1fb, 0x6b2e, 0xe687, 0x2a33, 0x4833, 0x2d67, 0x660f, 0x2e79, 0xd65e,
+	0x6b62, 0x6672, 0x5dbd, 0x8680, 0xbaa5, 0x2229, 0x2125, 0x2d01, 0x1cc0,
+	0x6d36, 0x33c0, 0xee36, 0xd832, 0x9820, 0x8a31, 0x53c5, 0x2e2,	0xdb0e,
+	0x49ed, 0x17a7, 0x77a0, 0xd72e, 0x3d72, 0x7dc8, 0x5b17, 0xf55d, 0xa4d9,
+	0x1446, 0x5d56, 0x6b2e, 0x69a5, 0xadb6, 0xff2a, 0x92e,	0xe044, 0x3402,
+	0xbb60, 0xec7f, 0xe7e6, 0x1986, 0x32f4, 0x8f8,	0x5e00, 0x47c6, 0x3059,
+	0x3969, 0xe957, 0x4388, 0x2854, 0x3334, 0xea71, 0xa6de, 0x33f9, 0x83fc,
+	0x37b4, 0x5531, 0x3404, 0x1010, 0xed30, 0x610a, 0xc95,	0x9aed, 0x6ff,
+	0x5136, 0x2741, 0x660e, 0x8b80, 0xf71,	0xa263, 0x88af, 0x7a73, 0x3c37,
+	0x1908, 0x6db5, 0x2e92, 0x1cd2, 0x70c8, 0xee16, 0xe80,	0xcd55, 0x6e6,
+	0x6434, 0x127,	0x655d, 0x2ea0, 0xb4f4, 0xdc20, 0x5671, 0xe462, 0xe52b,
+	0xdb44, 0x3589, 0xc48f, 0xe60b, 0xd2d2, 0x66ad, 0x498,	0x436,	0xb917,
+	0xf0ca, 0x1a6e, 0x1cb7, 0xbf61, 0x2870, 0xc7e8, 0x5b30, 0xe4a5, 0x168,
+	0xadfc, 0xd035, 0xe690, 0xe283, 0xfb27, 0xe4ad, 0xb1a5, 0xf2d5, 0xc4b6,
+	0x8a30, 0xd7d5, 0x7df9, 0x91d5, 0x63ed, 0x2d21, 0x312b, 0xab19, 0xa632,
+	0x8d2e, 0xef06, 0x57b9, 0xc373, 0xbd1f, 0xa41f, 0x8444, 0x9975, 0x90cb,
+	0xc49c, 0xe965, 0x4eff, 0x5a,	0xef6d, 0xe81a, 0xe260, 0x853a, 0xff7a,
+	0x99aa, 0xb06b, 0xee19, 0xcc2c, 0xf34c, 0x7c49, 0xdac3, 0xa71e, 0xc988,
+	0x3845, 0x1014
+};
+
+static const u16 expected_fast_csum[] = {
+	0xda83, 0x45da, 0x4f46, 0x4e4f, 0x34e,	0xe902, 0xa5e9, 0x87a5, 0x7187,
+	0x5671, 0xf556, 0x6df5, 0x816d, 0x8f81, 0xbb8f, 0xfbba, 0x5afb, 0xbe5a,
+	0xedbe, 0xabee, 0x6aac, 0xe6b,	0xea0d, 0x67ea, 0x7e68, 0x8a7e, 0x6f8a,
+	0x3a70, 0x9f3a, 0xe89e, 0x75e8, 0x7976, 0xfa79, 0x2cfa, 0x3c2c, 0x463c,
+	0x7146, 0x7a71, 0x547a, 0xfd53, 0x99fc, 0xb699, 0x92b6, 0xdb91, 0xe8da,
+	0x5fe9, 0x1e60, 0xae1d, 0x39ae, 0xf439, 0xa1f4, 0xdda1, 0xede,	0x790f,
+	0x579,	0x1206, 0x9012, 0x2490, 0xd224, 0x5cd2, 0xa65d, 0xca7,	0x220d,
+	0xf922, 0xbf9,	0x920b, 0x1b92, 0x361c, 0x2e36, 0x4d2e, 0x24d,	0x2,
+	0xcfff, 0x90cf, 0xa591, 0x93a5, 0x7993, 0x9579, 0xc894, 0x50c8, 0x5f50,
+	0xd55e, 0xcad5, 0xf3c9, 0x8f4,	0x4409, 0x5043, 0x5b50, 0x55b,	0x2205,
+	0x1e22, 0x801e, 0x3780, 0xe137, 0x7ee0, 0xf67d, 0x3cf6, 0xa53c, 0x2ea5,
+	0x472e, 0x5147, 0xcf51, 0x1bcf, 0x951c, 0x1e95, 0xc71e, 0xe4c7, 0xc3e4,
+	0x3dc3, 0xee3d, 0xa4ed, 0xf9a4, 0xcbf8, 0x75cb, 0xb375, 0x50b4, 0x3551,
+	0xf835, 0x19f8, 0x8c1a, 0x538c, 0xad52, 0xa3ac, 0xb0a3, 0x5cb0, 0x6c5c,
+	0x5b6c, 0xc05a, 0x92c0, 0x4792, 0xbe47, 0x53be, 0x1554, 0x5715, 0x4b57,
+	0xe54a, 0x20e5, 0x21,	0xd500, 0xa1d4, 0xa8a1, 0x57a9, 0xca57, 0x5ca,
+	0x1c06, 0x4f1c, 0xe24e, 0xd9e2, 0xf0d9, 0x4af1, 0x474b, 0x8146, 0xe81,
+	0xfd0e, 0x84fd, 0x7c85, 0xba7c, 0x17ba, 0x4a17, 0x964a, 0xf595, 0xff5,
+	0x5310, 0x3253, 0x6432, 0x4263, 0x2242, 0xe121, 0x32e1, 0xf632, 0xc5f5,
+	0x21c6, 0x7d22, 0x8e7c, 0x418e, 0x5641, 0x3156, 0x7c31, 0x737c, 0x373,
+	0x2503, 0xc22a, 0x3c2,	0x4a04, 0x8549, 0x5285, 0xa352, 0xe8a3, 0x6fe8,
+	0x1a6f, 0x211a, 0xe021, 0x38e0, 0x7638, 0xf575, 0x9df5, 0x169e, 0xf116,
+	0x23f1, 0xcd23, 0xece,	0x660f, 0x4866, 0x6a48, 0x716a, 0xee71, 0xa2ee,
+	0xb8a2, 0x61b9, 0xa361, 0xf7a2, 0x26f7, 0x1127, 0x6611, 0xe065, 0x36e0,
+	0x1837, 0x3018, 0x1c30, 0x721b, 0x3e71, 0xe43d, 0x99e4, 0x9e9a, 0xb79d,
+	0xa9b7, 0xcaa,	0xeb0c, 0x4eb,	0x1305, 0x8813, 0xb687, 0xa9b6, 0xfba9,
+	0xd7fb, 0xccd8, 0x2ecd, 0x652f, 0xae65, 0x3fae, 0x3a40, 0x563a, 0x7556,
+	0x2776, 0x1228, 0xef12, 0xf9ee, 0xcef9, 0x56cf, 0xa956, 0x24a9, 0xba24,
+	0x5fba, 0x665f, 0xf465, 0x8ff4, 0x6d8f, 0x346d, 0x5f34, 0x385f, 0xd137,
+	0xb8d0, 0xacb8, 0x55ac, 0x7455, 0xe874, 0x89e8, 0xd189, 0xa0d1, 0xb2a0,
+	0xb8b2, 0x36b8, 0x5636, 0xd355, 0x8d3,	0x1908, 0x2118, 0xc21,	0x990c,
+	0x8b99, 0x158c, 0x7815, 0x9e78, 0x6f9e, 0x4470, 0x1d44, 0x341d, 0x2634,
+	0x3f26, 0x793e, 0xc79,	0xcc0b, 0x26cc, 0xd126, 0x1fd1, 0xb41f, 0xb6b4,
+	0x22b7, 0xa122, 0xa1,	0x7f01, 0x837e, 0x3b83, 0xaf3b, 0x6fae, 0x916f,
+	0xb490, 0xffb3, 0xceff, 0x50cf, 0x7550, 0x7275, 0x1272, 0x2613, 0xaa26,
+	0xd5aa, 0x7d5,	0x9607, 0x96,	0xb100, 0xf8b0, 0x4bf8, 0xdd4c, 0xeddd,
+	0x98ed, 0x2599, 0x9325, 0xeb92, 0x8feb, 0xcc8f, 0x2acd, 0x392b, 0x3b39,
+	0xcb3b, 0x6acb, 0xd46a, 0xb8d4, 0x6ab8, 0x106a, 0x2f10, 0x892f, 0x789,
+	0xc806, 0x45c8, 0x7445, 0x3c74, 0x3a3c, 0xcf39, 0xd7ce, 0x58d8, 0x6e58,
+	0x336e, 0x1034, 0xee10, 0xe9ed, 0xc2e9, 0x3fc2, 0xd53e, 0xd2d4, 0xead2,
+	0x8fea, 0x2190, 0x1162, 0xbe11, 0x8cbe, 0x6d8c, 0xfb6c, 0x6dfb, 0xd36e,
+	0x3ad3, 0xf3a,	0x870e, 0xc287, 0x53c3, 0xc54,	0x5b0c, 0x7d5a, 0x797d,
+	0xec79, 0x5dec, 0x4d5e, 0x184e, 0xd618, 0x60d6, 0xb360, 0x98b3, 0xf298,
+	0xb1f2, 0x69b1, 0xf969, 0xef9,	0xab0e, 0x21ab, 0xe321, 0x24e3, 0x8224,
+	0x5481, 0x5954, 0x7a59, 0xff7a, 0x7dff, 0x1a7d, 0xa51a, 0x46a5, 0x6b47,
+	0xe6b,	0x830e, 0xa083, 0xff9f, 0xd0ff, 0xffd0, 0xe6ff, 0x7de7, 0xc67d,
+	0xd0c6, 0x61d1, 0x3a62, 0xc3b,	0x150c, 0x1715, 0x4517, 0x5345, 0x3954,
+	0xdd39, 0xdadd, 0x32db, 0x6a33, 0xd169, 0x86d1, 0xb687, 0x3fb6, 0x883f,
+	0xa487, 0x39a4, 0x2139, 0xbe20, 0xffbe, 0xedfe, 0x8ded, 0x368e, 0xc335,
+	0x51c3, 0x9851, 0xf297, 0xd6f2, 0xb9d6, 0x95ba, 0x2096, 0xea1f, 0x76e9,
+	0x4e76, 0xe04d, 0xd0df, 0x80d0, 0xa280, 0xfca2, 0x75fc, 0xef75, 0x32ef,
+	0x6833, 0xdf68, 0xc4df, 0x76c4, 0xb77,	0xb10a, 0xbfb1, 0x58bf, 0x5258,
+	0x4d52, 0x6c4d, 0x7e6c, 0xb67e, 0xccb5, 0x8ccc, 0xbe8c, 0xc8bd, 0x9ac8,
+	0xa99b, 0x52a9, 0x2f53, 0xc30,	0x3e0c, 0xb83d, 0x83b7, 0x5383, 0x7e53,
+	0x4f7e, 0xe24e, 0xb3e1, 0x8db3, 0x618e, 0xc861, 0xfcc8, 0x34fc, 0x9b35,
+	0xaa9b, 0xb1aa, 0x5eb1, 0x395e, 0x8639, 0xd486, 0x8bd4, 0x558b, 0x2156,
+	0xf721, 0x4ef6, 0x14f,	0x7301, 0xdd72, 0x49de, 0x894a, 0x9889, 0x8898,
+	0x7788, 0x7b77, 0x637b, 0xb963, 0xabb9, 0x7cab, 0xc87b, 0x21c8, 0xcb21,
+	0xdfca, 0xbfdf, 0xf2bf, 0x6af2, 0x626b, 0xb261, 0x3cb2, 0xc63c, 0xc9c6,
+	0xc9c9, 0xb4c9, 0xf9b4, 0x91f9, 0x4091, 0x3a40, 0xcc39, 0xd1cb, 0x7ed1,
+	0x537f, 0x6753, 0xa167, 0xba49, 0x88ba, 0x7789, 0x3877, 0xf037, 0xd3ef,
+	0xb5d4, 0x55b6, 0xa555, 0xeca4, 0xa1ec, 0xb6a2, 0x7b7,	0x9507, 0xfd94,
+	0x82fd, 0x5c83, 0x765c, 0x9676, 0x3f97, 0xda3f, 0x6fda, 0x646f, 0x3064,
+	0x5e30, 0x655e, 0x6465, 0xcb64, 0xcdca, 0x4ccd, 0x3f4c, 0x243f, 0x6f24,
+	0x656f, 0x6065, 0x3560, 0x3b36, 0xac3b, 0x4aac, 0x714a, 0x7e71, 0xda7e,
+	0x7fda, 0xda7f, 0x6fda, 0xff6f, 0xc6ff, 0xedc6, 0xd4ed, 0x70d5, 0xeb70,
+	0xa3eb, 0x80a3, 0xca80, 0x3fcb, 0x2540, 0xf825, 0x7ef8, 0xf87e, 0x73f8,
+	0xb474, 0xb4b4, 0x92b5, 0x9293, 0x93,	0x3500, 0x7134, 0x9071, 0xfa8f,
+	0x51fa, 0x1452, 0xba13, 0x7ab9, 0x957a, 0x8a95, 0x6e8a, 0x6d6e, 0x7c6d,
+	0x447c, 0x9744, 0x4597, 0x8945, 0xef88, 0x8fee, 0x3190, 0x4831, 0x8447,
+	0xa183, 0x1da1, 0xd41d, 0x2dd4, 0x4f2e, 0xc94e, 0xcbc9, 0xc9cb, 0x9ec9,
+	0x319e, 0xd531, 0x20d5, 0x4021, 0xb23f, 0x29b2, 0xd828, 0xecd8, 0x5ded,
+	0xfc5d, 0x4dfc, 0xd24d, 0x6bd2, 0x5f6b, 0xb35e, 0x7fb3, 0xee7e, 0x56ee,
+	0xa657, 0x68a6, 0x8768, 0x7787, 0xb077, 0x4cb1, 0x764c, 0xb175, 0x7b1,
+	0x3d07, 0x603d, 0x3560, 0x3e35, 0xb03d, 0xd6b0, 0xc8d6, 0xd8c8, 0x8bd8,
+	0x3e8c, 0x303f, 0xd530, 0xf1d4, 0x42f1, 0xca42, 0xddca, 0x41dd, 0x3141,
+	0x132,	0xe901, 0x8e9,	0xbe09, 0xe0bd, 0x2ce0, 0x862d, 0x3986, 0x9139,
+	0x6d91, 0x6a6d, 0x8d6a, 0x1b8d, 0xac1b, 0xedab, 0x54ed, 0xc054, 0xcebf,
+	0xc1ce, 0x5c2,	0x3805, 0x6038, 0x5960, 0xd359, 0xdd3,	0xbe0d, 0xafbd,
+	0x6daf, 0x206d, 0x2c20, 0x862c, 0x8e86, 0xec8d, 0xa2ec, 0xa3a2, 0x51a3,
+	0x8051, 0xfd7f, 0x91fd, 0xa292, 0xaf14, 0xeeae, 0x59ef, 0x535a, 0x8653,
+	0x3986, 0x9539, 0xb895, 0xa0b8, 0x26a0, 0x2227, 0xc022, 0x77c0, 0xad77,
+	0x46ad, 0xaa46, 0x60aa, 0x8560, 0x4785, 0xd747, 0x45d7, 0x2346, 0x5f23,
+	0x25f,	0x1d02, 0x71d,	0x8206, 0xc82,	0x180c, 0x3018, 0x4b30, 0x4b,
+	0x3001, 0x1230, 0x2d12, 0x8c2d, 0x148d, 0x4015, 0x5f3f, 0x3d5f, 0x6b3d,
+	0x396b, 0x473a, 0xf746, 0x44f7, 0x8945, 0x3489, 0xcb34, 0x84ca, 0xd984,
+	0xf0d9, 0xbcf0, 0x63bd, 0x3264, 0xf332, 0x45f3, 0x7346, 0x5673, 0xb056,
+	0xd3b0, 0x4ad4, 0x184b, 0x7d18, 0x6c7d, 0xbb6c, 0xfeba, 0xe0fe, 0x10e1,
+	0x5410, 0x2954, 0x9f28, 0x3a9f, 0x5a3a, 0xdb59, 0xbdc,	0xb40b, 0x1ab4,
+	0x131b, 0x5d12, 0x6d5c, 0xe16c, 0xb0e0, 0x89b0, 0xba88, 0xbb,	0x3c01,
+	0xe13b, 0x6fe1, 0x446f, 0xa344, 0x81a3, 0xfe81, 0xc7fd, 0x38c8, 0xb38,
+	0x1a0b, 0x6d19, 0xf36c, 0x47f3, 0x6d48, 0xb76d, 0xd3b7, 0xd8d2, 0x52d9,
+	0x4b53, 0xa54a, 0x34a5, 0xc534, 0x9bc4, 0xed9b, 0xbeed, 0x3ebe, 0x233e,
+	0x9f22, 0x4a9f, 0x774b, 0x4577, 0xa545, 0x64a5, 0xb65,	0x870b, 0x487,
+	0x9204, 0x5f91, 0xd55f, 0x35d5, 0x1a35, 0x71a,	0x7a07, 0x4e7a, 0xfc4e,
+	0x1efc, 0x481f, 0x7448, 0xde74, 0xa7dd, 0x1ea7, 0xaa1e, 0xcfaa, 0xfbcf,
+	0xedfb, 0x6eee, 0x386f, 0x4538, 0x6e45, 0xd96d, 0x11d9, 0x7912, 0x4b79,
+	0x494b, 0x6049, 0xac5f, 0x65ac, 0x1366, 0x5913, 0xe458, 0x7ae4, 0x387a,
+	0x3c38, 0xb03c, 0x76b0, 0x9376, 0xe193, 0x42e1, 0x7742, 0x6476, 0x3564,
+	0x3c35, 0x6a3c, 0xcc69, 0x94cc, 0x5d95, 0xe5e,	0xee0d, 0x4ced, 0xce4c,
+	0x52ce, 0xaa52, 0xdaaa, 0xe4da, 0x1de5, 0x4530, 0x5445, 0x3954, 0xb639,
+	0x81b6, 0x7381, 0x1574, 0xc215, 0x10c2, 0x3f10, 0x6b3f, 0xe76b, 0x7be7,
+	0xbc7b, 0xf7bb, 0x41f7, 0xcc41, 0x38cc, 0x4239, 0xa942, 0x4a9,	0xc504,
+	0x7cc4, 0x437c, 0x6743, 0xea67, 0x8dea, 0xe88d, 0xd8e8, 0xdcd8, 0x17dd,
+	0x5718, 0x958,	0xa609, 0x41a5, 0x5842, 0x159,	0x9f01, 0x269f, 0x5a26,
+	0x405a, 0xc340, 0xb4c3, 0xd4b4, 0xf4d3, 0xf1f4, 0x39f2, 0xe439, 0x67e4,
+	0x4168, 0xa441, 0xdda3, 0xdedd, 0x9df,	0xab0a, 0xa5ab, 0x9a6,	0xba09,
+	0x9ab9, 0xad9a, 0x5ae,	0xe205, 0xece2, 0xecec, 0x14ed, 0xd614, 0x6bd5,
+	0x916c, 0x3391, 0x6f33, 0x206f, 0x8020, 0x780,	0x7207, 0x2472, 0x8a23,
+	0xb689, 0x3ab6, 0xf739, 0x97f6, 0xb097, 0xa4b0, 0xe6a4, 0x88e6, 0x2789,
+	0xb28,	0x350b, 0x1f35, 0x431e, 0x1043, 0xc30f, 0x79c3, 0x379,	0x5703,
+	0x3256, 0x4732, 0x7247, 0x9d72, 0x489d, 0xd348, 0xa4d3, 0x7ca4, 0xbf7b,
+	0x45c0, 0x7b45, 0x337b, 0x4034, 0x843f, 0xd083, 0x35d0, 0x6335, 0x4d63,
+	0xe14c, 0xcce0, 0xfecc, 0x35ff, 0x5636, 0xf856, 0xeef8, 0x2def, 0xfc2d,
+	0x4fc,	0x6e04, 0xb66d, 0x78b6, 0xbb78, 0x3dbb, 0x9a3d, 0x839a, 0x9283,
+	0x593,	0xd504, 0x23d5, 0x5424, 0xd054, 0x61d0, 0xdb61, 0x17db, 0x1f18,
+	0x381f, 0x9e37, 0x679e, 0x1d68, 0x381d, 0x8038, 0x917f, 0x491,	0xbb04,
+	0x23bb, 0x4124, 0xd41,	0xa30c, 0x8ba3, 0x8b8b, 0xc68b, 0xd2c6, 0xebd2,
+	0x93eb, 0xbd93, 0x99bd, 0x1a99, 0xea19, 0x58ea, 0xcf58, 0x73cf, 0x1073,
+	0x9e10, 0x139e, 0xea13, 0xcde9, 0x3ecd, 0x883f, 0xf89,	0x180f, 0x2a18,
+	0x212a, 0xce20, 0x73ce, 0xf373, 0x60f3, 0xad60, 0x4093, 0x8e40, 0xb98e,
+	0xbfb9, 0xf1bf, 0x8bf1, 0x5e8c, 0xe95e, 0x14e9, 0x4e14, 0x1c4e, 0x7f1c,
+	0xe77e, 0x6fe7, 0xf26f, 0x13f2, 0x8b13, 0xda8a, 0x5fda, 0xea5f, 0x4eea,
+	0xa84f, 0x88a8, 0x1f88, 0x2820, 0x9728, 0x5a97, 0x3f5b, 0xb23f, 0x70b2,
+	0x2c70, 0x232d, 0xf623, 0x4f6,	0x905,	0x7509, 0xd675, 0x28d7, 0x9428,
+	0x3794, 0xf036, 0x2bf0, 0xba2c, 0xedb9, 0xd7ed, 0x59d8, 0xed59, 0x4ed,
+	0xe304, 0x18e3, 0x5c19, 0x3d5c, 0x753d, 0x6d75, 0x956d, 0x7f95, 0xc47f,
+	0x83c4, 0xa84,	0x2e0a, 0x5f2e, 0xb95f, 0x77b9, 0x6d78, 0xf46d, 0x1bf4,
+	0xed1b, 0xd6ed, 0xe0d6, 0x5e1,	0x3905, 0x5638, 0xa355, 0x99a2, 0xbe99,
+	0xb4bd, 0x85b4, 0x2e86, 0x542e, 0x6654, 0xd765, 0x73d7, 0x3a74, 0x383a,
+	0x2638, 0x7826, 0x7677, 0x9a76, 0x7e99, 0x2e7e, 0xea2d, 0xa6ea, 0x8a7,
+	0x109,	0x3300, 0xad32, 0x5fad, 0x465f, 0x2f46, 0xc62f, 0xd4c5, 0xad5,
+	0xcb0a, 0x4cb,	0xb004, 0x7baf, 0xe47b, 0x92e4, 0x8e92, 0x638e, 0x1763,
+	0xc17,	0xf20b, 0x1ff2, 0x8920, 0x5889, 0xcb58, 0xf8cb, 0xcaf8, 0x84cb,
+	0x9f84, 0x8a9f, 0x918a, 0x4991, 0x8249, 0xff81, 0x46ff, 0x5046, 0x5f50,
+	0x725f, 0xf772, 0x8ef7, 0xe08f, 0xc1e0, 0x1fc2, 0x9e1f, 0x8b9d, 0x108b,
+	0x411,	0x2b04, 0xb02a, 0x1fb0, 0x1020, 0x7a0f, 0x587a, 0x8958, 0xb188,
+	0xb1b1, 0x49b2, 0xb949, 0x7ab9, 0x917a, 0xfc91, 0xe6fc, 0x47e7, 0xbc47,
+	0x8fbb, 0xea8e, 0x34ea, 0x2635, 0x1726, 0x9616, 0xc196, 0xa6c1, 0xf3a6,
+	0x11f3, 0x4811, 0x3e48, 0xeb3e, 0xf7ea, 0x1bf8, 0xdb1c, 0x8adb, 0xe18a,
+	0x42e1, 0x9d42, 0x5d9c, 0x6e5d, 0x286e, 0x4928, 0x9a49, 0xb09c, 0xa6b0,
+	0x2a7,	0xe702, 0xf5e6, 0x9af5, 0xf9b,	0x810f, 0x8080, 0x180,	0x1702,
+	0x5117, 0xa650, 0x11a6, 0x1011, 0x550f, 0xd554, 0xbdd5, 0x6bbe, 0xc66b,
+	0xfc7,	0x5510, 0x5555, 0x7655, 0x177,	0x2b02, 0x6f2a, 0xb70,	0x9f0b,
+	0xcf9e, 0xf3cf, 0x3ff4, 0xcb40, 0x8ecb, 0x768e, 0x5277, 0x8652, 0x9186,
+	0x9991, 0x5099, 0xd350, 0x93d3, 0x6d94, 0xe6d,	0x530e, 0x3153, 0xa531,
+	0x64a5, 0x7964, 0x7c79, 0x467c, 0x1746, 0x3017, 0x3730, 0x538,	0x5,
+	0x1e00, 0x5b1e, 0x955a, 0xae95, 0x3eaf, 0xff3e, 0xf8ff, 0xb2f9, 0xa1b3,
+	0xb2a1, 0x5b2,	0xad05, 0x7cac, 0x2d7c, 0xd32c, 0x80d2, 0x7280, 0x8d72,
+	0x1b8e, 0x831b, 0xac82, 0xfdac, 0xa7fd, 0x15a8, 0xd614, 0xe0d5, 0x7be0,
+	0xb37b, 0x61b3, 0x9661, 0x9d95, 0xc79d, 0x83c7, 0xd883, 0xead7, 0xceb,
+	0xf60c, 0xa9f5, 0x19a9, 0xa019, 0x8f9f, 0xd48f, 0x3ad5, 0x853a, 0x985,
+	0x5309, 0x6f52, 0x1370, 0x6e13, 0xa96d, 0x98a9, 0x5198, 0x9f51, 0xb69f,
+	0xa1b6, 0x2ea1, 0x672e, 0x2067, 0x6520, 0xaf65, 0x6eaf, 0x7e6f, 0xee7e,
+	0x17ef, 0xa917, 0xcea8, 0x9ace, 0xff99, 0x5dff, 0xdf5d, 0x38df, 0xa39,
+	0x1c0b, 0xe01b, 0x46e0, 0xcb46, 0x90cb, 0xba90, 0x4bb,	0x9104, 0x9d90,
+	0xc89c, 0xf6c8, 0x6cf6, 0x886c, 0x1789, 0xbd17, 0x70bc, 0x7e71, 0x17e,
+	0x1f01, 0xa01f, 0xbaa0, 0x14bb, 0xfc14, 0x7afb, 0xa07a, 0x3da0, 0xbf3d,
+	0x48bf, 0x8c48, 0x968b, 0x9d96, 0xfd9d, 0x96fd, 0x9796, 0x6b97, 0xd16b,
+	0xf4d1, 0x3bf4, 0x253c, 0x9125, 0x6691, 0xc166, 0x34c1, 0x5735, 0x1a57,
+	0xdc19, 0x77db, 0x8577, 0x4a85, 0x824a, 0x9182, 0x7f91, 0xfd7f, 0xb4c3,
+	0xb5b4, 0xb3b5, 0x7eb3, 0x617e, 0x4e61, 0xa4f,	0x530a, 0x3f52, 0xa33e,
+	0x34a3, 0x9234, 0xf091, 0xf4f0, 0x1bf5, 0x311b, 0x9631, 0x6a96, 0x386b,
+	0x1d39, 0xe91d, 0xe8e9, 0x69e8, 0x426a, 0xee42, 0x89ee, 0x368a, 0x2837,
+	0x7428, 0x5974, 0x6159, 0x1d62, 0x7b1d, 0xf77a, 0x7bf7, 0x6b7c, 0x696c,
+	0xf969, 0x4cf9, 0x714c, 0x4e71, 0x6b4e, 0x256c, 0x6e25, 0xe96d, 0x94e9,
+	0x8f94, 0x3e8f, 0x343e, 0x4634, 0xb646, 0x97b5, 0x8997, 0xe8a,	0x900e,
+	0x8090, 0xfd80, 0xa0fd, 0x16a1, 0xf416, 0xebf4, 0x95ec, 0x1196, 0x8911,
+	0x3d89, 0xda3c, 0x9fd9, 0xd79f, 0x4bd7, 0x214c, 0x3021, 0x4f30, 0x994e,
+	0x5c99, 0x6f5d, 0x326f, 0xab31, 0x6aab, 0xe969, 0x90e9, 0x1190, 0xff10,
+	0xa2fe, 0xe0a2, 0x66e1, 0x4067, 0x9e3f, 0x2d9e, 0x712d, 0x8170, 0xd180,
+	0xffd1, 0x25ff, 0x3826, 0x2538, 0x5f24, 0xc45e, 0x1cc4, 0xdf1c, 0x93df,
+	0xc793, 0x80c7, 0x2380, 0xd223, 0x7ed2, 0xfc7e, 0x22fd, 0x7422, 0x1474,
+	0xb714, 0x7db6, 0x857d, 0xa85,	0xa60a, 0x88a6, 0x4289, 0x7842, 0xc278,
+	0xf7c2, 0xcdf7, 0x84cd, 0xae84, 0x8cae, 0xb98c, 0x1aba, 0x4d1a, 0x884c,
+	0x4688, 0xcc46, 0xd8cb, 0x2bd9, 0xbe2b, 0xa2be, 0x72a2, 0xf772, 0xd2f6,
+	0x75d2, 0xc075, 0xa3c0, 0x63a3, 0xae63, 0x8fae, 0x2a90, 0x5f2a, 0xef5f,
+	0x5cef, 0xa05c, 0x89a0, 0x5e89, 0x6b5e, 0x736b, 0x773,	0x9d07, 0xe99c,
+	0x27ea, 0x2028, 0xc20,	0x980b, 0x4797, 0x2848, 0x9828, 0xc197, 0x48c2,
+	0x2449, 0x7024, 0x570,	0x3e05, 0xd3e,	0xf60c, 0xbbf5, 0x69bb, 0x3f6a,
+	0x740,	0xf006, 0xe0ef, 0xbbe0, 0xadbb, 0x56ad, 0xcf56, 0xbfce, 0xa9bf,
+	0x205b, 0x6920, 0xae69, 0x50ae, 0x2050, 0xf01f, 0x27f0, 0x9427, 0x8993,
+	0x8689, 0x4087, 0x6e40, 0xb16e, 0xa1b1, 0xe8a1, 0x87e8, 0x6f88, 0xfe6f,
+	0x4cfe, 0xe94d, 0xd5e9, 0x47d6, 0x3148, 0x5f31, 0xc35f, 0x13c4, 0xa413,
+	0x5a5,	0x2405, 0xc223, 0x66c2, 0x3667, 0x5e37, 0x5f5e, 0x2f5f, 0x8c2f,
+	0xe48c, 0xd0e4, 0x4d1,	0xd104, 0xe4d0, 0xcee4, 0xfcf,	0x480f, 0xa447,
+	0x5ea4, 0xff5e, 0xbefe, 0x8dbe, 0x1d8e, 0x411d, 0x1841, 0x6918, 0x5469,
+	0x1155, 0xc611, 0xaac6, 0x37ab, 0x2f37, 0xca2e, 0x87ca, 0xbd87, 0xabbd,
+	0xb3ab, 0xcb4,	0xce0c, 0xfccd, 0xa5fd, 0x72a5, 0xf072, 0x83f0, 0xfe83,
+	0x97fd, 0xc997, 0xb0c9, 0xadb0, 0xe6ac, 0x88e6, 0x1088, 0xbe10, 0x16be,
+	0xa916, 0xa3a8, 0x46a3, 0x5447, 0xe953, 0x84e8, 0x2085, 0xa11f, 0xfa1,
+	0xdd0f, 0xbedc, 0x5abe, 0x805a, 0xc97f, 0x6dc9, 0x826d, 0x4a82, 0x934a,
+	0x5293, 0xd852, 0xd3d8, 0xadd3, 0xf4ad, 0xf3f4, 0xfcf3, 0xfefc, 0xcafe,
+	0xb7ca, 0x3cb8, 0xa13c, 0x18a1, 0x1418, 0xea13, 0x91ea, 0xf891, 0x53f8,
+	0xa254, 0xe9a2, 0x87ea, 0x4188, 0x1c41, 0xdc1b, 0xf5db, 0xcaf5, 0x45ca,
+	0x6d45, 0x396d, 0xde39, 0x90dd, 0x1e91, 0x1e,	0x7b00, 0x6a7b, 0xa46a,
+	0xc9a3, 0x9bc9, 0x389b, 0x1139, 0x5211, 0x1f52, 0xeb1f, 0xabeb, 0x48ab,
+	0x9348, 0xb392, 0x17b3, 0x1618, 0x5b16, 0x175b, 0xdc17, 0xdedb, 0x1cdf,
+	0xeb1c, 0xd1ea, 0x4ad2, 0xd4b,	0xc20c, 0x24c2, 0x7b25, 0x137b, 0x8b13,
+	0x618b, 0xa061, 0xff9f, 0xfffe, 0x72ff, 0xf572, 0xe2f5, 0xcfe2, 0xd2cf,
+	0x75d3, 0x6a76, 0xc469, 0x1ec4, 0xfc1d, 0x59fb, 0x455a, 0x7a45, 0xa479,
+	0xb7a4
+};
+
+static u8 tmp_buf[TEST_BUFLEN];
+
+#define full_csum(buff, len, sum) csum_fold(csum_partial(buff, len, sum))
+
+#define CHECK_EQ(lhs, rhs) KUNIT_ASSERT_EQ(test, (__force u64)lhs, (__force u64)rhs)
+
+static __sum16 to_sum16(u16 x)
+{
+	return (__force __sum16)le16_to_cpu((__force __le16)x);
+}
+
+/* This function swaps the bytes inside each half of a __wsum */
+static __wsum to_wsum(u32 x)
+{
+	u16 hi = le16_to_cpu((__force __le16)(x >> 16));
+	u16 lo = le16_to_cpu((__force __le16)x);
+
+	return (__force __wsum)((hi << 16) | lo);
+}
+
+static void assert_setup_correct(struct kunit *test)
+{
+	CHECK_EQ(ARRAY_SIZE(random_buf), MAX_LEN);
+	CHECK_EQ(ARRAY_SIZE(expected_results), MAX_LEN);
+	CHECK_EQ(ARRAY_SIZE(init_sums_no_overflow), MAX_LEN);
+}
+
+/*
+ * Test with randomized input (pre determined random with known results).
+ */
+static void test_csum_fixed_random_inputs(struct kunit *test)
+{
+	int len, align;
+	__wsum sum;
+	__sum16 result, expec;
+
+	assert_setup_correct(test);
+	for (align = 0; align < TEST_BUFLEN; ++align) {
+		memcpy(&tmp_buf[align], random_buf,
+		       min(MAX_LEN, TEST_BUFLEN - align));
+		for (len = 0; len < MAX_LEN && (align + len) < TEST_BUFLEN;
+		     ++len) {
+			/*
+			 * Test the precomputed random input.
+			 */
+			sum = to_wsum(random_init_sum);
+			result = full_csum(&tmp_buf[align], len, sum);
+			expec = to_sum16(expected_results[len]);
+			CHECK_EQ(result, expec);
+		}
+	}
+}
+
+/*
+ * All ones input test. If there are any missing carry operations, it fails.
+ */
+static void test_csum_all_carry_inputs(struct kunit *test)
+{
+	int len, align;
+	__wsum sum;
+	__sum16 result, expec;
+
+	assert_setup_correct(test);
+	memset(tmp_buf, 0xff, TEST_BUFLEN);
+	for (align = 0; align < TEST_BUFLEN; ++align) {
+		for (len = 0; len < MAX_LEN && (align + len) < TEST_BUFLEN;
+		     ++len) {
+			/*
+			 * All carries from input and initial sum.
+			 */
+			sum = to_wsum(0xffffffff);
+			result = full_csum(&tmp_buf[align], len, sum);
+			expec = to_sum16((len & 1) ? 0xff00 : 0);
+			CHECK_EQ(result, expec);
+
+			/*
+			 * All carries from input.
+			 */
+			sum = 0;
+			result = full_csum(&tmp_buf[align], len, sum);
+			if (len & 1)
+				expec = to_sum16(0xff00);
+			else if (len)
+				expec = 0;
+			else
+				expec = to_sum16(0xffff);
+			CHECK_EQ(result, expec);
+		}
+	}
+}
+
+/*
+ * Test with input that alone doesn't cause any carries. By selecting the
+ * maximum initial sum, this allows us to test that there are no carries
+ * where there shouldn't be.
+ */
+static void test_csum_no_carry_inputs(struct kunit *test)
+{
+	int len, align;
+	__wsum sum;
+	__sum16 result, expec;
+
+	assert_setup_correct(test);
+	memset(tmp_buf, 0x4, TEST_BUFLEN);
+	for (align = 0; align < TEST_BUFLEN; ++align) {
+		for (len = 0; len < MAX_LEN && (align + len) < TEST_BUFLEN;
+		     ++len) {
+			/*
+			 * Expect no carries.
+			 */
+			sum = to_wsum(init_sums_no_overflow[len]);
+			result = full_csum(&tmp_buf[align], len, sum);
+			expec = 0;
+			CHECK_EQ(result, expec);
+
+			/*
+			 * Expect one carry.
+			 */
+			sum = to_wsum(init_sums_no_overflow[len] + 1);
+			result = full_csum(&tmp_buf[align], len, sum);
+			expec = to_sum16(len ? 0xfffe : 0xffff);
+			CHECK_EQ(result, expec);
+		}
+	}
+}
+
+static void test_ip_fast_csum(struct kunit *test)
+{
+	__sum16 csum_result;
+	u16 expected;
+
+	for (int len = IPv4_MIN_WORDS; len < IPv4_MAX_WORDS; len++) {
+		for (int index = 0; index < NUM_IP_FAST_CSUM_TESTS; index++) {
+			csum_result = ip_fast_csum(random_buf + index, len);
+			expected =
+				expected_fast_csum[(len - IPv4_MIN_WORDS) *
+						   NUM_IP_FAST_CSUM_TESTS +
+						   index];
+			CHECK_EQ(to_sum16(expected), csum_result);
+		}
+	}
+}
+
+static void test_csum_ipv6_magic(struct kunit *test)
+{
+	const struct in6_addr *saddr;
+	const struct in6_addr *daddr;
+	unsigned int len;
+	unsigned char proto;
+	__wsum csum;
+
+	if (!IS_ENABLED(CONFIG_NET))
+		return;
+
+	const int daddr_offset = sizeof(struct in6_addr);
+	const int len_offset = sizeof(struct in6_addr) + sizeof(struct in6_addr);
+	const int proto_offset = sizeof(struct in6_addr) + sizeof(struct in6_addr) +
+			     sizeof(int);
+	const int csum_offset = sizeof(struct in6_addr) + sizeof(struct in6_addr) +
+			    sizeof(int) + sizeof(char);
+
+	for (int i = 0; i < NUM_IPv6_TESTS; i++) {
+		saddr = (const struct in6_addr *)(random_buf + i);
+		daddr = (const struct in6_addr *)(random_buf + i +
+						  daddr_offset);
+		len = le32_to_cpu(*(__le32 *)(random_buf + i + len_offset));
+		proto = *(random_buf + i + proto_offset);
+		csum = *(__wsum *)(random_buf + i + csum_offset);
+		CHECK_EQ(to_sum16(expected_csum_ipv6_magic[i]),
+			 csum_ipv6_magic(saddr, daddr, len, proto, csum));
+	}
+}
+
+static struct kunit_case __refdata checksum_test_cases[] = {
+	KUNIT_CASE(test_csum_fixed_random_inputs),
+	KUNIT_CASE(test_csum_all_carry_inputs),
+	KUNIT_CASE(test_csum_no_carry_inputs),
+	KUNIT_CASE(test_ip_fast_csum),
+	KUNIT_CASE(test_csum_ipv6_magic),
+	{}
+};
+
+static struct kunit_suite checksum_test_suite = {
+	.name = "checksum",
+	.test_cases = checksum_test_cases,
+};
+
+kunit_test_suites(&checksum_test_suite);
+
+MODULE_AUTHOR("Noah Goldstein <goldstein.w.n@xxxxxxxxx>");
+MODULE_DESCRIPTION("Test cases csum_* APIs");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/cmdline_kunit.c a/lib/tests/cmdline_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/cmdline_kunit.c
@@ -0,0 +1,157 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test cases for API provided by cmdline.c
+ */
+
+#include <kunit/test.h>
+#include <linux/kernel.h>
+#include <linux/random.h>
+#include <linux/string.h>
+
+static const char *cmdline_test_strings[] = {
+	"\"\"", ""  , "=" , "\"-", ","    , "-,"   , ",-"   , "-" ,
+	"+,"  , "--", ",,", "''" , "\"\",", "\",\"", "-\"\"", "\"",
+};
+
+static const int cmdline_test_values[] = {
+	1, 1, 1, 1, 2, 3, 2, 3,
+	1, 3, 2, 1, 1, 1, 3, 1,
+};
+
+static_assert(ARRAY_SIZE(cmdline_test_strings) == ARRAY_SIZE(cmdline_test_values));
+
+static const char *cmdline_test_range_strings[] = {
+	"-7" , "--7"  , "-1-2"    , "7--9",
+	"7-" , "-7--9", "7-9,"    , "9-7" ,
+	"5-a", "a-5"  , "5-8"     , ",8-5",
+	"+,1", "-,4"  , "-3,0-1,6", "4,-" ,
+	" +2", " -9"  , "0-1,-3,6", "- 9" ,
+};
+
+static const int cmdline_test_range_values[][16] = {
+	{ 1, -7, }, { 0, -0, }, { 4, -1, 0, +1, 2, }, { 0, 7, },
+	{ 0, +7, }, { 0, -7, }, { 3, +7, 8, +9, 0, }, { 0, 9, },
+	{ 0, +5, }, { 0, -0, }, { 4, +5, 6, +7, 8, }, { 0, 0, },
+	{ 0, +0, }, { 0, -0, }, { 4, -3, 0, +1, 6, }, { 1, 4, },
+	{ 0, +0, }, { 0, -0, }, { 4, +0, 1, -3, 6, }, { 0, 0, },
+};
+
+static_assert(ARRAY_SIZE(cmdline_test_range_strings) == ARRAY_SIZE(cmdline_test_range_values));
+
+static void cmdline_do_one_test(struct kunit *test, const char *in, int rc, int offset)
+{
+	const char *fmt = "Pattern: %s";
+	const char *out = in;
+	int dummy;
+	int ret;
+
+	ret = get_option((char **)&out, &dummy);
+
+	KUNIT_EXPECT_EQ_MSG(test, ret, rc, fmt, in);
+	KUNIT_EXPECT_PTR_EQ_MSG(test, out, in + offset, fmt, in);
+}
+
+static void cmdline_test_noint(struct kunit *test)
+{
+	unsigned int i = 0;
+
+	do {
+		const char *str = cmdline_test_strings[i];
+		int rc = 0;
+		int offset;
+
+		/* Only first and leading '-' will advance the pointer */
+		offset = !!(*str == '-');
+		cmdline_do_one_test(test, str, rc, offset);
+	} while (++i < ARRAY_SIZE(cmdline_test_strings));
+}
+
+static void cmdline_test_lead_int(struct kunit *test)
+{
+	unsigned int i = 0;
+	char in[32];
+
+	do {
+		const char *str = cmdline_test_strings[i];
+		int rc = cmdline_test_values[i];
+		int offset;
+
+		sprintf(in, "%u%s", get_random_u8(), str);
+		/* Only first '-' after the number will advance the pointer */
+		offset = strlen(in) - strlen(str) + !!(rc == 2);
+		cmdline_do_one_test(test, in, rc, offset);
+	} while (++i < ARRAY_SIZE(cmdline_test_strings));
+}
+
+static void cmdline_test_tail_int(struct kunit *test)
+{
+	unsigned int i = 0;
+	char in[32];
+
+	do {
+		const char *str = cmdline_test_strings[i];
+		/* When "" or "-" the result will be valid integer */
+		int rc = strcmp(str, "") ? (strcmp(str, "-") ? 0 : 1) : 1;
+		int offset;
+
+		sprintf(in, "%s%u", str, get_random_u8());
+		/*
+		 * Only first and leading '-' not followed by integer
+		 * will advance the pointer.
+		 */
+		offset = rc ? strlen(in) : !!(*str == '-');
+		cmdline_do_one_test(test, in, rc, offset);
+	} while (++i < ARRAY_SIZE(cmdline_test_strings));
+}
+
+static void cmdline_do_one_range_test(struct kunit *test, const char *in,
+				      unsigned int n, const int *e)
+{
+	unsigned int i;
+	int r[16];
+	int *p;
+
+	memset(r, 0, sizeof(r));
+	get_options(in, ARRAY_SIZE(r), r);
+	KUNIT_EXPECT_EQ_MSG(test, r[0], e[0], "in test %u (parsed) expected %d numbers, got %d",
+			    n, e[0], r[0]);
+	for (i = 1; i < ARRAY_SIZE(r); i++)
+		KUNIT_EXPECT_EQ_MSG(test, r[i], e[i], "in test %u at %u", n, i);
+
+	memset(r, 0, sizeof(r));
+	get_options(in, 0, r);
+	KUNIT_EXPECT_EQ_MSG(test, r[0], e[0], "in test %u (validated) expected %d numbers, got %d",
+			    n, e[0], r[0]);
+
+	p = memchr_inv(&r[1], 0, sizeof(r) - sizeof(r[0]));
+	KUNIT_EXPECT_PTR_EQ_MSG(test, p, NULL, "in test %u at %td out of bound", n, p - r);
+}
+
+static void cmdline_test_range(struct kunit *test)
+{
+	unsigned int i = 0;
+
+	do {
+		const char *str = cmdline_test_range_strings[i];
+		const int *e = cmdline_test_range_values[i];
+
+		cmdline_do_one_range_test(test, str, i, e);
+	} while (++i < ARRAY_SIZE(cmdline_test_range_strings));
+}
+
+static struct kunit_case cmdline_test_cases[] = {
+	KUNIT_CASE(cmdline_test_noint),
+	KUNIT_CASE(cmdline_test_lead_int),
+	KUNIT_CASE(cmdline_test_tail_int),
+	KUNIT_CASE(cmdline_test_range),
+	{}
+};
+
+static struct kunit_suite cmdline_test_suite = {
+	.name = "cmdline",
+	.test_cases = cmdline_test_cases,
+};
+kunit_test_suite(cmdline_test_suite);
+
+MODULE_DESCRIPTION("Test cases for API provided by cmdline.c");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/cpumask_kunit.c a/lib/tests/cpumask_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/cpumask_kunit.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * KUnit tests for cpumask.
+ *
+ * Author: Sander Vanheule <sander@xxxxxxxxxxxxx>
+ */
+
+#include <kunit/test.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+
+#define MASK_MSG(m) \
+	"%s contains %sCPUs %*pbl", #m, (cpumask_weight(m) ? "" : "no "), \
+	nr_cpumask_bits, cpumask_bits(m)
+
+#define EXPECT_FOR_EACH_CPU_EQ(test, mask)			\
+	do {							\
+		const cpumask_t *m = (mask);			\
+		int mask_weight = cpumask_weight(m);		\
+		int cpu, iter = 0;				\
+		for_each_cpu(cpu, m)				\
+			iter++;					\
+		KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(mask));	\
+	} while (0)
+
+#define EXPECT_FOR_EACH_CPU_OP_EQ(test, op, mask1, mask2)			\
+	do {									\
+		const cpumask_t *m1 = (mask1);					\
+		const cpumask_t *m2 = (mask2);					\
+		int weight;                                                     \
+		int cpu, iter = 0;						\
+		cpumask_##op(&mask_tmp, m1, m2);                                \
+		weight = cpumask_weight(&mask_tmp);				\
+		for_each_cpu_##op(cpu, mask1, mask2)				\
+			iter++;							\
+		KUNIT_EXPECT_EQ((test), weight, iter);				\
+	} while (0)
+
+#define EXPECT_FOR_EACH_CPU_WRAP_EQ(test, mask)			\
+	do {							\
+		const cpumask_t *m = (mask);			\
+		int mask_weight = cpumask_weight(m);		\
+		int cpu, iter = 0;				\
+		for_each_cpu_wrap(cpu, m, nr_cpu_ids / 2)	\
+			iter++;					\
+		KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(mask));	\
+	} while (0)
+
+#define EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, name)		\
+	do {							\
+		int mask_weight = num_##name##_cpus();		\
+		int cpu, iter = 0;				\
+		for_each_##name##_cpu(cpu)			\
+			iter++;					\
+		KUNIT_EXPECT_EQ_MSG((test), mask_weight, iter, MASK_MSG(cpu_##name##_mask));	\
+	} while (0)
+
+static cpumask_t mask_empty;
+static cpumask_t mask_all;
+static cpumask_t mask_tmp;
+
+static void test_cpumask_weight(struct kunit *test)
+{
+	KUNIT_EXPECT_TRUE_MSG(test, cpumask_empty(&mask_empty), MASK_MSG(&mask_empty));
+	KUNIT_EXPECT_TRUE_MSG(test, cpumask_full(&mask_all), MASK_MSG(&mask_all));
+
+	KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_weight(&mask_empty), MASK_MSG(&mask_empty));
+	KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids, cpumask_weight(cpu_possible_mask),
+			    MASK_MSG(cpu_possible_mask));
+	KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids, cpumask_weight(&mask_all), MASK_MSG(&mask_all));
+}
+
+static void test_cpumask_first(struct kunit *test)
+{
+	KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_first(&mask_empty), MASK_MSG(&mask_empty));
+	KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_first(cpu_possible_mask), MASK_MSG(cpu_possible_mask));
+
+	KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_first_zero(&mask_empty), MASK_MSG(&mask_empty));
+	KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_first_zero(cpu_possible_mask),
+			    MASK_MSG(cpu_possible_mask));
+}
+
+static void test_cpumask_last(struct kunit *test)
+{
+	KUNIT_EXPECT_LE_MSG(test, nr_cpumask_bits, cpumask_last(&mask_empty),
+			    MASK_MSG(&mask_empty));
+	KUNIT_EXPECT_EQ_MSG(test, nr_cpu_ids - 1, cpumask_last(cpu_possible_mask),
+			    MASK_MSG(cpu_possible_mask));
+}
+
+static void test_cpumask_next(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_next_zero(-1, &mask_empty), MASK_MSG(&mask_empty));
+	KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_next_zero(-1, cpu_possible_mask),
+			    MASK_MSG(cpu_possible_mask));
+
+	KUNIT_EXPECT_LE_MSG(test, nr_cpu_ids, cpumask_next(-1, &mask_empty),
+			    MASK_MSG(&mask_empty));
+	KUNIT_EXPECT_EQ_MSG(test, 0, cpumask_next(-1, cpu_possible_mask),
+			    MASK_MSG(cpu_possible_mask));
+}
+
+static void test_cpumask_iterators(struct kunit *test)
+{
+	EXPECT_FOR_EACH_CPU_EQ(test, &mask_empty);
+	EXPECT_FOR_EACH_CPU_WRAP_EQ(test, &mask_empty);
+	EXPECT_FOR_EACH_CPU_OP_EQ(test, and, &mask_empty, &mask_empty);
+	EXPECT_FOR_EACH_CPU_OP_EQ(test, and, cpu_possible_mask, &mask_empty);
+	EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot, &mask_empty, &mask_empty);
+
+	EXPECT_FOR_EACH_CPU_EQ(test, cpu_possible_mask);
+	EXPECT_FOR_EACH_CPU_WRAP_EQ(test, cpu_possible_mask);
+	EXPECT_FOR_EACH_CPU_OP_EQ(test, and, cpu_possible_mask, cpu_possible_mask);
+	EXPECT_FOR_EACH_CPU_OP_EQ(test, andnot, cpu_possible_mask, &mask_empty);
+}
+
+static void test_cpumask_iterators_builtin(struct kunit *test)
+{
+	EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, possible);
+
+	/* Ensure the dynamic masks are stable while running the tests */
+	cpu_hotplug_disable();
+
+	EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, online);
+	EXPECT_FOR_EACH_CPU_BUILTIN_EQ(test, present);
+
+	cpu_hotplug_enable();
+}
+
+static int test_cpumask_init(struct kunit *test)
+{
+	cpumask_clear(&mask_empty);
+	cpumask_setall(&mask_all);
+
+	return 0;
+}
+
+static struct kunit_case test_cpumask_cases[] = {
+	KUNIT_CASE(test_cpumask_weight),
+	KUNIT_CASE(test_cpumask_first),
+	KUNIT_CASE(test_cpumask_last),
+	KUNIT_CASE(test_cpumask_next),
+	KUNIT_CASE(test_cpumask_iterators),
+	KUNIT_CASE(test_cpumask_iterators_builtin),
+	{}
+};
+
+static struct kunit_suite test_cpumask_suite = {
+	.name = "cpumask",
+	.init = test_cpumask_init,
+	.test_cases = test_cpumask_cases,
+};
+kunit_test_suite(test_cpumask_suite);
+
+MODULE_DESCRIPTION("KUnit tests for cpumask");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/fortify_kunit.c a/lib/tests/fortify_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/fortify_kunit.c
@@ -0,0 +1,1096 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Runtime test cases for CONFIG_FORTIFY_SOURCE. For additional memcpy()
+ * testing see FORTIFY_MEM_* tests in LKDTM (drivers/misc/lkdtm/fortify.c).
+ *
+ * For corner cases with UBSAN, try testing with:
+ *
+ * ./tools/testing/kunit/kunit.py run --arch=x86_64 \
+ *	--kconfig_add CONFIG_FORTIFY_SOURCE=y \
+ *	--kconfig_add CONFIG_UBSAN=y \
+ *	--kconfig_add CONFIG_UBSAN_TRAP=y \
+ *	--kconfig_add CONFIG_UBSAN_BOUNDS=y \
+ *	--kconfig_add CONFIG_UBSAN_LOCAL_BOUNDS=y \
+ *	--make_options LLVM=1 fortify
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+/* We don't need to fill dmesg with the fortify WARNs during testing. */
+#ifdef DEBUG
+# define FORTIFY_REPORT_KUNIT(x...) __fortify_report(x)
+# define FORTIFY_WARN_KUNIT(x...)   WARN_ONCE(x)
+#else
+# define FORTIFY_REPORT_KUNIT(x...) do { } while (0)
+# define FORTIFY_WARN_KUNIT(x...)   do { } while (0)
+#endif
+
+/* Redefine fortify_panic() to track failures. */
+void fortify_add_kunit_error(int write);
+#define fortify_panic(func, write, avail, size, retfail) do {		\
+	FORTIFY_REPORT_KUNIT(FORTIFY_REASON(func, write), avail, size);	\
+	fortify_add_kunit_error(write);					\
+	return (retfail);						\
+} while (0)
+
+/* Redefine fortify_warn_once() to track memcpy() failures. */
+#define fortify_warn_once(chk_func, x...) do {				\
+	bool __result = chk_func;					\
+	FORTIFY_WARN_KUNIT(__result, x);				\
+	if (__result)							\
+		fortify_add_kunit_error(1);				\
+} while (0)
+
+#include <kunit/device.h>
+#include <kunit/test.h>
+#include <kunit/test-bug.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
+
+/* Handle being built without CONFIG_FORTIFY_SOURCE */
+#ifndef __compiletime_strlen
+# define __compiletime_strlen __builtin_strlen
+#endif
+
+static struct kunit_resource read_resource;
+static struct kunit_resource write_resource;
+static int fortify_read_overflows;
+static int fortify_write_overflows;
+
+static const char array_of_10[] = "this is 10";
+static const char *ptr_of_11 = "this is 11!";
+static char array_unknown[] = "compiler thinks I might change";
+
+void fortify_add_kunit_error(int write)
+{
+	struct kunit_resource *resource;
+	struct kunit *current_test;
+
+	current_test = kunit_get_current_test();
+	if (!current_test)
+		return;
+
+	resource = kunit_find_named_resource(current_test,
+			write ? "fortify_write_overflows"
+			      : "fortify_read_overflows");
+	if (!resource)
+		return;
+
+	(*(int *)resource->data)++;
+	kunit_put_resource(resource);
+}
+
+static void fortify_test_known_sizes(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, __compiletime_strlen("88888888"), 8);
+	KUNIT_EXPECT_EQ(test, __compiletime_strlen(array_of_10), 10);
+	KUNIT_EXPECT_EQ(test, __compiletime_strlen(ptr_of_11), 11);
+
+	KUNIT_EXPECT_EQ(test, __compiletime_strlen(array_unknown), SIZE_MAX);
+	/* Externally defined and dynamically sized string pointer: */
+	KUNIT_EXPECT_EQ(test, __compiletime_strlen(test->name), SIZE_MAX);
+}
+
+/* This is volatile so the optimizer can't perform DCE below. */
+static volatile int pick;
+
+/* Not inline to keep optimizer from figuring out which string we want. */
+static noinline size_t want_minus_one(int pick)
+{
+	const char *str;
+
+	switch (pick) {
+	case 1:
+		str = "4444";
+		break;
+	case 2:
+		str = "333";
+		break;
+	default:
+		str = "1";
+		break;
+	}
+	return __compiletime_strlen(str);
+}
+
+static void fortify_test_control_flow_split(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, want_minus_one(pick), SIZE_MAX);
+}
+
+#define KUNIT_EXPECT_BOS(test, p, expected, name)			\
+	KUNIT_EXPECT_EQ_MSG(test, __builtin_object_size(p, 1),		\
+		expected,						\
+		"__alloc_size() not working with __bos on " name "\n")
+
+#if !__has_builtin(__builtin_dynamic_object_size)
+#define KUNIT_EXPECT_BDOS(test, p, expected, name)			\
+	/* Silence "unused variable 'expected'" warning. */		\
+	KUNIT_EXPECT_EQ(test, expected, expected)
+#else
+#define KUNIT_EXPECT_BDOS(test, p, expected, name)			\
+	KUNIT_EXPECT_EQ_MSG(test, __builtin_dynamic_object_size(p, 1),	\
+		expected,						\
+		"__alloc_size() not working with __bdos on " name "\n")
+#endif
+
+/* If the execpted size is a constant value, __bos can see it. */
+#define check_const(_expected, alloc, free)		do {		\
+	size_t expected = (_expected);					\
+	void *p = alloc;						\
+	KUNIT_EXPECT_TRUE_MSG(test, p != NULL, #alloc " failed?!\n");	\
+	KUNIT_EXPECT_BOS(test, p, expected, #alloc);			\
+	KUNIT_EXPECT_BDOS(test, p, expected, #alloc);			\
+	free;								\
+} while (0)
+
+/* If the execpted size is NOT a constant value, __bos CANNOT see it. */
+#define check_dynamic(_expected, alloc, free)		do {		\
+	size_t expected = (_expected);					\
+	void *p = alloc;						\
+	KUNIT_EXPECT_TRUE_MSG(test, p != NULL, #alloc " failed?!\n");	\
+	KUNIT_EXPECT_BOS(test, p, SIZE_MAX, #alloc);			\
+	KUNIT_EXPECT_BDOS(test, p, expected, #alloc);			\
+	free;								\
+} while (0)
+
+/* Assortment of constant-value kinda-edge cases. */
+#define CONST_TEST_BODY(TEST_alloc)	do {				\
+	/* Special-case vmalloc()-family to skip 0-sized allocs. */	\
+	if (strcmp(#TEST_alloc, "TEST_vmalloc") != 0)			\
+		TEST_alloc(check_const, 0, 0);				\
+	TEST_alloc(check_const, 1, 1);					\
+	TEST_alloc(check_const, 128, 128);				\
+	TEST_alloc(check_const, 1023, 1023);				\
+	TEST_alloc(check_const, 1025, 1025);				\
+	TEST_alloc(check_const, 4096, 4096);				\
+	TEST_alloc(check_const, 4097, 4097);				\
+} while (0)
+
+static volatile size_t zero_size;
+static volatile size_t unknown_size = 50;
+
+#if !__has_builtin(__builtin_dynamic_object_size)
+#define DYNAMIC_TEST_BODY(TEST_alloc)					\
+	kunit_skip(test, "Compiler is missing __builtin_dynamic_object_size() support\n")
+#else
+#define DYNAMIC_TEST_BODY(TEST_alloc)	do {				\
+	size_t size = unknown_size;					\
+									\
+	/*								\
+	 * Expected size is "size" in each test, before it is then	\
+	 * internally incremented in each test.	Requires we disable	\
+	 * -Wunsequenced.						\
+	 */								\
+	TEST_alloc(check_dynamic, size, size++);			\
+	/* Make sure incrementing actually happened. */			\
+	KUNIT_EXPECT_NE(test, size, unknown_size);			\
+} while (0)
+#endif
+
+#define DEFINE_ALLOC_SIZE_TEST_PAIR(allocator)				\
+static void fortify_test_alloc_size_##allocator##_const(struct kunit *test) \
+{									\
+	CONST_TEST_BODY(TEST_##allocator);				\
+}									\
+static void fortify_test_alloc_size_##allocator##_dynamic(struct kunit *test) \
+{									\
+	DYNAMIC_TEST_BODY(TEST_##allocator);				\
+}
+
+#define TEST_kmalloc(checker, expected_size, alloc_size)	do {	\
+	gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;				\
+	void *orig;							\
+	size_t len;							\
+									\
+	checker(expected_size, kmalloc(alloc_size, gfp),		\
+		kfree(p));						\
+	checker(expected_size,						\
+		kmalloc_node(alloc_size, gfp, NUMA_NO_NODE),		\
+		kfree(p));						\
+	checker(expected_size, kzalloc(alloc_size, gfp),		\
+		kfree(p));						\
+	checker(expected_size,						\
+		kzalloc_node(alloc_size, gfp, NUMA_NO_NODE),		\
+		kfree(p));						\
+	checker(expected_size, kcalloc(1, alloc_size, gfp),		\
+		kfree(p));						\
+	checker(expected_size, kcalloc(alloc_size, 1, gfp),		\
+		kfree(p));						\
+	checker(expected_size,						\
+		kcalloc_node(1, alloc_size, gfp, NUMA_NO_NODE),		\
+		kfree(p));						\
+	checker(expected_size,						\
+		kcalloc_node(alloc_size, 1, gfp, NUMA_NO_NODE),		\
+		kfree(p));						\
+	checker(expected_size, kmalloc_array(1, alloc_size, gfp),	\
+		kfree(p));						\
+	checker(expected_size, kmalloc_array(alloc_size, 1, gfp),	\
+		kfree(p));						\
+	checker(expected_size,						\
+		kmalloc_array_node(1, alloc_size, gfp, NUMA_NO_NODE),	\
+		kfree(p));						\
+	checker(expected_size,						\
+		kmalloc_array_node(alloc_size, 1, gfp, NUMA_NO_NODE),	\
+		kfree(p));						\
+									\
+	orig = kmalloc(alloc_size, gfp);				\
+	KUNIT_EXPECT_TRUE(test, orig != NULL);				\
+	checker((expected_size) * 2,					\
+		krealloc(orig, (alloc_size) * 2, gfp),			\
+		kfree(p));						\
+	orig = kmalloc(alloc_size, gfp);				\
+	KUNIT_EXPECT_TRUE(test, orig != NULL);				\
+	checker((expected_size) * 2,					\
+		krealloc_array(orig, 1, (alloc_size) * 2, gfp),		\
+		kfree(p));						\
+	orig = kmalloc(alloc_size, gfp);				\
+	KUNIT_EXPECT_TRUE(test, orig != NULL);				\
+	checker((expected_size) * 2,					\
+		krealloc_array(orig, (alloc_size) * 2, 1, gfp),		\
+		kfree(p));						\
+									\
+	len = 11;							\
+	/* Using memdup() with fixed size, so force unknown length. */	\
+	if (!__builtin_constant_p(expected_size))			\
+		len += zero_size;					\
+	checker(len, kmemdup("hello there", len, gfp), kfree(p));	\
+} while (0)
+DEFINE_ALLOC_SIZE_TEST_PAIR(kmalloc)
+
+/* Sizes are in pages, not bytes. */
+#define TEST_vmalloc(checker, expected_pages, alloc_pages)	do {	\
+	gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;				\
+	checker((expected_pages) * PAGE_SIZE,				\
+		vmalloc((alloc_pages) * PAGE_SIZE),	   vfree(p));	\
+	checker((expected_pages) * PAGE_SIZE,				\
+		vzalloc((alloc_pages) * PAGE_SIZE),	   vfree(p));	\
+	checker((expected_pages) * PAGE_SIZE,				\
+		__vmalloc((alloc_pages) * PAGE_SIZE, gfp), vfree(p));	\
+} while (0)
+DEFINE_ALLOC_SIZE_TEST_PAIR(vmalloc)
+
+/* Sizes are in pages (and open-coded for side-effects), not bytes. */
+#define TEST_kvmalloc(checker, expected_pages, alloc_pages)	do {	\
+	gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;				\
+	size_t prev_size;						\
+	void *orig;							\
+									\
+	checker((expected_pages) * PAGE_SIZE,				\
+		kvmalloc((alloc_pages) * PAGE_SIZE, gfp),		\
+		kvfree(p));						\
+	checker((expected_pages) * PAGE_SIZE,				\
+		kvmalloc_node((alloc_pages) * PAGE_SIZE, gfp, NUMA_NO_NODE), \
+		kvfree(p));						\
+	checker((expected_pages) * PAGE_SIZE,				\
+		kvzalloc((alloc_pages) * PAGE_SIZE, gfp),		\
+		kvfree(p));						\
+	checker((expected_pages) * PAGE_SIZE,				\
+		kvzalloc_node((alloc_pages) * PAGE_SIZE, gfp, NUMA_NO_NODE), \
+		kvfree(p));						\
+	checker((expected_pages) * PAGE_SIZE,				\
+		kvcalloc(1, (alloc_pages) * PAGE_SIZE, gfp),		\
+		kvfree(p));						\
+	checker((expected_pages) * PAGE_SIZE,				\
+		kvcalloc((alloc_pages) * PAGE_SIZE, 1, gfp),		\
+		kvfree(p));						\
+	checker((expected_pages) * PAGE_SIZE,				\
+		kvmalloc_array(1, (alloc_pages) * PAGE_SIZE, gfp),	\
+		kvfree(p));						\
+	checker((expected_pages) * PAGE_SIZE,				\
+		kvmalloc_array((alloc_pages) * PAGE_SIZE, 1, gfp),	\
+		kvfree(p));						\
+									\
+	prev_size = (expected_pages) * PAGE_SIZE;			\
+	orig = kvmalloc(prev_size, gfp);				\
+	KUNIT_EXPECT_TRUE(test, orig != NULL);				\
+	checker(((expected_pages) * PAGE_SIZE) * 2,			\
+		kvrealloc(orig, ((alloc_pages) * PAGE_SIZE) * 2, gfp),	\
+		kvfree(p));						\
+} while (0)
+DEFINE_ALLOC_SIZE_TEST_PAIR(kvmalloc)
+
+#define TEST_devm_kmalloc(checker, expected_size, alloc_size)	do {	\
+	gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;				\
+	const char dev_name[] = "fortify-test";				\
+	struct device *dev;						\
+	void *orig;							\
+	size_t len;							\
+									\
+	/* Create dummy device for devm_kmalloc()-family tests. */	\
+	dev = kunit_device_register(test, dev_name);			\
+	KUNIT_ASSERT_FALSE_MSG(test, IS_ERR(dev),			\
+			       "Cannot register test device\n");	\
+									\
+	checker(expected_size, devm_kmalloc(dev, alloc_size, gfp),	\
+		devm_kfree(dev, p));					\
+	checker(expected_size, devm_kzalloc(dev, alloc_size, gfp),	\
+		devm_kfree(dev, p));					\
+	checker(expected_size,						\
+		devm_kmalloc_array(dev, 1, alloc_size, gfp),		\
+		devm_kfree(dev, p));					\
+	checker(expected_size,						\
+		devm_kmalloc_array(dev, alloc_size, 1, gfp),		\
+		devm_kfree(dev, p));					\
+	checker(expected_size,						\
+		devm_kcalloc(dev, 1, alloc_size, gfp),			\
+		devm_kfree(dev, p));					\
+	checker(expected_size,						\
+		devm_kcalloc(dev, alloc_size, 1, gfp),			\
+		devm_kfree(dev, p));					\
+									\
+	orig = devm_kmalloc(dev, alloc_size, gfp);			\
+	KUNIT_EXPECT_TRUE(test, orig != NULL);				\
+	checker((expected_size) * 2,					\
+		devm_krealloc(dev, orig, (alloc_size) * 2, gfp),	\
+		devm_kfree(dev, p));					\
+									\
+	len = 4;							\
+	/* Using memdup() with fixed size, so force unknown length. */	\
+	if (!__builtin_constant_p(expected_size))			\
+		len += zero_size;					\
+	checker(len, devm_kmemdup(dev, "Ohai", len, gfp),		\
+		devm_kfree(dev, p));					\
+									\
+	kunit_device_unregister(test, dev);				\
+} while (0)
+DEFINE_ALLOC_SIZE_TEST_PAIR(devm_kmalloc)
+
+static const char * const test_strs[] = {
+	"",
+	"Hello there",
+	"A longer string, just for variety",
+};
+
+#define TEST_realloc(checker)	do {					\
+	gfp_t gfp = GFP_KERNEL;						\
+	size_t len;							\
+	int i;								\
+									\
+	for (i = 0; i < ARRAY_SIZE(test_strs); i++) {			\
+		len = strlen(test_strs[i]);				\
+		KUNIT_EXPECT_EQ(test, __builtin_constant_p(len), 0);	\
+		checker(len, kmemdup_array(test_strs[i], 1, len, gfp),	\
+			kfree(p));					\
+		checker(len, kmemdup(test_strs[i], len, gfp),		\
+			kfree(p));					\
+	}								\
+} while (0)
+static void fortify_test_realloc_size(struct kunit *test)
+{
+	TEST_realloc(check_dynamic);
+}
+
+/*
+ * We can't have an array at the end of a structure or else
+ * builds without -fstrict-flex-arrays=3 will report them as
+ * being an unknown length. Additionally, add bytes before
+ * and after the string to catch over/underflows if tests
+ * fail.
+ */
+struct fortify_padding {
+	unsigned long bytes_before;
+	char buf[32];
+	unsigned long bytes_after;
+};
+/* Force compiler into not being able to resolve size at compile-time. */
+static volatile int unconst;
+
+static void fortify_test_strlen(struct kunit *test)
+{
+	struct fortify_padding pad = { };
+	int i, end = sizeof(pad.buf) - 1;
+
+	/* Fill 31 bytes with valid characters. */
+	for (i = 0; i < sizeof(pad.buf) - 1; i++)
+		pad.buf[i] = i + '0';
+	/* Trailing bytes are still %NUL. */
+	KUNIT_EXPECT_EQ(test, pad.buf[end], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* String is terminated, so strlen() is valid. */
+	KUNIT_EXPECT_EQ(test, strlen(pad.buf), end);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+
+	/* Make string unterminated, and recount. */
+	pad.buf[end] = 'A';
+	end = sizeof(pad.buf);
+	KUNIT_EXPECT_EQ(test, strlen(pad.buf), end);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
+}
+
+static void fortify_test_strnlen(struct kunit *test)
+{
+	struct fortify_padding pad = { };
+	int i, end = sizeof(pad.buf) - 1;
+
+	/* Fill 31 bytes with valid characters. */
+	for (i = 0; i < sizeof(pad.buf) - 1; i++)
+		pad.buf[i] = i + '0';
+	/* Trailing bytes are still %NUL. */
+	KUNIT_EXPECT_EQ(test, pad.buf[end], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* String is terminated, so strnlen() is valid. */
+	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, sizeof(pad.buf)), end);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	/* A truncated strnlen() will be safe, too. */
+	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, sizeof(pad.buf) / 2),
+					sizeof(pad.buf) / 2);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+
+	/* Make string unterminated, and recount. */
+	pad.buf[end] = 'A';
+	end = sizeof(pad.buf);
+	/* Reading beyond with strncpy() will fail. */
+	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end + 1), end);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
+	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end + 2), end);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
+
+	/* Early-truncated is safe still, though. */
+	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end), end);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
+
+	end = sizeof(pad.buf) / 2;
+	KUNIT_EXPECT_EQ(test, strnlen(pad.buf, end), end);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
+}
+
+static void fortify_test_strcpy(struct kunit *test)
+{
+	struct fortify_padding pad = { };
+	char src[sizeof(pad.buf) + 1] = { };
+	int i;
+
+	/* Fill 31 bytes with valid characters. */
+	for (i = 0; i < sizeof(src) - 2; i++)
+		src[i] = i + '0';
+
+	/* Destination is %NUL-filled to start with. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* Legitimate strcpy() 1 less than of max size. */
+	KUNIT_ASSERT_TRUE(test, strcpy(pad.buf, src)
+				== pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Only last byte should be %NUL */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+
+	src[sizeof(src) - 2] = 'A';
+	/* But now we trip the overflow checking. */
+	KUNIT_ASSERT_TRUE(test, strcpy(pad.buf, src)
+				== pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
+	/* Trailing %NUL -- thanks to FORTIFY. */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	/* And we will not have gone beyond. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	src[sizeof(src) - 1] = 'A';
+	/* And for sure now, two bytes past. */
+	KUNIT_ASSERT_TRUE(test, strcpy(pad.buf, src)
+				== pad.buf);
+	/*
+	 * Which trips both the strlen() on the unterminated src,
+	 * and the resulting copy attempt.
+	 */
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
+	/* Trailing %NUL -- thanks to FORTIFY. */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	/* And we will not have gone beyond. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+}
+
+static void fortify_test_strncpy(struct kunit *test)
+{
+	struct fortify_padding pad = { };
+	char src[] = "Copy me fully into a small buffer and I will overflow!";
+
+	/* Destination is %NUL-filled to start with. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* Legitimate strncpy() 1 less than of max size. */
+	KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src,
+					sizeof(pad.buf) + unconst - 1)
+				== pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Only last byte should be %NUL */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+
+	/* Legitimate (though unterminated) max-size strncpy. */
+	KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src,
+					sizeof(pad.buf) + unconst)
+				== pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* No trailing %NUL -- thanks strncpy API. */
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	/* But we will not have gone beyond. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* Now verify that FORTIFY is working... */
+	KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src,
+					sizeof(pad.buf) + unconst + 1)
+				== pad.buf);
+	/* Should catch the overflow. */
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	/* And we will not have gone beyond. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* And further... */
+	KUNIT_ASSERT_TRUE(test, strncpy(pad.buf, src,
+					sizeof(pad.buf) + unconst + 2)
+				== pad.buf);
+	/* Should catch the overflow. */
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	/* And we will not have gone beyond. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+}
+
+static void fortify_test_strscpy(struct kunit *test)
+{
+	struct fortify_padding pad = { };
+	char src[] = "Copy me fully into a small buffer and I will overflow!";
+
+	/* Destination is %NUL-filled to start with. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* Legitimate strscpy() 1 less than of max size. */
+	KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src,
+				      sizeof(pad.buf) + unconst - 1),
+			-E2BIG);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Keeping space for %NUL, last two bytes should be %NUL */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+
+	/* Legitimate max-size strscpy. */
+	KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src,
+				      sizeof(pad.buf) + unconst),
+			-E2BIG);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* A trailing %NUL will exist. */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+
+	/* Now verify that FORTIFY is working... */
+	KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src,
+				      sizeof(pad.buf) + unconst + 1),
+			-E2BIG);
+	/* Should catch the overflow. */
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	/* And we will not have gone beyond. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* And much further... */
+	KUNIT_ASSERT_EQ(test, strscpy(pad.buf, src,
+				      sizeof(src) * 2 + unconst),
+			-E2BIG);
+	/* Should catch the overflow. */
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	/* And we will not have gone beyond. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+}
+
+static void fortify_test_strcat(struct kunit *test)
+{
+	struct fortify_padding pad = { };
+	char src[sizeof(pad.buf) / 2] = { };
+	char one[] = "A";
+	char two[] = "BC";
+	int i;
+
+	/* Fill 15 bytes with valid characters. */
+	for (i = 0; i < sizeof(src) - 1; i++)
+		src[i] = i + 'A';
+
+	/* Destination is %NUL-filled to start with. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* Legitimate strcat() using less than half max size. */
+	KUNIT_ASSERT_TRUE(test, strcat(pad.buf, src) == pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Legitimate strcat() now 2 bytes shy of end. */
+	KUNIT_ASSERT_TRUE(test, strcat(pad.buf, src) == pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Last two bytes should be %NUL */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+
+	/* Add one more character to the end. */
+	KUNIT_ASSERT_TRUE(test, strcat(pad.buf, one) == pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Last byte should be %NUL */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+
+	/* And this one char will overflow. */
+	KUNIT_ASSERT_TRUE(test, strcat(pad.buf, one) == pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
+	/* Last byte should be %NUL thanks to FORTIFY. */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* And adding two will overflow more. */
+	KUNIT_ASSERT_TRUE(test, strcat(pad.buf, two) == pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
+	/* Last byte should be %NUL thanks to FORTIFY. */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+}
+
+static void fortify_test_strncat(struct kunit *test)
+{
+	struct fortify_padding pad = { };
+	char src[sizeof(pad.buf)] = { };
+	int i, partial;
+
+	/* Fill 31 bytes with valid characters. */
+	partial = sizeof(src) / 2 - 1;
+	for (i = 0; i < partial; i++)
+		src[i] = i + 'A';
+
+	/* Destination is %NUL-filled to start with. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* Legitimate strncat() using less than half max size. */
+	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, partial) == pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Legitimate strncat() now 2 bytes shy of end. */
+	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, partial) == pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Last two bytes should be %NUL */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+
+	/* Add one more character to the end. */
+	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 1) == pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Last byte should be %NUL */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+
+	/* And this one char will overflow. */
+	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 1) == pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
+	/* Last byte should be %NUL thanks to FORTIFY. */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* And adding two will overflow more. */
+	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 2) == pad.buf);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
+	/* Last byte should be %NUL thanks to FORTIFY. */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* Force an unterminated destination, and overflow. */
+	pad.buf[sizeof(pad.buf) - 1] = 'A';
+	KUNIT_ASSERT_TRUE(test, strncat(pad.buf, src, 1) == pad.buf);
+	/* This will have tripped both strlen() and strcat(). */
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 3);
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	/* But we should not go beyond the end. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+}
+
+static void fortify_test_strlcat(struct kunit *test)
+{
+	struct fortify_padding pad = { };
+	char src[sizeof(pad.buf)] = { };
+	int i, partial;
+	int len = sizeof(pad.buf) + unconst;
+
+	/* Fill 15 bytes with valid characters. */
+	partial = sizeof(src) / 2 - 1;
+	for (i = 0; i < partial; i++)
+		src[i] = i + 'A';
+
+	/* Destination is %NUL-filled to start with. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_before, 0);
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* Legitimate strlcat() using less than half max size. */
+	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, src, len), partial);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Legitimate strlcat() now 2 bytes shy of end. */
+	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, src, len), partial * 2);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Last two bytes should be %NUL */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+
+	/* Add one more character to the end. */
+	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "Q", len), partial * 2 + 1);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);
+	/* Last byte should be %NUL */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+
+	/* And this one char will overflow. */
+	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "V", len * 2), len);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);
+	/* Last byte should be %NUL thanks to FORTIFY. */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* And adding two will overflow more. */
+	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "QQ", len * 2), len + 1);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
+	/* Last byte should be %NUL thanks to FORTIFY. */
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* Force an unterminated destination, and overflow. */
+	pad.buf[sizeof(pad.buf) - 1] = 'A';
+	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, "TT", len * 2), len + 2);
+	/* This will have tripped both strlen() and strlcat(). */
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 2], '\0');
+	KUNIT_EXPECT_NE(test, pad.buf[sizeof(pad.buf) - 3], '\0');
+	/* But we should not go beyond the end. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+
+	/* Force an unterminated source, and overflow. */
+	memset(src, 'B', sizeof(src));
+	pad.buf[sizeof(pad.buf) - 1] = '\0';
+	KUNIT_ASSERT_EQ(test, strlcat(pad.buf, src, len * 3), len - 1 + sizeof(src));
+	/* This will have tripped both strlen() and strlcat(). */
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 3);
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 3);
+	KUNIT_EXPECT_EQ(test, pad.buf[sizeof(pad.buf) - 1], '\0');
+	/* But we should not go beyond the end. */
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);
+}
+
+/* Check for 0-sized arrays... */
+struct fortify_zero_sized {
+	unsigned long bytes_before;
+	char buf[0];
+	unsigned long bytes_after;
+};
+
+#define __fortify_test(memfunc)					\
+static void fortify_test_##memfunc(struct kunit *test)		\
+{								\
+	struct fortify_zero_sized zero = { };			\
+	struct fortify_padding pad = { };			\
+	char srcA[sizeof(pad.buf) + 2];				\
+	char srcB[sizeof(pad.buf) + 2];				\
+	size_t len = sizeof(pad.buf) + unconst;			\
+								\
+	memset(srcA, 'A', sizeof(srcA));			\
+	KUNIT_ASSERT_EQ(test, srcA[0], 'A');			\
+	memset(srcB, 'B', sizeof(srcB));			\
+	KUNIT_ASSERT_EQ(test, srcB[0], 'B');			\
+								\
+	memfunc(pad.buf, srcA, 0 + unconst);			\
+	KUNIT_EXPECT_EQ(test, pad.buf[0], '\0');		\
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
+	memfunc(pad.buf + 1, srcB, 1 + unconst);		\
+	KUNIT_EXPECT_EQ(test, pad.buf[0], '\0');		\
+	KUNIT_EXPECT_EQ(test, pad.buf[1], 'B');			\
+	KUNIT_EXPECT_EQ(test, pad.buf[2], '\0');		\
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
+	memfunc(pad.buf, srcA, 1 + unconst);			\
+	KUNIT_EXPECT_EQ(test, pad.buf[0], 'A');			\
+	KUNIT_EXPECT_EQ(test, pad.buf[1], 'B');			\
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
+	memfunc(pad.buf, srcA, len - 1);			\
+	KUNIT_EXPECT_EQ(test, pad.buf[1], 'A');			\
+	KUNIT_EXPECT_EQ(test, pad.buf[len - 1], '\0');		\
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
+	memfunc(pad.buf, srcA, len);				\
+	KUNIT_EXPECT_EQ(test, pad.buf[1], 'A');			\
+	KUNIT_EXPECT_EQ(test, pad.buf[len - 1], 'A');		\
+	KUNIT_EXPECT_EQ(test, pad.bytes_after, 0);		\
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
+	memfunc(pad.buf, srcA, len + 1);			\
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);	\
+	memfunc(pad.buf + 1, srcB, len);			\
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2);	\
+								\
+	/* Reset error counter. */				\
+	fortify_write_overflows = 0;				\
+	/* Copy nothing into nothing: no errors. */		\
+	memfunc(zero.buf, srcB, 0 + unconst);			\
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0);	\
+	memfunc(zero.buf, srcB, 1 + unconst);			\
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);	\
+	KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1);	\
+}
+__fortify_test(memcpy)
+__fortify_test(memmove)
+
+static void fortify_test_memscan(struct kunit *test)
+{
+	char haystack[] = "Where oh where is my memory range?";
+	char *mem = haystack + strlen("Where oh where is ");
+	char needle = 'm';
+	size_t len = sizeof(haystack) + unconst;
+
+	KUNIT_ASSERT_PTR_EQ(test, memscan(haystack, needle, len),
+				  mem);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	/* Catch too-large range. */
+	KUNIT_ASSERT_PTR_EQ(test, memscan(haystack, needle, len + 1),
+				  NULL);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
+	KUNIT_ASSERT_PTR_EQ(test, memscan(haystack, needle, len * 2),
+				  NULL);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
+}
+
+static void fortify_test_memchr(struct kunit *test)
+{
+	char haystack[] = "Where oh where is my memory range?";
+	char *mem = haystack + strlen("Where oh where is ");
+	char needle = 'm';
+	size_t len = sizeof(haystack) + unconst;
+
+	KUNIT_ASSERT_PTR_EQ(test, memchr(haystack, needle, len),
+				  mem);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	/* Catch too-large range. */
+	KUNIT_ASSERT_PTR_EQ(test, memchr(haystack, needle, len + 1),
+				  NULL);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
+	KUNIT_ASSERT_PTR_EQ(test, memchr(haystack, needle, len * 2),
+				  NULL);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
+}
+
+static void fortify_test_memchr_inv(struct kunit *test)
+{
+	char haystack[] = "Where oh where is my memory range?";
+	char *mem = haystack + 1;
+	char needle = 'W';
+	size_t len = sizeof(haystack) + unconst;
+
+	/* Normal search is okay. */
+	KUNIT_ASSERT_PTR_EQ(test, memchr_inv(haystack, needle, len),
+				  mem);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	/* Catch too-large range. */
+	KUNIT_ASSERT_PTR_EQ(test, memchr_inv(haystack, needle, len + 1),
+				  NULL);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
+	KUNIT_ASSERT_PTR_EQ(test, memchr_inv(haystack, needle, len * 2),
+				  NULL);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
+}
+
+static void fortify_test_memcmp(struct kunit *test)
+{
+	char one[] = "My mind is going ...";
+	char two[] = "My mind is going ... I can feel it.";
+	size_t one_len = sizeof(one) + unconst - 1;
+	size_t two_len = sizeof(two) + unconst - 1;
+
+	/* We match the first string (ignoring the %NUL). */
+	KUNIT_ASSERT_EQ(test, memcmp(one, two, one_len), 0);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	/* Still in bounds, but no longer matching. */
+	KUNIT_ASSERT_LT(test, memcmp(one, two, one_len + 1), 0);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+
+	/* Catch too-large ranges. */
+	KUNIT_ASSERT_EQ(test, memcmp(one, two, one_len + 2), INT_MIN);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
+
+	KUNIT_ASSERT_EQ(test, memcmp(two, one, two_len + 2), INT_MIN);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
+}
+
+static void fortify_test_kmemdup(struct kunit *test)
+{
+	char src[] = "I got Doom running on it!";
+	char *copy;
+	size_t len = sizeof(src) + unconst;
+
+	/* Copy is within bounds. */
+	copy = kmemdup(src, len, GFP_KERNEL);
+	KUNIT_EXPECT_NOT_NULL(test, copy);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	kfree(copy);
+
+	/* Without %NUL. */
+	copy = kmemdup(src, len - 1, GFP_KERNEL);
+	KUNIT_EXPECT_NOT_NULL(test, copy);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	kfree(copy);
+
+	/* Tiny bounds. */
+	copy = kmemdup(src, 1, GFP_KERNEL);
+	KUNIT_EXPECT_NOT_NULL(test, copy);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0);
+	kfree(copy);
+
+	/* Out of bounds by 1 byte. */
+	copy = kmemdup(src, len + 1, GFP_KERNEL);
+	KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1);
+	kfree(copy);
+
+	/* Way out of bounds. */
+	copy = kmemdup(src, len * 2, GFP_KERNEL);
+	KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2);
+	kfree(copy);
+
+	/* Starting offset causing out of bounds. */
+	copy = kmemdup(src + 1, len, GFP_KERNEL);
+	KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR);
+	KUNIT_EXPECT_EQ(test, fortify_read_overflows, 3);
+	kfree(copy);
+}
+
+static int fortify_test_init(struct kunit *test)
+{
+	if (!IS_ENABLED(CONFIG_FORTIFY_SOURCE))
+		kunit_skip(test, "Not built with CONFIG_FORTIFY_SOURCE=y");
+
+	fortify_read_overflows = 0;
+	kunit_add_named_resource(test, NULL, NULL, &read_resource,
+				 "fortify_read_overflows",
+				 &fortify_read_overflows);
+	fortify_write_overflows = 0;
+	kunit_add_named_resource(test, NULL, NULL, &write_resource,
+				 "fortify_write_overflows",
+				 &fortify_write_overflows);
+	return 0;
+}
+
+static struct kunit_case fortify_test_cases[] = {
+	KUNIT_CASE(fortify_test_known_sizes),
+	KUNIT_CASE(fortify_test_control_flow_split),
+	KUNIT_CASE(fortify_test_alloc_size_kmalloc_const),
+	KUNIT_CASE(fortify_test_alloc_size_kmalloc_dynamic),
+	KUNIT_CASE(fortify_test_alloc_size_vmalloc_const),
+	KUNIT_CASE(fortify_test_alloc_size_vmalloc_dynamic),
+	KUNIT_CASE(fortify_test_alloc_size_kvmalloc_const),
+	KUNIT_CASE(fortify_test_alloc_size_kvmalloc_dynamic),
+	KUNIT_CASE(fortify_test_alloc_size_devm_kmalloc_const),
+	KUNIT_CASE(fortify_test_alloc_size_devm_kmalloc_dynamic),
+	KUNIT_CASE(fortify_test_realloc_size),
+	KUNIT_CASE(fortify_test_strlen),
+	KUNIT_CASE(fortify_test_strnlen),
+	KUNIT_CASE(fortify_test_strcpy),
+	KUNIT_CASE(fortify_test_strncpy),
+	KUNIT_CASE(fortify_test_strscpy),
+	KUNIT_CASE(fortify_test_strcat),
+	KUNIT_CASE(fortify_test_strncat),
+	KUNIT_CASE(fortify_test_strlcat),
+	/* skip memset: performs bounds checking on whole structs */
+	KUNIT_CASE(fortify_test_memcpy),
+	KUNIT_CASE(fortify_test_memmove),
+	KUNIT_CASE(fortify_test_memscan),
+	KUNIT_CASE(fortify_test_memchr),
+	KUNIT_CASE(fortify_test_memchr_inv),
+	KUNIT_CASE(fortify_test_memcmp),
+	KUNIT_CASE(fortify_test_kmemdup),
+	{}
+};
+
+static struct kunit_suite fortify_test_suite = {
+	.name = "fortify",
+	.init = fortify_test_init,
+	.test_cases = fortify_test_cases,
+};
+
+kunit_test_suite(fortify_test_suite);
+
+MODULE_DESCRIPTION("Runtime test cases for CONFIG_FORTIFY_SOURCE");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/hashtable_test.c a/lib/tests/hashtable_test.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/hashtable_test.c
@@ -0,0 +1,318 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit test for the Kernel Hashtable structures.
+ *
+ * Copyright (C) 2022, Google LLC.
+ * Author: Rae Moar <rmoar@xxxxxxxxxx>
+ */
+#include <kunit/test.h>
+
+#include <linux/hashtable.h>
+
+struct hashtable_test_entry {
+	int key;
+	int data;
+	struct hlist_node node;
+	int visited;
+};
+
+static void hashtable_test_hash_init(struct kunit *test)
+{
+	/* Test the different ways of initialising a hashtable. */
+	DEFINE_HASHTABLE(hash1, 2);
+	DECLARE_HASHTABLE(hash2, 3);
+
+	/* When using DECLARE_HASHTABLE, must use hash_init to
+	 * initialize the hashtable.
+	 */
+	hash_init(hash2);
+
+	KUNIT_EXPECT_TRUE(test, hash_empty(hash1));
+	KUNIT_EXPECT_TRUE(test, hash_empty(hash2));
+}
+
+static void hashtable_test_hash_empty(struct kunit *test)
+{
+	struct hashtable_test_entry a;
+	DEFINE_HASHTABLE(hash, 1);
+
+	KUNIT_EXPECT_TRUE(test, hash_empty(hash));
+
+	a.key = 1;
+	a.data = 13;
+	hash_add(hash, &a.node, a.key);
+
+	/* Hashtable should no longer be empty. */
+	KUNIT_EXPECT_FALSE(test, hash_empty(hash));
+}
+
+static void hashtable_test_hash_hashed(struct kunit *test)
+{
+	struct hashtable_test_entry a, b;
+	DEFINE_HASHTABLE(hash, 4);
+
+	a.key = 1;
+	a.data = 13;
+	hash_add(hash, &a.node, a.key);
+	b.key = 1;
+	b.data = 2;
+	hash_add(hash, &b.node, b.key);
+
+	KUNIT_EXPECT_TRUE(test, hash_hashed(&a.node));
+	KUNIT_EXPECT_TRUE(test, hash_hashed(&b.node));
+}
+
+static void hashtable_test_hash_add(struct kunit *test)
+{
+	struct hashtable_test_entry a, b, *x;
+	int bkt;
+	DEFINE_HASHTABLE(hash, 3);
+
+	a.key = 1;
+	a.data = 13;
+	a.visited = 0;
+	hash_add(hash, &a.node, a.key);
+	b.key = 2;
+	b.data = 10;
+	b.visited = 0;
+	hash_add(hash, &b.node, b.key);
+
+	hash_for_each(hash, bkt, x, node) {
+		x->visited++;
+		if (x->key == a.key)
+			KUNIT_EXPECT_EQ(test, x->data, 13);
+		else if (x->key == b.key)
+			KUNIT_EXPECT_EQ(test, x->data, 10);
+		else
+			KUNIT_FAIL(test, "Unexpected key in hashtable.");
+	}
+
+	/* Both entries should have been visited exactly once. */
+	KUNIT_EXPECT_EQ(test, a.visited, 1);
+	KUNIT_EXPECT_EQ(test, b.visited, 1);
+}
+
+static void hashtable_test_hash_del(struct kunit *test)
+{
+	struct hashtable_test_entry a, b, *x;
+	DEFINE_HASHTABLE(hash, 6);
+
+	a.key = 1;
+	a.data = 13;
+	hash_add(hash, &a.node, a.key);
+	b.key = 2;
+	b.data = 10;
+	b.visited = 0;
+	hash_add(hash, &b.node, b.key);
+
+	hash_del(&b.node);
+	hash_for_each_possible(hash, x, node, b.key) {
+		x->visited++;
+		KUNIT_EXPECT_NE(test, x->key, b.key);
+	}
+
+	/* The deleted entry should not have been visited. */
+	KUNIT_EXPECT_EQ(test, b.visited, 0);
+
+	hash_del(&a.node);
+
+	/* The hashtable should be empty. */
+	KUNIT_EXPECT_TRUE(test, hash_empty(hash));
+}
+
+static void hashtable_test_hash_for_each(struct kunit *test)
+{
+	struct hashtable_test_entry entries[3];
+	struct hashtable_test_entry *x;
+	int bkt, i, j, count;
+	DEFINE_HASHTABLE(hash, 3);
+
+	/* Add three entries to the hashtable. */
+	for (i = 0; i < 3; i++) {
+		entries[i].key = i;
+		entries[i].data = i + 10;
+		entries[i].visited = 0;
+		hash_add(hash, &entries[i].node, entries[i].key);
+	}
+
+	count = 0;
+	hash_for_each(hash, bkt, x, node) {
+		x->visited += 1;
+		KUNIT_ASSERT_GE_MSG(test, x->key, 0, "Unexpected key in hashtable.");
+		KUNIT_ASSERT_LT_MSG(test, x->key, 3, "Unexpected key in hashtable.");
+		count++;
+	}
+
+	/* Should have visited each entry exactly once. */
+	KUNIT_EXPECT_EQ(test, count, 3);
+	for (j = 0; j < 3; j++)
+		KUNIT_EXPECT_EQ(test, entries[j].visited, 1);
+}
+
+static void hashtable_test_hash_for_each_safe(struct kunit *test)
+{
+	struct hashtable_test_entry entries[3];
+	struct hashtable_test_entry *x;
+	struct hlist_node *tmp;
+	int bkt, i, j, count;
+	DEFINE_HASHTABLE(hash, 3);
+
+	/* Add three entries to the hashtable. */
+	for (i = 0; i < 3; i++) {
+		entries[i].key = i;
+		entries[i].data = i + 10;
+		entries[i].visited = 0;
+		hash_add(hash, &entries[i].node, entries[i].key);
+	}
+
+	count = 0;
+	hash_for_each_safe(hash, bkt, tmp, x, node) {
+		x->visited += 1;
+		KUNIT_ASSERT_GE_MSG(test, x->key, 0, "Unexpected key in hashtable.");
+		KUNIT_ASSERT_LT_MSG(test, x->key, 3, "Unexpected key in hashtable.");
+		count++;
+
+		/* Delete entry during loop. */
+		hash_del(&x->node);
+	}
+
+	/* Should have visited each entry exactly once. */
+	KUNIT_EXPECT_EQ(test, count, 3);
+	for (j = 0; j < 3; j++)
+		KUNIT_EXPECT_EQ(test, entries[j].visited, 1);
+}
+
+static void hashtable_test_hash_for_each_possible(struct kunit *test)
+{
+	struct hashtable_test_entry entries[4];
+	struct hashtable_test_entry *x, *y;
+	int buckets[2];
+	int bkt, i, j, count;
+	DEFINE_HASHTABLE(hash, 5);
+
+	/* Add three entries with key = 0 to the hashtable. */
+	for (i = 0; i < 3; i++) {
+		entries[i].key = 0;
+		entries[i].data = i;
+		entries[i].visited = 0;
+		hash_add(hash, &entries[i].node, entries[i].key);
+	}
+
+	/* Add an entry with key = 1. */
+	entries[3].key = 1;
+	entries[3].data = 3;
+	entries[3].visited = 0;
+	hash_add(hash, &entries[3].node, entries[3].key);
+
+	count = 0;
+	hash_for_each_possible(hash, x, node, 0) {
+		x->visited += 1;
+		KUNIT_ASSERT_GE_MSG(test, x->data, 0, "Unexpected data in hashtable.");
+		KUNIT_ASSERT_LT_MSG(test, x->data, 4, "Unexpected data in hashtable.");
+		count++;
+	}
+
+	/* Should have visited each entry with key = 0 exactly once. */
+	for (j = 0; j < 3; j++)
+		KUNIT_EXPECT_EQ(test, entries[j].visited, 1);
+
+	/* Save the buckets for the different keys. */
+	hash_for_each(hash, bkt, y, node) {
+		KUNIT_ASSERT_GE_MSG(test, y->key, 0, "Unexpected key in hashtable.");
+		KUNIT_ASSERT_LE_MSG(test, y->key, 1, "Unexpected key in hashtable.");
+		buckets[y->key] = bkt;
+	}
+
+	/* If entry with key = 1 is in the same bucket as the entries with
+	 * key = 0, check it was visited. Otherwise ensure that only three
+	 * entries were visited.
+	 */
+	if (buckets[0] == buckets[1]) {
+		KUNIT_EXPECT_EQ(test, count, 4);
+		KUNIT_EXPECT_EQ(test, entries[3].visited, 1);
+	} else {
+		KUNIT_EXPECT_EQ(test, count, 3);
+		KUNIT_EXPECT_EQ(test, entries[3].visited, 0);
+	}
+}
+
+static void hashtable_test_hash_for_each_possible_safe(struct kunit *test)
+{
+	struct hashtable_test_entry entries[4];
+	struct hashtable_test_entry *x, *y;
+	struct hlist_node *tmp;
+	int buckets[2];
+	int bkt, i, j, count;
+	DEFINE_HASHTABLE(hash, 5);
+
+	/* Add three entries with key = 0 to the hashtable. */
+	for (i = 0; i < 3; i++) {
+		entries[i].key = 0;
+		entries[i].data = i;
+		entries[i].visited = 0;
+		hash_add(hash, &entries[i].node, entries[i].key);
+	}
+
+	/* Add an entry with key = 1. */
+	entries[3].key = 1;
+	entries[3].data = 3;
+	entries[3].visited = 0;
+	hash_add(hash, &entries[3].node, entries[3].key);
+
+	count = 0;
+	hash_for_each_possible_safe(hash, x, tmp, node, 0) {
+		x->visited += 1;
+		KUNIT_ASSERT_GE_MSG(test, x->data, 0, "Unexpected data in hashtable.");
+		KUNIT_ASSERT_LT_MSG(test, x->data, 4, "Unexpected data in hashtable.");
+		count++;
+
+		/* Delete entry during loop. */
+		hash_del(&x->node);
+	}
+
+	/* Should have visited each entry with key = 0 exactly once. */
+	for (j = 0; j < 3; j++)
+		KUNIT_EXPECT_EQ(test, entries[j].visited, 1);
+
+	/* Save the buckets for the different keys. */
+	hash_for_each(hash, bkt, y, node) {
+		KUNIT_ASSERT_GE_MSG(test, y->key, 0, "Unexpected key in hashtable.");
+		KUNIT_ASSERT_LE_MSG(test, y->key, 1, "Unexpected key in hashtable.");
+		buckets[y->key] = bkt;
+	}
+
+	/* If entry with key = 1 is in the same bucket as the entries with
+	 * key = 0, check it was visited. Otherwise ensure that only three
+	 * entries were visited.
+	 */
+	if (buckets[0] == buckets[1]) {
+		KUNIT_EXPECT_EQ(test, count, 4);
+		KUNIT_EXPECT_EQ(test, entries[3].visited, 1);
+	} else {
+		KUNIT_EXPECT_EQ(test, count, 3);
+		KUNIT_EXPECT_EQ(test, entries[3].visited, 0);
+	}
+}
+
+static struct kunit_case hashtable_test_cases[] = {
+	KUNIT_CASE(hashtable_test_hash_init),
+	KUNIT_CASE(hashtable_test_hash_empty),
+	KUNIT_CASE(hashtable_test_hash_hashed),
+	KUNIT_CASE(hashtable_test_hash_add),
+	KUNIT_CASE(hashtable_test_hash_del),
+	KUNIT_CASE(hashtable_test_hash_for_each),
+	KUNIT_CASE(hashtable_test_hash_for_each_safe),
+	KUNIT_CASE(hashtable_test_hash_for_each_possible),
+	KUNIT_CASE(hashtable_test_hash_for_each_possible_safe),
+	{},
+};
+
+static struct kunit_suite hashtable_test_module = {
+	.name = "hashtable",
+	.test_cases = hashtable_test_cases,
+};
+
+kunit_test_suites(&hashtable_test_module);
+
+MODULE_DESCRIPTION("KUnit test for the Kernel Hashtable structures");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/is_signed_type_kunit.c a/lib/tests/is_signed_type_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/is_signed_type_kunit.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ *	./tools/testing/kunit/kunit.py run is_signed_type [--raw_output]
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <kunit/test.h>
+#include <linux/compiler.h>
+
+enum unsigned_enum {
+	constant_a = 3,
+};
+
+enum signed_enum {
+	constant_b = -1,
+	constant_c = 2,
+};
+
+static void is_signed_type_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, is_signed_type(bool), false);
+	KUNIT_EXPECT_EQ(test, is_signed_type(signed char), true);
+	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned char), false);
+	KUNIT_EXPECT_EQ(test, is_signed_type(char), false);
+	KUNIT_EXPECT_EQ(test, is_signed_type(int), true);
+	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned int), false);
+	KUNIT_EXPECT_EQ(test, is_signed_type(long), true);
+	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned long), false);
+	KUNIT_EXPECT_EQ(test, is_signed_type(long long), true);
+	KUNIT_EXPECT_EQ(test, is_signed_type(unsigned long long), false);
+	KUNIT_EXPECT_EQ(test, is_signed_type(enum unsigned_enum), false);
+	KUNIT_EXPECT_EQ(test, is_signed_type(enum signed_enum), true);
+	KUNIT_EXPECT_EQ(test, is_signed_type(void *), false);
+	KUNIT_EXPECT_EQ(test, is_signed_type(const char *), false);
+}
+
+static struct kunit_case is_signed_type_test_cases[] = {
+	KUNIT_CASE(is_signed_type_test),
+	{}
+};
+
+static struct kunit_suite is_signed_type_test_suite = {
+	.name = "is_signed_type",
+	.test_cases = is_signed_type_test_cases,
+};
+
+kunit_test_suite(is_signed_type_test_suite);
+
+MODULE_DESCRIPTION("is_signed_type() KUnit test suite");
+MODULE_LICENSE("Dual MIT/GPL");
diff --git a/lib/tests/kunit_iov_iter.c a/lib/tests/kunit_iov_iter.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/kunit_iov_iter.c
@@ -0,0 +1,1036 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* I/O iterator tests.  This can only test kernel-backed iterator types.
+ *
+ * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@xxxxxxxxxx)
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/uio.h>
+#include <linux/bvec.h>
+#include <linux/folio_queue.h>
+#include <kunit/test.h>
+
+MODULE_DESCRIPTION("iov_iter testing");
+MODULE_AUTHOR("David Howells <dhowells@xxxxxxxxxx>");
+MODULE_LICENSE("GPL");
+
+struct kvec_test_range {
+	int	from, to;
+};
+
+static const struct kvec_test_range kvec_test_ranges[] = {
+	{ 0x00002, 0x00002 },
+	{ 0x00027, 0x03000 },
+	{ 0x05193, 0x18794 },
+	{ 0x20000, 0x20000 },
+	{ 0x20000, 0x24000 },
+	{ 0x24000, 0x27001 },
+	{ 0x29000, 0xffffb },
+	{ 0xffffd, 0xffffe },
+	{ -1 }
+};
+
+static inline u8 pattern(unsigned long x)
+{
+	return x & 0xff;
+}
+
+static void iov_kunit_unmap(void *data)
+{
+	vunmap(data);
+}
+
+static void *__init iov_kunit_create_buffer(struct kunit *test,
+					    struct page ***ppages,
+					    size_t npages)
+{
+	struct page **pages;
+	unsigned long got;
+	void *buffer;
+
+	pages = kunit_kcalloc(test, npages, sizeof(struct page *), GFP_KERNEL);
+        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pages);
+	*ppages = pages;
+
+	got = alloc_pages_bulk_array(GFP_KERNEL, npages, pages);
+	if (got != npages) {
+		release_pages(pages, got);
+		KUNIT_ASSERT_EQ(test, got, npages);
+	}
+
+	for (int i = 0; i < npages; i++)
+		pages[i]->index = i;
+
+	buffer = vmap(pages, npages, VM_MAP | VM_MAP_PUT_PAGES, PAGE_KERNEL);
+        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buffer);
+
+	kunit_add_action_or_reset(test, iov_kunit_unmap, buffer);
+	return buffer;
+}
+
+static void __init iov_kunit_load_kvec(struct kunit *test,
+				       struct iov_iter *iter, int dir,
+				       struct kvec *kvec, unsigned int kvmax,
+				       void *buffer, size_t bufsize,
+				       const struct kvec_test_range *pr)
+{
+	size_t size = 0;
+	int i;
+
+	for (i = 0; i < kvmax; i++, pr++) {
+		if (pr->from < 0)
+			break;
+		KUNIT_ASSERT_GE(test, pr->to, pr->from);
+		KUNIT_ASSERT_LE(test, pr->to, bufsize);
+		kvec[i].iov_base = buffer + pr->from;
+		kvec[i].iov_len = pr->to - pr->from;
+		size += pr->to - pr->from;
+	}
+	KUNIT_ASSERT_LE(test, size, bufsize);
+
+	iov_iter_kvec(iter, dir, kvec, i, size);
+}
+
+/*
+ * Test copying to a ITER_KVEC-type iterator.
+ */
+static void __init iov_kunit_copy_to_kvec(struct kunit *test)
+{
+	const struct kvec_test_range *pr;
+	struct iov_iter iter;
+	struct page **spages, **bpages;
+	struct kvec kvec[8];
+	u8 *scratch, *buffer;
+	size_t bufsize, npages, size, copied;
+	int i, patt;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	scratch = iov_kunit_create_buffer(test, &spages, npages);
+	for (i = 0; i < bufsize; i++)
+		scratch[i] = pattern(i);
+
+	buffer = iov_kunit_create_buffer(test, &bpages, npages);
+	memset(buffer, 0, bufsize);
+
+	iov_kunit_load_kvec(test, &iter, READ, kvec, ARRAY_SIZE(kvec),
+			    buffer, bufsize, kvec_test_ranges);
+	size = iter.count;
+
+	copied = copy_to_iter(scratch, size, &iter);
+
+	KUNIT_EXPECT_EQ(test, copied, size);
+	KUNIT_EXPECT_EQ(test, iter.count, 0);
+	KUNIT_EXPECT_EQ(test, iter.nr_segs, 0);
+
+	/* Build the expected image in the scratch buffer. */
+	patt = 0;
+	memset(scratch, 0, bufsize);
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++)
+		for (i = pr->from; i < pr->to; i++)
+			scratch[i] = pattern(patt++);
+
+	/* Compare the images */
+	for (i = 0; i < bufsize; i++) {
+		KUNIT_EXPECT_EQ_MSG(test, buffer[i], scratch[i], "at i=%x", i);
+		if (buffer[i] != scratch[i])
+			return;
+	}
+
+	KUNIT_SUCCEED(test);
+}
+
+/*
+ * Test copying from a ITER_KVEC-type iterator.
+ */
+static void __init iov_kunit_copy_from_kvec(struct kunit *test)
+{
+	const struct kvec_test_range *pr;
+	struct iov_iter iter;
+	struct page **spages, **bpages;
+	struct kvec kvec[8];
+	u8 *scratch, *buffer;
+	size_t bufsize, npages, size, copied;
+	int i, j;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	buffer = iov_kunit_create_buffer(test, &bpages, npages);
+	for (i = 0; i < bufsize; i++)
+		buffer[i] = pattern(i);
+
+	scratch = iov_kunit_create_buffer(test, &spages, npages);
+	memset(scratch, 0, bufsize);
+
+	iov_kunit_load_kvec(test, &iter, WRITE, kvec, ARRAY_SIZE(kvec),
+			    buffer, bufsize, kvec_test_ranges);
+	size = min(iter.count, bufsize);
+
+	copied = copy_from_iter(scratch, size, &iter);
+
+	KUNIT_EXPECT_EQ(test, copied, size);
+	KUNIT_EXPECT_EQ(test, iter.count, 0);
+	KUNIT_EXPECT_EQ(test, iter.nr_segs, 0);
+
+	/* Build the expected image in the main buffer. */
+	i = 0;
+	memset(buffer, 0, bufsize);
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
+		for (j = pr->from; j < pr->to; j++) {
+			buffer[i++] = pattern(j);
+			if (i >= bufsize)
+				goto stop;
+		}
+	}
+stop:
+
+	/* Compare the images */
+	for (i = 0; i < bufsize; i++) {
+		KUNIT_EXPECT_EQ_MSG(test, scratch[i], buffer[i], "at i=%x", i);
+		if (scratch[i] != buffer[i])
+			return;
+	}
+
+	KUNIT_SUCCEED(test);
+}
+
+struct bvec_test_range {
+	int	page, from, to;
+};
+
+static const struct bvec_test_range bvec_test_ranges[] = {
+	{ 0, 0x0002, 0x0002 },
+	{ 1, 0x0027, 0x0893 },
+	{ 2, 0x0193, 0x0794 },
+	{ 3, 0x0000, 0x1000 },
+	{ 4, 0x0000, 0x1000 },
+	{ 5, 0x0000, 0x1000 },
+	{ 6, 0x0000, 0x0ffb },
+	{ 6, 0x0ffd, 0x0ffe },
+	{ -1, -1, -1 }
+};
+
+static void __init iov_kunit_load_bvec(struct kunit *test,
+				       struct iov_iter *iter, int dir,
+				       struct bio_vec *bvec, unsigned int bvmax,
+				       struct page **pages, size_t npages,
+				       size_t bufsize,
+				       const struct bvec_test_range *pr)
+{
+	struct page *can_merge = NULL, *page;
+	size_t size = 0;
+	int i;
+
+	for (i = 0; i < bvmax; i++, pr++) {
+		if (pr->from < 0)
+			break;
+		KUNIT_ASSERT_LT(test, pr->page, npages);
+		KUNIT_ASSERT_LT(test, pr->page * PAGE_SIZE, bufsize);
+		KUNIT_ASSERT_GE(test, pr->from, 0);
+		KUNIT_ASSERT_GE(test, pr->to, pr->from);
+		KUNIT_ASSERT_LE(test, pr->to, PAGE_SIZE);
+
+		page = pages[pr->page];
+		if (pr->from == 0 && pr->from != pr->to && page == can_merge) {
+			i--;
+			bvec[i].bv_len += pr->to;
+		} else {
+			bvec_set_page(&bvec[i], page, pr->to - pr->from, pr->from);
+		}
+
+		size += pr->to - pr->from;
+		if ((pr->to & ~PAGE_MASK) == 0)
+			can_merge = page + pr->to / PAGE_SIZE;
+		else
+			can_merge = NULL;
+	}
+
+	iov_iter_bvec(iter, dir, bvec, i, size);
+}
+
+/*
+ * Test copying to a ITER_BVEC-type iterator.
+ */
+static void __init iov_kunit_copy_to_bvec(struct kunit *test)
+{
+	const struct bvec_test_range *pr;
+	struct iov_iter iter;
+	struct bio_vec bvec[8];
+	struct page **spages, **bpages;
+	u8 *scratch, *buffer;
+	size_t bufsize, npages, size, copied;
+	int i, b, patt;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	scratch = iov_kunit_create_buffer(test, &spages, npages);
+	for (i = 0; i < bufsize; i++)
+		scratch[i] = pattern(i);
+
+	buffer = iov_kunit_create_buffer(test, &bpages, npages);
+	memset(buffer, 0, bufsize);
+
+	iov_kunit_load_bvec(test, &iter, READ, bvec, ARRAY_SIZE(bvec),
+			    bpages, npages, bufsize, bvec_test_ranges);
+	size = iter.count;
+
+	copied = copy_to_iter(scratch, size, &iter);
+
+	KUNIT_EXPECT_EQ(test, copied, size);
+	KUNIT_EXPECT_EQ(test, iter.count, 0);
+	KUNIT_EXPECT_EQ(test, iter.nr_segs, 0);
+
+	/* Build the expected image in the scratch buffer. */
+	b = 0;
+	patt = 0;
+	memset(scratch, 0, bufsize);
+	for (pr = bvec_test_ranges; pr->from >= 0; pr++, b++) {
+		u8 *p = scratch + pr->page * PAGE_SIZE;
+
+		for (i = pr->from; i < pr->to; i++)
+			p[i] = pattern(patt++);
+	}
+
+	/* Compare the images */
+	for (i = 0; i < bufsize; i++) {
+		KUNIT_EXPECT_EQ_MSG(test, buffer[i], scratch[i], "at i=%x", i);
+		if (buffer[i] != scratch[i])
+			return;
+	}
+
+	KUNIT_SUCCEED(test);
+}
+
+/*
+ * Test copying from a ITER_BVEC-type iterator.
+ */
+static void __init iov_kunit_copy_from_bvec(struct kunit *test)
+{
+	const struct bvec_test_range *pr;
+	struct iov_iter iter;
+	struct bio_vec bvec[8];
+	struct page **spages, **bpages;
+	u8 *scratch, *buffer;
+	size_t bufsize, npages, size, copied;
+	int i, j;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	buffer = iov_kunit_create_buffer(test, &bpages, npages);
+	for (i = 0; i < bufsize; i++)
+		buffer[i] = pattern(i);
+
+	scratch = iov_kunit_create_buffer(test, &spages, npages);
+	memset(scratch, 0, bufsize);
+
+	iov_kunit_load_bvec(test, &iter, WRITE, bvec, ARRAY_SIZE(bvec),
+			    bpages, npages, bufsize, bvec_test_ranges);
+	size = iter.count;
+
+	copied = copy_from_iter(scratch, size, &iter);
+
+	KUNIT_EXPECT_EQ(test, copied, size);
+	KUNIT_EXPECT_EQ(test, iter.count, 0);
+	KUNIT_EXPECT_EQ(test, iter.nr_segs, 0);
+
+	/* Build the expected image in the main buffer. */
+	i = 0;
+	memset(buffer, 0, bufsize);
+	for (pr = bvec_test_ranges; pr->from >= 0; pr++) {
+		size_t patt = pr->page * PAGE_SIZE;
+
+		for (j = pr->from; j < pr->to; j++) {
+			buffer[i++] = pattern(patt + j);
+			if (i >= bufsize)
+				goto stop;
+		}
+	}
+stop:
+
+	/* Compare the images */
+	for (i = 0; i < bufsize; i++) {
+		KUNIT_EXPECT_EQ_MSG(test, scratch[i], buffer[i], "at i=%x", i);
+		if (scratch[i] != buffer[i])
+			return;
+	}
+
+	KUNIT_SUCCEED(test);
+}
+
+static void iov_kunit_destroy_folioq(void *data)
+{
+	struct folio_queue *folioq, *next;
+
+	for (folioq = data; folioq; folioq = next) {
+		next = folioq->next;
+		for (int i = 0; i < folioq_nr_slots(folioq); i++)
+			if (folioq_folio(folioq, i))
+				folio_put(folioq_folio(folioq, i));
+		kfree(folioq);
+	}
+}
+
+static void __init iov_kunit_load_folioq(struct kunit *test,
+					struct iov_iter *iter, int dir,
+					struct folio_queue *folioq,
+					struct page **pages, size_t npages)
+{
+	struct folio_queue *p = folioq;
+	size_t size = 0;
+	int i;
+
+	for (i = 0; i < npages; i++) {
+		if (folioq_full(p)) {
+			p->next = kzalloc(sizeof(struct folio_queue), GFP_KERNEL);
+			KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p->next);
+			folioq_init(p->next);
+			p->next->prev = p;
+			p = p->next;
+		}
+		folioq_append(p, page_folio(pages[i]));
+		size += PAGE_SIZE;
+	}
+	iov_iter_folio_queue(iter, dir, folioq, 0, 0, size);
+}
+
+static struct folio_queue *iov_kunit_create_folioq(struct kunit *test)
+{
+	struct folio_queue *folioq;
+
+	folioq = kzalloc(sizeof(struct folio_queue), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, folioq);
+	kunit_add_action_or_reset(test, iov_kunit_destroy_folioq, folioq);
+	folioq_init(folioq);
+	return folioq;
+}
+
+/*
+ * Test copying to a ITER_FOLIOQ-type iterator.
+ */
+static void __init iov_kunit_copy_to_folioq(struct kunit *test)
+{
+	const struct kvec_test_range *pr;
+	struct iov_iter iter;
+	struct folio_queue *folioq;
+	struct page **spages, **bpages;
+	u8 *scratch, *buffer;
+	size_t bufsize, npages, size, copied;
+	int i, patt;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	folioq = iov_kunit_create_folioq(test);
+
+	scratch = iov_kunit_create_buffer(test, &spages, npages);
+	for (i = 0; i < bufsize; i++)
+		scratch[i] = pattern(i);
+
+	buffer = iov_kunit_create_buffer(test, &bpages, npages);
+	memset(buffer, 0, bufsize);
+
+	iov_kunit_load_folioq(test, &iter, READ, folioq, bpages, npages);
+
+	i = 0;
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
+		size = pr->to - pr->from;
+		KUNIT_ASSERT_LE(test, pr->to, bufsize);
+
+		iov_iter_folio_queue(&iter, READ, folioq, 0, 0, pr->to);
+		iov_iter_advance(&iter, pr->from);
+		copied = copy_to_iter(scratch + i, size, &iter);
+
+		KUNIT_EXPECT_EQ(test, copied, size);
+		KUNIT_EXPECT_EQ(test, iter.count, 0);
+		KUNIT_EXPECT_EQ(test, iter.iov_offset, pr->to % PAGE_SIZE);
+		i += size;
+		if (test->status == KUNIT_FAILURE)
+			goto stop;
+	}
+
+	/* Build the expected image in the scratch buffer. */
+	patt = 0;
+	memset(scratch, 0, bufsize);
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++)
+		for (i = pr->from; i < pr->to; i++)
+			scratch[i] = pattern(patt++);
+
+	/* Compare the images */
+	for (i = 0; i < bufsize; i++) {
+		KUNIT_EXPECT_EQ_MSG(test, buffer[i], scratch[i], "at i=%x", i);
+		if (buffer[i] != scratch[i])
+			return;
+	}
+
+stop:
+	KUNIT_SUCCEED(test);
+}
+
+/*
+ * Test copying from a ITER_FOLIOQ-type iterator.
+ */
+static void __init iov_kunit_copy_from_folioq(struct kunit *test)
+{
+	const struct kvec_test_range *pr;
+	struct iov_iter iter;
+	struct folio_queue *folioq;
+	struct page **spages, **bpages;
+	u8 *scratch, *buffer;
+	size_t bufsize, npages, size, copied;
+	int i, j;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	folioq = iov_kunit_create_folioq(test);
+
+	buffer = iov_kunit_create_buffer(test, &bpages, npages);
+	for (i = 0; i < bufsize; i++)
+		buffer[i] = pattern(i);
+
+	scratch = iov_kunit_create_buffer(test, &spages, npages);
+	memset(scratch, 0, bufsize);
+
+	iov_kunit_load_folioq(test, &iter, READ, folioq, bpages, npages);
+
+	i = 0;
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
+		size = pr->to - pr->from;
+		KUNIT_ASSERT_LE(test, pr->to, bufsize);
+
+		iov_iter_folio_queue(&iter, WRITE, folioq, 0, 0, pr->to);
+		iov_iter_advance(&iter, pr->from);
+		copied = copy_from_iter(scratch + i, size, &iter);
+
+		KUNIT_EXPECT_EQ(test, copied, size);
+		KUNIT_EXPECT_EQ(test, iter.count, 0);
+		KUNIT_EXPECT_EQ(test, iter.iov_offset, pr->to % PAGE_SIZE);
+		i += size;
+	}
+
+	/* Build the expected image in the main buffer. */
+	i = 0;
+	memset(buffer, 0, bufsize);
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
+		for (j = pr->from; j < pr->to; j++) {
+			buffer[i++] = pattern(j);
+			if (i >= bufsize)
+				goto stop;
+		}
+	}
+stop:
+
+	/* Compare the images */
+	for (i = 0; i < bufsize; i++) {
+		KUNIT_EXPECT_EQ_MSG(test, scratch[i], buffer[i], "at i=%x", i);
+		if (scratch[i] != buffer[i])
+			return;
+	}
+
+	KUNIT_SUCCEED(test);
+}
+
+static void iov_kunit_destroy_xarray(void *data)
+{
+	struct xarray *xarray = data;
+
+	xa_destroy(xarray);
+	kfree(xarray);
+}
+
+static void __init iov_kunit_load_xarray(struct kunit *test,
+					 struct iov_iter *iter, int dir,
+					 struct xarray *xarray,
+					 struct page **pages, size_t npages)
+{
+	size_t size = 0;
+	int i;
+
+	for (i = 0; i < npages; i++) {
+		void *x = xa_store(xarray, i, pages[i], GFP_KERNEL);
+
+		KUNIT_ASSERT_FALSE(test, xa_is_err(x));
+		size += PAGE_SIZE;
+	}
+	iov_iter_xarray(iter, dir, xarray, 0, size);
+}
+
+static struct xarray *iov_kunit_create_xarray(struct kunit *test)
+{
+	struct xarray *xarray;
+
+	xarray = kzalloc(sizeof(struct xarray), GFP_KERNEL);
+	xa_init(xarray);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xarray);
+	kunit_add_action_or_reset(test, iov_kunit_destroy_xarray, xarray);
+	return xarray;
+}
+
+/*
+ * Test copying to a ITER_XARRAY-type iterator.
+ */
+static void __init iov_kunit_copy_to_xarray(struct kunit *test)
+{
+	const struct kvec_test_range *pr;
+	struct iov_iter iter;
+	struct xarray *xarray;
+	struct page **spages, **bpages;
+	u8 *scratch, *buffer;
+	size_t bufsize, npages, size, copied;
+	int i, patt;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	xarray = iov_kunit_create_xarray(test);
+
+	scratch = iov_kunit_create_buffer(test, &spages, npages);
+	for (i = 0; i < bufsize; i++)
+		scratch[i] = pattern(i);
+
+	buffer = iov_kunit_create_buffer(test, &bpages, npages);
+	memset(buffer, 0, bufsize);
+
+	iov_kunit_load_xarray(test, &iter, READ, xarray, bpages, npages);
+
+	i = 0;
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
+		size = pr->to - pr->from;
+		KUNIT_ASSERT_LE(test, pr->to, bufsize);
+
+		iov_iter_xarray(&iter, READ, xarray, pr->from, size);
+		copied = copy_to_iter(scratch + i, size, &iter);
+
+		KUNIT_EXPECT_EQ(test, copied, size);
+		KUNIT_EXPECT_EQ(test, iter.count, 0);
+		KUNIT_EXPECT_EQ(test, iter.iov_offset, size);
+		i += size;
+	}
+
+	/* Build the expected image in the scratch buffer. */
+	patt = 0;
+	memset(scratch, 0, bufsize);
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++)
+		for (i = pr->from; i < pr->to; i++)
+			scratch[i] = pattern(patt++);
+
+	/* Compare the images */
+	for (i = 0; i < bufsize; i++) {
+		KUNIT_EXPECT_EQ_MSG(test, buffer[i], scratch[i], "at i=%x", i);
+		if (buffer[i] != scratch[i])
+			return;
+	}
+
+	KUNIT_SUCCEED(test);
+}
+
+/*
+ * Test copying from a ITER_XARRAY-type iterator.
+ */
+static void __init iov_kunit_copy_from_xarray(struct kunit *test)
+{
+	const struct kvec_test_range *pr;
+	struct iov_iter iter;
+	struct xarray *xarray;
+	struct page **spages, **bpages;
+	u8 *scratch, *buffer;
+	size_t bufsize, npages, size, copied;
+	int i, j;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	xarray = iov_kunit_create_xarray(test);
+
+	buffer = iov_kunit_create_buffer(test, &bpages, npages);
+	for (i = 0; i < bufsize; i++)
+		buffer[i] = pattern(i);
+
+	scratch = iov_kunit_create_buffer(test, &spages, npages);
+	memset(scratch, 0, bufsize);
+
+	iov_kunit_load_xarray(test, &iter, READ, xarray, bpages, npages);
+
+	i = 0;
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
+		size = pr->to - pr->from;
+		KUNIT_ASSERT_LE(test, pr->to, bufsize);
+
+		iov_iter_xarray(&iter, WRITE, xarray, pr->from, size);
+		copied = copy_from_iter(scratch + i, size, &iter);
+
+		KUNIT_EXPECT_EQ(test, copied, size);
+		KUNIT_EXPECT_EQ(test, iter.count, 0);
+		KUNIT_EXPECT_EQ(test, iter.iov_offset, size);
+		i += size;
+	}
+
+	/* Build the expected image in the main buffer. */
+	i = 0;
+	memset(buffer, 0, bufsize);
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
+		for (j = pr->from; j < pr->to; j++) {
+			buffer[i++] = pattern(j);
+			if (i >= bufsize)
+				goto stop;
+		}
+	}
+stop:
+
+	/* Compare the images */
+	for (i = 0; i < bufsize; i++) {
+		KUNIT_EXPECT_EQ_MSG(test, scratch[i], buffer[i], "at i=%x", i);
+		if (scratch[i] != buffer[i])
+			return;
+	}
+
+	KUNIT_SUCCEED(test);
+}
+
+/*
+ * Test the extraction of ITER_KVEC-type iterators.
+ */
+static void __init iov_kunit_extract_pages_kvec(struct kunit *test)
+{
+	const struct kvec_test_range *pr;
+	struct iov_iter iter;
+	struct page **bpages, *pagelist[8], **pages = pagelist;
+	struct kvec kvec[8];
+	u8 *buffer;
+	ssize_t len;
+	size_t bufsize, size = 0, npages;
+	int i, from;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	buffer = iov_kunit_create_buffer(test, &bpages, npages);
+
+	iov_kunit_load_kvec(test, &iter, READ, kvec, ARRAY_SIZE(kvec),
+			    buffer, bufsize, kvec_test_ranges);
+	size = iter.count;
+
+	pr = kvec_test_ranges;
+	from = pr->from;
+	do {
+		size_t offset0 = LONG_MAX;
+
+		for (i = 0; i < ARRAY_SIZE(pagelist); i++)
+			pagelist[i] = (void *)(unsigned long)0xaa55aa55aa55aa55ULL;
+
+		len = iov_iter_extract_pages(&iter, &pages, 100 * 1024,
+					     ARRAY_SIZE(pagelist), 0, &offset0);
+		KUNIT_EXPECT_GE(test, len, 0);
+		if (len < 0)
+			break;
+		KUNIT_EXPECT_GE(test, (ssize_t)offset0, 0);
+		KUNIT_EXPECT_LT(test, offset0, PAGE_SIZE);
+		KUNIT_EXPECT_LE(test, len, size);
+		KUNIT_EXPECT_EQ(test, iter.count, size - len);
+		size -= len;
+
+		if (len == 0)
+			break;
+
+		for (i = 0; i < ARRAY_SIZE(pagelist); i++) {
+			struct page *p;
+			ssize_t part = min_t(ssize_t, len, PAGE_SIZE - offset0);
+			int ix;
+
+			KUNIT_ASSERT_GE(test, part, 0);
+			while (from == pr->to) {
+				pr++;
+				from = pr->from;
+				if (from < 0)
+					goto stop;
+			}
+			ix = from / PAGE_SIZE;
+			KUNIT_ASSERT_LT(test, ix, npages);
+			p = bpages[ix];
+			KUNIT_EXPECT_PTR_EQ(test, pagelist[i], p);
+			KUNIT_EXPECT_EQ(test, offset0, from % PAGE_SIZE);
+			from += part;
+			len -= part;
+			KUNIT_ASSERT_GE(test, len, 0);
+			if (len == 0)
+				break;
+			offset0 = 0;
+		}
+
+		if (test->status == KUNIT_FAILURE)
+			break;
+	} while (iov_iter_count(&iter) > 0);
+
+stop:
+	KUNIT_EXPECT_EQ(test, size, 0);
+	KUNIT_EXPECT_EQ(test, iter.count, 0);
+	KUNIT_SUCCEED(test);
+}
+
+/*
+ * Test the extraction of ITER_BVEC-type iterators.
+ */
+static void __init iov_kunit_extract_pages_bvec(struct kunit *test)
+{
+	const struct bvec_test_range *pr;
+	struct iov_iter iter;
+	struct page **bpages, *pagelist[8], **pages = pagelist;
+	struct bio_vec bvec[8];
+	ssize_t len;
+	size_t bufsize, size = 0, npages;
+	int i, from;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	iov_kunit_create_buffer(test, &bpages, npages);
+	iov_kunit_load_bvec(test, &iter, READ, bvec, ARRAY_SIZE(bvec),
+			    bpages, npages, bufsize, bvec_test_ranges);
+	size = iter.count;
+
+	pr = bvec_test_ranges;
+	from = pr->from;
+	do {
+		size_t offset0 = LONG_MAX;
+
+		for (i = 0; i < ARRAY_SIZE(pagelist); i++)
+			pagelist[i] = (void *)(unsigned long)0xaa55aa55aa55aa55ULL;
+
+		len = iov_iter_extract_pages(&iter, &pages, 100 * 1024,
+					     ARRAY_SIZE(pagelist), 0, &offset0);
+		KUNIT_EXPECT_GE(test, len, 0);
+		if (len < 0)
+			break;
+		KUNIT_EXPECT_GE(test, (ssize_t)offset0, 0);
+		KUNIT_EXPECT_LT(test, offset0, PAGE_SIZE);
+		KUNIT_EXPECT_LE(test, len, size);
+		KUNIT_EXPECT_EQ(test, iter.count, size - len);
+		size -= len;
+
+		if (len == 0)
+			break;
+
+		for (i = 0; i < ARRAY_SIZE(pagelist); i++) {
+			struct page *p;
+			ssize_t part = min_t(ssize_t, len, PAGE_SIZE - offset0);
+			int ix;
+
+			KUNIT_ASSERT_GE(test, part, 0);
+			while (from == pr->to) {
+				pr++;
+				from = pr->from;
+				if (from < 0)
+					goto stop;
+			}
+			ix = pr->page + from / PAGE_SIZE;
+			KUNIT_ASSERT_LT(test, ix, npages);
+			p = bpages[ix];
+			KUNIT_EXPECT_PTR_EQ(test, pagelist[i], p);
+			KUNIT_EXPECT_EQ(test, offset0, from % PAGE_SIZE);
+			from += part;
+			len -= part;
+			KUNIT_ASSERT_GE(test, len, 0);
+			if (len == 0)
+				break;
+			offset0 = 0;
+		}
+
+		if (test->status == KUNIT_FAILURE)
+			break;
+	} while (iov_iter_count(&iter) > 0);
+
+stop:
+	KUNIT_EXPECT_EQ(test, size, 0);
+	KUNIT_EXPECT_EQ(test, iter.count, 0);
+	KUNIT_SUCCEED(test);
+}
+
+/*
+ * Test the extraction of ITER_FOLIOQ-type iterators.
+ */
+static void __init iov_kunit_extract_pages_folioq(struct kunit *test)
+{
+	const struct kvec_test_range *pr;
+	struct folio_queue *folioq;
+	struct iov_iter iter;
+	struct page **bpages, *pagelist[8], **pages = pagelist;
+	ssize_t len;
+	size_t bufsize, size = 0, npages;
+	int i, from;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	folioq = iov_kunit_create_folioq(test);
+
+	iov_kunit_create_buffer(test, &bpages, npages);
+	iov_kunit_load_folioq(test, &iter, READ, folioq, bpages, npages);
+
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
+		from = pr->from;
+		size = pr->to - from;
+		KUNIT_ASSERT_LE(test, pr->to, bufsize);
+
+		iov_iter_folio_queue(&iter, WRITE, folioq, 0, 0, pr->to);
+		iov_iter_advance(&iter, from);
+
+		do {
+			size_t offset0 = LONG_MAX;
+
+			for (i = 0; i < ARRAY_SIZE(pagelist); i++)
+				pagelist[i] = (void *)(unsigned long)0xaa55aa55aa55aa55ULL;
+
+			len = iov_iter_extract_pages(&iter, &pages, 100 * 1024,
+						     ARRAY_SIZE(pagelist), 0, &offset0);
+			KUNIT_EXPECT_GE(test, len, 0);
+			if (len < 0)
+				break;
+			KUNIT_EXPECT_LE(test, len, size);
+			KUNIT_EXPECT_EQ(test, iter.count, size - len);
+			if (len == 0)
+				break;
+			size -= len;
+			KUNIT_EXPECT_GE(test, (ssize_t)offset0, 0);
+			KUNIT_EXPECT_LT(test, offset0, PAGE_SIZE);
+
+			for (i = 0; i < ARRAY_SIZE(pagelist); i++) {
+				struct page *p;
+				ssize_t part = min_t(ssize_t, len, PAGE_SIZE - offset0);
+				int ix;
+
+				KUNIT_ASSERT_GE(test, part, 0);
+				ix = from / PAGE_SIZE;
+				KUNIT_ASSERT_LT(test, ix, npages);
+				p = bpages[ix];
+				KUNIT_EXPECT_PTR_EQ(test, pagelist[i], p);
+				KUNIT_EXPECT_EQ(test, offset0, from % PAGE_SIZE);
+				from += part;
+				len -= part;
+				KUNIT_ASSERT_GE(test, len, 0);
+				if (len == 0)
+					break;
+				offset0 = 0;
+			}
+
+			if (test->status == KUNIT_FAILURE)
+				goto stop;
+		} while (iov_iter_count(&iter) > 0);
+
+		KUNIT_EXPECT_EQ(test, size, 0);
+		KUNIT_EXPECT_EQ(test, iter.count, 0);
+	}
+
+stop:
+	KUNIT_SUCCEED(test);
+}
+
+/*
+ * Test the extraction of ITER_XARRAY-type iterators.
+ */
+static void __init iov_kunit_extract_pages_xarray(struct kunit *test)
+{
+	const struct kvec_test_range *pr;
+	struct iov_iter iter;
+	struct xarray *xarray;
+	struct page **bpages, *pagelist[8], **pages = pagelist;
+	ssize_t len;
+	size_t bufsize, size = 0, npages;
+	int i, from;
+
+	bufsize = 0x100000;
+	npages = bufsize / PAGE_SIZE;
+
+	xarray = iov_kunit_create_xarray(test);
+
+	iov_kunit_create_buffer(test, &bpages, npages);
+	iov_kunit_load_xarray(test, &iter, READ, xarray, bpages, npages);
+
+	for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
+		from = pr->from;
+		size = pr->to - from;
+		KUNIT_ASSERT_LE(test, pr->to, bufsize);
+
+		iov_iter_xarray(&iter, WRITE, xarray, from, size);
+
+		do {
+			size_t offset0 = LONG_MAX;
+
+			for (i = 0; i < ARRAY_SIZE(pagelist); i++)
+				pagelist[i] = (void *)(unsigned long)0xaa55aa55aa55aa55ULL;
+
+			len = iov_iter_extract_pages(&iter, &pages, 100 * 1024,
+						     ARRAY_SIZE(pagelist), 0, &offset0);
+			KUNIT_EXPECT_GE(test, len, 0);
+			if (len < 0)
+				break;
+			KUNIT_EXPECT_LE(test, len, size);
+			KUNIT_EXPECT_EQ(test, iter.count, size - len);
+			if (len == 0)
+				break;
+			size -= len;
+			KUNIT_EXPECT_GE(test, (ssize_t)offset0, 0);
+			KUNIT_EXPECT_LT(test, offset0, PAGE_SIZE);
+
+			for (i = 0; i < ARRAY_SIZE(pagelist); i++) {
+				struct page *p;
+				ssize_t part = min_t(ssize_t, len, PAGE_SIZE - offset0);
+				int ix;
+
+				KUNIT_ASSERT_GE(test, part, 0);
+				ix = from / PAGE_SIZE;
+				KUNIT_ASSERT_LT(test, ix, npages);
+				p = bpages[ix];
+				KUNIT_EXPECT_PTR_EQ(test, pagelist[i], p);
+				KUNIT_EXPECT_EQ(test, offset0, from % PAGE_SIZE);
+				from += part;
+				len -= part;
+				KUNIT_ASSERT_GE(test, len, 0);
+				if (len == 0)
+					break;
+				offset0 = 0;
+			}
+
+			if (test->status == KUNIT_FAILURE)
+				goto stop;
+		} while (iov_iter_count(&iter) > 0);
+
+		KUNIT_EXPECT_EQ(test, size, 0);
+		KUNIT_EXPECT_EQ(test, iter.count, 0);
+		KUNIT_EXPECT_EQ(test, iter.iov_offset, pr->to - pr->from);
+	}
+
+stop:
+	KUNIT_SUCCEED(test);
+}
+
+static struct kunit_case __refdata iov_kunit_cases[] = {
+	KUNIT_CASE(iov_kunit_copy_to_kvec),
+	KUNIT_CASE(iov_kunit_copy_from_kvec),
+	KUNIT_CASE(iov_kunit_copy_to_bvec),
+	KUNIT_CASE(iov_kunit_copy_from_bvec),
+	KUNIT_CASE(iov_kunit_copy_to_folioq),
+	KUNIT_CASE(iov_kunit_copy_from_folioq),
+	KUNIT_CASE(iov_kunit_copy_to_xarray),
+	KUNIT_CASE(iov_kunit_copy_from_xarray),
+	KUNIT_CASE(iov_kunit_extract_pages_kvec),
+	KUNIT_CASE(iov_kunit_extract_pages_bvec),
+	KUNIT_CASE(iov_kunit_extract_pages_folioq),
+	KUNIT_CASE(iov_kunit_extract_pages_xarray),
+	{}
+};
+
+static struct kunit_suite iov_kunit_suite = {
+	.name = "iov_iter",
+	.test_cases = iov_kunit_cases,
+};
+
+kunit_test_suites(&iov_kunit_suite);
diff --git a/lib/tests/list-test.c a/lib/tests/list-test.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/list-test.c
@@ -0,0 +1,1505 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit test for the Kernel Linked-list structures.
+ *
+ * Copyright (C) 2019, Google LLC.
+ * Author: David Gow <davidgow@xxxxxxxxxx>
+ */
+#include <kunit/test.h>
+
+#include <linux/list.h>
+#include <linux/klist.h>
+
+struct list_test_struct {
+	int data;
+	struct list_head list;
+};
+
+static void list_test_list_init(struct kunit *test)
+{
+	/* Test the different ways of initialising a list. */
+	struct list_head list1 = LIST_HEAD_INIT(list1);
+	struct list_head list2;
+	LIST_HEAD(list3);
+	struct list_head *list4;
+	struct list_head *list5;
+
+	INIT_LIST_HEAD(&list2);
+
+	list4 = kzalloc(sizeof(*list4), GFP_KERNEL | __GFP_NOFAIL);
+	INIT_LIST_HEAD(list4);
+
+	list5 = kmalloc(sizeof(*list5), GFP_KERNEL | __GFP_NOFAIL);
+	memset(list5, 0xFF, sizeof(*list5));
+	INIT_LIST_HEAD(list5);
+
+	/* list_empty_careful() checks both next and prev. */
+	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list1));
+	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
+	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list3));
+	KUNIT_EXPECT_TRUE(test, list_empty_careful(list4));
+	KUNIT_EXPECT_TRUE(test, list_empty_careful(list5));
+
+	kfree(list4);
+	kfree(list5);
+}
+
+static void list_test_list_add(struct kunit *test)
+{
+	struct list_head a, b;
+	LIST_HEAD(list);
+
+	list_add(&a, &list);
+	list_add(&b, &list);
+
+	/* should be [list] -> b -> a */
+	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
+	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
+	KUNIT_EXPECT_PTR_EQ(test, b.next, &a);
+}
+
+static void list_test_list_add_tail(struct kunit *test)
+{
+	struct list_head a, b;
+	LIST_HEAD(list);
+
+	list_add_tail(&a, &list);
+	list_add_tail(&b, &list);
+
+	/* should be [list] -> a -> b */
+	KUNIT_EXPECT_PTR_EQ(test, list.next, &a);
+	KUNIT_EXPECT_PTR_EQ(test, a.prev, &list);
+	KUNIT_EXPECT_PTR_EQ(test, a.next, &b);
+}
+
+static void list_test_list_del(struct kunit *test)
+{
+	struct list_head a, b;
+	LIST_HEAD(list);
+
+	list_add_tail(&a, &list);
+	list_add_tail(&b, &list);
+
+	/* before: [list] -> a -> b */
+	list_del(&a);
+
+	/* now: [list] -> b */
+	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
+	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
+}
+
+static void list_test_list_replace(struct kunit *test)
+{
+	struct list_head a_old, a_new, b;
+	LIST_HEAD(list);
+
+	list_add_tail(&a_old, &list);
+	list_add_tail(&b, &list);
+
+	/* before: [list] -> a_old -> b */
+	list_replace(&a_old, &a_new);
+
+	/* now: [list] -> a_new -> b */
+	KUNIT_EXPECT_PTR_EQ(test, list.next, &a_new);
+	KUNIT_EXPECT_PTR_EQ(test, b.prev, &a_new);
+	KUNIT_EXPECT_PTR_EQ(test, a_new.next, &b);
+	KUNIT_EXPECT_PTR_EQ(test, a_new.prev, &list);
+}
+
+static void list_test_list_replace_init(struct kunit *test)
+{
+	struct list_head a_old, a_new, b;
+	LIST_HEAD(list);
+
+	list_add_tail(&a_old, &list);
+	list_add_tail(&b, &list);
+
+	/* before: [list] -> a_old -> b */
+	list_replace_init(&a_old, &a_new);
+
+	/* now: [list] -> a_new -> b */
+	KUNIT_EXPECT_PTR_EQ(test, list.next, &a_new);
+	KUNIT_EXPECT_PTR_EQ(test, b.prev, &a_new);
+	KUNIT_EXPECT_PTR_EQ(test, a_new.next, &b);
+	KUNIT_EXPECT_PTR_EQ(test, a_new.prev, &list);
+
+	/* check a_old is empty (initialized) */
+	KUNIT_EXPECT_TRUE(test, list_empty_careful(&a_old));
+}
+
+static void list_test_list_swap(struct kunit *test)
+{
+	struct list_head a, b;
+	LIST_HEAD(list);
+
+	list_add_tail(&a, &list);
+	list_add_tail(&b, &list);
+
+	/* before: [list] -> a -> b */
+	list_swap(&a, &b);
+
+	/* after: [list] -> b -> a */
+	KUNIT_EXPECT_PTR_EQ(test, &b, list.next);
+	KUNIT_EXPECT_PTR_EQ(test, &a, list.prev);
+
+	KUNIT_EXPECT_PTR_EQ(test, &a, b.next);
+	KUNIT_EXPECT_PTR_EQ(test, &list, b.prev);
+
+	KUNIT_EXPECT_PTR_EQ(test, &list, a.next);
+	KUNIT_EXPECT_PTR_EQ(test, &b, a.prev);
+}
+
+static void list_test_list_del_init(struct kunit *test)
+{
+	struct list_head a, b;
+	LIST_HEAD(list);
+
+	list_add_tail(&a, &list);
+	list_add_tail(&b, &list);
+
+	/* before: [list] -> a -> b */
+	list_del_init(&a);
+	/* after: [list] -> b, a initialised */
+
+	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
+	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
+	KUNIT_EXPECT_TRUE(test, list_empty_careful(&a));
+}
+
+static void list_test_list_del_init_careful(struct kunit *test)
+{
+	/* NOTE: This test only checks the behaviour of this function in
+	 * isolation. It does not verify memory model guarantees.
+	 */
+	struct list_head a, b;
+	LIST_HEAD(list);
+
+	list_add_tail(&a, &list);
+	list_add_tail(&b, &list);
+
+	/* before: [list] -> a -> b */
+	list_del_init_careful(&a);
+	/* after: [list] -> b, a initialised */
+
+	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
+	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
+	KUNIT_EXPECT_TRUE(test, list_empty_careful(&a));
+}
+
+static void list_test_list_move(struct kunit *test)
+{
+	struct list_head a, b;
+	LIST_HEAD(list1);
+	LIST_HEAD(list2);
+
+	list_add_tail(&a, &list1);
+	list_add_tail(&b, &list2);
+
+	/* before: [list1] -> a, [list2] -> b */
+	list_move(&a, &list2);
+	/* after: [list1] empty, [list2] -> a -> b */
+
+	KUNIT_EXPECT_TRUE(test, list_empty(&list1));
+
+	KUNIT_EXPECT_PTR_EQ(test, &a, list2.next);
+	KUNIT_EXPECT_PTR_EQ(test, &b, a.next);
+}
+
+static void list_test_list_move_tail(struct kunit *test)
+{
+	struct list_head a, b;
+	LIST_HEAD(list1);
+	LIST_HEAD(list2);
+
+	list_add_tail(&a, &list1);
+	list_add_tail(&b, &list2);
+
+	/* before: [list1] -> a, [list2] -> b */
+	list_move_tail(&a, &list2);
+	/* after: [list1] empty, [list2] -> b -> a */
+
+	KUNIT_EXPECT_TRUE(test, list_empty(&list1));
+
+	KUNIT_EXPECT_PTR_EQ(test, &b, list2.next);
+	KUNIT_EXPECT_PTR_EQ(test, &a, b.next);
+}
+
+static void list_test_list_bulk_move_tail(struct kunit *test)
+{
+	struct list_head a, b, c, d, x, y;
+	struct list_head *list1_values[] = { &x, &b, &c, &y };
+	struct list_head *list2_values[] = { &a, &d };
+	struct list_head *ptr;
+	LIST_HEAD(list1);
+	LIST_HEAD(list2);
+	int i = 0;
+
+	list_add_tail(&x, &list1);
+	list_add_tail(&y, &list1);
+
+	list_add_tail(&a, &list2);
+	list_add_tail(&b, &list2);
+	list_add_tail(&c, &list2);
+	list_add_tail(&d, &list2);
+
+	/* before: [list1] -> x -> y, [list2] -> a -> b -> c -> d */
+	list_bulk_move_tail(&y, &b, &c);
+	/* after: [list1] -> x -> b -> c -> y, [list2] -> a -> d */
+
+	list_for_each(ptr, &list1) {
+		KUNIT_EXPECT_PTR_EQ(test, ptr, list1_values[i]);
+		i++;
+	}
+	KUNIT_EXPECT_EQ(test, i, 4);
+	i = 0;
+	list_for_each(ptr, &list2) {
+		KUNIT_EXPECT_PTR_EQ(test, ptr, list2_values[i]);
+		i++;
+	}
+	KUNIT_EXPECT_EQ(test, i, 2);
+}
+
+static void list_test_list_is_head(struct kunit *test)
+{
+	struct list_head a, b, c;
+
+	/* Two lists: [a] -> b, [c] */
+	INIT_LIST_HEAD(&a);
+	INIT_LIST_HEAD(&c);
+	list_add_tail(&b, &a);
+
+	KUNIT_EXPECT_TRUE_MSG(test, list_is_head(&a, &a),
+		"Head element of same list");
+	KUNIT_EXPECT_FALSE_MSG(test, list_is_head(&a, &b),
+		"Non-head element of same list");
+	KUNIT_EXPECT_FALSE_MSG(test, list_is_head(&a, &c),
+		"Head element of different list");
+}
+
+
+static void list_test_list_is_first(struct kunit *test)
+{
+	struct list_head a, b;
+	LIST_HEAD(list);
+
+	list_add_tail(&a, &list);
+	list_add_tail(&b, &list);
+
+	KUNIT_EXPECT_TRUE(test, list_is_first(&a, &list));
+	KUNIT_EXPECT_FALSE(test, list_is_first(&b, &list));
+}
+
+static void list_test_list_is_last(struct kunit *test)
+{
+	struct list_head a, b;
+	LIST_HEAD(list);
+
+	list_add_tail(&a, &list);
+	list_add_tail(&b, &list);
+
+	KUNIT_EXPECT_FALSE(test, list_is_last(&a, &list));
+	KUNIT_EXPECT_TRUE(test, list_is_last(&b, &list));
+}
+
+static void list_test_list_empty(struct kunit *test)
+{
+	struct list_head a;
+	LIST_HEAD(list1);
+	LIST_HEAD(list2);
+
+	list_add_tail(&a, &list1);
+
+	KUNIT_EXPECT_FALSE(test, list_empty(&list1));
+	KUNIT_EXPECT_TRUE(test, list_empty(&list2));
+}
+
+static void list_test_list_empty_careful(struct kunit *test)
+{
+	/* This test doesn't check correctness under concurrent access */
+	struct list_head a;
+	LIST_HEAD(list1);
+	LIST_HEAD(list2);
+
+	list_add_tail(&a, &list1);
+
+	KUNIT_EXPECT_FALSE(test, list_empty_careful(&list1));
+	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
+}
+
+static void list_test_list_rotate_left(struct kunit *test)
+{
+	struct list_head a, b;
+	LIST_HEAD(list);
+
+	list_add_tail(&a, &list);
+	list_add_tail(&b, &list);
+
+	/* before: [list] -> a -> b */
+	list_rotate_left(&list);
+	/* after: [list] -> b -> a */
+
+	KUNIT_EXPECT_PTR_EQ(test, list.next, &b);
+	KUNIT_EXPECT_PTR_EQ(test, b.prev, &list);
+	KUNIT_EXPECT_PTR_EQ(test, b.next, &a);
+}
+
+static void list_test_list_rotate_to_front(struct kunit *test)
+{
+	struct list_head a, b, c, d;
+	struct list_head *list_values[] = { &c, &d, &a, &b };
+	struct list_head *ptr;
+	LIST_HEAD(list);
+	int i = 0;
+
+	list_add_tail(&a, &list);
+	list_add_tail(&b, &list);
+	list_add_tail(&c, &list);
+	list_add_tail(&d, &list);
+
+	/* before: [list] -> a -> b -> c -> d */
+	list_rotate_to_front(&c, &list);
+	/* after: [list] -> c -> d -> a -> b */
+
+	list_for_each(ptr, &list) {
+		KUNIT_EXPECT_PTR_EQ(test, ptr, list_values[i]);
+		i++;
+	}
+	KUNIT_EXPECT_EQ(test, i, 4);
+}
+
+static void list_test_list_is_singular(struct kunit *test)
+{
+	struct list_head a, b;
+	LIST_HEAD(list);
+
+	/* [list] empty */
+	KUNIT_EXPECT_FALSE(test, list_is_singular(&list));
+
+	list_add_tail(&a, &list);
+
+	/* [list] -> a */
+	KUNIT_EXPECT_TRUE(test, list_is_singular(&list));
+
+	list_add_tail(&b, &list);
+
+	/* [list] -> a -> b */
+	KUNIT_EXPECT_FALSE(test, list_is_singular(&list));
+}
+
+static void list_test_list_cut_position(struct kunit *test)
+{
+	struct list_head entries[3], *cur;
+	LIST_HEAD(list1);
+	LIST_HEAD(list2);
+	int i = 0;
+
+	list_add_tail(&entries[0], &list1);
+	list_add_tail(&entries[1], &list1);
+	list_add_tail(&entries[2], &list1);
+
+	/* before: [list1] -> entries[0] -> entries[1] -> entries[2] */
+	list_cut_position(&list2, &list1, &entries[1]);
+	/* after: [list2] -> entries[0] -> entries[1], [list1] -> entries[2] */
+
+	list_for_each(cur, &list2) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 2);
+
+	list_for_each(cur, &list1) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 3);
+}
+
+static void list_test_list_cut_before(struct kunit *test)
+{
+	struct list_head entries[3], *cur;
+	LIST_HEAD(list1);
+	LIST_HEAD(list2);
+	int i = 0;
+
+	list_add_tail(&entries[0], &list1);
+	list_add_tail(&entries[1], &list1);
+	list_add_tail(&entries[2], &list1);
+
+	/* before: [list1] -> entries[0] -> entries[1] -> entries[2] */
+	list_cut_before(&list2, &list1, &entries[1]);
+	/* after: [list2] -> entries[0], [list1] -> entries[1] -> entries[2] */
+
+	list_for_each(cur, &list2) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 1);
+
+	list_for_each(cur, &list1) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 3);
+}
+
+static void list_test_list_splice(struct kunit *test)
+{
+	struct list_head entries[5], *cur;
+	LIST_HEAD(list1);
+	LIST_HEAD(list2);
+	int i = 0;
+
+	list_add_tail(&entries[0], &list1);
+	list_add_tail(&entries[1], &list1);
+	list_add_tail(&entries[2], &list2);
+	list_add_tail(&entries[3], &list2);
+	list_add_tail(&entries[4], &list1);
+
+	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
+	list_splice(&list2, &entries[1]);
+	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] uninit */
+
+	list_for_each(cur, &list1) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 5);
+}
+
+static void list_test_list_splice_tail(struct kunit *test)
+{
+	struct list_head entries[5], *cur;
+	LIST_HEAD(list1);
+	LIST_HEAD(list2);
+	int i = 0;
+
+	list_add_tail(&entries[0], &list1);
+	list_add_tail(&entries[1], &list1);
+	list_add_tail(&entries[2], &list2);
+	list_add_tail(&entries[3], &list2);
+	list_add_tail(&entries[4], &list1);
+
+	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
+	list_splice_tail(&list2, &entries[4]);
+	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] uninit */
+
+	list_for_each(cur, &list1) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 5);
+}
+
+static void list_test_list_splice_init(struct kunit *test)
+{
+	struct list_head entries[5], *cur;
+	LIST_HEAD(list1);
+	LIST_HEAD(list2);
+	int i = 0;
+
+	list_add_tail(&entries[0], &list1);
+	list_add_tail(&entries[1], &list1);
+	list_add_tail(&entries[2], &list2);
+	list_add_tail(&entries[3], &list2);
+	list_add_tail(&entries[4], &list1);
+
+	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
+	list_splice_init(&list2, &entries[1]);
+	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] empty */
+
+	list_for_each(cur, &list1) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 5);
+
+	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
+}
+
+static void list_test_list_splice_tail_init(struct kunit *test)
+{
+	struct list_head entries[5], *cur;
+	LIST_HEAD(list1);
+	LIST_HEAD(list2);
+	int i = 0;
+
+	list_add_tail(&entries[0], &list1);
+	list_add_tail(&entries[1], &list1);
+	list_add_tail(&entries[2], &list2);
+	list_add_tail(&entries[3], &list2);
+	list_add_tail(&entries[4], &list1);
+
+	/* before: [list1]->e[0]->e[1]->e[4], [list2]->e[2]->e[3] */
+	list_splice_tail_init(&list2, &entries[4]);
+	/* after: [list1]->e[0]->e[1]->e[2]->e[3]->e[4], [list2] empty */
+
+	list_for_each(cur, &list1) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 5);
+
+	KUNIT_EXPECT_TRUE(test, list_empty_careful(&list2));
+}
+
+static void list_test_list_entry(struct kunit *test)
+{
+	struct list_test_struct test_struct;
+
+	KUNIT_EXPECT_PTR_EQ(test, &test_struct, list_entry(&(test_struct.list),
+				struct list_test_struct, list));
+}
+
+static void list_test_list_entry_is_head(struct kunit *test)
+{
+	struct list_test_struct test_struct1, test_struct2, test_struct3;
+
+	INIT_LIST_HEAD(&test_struct1.list);
+	INIT_LIST_HEAD(&test_struct3.list);
+
+	list_add_tail(&test_struct2.list, &test_struct1.list);
+
+	KUNIT_EXPECT_TRUE_MSG(test,
+		list_entry_is_head((&test_struct1), &test_struct1.list, list),
+		"Head element of same list");
+	KUNIT_EXPECT_FALSE_MSG(test,
+		list_entry_is_head((&test_struct2), &test_struct1.list, list),
+		"Non-head element of same list");
+	KUNIT_EXPECT_FALSE_MSG(test,
+		list_entry_is_head((&test_struct3), &test_struct1.list, list),
+		"Head element of different list");
+}
+
+static void list_test_list_first_entry(struct kunit *test)
+{
+	struct list_test_struct test_struct1, test_struct2;
+	LIST_HEAD(list);
+
+	list_add_tail(&test_struct1.list, &list);
+	list_add_tail(&test_struct2.list, &list);
+
+
+	KUNIT_EXPECT_PTR_EQ(test, &test_struct1, list_first_entry(&list,
+				struct list_test_struct, list));
+}
+
+static void list_test_list_last_entry(struct kunit *test)
+{
+	struct list_test_struct test_struct1, test_struct2;
+	LIST_HEAD(list);
+
+	list_add_tail(&test_struct1.list, &list);
+	list_add_tail(&test_struct2.list, &list);
+
+
+	KUNIT_EXPECT_PTR_EQ(test, &test_struct2, list_last_entry(&list,
+				struct list_test_struct, list));
+}
+
+static void list_test_list_first_entry_or_null(struct kunit *test)
+{
+	struct list_test_struct test_struct1, test_struct2;
+	LIST_HEAD(list);
+
+	KUNIT_EXPECT_FALSE(test, list_first_entry_or_null(&list,
+				struct list_test_struct, list));
+
+	list_add_tail(&test_struct1.list, &list);
+	list_add_tail(&test_struct2.list, &list);
+
+	KUNIT_EXPECT_PTR_EQ(test, &test_struct1,
+			list_first_entry_or_null(&list,
+				struct list_test_struct, list));
+}
+
+static void list_test_list_next_entry(struct kunit *test)
+{
+	struct list_test_struct test_struct1, test_struct2;
+	LIST_HEAD(list);
+
+	list_add_tail(&test_struct1.list, &list);
+	list_add_tail(&test_struct2.list, &list);
+
+
+	KUNIT_EXPECT_PTR_EQ(test, &test_struct2, list_next_entry(&test_struct1,
+				list));
+}
+
+static void list_test_list_prev_entry(struct kunit *test)
+{
+	struct list_test_struct test_struct1, test_struct2;
+	LIST_HEAD(list);
+
+	list_add_tail(&test_struct1.list, &list);
+	list_add_tail(&test_struct2.list, &list);
+
+
+	KUNIT_EXPECT_PTR_EQ(test, &test_struct1, list_prev_entry(&test_struct2,
+				list));
+}
+
+static void list_test_list_for_each(struct kunit *test)
+{
+	struct list_head entries[3], *cur;
+	LIST_HEAD(list);
+	int i = 0;
+
+	list_add_tail(&entries[0], &list);
+	list_add_tail(&entries[1], &list);
+	list_add_tail(&entries[2], &list);
+
+	list_for_each(cur, &list) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 3);
+}
+
+static void list_test_list_for_each_prev(struct kunit *test)
+{
+	struct list_head entries[3], *cur;
+	LIST_HEAD(list);
+	int i = 2;
+
+	list_add_tail(&entries[0], &list);
+	list_add_tail(&entries[1], &list);
+	list_add_tail(&entries[2], &list);
+
+	list_for_each_prev(cur, &list) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		i--;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, -1);
+}
+
+static void list_test_list_for_each_safe(struct kunit *test)
+{
+	struct list_head entries[3], *cur, *n;
+	LIST_HEAD(list);
+	int i = 0;
+
+
+	list_add_tail(&entries[0], &list);
+	list_add_tail(&entries[1], &list);
+	list_add_tail(&entries[2], &list);
+
+	list_for_each_safe(cur, n, &list) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		list_del(&entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 3);
+	KUNIT_EXPECT_TRUE(test, list_empty(&list));
+}
+
+static void list_test_list_for_each_prev_safe(struct kunit *test)
+{
+	struct list_head entries[3], *cur, *n;
+	LIST_HEAD(list);
+	int i = 2;
+
+	list_add_tail(&entries[0], &list);
+	list_add_tail(&entries[1], &list);
+	list_add_tail(&entries[2], &list);
+
+	list_for_each_prev_safe(cur, n, &list) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		list_del(&entries[i]);
+		i--;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, -1);
+	KUNIT_EXPECT_TRUE(test, list_empty(&list));
+}
+
+static void list_test_list_for_each_entry(struct kunit *test)
+{
+	struct list_test_struct entries[5], *cur;
+	LIST_HEAD(list);
+	int i = 0;
+
+	for (i = 0; i < 5; ++i) {
+		entries[i].data = i;
+		list_add_tail(&entries[i].list, &list);
+	}
+
+	i = 0;
+
+	list_for_each_entry(cur, &list, list) {
+		KUNIT_EXPECT_EQ(test, cur->data, i);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 5);
+}
+
+static void list_test_list_for_each_entry_reverse(struct kunit *test)
+{
+	struct list_test_struct entries[5], *cur;
+	LIST_HEAD(list);
+	int i = 0;
+
+	for (i = 0; i < 5; ++i) {
+		entries[i].data = i;
+		list_add_tail(&entries[i].list, &list);
+	}
+
+	i = 4;
+
+	list_for_each_entry_reverse(cur, &list, list) {
+		KUNIT_EXPECT_EQ(test, cur->data, i);
+		i--;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, -1);
+}
+
+static struct kunit_case list_test_cases[] = {
+	KUNIT_CASE(list_test_list_init),
+	KUNIT_CASE(list_test_list_add),
+	KUNIT_CASE(list_test_list_add_tail),
+	KUNIT_CASE(list_test_list_del),
+	KUNIT_CASE(list_test_list_replace),
+	KUNIT_CASE(list_test_list_replace_init),
+	KUNIT_CASE(list_test_list_swap),
+	KUNIT_CASE(list_test_list_del_init),
+	KUNIT_CASE(list_test_list_del_init_careful),
+	KUNIT_CASE(list_test_list_move),
+	KUNIT_CASE(list_test_list_move_tail),
+	KUNIT_CASE(list_test_list_bulk_move_tail),
+	KUNIT_CASE(list_test_list_is_head),
+	KUNIT_CASE(list_test_list_is_first),
+	KUNIT_CASE(list_test_list_is_last),
+	KUNIT_CASE(list_test_list_empty),
+	KUNIT_CASE(list_test_list_empty_careful),
+	KUNIT_CASE(list_test_list_rotate_left),
+	KUNIT_CASE(list_test_list_rotate_to_front),
+	KUNIT_CASE(list_test_list_is_singular),
+	KUNIT_CASE(list_test_list_cut_position),
+	KUNIT_CASE(list_test_list_cut_before),
+	KUNIT_CASE(list_test_list_splice),
+	KUNIT_CASE(list_test_list_splice_tail),
+	KUNIT_CASE(list_test_list_splice_init),
+	KUNIT_CASE(list_test_list_splice_tail_init),
+	KUNIT_CASE(list_test_list_entry),
+	KUNIT_CASE(list_test_list_entry_is_head),
+	KUNIT_CASE(list_test_list_first_entry),
+	KUNIT_CASE(list_test_list_last_entry),
+	KUNIT_CASE(list_test_list_first_entry_or_null),
+	KUNIT_CASE(list_test_list_next_entry),
+	KUNIT_CASE(list_test_list_prev_entry),
+	KUNIT_CASE(list_test_list_for_each),
+	KUNIT_CASE(list_test_list_for_each_prev),
+	KUNIT_CASE(list_test_list_for_each_safe),
+	KUNIT_CASE(list_test_list_for_each_prev_safe),
+	KUNIT_CASE(list_test_list_for_each_entry),
+	KUNIT_CASE(list_test_list_for_each_entry_reverse),
+	{},
+};
+
+static struct kunit_suite list_test_module = {
+	.name = "list-kunit-test",
+	.test_cases = list_test_cases,
+};
+
+struct hlist_test_struct {
+	int data;
+	struct hlist_node list;
+};
+
+static void hlist_test_init(struct kunit *test)
+{
+	/* Test the different ways of initialising a list. */
+	struct hlist_head list1 = HLIST_HEAD_INIT;
+	struct hlist_head list2;
+	HLIST_HEAD(list3);
+	struct hlist_head *list4;
+	struct hlist_head *list5;
+
+	INIT_HLIST_HEAD(&list2);
+
+	list4 = kzalloc(sizeof(*list4), GFP_KERNEL | __GFP_NOFAIL);
+	INIT_HLIST_HEAD(list4);
+
+	list5 = kmalloc(sizeof(*list5), GFP_KERNEL | __GFP_NOFAIL);
+	memset(list5, 0xFF, sizeof(*list5));
+	INIT_HLIST_HEAD(list5);
+
+	KUNIT_EXPECT_TRUE(test, hlist_empty(&list1));
+	KUNIT_EXPECT_TRUE(test, hlist_empty(&list2));
+	KUNIT_EXPECT_TRUE(test, hlist_empty(&list3));
+	KUNIT_EXPECT_TRUE(test, hlist_empty(list4));
+	KUNIT_EXPECT_TRUE(test, hlist_empty(list5));
+
+	kfree(list4);
+	kfree(list5);
+}
+
+static void hlist_test_unhashed(struct kunit *test)
+{
+	struct hlist_node a;
+	HLIST_HEAD(list);
+
+	INIT_HLIST_NODE(&a);
+
+	/* is unhashed by default */
+	KUNIT_EXPECT_TRUE(test, hlist_unhashed(&a));
+
+	hlist_add_head(&a, &list);
+
+	/* is hashed once added to list */
+	KUNIT_EXPECT_FALSE(test, hlist_unhashed(&a));
+
+	hlist_del_init(&a);
+
+	/* is again unhashed after del_init */
+	KUNIT_EXPECT_TRUE(test, hlist_unhashed(&a));
+}
+
+/* Doesn't test concurrency guarantees */
+static void hlist_test_unhashed_lockless(struct kunit *test)
+{
+	struct hlist_node a;
+	HLIST_HEAD(list);
+
+	INIT_HLIST_NODE(&a);
+
+	/* is unhashed by default */
+	KUNIT_EXPECT_TRUE(test, hlist_unhashed_lockless(&a));
+
+	hlist_add_head(&a, &list);
+
+	/* is hashed once added to list */
+	KUNIT_EXPECT_FALSE(test, hlist_unhashed_lockless(&a));
+
+	hlist_del_init(&a);
+
+	/* is again unhashed after del_init */
+	KUNIT_EXPECT_TRUE(test, hlist_unhashed_lockless(&a));
+}
+
+static void hlist_test_del(struct kunit *test)
+{
+	struct hlist_node a, b;
+	HLIST_HEAD(list);
+
+	hlist_add_head(&a, &list);
+	hlist_add_behind(&b, &a);
+
+	/* before: [list] -> a -> b */
+	hlist_del(&a);
+
+	/* now: [list] -> b */
+	KUNIT_EXPECT_PTR_EQ(test, list.first, &b);
+	KUNIT_EXPECT_PTR_EQ(test, b.pprev, &list.first);
+}
+
+static void hlist_test_del_init(struct kunit *test)
+{
+	struct hlist_node a, b;
+	HLIST_HEAD(list);
+
+	hlist_add_head(&a, &list);
+	hlist_add_behind(&b, &a);
+
+	/* before: [list] -> a -> b */
+	hlist_del_init(&a);
+
+	/* now: [list] -> b */
+	KUNIT_EXPECT_PTR_EQ(test, list.first, &b);
+	KUNIT_EXPECT_PTR_EQ(test, b.pprev, &list.first);
+
+	/* a is now initialised */
+	KUNIT_EXPECT_PTR_EQ(test, a.next, NULL);
+	KUNIT_EXPECT_PTR_EQ(test, a.pprev, NULL);
+}
+
+/* Tests all three hlist_add_* functions */
+static void hlist_test_add(struct kunit *test)
+{
+	struct hlist_node a, b, c, d;
+	HLIST_HEAD(list);
+
+	hlist_add_head(&a, &list);
+	hlist_add_head(&b, &list);
+	hlist_add_before(&c, &a);
+	hlist_add_behind(&d, &a);
+
+	/* should be [list] -> b -> c -> a -> d */
+	KUNIT_EXPECT_PTR_EQ(test, list.first, &b);
+
+	KUNIT_EXPECT_PTR_EQ(test, c.pprev, &(b.next));
+	KUNIT_EXPECT_PTR_EQ(test, b.next, &c);
+
+	KUNIT_EXPECT_PTR_EQ(test, a.pprev, &(c.next));
+	KUNIT_EXPECT_PTR_EQ(test, c.next, &a);
+
+	KUNIT_EXPECT_PTR_EQ(test, d.pprev, &(a.next));
+	KUNIT_EXPECT_PTR_EQ(test, a.next, &d);
+}
+
+/* Tests both hlist_fake() and hlist_add_fake() */
+static void hlist_test_fake(struct kunit *test)
+{
+	struct hlist_node a;
+
+	INIT_HLIST_NODE(&a);
+
+	/* not fake after init */
+	KUNIT_EXPECT_FALSE(test, hlist_fake(&a));
+
+	hlist_add_fake(&a);
+
+	/* is now fake */
+	KUNIT_EXPECT_TRUE(test, hlist_fake(&a));
+}
+
+static void hlist_test_is_singular_node(struct kunit *test)
+{
+	struct hlist_node a, b;
+	HLIST_HEAD(list);
+
+	INIT_HLIST_NODE(&a);
+	KUNIT_EXPECT_FALSE(test, hlist_is_singular_node(&a, &list));
+
+	hlist_add_head(&a, &list);
+	KUNIT_EXPECT_TRUE(test, hlist_is_singular_node(&a, &list));
+
+	hlist_add_head(&b, &list);
+	KUNIT_EXPECT_FALSE(test, hlist_is_singular_node(&a, &list));
+	KUNIT_EXPECT_FALSE(test, hlist_is_singular_node(&b, &list));
+}
+
+static void hlist_test_empty(struct kunit *test)
+{
+	struct hlist_node a;
+	HLIST_HEAD(list);
+
+	/* list starts off empty */
+	KUNIT_EXPECT_TRUE(test, hlist_empty(&list));
+
+	hlist_add_head(&a, &list);
+
+	/* list is no longer empty */
+	KUNIT_EXPECT_FALSE(test, hlist_empty(&list));
+}
+
+static void hlist_test_move_list(struct kunit *test)
+{
+	struct hlist_node a;
+	HLIST_HEAD(list1);
+	HLIST_HEAD(list2);
+
+	hlist_add_head(&a, &list1);
+
+	KUNIT_EXPECT_FALSE(test, hlist_empty(&list1));
+	KUNIT_EXPECT_TRUE(test, hlist_empty(&list2));
+	hlist_move_list(&list1, &list2);
+	KUNIT_EXPECT_TRUE(test, hlist_empty(&list1));
+	KUNIT_EXPECT_FALSE(test, hlist_empty(&list2));
+
+}
+
+static void hlist_test_entry(struct kunit *test)
+{
+	struct hlist_test_struct test_struct;
+
+	KUNIT_EXPECT_PTR_EQ(test, &test_struct,
+			    hlist_entry(&(test_struct.list),
+				struct hlist_test_struct, list));
+}
+
+static void hlist_test_entry_safe(struct kunit *test)
+{
+	struct hlist_test_struct test_struct;
+
+	KUNIT_EXPECT_PTR_EQ(test, &test_struct,
+			    hlist_entry_safe(&(test_struct.list),
+				struct hlist_test_struct, list));
+
+	KUNIT_EXPECT_PTR_EQ(test, NULL,
+			    hlist_entry_safe((struct hlist_node *)NULL,
+				struct hlist_test_struct, list));
+}
+
+static void hlist_test_for_each(struct kunit *test)
+{
+	struct hlist_node entries[3], *cur;
+	HLIST_HEAD(list);
+	int i = 0;
+
+	hlist_add_head(&entries[0], &list);
+	hlist_add_behind(&entries[1], &entries[0]);
+	hlist_add_behind(&entries[2], &entries[1]);
+
+	hlist_for_each(cur, &list) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 3);
+}
+
+
+static void hlist_test_for_each_safe(struct kunit *test)
+{
+	struct hlist_node entries[3], *cur, *n;
+	HLIST_HEAD(list);
+	int i = 0;
+
+	hlist_add_head(&entries[0], &list);
+	hlist_add_behind(&entries[1], &entries[0]);
+	hlist_add_behind(&entries[2], &entries[1]);
+
+	hlist_for_each_safe(cur, n, &list) {
+		KUNIT_EXPECT_PTR_EQ(test, cur, &entries[i]);
+		hlist_del(&entries[i]);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 3);
+	KUNIT_EXPECT_TRUE(test, hlist_empty(&list));
+}
+
+static void hlist_test_for_each_entry(struct kunit *test)
+{
+	struct hlist_test_struct entries[5], *cur;
+	HLIST_HEAD(list);
+	int i = 0;
+
+	entries[0].data = 0;
+	hlist_add_head(&entries[0].list, &list);
+	for (i = 1; i < 5; ++i) {
+		entries[i].data = i;
+		hlist_add_behind(&entries[i].list, &entries[i-1].list);
+	}
+
+	i = 0;
+
+	hlist_for_each_entry(cur, &list, list) {
+		KUNIT_EXPECT_EQ(test, cur->data, i);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 5);
+}
+
+static void hlist_test_for_each_entry_continue(struct kunit *test)
+{
+	struct hlist_test_struct entries[5], *cur;
+	HLIST_HEAD(list);
+	int i = 0;
+
+	entries[0].data = 0;
+	hlist_add_head(&entries[0].list, &list);
+	for (i = 1; i < 5; ++i) {
+		entries[i].data = i;
+		hlist_add_behind(&entries[i].list, &entries[i-1].list);
+	}
+
+	/* We skip the first (zero-th) entry. */
+	i = 1;
+
+	cur = &entries[0];
+	hlist_for_each_entry_continue(cur, list) {
+		KUNIT_EXPECT_EQ(test, cur->data, i);
+		/* Stamp over the entry. */
+		cur->data = 42;
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 5);
+	/* The first entry was not visited. */
+	KUNIT_EXPECT_EQ(test, entries[0].data, 0);
+	/* The second (and presumably others), were. */
+	KUNIT_EXPECT_EQ(test, entries[1].data, 42);
+}
+
+static void hlist_test_for_each_entry_from(struct kunit *test)
+{
+	struct hlist_test_struct entries[5], *cur;
+	HLIST_HEAD(list);
+	int i = 0;
+
+	entries[0].data = 0;
+	hlist_add_head(&entries[0].list, &list);
+	for (i = 1; i < 5; ++i) {
+		entries[i].data = i;
+		hlist_add_behind(&entries[i].list, &entries[i-1].list);
+	}
+
+	i = 0;
+
+	cur = &entries[0];
+	hlist_for_each_entry_from(cur, list) {
+		KUNIT_EXPECT_EQ(test, cur->data, i);
+		/* Stamp over the entry. */
+		cur->data = 42;
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 5);
+	/* The first entry was visited. */
+	KUNIT_EXPECT_EQ(test, entries[0].data, 42);
+}
+
+static void hlist_test_for_each_entry_safe(struct kunit *test)
+{
+	struct hlist_test_struct entries[5], *cur;
+	struct hlist_node *tmp_node;
+	HLIST_HEAD(list);
+	int i = 0;
+
+	entries[0].data = 0;
+	hlist_add_head(&entries[0].list, &list);
+	for (i = 1; i < 5; ++i) {
+		entries[i].data = i;
+		hlist_add_behind(&entries[i].list, &entries[i-1].list);
+	}
+
+	i = 0;
+
+	hlist_for_each_entry_safe(cur, tmp_node, &list, list) {
+		KUNIT_EXPECT_EQ(test, cur->data, i);
+		hlist_del(&cur->list);
+		i++;
+	}
+
+	KUNIT_EXPECT_EQ(test, i, 5);
+	KUNIT_EXPECT_TRUE(test, hlist_empty(&list));
+}
+
+
+static struct kunit_case hlist_test_cases[] = {
+	KUNIT_CASE(hlist_test_init),
+	KUNIT_CASE(hlist_test_unhashed),
+	KUNIT_CASE(hlist_test_unhashed_lockless),
+	KUNIT_CASE(hlist_test_del),
+	KUNIT_CASE(hlist_test_del_init),
+	KUNIT_CASE(hlist_test_add),
+	KUNIT_CASE(hlist_test_fake),
+	KUNIT_CASE(hlist_test_is_singular_node),
+	KUNIT_CASE(hlist_test_empty),
+	KUNIT_CASE(hlist_test_move_list),
+	KUNIT_CASE(hlist_test_entry),
+	KUNIT_CASE(hlist_test_entry_safe),
+	KUNIT_CASE(hlist_test_for_each),
+	KUNIT_CASE(hlist_test_for_each_safe),
+	KUNIT_CASE(hlist_test_for_each_entry),
+	KUNIT_CASE(hlist_test_for_each_entry_continue),
+	KUNIT_CASE(hlist_test_for_each_entry_from),
+	KUNIT_CASE(hlist_test_for_each_entry_safe),
+	{},
+};
+
+static struct kunit_suite hlist_test_module = {
+	.name = "hlist",
+	.test_cases = hlist_test_cases,
+};
+
+
+static int node_count;
+static struct klist_node *last_node;
+
+static void check_node(struct klist_node *node_ptr)
+{
+	node_count++;
+	last_node = node_ptr;
+}
+
+static void check_delete_node(struct klist_node *node_ptr)
+{
+	node_count--;
+	last_node = node_ptr;
+}
+
+static void klist_test_add_tail(struct kunit *test)
+{
+	struct klist_node a, b;
+	struct klist mylist;
+	struct klist_iter i;
+
+	node_count = 0;
+	klist_init(&mylist, &check_node, NULL);
+
+	klist_add_tail(&a, &mylist);
+	KUNIT_EXPECT_EQ(test, node_count, 1);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &a);
+
+	klist_add_tail(&b, &mylist);
+	KUNIT_EXPECT_EQ(test, node_count, 2);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &b);
+
+	/* should be [list] -> a -> b */
+	klist_iter_init(&mylist, &i);
+
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+	KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+	klist_iter_exit(&i);
+
+}
+
+static void klist_test_add_head(struct kunit *test)
+{
+	struct klist_node a, b;
+	struct klist mylist;
+	struct klist_iter i;
+
+	node_count = 0;
+	klist_init(&mylist, &check_node, NULL);
+
+	klist_add_head(&a, &mylist);
+	KUNIT_EXPECT_EQ(test, node_count, 1);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &a);
+
+	klist_add_head(&b, &mylist);
+	KUNIT_EXPECT_EQ(test, node_count, 2);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &b);
+
+	/* should be [list] -> b -> a */
+	klist_iter_init(&mylist, &i);
+
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+	KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+	klist_iter_exit(&i);
+
+}
+
+static void klist_test_add_behind(struct kunit *test)
+{
+	struct klist_node a, b, c, d;
+	struct klist mylist;
+	struct klist_iter i;
+
+	node_count = 0;
+	klist_init(&mylist, &check_node, NULL);
+
+	klist_add_head(&a, &mylist);
+	klist_add_head(&b, &mylist);
+
+	klist_add_behind(&c, &a);
+	KUNIT_EXPECT_EQ(test, node_count, 3);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
+
+	klist_add_behind(&d, &b);
+	KUNIT_EXPECT_EQ(test, node_count, 4);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
+
+	klist_iter_init(&mylist, &i);
+
+	/* should be [list] -> b -> d -> a -> c*/
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
+	KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+	klist_iter_exit(&i);
+
+}
+
+static void klist_test_add_before(struct kunit *test)
+{
+	struct klist_node a, b, c, d;
+	struct klist mylist;
+	struct klist_iter i;
+
+	node_count = 0;
+	klist_init(&mylist, &check_node, NULL);
+
+	klist_add_head(&a, &mylist);
+	klist_add_head(&b, &mylist);
+	klist_add_before(&c, &a);
+	KUNIT_EXPECT_EQ(test, node_count, 3);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
+
+	klist_add_before(&d, &b);
+	KUNIT_EXPECT_EQ(test, node_count, 4);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
+
+	klist_iter_init(&mylist, &i);
+
+	/* should be [list] -> b -> d -> a -> c*/
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+	KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+	klist_iter_exit(&i);
+
+}
+
+/*
+ * Verify that klist_del() delays the deletion of a node until there
+ * are no other references to it
+ */
+static void klist_test_del_refcount_greater_than_zero(struct kunit *test)
+{
+	struct klist_node a, b, c, d;
+	struct klist mylist;
+	struct klist_iter i;
+
+	node_count = 0;
+	klist_init(&mylist, &check_node, &check_delete_node);
+
+	/* Add nodes a,b,c,d to the list*/
+	klist_add_tail(&a, &mylist);
+	klist_add_tail(&b, &mylist);
+	klist_add_tail(&c, &mylist);
+	klist_add_tail(&d, &mylist);
+
+	klist_iter_init(&mylist, &i);
+
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+	/* Advance the iterator to point to node c*/
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &c);
+
+	/* Try to delete node c while there is a reference to it*/
+	klist_del(&c);
+
+	/*
+	 * Verify that node c is still attached to the list even after being
+	 * deleted. Since the iterator still points to c, the reference count is not
+	 * decreased to 0
+	 */
+	KUNIT_EXPECT_TRUE(test, klist_node_attached(&c));
+
+	/* Check that node c has not been removed yet*/
+	KUNIT_EXPECT_EQ(test, node_count, 4);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &d);
+
+	klist_iter_exit(&i);
+
+	/*
+	 * Since the iterator is no longer pointing to node c, node c is removed
+	 * from the list
+	 */
+	KUNIT_EXPECT_EQ(test, node_count, 3);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
+
+}
+
+/*
+ * Verify that klist_del() deletes a node immediately when there are no
+ * other references to it.
+ */
+static void klist_test_del_refcount_zero(struct kunit *test)
+{
+	struct klist_node a, b, c, d;
+	struct klist mylist;
+	struct klist_iter i;
+
+	node_count = 0;
+	klist_init(&mylist, &check_node, &check_delete_node);
+
+	/* Add nodes a,b,c,d to the list*/
+	klist_add_tail(&a, &mylist);
+	klist_add_tail(&b, &mylist);
+	klist_add_tail(&c, &mylist);
+	klist_add_tail(&d, &mylist);
+	/* Delete node c*/
+	klist_del(&c);
+
+	/* Check that node c is deleted from the list*/
+	KUNIT_EXPECT_EQ(test, node_count, 3);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
+
+	/* Should be [list] -> a -> b -> d*/
+	klist_iter_init(&mylist, &i);
+
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
+	KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+	klist_iter_exit(&i);
+
+}
+
+static void klist_test_remove(struct kunit *test)
+{
+	/* This test doesn't check correctness under concurrent access */
+	struct klist_node a, b, c, d;
+	struct klist mylist;
+	struct klist_iter i;
+
+	node_count = 0;
+	klist_init(&mylist, &check_node, &check_delete_node);
+
+	/* Add nodes a,b,c,d to the list*/
+	klist_add_tail(&a, &mylist);
+	klist_add_tail(&b, &mylist);
+	klist_add_tail(&c, &mylist);
+	klist_add_tail(&d, &mylist);
+	/* Delete node c*/
+	klist_remove(&c);
+
+	/* Check the nodes in the list*/
+	KUNIT_EXPECT_EQ(test, node_count, 3);
+	KUNIT_EXPECT_PTR_EQ(test, last_node, &c);
+
+	/* should be [list] -> a -> b -> d*/
+	klist_iter_init(&mylist, &i);
+
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &a);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &b);
+	KUNIT_EXPECT_PTR_EQ(test, klist_next(&i), &d);
+	KUNIT_EXPECT_NULL(test, klist_next(&i));
+
+	klist_iter_exit(&i);
+
+}
+
+static void klist_test_node_attached(struct kunit *test)
+{
+	struct klist_node a = {};
+	struct klist mylist;
+
+	klist_init(&mylist, NULL, NULL);
+
+	KUNIT_EXPECT_FALSE(test, klist_node_attached(&a));
+	klist_add_head(&a, &mylist);
+	KUNIT_EXPECT_TRUE(test, klist_node_attached(&a));
+	klist_del(&a);
+	KUNIT_EXPECT_FALSE(test, klist_node_attached(&a));
+
+}
+
+static struct kunit_case klist_test_cases[] = {
+	KUNIT_CASE(klist_test_add_tail),
+	KUNIT_CASE(klist_test_add_head),
+	KUNIT_CASE(klist_test_add_behind),
+	KUNIT_CASE(klist_test_add_before),
+	KUNIT_CASE(klist_test_del_refcount_greater_than_zero),
+	KUNIT_CASE(klist_test_del_refcount_zero),
+	KUNIT_CASE(klist_test_remove),
+	KUNIT_CASE(klist_test_node_attached),
+	{},
+};
+
+static struct kunit_suite klist_test_module = {
+	.name = "klist",
+	.test_cases = klist_test_cases,
+};
+
+kunit_test_suites(&list_test_module, &hlist_test_module, &klist_test_module);
+
+MODULE_DESCRIPTION("KUnit test for the Kernel Linked-list structures");
+MODULE_LICENSE("GPL v2");
diff --git a/lib/tests/Makefile a/lib/tests/Makefile
new file mode 100644
--- /dev/null
+++ a/lib/tests/Makefile
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for tests of kernel library functions.
+
+# KUnit tests
+CFLAGS_bitfield_kunit.o := $(DISABLE_STRUCTLEAK_PLUGIN)
+obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o
+obj-$(CONFIG_CHECKSUM_KUNIT) += checksum_kunit.o
+obj-$(CONFIG_LIST_KUNIT_TEST) += list-test.o
+obj-$(CONFIG_HASHTABLE_KUNIT_TEST) += hashtable_test.o
+obj-$(CONFIG_LINEAR_RANGES_TEST) += test_linear_ranges.o
+obj-$(CONFIG_BITS_TEST) += test_bits.o
+obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o
+obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o
+obj-$(CONFIG_MEMCPY_KUNIT_TEST) += memcpy_kunit.o
+obj-$(CONFIG_IS_SIGNED_TYPE_KUNIT_TEST) += is_signed_type_kunit.o
+CFLAGS_overflow_kunit.o = $(call cc-disable-warning, tautological-constant-out-of-range-compare)
+obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o
+CFLAGS_stackinit_kunit.o += $(call cc-disable-warning, switch-unreachable)
+obj-$(CONFIG_STACKINIT_KUNIT_TEST) += stackinit_kunit.o
+CFLAGS_fortify_kunit.o += $(call cc-disable-warning, unsequenced)
+CFLAGS_fortify_kunit.o += $(call cc-disable-warning, stringop-overread)
+CFLAGS_fortify_kunit.o += $(call cc-disable-warning, stringop-truncation)
+CFLAGS_fortify_kunit.o += $(DISABLE_STRUCTLEAK_PLUGIN)
+obj-$(CONFIG_FORTIFY_KUNIT_TEST) += fortify_kunit.o
+obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o
+obj-$(CONFIG_USERCOPY_KUNIT_TEST) += usercopy_kunit.o
+obj-$(CONFIG_CRC16_KUNIT_TEST) += crc16_kunit.o
diff --git a/lib/tests/memcpy_kunit.c a/lib/tests/memcpy_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/memcpy_kunit.c
@@ -0,0 +1,514 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test cases for memcpy(), memmove(), and memset().
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <kunit/test.h>
+#include <linux/device.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/overflow.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+struct some_bytes {
+	union {
+		u8 data[32];
+		struct {
+			u32 one;
+			u16 two;
+			u8  three;
+			/* 1 byte hole */
+			u32 four[4];
+		};
+	};
+};
+
+#define check(instance, v) do {	\
+	BUILD_BUG_ON(sizeof(instance.data) != 32);	\
+	for (size_t i = 0; i < sizeof(instance.data); i++) {	\
+		KUNIT_ASSERT_EQ_MSG(test, instance.data[i], v, \
+			"line %d: '%s' not initialized to 0x%02x @ %zu (saw 0x%02x)\n", \
+			__LINE__, #instance, v, i, instance.data[i]);	\
+	}	\
+} while (0)
+
+#define compare(name, one, two) do { \
+	BUILD_BUG_ON(sizeof(one) != sizeof(two)); \
+	for (size_t i = 0; i < sizeof(one); i++) {	\
+		KUNIT_EXPECT_EQ_MSG(test, one.data[i], two.data[i], \
+			"line %d: %s.data[%zu] (0x%02x) != %s.data[%zu] (0x%02x)\n", \
+			__LINE__, #one, i, one.data[i], #two, i, two.data[i]); \
+	}	\
+	kunit_info(test, "ok: " TEST_OP "() " name "\n");	\
+} while (0)
+
+static void memcpy_test(struct kunit *test)
+{
+#define TEST_OP "memcpy"
+	struct some_bytes control = {
+		.data = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+			},
+	};
+	struct some_bytes zero = { };
+	struct some_bytes middle = {
+		.data = { 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+			  0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
+			  0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
+			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+			},
+	};
+	struct some_bytes three = {
+		.data = { 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+			  0x20, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20,
+			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+			  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+			},
+	};
+	struct some_bytes dest = { };
+	int count;
+	u8 *ptr;
+
+	/* Verify static initializers. */
+	check(control, 0x20);
+	check(zero, 0);
+	compare("static initializers", dest, zero);
+
+	/* Verify assignment. */
+	dest = control;
+	compare("direct assignment", dest, control);
+
+	/* Verify complete overwrite. */
+	memcpy(dest.data, zero.data, sizeof(dest.data));
+	compare("complete overwrite", dest, zero);
+
+	/* Verify middle overwrite. */
+	dest = control;
+	memcpy(dest.data + 12, zero.data, 7);
+	compare("middle overwrite", dest, middle);
+
+	/* Verify argument side-effects aren't repeated. */
+	dest = control;
+	ptr = dest.data;
+	count = 1;
+	memcpy(ptr++, zero.data, count++);
+	ptr += 8;
+	memcpy(ptr++, zero.data, count++);
+	compare("argument side-effects", dest, three);
+#undef TEST_OP
+}
+
+static unsigned char larger_array [2048];
+
+static void memmove_test(struct kunit *test)
+{
+#define TEST_OP "memmove"
+	struct some_bytes control = {
+		.data = { 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			},
+	};
+	struct some_bytes zero = { };
+	struct some_bytes middle = {
+		.data = { 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			  0x99, 0x99, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00,
+			  0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x99,
+			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			},
+	};
+	struct some_bytes five = {
+		.data = { 0x00, 0x00, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			  0x99, 0x99, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99,
+			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			},
+	};
+	struct some_bytes overlap = {
+		.data = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			},
+	};
+	struct some_bytes overlap_expected = {
+		.data = { 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x04, 0x07,
+			  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			  0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
+			},
+	};
+	struct some_bytes dest = { };
+	int count;
+	u8 *ptr;
+
+	/* Verify static initializers. */
+	check(control, 0x99);
+	check(zero, 0);
+	compare("static initializers", zero, dest);
+
+	/* Verify assignment. */
+	dest = control;
+	compare("direct assignment", dest, control);
+
+	/* Verify complete overwrite. */
+	memmove(dest.data, zero.data, sizeof(dest.data));
+	compare("complete overwrite", dest, zero);
+
+	/* Verify middle overwrite. */
+	dest = control;
+	memmove(dest.data + 12, zero.data, 7);
+	compare("middle overwrite", dest, middle);
+
+	/* Verify argument side-effects aren't repeated. */
+	dest = control;
+	ptr = dest.data;
+	count = 2;
+	memmove(ptr++, zero.data, count++);
+	ptr += 9;
+	memmove(ptr++, zero.data, count++);
+	compare("argument side-effects", dest, five);
+
+	/* Verify overlapping overwrite is correct. */
+	ptr = &overlap.data[2];
+	memmove(ptr, overlap.data, 5);
+	compare("overlapping write", overlap, overlap_expected);
+
+	/* Verify larger overlapping moves. */
+	larger_array[256] = 0xAAu;
+	/*
+	 * Test a backwards overlapping memmove first. 256 and 1024 are
+	 * important for i386 to use rep movsl.
+	 */
+	memmove(larger_array, larger_array + 256, 1024);
+	KUNIT_ASSERT_EQ(test, larger_array[0], 0xAAu);
+	KUNIT_ASSERT_EQ(test, larger_array[256], 0x00);
+	KUNIT_ASSERT_NULL(test,
+		memchr(larger_array + 1, 0xaa, ARRAY_SIZE(larger_array) - 1));
+	/* Test a forwards overlapping memmove. */
+	larger_array[0] = 0xBBu;
+	memmove(larger_array + 256, larger_array, 1024);
+	KUNIT_ASSERT_EQ(test, larger_array[0], 0xBBu);
+	KUNIT_ASSERT_EQ(test, larger_array[256], 0xBBu);
+	KUNIT_ASSERT_NULL(test, memchr(larger_array + 1, 0xBBu, 256 - 1));
+	KUNIT_ASSERT_NULL(test,
+		memchr(larger_array + 257, 0xBBu, ARRAY_SIZE(larger_array) - 257));
+#undef TEST_OP
+}
+
+static void memset_test(struct kunit *test)
+{
+#define TEST_OP "memset"
+	struct some_bytes control = {
+		.data = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+			},
+	};
+	struct some_bytes complete = {
+		.data = { 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, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+			},
+	};
+	struct some_bytes middle = {
+		.data = { 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31,
+			  0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
+			  0x31, 0x31, 0x31, 0x31, 0x30, 0x30, 0x30, 0x30,
+			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+			},
+	};
+	struct some_bytes three = {
+		.data = { 0x60, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+			  0x30, 0x61, 0x61, 0x30, 0x30, 0x30, 0x30, 0x30,
+			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+			  0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+			},
+	};
+	struct some_bytes after = {
+		.data = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x72,
+			  0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
+			  0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
+			  0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72, 0x72,
+			},
+	};
+	struct some_bytes startat = {
+		.data = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+			  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+			  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+			  0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79, 0x79,
+			},
+	};
+	struct some_bytes dest = { };
+	int count, value;
+	u8 *ptr;
+
+	/* Verify static initializers. */
+	check(control, 0x30);
+	check(dest, 0);
+
+	/* Verify assignment. */
+	dest = control;
+	compare("direct assignment", dest, control);
+
+	/* Verify complete overwrite. */
+	memset(dest.data, 0xff, sizeof(dest.data));
+	compare("complete overwrite", dest, complete);
+
+	/* Verify middle overwrite. */
+	dest = control;
+	memset(dest.data + 4, 0x31, 16);
+	compare("middle overwrite", dest, middle);
+
+	/* Verify argument side-effects aren't repeated. */
+	dest = control;
+	ptr = dest.data;
+	value = 0x60;
+	count = 1;
+	memset(ptr++, value++, count++);
+	ptr += 8;
+	memset(ptr++, value++, count++);
+	compare("argument side-effects", dest, three);
+
+	/* Verify memset_after() */
+	dest = control;
+	memset_after(&dest, 0x72, three);
+	compare("memset_after()", dest, after);
+
+	/* Verify memset_startat() */
+	dest = control;
+	memset_startat(&dest, 0x79, four);
+	compare("memset_startat()", dest, startat);
+#undef TEST_OP
+}
+
+static u8 large_src[1024];
+static u8 large_dst[2048];
+static const u8 large_zero[2048];
+
+static void set_random_nonzero(struct kunit *test, u8 *byte)
+{
+	int failed_rng = 0;
+
+	while (*byte == 0) {
+		get_random_bytes(byte, 1);
+		KUNIT_ASSERT_LT_MSG(test, failed_rng++, 100,
+				    "Is the RNG broken?");
+	}
+}
+
+static void init_large(struct kunit *test)
+{
+	/* Get many bit patterns. */
+	get_random_bytes(large_src, ARRAY_SIZE(large_src));
+
+	/* Make sure we have non-zero edges. */
+	set_random_nonzero(test, &large_src[0]);
+	set_random_nonzero(test, &large_src[ARRAY_SIZE(large_src) - 1]);
+
+	/* Explicitly zero the entire destination. */
+	memset(large_dst, 0, ARRAY_SIZE(large_dst));
+}
+
+/*
+ * Instead of an indirect function call for "copy" or a giant macro,
+ * use a bool to pick memcpy or memmove.
+ */
+static void copy_large_test(struct kunit *test, bool use_memmove)
+{
+	init_large(test);
+
+	/* Copy a growing number of non-overlapping bytes ... */
+	for (int bytes = 1; bytes <= ARRAY_SIZE(large_src); bytes++) {
+		/* Over a shifting destination window ... */
+		for (int offset = 0; offset < ARRAY_SIZE(large_src); offset++) {
+			int right_zero_pos = offset + bytes;
+			int right_zero_size = ARRAY_SIZE(large_dst) - right_zero_pos;
+
+			/* Copy! */
+			if (use_memmove)
+				memmove(large_dst + offset, large_src, bytes);
+			else
+				memcpy(large_dst + offset, large_src, bytes);
+
+			/* Did we touch anything before the copy area? */
+			KUNIT_ASSERT_EQ_MSG(test,
+				memcmp(large_dst, large_zero, offset), 0,
+				"with size %d at offset %d", bytes, offset);
+			/* Did we touch anything after the copy area? */
+			KUNIT_ASSERT_EQ_MSG(test,
+				memcmp(&large_dst[right_zero_pos], large_zero, right_zero_size), 0,
+				"with size %d at offset %d", bytes, offset);
+
+			/* Are we byte-for-byte exact across the copy? */
+			KUNIT_ASSERT_EQ_MSG(test,
+				memcmp(large_dst + offset, large_src, bytes), 0,
+				"with size %d at offset %d", bytes, offset);
+
+			/* Zero out what we copied for the next cycle. */
+			memset(large_dst + offset, 0, bytes);
+		}
+		/* Avoid stall warnings if this loop gets slow. */
+		cond_resched();
+	}
+}
+
+static void memcpy_large_test(struct kunit *test)
+{
+	copy_large_test(test, false);
+}
+
+static void memmove_large_test(struct kunit *test)
+{
+	copy_large_test(test, true);
+}
+
+/*
+ * On the assumption that boundary conditions are going to be the most
+ * sensitive, instead of taking a full step (inc) each iteration,
+ * take single index steps for at least the first "inc"-many indexes
+ * from the "start" and at least the last "inc"-many indexes before
+ * the "end". When in the middle, take full "inc"-wide steps. For
+ * example, calling next_step(idx, 1, 15, 3) with idx starting at 0
+ * would see the following pattern: 1 2 3 4 7 10 11 12 13 14 15.
+ */
+static int next_step(int idx, int start, int end, int inc)
+{
+	start += inc;
+	end -= inc;
+
+	if (idx < start || idx + inc > end)
+		inc = 1;
+	return idx + inc;
+}
+
+static void inner_loop(struct kunit *test, int bytes, int d_off, int s_off)
+{
+	int left_zero_pos, left_zero_size;
+	int right_zero_pos, right_zero_size;
+	int src_pos, src_orig_pos, src_size;
+	int pos;
+
+	/* Place the source in the destination buffer. */
+	memcpy(&large_dst[s_off], large_src, bytes);
+
+	/* Copy to destination offset. */
+	memmove(&large_dst[d_off], &large_dst[s_off], bytes);
+
+	/* Make sure destination entirely matches. */
+	KUNIT_ASSERT_EQ_MSG(test, memcmp(&large_dst[d_off], large_src, bytes), 0,
+		"with size %d at src offset %d and dest offset %d",
+		bytes, s_off, d_off);
+
+	/* Calculate the expected zero spans. */
+	if (s_off < d_off) {
+		left_zero_pos = 0;
+		left_zero_size = s_off;
+
+		right_zero_pos = d_off + bytes;
+		right_zero_size = ARRAY_SIZE(large_dst) - right_zero_pos;
+
+		src_pos = s_off;
+		src_orig_pos = 0;
+		src_size = d_off - s_off;
+	} else {
+		left_zero_pos = 0;
+		left_zero_size = d_off;
+
+		right_zero_pos = s_off + bytes;
+		right_zero_size = ARRAY_SIZE(large_dst) - right_zero_pos;
+
+		src_pos = d_off + bytes;
+		src_orig_pos = src_pos - s_off;
+		src_size = right_zero_pos - src_pos;
+	}
+
+	/* Check non-overlapping source is unchanged.*/
+	KUNIT_ASSERT_EQ_MSG(test,
+		memcmp(&large_dst[src_pos], &large_src[src_orig_pos], src_size), 0,
+		"with size %d at src offset %d and dest offset %d",
+		bytes, s_off, d_off);
+
+	/* Check leading buffer contents are zero. */
+	KUNIT_ASSERT_EQ_MSG(test,
+		memcmp(&large_dst[left_zero_pos], large_zero, left_zero_size), 0,
+		"with size %d at src offset %d and dest offset %d",
+		bytes, s_off, d_off);
+	/* Check trailing buffer contents are zero. */
+	KUNIT_ASSERT_EQ_MSG(test,
+		memcmp(&large_dst[right_zero_pos], large_zero, right_zero_size), 0,
+		"with size %d at src offset %d and dest offset %d",
+		bytes, s_off, d_off);
+
+	/* Zero out everything not already zeroed.*/
+	pos = left_zero_pos + left_zero_size;
+	memset(&large_dst[pos], 0, right_zero_pos - pos);
+}
+
+static void memmove_overlap_test(struct kunit *test)
+{
+	/*
+	 * Running all possible offset and overlap combinations takes a
+	 * very long time. Instead, only check up to 128 bytes offset
+	 * into the destination buffer (which should result in crossing
+	 * cachelines), with a step size of 1 through 7 to try to skip some
+	 * redundancy.
+	 */
+	static const int offset_max = 128; /* less than ARRAY_SIZE(large_src); */
+	static const int bytes_step = 7;
+	static const int window_step = 7;
+
+	static const int bytes_start = 1;
+	static const int bytes_end = ARRAY_SIZE(large_src) + 1;
+
+	init_large(test);
+
+	/* Copy a growing number of overlapping bytes ... */
+	for (int bytes = bytes_start; bytes < bytes_end;
+	     bytes = next_step(bytes, bytes_start, bytes_end, bytes_step)) {
+
+		/* Over a shifting destination window ... */
+		for (int d_off = 0; d_off < offset_max; d_off++) {
+			int s_start = max(d_off - bytes, 0);
+			int s_end = min_t(int, d_off + bytes, ARRAY_SIZE(large_src));
+
+			/* Over a shifting source window ... */
+			for (int s_off = s_start; s_off < s_end;
+			     s_off = next_step(s_off, s_start, s_end, window_step))
+				inner_loop(test, bytes, d_off, s_off);
+
+			/* Avoid stall warnings. */
+			cond_resched();
+		}
+	}
+}
+
+static struct kunit_case memcpy_test_cases[] = {
+	KUNIT_CASE(memset_test),
+	KUNIT_CASE(memcpy_test),
+	KUNIT_CASE_SLOW(memcpy_large_test),
+	KUNIT_CASE_SLOW(memmove_test),
+	KUNIT_CASE_SLOW(memmove_large_test),
+	KUNIT_CASE_SLOW(memmove_overlap_test),
+	{}
+};
+
+static struct kunit_suite memcpy_test_suite = {
+	.name = "memcpy",
+	.test_cases = memcpy_test_cases,
+};
+
+kunit_test_suite(memcpy_test_suite);
+
+MODULE_DESCRIPTION("test cases for memcpy(), memmove(), and memset()");
+MODULE_LICENSE("GPL");
diff --git a/lib/test_sort.c a/lib/test_sort.c
deleted file mode 100644
--- a/lib/test_sort.c
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-
-#include <kunit/test.h>
-
-#include <linux/sort.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-
-/* a simple boot-time regression test */
-
-#define TEST_LEN 1000
-
-static int cmpint(const void *a, const void *b)
-{
-	return *(int *)a - *(int *)b;
-}
-
-static void test_sort(struct kunit *test)
-{
-	int *a, i, r = 1;
-
-	a = kunit_kmalloc_array(test, TEST_LEN, sizeof(*a), GFP_KERNEL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, a);
-
-	for (i = 0; i < TEST_LEN; i++) {
-		r = (r * 725861) % 6599;
-		a[i] = r;
-	}
-
-	sort(a, TEST_LEN, sizeof(*a), cmpint, NULL);
-
-	for (i = 0; i < TEST_LEN - 1; i++)
-		KUNIT_ASSERT_LE(test, a[i], a[i + 1]);
-
-	r = 48;
-
-	for (i = 0; i < TEST_LEN - 1; i++) {
-		r = (r * 725861) % 6599;
-		a[i] = r;
-	}
-
-	sort(a, TEST_LEN - 1, sizeof(*a), cmpint, NULL);
-
-	for (i = 0; i < TEST_LEN - 2; i++)
-		KUNIT_ASSERT_LE(test, a[i], a[i + 1]);
-}
-
-static struct kunit_case sort_test_cases[] = {
-	KUNIT_CASE(test_sort),
-	{}
-};
-
-static struct kunit_suite sort_test_suite = {
-	.name = "lib_sort",
-	.test_cases = sort_test_cases,
-};
-
-kunit_test_suites(&sort_test_suite);
-
-MODULE_DESCRIPTION("sort() KUnit test suite");
-MODULE_LICENSE("GPL");
diff --git a/lib/tests/overflow_kunit.c a/lib/tests/overflow_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/overflow_kunit.c
@@ -0,0 +1,1240 @@
+// SPDX-License-Identifier: GPL-2.0 OR MIT
+/*
+ * Test cases for arithmetic overflow checks. See:
+ * "Running tests with kunit_tool" at Documentation/dev-tools/kunit/start.rst
+ *	./tools/testing/kunit/kunit.py run overflow [--raw_output]
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <kunit/device.h>
+#include <kunit/test.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/overflow.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/vmalloc.h>
+
+#define SKIP(cond, reason)		do {			\
+	if (cond) {						\
+		kunit_skip(test, reason);			\
+		return;						\
+	}							\
+} while (0)
+
+/*
+ * Clang 11 and earlier generate unwanted libcalls for signed output
+ * on unsigned input.
+ */
+#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 11
+# define SKIP_SIGN_MISMATCH(t)	SKIP(t, "Clang 11 unwanted libcalls")
+#else
+# define SKIP_SIGN_MISMATCH(t)	do { } while (0)
+#endif
+
+/*
+ * Clang 13 and earlier generate unwanted libcalls for 64-bit tests on
+ * 32-bit hosts.
+ */
+#if defined(CONFIG_CC_IS_CLANG) && __clang_major__ <= 13 &&	\
+    BITS_PER_LONG != 64
+# define SKIP_64_ON_32(t)	SKIP(t, "Clang 13 unwanted libcalls")
+#else
+# define SKIP_64_ON_32(t)	do { } while (0)
+#endif
+
+#define DEFINE_TEST_ARRAY_TYPED(t1, t2, t)			\
+	static const struct test_ ## t1 ## _ ## t2 ## __ ## t {	\
+		t1 a;						\
+		t2 b;						\
+		t sum, diff, prod;				\
+		bool s_of, d_of, p_of;				\
+	} t1 ## _ ## t2 ## __ ## t ## _tests[]
+
+#define DEFINE_TEST_ARRAY(t)	DEFINE_TEST_ARRAY_TYPED(t, t, t)
+
+DEFINE_TEST_ARRAY(u8) = {
+	{0, 0, 0, 0, 0, false, false, false},
+	{1, 1, 2, 0, 1, false, false, false},
+	{0, 1, 1, U8_MAX, 0, false, true, false},
+	{1, 0, 1, 1, 0, false, false, false},
+	{0, U8_MAX, U8_MAX, 1, 0, false, true, false},
+	{U8_MAX, 0, U8_MAX, U8_MAX, 0, false, false, false},
+	{1, U8_MAX, 0, 2, U8_MAX, true, true, false},
+	{U8_MAX, 1, 0, U8_MAX-1, U8_MAX, true, false, false},
+	{U8_MAX, U8_MAX, U8_MAX-1, 0, 1, true, false, true},
+
+	{U8_MAX, U8_MAX-1, U8_MAX-2, 1, 2, true, false, true},
+	{U8_MAX-1, U8_MAX, U8_MAX-2, U8_MAX, 2, true, true, true},
+
+	{1U << 3, 1U << 3, 1U << 4, 0, 1U << 6, false, false, false},
+	{1U << 4, 1U << 4, 1U << 5, 0, 0, false, false, true},
+	{1U << 4, 1U << 3, 3*(1U << 3), 1U << 3, 1U << 7, false, false, false},
+	{1U << 7, 1U << 7, 0, 0, 0, true, false, true},
+
+	{48, 32, 80, 16, 0, false, false, true},
+	{128, 128, 0, 0, 0, true, false, true},
+	{123, 234, 101, 145, 110, true, true, true},
+};
+DEFINE_TEST_ARRAY(u16) = {
+	{0, 0, 0, 0, 0, false, false, false},
+	{1, 1, 2, 0, 1, false, false, false},
+	{0, 1, 1, U16_MAX, 0, false, true, false},
+	{1, 0, 1, 1, 0, false, false, false},
+	{0, U16_MAX, U16_MAX, 1, 0, false, true, false},
+	{U16_MAX, 0, U16_MAX, U16_MAX, 0, false, false, false},
+	{1, U16_MAX, 0, 2, U16_MAX, true, true, false},
+	{U16_MAX, 1, 0, U16_MAX-1, U16_MAX, true, false, false},
+	{U16_MAX, U16_MAX, U16_MAX-1, 0, 1, true, false, true},
+
+	{U16_MAX, U16_MAX-1, U16_MAX-2, 1, 2, true, false, true},
+	{U16_MAX-1, U16_MAX, U16_MAX-2, U16_MAX, 2, true, true, true},
+
+	{1U << 7, 1U << 7, 1U << 8, 0, 1U << 14, false, false, false},
+	{1U << 8, 1U << 8, 1U << 9, 0, 0, false, false, true},
+	{1U << 8, 1U << 7, 3*(1U << 7), 1U << 7, 1U << 15, false, false, false},
+	{1U << 15, 1U << 15, 0, 0, 0, true, false, true},
+
+	{123, 234, 357, 65425, 28782, false, true, false},
+	{1234, 2345, 3579, 64425, 10146, false, true, true},
+};
+DEFINE_TEST_ARRAY(u32) = {
+	{0, 0, 0, 0, 0, false, false, false},
+	{1, 1, 2, 0, 1, false, false, false},
+	{0, 1, 1, U32_MAX, 0, false, true, false},
+	{1, 0, 1, 1, 0, false, false, false},
+	{0, U32_MAX, U32_MAX, 1, 0, false, true, false},
+	{U32_MAX, 0, U32_MAX, U32_MAX, 0, false, false, false},
+	{1, U32_MAX, 0, 2, U32_MAX, true, true, false},
+	{U32_MAX, 1, 0, U32_MAX-1, U32_MAX, true, false, false},
+	{U32_MAX, U32_MAX, U32_MAX-1, 0, 1, true, false, true},
+
+	{U32_MAX, U32_MAX-1, U32_MAX-2, 1, 2, true, false, true},
+	{U32_MAX-1, U32_MAX, U32_MAX-2, U32_MAX, 2, true, true, true},
+
+	{1U << 15, 1U << 15, 1U << 16, 0, 1U << 30, false, false, false},
+	{1U << 16, 1U << 16, 1U << 17, 0, 0, false, false, true},
+	{1U << 16, 1U << 15, 3*(1U << 15), 1U << 15, 1U << 31, false, false, false},
+	{1U << 31, 1U << 31, 0, 0, 0, true, false, true},
+
+	{-2U, 1U, -1U, -3U, -2U, false, false, false},
+	{-4U, 5U, 1U, -9U, -20U, true, false, true},
+};
+
+DEFINE_TEST_ARRAY(u64) = {
+	{0, 0, 0, 0, 0, false, false, false},
+	{1, 1, 2, 0, 1, false, false, false},
+	{0, 1, 1, U64_MAX, 0, false, true, false},
+	{1, 0, 1, 1, 0, false, false, false},
+	{0, U64_MAX, U64_MAX, 1, 0, false, true, false},
+	{U64_MAX, 0, U64_MAX, U64_MAX, 0, false, false, false},
+	{1, U64_MAX, 0, 2, U64_MAX, true, true, false},
+	{U64_MAX, 1, 0, U64_MAX-1, U64_MAX, true, false, false},
+	{U64_MAX, U64_MAX, U64_MAX-1, 0, 1, true, false, true},
+
+	{U64_MAX, U64_MAX-1, U64_MAX-2, 1, 2, true, false, true},
+	{U64_MAX-1, U64_MAX, U64_MAX-2, U64_MAX, 2, true, true, true},
+
+	{1ULL << 31, 1ULL << 31, 1ULL << 32, 0, 1ULL << 62, false, false, false},
+	{1ULL << 32, 1ULL << 32, 1ULL << 33, 0, 0, false, false, true},
+	{1ULL << 32, 1ULL << 31, 3*(1ULL << 31), 1ULL << 31, 1ULL << 63, false, false, false},
+	{1ULL << 63, 1ULL << 63, 0, 0, 0, true, false, true},
+	{1000000000ULL /* 10^9 */, 10000000000ULL /* 10^10 */,
+	 11000000000ULL, 18446744064709551616ULL, 10000000000000000000ULL,
+	 false, true, false},
+	{-15ULL, 10ULL, -5ULL, -25ULL, -150ULL, false, false, true},
+};
+
+DEFINE_TEST_ARRAY(s8) = {
+	{0, 0, 0, 0, 0, false, false, false},
+
+	{0, S8_MAX, S8_MAX, -S8_MAX, 0, false, false, false},
+	{S8_MAX, 0, S8_MAX, S8_MAX, 0, false, false, false},
+	{0, S8_MIN, S8_MIN, S8_MIN, 0, false, true, false},
+	{S8_MIN, 0, S8_MIN, S8_MIN, 0, false, false, false},
+
+	{-1, S8_MIN, S8_MAX, S8_MAX, S8_MIN, true, false, true},
+	{S8_MIN, -1, S8_MAX, -S8_MAX, S8_MIN, true, false, true},
+	{-1, S8_MAX, S8_MAX-1, S8_MIN, -S8_MAX, false, false, false},
+	{S8_MAX, -1, S8_MAX-1, S8_MIN, -S8_MAX, false, true, false},
+	{-1, -S8_MAX, S8_MIN, S8_MAX-1, S8_MAX, false, false, false},
+	{-S8_MAX, -1, S8_MIN, S8_MIN+2, S8_MAX, false, false, false},
+
+	{1, S8_MIN, -S8_MAX, -S8_MAX, S8_MIN, false, true, false},
+	{S8_MIN, 1, -S8_MAX, S8_MAX, S8_MIN, false, true, false},
+	{1, S8_MAX, S8_MIN, S8_MIN+2, S8_MAX, true, false, false},
+	{S8_MAX, 1, S8_MIN, S8_MAX-1, S8_MAX, true, false, false},
+
+	{S8_MIN, S8_MIN, 0, 0, 0, true, false, true},
+	{S8_MAX, S8_MAX, -2, 0, 1, true, false, true},
+
+	{-4, -32, -36, 28, -128, false, false, true},
+	{-4, 32, 28, -36, -128, false, false, false},
+};
+
+DEFINE_TEST_ARRAY(s16) = {
+	{0, 0, 0, 0, 0, false, false, false},
+
+	{0, S16_MAX, S16_MAX, -S16_MAX, 0, false, false, false},
+	{S16_MAX, 0, S16_MAX, S16_MAX, 0, false, false, false},
+	{0, S16_MIN, S16_MIN, S16_MIN, 0, false, true, false},
+	{S16_MIN, 0, S16_MIN, S16_MIN, 0, false, false, false},
+
+	{-1, S16_MIN, S16_MAX, S16_MAX, S16_MIN, true, false, true},
+	{S16_MIN, -1, S16_MAX, -S16_MAX, S16_MIN, true, false, true},
+	{-1, S16_MAX, S16_MAX-1, S16_MIN, -S16_MAX, false, false, false},
+	{S16_MAX, -1, S16_MAX-1, S16_MIN, -S16_MAX, false, true, false},
+	{-1, -S16_MAX, S16_MIN, S16_MAX-1, S16_MAX, false, false, false},
+	{-S16_MAX, -1, S16_MIN, S16_MIN+2, S16_MAX, false, false, false},
+
+	{1, S16_MIN, -S16_MAX, -S16_MAX, S16_MIN, false, true, false},
+	{S16_MIN, 1, -S16_MAX, S16_MAX, S16_MIN, false, true, false},
+	{1, S16_MAX, S16_MIN, S16_MIN+2, S16_MAX, true, false, false},
+	{S16_MAX, 1, S16_MIN, S16_MAX-1, S16_MAX, true, false, false},
+
+	{S16_MIN, S16_MIN, 0, 0, 0, true, false, true},
+	{S16_MAX, S16_MAX, -2, 0, 1, true, false, true},
+};
+DEFINE_TEST_ARRAY(s32) = {
+	{0, 0, 0, 0, 0, false, false, false},
+
+	{0, S32_MAX, S32_MAX, -S32_MAX, 0, false, false, false},
+	{S32_MAX, 0, S32_MAX, S32_MAX, 0, false, false, false},
+	{0, S32_MIN, S32_MIN, S32_MIN, 0, false, true, false},
+	{S32_MIN, 0, S32_MIN, S32_MIN, 0, false, false, false},
+
+	{-1, S32_MIN, S32_MAX, S32_MAX, S32_MIN, true, false, true},
+	{S32_MIN, -1, S32_MAX, -S32_MAX, S32_MIN, true, false, true},
+	{-1, S32_MAX, S32_MAX-1, S32_MIN, -S32_MAX, false, false, false},
+	{S32_MAX, -1, S32_MAX-1, S32_MIN, -S32_MAX, false, true, false},
+	{-1, -S32_MAX, S32_MIN, S32_MAX-1, S32_MAX, false, false, false},
+	{-S32_MAX, -1, S32_MIN, S32_MIN+2, S32_MAX, false, false, false},
+
+	{1, S32_MIN, -S32_MAX, -S32_MAX, S32_MIN, false, true, false},
+	{S32_MIN, 1, -S32_MAX, S32_MAX, S32_MIN, false, true, false},
+	{1, S32_MAX, S32_MIN, S32_MIN+2, S32_MAX, true, false, false},
+	{S32_MAX, 1, S32_MIN, S32_MAX-1, S32_MAX, true, false, false},
+
+	{S32_MIN, S32_MIN, 0, 0, 0, true, false, true},
+	{S32_MAX, S32_MAX, -2, 0, 1, true, false, true},
+};
+
+DEFINE_TEST_ARRAY(s64) = {
+	{0, 0, 0, 0, 0, false, false, false},
+
+	{0, S64_MAX, S64_MAX, -S64_MAX, 0, false, false, false},
+	{S64_MAX, 0, S64_MAX, S64_MAX, 0, false, false, false},
+	{0, S64_MIN, S64_MIN, S64_MIN, 0, false, true, false},
+	{S64_MIN, 0, S64_MIN, S64_MIN, 0, false, false, false},
+
+	{-1, S64_MIN, S64_MAX, S64_MAX, S64_MIN, true, false, true},
+	{S64_MIN, -1, S64_MAX, -S64_MAX, S64_MIN, true, false, true},
+	{-1, S64_MAX, S64_MAX-1, S64_MIN, -S64_MAX, false, false, false},
+	{S64_MAX, -1, S64_MAX-1, S64_MIN, -S64_MAX, false, true, false},
+	{-1, -S64_MAX, S64_MIN, S64_MAX-1, S64_MAX, false, false, false},
+	{-S64_MAX, -1, S64_MIN, S64_MIN+2, S64_MAX, false, false, false},
+
+	{1, S64_MIN, -S64_MAX, -S64_MAX, S64_MIN, false, true, false},
+	{S64_MIN, 1, -S64_MAX, S64_MAX, S64_MIN, false, true, false},
+	{1, S64_MAX, S64_MIN, S64_MIN+2, S64_MAX, true, false, false},
+	{S64_MAX, 1, S64_MIN, S64_MAX-1, S64_MAX, true, false, false},
+
+	{S64_MIN, S64_MIN, 0, 0, 0, true, false, true},
+	{S64_MAX, S64_MAX, -2, 0, 1, true, false, true},
+
+	{-1, -1, -2, 0, 1, false, false, false},
+	{-1, -128, -129, 127, 128, false, false, false},
+	{-128, -1, -129, -127, 128, false, false, false},
+	{0, -S64_MAX, -S64_MAX, S64_MAX, 0, false, false, false},
+};
+
+#define check_one_op(t, fmt, op, sym, a, b, r, of) do {			\
+	int _a_orig = a, _a_bump = a + 1;				\
+	int _b_orig = b, _b_bump = b + 1;				\
+	bool _of;							\
+	t _r;								\
+									\
+	_of = check_ ## op ## _overflow(a, b, &_r);			\
+	KUNIT_EXPECT_EQ_MSG(test, _of, of,				\
+		"expected check "fmt" "sym" "fmt" to%s overflow (type %s)\n",	\
+		a, b, of ? "" : " not", #t);				\
+	KUNIT_EXPECT_EQ_MSG(test, _r, r,				\
+		"expected check "fmt" "sym" "fmt" == "fmt", got "fmt" (type %s)\n", \
+		a, b, r, _r, #t);					\
+	/* Check for internal macro side-effects. */			\
+	_of = check_ ## op ## _overflow(_a_orig++, _b_orig++, &_r);	\
+	KUNIT_EXPECT_EQ_MSG(test, _a_orig, _a_bump,			\
+		"Unexpected check " #op " macro side-effect!\n");	\
+	KUNIT_EXPECT_EQ_MSG(test, _b_orig, _b_bump,			\
+		"Unexpected check " #op " macro side-effect!\n");	\
+									\
+	_r = wrapping_ ## op(t, a, b);					\
+	KUNIT_EXPECT_TRUE_MSG(test, _r == r,				\
+		"expected wrap "fmt" "sym" "fmt" == "fmt", got "fmt" (type %s)\n", \
+		a, b, r, _r, #t);					\
+	/* Check for internal macro side-effects. */			\
+	_a_orig = a;							\
+	_b_orig = b;							\
+	_r = wrapping_ ## op(t, _a_orig++, _b_orig++);			\
+	KUNIT_EXPECT_EQ_MSG(test, _a_orig, _a_bump,			\
+		"Unexpected wrap " #op " macro side-effect!\n");	\
+	KUNIT_EXPECT_EQ_MSG(test, _b_orig, _b_bump,			\
+		"Unexpected wrap " #op " macro side-effect!\n");	\
+} while (0)
+
+static int global_counter;
+static void bump_counter(void)
+{
+	global_counter++;
+}
+
+static int get_index(void)
+{
+	volatile int index = 0;
+	bump_counter();
+	return index;
+}
+
+#define check_self_op(fmt, op, sym, a, b) do {				\
+	typeof(a + 0) _a = a;						\
+	typeof(b + 0) _b = b;						\
+	typeof(a + 0) _a_sym = a;					\
+	typeof(a + 0) _a_orig[1] = { a };				\
+	typeof(b + 0) _b_orig = b;					\
+	typeof(b + 0) _b_bump = b + 1;					\
+	typeof(a + 0) _r;						\
+									\
+	_a_sym sym _b;							\
+	_r = wrapping_ ## op(_a, _b);					\
+	KUNIT_EXPECT_TRUE_MSG(test, _r == _a_sym,			\
+		"expected "fmt" "#op" "fmt" == "fmt", got "fmt"\n",	\
+		a, b, _a_sym, _r);					\
+	KUNIT_EXPECT_TRUE_MSG(test, _a == _a_sym,			\
+		"expected "fmt" "#op" "fmt" == "fmt", got "fmt"\n",	\
+		a, b, _a_sym, _a);					\
+	/* Check for internal macro side-effects. */			\
+	global_counter = 0;						\
+	wrapping_ ## op(_a_orig[get_index()], _b_orig++);		\
+	KUNIT_EXPECT_EQ_MSG(test, global_counter, 1,			\
+		"Unexpected wrapping_" #op " macro side-effect on arg1!\n"); \
+	KUNIT_EXPECT_EQ_MSG(test, _b_orig, _b_bump,			\
+		"Unexpected wrapping_" #op " macro side-effect on arg2!\n"); \
+} while (0)
+
+#define DEFINE_TEST_FUNC_TYPED(n, t, fmt)				\
+static void do_test_ ## n(struct kunit *test, const struct test_ ## n *p) \
+{									\
+	/* check_{add,sub,mul}_overflow() and wrapping_{add,sub,mul} */	\
+	check_one_op(t, fmt, add, "+", p->a, p->b, p->sum, p->s_of);	\
+	check_one_op(t, fmt, add, "+", p->b, p->a, p->sum, p->s_of);	\
+	check_one_op(t, fmt, sub, "-", p->a, p->b, p->diff, p->d_of);	\
+	check_one_op(t, fmt, mul, "*", p->a, p->b, p->prod, p->p_of);	\
+	check_one_op(t, fmt, mul, "*", p->b, p->a, p->prod, p->p_of);	\
+	/* wrapping_assign_{add,sub}() */				\
+	check_self_op(fmt, assign_add, +=, p->a, p->b);			\
+	check_self_op(fmt, assign_add, +=, p->b, p->a);			\
+	check_self_op(fmt, assign_sub, -=, p->a, p->b);			\
+}									\
+									\
+static void n ## _overflow_test(struct kunit *test) {			\
+	unsigned i;							\
+									\
+	SKIP_64_ON_32(__same_type(t, u64));				\
+	SKIP_64_ON_32(__same_type(t, s64));				\
+	SKIP_SIGN_MISMATCH(__same_type(n ## _tests[0].a, u32) &&	\
+			   __same_type(n ## _tests[0].b, u32) &&	\
+			   __same_type(n ## _tests[0].sum, int));	\
+									\
+	for (i = 0; i < ARRAY_SIZE(n ## _tests); ++i)			\
+		do_test_ ## n(test, &n ## _tests[i]);			\
+	kunit_info(test, "%zu %s arithmetic tests finished\n",		\
+		ARRAY_SIZE(n ## _tests), #n);				\
+}
+
+#define DEFINE_TEST_FUNC(t, fmt)					\
+	DEFINE_TEST_FUNC_TYPED(t ## _ ## t ## __ ## t, t, fmt)
+
+DEFINE_TEST_FUNC(u8, "%d");
+DEFINE_TEST_FUNC(s8, "%d");
+DEFINE_TEST_FUNC(u16, "%d");
+DEFINE_TEST_FUNC(s16, "%d");
+DEFINE_TEST_FUNC(u32, "%u");
+DEFINE_TEST_FUNC(s32, "%d");
+DEFINE_TEST_FUNC(u64, "%llu");
+DEFINE_TEST_FUNC(s64, "%lld");
+
+DEFINE_TEST_ARRAY_TYPED(u32, u32, u8) = {
+	{0, 0, 0, 0, 0, false, false, false},
+	{U8_MAX, 2, 1, U8_MAX - 2, U8_MAX - 1, true, false, true},
+	{U8_MAX + 1, 0, 0, 0, 0, true, true, false},
+};
+DEFINE_TEST_FUNC_TYPED(u32_u32__u8, u8, "%d");
+
+DEFINE_TEST_ARRAY_TYPED(u32, u32, int) = {
+	{0, 0, 0, 0, 0, false, false, false},
+	{U32_MAX, 0, -1, -1, 0, true, true, false},
+};
+DEFINE_TEST_FUNC_TYPED(u32_u32__int, int, "%d");
+
+DEFINE_TEST_ARRAY_TYPED(u8, u8, int) = {
+	{0, 0, 0, 0, 0, false, false, false},
+	{U8_MAX, U8_MAX, 2 * U8_MAX, 0, U8_MAX * U8_MAX, false, false, false},
+	{1, 2, 3, -1, 2, false, false, false},
+};
+DEFINE_TEST_FUNC_TYPED(u8_u8__int, int, "%d");
+
+DEFINE_TEST_ARRAY_TYPED(int, int, u8) = {
+	{0, 0, 0, 0, 0, false, false, false},
+	{1, 2, 3, U8_MAX, 2, false, true, false},
+	{-1, 0, U8_MAX, U8_MAX, 0, true, true, false},
+};
+DEFINE_TEST_FUNC_TYPED(int_int__u8, u8, "%d");
+
+/* Args are: value, shift, type, expected result, overflow expected */
+#define TEST_ONE_SHIFT(a, s, t, expect, of)	do {			\
+	typeof(a) __a = (a);						\
+	typeof(s) __s = (s);						\
+	t __e = (expect);						\
+	t __d;								\
+	bool __of = check_shl_overflow(__a, __s, &__d);			\
+	if (__of != of) {						\
+		KUNIT_EXPECT_EQ_MSG(test, __of, of,			\
+			"expected (%s)(%s << %s) to%s overflow\n",	\
+			#t, #a, #s, of ? "" : " not");			\
+	} else if (!__of && __d != __e) {				\
+		KUNIT_EXPECT_EQ_MSG(test, __d, __e,			\
+			"expected (%s)(%s << %s) == %s\n",		\
+			#t, #a, #s, #expect);				\
+		if ((t)-1 < 0)						\
+			kunit_info(test, "got %lld\n", (s64)__d);	\
+		else							\
+			kunit_info(test, "got %llu\n", (u64)__d);	\
+	}								\
+	count++;							\
+} while (0)
+
+static void shift_sane_test(struct kunit *test)
+{
+	int count = 0;
+
+	/* Sane shifts. */
+	TEST_ONE_SHIFT(1, 0, u8, 1 << 0, false);
+	TEST_ONE_SHIFT(1, 4, u8, 1 << 4, false);
+	TEST_ONE_SHIFT(1, 7, u8, 1 << 7, false);
+	TEST_ONE_SHIFT(0xF, 4, u8, 0xF << 4, false);
+	TEST_ONE_SHIFT(1, 0, u16, 1 << 0, false);
+	TEST_ONE_SHIFT(1, 10, u16, 1 << 10, false);
+	TEST_ONE_SHIFT(1, 15, u16, 1 << 15, false);
+	TEST_ONE_SHIFT(0xFF, 8, u16, 0xFF << 8, false);
+	TEST_ONE_SHIFT(1, 0, int, 1 << 0, false);
+	TEST_ONE_SHIFT(1, 16, int, 1 << 16, false);
+	TEST_ONE_SHIFT(1, 30, int, 1 << 30, false);
+	TEST_ONE_SHIFT(1, 0, s32, 1 << 0, false);
+	TEST_ONE_SHIFT(1, 16, s32, 1 << 16, false);
+	TEST_ONE_SHIFT(1, 30, s32, 1 << 30, false);
+	TEST_ONE_SHIFT(1, 0, unsigned int, 1U << 0, false);
+	TEST_ONE_SHIFT(1, 20, unsigned int, 1U << 20, false);
+	TEST_ONE_SHIFT(1, 31, unsigned int, 1U << 31, false);
+	TEST_ONE_SHIFT(0xFFFFU, 16, unsigned int, 0xFFFFU << 16, false);
+	TEST_ONE_SHIFT(1, 0, u32, 1U << 0, false);
+	TEST_ONE_SHIFT(1, 20, u32, 1U << 20, false);
+	TEST_ONE_SHIFT(1, 31, u32, 1U << 31, false);
+	TEST_ONE_SHIFT(0xFFFFU, 16, u32, 0xFFFFU << 16, false);
+	TEST_ONE_SHIFT(1, 0, u64, 1ULL << 0, false);
+	TEST_ONE_SHIFT(1, 40, u64, 1ULL << 40, false);
+	TEST_ONE_SHIFT(1, 63, u64, 1ULL << 63, false);
+	TEST_ONE_SHIFT(0xFFFFFFFFULL, 32, u64, 0xFFFFFFFFULL << 32, false);
+
+	/* Sane shift: start and end with 0, without a too-wide shift. */
+	TEST_ONE_SHIFT(0, 7, u8, 0, false);
+	TEST_ONE_SHIFT(0, 15, u16, 0, false);
+	TEST_ONE_SHIFT(0, 31, unsigned int, 0, false);
+	TEST_ONE_SHIFT(0, 31, u32, 0, false);
+	TEST_ONE_SHIFT(0, 63, u64, 0, false);
+
+	/* Sane shift: start and end with 0, without reaching signed bit. */
+	TEST_ONE_SHIFT(0, 6, s8, 0, false);
+	TEST_ONE_SHIFT(0, 14, s16, 0, false);
+	TEST_ONE_SHIFT(0, 30, int, 0, false);
+	TEST_ONE_SHIFT(0, 30, s32, 0, false);
+	TEST_ONE_SHIFT(0, 62, s64, 0, false);
+
+	kunit_info(test, "%d sane shift tests finished\n", count);
+}
+
+static void shift_overflow_test(struct kunit *test)
+{
+	int count = 0;
+
+	/* Overflow: shifted the bit off the end. */
+	TEST_ONE_SHIFT(1, 8, u8, 0, true);
+	TEST_ONE_SHIFT(1, 16, u16, 0, true);
+	TEST_ONE_SHIFT(1, 32, unsigned int, 0, true);
+	TEST_ONE_SHIFT(1, 32, u32, 0, true);
+	TEST_ONE_SHIFT(1, 64, u64, 0, true);
+
+	/* Overflow: shifted into the signed bit. */
+	TEST_ONE_SHIFT(1, 7, s8, 0, true);
+	TEST_ONE_SHIFT(1, 15, s16, 0, true);
+	TEST_ONE_SHIFT(1, 31, int, 0, true);
+	TEST_ONE_SHIFT(1, 31, s32, 0, true);
+	TEST_ONE_SHIFT(1, 63, s64, 0, true);
+
+	/* Overflow: high bit falls off unsigned types. */
+	/* 10010110 */
+	TEST_ONE_SHIFT(150, 1, u8, 0, true);
+	/* 1000100010010110 */
+	TEST_ONE_SHIFT(34966, 1, u16, 0, true);
+	/* 10000100000010001000100010010110 */
+	TEST_ONE_SHIFT(2215151766U, 1, u32, 0, true);
+	TEST_ONE_SHIFT(2215151766U, 1, unsigned int, 0, true);
+	/* 1000001000010000010000000100000010000100000010001000100010010110 */
+	TEST_ONE_SHIFT(9372061470395238550ULL, 1, u64, 0, true);
+
+	/* Overflow: bit shifted into signed bit on signed types. */
+	/* 01001011 */
+	TEST_ONE_SHIFT(75, 1, s8, 0, true);
+	/* 0100010001001011 */
+	TEST_ONE_SHIFT(17483, 1, s16, 0, true);
+	/* 01000010000001000100010001001011 */
+	TEST_ONE_SHIFT(1107575883, 1, s32, 0, true);
+	TEST_ONE_SHIFT(1107575883, 1, int, 0, true);
+	/* 0100000100001000001000000010000001000010000001000100010001001011 */
+	TEST_ONE_SHIFT(4686030735197619275LL, 1, s64, 0, true);
+
+	/* Overflow: bit shifted past signed bit on signed types. */
+	/* 01001011 */
+	TEST_ONE_SHIFT(75, 2, s8, 0, true);
+	/* 0100010001001011 */
+	TEST_ONE_SHIFT(17483, 2, s16, 0, true);
+	/* 01000010000001000100010001001011 */
+	TEST_ONE_SHIFT(1107575883, 2, s32, 0, true);
+	TEST_ONE_SHIFT(1107575883, 2, int, 0, true);
+	/* 0100000100001000001000000010000001000010000001000100010001001011 */
+	TEST_ONE_SHIFT(4686030735197619275LL, 2, s64, 0, true);
+
+	kunit_info(test, "%d overflow shift tests finished\n", count);
+}
+
+static void shift_truncate_test(struct kunit *test)
+{
+	int count = 0;
+
+	/* Overflow: values larger than destination type. */
+	TEST_ONE_SHIFT(0x100, 0, u8, 0, true);
+	TEST_ONE_SHIFT(0xFF, 0, s8, 0, true);
+	TEST_ONE_SHIFT(0x10000U, 0, u16, 0, true);
+	TEST_ONE_SHIFT(0xFFFFU, 0, s16, 0, true);
+	TEST_ONE_SHIFT(0x100000000ULL, 0, u32, 0, true);
+	TEST_ONE_SHIFT(0x100000000ULL, 0, unsigned int, 0, true);
+	TEST_ONE_SHIFT(0xFFFFFFFFUL, 0, s32, 0, true);
+	TEST_ONE_SHIFT(0xFFFFFFFFUL, 0, int, 0, true);
+	TEST_ONE_SHIFT(0xFFFFFFFFFFFFFFFFULL, 0, s64, 0, true);
+
+	/* Overflow: shifted at or beyond entire type's bit width. */
+	TEST_ONE_SHIFT(0, 8, u8, 0, true);
+	TEST_ONE_SHIFT(0, 9, u8, 0, true);
+	TEST_ONE_SHIFT(0, 8, s8, 0, true);
+	TEST_ONE_SHIFT(0, 9, s8, 0, true);
+	TEST_ONE_SHIFT(0, 16, u16, 0, true);
+	TEST_ONE_SHIFT(0, 17, u16, 0, true);
+	TEST_ONE_SHIFT(0, 16, s16, 0, true);
+	TEST_ONE_SHIFT(0, 17, s16, 0, true);
+	TEST_ONE_SHIFT(0, 32, u32, 0, true);
+	TEST_ONE_SHIFT(0, 33, u32, 0, true);
+	TEST_ONE_SHIFT(0, 32, int, 0, true);
+	TEST_ONE_SHIFT(0, 33, int, 0, true);
+	TEST_ONE_SHIFT(0, 32, s32, 0, true);
+	TEST_ONE_SHIFT(0, 33, s32, 0, true);
+	TEST_ONE_SHIFT(0, 64, u64, 0, true);
+	TEST_ONE_SHIFT(0, 65, u64, 0, true);
+	TEST_ONE_SHIFT(0, 64, s64, 0, true);
+	TEST_ONE_SHIFT(0, 65, s64, 0, true);
+
+	kunit_info(test, "%d truncate shift tests finished\n", count);
+}
+
+static void shift_nonsense_test(struct kunit *test)
+{
+	int count = 0;
+
+	/* Nonsense: negative initial value. */
+	TEST_ONE_SHIFT(-1, 0, s8, 0, true);
+	TEST_ONE_SHIFT(-1, 0, u8, 0, true);
+	TEST_ONE_SHIFT(-5, 0, s16, 0, true);
+	TEST_ONE_SHIFT(-5, 0, u16, 0, true);
+	TEST_ONE_SHIFT(-10, 0, int, 0, true);
+	TEST_ONE_SHIFT(-10, 0, unsigned int, 0, true);
+	TEST_ONE_SHIFT(-100, 0, s32, 0, true);
+	TEST_ONE_SHIFT(-100, 0, u32, 0, true);
+	TEST_ONE_SHIFT(-10000, 0, s64, 0, true);
+	TEST_ONE_SHIFT(-10000, 0, u64, 0, true);
+
+	/* Nonsense: negative shift values. */
+	TEST_ONE_SHIFT(0, -5, s8, 0, true);
+	TEST_ONE_SHIFT(0, -5, u8, 0, true);
+	TEST_ONE_SHIFT(0, -10, s16, 0, true);
+	TEST_ONE_SHIFT(0, -10, u16, 0, true);
+	TEST_ONE_SHIFT(0, -15, int, 0, true);
+	TEST_ONE_SHIFT(0, -15, unsigned int, 0, true);
+	TEST_ONE_SHIFT(0, -20, s32, 0, true);
+	TEST_ONE_SHIFT(0, -20, u32, 0, true);
+	TEST_ONE_SHIFT(0, -30, s64, 0, true);
+	TEST_ONE_SHIFT(0, -30, u64, 0, true);
+
+	/*
+	 * Corner case: for unsigned types, we fail when we've shifted
+	 * through the entire width of bits. For signed types, we might
+	 * want to match this behavior, but that would mean noticing if
+	 * we shift through all but the signed bit, and this is not
+	 * currently detected (but we'll notice an overflow into the
+	 * signed bit). So, for now, we will test this condition but
+	 * mark it as not expected to overflow.
+	 */
+	TEST_ONE_SHIFT(0, 7, s8, 0, false);
+	TEST_ONE_SHIFT(0, 15, s16, 0, false);
+	TEST_ONE_SHIFT(0, 31, int, 0, false);
+	TEST_ONE_SHIFT(0, 31, s32, 0, false);
+	TEST_ONE_SHIFT(0, 63, s64, 0, false);
+
+	kunit_info(test, "%d nonsense shift tests finished\n", count);
+}
+#undef TEST_ONE_SHIFT
+
+/*
+ * Deal with the various forms of allocator arguments. See comments above
+ * the DEFINE_TEST_ALLOC() instances for mapping of the "bits".
+ */
+#define alloc_GFP		 (GFP_KERNEL | __GFP_NOWARN)
+#define alloc010(alloc, arg, sz) alloc(sz, alloc_GFP)
+#define alloc011(alloc, arg, sz) alloc(sz, alloc_GFP, NUMA_NO_NODE)
+#define alloc000(alloc, arg, sz) alloc(sz)
+#define alloc001(alloc, arg, sz) alloc(sz, NUMA_NO_NODE)
+#define alloc110(alloc, arg, sz) alloc(arg, sz, alloc_GFP)
+#define free0(free, arg, ptr)	 free(ptr)
+#define free1(free, arg, ptr)	 free(arg, ptr)
+
+/* Wrap around to 16K */
+#define TEST_SIZE		(5 * 4096)
+
+#define DEFINE_TEST_ALLOC(func, free_func, want_arg, want_gfp, want_node)\
+static void test_ ## func (struct kunit *test, void *arg)		\
+{									\
+	volatile size_t a = TEST_SIZE;					\
+	volatile size_t b = (SIZE_MAX / TEST_SIZE) + 1;			\
+	void *ptr;							\
+									\
+	/* Tiny allocation test. */					\
+	ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg, 1);\
+	KUNIT_ASSERT_NOT_ERR_OR_NULL_MSG(test, ptr,			\
+			    #func " failed regular allocation?!\n");	\
+	free ## want_arg (free_func, arg, ptr);				\
+									\
+	/* Wrapped allocation test. */					\
+	ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg,	\
+							  a * b);	\
+	KUNIT_ASSERT_NOT_ERR_OR_NULL_MSG(test, ptr,			\
+			    #func " unexpectedly failed bad wrapping?!\n"); \
+	free ## want_arg (free_func, arg, ptr);				\
+									\
+	/* Saturated allocation test. */				\
+	ptr = alloc ## want_arg ## want_gfp ## want_node (func, arg,	\
+						   array_size(a, b));	\
+	if (ptr) {							\
+		KUNIT_FAIL(test, #func " missed saturation!\n");	\
+		free ## want_arg (free_func, arg, ptr);			\
+	}								\
+}
+
+/*
+ * Allocator uses a trailing node argument --------+  (e.g. kmalloc_node())
+ * Allocator uses the gfp_t argument -----------+  |  (e.g. kmalloc())
+ * Allocator uses a special leading argument +  |  |  (e.g. devm_kmalloc())
+ *                                           |  |  |
+ */
+DEFINE_TEST_ALLOC(kmalloc,	 kfree,	     0, 1, 0);
+DEFINE_TEST_ALLOC(kmalloc_node,	 kfree,	     0, 1, 1);
+DEFINE_TEST_ALLOC(kzalloc,	 kfree,	     0, 1, 0);
+DEFINE_TEST_ALLOC(kzalloc_node,  kfree,	     0, 1, 1);
+DEFINE_TEST_ALLOC(__vmalloc,	 vfree,	     0, 1, 0);
+DEFINE_TEST_ALLOC(kvmalloc,	 kvfree,     0, 1, 0);
+DEFINE_TEST_ALLOC(kvmalloc_node, kvfree,     0, 1, 1);
+DEFINE_TEST_ALLOC(kvzalloc,	 kvfree,     0, 1, 0);
+DEFINE_TEST_ALLOC(kvzalloc_node, kvfree,     0, 1, 1);
+DEFINE_TEST_ALLOC(devm_kmalloc,  devm_kfree, 1, 1, 0);
+DEFINE_TEST_ALLOC(devm_kzalloc,  devm_kfree, 1, 1, 0);
+
+static void overflow_allocation_test(struct kunit *test)
+{
+	struct device *dev;
+	int count = 0;
+
+#define check_allocation_overflow(alloc)	do {	\
+	count++;					\
+	test_ ## alloc(test, dev);			\
+} while (0)
+
+	/* Create dummy device for devm_kmalloc()-family tests. */
+	dev = kunit_device_register(test, "overflow-test");
+	KUNIT_ASSERT_FALSE_MSG(test, IS_ERR(dev),
+			       "Cannot register test device\n");
+
+	check_allocation_overflow(kmalloc);
+	check_allocation_overflow(kmalloc_node);
+	check_allocation_overflow(kzalloc);
+	check_allocation_overflow(kzalloc_node);
+	check_allocation_overflow(__vmalloc);
+	check_allocation_overflow(kvmalloc);
+	check_allocation_overflow(kvmalloc_node);
+	check_allocation_overflow(kvzalloc);
+	check_allocation_overflow(kvzalloc_node);
+	check_allocation_overflow(devm_kmalloc);
+	check_allocation_overflow(devm_kzalloc);
+
+	kunit_info(test, "%d allocation overflow tests finished\n", count);
+#undef check_allocation_overflow
+}
+
+struct __test_flex_array {
+	unsigned long flags;
+	size_t count;
+	unsigned long data[];
+};
+
+static void overflow_size_helpers_test(struct kunit *test)
+{
+	/* Make sure struct_size() can be used in a constant expression. */
+	u8 ce_array[struct_size_t(struct __test_flex_array, data, 55)];
+	struct __test_flex_array *obj;
+	int count = 0;
+	int var;
+	volatile int unconst = 0;
+
+	/* Verify constant expression against runtime version. */
+	var = 55;
+	OPTIMIZER_HIDE_VAR(var);
+	KUNIT_EXPECT_EQ(test, sizeof(ce_array), struct_size(obj, data, var));
+
+#define check_one_size_helper(expected, func, args...)	do {	\
+	size_t _r = func(args);					\
+	KUNIT_EXPECT_EQ_MSG(test, _r, expected,			\
+		"expected " #func "(" #args ") to return %zu but got %zu instead\n", \
+		(size_t)(expected), _r);			\
+	count++;						\
+} while (0)
+
+	var = 4;
+	check_one_size_helper(20,	size_mul, var++, 5);
+	check_one_size_helper(20,	size_mul, 4, var++);
+	check_one_size_helper(0,	size_mul, 0, 3);
+	check_one_size_helper(0,	size_mul, 3, 0);
+	check_one_size_helper(6,	size_mul, 2, 3);
+	check_one_size_helper(SIZE_MAX,	size_mul, SIZE_MAX,  1);
+	check_one_size_helper(SIZE_MAX,	size_mul, SIZE_MAX,  3);
+	check_one_size_helper(SIZE_MAX,	size_mul, SIZE_MAX, -3);
+
+	var = 4;
+	check_one_size_helper(9,	size_add, var++, 5);
+	check_one_size_helper(9,	size_add, 4, var++);
+	check_one_size_helper(9,	size_add, 9, 0);
+	check_one_size_helper(9,	size_add, 0, 9);
+	check_one_size_helper(5,	size_add, 2, 3);
+	check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX,  1);
+	check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX,  3);
+	check_one_size_helper(SIZE_MAX, size_add, SIZE_MAX, -3);
+
+	var = 4;
+	check_one_size_helper(1,	size_sub, var--, 3);
+	check_one_size_helper(1,	size_sub, 4, var--);
+	check_one_size_helper(1,	size_sub, 3, 2);
+	check_one_size_helper(9,	size_sub, 9, 0);
+	check_one_size_helper(SIZE_MAX, size_sub, 9, -3);
+	check_one_size_helper(SIZE_MAX, size_sub, 0, 9);
+	check_one_size_helper(SIZE_MAX, size_sub, 2, 3);
+	check_one_size_helper(SIZE_MAX, size_sub, SIZE_MAX,  0);
+	check_one_size_helper(SIZE_MAX, size_sub, SIZE_MAX, 10);
+	check_one_size_helper(SIZE_MAX, size_sub, 0,  SIZE_MAX);
+	check_one_size_helper(SIZE_MAX, size_sub, 14, SIZE_MAX);
+	check_one_size_helper(SIZE_MAX - 2, size_sub, SIZE_MAX - 1,  1);
+	check_one_size_helper(SIZE_MAX - 4, size_sub, SIZE_MAX - 1,  3);
+	check_one_size_helper(1,		size_sub, SIZE_MAX - 1, -3);
+
+	var = 4;
+	check_one_size_helper(4 * sizeof(*obj->data),
+			      flex_array_size, obj, data, var++);
+	check_one_size_helper(5 * sizeof(*obj->data),
+			      flex_array_size, obj, data, var++);
+	check_one_size_helper(0, flex_array_size, obj, data, 0 + unconst);
+	check_one_size_helper(sizeof(*obj->data),
+			      flex_array_size, obj, data, 1 + unconst);
+	check_one_size_helper(7 * sizeof(*obj->data),
+			      flex_array_size, obj, data, 7 + unconst);
+	check_one_size_helper(SIZE_MAX,
+			      flex_array_size, obj, data, -1 + unconst);
+	check_one_size_helper(SIZE_MAX,
+			      flex_array_size, obj, data, SIZE_MAX - 4 + unconst);
+
+	var = 4;
+	check_one_size_helper(sizeof(*obj) + (4 * sizeof(*obj->data)),
+			      struct_size, obj, data, var++);
+	check_one_size_helper(sizeof(*obj) + (5 * sizeof(*obj->data)),
+			      struct_size, obj, data, var++);
+	check_one_size_helper(sizeof(*obj), struct_size, obj, data, 0 + unconst);
+	check_one_size_helper(sizeof(*obj) + sizeof(*obj->data),
+			      struct_size, obj, data, 1 + unconst);
+	check_one_size_helper(SIZE_MAX,
+			      struct_size, obj, data, -3 + unconst);
+	check_one_size_helper(SIZE_MAX,
+			      struct_size, obj, data, SIZE_MAX - 3 + unconst);
+
+	kunit_info(test, "%d overflow size helper tests finished\n", count);
+#undef check_one_size_helper
+}
+
+static void overflows_type_test(struct kunit *test)
+{
+	int count = 0;
+	unsigned int var;
+
+#define __TEST_OVERFLOWS_TYPE(func, arg1, arg2, of)	do {		\
+	bool __of = func(arg1, arg2);					\
+	KUNIT_EXPECT_EQ_MSG(test, __of, of,				\
+		"expected " #func "(" #arg1 ", " #arg2 " to%s overflow\n",\
+		of ? "" : " not");					\
+	count++;							\
+} while (0)
+
+/* Args are: first type, second type, value, overflow expected */
+#define TEST_OVERFLOWS_TYPE(__t1, __t2, v, of) do {			\
+	__t1 t1 = (v);							\
+	__t2 t2;							\
+	__TEST_OVERFLOWS_TYPE(__overflows_type, t1, t2, of);		\
+	__TEST_OVERFLOWS_TYPE(__overflows_type, t1, __t2, of);		\
+	__TEST_OVERFLOWS_TYPE(__overflows_type_constexpr, t1, t2, of);	\
+	__TEST_OVERFLOWS_TYPE(__overflows_type_constexpr, t1, __t2, of);\
+} while (0)
+
+	TEST_OVERFLOWS_TYPE(u8, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u8, u16, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u8, s8, U8_MAX, true);
+	TEST_OVERFLOWS_TYPE(u8, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u8, s8, (u8)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u8, s16, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, u8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, u8, -1, true);
+	TEST_OVERFLOWS_TYPE(s8, u8, S8_MIN, true);
+	TEST_OVERFLOWS_TYPE(s8, u16, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, u16, -1, true);
+	TEST_OVERFLOWS_TYPE(s8, u16, S8_MIN, true);
+	TEST_OVERFLOWS_TYPE(s8, u32, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, u32, -1, true);
+	TEST_OVERFLOWS_TYPE(s8, u32, S8_MIN, true);
+#if BITS_PER_LONG == 64
+	TEST_OVERFLOWS_TYPE(s8, u64, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, u64, -1, true);
+	TEST_OVERFLOWS_TYPE(s8, u64, S8_MIN, true);
+#endif
+	TEST_OVERFLOWS_TYPE(s8, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, s8, S8_MIN, false);
+	TEST_OVERFLOWS_TYPE(s8, s16, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s8, s16, S8_MIN, false);
+	TEST_OVERFLOWS_TYPE(u16, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u16, u8, (u16)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u16, u8, U16_MAX, true);
+	TEST_OVERFLOWS_TYPE(u16, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u16, s8, (u16)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u16, s8, U16_MAX, true);
+	TEST_OVERFLOWS_TYPE(u16, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u16, s16, (u16)S16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u16, s16, U16_MAX, true);
+	TEST_OVERFLOWS_TYPE(u16, u32, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u16, s32, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, u8, (s16)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s16, u8, -1, true);
+	TEST_OVERFLOWS_TYPE(s16, u8, S16_MIN, true);
+	TEST_OVERFLOWS_TYPE(s16, u16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, u16, -1, true);
+	TEST_OVERFLOWS_TYPE(s16, u16, S16_MIN, true);
+	TEST_OVERFLOWS_TYPE(s16, u32, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, u32, -1, true);
+	TEST_OVERFLOWS_TYPE(s16, u32, S16_MIN, true);
+#if BITS_PER_LONG == 64
+	TEST_OVERFLOWS_TYPE(s16, u64, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, u64, -1, true);
+	TEST_OVERFLOWS_TYPE(s16, u64, S16_MIN, true);
+#endif
+	TEST_OVERFLOWS_TYPE(s16, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, s8, S8_MIN, false);
+	TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s16, s8, S16_MAX, true);
+	TEST_OVERFLOWS_TYPE(s16, s8, S16_MIN, true);
+	TEST_OVERFLOWS_TYPE(s16, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, s16, S16_MIN, false);
+	TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
+	TEST_OVERFLOWS_TYPE(u32, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, u8, (u32)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u32, u8, U32_MAX, true);
+	TEST_OVERFLOWS_TYPE(u32, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, s8, (u32)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u32, s8, U32_MAX, true);
+	TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u32, u16, U32_MAX, true);
+	TEST_OVERFLOWS_TYPE(u32, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, s16, (u32)S16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u32, s16, U32_MAX, true);
+	TEST_OVERFLOWS_TYPE(u32, u32, U32_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, s32, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, s32, U32_MAX, true);
+	TEST_OVERFLOWS_TYPE(u32, s32, (u32)S32_MAX + 1, true);
+#if BITS_PER_LONG == 64
+	TEST_OVERFLOWS_TYPE(u32, u64, U32_MAX, false);
+	TEST_OVERFLOWS_TYPE(u32, s64, U32_MAX, false);
+#endif
+	TEST_OVERFLOWS_TYPE(s32, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, u8, (s32)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
+	TEST_OVERFLOWS_TYPE(s32, u8, -1, true);
+	TEST_OVERFLOWS_TYPE(s32, u8, S32_MIN, true);
+	TEST_OVERFLOWS_TYPE(s32, u16, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, u16, (s32)U16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
+	TEST_OVERFLOWS_TYPE(s32, u16, -1, true);
+	TEST_OVERFLOWS_TYPE(s32, u16, S32_MIN, true);
+	TEST_OVERFLOWS_TYPE(s32, u32, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, u32, -1, true);
+	TEST_OVERFLOWS_TYPE(s32, u32, S32_MIN, true);
+#if BITS_PER_LONG == 64
+	TEST_OVERFLOWS_TYPE(s32, u64, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, u64, -1, true);
+	TEST_OVERFLOWS_TYPE(s32, u64, S32_MIN, true);
+#endif
+	TEST_OVERFLOWS_TYPE(s32, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, s8, S8_MIN, false);
+	TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s32, s8, S32_MAX, true);
+	TEST_OVERFLOWS_TYPE(s32, s8, S32_MIN, true);
+	TEST_OVERFLOWS_TYPE(s32, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, s16, S16_MIN, false);
+	TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s32, s16, S32_MAX, true);
+	TEST_OVERFLOWS_TYPE(s32, s16, S32_MIN, true);
+	TEST_OVERFLOWS_TYPE(s32, s32, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, s32, S32_MIN, false);
+#if BITS_PER_LONG == 64
+	TEST_OVERFLOWS_TYPE(s32, s64, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s32, s64, S32_MIN, false);
+	TEST_OVERFLOWS_TYPE(u64, u8, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, u8, (u64)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, u16, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, u16, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, u16, (u64)U16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, u32, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, u32, U32_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, u32, (u64)U32_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, u64, U64_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, s8, (u64)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, s8, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, s16, (u64)S16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, s16, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, s32, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, s32, (u64)S32_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(u64, s32, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, s64, S64_MAX, false);
+	TEST_OVERFLOWS_TYPE(u64, s64, U64_MAX, true);
+	TEST_OVERFLOWS_TYPE(u64, s64, (u64)S64_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, u8, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, u8, S64_MIN, true);
+	TEST_OVERFLOWS_TYPE(s64, u8, -1, true);
+	TEST_OVERFLOWS_TYPE(s64, u8, U8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, u8, (s64)U8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, u16, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, u16, S64_MIN, true);
+	TEST_OVERFLOWS_TYPE(s64, u16, -1, true);
+	TEST_OVERFLOWS_TYPE(s64, u16, U16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, u16, (s64)U16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, u32, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, u32, S64_MIN, true);
+	TEST_OVERFLOWS_TYPE(s64, u32, -1, true);
+	TEST_OVERFLOWS_TYPE(s64, u32, U32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, u32, (s64)U32_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, u64, S64_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, u64, S64_MIN, true);
+	TEST_OVERFLOWS_TYPE(s64, u64, -1, true);
+	TEST_OVERFLOWS_TYPE(s64, s8, S8_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, s8, S8_MIN, false);
+	TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s8, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, s16, S16_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, s16, S16_MIN, false);
+	TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s16, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, s32, S32_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, s32, S32_MIN, false);
+	TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MAX + 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MIN - 1, true);
+	TEST_OVERFLOWS_TYPE(s64, s32, S64_MAX, true);
+	TEST_OVERFLOWS_TYPE(s64, s64, S64_MAX, false);
+	TEST_OVERFLOWS_TYPE(s64, s64, S64_MIN, false);
+#endif
+
+	/* Check for macro side-effects. */
+	var = INT_MAX - 1;
+	__TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, false);
+	__TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, false);
+	__TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, true);
+	var = INT_MAX - 1;
+	__TEST_OVERFLOWS_TYPE(overflows_type, var++, int, false);
+	__TEST_OVERFLOWS_TYPE(overflows_type, var++, int, false);
+	__TEST_OVERFLOWS_TYPE(overflows_type, var++, int, true);
+
+	kunit_info(test, "%d overflows_type() tests finished\n", count);
+#undef TEST_OVERFLOWS_TYPE
+#undef __TEST_OVERFLOWS_TYPE
+}
+
+static void same_type_test(struct kunit *test)
+{
+	int count = 0;
+	int var;
+
+#define TEST_SAME_TYPE(t1, t2, same)			do {	\
+	typeof(t1) __t1h = type_max(t1);			\
+	typeof(t1) __t1l = type_min(t1);			\
+	typeof(t2) __t2h = type_max(t2);			\
+	typeof(t2) __t2l = type_min(t2);			\
+	KUNIT_EXPECT_EQ(test, true, __same_type(t1, __t1h));	\
+	KUNIT_EXPECT_EQ(test, true, __same_type(t1, __t1l));	\
+	KUNIT_EXPECT_EQ(test, true, __same_type(__t1h, t1));	\
+	KUNIT_EXPECT_EQ(test, true, __same_type(__t1l, t1));	\
+	KUNIT_EXPECT_EQ(test, true, __same_type(t2, __t2h));	\
+	KUNIT_EXPECT_EQ(test, true, __same_type(t2, __t2l));	\
+	KUNIT_EXPECT_EQ(test, true, __same_type(__t2h, t2));	\
+	KUNIT_EXPECT_EQ(test, true, __same_type(__t2l, t2));	\
+	KUNIT_EXPECT_EQ(test, same, __same_type(t1, t2));	\
+	KUNIT_EXPECT_EQ(test, same, __same_type(t2, __t1h));	\
+	KUNIT_EXPECT_EQ(test, same, __same_type(t2, __t1l));	\
+	KUNIT_EXPECT_EQ(test, same, __same_type(__t1h, t2));	\
+	KUNIT_EXPECT_EQ(test, same, __same_type(__t1l, t2));	\
+	KUNIT_EXPECT_EQ(test, same, __same_type(t1, __t2h));	\
+	KUNIT_EXPECT_EQ(test, same, __same_type(t1, __t2l));	\
+	KUNIT_EXPECT_EQ(test, same, __same_type(__t2h, t1));	\
+	KUNIT_EXPECT_EQ(test, same, __same_type(__t2l, t1));	\
+} while (0)
+
+#if BITS_PER_LONG == 64
+# define TEST_SAME_TYPE64(base, t, m)	TEST_SAME_TYPE(base, t, m)
+#else
+# define TEST_SAME_TYPE64(base, t, m)	do { } while (0)
+#endif
+
+#define TEST_TYPE_SETS(base, mu8, mu16, mu32, ms8, ms16, ms32, mu64, ms64) \
+do {									\
+	TEST_SAME_TYPE(base,  u8,  mu8);				\
+	TEST_SAME_TYPE(base, u16, mu16);				\
+	TEST_SAME_TYPE(base, u32, mu32);				\
+	TEST_SAME_TYPE(base,  s8,  ms8);				\
+	TEST_SAME_TYPE(base, s16, ms16);				\
+	TEST_SAME_TYPE(base, s32, ms32);				\
+	TEST_SAME_TYPE64(base, u64, mu64);				\
+	TEST_SAME_TYPE64(base, s64, ms64);				\
+} while (0)
+
+	TEST_TYPE_SETS(u8,   true, false, false, false, false, false, false, false);
+	TEST_TYPE_SETS(u16, false,  true, false, false, false, false, false, false);
+	TEST_TYPE_SETS(u32, false, false,  true, false, false, false, false, false);
+	TEST_TYPE_SETS(s8,  false, false, false,  true, false, false, false, false);
+	TEST_TYPE_SETS(s16, false, false, false, false,  true, false, false, false);
+	TEST_TYPE_SETS(s32, false, false, false, false, false,  true, false, false);
+#if BITS_PER_LONG == 64
+	TEST_TYPE_SETS(u64, false, false, false, false, false, false,  true, false);
+	TEST_TYPE_SETS(s64, false, false, false, false, false, false, false,  true);
+#endif
+
+	/* Check for macro side-effects. */
+	var = 4;
+	KUNIT_EXPECT_EQ(test, var, 4);
+	KUNIT_EXPECT_TRUE(test, __same_type(var++, int));
+	KUNIT_EXPECT_EQ(test, var, 4);
+	KUNIT_EXPECT_TRUE(test, __same_type(int, var++));
+	KUNIT_EXPECT_EQ(test, var, 4);
+	KUNIT_EXPECT_TRUE(test, __same_type(var++, var++));
+	KUNIT_EXPECT_EQ(test, var, 4);
+
+	kunit_info(test, "%d __same_type() tests finished\n", count);
+
+#undef TEST_TYPE_SETS
+#undef TEST_SAME_TYPE64
+#undef TEST_SAME_TYPE
+}
+
+static void castable_to_type_test(struct kunit *test)
+{
+	int count = 0;
+
+#define TEST_CASTABLE_TO_TYPE(arg1, arg2, pass)	do {	\
+	bool __pass = castable_to_type(arg1, arg2);		\
+	KUNIT_EXPECT_EQ_MSG(test, __pass, pass,			\
+		"expected castable_to_type(" #arg1 ", " #arg2 ") to%s pass\n",\
+		pass ? "" : " not");				\
+	count++;						\
+} while (0)
+
+	TEST_CASTABLE_TO_TYPE(16, u8, true);
+	TEST_CASTABLE_TO_TYPE(16, u16, true);
+	TEST_CASTABLE_TO_TYPE(16, u32, true);
+	TEST_CASTABLE_TO_TYPE(16, s8, true);
+	TEST_CASTABLE_TO_TYPE(16, s16, true);
+	TEST_CASTABLE_TO_TYPE(16, s32, true);
+	TEST_CASTABLE_TO_TYPE(-16, s8, true);
+	TEST_CASTABLE_TO_TYPE(-16, s16, true);
+	TEST_CASTABLE_TO_TYPE(-16, s32, true);
+#if BITS_PER_LONG == 64
+	TEST_CASTABLE_TO_TYPE(16, u64, true);
+	TEST_CASTABLE_TO_TYPE(-16, s64, true);
+#endif
+
+#define TEST_CASTABLE_TO_TYPE_VAR(width)	do {				\
+	u ## width u ## width ## var = 0;					\
+	s ## width s ## width ## var = 0;					\
+										\
+	/* Constant expressions that fit types. */				\
+	TEST_CASTABLE_TO_TYPE(type_max(u ## width), u ## width, true);		\
+	TEST_CASTABLE_TO_TYPE(type_min(u ## width), u ## width, true);		\
+	TEST_CASTABLE_TO_TYPE(type_max(u ## width), u ## width ## var, true);	\
+	TEST_CASTABLE_TO_TYPE(type_min(u ## width), u ## width ## var, true);	\
+	TEST_CASTABLE_TO_TYPE(type_max(s ## width), s ## width, true);		\
+	TEST_CASTABLE_TO_TYPE(type_min(s ## width), s ## width, true);		\
+	TEST_CASTABLE_TO_TYPE(type_max(s ## width), s ## width ## var, true);	\
+	TEST_CASTABLE_TO_TYPE(type_min(u ## width), s ## width ## var, true);	\
+	/* Constant expressions that do not fit types. */			\
+	TEST_CASTABLE_TO_TYPE(type_max(u ## width), s ## width, false);		\
+	TEST_CASTABLE_TO_TYPE(type_max(u ## width), s ## width ## var, false);	\
+	TEST_CASTABLE_TO_TYPE(type_min(s ## width), u ## width, false);		\
+	TEST_CASTABLE_TO_TYPE(type_min(s ## width), u ## width ## var, false);	\
+	/* Non-constant expression with mismatched type. */			\
+	TEST_CASTABLE_TO_TYPE(s ## width ## var, u ## width, false);		\
+	TEST_CASTABLE_TO_TYPE(u ## width ## var, s ## width, false);		\
+} while (0)
+
+#define TEST_CASTABLE_TO_TYPE_RANGE(width)	do {				\
+	unsigned long big = U ## width ## _MAX;					\
+	signed long small = S ## width ## _MIN;					\
+	u ## width u ## width ## var = 0;					\
+	s ## width s ## width ## var = 0;					\
+										\
+	/* Constant expression in range. */					\
+	TEST_CASTABLE_TO_TYPE(U ## width ## _MAX, u ## width, true);		\
+	TEST_CASTABLE_TO_TYPE(U ## width ## _MAX, u ## width ## var, true);	\
+	TEST_CASTABLE_TO_TYPE(S ## width ## _MIN, s ## width, true);		\
+	TEST_CASTABLE_TO_TYPE(S ## width ## _MIN, s ## width ## var, true);	\
+	/* Constant expression out of range. */					\
+	TEST_CASTABLE_TO_TYPE((unsigned long)U ## width ## _MAX + 1, u ## width, false); \
+	TEST_CASTABLE_TO_TYPE((unsigned long)U ## width ## _MAX + 1, u ## width ## var, false); \
+	TEST_CASTABLE_TO_TYPE((signed long)S ## width ## _MIN - 1, s ## width, false); \
+	TEST_CASTABLE_TO_TYPE((signed long)S ## width ## _MIN - 1, s ## width ## var, false); \
+	/* Non-constant expression with mismatched type. */			\
+	TEST_CASTABLE_TO_TYPE(big, u ## width, false);				\
+	TEST_CASTABLE_TO_TYPE(big, u ## width ## var, false);			\
+	TEST_CASTABLE_TO_TYPE(small, s ## width, false);			\
+	TEST_CASTABLE_TO_TYPE(small, s ## width ## var, false);			\
+} while (0)
+
+	TEST_CASTABLE_TO_TYPE_VAR(8);
+	TEST_CASTABLE_TO_TYPE_VAR(16);
+	TEST_CASTABLE_TO_TYPE_VAR(32);
+#if BITS_PER_LONG == 64
+	TEST_CASTABLE_TO_TYPE_VAR(64);
+#endif
+
+	TEST_CASTABLE_TO_TYPE_RANGE(8);
+	TEST_CASTABLE_TO_TYPE_RANGE(16);
+#if BITS_PER_LONG == 64
+	TEST_CASTABLE_TO_TYPE_RANGE(32);
+#endif
+	kunit_info(test, "%d castable_to_type() tests finished\n", count);
+
+#undef TEST_CASTABLE_TO_TYPE_RANGE
+#undef TEST_CASTABLE_TO_TYPE_VAR
+#undef TEST_CASTABLE_TO_TYPE
+}
+
+struct foo {
+	int a;
+	u32 counter;
+	s16 array[] __counted_by(counter);
+};
+
+struct bar {
+	int a;
+	u32 counter;
+	s16 array[];
+};
+
+static void DEFINE_FLEX_test(struct kunit *test)
+{
+	/* Using _RAW_ on a __counted_by struct will initialize "counter" to zero */
+	DEFINE_RAW_FLEX(struct foo, two_but_zero, array, 2);
+#if __has_attribute(__counted_by__)
+	int expected_raw_size = sizeof(struct foo);
+#else
+	int expected_raw_size = sizeof(struct foo) + 2 * sizeof(s16);
+#endif
+	/* Without annotation, it will always be on-stack size. */
+	DEFINE_RAW_FLEX(struct bar, two, array, 2);
+	DEFINE_FLEX(struct foo, eight, array, counter, 8);
+	DEFINE_FLEX(struct foo, empty, array, counter, 0);
+
+	KUNIT_EXPECT_EQ(test, __struct_size(two_but_zero), expected_raw_size);
+	KUNIT_EXPECT_EQ(test, __struct_size(two), sizeof(struct bar) + 2 * sizeof(s16));
+	KUNIT_EXPECT_EQ(test, __struct_size(eight), 24);
+	KUNIT_EXPECT_EQ(test, __struct_size(empty), sizeof(struct foo));
+}
+
+static struct kunit_case overflow_test_cases[] = {
+	KUNIT_CASE(u8_u8__u8_overflow_test),
+	KUNIT_CASE(s8_s8__s8_overflow_test),
+	KUNIT_CASE(u16_u16__u16_overflow_test),
+	KUNIT_CASE(s16_s16__s16_overflow_test),
+	KUNIT_CASE(u32_u32__u32_overflow_test),
+	KUNIT_CASE(s32_s32__s32_overflow_test),
+	KUNIT_CASE(u64_u64__u64_overflow_test),
+	KUNIT_CASE(s64_s64__s64_overflow_test),
+	KUNIT_CASE(u32_u32__int_overflow_test),
+	KUNIT_CASE(u32_u32__u8_overflow_test),
+	KUNIT_CASE(u8_u8__int_overflow_test),
+	KUNIT_CASE(int_int__u8_overflow_test),
+	KUNIT_CASE(shift_sane_test),
+	KUNIT_CASE(shift_overflow_test),
+	KUNIT_CASE(shift_truncate_test),
+	KUNIT_CASE(shift_nonsense_test),
+	KUNIT_CASE(overflow_allocation_test),
+	KUNIT_CASE(overflow_size_helpers_test),
+	KUNIT_CASE(overflows_type_test),
+	KUNIT_CASE(same_type_test),
+	KUNIT_CASE(castable_to_type_test),
+	KUNIT_CASE(DEFINE_FLEX_test),
+	{}
+};
+
+static struct kunit_suite overflow_test_suite = {
+	.name = "overflow",
+	.test_cases = overflow_test_cases,
+};
+
+kunit_test_suite(overflow_test_suite);
+
+MODULE_DESCRIPTION("Test cases for arithmetic overflow checks");
+MODULE_LICENSE("Dual MIT/GPL");
diff --git a/lib/tests/siphash_kunit.c a/lib/tests/siphash_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/siphash_kunit.c
@@ -0,0 +1,198 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+/* Copyright (C) 2016-2022 Jason A. Donenfeld <Jason@xxxxxxxxx>. All Rights Reserved.
+ *
+ * Test cases for siphash.c
+ *
+ * SipHash: a fast short-input PRF
+ * https://131002.net/siphash/
+ *
+ * This implementation is specifically for SipHash2-4 for a secure PRF
+ * and HalfSipHash1-3/SipHash1-3 for an insecure PRF only suitable for
+ * hashtables.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <kunit/test.h>
+#include <linux/siphash.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+
+/* Test vectors taken from reference source available at:
+ *     https://github.com/veorq/SipHash
+ */
+
+static const siphash_key_t test_key_siphash =
+	{{ 0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL }};
+
+static const u64 test_vectors_siphash[64] = {
+	0x726fdb47dd0e0e31ULL, 0x74f839c593dc67fdULL, 0x0d6c8009d9a94f5aULL,
+	0x85676696d7fb7e2dULL, 0xcf2794e0277187b7ULL, 0x18765564cd99a68dULL,
+	0xcbc9466e58fee3ceULL, 0xab0200f58b01d137ULL, 0x93f5f5799a932462ULL,
+	0x9e0082df0ba9e4b0ULL, 0x7a5dbbc594ddb9f3ULL, 0xf4b32f46226bada7ULL,
+	0x751e8fbc860ee5fbULL, 0x14ea5627c0843d90ULL, 0xf723ca908e7af2eeULL,
+	0xa129ca6149be45e5ULL, 0x3f2acc7f57c29bdbULL, 0x699ae9f52cbe4794ULL,
+	0x4bc1b3f0968dd39cULL, 0xbb6dc91da77961bdULL, 0xbed65cf21aa2ee98ULL,
+	0xd0f2cbb02e3b67c7ULL, 0x93536795e3a33e88ULL, 0xa80c038ccd5ccec8ULL,
+	0xb8ad50c6f649af94ULL, 0xbce192de8a85b8eaULL, 0x17d835b85bbb15f3ULL,
+	0x2f2e6163076bcfadULL, 0xde4daaaca71dc9a5ULL, 0xa6a2506687956571ULL,
+	0xad87a3535c49ef28ULL, 0x32d892fad841c342ULL, 0x7127512f72f27cceULL,
+	0xa7f32346f95978e3ULL, 0x12e0b01abb051238ULL, 0x15e034d40fa197aeULL,
+	0x314dffbe0815a3b4ULL, 0x027990f029623981ULL, 0xcadcd4e59ef40c4dULL,
+	0x9abfd8766a33735cULL, 0x0e3ea96b5304a7d0ULL, 0xad0c42d6fc585992ULL,
+	0x187306c89bc215a9ULL, 0xd4a60abcf3792b95ULL, 0xf935451de4f21df2ULL,
+	0xa9538f0419755787ULL, 0xdb9acddff56ca510ULL, 0xd06c98cd5c0975ebULL,
+	0xe612a3cb9ecba951ULL, 0xc766e62cfcadaf96ULL, 0xee64435a9752fe72ULL,
+	0xa192d576b245165aULL, 0x0a8787bf8ecb74b2ULL, 0x81b3e73d20b49b6fULL,
+	0x7fa8220ba3b2eceaULL, 0x245731c13ca42499ULL, 0xb78dbfaf3a8d83bdULL,
+	0xea1ad565322a1a0bULL, 0x60e61c23a3795013ULL, 0x6606d7e446282b93ULL,
+	0x6ca4ecb15c5f91e1ULL, 0x9f626da15c9625f3ULL, 0xe51b38608ef25f57ULL,
+	0x958a324ceb064572ULL
+};
+
+#if BITS_PER_LONG == 64
+static const hsiphash_key_t test_key_hsiphash =
+	{{ 0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL }};
+
+static const u32 test_vectors_hsiphash[64] = {
+	0x050fc4dcU, 0x7d57ca93U, 0x4dc7d44dU,
+	0xe7ddf7fbU, 0x88d38328U, 0x49533b67U,
+	0xc59f22a7U, 0x9bb11140U, 0x8d299a8eU,
+	0x6c063de4U, 0x92ff097fU, 0xf94dc352U,
+	0x57b4d9a2U, 0x1229ffa7U, 0xc0f95d34U,
+	0x2a519956U, 0x7d908b66U, 0x63dbd80cU,
+	0xb473e63eU, 0x8d297d1cU, 0xa6cce040U,
+	0x2b45f844U, 0xa320872eU, 0xdae6c123U,
+	0x67349c8cU, 0x705b0979U, 0xca9913a5U,
+	0x4ade3b35U, 0xef6cd00dU, 0x4ab1e1f4U,
+	0x43c5e663U, 0x8c21d1bcU, 0x16a7b60dU,
+	0x7a8ff9bfU, 0x1f2a753eU, 0xbf186b91U,
+	0xada26206U, 0xa3c33057U, 0xae3a36a1U,
+	0x7b108392U, 0x99e41531U, 0x3f1ad944U,
+	0xc8138825U, 0xc28949a6U, 0xfaf8876bU,
+	0x9f042196U, 0x68b1d623U, 0x8b5114fdU,
+	0xdf074c46U, 0x12cc86b3U, 0x0a52098fU,
+	0x9d292f9aU, 0xa2f41f12U, 0x43a71ed0U,
+	0x73f0bce6U, 0x70a7e980U, 0x243c6d75U,
+	0xfdb71513U, 0xa67d8a08U, 0xb7e8f148U,
+	0xf7a644eeU, 0x0f1837f2U, 0x4b6694e0U,
+	0xb7bbb3a8U
+};
+#else
+static const hsiphash_key_t test_key_hsiphash =
+	{{ 0x03020100U, 0x07060504U }};
+
+static const u32 test_vectors_hsiphash[64] = {
+	0x5814c896U, 0xe7e864caU, 0xbc4b0e30U,
+	0x01539939U, 0x7e059ea6U, 0x88e3d89bU,
+	0xa0080b65U, 0x9d38d9d6U, 0x577999b1U,
+	0xc839caedU, 0xe4fa32cfU, 0x959246eeU,
+	0x6b28096cU, 0x66dd9cd6U, 0x16658a7cU,
+	0xd0257b04U, 0x8b31d501U, 0x2b1cd04bU,
+	0x06712339U, 0x522aca67U, 0x911bb605U,
+	0x90a65f0eU, 0xf826ef7bU, 0x62512debU,
+	0x57150ad7U, 0x5d473507U, 0x1ec47442U,
+	0xab64afd3U, 0x0a4100d0U, 0x6d2ce652U,
+	0x2331b6a3U, 0x08d8791aU, 0xbc6dda8dU,
+	0xe0f6c934U, 0xb0652033U, 0x9b9851ccU,
+	0x7c46fb7fU, 0x732ba8cbU, 0xf142997aU,
+	0xfcc9aa1bU, 0x05327eb2U, 0xe110131cU,
+	0xf9e5e7c0U, 0xa7d708a6U, 0x11795ab1U,
+	0x65671619U, 0x9f5fff91U, 0xd89c5267U,
+	0x007783ebU, 0x95766243U, 0xab639262U,
+	0x9c7e1390U, 0xc368dda6U, 0x38ddc455U,
+	0xfa13d379U, 0x979ea4e8U, 0x53ecd77eU,
+	0x2ee80657U, 0x33dbb66aU, 0xae3f0577U,
+	0x88b4c4ccU, 0x3e7f480bU, 0x74c1ebf8U,
+	0x87178304U
+};
+#endif
+
+#define chk(hash, vector, fmt...)			\
+	KUNIT_EXPECT_EQ_MSG(test, hash, vector, fmt)
+
+static void siphash_test(struct kunit *test)
+{
+	u8 in[64] __aligned(SIPHASH_ALIGNMENT);
+	u8 in_unaligned[65] __aligned(SIPHASH_ALIGNMENT);
+	u8 i;
+
+	for (i = 0; i < 64; ++i) {
+		in[i] = i;
+		in_unaligned[i + 1] = i;
+		chk(siphash(in, i, &test_key_siphash),
+		    test_vectors_siphash[i],
+		    "siphash self-test aligned %u: FAIL", i + 1);
+		chk(siphash(in_unaligned + 1, i, &test_key_siphash),
+		    test_vectors_siphash[i],
+		    "siphash self-test unaligned %u: FAIL", i + 1);
+		chk(hsiphash(in, i, &test_key_hsiphash),
+		    test_vectors_hsiphash[i],
+		    "hsiphash self-test aligned %u: FAIL", i + 1);
+		chk(hsiphash(in_unaligned + 1, i, &test_key_hsiphash),
+		    test_vectors_hsiphash[i],
+		    "hsiphash self-test unaligned %u: FAIL", i + 1);
+	}
+	chk(siphash_1u64(0x0706050403020100ULL, &test_key_siphash),
+	    test_vectors_siphash[8],
+	    "siphash self-test 1u64: FAIL");
+	chk(siphash_2u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
+			 &test_key_siphash),
+	    test_vectors_siphash[16],
+	    "siphash self-test 2u64: FAIL");
+	chk(siphash_3u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
+			 0x1716151413121110ULL, &test_key_siphash),
+	    test_vectors_siphash[24],
+	    "siphash self-test 3u64: FAIL");
+	chk(siphash_4u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
+			 0x1716151413121110ULL, 0x1f1e1d1c1b1a1918ULL,
+			 &test_key_siphash),
+	    test_vectors_siphash[32],
+	    "siphash self-test 4u64: FAIL");
+	chk(siphash_1u32(0x03020100U, &test_key_siphash),
+	    test_vectors_siphash[4],
+	    "siphash self-test 1u32: FAIL");
+	chk(siphash_2u32(0x03020100U, 0x07060504U, &test_key_siphash),
+	    test_vectors_siphash[8],
+	    "siphash self-test 2u32: FAIL");
+	chk(siphash_3u32(0x03020100U, 0x07060504U,
+			 0x0b0a0908U, &test_key_siphash),
+	    test_vectors_siphash[12],
+	    "siphash self-test 3u32: FAIL");
+	chk(siphash_4u32(0x03020100U, 0x07060504U,
+			 0x0b0a0908U, 0x0f0e0d0cU, &test_key_siphash),
+	    test_vectors_siphash[16],
+	    "siphash self-test 4u32: FAIL");
+	chk(hsiphash_1u32(0x03020100U, &test_key_hsiphash),
+	    test_vectors_hsiphash[4],
+	    "hsiphash self-test 1u32: FAIL");
+	chk(hsiphash_2u32(0x03020100U, 0x07060504U, &test_key_hsiphash),
+	    test_vectors_hsiphash[8],
+	    "hsiphash self-test 2u32: FAIL");
+	chk(hsiphash_3u32(0x03020100U, 0x07060504U,
+			  0x0b0a0908U, &test_key_hsiphash),
+	    test_vectors_hsiphash[12],
+	    "hsiphash self-test 3u32: FAIL");
+	chk(hsiphash_4u32(0x03020100U, 0x07060504U,
+			  0x0b0a0908U, 0x0f0e0d0cU, &test_key_hsiphash),
+	    test_vectors_hsiphash[16],
+	    "hsiphash self-test 4u32: FAIL");
+}
+
+static struct kunit_case siphash_test_cases[] = {
+	KUNIT_CASE(siphash_test),
+	{}
+};
+
+static struct kunit_suite siphash_test_suite = {
+	.name = "siphash",
+	.test_cases = siphash_test_cases,
+};
+
+kunit_test_suite(siphash_test_suite);
+
+MODULE_AUTHOR("Jason A. Donenfeld <Jason@xxxxxxxxx>");
+MODULE_DESCRIPTION("Test cases for siphash.c");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/lib/tests/slub_kunit.c a/lib/tests/slub_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/slub_kunit.c
@@ -0,0 +1,227 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <kunit/test.h>
+#include <kunit/test-bug.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/rcupdate.h>
+#include "../mm/slab.h"
+
+static struct kunit_resource resource;
+static int slab_errors;
+
+/*
+ * Wrapper function for kmem_cache_create(), which reduces 2 parameters:
+ * 'align' and 'ctor', and sets SLAB_SKIP_KFENCE flag to avoid getting an
+ * object from kfence pool, where the operation could be caught by both
+ * our test and kfence sanity check.
+ */
+static struct kmem_cache *test_kmem_cache_create(const char *name,
+				unsigned int size, slab_flags_t flags)
+{
+	struct kmem_cache *s = kmem_cache_create(name, size, 0,
+					(flags | SLAB_NO_USER_FLAGS), NULL);
+	s->flags |= SLAB_SKIP_KFENCE;
+	return s;
+}
+
+static void test_clobber_zone(struct kunit *test)
+{
+	struct kmem_cache *s = test_kmem_cache_create("TestSlub_RZ_alloc", 64,
+							SLAB_RED_ZONE);
+	u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+
+	kasan_disable_current();
+	p[64] = 0x12;
+
+	validate_slab_cache(s);
+	KUNIT_EXPECT_EQ(test, 2, slab_errors);
+
+	kasan_enable_current();
+	kmem_cache_free(s, p);
+	kmem_cache_destroy(s);
+}
+
+#ifndef CONFIG_KASAN
+static void test_next_pointer(struct kunit *test)
+{
+	struct kmem_cache *s = test_kmem_cache_create("TestSlub_next_ptr_free",
+							64, SLAB_POISON);
+	u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+	unsigned long tmp;
+	unsigned long *ptr_addr;
+
+	kmem_cache_free(s, p);
+
+	ptr_addr = (unsigned long *)(p + s->offset);
+	tmp = *ptr_addr;
+	p[s->offset] = ~p[s->offset];
+
+	/*
+	 * Expecting three errors.
+	 * One for the corrupted freechain and the other one for the wrong
+	 * count of objects in use. The third error is fixing broken cache.
+	 */
+	validate_slab_cache(s);
+	KUNIT_EXPECT_EQ(test, 3, slab_errors);
+
+	/*
+	 * Try to repair corrupted freepointer.
+	 * Still expecting two errors. The first for the wrong count
+	 * of objects in use.
+	 * The second error is for fixing broken cache.
+	 */
+	*ptr_addr = tmp;
+	slab_errors = 0;
+
+	validate_slab_cache(s);
+	KUNIT_EXPECT_EQ(test, 2, slab_errors);
+
+	/*
+	 * Previous validation repaired the count of objects in use.
+	 * Now expecting no error.
+	 */
+	slab_errors = 0;
+	validate_slab_cache(s);
+	KUNIT_EXPECT_EQ(test, 0, slab_errors);
+
+	kmem_cache_destroy(s);
+}
+
+static void test_first_word(struct kunit *test)
+{
+	struct kmem_cache *s = test_kmem_cache_create("TestSlub_1th_word_free",
+							64, SLAB_POISON);
+	u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+
+	kmem_cache_free(s, p);
+	*p = 0x78;
+
+	validate_slab_cache(s);
+	KUNIT_EXPECT_EQ(test, 2, slab_errors);
+
+	kmem_cache_destroy(s);
+}
+
+static void test_clobber_50th_byte(struct kunit *test)
+{
+	struct kmem_cache *s = test_kmem_cache_create("TestSlub_50th_word_free",
+							64, SLAB_POISON);
+	u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+
+	kmem_cache_free(s, p);
+	p[50] = 0x9a;
+
+	validate_slab_cache(s);
+	KUNIT_EXPECT_EQ(test, 2, slab_errors);
+
+	kmem_cache_destroy(s);
+}
+#endif
+
+static void test_clobber_redzone_free(struct kunit *test)
+{
+	struct kmem_cache *s = test_kmem_cache_create("TestSlub_RZ_free", 64,
+							SLAB_RED_ZONE);
+	u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
+
+	kasan_disable_current();
+	kmem_cache_free(s, p);
+	p[64] = 0xab;
+
+	validate_slab_cache(s);
+	KUNIT_EXPECT_EQ(test, 2, slab_errors);
+
+	kasan_enable_current();
+	kmem_cache_destroy(s);
+}
+
+static void test_kmalloc_redzone_access(struct kunit *test)
+{
+	struct kmem_cache *s = test_kmem_cache_create("TestSlub_RZ_kmalloc", 32,
+				SLAB_KMALLOC|SLAB_STORE_USER|SLAB_RED_ZONE);
+	u8 *p = __kmalloc_cache_noprof(s, GFP_KERNEL, 18);
+
+	kasan_disable_current();
+
+	/* Suppress the -Warray-bounds warning */
+	OPTIMIZER_HIDE_VAR(p);
+	p[18] = 0xab;
+	p[19] = 0xab;
+
+	validate_slab_cache(s);
+	KUNIT_EXPECT_EQ(test, 2, slab_errors);
+
+	kasan_enable_current();
+	kmem_cache_free(s, p);
+	kmem_cache_destroy(s);
+}
+
+struct test_kfree_rcu_struct {
+	struct rcu_head rcu;
+};
+
+static void test_kfree_rcu(struct kunit *test)
+{
+	struct kmem_cache *s;
+	struct test_kfree_rcu_struct *p;
+
+	if (IS_BUILTIN(CONFIG_SLUB_KUNIT_TEST))
+		kunit_skip(test, "can't do kfree_rcu() when test is built-in");
+
+	s = test_kmem_cache_create("TestSlub_kfree_rcu",
+				   sizeof(struct test_kfree_rcu_struct),
+				   SLAB_NO_MERGE);
+	p = kmem_cache_alloc(s, GFP_KERNEL);
+
+	kfree_rcu(p, rcu);
+	kmem_cache_destroy(s);
+
+	KUNIT_EXPECT_EQ(test, 0, slab_errors);
+}
+
+static void test_leak_destroy(struct kunit *test)
+{
+	struct kmem_cache *s = test_kmem_cache_create("TestSlub_leak_destroy",
+							64, SLAB_NO_MERGE);
+	kmem_cache_alloc(s, GFP_KERNEL);
+
+	kmem_cache_destroy(s);
+
+	KUNIT_EXPECT_EQ(test, 2, slab_errors);
+}
+
+static int test_init(struct kunit *test)
+{
+	slab_errors = 0;
+
+	kunit_add_named_resource(test, NULL, NULL, &resource,
+					"slab_errors", &slab_errors);
+	return 0;
+}
+
+static struct kunit_case test_cases[] = {
+	KUNIT_CASE(test_clobber_zone),
+
+#ifndef CONFIG_KASAN
+	KUNIT_CASE(test_next_pointer),
+	KUNIT_CASE(test_first_word),
+	KUNIT_CASE(test_clobber_50th_byte),
+#endif
+
+	KUNIT_CASE(test_clobber_redzone_free),
+	KUNIT_CASE(test_kmalloc_redzone_access),
+	KUNIT_CASE(test_kfree_rcu),
+	KUNIT_CASE(test_leak_destroy),
+	{}
+};
+
+static struct kunit_suite test_suite = {
+	.name = "slub_test",
+	.init = test_init,
+	.test_cases = test_cases,
+};
+kunit_test_suite(test_suite);
+
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/stackinit_kunit.c a/lib/tests/stackinit_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/stackinit_kunit.c
@@ -0,0 +1,475 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Test cases for compiler-based stack variable zeroing via
+ * -ftrivial-auto-var-init={zero,pattern} or CONFIG_GCC_PLUGIN_STRUCTLEAK*.
+ * For example, see:
+ * "Running tests with kunit_tool" at Documentation/dev-tools/kunit/start.rst
+ *	./tools/testing/kunit/kunit.py run stackinit [--raw_output] \
+ *		--make_option LLVM=1 \
+ *		--kconfig_add CONFIG_INIT_STACK_ALL_ZERO=y
+ *
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <kunit/test.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+/* Exfiltration buffer. */
+#define MAX_VAR_SIZE	128
+static u8 check_buf[MAX_VAR_SIZE];
+
+/* Character array to trigger stack protector in all functions. */
+#define VAR_BUFFER	 32
+
+/* Volatile mask to convince compiler to copy memory with 0xff. */
+static volatile u8 forced_mask = 0xff;
+
+/* Location and size tracking to validate fill and test are colocated. */
+static void *fill_start, *target_start;
+static size_t fill_size, target_size;
+
+static bool stackinit_range_contains(char *haystack_start, size_t haystack_size,
+				     char *needle_start, size_t needle_size)
+{
+	if (needle_start >= haystack_start &&
+	    needle_start + needle_size <= haystack_start + haystack_size)
+		return true;
+	return false;
+}
+
+/* Whether the test is expected to fail. */
+#define WANT_SUCCESS				0
+#define XFAIL					1
+
+#define DO_NOTHING_TYPE_SCALAR(var_type)	var_type
+#define DO_NOTHING_TYPE_STRING(var_type)	void
+#define DO_NOTHING_TYPE_STRUCT(var_type)	void
+
+#define DO_NOTHING_RETURN_SCALAR(ptr)		*(ptr)
+#define DO_NOTHING_RETURN_STRING(ptr)		/**/
+#define DO_NOTHING_RETURN_STRUCT(ptr)		/**/
+
+#define DO_NOTHING_CALL_SCALAR(var, name)			\
+		(var) = do_nothing_ ## name(&(var))
+#define DO_NOTHING_CALL_STRING(var, name)			\
+		do_nothing_ ## name(var)
+#define DO_NOTHING_CALL_STRUCT(var, name)			\
+		do_nothing_ ## name(&(var))
+
+#define FETCH_ARG_SCALAR(var)		&var
+#define FETCH_ARG_STRING(var)		var
+#define FETCH_ARG_STRUCT(var)		&var
+
+/*
+ * On m68k, if the leaf function test variable is longer than 8 bytes,
+ * the start of the stack frame moves. 8 is sufficiently large to
+ * test m68k char arrays, but leave it at 16 for other architectures.
+ */
+#ifdef CONFIG_M68K
+#define FILL_SIZE_STRING		8
+#else
+#define FILL_SIZE_STRING		16
+#endif
+
+#define INIT_CLONE_SCALAR		/**/
+#define INIT_CLONE_STRING		[FILL_SIZE_STRING]
+#define INIT_CLONE_STRUCT		/**/
+
+#define ZERO_CLONE_SCALAR(zero)		memset(&(zero), 0x00, sizeof(zero))
+#define ZERO_CLONE_STRING(zero)		memset(&(zero), 0x00, sizeof(zero))
+/*
+ * For the struct, intentionally poison padding to see if it gets
+ * copied out in direct assignments.
+ * */
+#define ZERO_CLONE_STRUCT(zero)				\
+	do {						\
+		memset(&(zero), 0xFF, sizeof(zero));	\
+		zero.one = 0;				\
+		zero.two = 0;				\
+		zero.three = 0;				\
+		zero.four = 0;				\
+	} while (0)
+
+#define INIT_SCALAR_none(var_type)	/**/
+#define INIT_SCALAR_zero(var_type)	= 0
+
+#define INIT_STRING_none(var_type)	[FILL_SIZE_STRING] /**/
+#define INIT_STRING_zero(var_type)	[FILL_SIZE_STRING] = { }
+
+#define INIT_STRUCT_none(var_type)	/**/
+#define INIT_STRUCT_zero(var_type)	= { }
+
+
+#define __static_partial		{ .two = 0, }
+#define __static_all			{ .one = 0,			\
+					  .two = 0,			\
+					  .three = 0,			\
+					  .four = 0,			\
+					}
+#define __dynamic_partial		{ .two = arg->two, }
+#define __dynamic_all			{ .one = arg->one,		\
+					  .two = arg->two,		\
+					  .three = arg->three,		\
+					  .four = arg->four,		\
+					}
+#define __runtime_partial		var.two = 0
+#define __runtime_all			var.one = 0;			\
+					var.two = 0;			\
+					var.three = 0;			\
+					var.four = 0
+
+#define INIT_STRUCT_static_partial(var_type)				\
+					= __static_partial
+#define INIT_STRUCT_static_all(var_type)				\
+					= __static_all
+#define INIT_STRUCT_dynamic_partial(var_type)				\
+					= __dynamic_partial
+#define INIT_STRUCT_dynamic_all(var_type)				\
+					= __dynamic_all
+#define INIT_STRUCT_runtime_partial(var_type)				\
+					; __runtime_partial
+#define INIT_STRUCT_runtime_all(var_type)				\
+					; __runtime_all
+
+#define INIT_STRUCT_assigned_static_partial(var_type)			\
+					; var = (var_type)__static_partial
+#define INIT_STRUCT_assigned_static_all(var_type)			\
+					; var = (var_type)__static_all
+#define INIT_STRUCT_assigned_dynamic_partial(var_type)			\
+					; var = (var_type)__dynamic_partial
+#define INIT_STRUCT_assigned_dynamic_all(var_type)			\
+					; var = (var_type)__dynamic_all
+
+#define INIT_STRUCT_assigned_copy(var_type)				\
+					; var = *(arg)
+
+/*
+ * @name: unique string name for the test
+ * @var_type: type to be tested for zeroing initialization
+ * @which: is this a SCALAR, STRING, or STRUCT type?
+ * @init_level: what kind of initialization is performed
+ * @xfail: is this test expected to fail?
+ */
+#define DEFINE_TEST_DRIVER(name, var_type, which, xfail)	\
+/* Returns 0 on success, 1 on failure. */			\
+static noinline void test_ ## name (struct kunit *test)		\
+{								\
+	var_type zero INIT_CLONE_ ## which;			\
+	int ignored;						\
+	u8 sum = 0, i;						\
+								\
+	/* Notice when a new test is larger than expected. */	\
+	BUILD_BUG_ON(sizeof(zero) > MAX_VAR_SIZE);		\
+								\
+	/* Fill clone type with zero for per-field init. */	\
+	ZERO_CLONE_ ## which(zero);				\
+	/* Clear entire check buffer for 0xFF overlap test. */	\
+	memset(check_buf, 0x00, sizeof(check_buf));		\
+	/* Fill stack with 0xFF. */				\
+	ignored = leaf_ ##name((unsigned long)&ignored, 1,	\
+				FETCH_ARG_ ## which(zero));	\
+	/* Verify all bytes overwritten with 0xFF. */		\
+	for (sum = 0, i = 0; i < target_size; i++)		\
+		sum += (check_buf[i] != 0xFF);			\
+	/* Clear entire check buffer for later bit tests. */	\
+	memset(check_buf, 0x00, sizeof(check_buf));		\
+	/* Extract stack-defined variable contents. */		\
+	ignored = leaf_ ##name((unsigned long)&ignored, 0,	\
+				FETCH_ARG_ ## which(zero));	\
+	/*							\
+	 * Delay the sum test to here to do as little as	\
+	 * possible between the two leaf function calls.	\
+	 */							\
+	KUNIT_ASSERT_EQ_MSG(test, sum, 0,			\
+			    "leaf fill was not 0xFF!?\n");	\
+								\
+	/* Validate that compiler lined up fill and target. */	\
+	KUNIT_ASSERT_TRUE_MSG(test,				\
+		stackinit_range_contains(fill_start, fill_size,	\
+			    target_start, target_size),		\
+		"stackframe was not the same between calls!? "	\
+		"(fill %zu wide, target offset by %d)\n",	\
+		fill_size,					\
+		(int)((ssize_t)(uintptr_t)fill_start -		\
+		      (ssize_t)(uintptr_t)target_start));	\
+								\
+	/* Look for any bytes still 0xFF in check region. */	\
+	for (sum = 0, i = 0; i < target_size; i++)		\
+		sum += (check_buf[i] == 0xFF);			\
+								\
+	if (sum != 0 && xfail)					\
+		kunit_skip(test,				\
+			   "XFAIL uninit bytes: %d\n",		\
+			   sum);				\
+	KUNIT_ASSERT_EQ_MSG(test, sum, 0,			\
+		"uninit bytes: %d\n", sum);			\
+}
+#define DEFINE_TEST(name, var_type, which, init_level, xfail)	\
+/* no-op to force compiler into ignoring "uninitialized" vars */\
+static noinline DO_NOTHING_TYPE_ ## which(var_type)		\
+do_nothing_ ## name(var_type *ptr)				\
+{								\
+	/* Will always be true, but compiler doesn't know. */	\
+	if ((unsigned long)ptr > 0x2)				\
+		return DO_NOTHING_RETURN_ ## which(ptr);	\
+	else							\
+		return DO_NOTHING_RETURN_ ## which(ptr + 1);	\
+}								\
+static noinline int leaf_ ## name(unsigned long sp, bool fill,	\
+				  var_type *arg)		\
+{								\
+	char buf[VAR_BUFFER];					\
+	var_type var						\
+		INIT_ ## which ## _ ## init_level(var_type);	\
+								\
+	target_start = &var;					\
+	target_size = sizeof(var);				\
+	/*							\
+	 * Keep this buffer around to make sure we've got a	\
+	 * stack frame of SOME kind...				\
+	 */							\
+	memset(buf, (char)(sp & 0xff), sizeof(buf));		\
+	/* Fill variable with 0xFF. */				\
+	if (fill) {						\
+		fill_start = &var;				\
+		fill_size = sizeof(var);			\
+		memset(fill_start,				\
+		       (char)((sp & 0xff) | forced_mask),	\
+		       fill_size);				\
+	}							\
+								\
+	/* Silence "never initialized" warnings. */		\
+	DO_NOTHING_CALL_ ## which(var, name);			\
+								\
+	/* Exfiltrate "var". */					\
+	memcpy(check_buf, target_start, target_size);		\
+								\
+	return (int)buf[0] | (int)buf[sizeof(buf) - 1];		\
+}								\
+DEFINE_TEST_DRIVER(name, var_type, which, xfail)
+
+/* Structure with no padding. */
+struct test_packed {
+	unsigned long one;
+	unsigned long two;
+	unsigned long three;
+	unsigned long four;
+};
+
+/* Simple structure with padding likely to be covered by compiler. */
+struct test_small_hole {
+	size_t one;
+	char two;
+	/* 3 byte padding hole here. */
+	int three;
+	unsigned long four;
+};
+
+/* Trigger unhandled padding in a structure. */
+struct test_big_hole {
+	u8 one;
+	u8 two;
+	u8 three;
+	/* 61 byte padding hole here. */
+	u8 four __aligned(64);
+} __aligned(64);
+
+struct test_trailing_hole {
+	char *one;
+	char *two;
+	char *three;
+	char four;
+	/* "sizeof(unsigned long) - 1" byte padding hole here. */
+};
+
+/* Test if STRUCTLEAK is clearing structs with __user fields. */
+struct test_user {
+	u8 one;
+	unsigned long two;
+	char __user *three;
+	unsigned long four;
+};
+
+#define ALWAYS_PASS	WANT_SUCCESS
+#define ALWAYS_FAIL	XFAIL
+
+#ifdef CONFIG_INIT_STACK_NONE
+# define USER_PASS	XFAIL
+# define BYREF_PASS	XFAIL
+# define STRONG_PASS	XFAIL
+#elif defined(CONFIG_GCC_PLUGIN_STRUCTLEAK_USER)
+# define USER_PASS	WANT_SUCCESS
+# define BYREF_PASS	XFAIL
+# define STRONG_PASS	XFAIL
+#elif defined(CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF)
+# define USER_PASS	WANT_SUCCESS
+# define BYREF_PASS	WANT_SUCCESS
+# define STRONG_PASS	XFAIL
+#else
+# define USER_PASS	WANT_SUCCESS
+# define BYREF_PASS	WANT_SUCCESS
+# define STRONG_PASS	WANT_SUCCESS
+#endif
+
+#define DEFINE_SCALAR_TEST(name, init, xfail)			\
+		DEFINE_TEST(name ## _ ## init, name, SCALAR,	\
+			    init, xfail)
+
+#define DEFINE_SCALAR_TESTS(init, xfail)			\
+		DEFINE_SCALAR_TEST(u8, init, xfail);		\
+		DEFINE_SCALAR_TEST(u16, init, xfail);		\
+		DEFINE_SCALAR_TEST(u32, init, xfail);		\
+		DEFINE_SCALAR_TEST(u64, init, xfail);		\
+		DEFINE_TEST(char_array_ ## init, unsigned char,	\
+			    STRING, init, xfail)
+
+#define DEFINE_STRUCT_TEST(name, init, xfail)			\
+		DEFINE_TEST(name ## _ ## init,			\
+			    struct test_ ## name, STRUCT, init, \
+			    xfail)
+
+#define DEFINE_STRUCT_TESTS(init, xfail)			\
+		DEFINE_STRUCT_TEST(small_hole, init, xfail);	\
+		DEFINE_STRUCT_TEST(big_hole, init, xfail);	\
+		DEFINE_STRUCT_TEST(trailing_hole, init, xfail);	\
+		DEFINE_STRUCT_TEST(packed, init, xfail)
+
+#define DEFINE_STRUCT_INITIALIZER_TESTS(base, xfail)		\
+		DEFINE_STRUCT_TESTS(base ## _ ## partial,	\
+				    xfail);			\
+		DEFINE_STRUCT_TESTS(base ## _ ## all, xfail)
+
+/* These should be fully initialized all the time! */
+DEFINE_SCALAR_TESTS(zero, ALWAYS_PASS);
+DEFINE_STRUCT_TESTS(zero, ALWAYS_PASS);
+/* Struct initializers: padding may be left uninitialized. */
+DEFINE_STRUCT_INITIALIZER_TESTS(static, STRONG_PASS);
+DEFINE_STRUCT_INITIALIZER_TESTS(dynamic, STRONG_PASS);
+DEFINE_STRUCT_INITIALIZER_TESTS(runtime, STRONG_PASS);
+DEFINE_STRUCT_INITIALIZER_TESTS(assigned_static, STRONG_PASS);
+DEFINE_STRUCT_INITIALIZER_TESTS(assigned_dynamic, STRONG_PASS);
+DEFINE_STRUCT_TESTS(assigned_copy, ALWAYS_FAIL);
+/* No initialization without compiler instrumentation. */
+DEFINE_SCALAR_TESTS(none, STRONG_PASS);
+DEFINE_STRUCT_TESTS(none, BYREF_PASS);
+/* Initialization of members with __user attribute. */
+DEFINE_TEST(user, struct test_user, STRUCT, none, USER_PASS);
+
+/*
+ * Check two uses through a variable declaration outside either path,
+ * which was noticed as a special case in porting earlier stack init
+ * compiler logic.
+ */
+static int noinline __leaf_switch_none(int path, bool fill)
+{
+	switch (path) {
+		/*
+		 * This is intentionally unreachable. To silence the
+		 * warning, build with -Wno-switch-unreachable
+		 */
+		uint64_t var[10];
+
+	case 1:
+		target_start = &var;
+		target_size = sizeof(var);
+		if (fill) {
+			fill_start = &var;
+			fill_size = sizeof(var);
+
+			memset(fill_start, forced_mask | 0x55, fill_size);
+		}
+		memcpy(check_buf, target_start, target_size);
+		break;
+	case 2:
+		target_start = &var;
+		target_size = sizeof(var);
+		if (fill) {
+			fill_start = &var;
+			fill_size = sizeof(var);
+
+			memset(fill_start, forced_mask | 0xaa, fill_size);
+		}
+		memcpy(check_buf, target_start, target_size);
+		break;
+	default:
+		var[1] = 5;
+		return var[1] & forced_mask;
+	}
+	return 0;
+}
+
+static noinline int leaf_switch_1_none(unsigned long sp, bool fill,
+					      uint64_t *arg)
+{
+	return __leaf_switch_none(1, fill);
+}
+
+static noinline int leaf_switch_2_none(unsigned long sp, bool fill,
+					      uint64_t *arg)
+{
+	return __leaf_switch_none(2, fill);
+}
+
+/*
+ * These are expected to fail for most configurations because neither
+ * GCC nor Clang have a way to perform initialization of variables in
+ * non-code areas (i.e. in a switch statement before the first "case").
+ * https://llvm.org/pr44916
+ */
+DEFINE_TEST_DRIVER(switch_1_none, uint64_t, SCALAR, ALWAYS_FAIL);
+DEFINE_TEST_DRIVER(switch_2_none, uint64_t, SCALAR, ALWAYS_FAIL);
+
+#define KUNIT_test_scalars(init)			\
+		KUNIT_CASE(test_u8_ ## init),		\
+		KUNIT_CASE(test_u16_ ## init),		\
+		KUNIT_CASE(test_u32_ ## init),		\
+		KUNIT_CASE(test_u64_ ## init),		\
+		KUNIT_CASE(test_char_array_ ## init)
+
+#define KUNIT_test_structs(init)			\
+		KUNIT_CASE(test_small_hole_ ## init),	\
+		KUNIT_CASE(test_big_hole_ ## init),	\
+		KUNIT_CASE(test_trailing_hole_ ## init),\
+		KUNIT_CASE(test_packed_ ## init)	\
+
+static struct kunit_case stackinit_test_cases[] = {
+	/* These are explicitly initialized and should always pass. */
+	KUNIT_test_scalars(zero),
+	KUNIT_test_structs(zero),
+	/* Padding here appears to be accidentally always initialized? */
+	KUNIT_test_structs(dynamic_partial),
+	KUNIT_test_structs(assigned_dynamic_partial),
+	/* Padding initialization depends on compiler behaviors. */
+	KUNIT_test_structs(static_partial),
+	KUNIT_test_structs(static_all),
+	KUNIT_test_structs(dynamic_all),
+	KUNIT_test_structs(runtime_partial),
+	KUNIT_test_structs(runtime_all),
+	KUNIT_test_structs(assigned_static_partial),
+	KUNIT_test_structs(assigned_static_all),
+	KUNIT_test_structs(assigned_dynamic_all),
+	/* Everything fails this since it effectively performs a memcpy(). */
+	KUNIT_test_structs(assigned_copy),
+	/* STRUCTLEAK_BYREF_ALL should cover everything from here down. */
+	KUNIT_test_scalars(none),
+	KUNIT_CASE(test_switch_1_none),
+	KUNIT_CASE(test_switch_2_none),
+	/* STRUCTLEAK_BYREF should cover from here down. */
+	KUNIT_test_structs(none),
+	/* STRUCTLEAK will only cover this. */
+	KUNIT_CASE(test_user),
+	{}
+};
+
+static struct kunit_suite stackinit_test_suite = {
+	.name = "stackinit",
+	.test_cases = stackinit_test_cases,
+};
+
+kunit_test_suites(&stackinit_test_suite);
+
+MODULE_DESCRIPTION("Test cases for compiler-based stack variable zeroing");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/string_helpers_kunit.c a/lib/tests/string_helpers_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/string_helpers_kunit.c
@@ -0,0 +1,629 @@
+// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
+/*
+ * Test cases for lib/string_helpers.c module.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <kunit/test.h>
+#include <linux/array_size.h>
+#include <linux/kernel.h>
+#include <linux/random.h>
+#include <linux/string.h>
+#include <linux/string_helpers.h>
+
+static void test_string_check_buf(struct kunit *test,
+				  const char *name, unsigned int flags,
+				  char *in, size_t p,
+				  char *out_real, size_t q_real,
+				  char *out_test, size_t q_test)
+{
+	KUNIT_ASSERT_EQ_MSG(test, q_real, q_test, "name:%s", name);
+	KUNIT_EXPECT_MEMEQ_MSG(test, out_test, out_real, q_test,
+			       "name:%s", name);
+}
+
+struct test_string {
+	const char *in;
+	const char *out;
+	unsigned int flags;
+};
+
+static const struct test_string strings[] = {
+	{
+		.in = "\\f\\ \\n\\r\\t\\v",
+		.out = "\f\\ \n\r\t\v",
+		.flags = UNESCAPE_SPACE,
+	},
+	{
+		.in = "\\40\\1\\387\\0064\\05\\040\\8a\\110\\777",
+		.out = " \001\00387\0064\005 \\8aH?7",
+		.flags = UNESCAPE_OCTAL,
+	},
+	{
+		.in = "\\xv\\xa\\x2c\\xD\\x6f2",
+		.out = "\\xv\n,\ro2",
+		.flags = UNESCAPE_HEX,
+	},
+	{
+		.in = "\\h\\\\\\\"\\a\\e\\",
+		.out = "\\h\\\"\a\e\\",
+		.flags = UNESCAPE_SPECIAL,
+	},
+};
+
+static void test_string_unescape(struct kunit *test,
+				 const char *name, unsigned int flags,
+				 bool inplace)
+{
+	int q_real = 256;
+	char *in = kunit_kzalloc(test, q_real, GFP_KERNEL);
+	char *out_test = kunit_kzalloc(test, q_real, GFP_KERNEL);
+	char *out_real = kunit_kzalloc(test, q_real, GFP_KERNEL);
+	int i, p = 0, q_test = 0;
+
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, in);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, out_test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, out_real);
+
+	for (i = 0; i < ARRAY_SIZE(strings); i++) {
+		const char *s = strings[i].in;
+		int len = strlen(strings[i].in);
+
+		/* Copy string to in buffer */
+		memcpy(&in[p], s, len);
+		p += len;
+
+		/* Copy expected result for given flags */
+		if (flags & strings[i].flags) {
+			s = strings[i].out;
+			len = strlen(strings[i].out);
+		}
+		memcpy(&out_test[q_test], s, len);
+		q_test += len;
+	}
+	in[p++] = '\0';
+
+	/* Call string_unescape and compare result */
+	if (inplace) {
+		memcpy(out_real, in, p);
+		if (flags == UNESCAPE_ANY)
+			q_real = string_unescape_any_inplace(out_real);
+		else
+			q_real = string_unescape_inplace(out_real, flags);
+	} else if (flags == UNESCAPE_ANY) {
+		q_real = string_unescape_any(in, out_real, q_real);
+	} else {
+		q_real = string_unescape(in, out_real, q_real, flags);
+	}
+
+	test_string_check_buf(test, name, flags, in, p - 1, out_real, q_real,
+			      out_test, q_test);
+}
+
+struct test_string_1 {
+	const char *out;
+	unsigned int flags;
+};
+
+#define	TEST_STRING_2_MAX_S1		32
+struct test_string_2 {
+	const char *in;
+	struct test_string_1 s1[TEST_STRING_2_MAX_S1];
+};
+
+#define	TEST_STRING_2_DICT_0		NULL
+static const struct test_string_2 escape0[] = {{
+	.in = "\f\\ \n\r\t\v",
+	.s1 = {{
+		.out = "\\f\\ \\n\\r\\t\\v",
+		.flags = ESCAPE_SPACE,
+	},{
+		.out = "\\f\\134\\040\\n\\r\\t\\v",
+		.flags = ESCAPE_SPACE | ESCAPE_OCTAL,
+	},{
+		.out = "\\f\\x5c\\x20\\n\\r\\t\\v",
+		.flags = ESCAPE_SPACE | ESCAPE_HEX,
+	},{
+		/* terminator */
+	}}
+},{
+	.in = "\\h\\\"\a\e\\",
+	.s1 = {{
+		.out = "\\\\h\\\\\\\"\\a\\e\\\\",
+		.flags = ESCAPE_SPECIAL,
+	},{
+		.out = "\\\\\\150\\\\\\\"\\a\\e\\\\",
+		.flags = ESCAPE_SPECIAL | ESCAPE_OCTAL,
+	},{
+		.out = "\\\\\\x68\\\\\\\"\\a\\e\\\\",
+		.flags = ESCAPE_SPECIAL | ESCAPE_HEX,
+	},{
+		/* terminator */
+	}}
+},{
+	.in = "\eb \\C\007\"\x90\r]",
+	.s1 = {{
+		.out = "\eb \\C\007\"\x90\\r]",
+		.flags = ESCAPE_SPACE,
+	},{
+		.out = "\\eb \\\\C\\a\\\"\x90\r]",
+		.flags = ESCAPE_SPECIAL,
+	},{
+		.out = "\\eb \\\\C\\a\\\"\x90\\r]",
+		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL,
+	},{
+		.out = "\\033\\142\\040\\134\\103\\007\\042\\220\\015\\135",
+		.flags = ESCAPE_OCTAL,
+	},{
+		.out = "\\033\\142\\040\\134\\103\\007\\042\\220\\r\\135",
+		.flags = ESCAPE_SPACE | ESCAPE_OCTAL,
+	},{
+		.out = "\\e\\142\\040\\\\\\103\\a\\\"\\220\\015\\135",
+		.flags = ESCAPE_SPECIAL | ESCAPE_OCTAL,
+	},{
+		.out = "\\e\\142\\040\\\\\\103\\a\\\"\\220\\r\\135",
+		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_OCTAL,
+	},{
+		.out = "\eb \\C\007\"\x90\r]",
+		.flags = ESCAPE_NP,
+	},{
+		.out = "\eb \\C\007\"\x90\\r]",
+		.flags = ESCAPE_SPACE | ESCAPE_NP,
+	},{
+		.out = "\\eb \\C\\a\"\x90\r]",
+		.flags = ESCAPE_SPECIAL | ESCAPE_NP,
+	},{
+		.out = "\\eb \\C\\a\"\x90\\r]",
+		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NP,
+	},{
+		.out = "\\033b \\C\\007\"\\220\\015]",
+		.flags = ESCAPE_OCTAL | ESCAPE_NP,
+	},{
+		.out = "\\033b \\C\\007\"\\220\\r]",
+		.flags = ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_NP,
+	},{
+		.out = "\\eb \\C\\a\"\\220\\r]",
+		.flags = ESCAPE_SPECIAL | ESCAPE_SPACE | ESCAPE_OCTAL |
+			 ESCAPE_NP,
+	},{
+		.out = "\\x1bb \\C\\x07\"\\x90\\x0d]",
+		.flags = ESCAPE_NP | ESCAPE_HEX,
+	},{
+		/* terminator */
+	}}
+},{
+	.in = "\007 \eb\"\x90\xCF\r",
+	.s1 = {{
+		.out = "\007 \eb\"\\220\\317\r",
+		.flags = ESCAPE_OCTAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\\x90\\xcf\r",
+		.flags = ESCAPE_HEX | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_NA,
+	},{
+		/* terminator */
+	}}
+},{
+	/* terminator */
+}};
+
+#define	TEST_STRING_2_DICT_1		"b\\ \t\r\xCF"
+static const struct test_string_2 escape1[] = {{
+	.in = "\f\\ \n\r\t\v",
+	.s1 = {{
+		.out = "\f\\134\\040\n\\015\\011\v",
+		.flags = ESCAPE_OCTAL,
+	},{
+		.out = "\f\\x5c\\x20\n\\x0d\\x09\v",
+		.flags = ESCAPE_HEX,
+	},{
+		.out = "\f\\134\\040\n\\015\\011\v",
+		.flags = ESCAPE_ANY | ESCAPE_APPEND,
+	},{
+		.out = "\\014\\134\\040\\012\\015\\011\\013",
+		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NAP,
+	},{
+		.out = "\\x0c\\x5c\\x20\\x0a\\x0d\\x09\\x0b",
+		.flags = ESCAPE_HEX | ESCAPE_APPEND | ESCAPE_NAP,
+	},{
+		.out = "\f\\134\\040\n\\015\\011\v",
+		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NA,
+	},{
+		.out = "\f\\x5c\\x20\n\\x0d\\x09\v",
+		.flags = ESCAPE_HEX | ESCAPE_APPEND | ESCAPE_NA,
+	},{
+		/* terminator */
+	}}
+},{
+	.in = "\\h\\\"\a\xCF\e\\",
+	.s1 = {{
+		.out = "\\134h\\134\"\a\\317\e\\134",
+		.flags = ESCAPE_OCTAL,
+	},{
+		.out = "\\134h\\134\"\a\\317\e\\134",
+		.flags = ESCAPE_ANY | ESCAPE_APPEND,
+	},{
+		.out = "\\134h\\134\"\\007\\317\\033\\134",
+		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NAP,
+	},{
+		.out = "\\134h\\134\"\a\\317\e\\134",
+		.flags = ESCAPE_OCTAL | ESCAPE_APPEND | ESCAPE_NA,
+	},{
+		/* terminator */
+	}}
+},{
+	.in = "\eb \\C\007\"\x90\r]",
+	.s1 = {{
+		.out = "\e\\142\\040\\134C\007\"\x90\\015]",
+		.flags = ESCAPE_OCTAL,
+	},{
+		/* terminator */
+	}}
+},{
+	.in = "\007 \eb\"\x90\xCF\r",
+	.s1 = {{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_SPACE | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_SPECIAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\317\r",
+		.flags = ESCAPE_OCTAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\317\r",
+		.flags = ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\317\r",
+		.flags = ESCAPE_SPECIAL | ESCAPE_OCTAL | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\317\r",
+		.flags = ESCAPE_ANY | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\r",
+		.flags = ESCAPE_HEX | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\r",
+		.flags = ESCAPE_SPACE | ESCAPE_HEX | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\r",
+		.flags = ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NA,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\r",
+		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NA,
+	},{
+		/* terminator */
+	}}
+},{
+	.in = "\007 \eb\"\x90\xCF\r",
+	.s1 = {{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\xCF\\r",
+		.flags = ESCAPE_SPACE | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\xCF\r",
+		.flags = ESCAPE_SPECIAL | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\xCF\\r",
+		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\317\\015",
+		.flags = ESCAPE_OCTAL | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\317\\r",
+		.flags = ESCAPE_SPACE | ESCAPE_OCTAL | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\317\\015",
+		.flags = ESCAPE_SPECIAL | ESCAPE_OCTAL | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\317\r",
+		.flags = ESCAPE_ANY | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\\x0d",
+		.flags = ESCAPE_HEX | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\\r",
+		.flags = ESCAPE_SPACE | ESCAPE_HEX | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\\x0d",
+		.flags = ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NAP,
+	},{
+		.out = "\007 \eb\"\x90\\xcf\\r",
+		.flags = ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_HEX | ESCAPE_NAP,
+	},{
+		/* terminator */
+	}}
+},{
+	/* terminator */
+}};
+
+static const struct test_string strings_upper[] = {
+	{
+		.in = "abcdefgh1234567890test",
+		.out = "ABCDEFGH1234567890TEST",
+	},
+	{
+		.in = "abCdeFgH1234567890TesT",
+		.out = "ABCDEFGH1234567890TEST",
+	},
+};
+
+static const struct test_string strings_lower[] = {
+	{
+		.in = "ABCDEFGH1234567890TEST",
+		.out = "abcdefgh1234567890test",
+	},
+	{
+		.in = "abCdeFgH1234567890TesT",
+		.out = "abcdefgh1234567890test",
+	},
+};
+
+static const char *test_string_find_match(const struct test_string_2 *s2,
+					  unsigned int flags)
+{
+	const struct test_string_1 *s1 = s2->s1;
+	unsigned int i;
+
+	if (!flags)
+		return s2->in;
+
+	/* Test cases are NULL-aware */
+	flags &= ~ESCAPE_NULL;
+
+	/* ESCAPE_OCTAL has a higher priority */
+	if (flags & ESCAPE_OCTAL)
+		flags &= ~ESCAPE_HEX;
+
+	for (i = 0; i < TEST_STRING_2_MAX_S1 && s1->out; i++, s1++)
+		if (s1->flags == flags)
+			return s1->out;
+	return NULL;
+}
+
+static void
+test_string_escape_overflow(struct kunit *test,
+			    const char *in, int p, unsigned int flags, const char *esc,
+			    int q_test, const char *name)
+{
+	int q_real;
+
+	q_real = string_escape_mem(in, p, NULL, 0, flags, esc);
+	KUNIT_EXPECT_EQ_MSG(test, q_real, q_test, "name:%s: flags:%#x", name, flags);
+}
+
+static void test_string_escape(struct kunit *test, const char *name,
+			       const struct test_string_2 *s2,
+			       unsigned int flags, const char *esc)
+{
+	size_t out_size = 512;
+	char *out_test = kunit_kzalloc(test, out_size, GFP_KERNEL);
+	char *out_real = kunit_kzalloc(test, out_size, GFP_KERNEL);
+	char *in = kunit_kzalloc(test, 256, GFP_KERNEL);
+	int p = 0, q_test = 0;
+	int q_real;
+
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, out_test);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, out_real);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, in);
+
+	for (; s2->in; s2++) {
+		const char *out;
+		int len;
+
+		/* NULL injection */
+		if (flags & ESCAPE_NULL) {
+			in[p++] = '\0';
+			/* '\0' passes isascii() test */
+			if (flags & ESCAPE_NA && !(flags & ESCAPE_APPEND && esc)) {
+				out_test[q_test++] = '\0';
+			} else {
+				out_test[q_test++] = '\\';
+				out_test[q_test++] = '0';
+			}
+		}
+
+		/* Don't try strings that have no output */
+		out = test_string_find_match(s2, flags);
+		if (!out)
+			continue;
+
+		/* Copy string to in buffer */
+		len = strlen(s2->in);
+		memcpy(&in[p], s2->in, len);
+		p += len;
+
+		/* Copy expected result for given flags */
+		len = strlen(out);
+		memcpy(&out_test[q_test], out, len);
+		q_test += len;
+	}
+
+	q_real = string_escape_mem(in, p, out_real, out_size, flags, esc);
+
+	test_string_check_buf(test, name, flags, in, p, out_real, q_real, out_test,
+			      q_test);
+
+	test_string_escape_overflow(test, in, p, flags, esc, q_test, name);
+}
+
+#define string_get_size_maxbuf 16
+#define test_string_get_size_one(size, blk_size, exp_result10, exp_result2)      \
+	do {                                                                     \
+		BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf);    \
+		BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf);     \
+		__test_string_get_size(test, (size), (blk_size), (exp_result10), \
+				       (exp_result2));                           \
+	} while (0)
+
+
+static void test_string_get_size_check(struct kunit *test,
+				       const char *units,
+				       const char *exp,
+				       char *res,
+				       const u64 size,
+				       const u64 blk_size)
+{
+	KUNIT_EXPECT_MEMEQ_MSG(test, res, exp, strlen(exp) + 1,
+		"string_get_size(size = %llu, blk_size = %llu, units = %s)",
+		size, blk_size, units);
+}
+
+static void __strchrcut(char *dst, const char *src, const char *cut)
+{
+	const char *from = src;
+	size_t len;
+
+	do {
+		len = strcspn(from, cut);
+		memcpy(dst, from, len);
+		dst += len;
+		from += len;
+	} while (*from++);
+	*dst = '\0';
+}
+
+static void __test_string_get_size_one(struct kunit *test,
+				       const u64 size, const u64 blk_size,
+				       const char *exp_result10,
+				       const char *exp_result2,
+				       enum string_size_units units,
+				       const char *cut)
+{
+	char buf10[string_get_size_maxbuf];
+	char buf2[string_get_size_maxbuf];
+	char exp10[string_get_size_maxbuf];
+	char exp2[string_get_size_maxbuf];
+	char prefix10[64];
+	char prefix2[64];
+
+	sprintf(prefix10, "STRING_UNITS_10 [%s]", cut);
+	sprintf(prefix2, "STRING_UNITS_2 [%s]", cut);
+
+	__strchrcut(exp10, exp_result10, cut);
+	__strchrcut(exp2, exp_result2, cut);
+
+	string_get_size(size, blk_size, STRING_UNITS_10 | units, buf10, sizeof(buf10));
+	string_get_size(size, blk_size, STRING_UNITS_2 | units, buf2, sizeof(buf2));
+
+	test_string_get_size_check(test, prefix10, exp10, buf10, size, blk_size);
+	test_string_get_size_check(test, prefix2, exp2, buf2, size, blk_size);
+}
+
+static void __test_string_get_size(struct kunit *test,
+				   const u64 size, const u64 blk_size,
+				   const char *exp_result10,
+				   const char *exp_result2)
+{
+	struct {
+		enum string_size_units units;
+		const char *cut;
+	} get_size_test_cases[] = {
+		{ 0, "" },
+		{ STRING_UNITS_NO_SPACE, " " },
+		{ STRING_UNITS_NO_SPACE | STRING_UNITS_NO_BYTES, " B" },
+		{ STRING_UNITS_NO_BYTES, "B" },
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(get_size_test_cases); i++)
+		__test_string_get_size_one(test, size, blk_size,
+					   exp_result10, exp_result2,
+					   get_size_test_cases[i].units,
+					   get_size_test_cases[i].cut);
+}
+
+static void test_get_size(struct kunit *test)
+{
+	/* small values */
+	test_string_get_size_one(0, 512, "0 B", "0 B");
+	test_string_get_size_one(1, 512, "512 B", "512 B");
+	test_string_get_size_one(1100, 1, "1.10 kB", "1.07 KiB");
+
+	/* normal values */
+	test_string_get_size_one(16384, 512, "8.39 MB", "8.00 MiB");
+	test_string_get_size_one(500118192, 512, "256 GB", "238 GiB");
+	test_string_get_size_one(8192, 4096, "33.6 MB", "32.0 MiB");
+
+	/* weird block sizes */
+	test_string_get_size_one(3000, 1900, "5.70 MB", "5.44 MiB");
+
+	/* huge values */
+	test_string_get_size_one(U64_MAX, 4096, "75.6 ZB", "64.0 ZiB");
+	test_string_get_size_one(4096, U64_MAX, "75.6 ZB", "64.0 ZiB");
+}
+
+static void test_upper_lower(struct kunit *test)
+{
+	char *dst;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(strings_upper); i++) {
+		const char *s = strings_upper[i].in;
+		int len = strlen(strings_upper[i].in) + 1;
+
+		dst = kmalloc(len, GFP_KERNEL);
+		KUNIT_ASSERT_NOT_NULL(test, dst);
+
+		string_upper(dst, s);
+		KUNIT_EXPECT_STREQ(test, dst, strings_upper[i].out);
+		kfree(dst);
+	}
+
+	for (i = 0; i < ARRAY_SIZE(strings_lower); i++) {
+		const char *s = strings_lower[i].in;
+		int len = strlen(strings_lower[i].in) + 1;
+
+		dst = kmalloc(len, GFP_KERNEL);
+		KUNIT_ASSERT_NOT_NULL(test, dst);
+
+		string_lower(dst, s);
+		KUNIT_EXPECT_STREQ(test, dst, strings_lower[i].out);
+		kfree(dst);
+	}
+}
+
+static void test_unescape(struct kunit *test)
+{
+	unsigned int i;
+
+	for (i = 0; i < UNESCAPE_ALL_MASK + 1; i++)
+		test_string_unescape(test, "unescape", i, false);
+	test_string_unescape(test, "unescape inplace",
+			     get_random_u32_below(UNESCAPE_ALL_MASK + 1), true);
+
+	/* Without dictionary */
+	for (i = 0; i < ESCAPE_ALL_MASK + 1; i++)
+		test_string_escape(test, "escape 0", escape0, i, TEST_STRING_2_DICT_0);
+
+	/* With dictionary */
+	for (i = 0; i < ESCAPE_ALL_MASK + 1; i++)
+		test_string_escape(test, "escape 1", escape1, i, TEST_STRING_2_DICT_1);
+}
+
+static struct kunit_case string_helpers_test_cases[] = {
+	KUNIT_CASE(test_get_size),
+	KUNIT_CASE(test_upper_lower),
+	KUNIT_CASE(test_unescape),
+	{}
+};
+
+static struct kunit_suite string_helpers_test_suite = {
+	.name = "string_helpers",
+	.test_cases = string_helpers_test_cases,
+};
+
+kunit_test_suites(&string_helpers_test_suite);
+
+MODULE_DESCRIPTION("Test cases for string helpers module");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/lib/tests/string_kunit.c a/lib/tests/string_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/string_kunit.c
@@ -0,0 +1,637 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test cases for string functions.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <kunit/test.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#define STRCMP_LARGE_BUF_LEN 2048
+#define STRCMP_CHANGE_POINT 1337
+#define STRCMP_TEST_EXPECT_EQUAL(test, fn, ...) KUNIT_EXPECT_EQ(test, fn(__VA_ARGS__), 0)
+#define STRCMP_TEST_EXPECT_LOWER(test, fn, ...) KUNIT_EXPECT_LT(test, fn(__VA_ARGS__), 0)
+#define STRCMP_TEST_EXPECT_GREATER(test, fn, ...) KUNIT_EXPECT_GT(test, fn(__VA_ARGS__), 0)
+
+static void string_test_memset16(struct kunit *test)
+{
+	unsigned i, j, k;
+	u16 v, *p;
+
+	p = kunit_kzalloc(test, 256 * 2 * 2, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
+
+	for (i = 0; i < 256; i++) {
+		for (j = 0; j < 256; j++) {
+			memset(p, 0xa1, 256 * 2 * sizeof(v));
+			memset16(p + i, 0xb1b2, j);
+			for (k = 0; k < 512; k++) {
+				v = p[k];
+				if (k < i) {
+					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1,
+						"i:%d j:%d k:%d", i, j, k);
+				} else if (k < i + j) {
+					KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2,
+						"i:%d j:%d k:%d", i, j, k);
+				} else {
+					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1,
+						"i:%d j:%d k:%d", i, j, k);
+				}
+			}
+		}
+	}
+}
+
+static void string_test_memset32(struct kunit *test)
+{
+	unsigned i, j, k;
+	u32 v, *p;
+
+	p = kunit_kzalloc(test, 256 * 2 * 4, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
+
+	for (i = 0; i < 256; i++) {
+		for (j = 0; j < 256; j++) {
+			memset(p, 0xa1, 256 * 2 * sizeof(v));
+			memset32(p + i, 0xb1b2b3b4, j);
+			for (k = 0; k < 512; k++) {
+				v = p[k];
+				if (k < i) {
+					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1,
+						"i:%d j:%d k:%d", i, j, k);
+				} else if (k < i + j) {
+					KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2b3b4,
+						"i:%d j:%d k:%d", i, j, k);
+				} else {
+					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1,
+						"i:%d j:%d k:%d", i, j, k);
+				}
+			}
+		}
+	}
+}
+
+static void string_test_memset64(struct kunit *test)
+{
+	unsigned i, j, k;
+	u64 v, *p;
+
+	p = kunit_kzalloc(test, 256 * 2 * 8, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, p);
+
+	for (i = 0; i < 256; i++) {
+		for (j = 0; j < 256; j++) {
+			memset(p, 0xa1, 256 * 2 * sizeof(v));
+			memset64(p + i, 0xb1b2b3b4b5b6b7b8ULL, j);
+			for (k = 0; k < 512; k++) {
+				v = p[k];
+				if (k < i) {
+					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1a1a1a1a1ULL,
+						"i:%d j:%d k:%d", i, j, k);
+				} else if (k < i + j) {
+					KUNIT_ASSERT_EQ_MSG(test, v, 0xb1b2b3b4b5b6b7b8ULL,
+						"i:%d j:%d k:%d", i, j, k);
+				} else {
+					KUNIT_ASSERT_EQ_MSG(test, v, 0xa1a1a1a1a1a1a1a1ULL,
+						"i:%d j:%d k:%d", i, j, k);
+				}
+			}
+		}
+	}
+}
+
+static void string_test_strchr(struct kunit *test)
+{
+	const char *test_string = "abcdefghijkl";
+	const char *empty_string = "";
+	char *result;
+	int i;
+
+	for (i = 0; i < strlen(test_string) + 1; i++) {
+		result = strchr(test_string, test_string[i]);
+		KUNIT_ASSERT_EQ_MSG(test, result - test_string, i,
+				    "char:%c", 'a' + i);
+	}
+
+	result = strchr(empty_string, '\0');
+	KUNIT_ASSERT_PTR_EQ(test, result, empty_string);
+
+	result = strchr(empty_string, 'a');
+	KUNIT_ASSERT_NULL(test, result);
+
+	result = strchr(test_string, 'z');
+	KUNIT_ASSERT_NULL(test, result);
+}
+
+static void string_test_strnchr(struct kunit *test)
+{
+	const char *test_string = "abcdefghijkl";
+	const char *empty_string = "";
+	char *result;
+	int i, j;
+
+	for (i = 0; i < strlen(test_string) + 1; i++) {
+		for (j = 0; j < strlen(test_string) + 2; j++) {
+			result = strnchr(test_string, j, test_string[i]);
+			if (j <= i) {
+				KUNIT_ASSERT_NULL_MSG(test, result,
+					"char:%c i:%d j:%d", 'a' + i, i, j);
+			} else {
+				KUNIT_ASSERT_EQ_MSG(test, result - test_string, i,
+					"char:%c i:%d j:%d", 'a' + i, i, j);
+			}
+		}
+	}
+
+	result = strnchr(empty_string, 0, '\0');
+	KUNIT_ASSERT_NULL(test, result);
+
+	result = strnchr(empty_string, 1, '\0');
+	KUNIT_ASSERT_PTR_EQ(test, result, empty_string);
+
+	result = strnchr(empty_string, 1, 'a');
+	KUNIT_ASSERT_NULL(test, result);
+
+	result = strnchr(NULL, 0, '\0');
+	KUNIT_ASSERT_NULL(test, result);
+}
+
+static void string_test_strspn(struct kunit *test)
+{
+	static const struct strspn_test {
+		const char str[16];
+		const char accept[16];
+		const char reject[16];
+		unsigned a;
+		unsigned r;
+	} tests[] = {
+		{ "foobar", "", "", 0, 6 },
+		{ "abba", "abc", "ABBA", 4, 4 },
+		{ "abba", "a", "b", 1, 1 },
+		{ "", "abc", "abc", 0, 0},
+	};
+	const struct strspn_test *s = tests;
+	size_t i;
+
+	for (i = 0; i < ARRAY_SIZE(tests); ++i, ++s) {
+		KUNIT_ASSERT_EQ_MSG(test, s->a, strspn(s->str, s->accept),
+			"i:%zu", i);
+		KUNIT_ASSERT_EQ_MSG(test, s->r, strcspn(s->str, s->reject),
+			"i:%zu", i);
+	}
+}
+
+static char strcmp_buffer1[STRCMP_LARGE_BUF_LEN];
+static char strcmp_buffer2[STRCMP_LARGE_BUF_LEN];
+
+static void strcmp_fill_buffers(char fill1, char fill2)
+{
+	memset(strcmp_buffer1, fill1, STRCMP_LARGE_BUF_LEN);
+	memset(strcmp_buffer2, fill2, STRCMP_LARGE_BUF_LEN);
+	strcmp_buffer1[STRCMP_LARGE_BUF_LEN - 1] = 0;
+	strcmp_buffer2[STRCMP_LARGE_BUF_LEN - 1] = 0;
+}
+
+static void string_test_strcmp(struct kunit *test)
+{
+	/* Equal strings */
+	STRCMP_TEST_EXPECT_EQUAL(test, strcmp, "Hello, Kernel!", "Hello, Kernel!");
+	/* First string is lexicographically less than the second */
+	STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Hello, KUnit!", "Hello, Kernel!");
+	/* First string is lexicographically larger than the second */
+	STRCMP_TEST_EXPECT_GREATER(test, strcmp, "Hello, Kernel!", "Hello, KUnit!");
+	/* Empty string is always lexicographically less than any non-empty string */
+	STRCMP_TEST_EXPECT_LOWER(test, strcmp, "", "Non-empty string");
+	/* Two empty strings should be equal */
+	STRCMP_TEST_EXPECT_EQUAL(test, strcmp, "", "");
+	/* Compare two strings which have only one char difference */
+	STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Abacaba", "Abadaba");
+	/* Compare two strings which have the same prefix*/
+	STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Just a string", "Just a string and something else");
+}
+
+static void string_test_strcmp_long_strings(struct kunit *test)
+{
+	strcmp_fill_buffers('B', 'B');
+	STRCMP_TEST_EXPECT_EQUAL(test, strcmp, strcmp_buffer1, strcmp_buffer2);
+
+	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A';
+	STRCMP_TEST_EXPECT_LOWER(test, strcmp, strcmp_buffer1, strcmp_buffer2);
+
+	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
+	STRCMP_TEST_EXPECT_GREATER(test, strcmp, strcmp_buffer1, strcmp_buffer2);
+}
+
+static void string_test_strncmp(struct kunit *test)
+{
+	/* Equal strings */
+	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Hello, KUnit!", "Hello, KUnit!", 13);
+	/* First string is lexicographically less than the second */
+	STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Hello, KUnit!", "Hello, Kernel!", 13);
+	/* Result is always 'equal' when count = 0 */
+	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Hello, Kernel!", "Hello, KUnit!", 0);
+	/* Strings with common prefix are equal if count = length of prefix */
+	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Abacaba", "Abadaba", 3);
+	/* Strings with common prefix are not equal when count = length of prefix + 1 */
+	STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Abacaba", "Abadaba", 4);
+	/* If one string is a prefix of another, the shorter string is lexicographically smaller */
+	STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Just a string", "Just a string and something else",
+				 strlen("Just a string and something else"));
+	/*
+	 * If one string is a prefix of another, and we check first length
+	 * of prefix chars, the result is 'equal'
+	 */
+	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Just a string", "Just a string and something else",
+				 strlen("Just a string"));
+}
+
+static void string_test_strncmp_long_strings(struct kunit *test)
+{
+	strcmp_fill_buffers('B', 'B');
+	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, strcmp_buffer1,
+				 strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
+
+	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A';
+	STRCMP_TEST_EXPECT_LOWER(test, strncmp, strcmp_buffer1,
+				 strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
+
+	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
+	STRCMP_TEST_EXPECT_GREATER(test, strncmp, strcmp_buffer1,
+				   strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
+	/* the strings are equal up to STRCMP_CHANGE_POINT */
+	STRCMP_TEST_EXPECT_EQUAL(test, strncmp, strcmp_buffer1,
+				 strcmp_buffer2, STRCMP_CHANGE_POINT);
+	STRCMP_TEST_EXPECT_GREATER(test, strncmp, strcmp_buffer1,
+				   strcmp_buffer2, STRCMP_CHANGE_POINT + 1);
+}
+
+static void string_test_strcasecmp(struct kunit *test)
+{
+	/* Same strings in different case should be equal */
+	STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "Hello, Kernel!", "HeLLO, KErNeL!");
+	/* Empty strings should be equal */
+	STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "", "");
+	/* Despite ascii code for 'a' is larger than ascii code for 'B', 'a' < 'B' */
+	STRCMP_TEST_EXPECT_LOWER(test, strcasecmp, "a", "B");
+	STRCMP_TEST_EXPECT_GREATER(test, strcasecmp, "B", "a");
+	/* Special symbols and numbers should be processed correctly */
+	STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "-+**.1230ghTTT~^", "-+**.1230Ghttt~^");
+}
+
+static void string_test_strcasecmp_long_strings(struct kunit *test)
+{
+	strcmp_fill_buffers('b', 'B');
+	STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, strcmp_buffer1, strcmp_buffer2);
+
+	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a';
+	STRCMP_TEST_EXPECT_LOWER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2);
+
+	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
+	STRCMP_TEST_EXPECT_GREATER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2);
+}
+
+static void string_test_strncasecmp(struct kunit *test)
+{
+	/* Same strings in different case should be equal */
+	STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "AbAcAbA", "Abacaba", strlen("Abacaba"));
+	/* strncasecmp should check 'count' chars only */
+	STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "AbaCaBa", "abaCaDa", 5);
+	STRCMP_TEST_EXPECT_LOWER(test, strncasecmp, "a", "B", 1);
+	STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, "B", "a", 1);
+	/* Result is always 'equal' when count = 0 */
+	STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "Abacaba", "Not abacaba", 0);
+}
+
+static void string_test_strncasecmp_long_strings(struct kunit *test)
+{
+	strcmp_fill_buffers('b', 'B');
+	STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, strcmp_buffer1,
+				 strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
+
+	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a';
+	STRCMP_TEST_EXPECT_LOWER(test, strncasecmp, strcmp_buffer1,
+				 strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
+
+	strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C';
+	STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, strcmp_buffer1,
+				   strcmp_buffer2, STRCMP_LARGE_BUF_LEN);
+
+	STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, strcmp_buffer1,
+				 strcmp_buffer2, STRCMP_CHANGE_POINT);
+	STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, strcmp_buffer1,
+				   strcmp_buffer2, STRCMP_CHANGE_POINT + 1);
+}
+
+/**
+ * strscpy_check() - Run a specific test case.
+ * @test: KUnit test context pointer
+ * @src: Source string, argument to strscpy_pad()
+ * @count: Size of destination buffer, argument to strscpy_pad()
+ * @expected: Expected return value from call to strscpy_pad()
+ * @chars: Number of characters from the src string expected to be
+ *         written to the dst buffer.
+ * @terminator: 1 if there should be a terminating null byte 0 otherwise.
+ * @pad: Number of pad characters expected (in the tail of dst buffer).
+ *       (@pad does not include the null terminator byte.)
+ *
+ * Calls strscpy_pad() and verifies the return value and state of the
+ * destination buffer after the call returns.
+ */
+static void strscpy_check(struct kunit *test, char *src, int count,
+			  int expected, int chars, int terminator, int pad)
+{
+	int nr_bytes_poison;
+	int max_expected;
+	int max_count;
+	int written;
+	char buf[6];
+	int index, i;
+	const char POISON = 'z';
+
+	KUNIT_ASSERT_TRUE_MSG(test, src != NULL,
+			      "null source string not supported");
+
+	memset(buf, POISON, sizeof(buf));
+	/* Future proofing test suite, validate args */
+	max_count = sizeof(buf) - 2; /* Space for null and to verify overflow */
+	max_expected = count - 1;    /* Space for the null */
+
+	KUNIT_ASSERT_LE_MSG(test, count, max_count,
+		"count (%d) is too big (%d) ... aborting", count, max_count);
+	KUNIT_EXPECT_LE_MSG(test, expected, max_expected,
+		"expected (%d) is bigger than can possibly be returned (%d)",
+		expected, max_expected);
+
+	written = strscpy_pad(buf, src, count);
+	KUNIT_ASSERT_EQ(test, written, expected);
+
+	if (count && written == -E2BIG) {
+		KUNIT_ASSERT_EQ_MSG(test, 0, strncmp(buf, src, count - 1),
+			"buffer state invalid for -E2BIG");
+		KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0',
+			"too big string is not null terminated correctly");
+	}
+
+	for (i = 0; i < chars; i++)
+		KUNIT_ASSERT_EQ_MSG(test, buf[i], src[i],
+			"buf[i]==%c != src[i]==%c", buf[i], src[i]);
+
+	if (terminator)
+		KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0',
+			"string is not null terminated correctly");
+
+	for (i = 0; i < pad; i++) {
+		index = chars + terminator + i;
+		KUNIT_ASSERT_EQ_MSG(test, buf[index], '\0',
+			"padding missing at index: %d", i);
+	}
+
+	nr_bytes_poison = sizeof(buf) - chars - terminator - pad;
+	for (i = 0; i < nr_bytes_poison; i++) {
+		index = sizeof(buf) - 1 - i; /* Check from the end back */
+		KUNIT_ASSERT_EQ_MSG(test, buf[index], POISON,
+			"poison value missing at index: %d", i);
+	}
+}
+
+static void string_test_strscpy(struct kunit *test)
+{
+	char dest[8];
+
+	/*
+	 * strscpy_check() uses a destination buffer of size 6 and needs at
+	 * least 2 characters spare (one for null and one to check for
+	 * overflow).  This means we should only call tc() with
+	 * strings up to a maximum of 4 characters long and 'count'
+	 * should not exceed 4.  To test with longer strings increase
+	 * the buffer size in tc().
+	 */
+
+	/* strscpy_check(test, src, count, expected, chars, terminator, pad) */
+	strscpy_check(test, "a", 0, -E2BIG, 0, 0, 0);
+	strscpy_check(test, "",  0, -E2BIG, 0, 0, 0);
+
+	strscpy_check(test, "a", 1, -E2BIG, 0, 1, 0);
+	strscpy_check(test, "",  1, 0,	 0, 1, 0);
+
+	strscpy_check(test, "ab", 2, -E2BIG, 1, 1, 0);
+	strscpy_check(test, "a",  2, 1,	  1, 1, 0);
+	strscpy_check(test, "",   2, 0,	  0, 1, 1);
+
+	strscpy_check(test, "abc", 3, -E2BIG, 2, 1, 0);
+	strscpy_check(test, "ab",  3, 2,	   2, 1, 0);
+	strscpy_check(test, "a",   3, 1,	   1, 1, 1);
+	strscpy_check(test, "",    3, 0,	   0, 1, 2);
+
+	strscpy_check(test, "abcd", 4, -E2BIG, 3, 1, 0);
+	strscpy_check(test, "abc",  4, 3,	    3, 1, 0);
+	strscpy_check(test, "ab",   4, 2,	    2, 1, 1);
+	strscpy_check(test, "a",    4, 1,	    1, 1, 2);
+	strscpy_check(test, "",     4, 0,	    0, 1, 3);
+
+	/* Compile-time-known source strings. */
+	KUNIT_EXPECT_EQ(test, strscpy(dest, "", ARRAY_SIZE(dest)), 0);
+	KUNIT_EXPECT_EQ(test, strscpy(dest, "", 3), 0);
+	KUNIT_EXPECT_EQ(test, strscpy(dest, "", 1), 0);
+	KUNIT_EXPECT_EQ(test, strscpy(dest, "", 0), -E2BIG);
+	KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", ARRAY_SIZE(dest)), 5);
+	KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 3), -E2BIG);
+	KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 1), -E2BIG);
+	KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 0), -E2BIG);
+	KUNIT_EXPECT_EQ(test, strscpy(dest, "This is too long", ARRAY_SIZE(dest)), -E2BIG);
+}
+
+static volatile int unconst;
+
+static void string_test_strcat(struct kunit *test)
+{
+	char dest[8];
+
+	/* Destination is terminated. */
+	memset(dest, 0, sizeof(dest));
+	KUNIT_EXPECT_EQ(test, strlen(dest), 0);
+	/* Empty copy does nothing. */
+	KUNIT_EXPECT_TRUE(test, strcat(dest, "") == dest);
+	KUNIT_EXPECT_STREQ(test, dest, "");
+	/* 4 characters copied in, stops at %NUL. */
+	KUNIT_EXPECT_TRUE(test, strcat(dest, "four\000123") == dest);
+	KUNIT_EXPECT_STREQ(test, dest, "four");
+	KUNIT_EXPECT_EQ(test, dest[5], '\0');
+	/* 2 more characters copied in okay. */
+	KUNIT_EXPECT_TRUE(test, strcat(dest, "AB") == dest);
+	KUNIT_EXPECT_STREQ(test, dest, "fourAB");
+}
+
+static void string_test_strncat(struct kunit *test)
+{
+	char dest[8];
+
+	/* Destination is terminated. */
+	memset(dest, 0, sizeof(dest));
+	KUNIT_EXPECT_EQ(test, strlen(dest), 0);
+	/* Empty copy of size 0 does nothing. */
+	KUNIT_EXPECT_TRUE(test, strncat(dest, "", 0 + unconst) == dest);
+	KUNIT_EXPECT_STREQ(test, dest, "");
+	/* Empty copy of size 1 does nothing too. */
+	KUNIT_EXPECT_TRUE(test, strncat(dest, "", 1 + unconst) == dest);
+	KUNIT_EXPECT_STREQ(test, dest, "");
+	/* Copy of max 0 characters should do nothing. */
+	KUNIT_EXPECT_TRUE(test, strncat(dest, "asdf", 0 + unconst) == dest);
+	KUNIT_EXPECT_STREQ(test, dest, "");
+
+	/* 4 characters copied in, even if max is 8. */
+	KUNIT_EXPECT_TRUE(test, strncat(dest, "four\000123", 8 + unconst) == dest);
+	KUNIT_EXPECT_STREQ(test, dest, "four");
+	KUNIT_EXPECT_EQ(test, dest[5], '\0');
+	KUNIT_EXPECT_EQ(test, dest[6], '\0');
+	/* 2 characters copied in okay, 2 ignored. */
+	KUNIT_EXPECT_TRUE(test, strncat(dest, "ABCD", 2 + unconst) == dest);
+	KUNIT_EXPECT_STREQ(test, dest, "fourAB");
+}
+
+static void string_test_strlcat(struct kunit *test)
+{
+	char dest[8] = "";
+	int len = sizeof(dest) + unconst;
+
+	/* Destination is terminated. */
+	KUNIT_EXPECT_EQ(test, strlen(dest), 0);
+	/* Empty copy is size 0. */
+	KUNIT_EXPECT_EQ(test, strlcat(dest, "", len), 0);
+	KUNIT_EXPECT_STREQ(test, dest, "");
+	/* Size 1 should keep buffer terminated, report size of source only. */
+	KUNIT_EXPECT_EQ(test, strlcat(dest, "four", 1 + unconst), 4);
+	KUNIT_EXPECT_STREQ(test, dest, "");
+
+	/* 4 characters copied in. */
+	KUNIT_EXPECT_EQ(test, strlcat(dest, "four", len), 4);
+	KUNIT_EXPECT_STREQ(test, dest, "four");
+	/* 2 characters copied in okay, gets to 6 total. */
+	KUNIT_EXPECT_EQ(test, strlcat(dest, "AB", len), 6);
+	KUNIT_EXPECT_STREQ(test, dest, "fourAB");
+	/* 2 characters ignored if max size (7) reached. */
+	KUNIT_EXPECT_EQ(test, strlcat(dest, "CD", 7 + unconst), 8);
+	KUNIT_EXPECT_STREQ(test, dest, "fourAB");
+	/* 1 of 2 characters skipped, now at true max size. */
+	KUNIT_EXPECT_EQ(test, strlcat(dest, "EFG", len), 9);
+	KUNIT_EXPECT_STREQ(test, dest, "fourABE");
+	/* Everything else ignored, now at full size. */
+	KUNIT_EXPECT_EQ(test, strlcat(dest, "1234", len), 11);
+	KUNIT_EXPECT_STREQ(test, dest, "fourABE");
+}
+
+static void string_test_strtomem(struct kunit *test)
+{
+	static const char input[sizeof(unsigned long)] = "hi";
+	static const char truncate[] = "this is too long";
+	struct {
+		unsigned long canary1;
+		unsigned char output[sizeof(unsigned long)] __nonstring;
+		unsigned long canary2;
+	} wrap;
+
+	memset(&wrap, 0xFF, sizeof(wrap));
+	KUNIT_EXPECT_EQ_MSG(test, wrap.canary1, ULONG_MAX,
+			    "bad initial canary value");
+	KUNIT_EXPECT_EQ_MSG(test, wrap.canary2, ULONG_MAX,
+			    "bad initial canary value");
+
+	/* Check unpadded copy leaves surroundings untouched. */
+	strtomem(wrap.output, input);
+	KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
+	KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]);
+	KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]);
+	for (size_t i = 2; i < sizeof(wrap.output); i++)
+		KUNIT_EXPECT_EQ(test, wrap.output[i], 0xFF);
+	KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
+
+	/* Check truncated copy leaves surroundings untouched. */
+	memset(&wrap, 0xFF, sizeof(wrap));
+	strtomem(wrap.output, truncate);
+	KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
+	for (size_t i = 0; i < sizeof(wrap.output); i++)
+		KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]);
+	KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
+
+	/* Check padded copy leaves only string padded. */
+	memset(&wrap, 0xFF, sizeof(wrap));
+	strtomem_pad(wrap.output, input, 0xAA);
+	KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
+	KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]);
+	KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]);
+	for (size_t i = 2; i < sizeof(wrap.output); i++)
+		KUNIT_EXPECT_EQ(test, wrap.output[i], 0xAA);
+	KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
+
+	/* Check truncated padded copy has no padding. */
+	memset(&wrap, 0xFF, sizeof(wrap));
+	strtomem(wrap.output, truncate);
+	KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX);
+	for (size_t i = 0; i < sizeof(wrap.output); i++)
+		KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]);
+	KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX);
+}
+
+
+static void string_test_memtostr(struct kunit *test)
+{
+	char nonstring[7] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' };
+	char nonstring_small[3] = { 'a', 'b', 'c' };
+	char dest[sizeof(nonstring) + 1];
+
+	/* Copy in a non-NUL-terminated string into exactly right-sized dest. */
+	KUNIT_EXPECT_EQ(test, sizeof(dest), sizeof(nonstring) + 1);
+	memset(dest, 'X', sizeof(dest));
+	memtostr(dest, nonstring);
+	KUNIT_EXPECT_STREQ(test, dest, "abcdefg");
+	memset(dest, 'X', sizeof(dest));
+	memtostr(dest, nonstring_small);
+	KUNIT_EXPECT_STREQ(test, dest, "abc");
+	KUNIT_EXPECT_EQ(test, dest[7], 'X');
+
+	memset(dest, 'X', sizeof(dest));
+	memtostr_pad(dest, nonstring);
+	KUNIT_EXPECT_STREQ(test, dest, "abcdefg");
+	memset(dest, 'X', sizeof(dest));
+	memtostr_pad(dest, nonstring_small);
+	KUNIT_EXPECT_STREQ(test, dest, "abc");
+	KUNIT_EXPECT_EQ(test, dest[7], '\0');
+}
+
+static struct kunit_case string_test_cases[] = {
+	KUNIT_CASE(string_test_memset16),
+	KUNIT_CASE(string_test_memset32),
+	KUNIT_CASE(string_test_memset64),
+	KUNIT_CASE(string_test_strchr),
+	KUNIT_CASE(string_test_strnchr),
+	KUNIT_CASE(string_test_strspn),
+	KUNIT_CASE(string_test_strcmp),
+	KUNIT_CASE(string_test_strcmp_long_strings),
+	KUNIT_CASE(string_test_strncmp),
+	KUNIT_CASE(string_test_strncmp_long_strings),
+	KUNIT_CASE(string_test_strcasecmp),
+	KUNIT_CASE(string_test_strcasecmp_long_strings),
+	KUNIT_CASE(string_test_strncasecmp),
+	KUNIT_CASE(string_test_strncasecmp_long_strings),
+	KUNIT_CASE(string_test_strscpy),
+	KUNIT_CASE(string_test_strcat),
+	KUNIT_CASE(string_test_strncat),
+	KUNIT_CASE(string_test_strlcat),
+	KUNIT_CASE(string_test_strtomem),
+	KUNIT_CASE(string_test_memtostr),
+	{}
+};
+
+static struct kunit_suite string_test_suite = {
+	.name = "string",
+	.test_cases = string_test_cases,
+};
+
+kunit_test_suites(&string_test_suite);
+
+MODULE_DESCRIPTION("Test cases for string functions");
+MODULE_LICENSE("GPL v2");
diff --git a/lib/tests/test_bits.c a/lib/tests/test_bits.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/test_bits.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test cases for functions and macros in bits.h
+ */
+
+#include <kunit/test.h>
+#include <linux/bits.h>
+
+
+static void genmask_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, 1ul, GENMASK(0, 0));
+	KUNIT_EXPECT_EQ(test, 3ul, GENMASK(1, 0));
+	KUNIT_EXPECT_EQ(test, 6ul, GENMASK(2, 1));
+	KUNIT_EXPECT_EQ(test, 0xFFFFFFFFul, GENMASK(31, 0));
+
+#ifdef TEST_GENMASK_FAILURES
+	/* these should fail compilation */
+	GENMASK(0, 1);
+	GENMASK(0, 10);
+	GENMASK(9, 10);
+#endif
+
+
+}
+
+static void genmask_ull_test(struct kunit *test)
+{
+	KUNIT_EXPECT_EQ(test, 1ull, GENMASK_ULL(0, 0));
+	KUNIT_EXPECT_EQ(test, 3ull, GENMASK_ULL(1, 0));
+	KUNIT_EXPECT_EQ(test, 0x000000ffffe00000ull, GENMASK_ULL(39, 21));
+	KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_ULL(63, 0));
+
+#ifdef TEST_GENMASK_FAILURES
+	/* these should fail compilation */
+	GENMASK_ULL(0, 1);
+	GENMASK_ULL(0, 10);
+	GENMASK_ULL(9, 10);
+#endif
+}
+
+static void genmask_u128_test(struct kunit *test)
+{
+#ifdef CONFIG_ARCH_SUPPORTS_INT128
+	/* Below 64 bit masks */
+	KUNIT_EXPECT_EQ(test, 0x0000000000000001ull, GENMASK_U128(0, 0));
+	KUNIT_EXPECT_EQ(test, 0x0000000000000003ull, GENMASK_U128(1, 0));
+	KUNIT_EXPECT_EQ(test, 0x0000000000000006ull, GENMASK_U128(2, 1));
+	KUNIT_EXPECT_EQ(test, 0x00000000ffffffffull, GENMASK_U128(31, 0));
+	KUNIT_EXPECT_EQ(test, 0x000000ffffe00000ull, GENMASK_U128(39, 21));
+	KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(63, 0));
+
+	/* Above 64 bit masks - only 64 bit portion can be validated once */
+	KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(64, 0) >> 1);
+	KUNIT_EXPECT_EQ(test, 0x00000000ffffffffull, GENMASK_U128(81, 50) >> 50);
+	KUNIT_EXPECT_EQ(test, 0x0000000000ffffffull, GENMASK_U128(87, 64) >> 64);
+	KUNIT_EXPECT_EQ(test, 0x0000000000ff0000ull, GENMASK_U128(87, 80) >> 64);
+
+	KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, GENMASK_U128(127, 0) >> 64);
+	KUNIT_EXPECT_EQ(test, 0xffffffffffffffffull, (u64)GENMASK_U128(127, 0));
+	KUNIT_EXPECT_EQ(test, 0x0000000000000003ull, GENMASK_U128(127, 126) >> 126);
+	KUNIT_EXPECT_EQ(test, 0x0000000000000001ull, GENMASK_U128(127, 127) >> 127);
+#ifdef TEST_GENMASK_FAILURES
+	/* these should fail compilation */
+	GENMASK_U128(0, 1);
+	GENMASK_U128(0, 10);
+	GENMASK_U128(9, 10);
+#endif /* TEST_GENMASK_FAILURES */
+#endif /* CONFIG_ARCH_SUPPORTS_INT128 */
+}
+
+static void genmask_input_check_test(struct kunit *test)
+{
+	unsigned int x, y;
+	int z, w;
+
+	/* Unknown input */
+	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, 0));
+	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, x));
+	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(x, y));
+
+	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, 0));
+	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(0, z));
+	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(z, w));
+
+	/* Valid input */
+	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(1, 1));
+	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(39, 21));
+	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(100, 80));
+	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(110, 65));
+	KUNIT_EXPECT_EQ(test, 0, GENMASK_INPUT_CHECK(127, 0));
+}
+
+
+static struct kunit_case bits_test_cases[] = {
+	KUNIT_CASE(genmask_test),
+	KUNIT_CASE(genmask_ull_test),
+	KUNIT_CASE(genmask_u128_test),
+	KUNIT_CASE(genmask_input_check_test),
+	{}
+};
+
+static struct kunit_suite bits_test_suite = {
+	.name = "bits-test",
+	.test_cases = bits_test_cases,
+};
+kunit_test_suite(bits_test_suite);
+
+MODULE_DESCRIPTION("Test cases for functions and macros in bits.h");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/test_fprobe.c a/lib/tests/test_fprobe.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/test_fprobe.c
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * test_fprobe.c - simple sanity test for fprobe
+ */
+
+#include <linux/kernel.h>
+#include <linux/fprobe.h>
+#include <linux/random.h>
+#include <kunit/test.h>
+
+#define div_factor 3
+
+static struct kunit *current_test;
+
+static u32 rand1, entry_val, exit_val;
+
+/* Use indirect calls to avoid inlining the target functions */
+static u32 (*target)(u32 value);
+static u32 (*target2)(u32 value);
+static u32 (*target_nest)(u32 value, u32 (*nest)(u32));
+static unsigned long target_ip;
+static unsigned long target2_ip;
+static unsigned long target_nest_ip;
+static int entry_return_value;
+
+static noinline u32 fprobe_selftest_target(u32 value)
+{
+	return (value / div_factor);
+}
+
+static noinline u32 fprobe_selftest_target2(u32 value)
+{
+	return (value / div_factor) + 1;
+}
+
+static noinline u32 fprobe_selftest_nest_target(u32 value, u32 (*nest)(u32))
+{
+	return nest(value + 2);
+}
+
+static notrace int fp_entry_handler(struct fprobe *fp, unsigned long ip,
+				    unsigned long ret_ip,
+				    struct pt_regs *regs, void *data)
+{
+	KUNIT_EXPECT_FALSE(current_test, preemptible());
+	/* This can be called on the fprobe_selftest_target and the fprobe_selftest_target2 */
+	if (ip != target_ip)
+		KUNIT_EXPECT_EQ(current_test, ip, target2_ip);
+	entry_val = (rand1 / div_factor);
+	if (fp->entry_data_size) {
+		KUNIT_EXPECT_NOT_NULL(current_test, data);
+		if (data)
+			*(u32 *)data = entry_val;
+	} else
+		KUNIT_EXPECT_NULL(current_test, data);
+
+	return entry_return_value;
+}
+
+static notrace void fp_exit_handler(struct fprobe *fp, unsigned long ip,
+				    unsigned long ret_ip,
+				    struct pt_regs *regs, void *data)
+{
+	unsigned long ret = regs_return_value(regs);
+
+	KUNIT_EXPECT_FALSE(current_test, preemptible());
+	if (ip != target_ip) {
+		KUNIT_EXPECT_EQ(current_test, ip, target2_ip);
+		KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor) + 1);
+	} else
+		KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor));
+	KUNIT_EXPECT_EQ(current_test, entry_val, (rand1 / div_factor));
+	exit_val = entry_val + div_factor;
+	if (fp->entry_data_size) {
+		KUNIT_EXPECT_NOT_NULL(current_test, data);
+		if (data)
+			KUNIT_EXPECT_EQ(current_test, *(u32 *)data, entry_val);
+	} else
+		KUNIT_EXPECT_NULL(current_test, data);
+}
+
+static notrace int nest_entry_handler(struct fprobe *fp, unsigned long ip,
+				      unsigned long ret_ip,
+				      struct pt_regs *regs, void *data)
+{
+	KUNIT_EXPECT_FALSE(current_test, preemptible());
+	return 0;
+}
+
+static notrace void nest_exit_handler(struct fprobe *fp, unsigned long ip,
+				      unsigned long ret_ip,
+				      struct pt_regs *regs, void *data)
+{
+	KUNIT_EXPECT_FALSE(current_test, preemptible());
+	KUNIT_EXPECT_EQ(current_test, ip, target_nest_ip);
+}
+
+/* Test entry only (no rethook) */
+static void test_fprobe_entry(struct kunit *test)
+{
+	struct fprobe fp_entry = {
+		.entry_handler = fp_entry_handler,
+	};
+
+	current_test = test;
+
+	/* Before register, unregister should be failed. */
+	KUNIT_EXPECT_NE(test, 0, unregister_fprobe(&fp_entry));
+	KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp_entry, "fprobe_selftest_target*", NULL));
+
+	entry_val = 0;
+	exit_val = 0;
+	target(rand1);
+	KUNIT_EXPECT_NE(test, 0, entry_val);
+	KUNIT_EXPECT_EQ(test, 0, exit_val);
+
+	entry_val = 0;
+	exit_val = 0;
+	target2(rand1);
+	KUNIT_EXPECT_NE(test, 0, entry_val);
+	KUNIT_EXPECT_EQ(test, 0, exit_val);
+
+	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp_entry));
+}
+
+static void test_fprobe(struct kunit *test)
+{
+	struct fprobe fp = {
+		.entry_handler = fp_entry_handler,
+		.exit_handler = fp_exit_handler,
+	};
+
+	current_test = test;
+	KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp, "fprobe_selftest_target*", NULL));
+
+	entry_val = 0;
+	exit_val = 0;
+	target(rand1);
+	KUNIT_EXPECT_NE(test, 0, entry_val);
+	KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
+
+	entry_val = 0;
+	exit_val = 0;
+	target2(rand1);
+	KUNIT_EXPECT_NE(test, 0, entry_val);
+	KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
+
+	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
+}
+
+static void test_fprobe_syms(struct kunit *test)
+{
+	static const char *syms[] = {"fprobe_selftest_target", "fprobe_selftest_target2"};
+	struct fprobe fp = {
+		.entry_handler = fp_entry_handler,
+		.exit_handler = fp_exit_handler,
+	};
+
+	current_test = test;
+	KUNIT_EXPECT_EQ(test, 0, register_fprobe_syms(&fp, syms, 2));
+
+	entry_val = 0;
+	exit_val = 0;
+	target(rand1);
+	KUNIT_EXPECT_NE(test, 0, entry_val);
+	KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
+
+	entry_val = 0;
+	exit_val = 0;
+	target2(rand1);
+	KUNIT_EXPECT_NE(test, 0, entry_val);
+	KUNIT_EXPECT_EQ(test, entry_val + div_factor, exit_val);
+
+	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
+}
+
+/* Test private entry_data */
+static void test_fprobe_data(struct kunit *test)
+{
+	struct fprobe fp = {
+		.entry_handler = fp_entry_handler,
+		.exit_handler = fp_exit_handler,
+		.entry_data_size = sizeof(u32),
+	};
+
+	current_test = test;
+	KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp, "fprobe_selftest_target", NULL));
+
+	target(rand1);
+
+	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
+}
+
+/* Test nr_maxactive */
+static void test_fprobe_nest(struct kunit *test)
+{
+	static const char *syms[] = {"fprobe_selftest_target", "fprobe_selftest_nest_target"};
+	struct fprobe fp = {
+		.entry_handler = nest_entry_handler,
+		.exit_handler = nest_exit_handler,
+		.nr_maxactive = 1,
+	};
+
+	current_test = test;
+	KUNIT_EXPECT_EQ(test, 0, register_fprobe_syms(&fp, syms, 2));
+
+	target_nest(rand1, target);
+	KUNIT_EXPECT_EQ(test, 1, fp.nmissed);
+
+	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
+}
+
+static void test_fprobe_skip(struct kunit *test)
+{
+	struct fprobe fp = {
+		.entry_handler = fp_entry_handler,
+		.exit_handler = fp_exit_handler,
+	};
+
+	current_test = test;
+	KUNIT_EXPECT_EQ(test, 0, register_fprobe(&fp, "fprobe_selftest_target", NULL));
+
+	entry_return_value = 1;
+	entry_val = 0;
+	exit_val = 0;
+	target(rand1);
+	KUNIT_EXPECT_NE(test, 0, entry_val);
+	KUNIT_EXPECT_EQ(test, 0, exit_val);
+	KUNIT_EXPECT_EQ(test, 0, fp.nmissed);
+	entry_return_value = 0;
+
+	KUNIT_EXPECT_EQ(test, 0, unregister_fprobe(&fp));
+}
+
+static unsigned long get_ftrace_location(void *func)
+{
+	unsigned long size, addr = (unsigned long)func;
+
+	if (!kallsyms_lookup_size_offset(addr, &size, NULL) || !size)
+		return 0;
+
+	return ftrace_location_range(addr, addr + size - 1);
+}
+
+static int fprobe_test_init(struct kunit *test)
+{
+	rand1 = get_random_u32_above(div_factor);
+	target = fprobe_selftest_target;
+	target2 = fprobe_selftest_target2;
+	target_nest = fprobe_selftest_nest_target;
+	target_ip = get_ftrace_location(target);
+	target2_ip = get_ftrace_location(target2);
+	target_nest_ip = get_ftrace_location(target_nest);
+
+	return 0;
+}
+
+static struct kunit_case fprobe_testcases[] = {
+	KUNIT_CASE(test_fprobe_entry),
+	KUNIT_CASE(test_fprobe),
+	KUNIT_CASE(test_fprobe_syms),
+	KUNIT_CASE(test_fprobe_data),
+	KUNIT_CASE(test_fprobe_nest),
+	KUNIT_CASE(test_fprobe_skip),
+	{}
+};
+
+static struct kunit_suite fprobe_test_suite = {
+	.name = "fprobe_test",
+	.init = fprobe_test_init,
+	.test_cases = fprobe_testcases,
+};
+
+kunit_test_suites(&fprobe_test_suite);
+
diff --git a/lib/tests/test_hash.c a/lib/tests/test_hash.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/test_hash.c
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test cases for <linux/hash.h> and <linux/stringhash.h>
+ * This just verifies that various ways of computing a hash
+ * produce the same thing and, for cases where a k-bit hash
+ * value is requested, is of the requested size.
+ *
+ * We fill a buffer with a 255-byte null-terminated string,
+ * and use both full_name_hash() and hashlen_string() to hash the
+ * substrings from i to j, where 0 <= i < j < 256.
+ *
+ * The returned values are used to check that __hash_32() and
+ * __hash_32_generic() compute the same thing.  Likewise hash_32()
+ * and hash_64().
+ */
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/hash.h>
+#include <linux/stringhash.h>
+#include <kunit/test.h>
+
+/* 32-bit XORSHIFT generator.  Seed must not be zero. */
+static u32 __attribute_const__
+xorshift(u32 seed)
+{
+	seed ^= seed << 13;
+	seed ^= seed >> 17;
+	seed ^= seed << 5;
+	return seed;
+}
+
+/* Given a non-zero x, returns a non-zero byte. */
+static u8 __attribute_const__
+mod255(u32 x)
+{
+	x = (x & 0xffff) + (x >> 16);	/* 1 <= x <= 0x1fffe */
+	x = (x & 0xff) + (x >> 8);	/* 1 <= x <= 0x2fd */
+	x = (x & 0xff) + (x >> 8);	/* 1 <= x <= 0x100 */
+	x = (x & 0xff) + (x >> 8);	/* 1 <= x <= 0xff */
+	return x;
+}
+
+/* Fill the buffer with non-zero bytes. */
+static void fill_buf(char *buf, size_t len, u32 seed)
+{
+	size_t i;
+
+	for (i = 0; i < len; i++) {
+		seed = xorshift(seed);
+		buf[i] = mod255(seed);
+	}
+}
+
+/* Holds most testing variables for the int test. */
+struct test_hash_params {
+        /* Pointer to integer to be hashed. */
+	unsigned long long *h64;
+        /* Low 32-bits of integer to be hashed. */
+	u32 h0;
+        /* Arch-specific hash result. */
+	u32 h1;
+        /* Generic hash result. */
+	u32 h2;
+        /* ORed hashes of given size (in bits). */
+	u32 (*hash_or)[33];
+};
+
+#ifdef HAVE_ARCH__HASH_32
+static void
+test_int__hash_32(struct kunit *test, struct test_hash_params *params)
+{
+	params->hash_or[1][0] |= params->h2 = __hash_32_generic(params->h0);
+#if HAVE_ARCH__HASH_32 == 1
+	KUNIT_EXPECT_EQ_MSG(test, params->h1, params->h2,
+			    "__hash_32(%#x) = %#x != __hash_32_generic() = %#x",
+			    params->h0, params->h1, params->h2);
+#endif
+}
+#endif
+
+#ifdef HAVE_ARCH_HASH_64
+static void
+test_int_hash_64(struct kunit *test, struct test_hash_params *params, u32 const *m, int *k)
+{
+	params->h2 = hash_64_generic(*params->h64, *k);
+#if HAVE_ARCH_HASH_64 == 1
+	KUNIT_EXPECT_EQ_MSG(test, params->h1, params->h2,
+			    "hash_64(%#llx, %d) = %#x != hash_64_generic() = %#x",
+			    *params->h64, *k, params->h1, params->h2);
+#else
+	KUNIT_EXPECT_LE_MSG(test, params->h1, params->h2,
+			    "hash_64_generic(%#llx, %d) = %#x > %#x",
+			    *params->h64, *k, params->h1, *m);
+#endif
+}
+#endif
+
+/*
+ * Test the various integer hash functions.  h64 (or its low-order bits)
+ * is the integer to hash.  hash_or accumulates the OR of the hash values,
+ * which are later checked to see that they cover all the requested bits.
+ *
+ * Because these functions (as opposed to the string hashes) are all
+ * inline, the code being tested is actually in the module, and you can
+ * recompile and re-test the module without rebooting.
+ */
+static void
+test_int_hash(struct kunit *test, unsigned long long h64, u32 hash_or[2][33])
+{
+	int k;
+	struct test_hash_params params = { &h64, (u32)h64, 0, 0, hash_or };
+
+	/* Test __hash32 */
+	hash_or[0][0] |= params.h1 = __hash_32(params.h0);
+#ifdef HAVE_ARCH__HASH_32
+	test_int__hash_32(test, &params);
+#endif
+
+	/* Test k = 1..32 bits */
+	for (k = 1; k <= 32; k++) {
+		u32 const m = ((u32)2 << (k-1)) - 1;	/* Low k bits set */
+
+		/* Test hash_32 */
+		hash_or[0][k] |= params.h1 = hash_32(params.h0, k);
+		KUNIT_EXPECT_LE_MSG(test, params.h1, m,
+				    "hash_32(%#x, %d) = %#x > %#x",
+				    params.h0, k, params.h1, m);
+
+		/* Test hash_64 */
+		hash_or[1][k] |= params.h1 = hash_64(h64, k);
+		KUNIT_EXPECT_LE_MSG(test, params.h1, m,
+				    "hash_64(%#llx, %d) = %#x > %#x",
+				    h64, k, params.h1, m);
+#ifdef HAVE_ARCH_HASH_64
+		test_int_hash_64(test, &params, &m, &k);
+#endif
+	}
+}
+
+#define SIZE 256	/* Run time is cubic in SIZE */
+
+static void test_string_or(struct kunit *test)
+{
+	char buf[SIZE+1];
+	u32 string_or = 0;
+	int i, j;
+
+	fill_buf(buf, SIZE, 1);
+
+	/* Test every possible non-empty substring in the buffer. */
+	for (j = SIZE; j > 0; --j) {
+		buf[j] = '\0';
+
+		for (i = 0; i <= j; i++) {
+			u32 h0 = full_name_hash(buf+i, buf+i, j-i);
+
+			string_or |= h0;
+		} /* i */
+	} /* j */
+
+	/* The OR of all the hash values should cover all the bits */
+	KUNIT_EXPECT_EQ_MSG(test, string_or, -1u,
+			    "OR of all string hash results = %#x != %#x",
+			    string_or, -1u);
+}
+
+static void test_hash_or(struct kunit *test)
+{
+	char buf[SIZE+1];
+	u32 hash_or[2][33] = { { 0, } };
+	unsigned long long h64 = 0;
+	int i, j;
+
+	fill_buf(buf, SIZE, 1);
+
+	/* Test every possible non-empty substring in the buffer. */
+	for (j = SIZE; j > 0; --j) {
+		buf[j] = '\0';
+
+		for (i = 0; i <= j; i++) {
+			u64 hashlen = hashlen_string(buf+i, buf+i);
+			u32 h0 = full_name_hash(buf+i, buf+i, j-i);
+
+			/* Check that hashlen_string gets the length right */
+			KUNIT_EXPECT_EQ_MSG(test, hashlen_len(hashlen), j-i,
+					    "hashlen_string(%d..%d) returned length %u, expected %d",
+					    i, j, hashlen_len(hashlen), j-i);
+			/* Check that the hashes match */
+			KUNIT_EXPECT_EQ_MSG(test, hashlen_hash(hashlen), h0,
+					    "hashlen_string(%d..%d) = %08x != full_name_hash() = %08x",
+					    i, j, hashlen_hash(hashlen), h0);
+
+			h64 = h64 << 32 | h0;	/* For use with hash_64 */
+			test_int_hash(test, h64, hash_or);
+		} /* i */
+	} /* j */
+
+	KUNIT_EXPECT_EQ_MSG(test, hash_or[0][0], -1u,
+			    "OR of all __hash_32 results = %#x != %#x",
+			    hash_or[0][0], -1u);
+#ifdef HAVE_ARCH__HASH_32
+#if HAVE_ARCH__HASH_32 != 1	/* Test is pointless if results match */
+	KUNIT_EXPECT_EQ_MSG(test, hash_or[1][0], -1u,
+			    "OR of all __hash_32_generic results = %#x != %#x",
+			    hash_or[1][0], -1u);
+#endif
+#endif
+
+	/* Likewise for all the i-bit hash values */
+	for (i = 1; i <= 32; i++) {
+		u32 const m = ((u32)2 << (i-1)) - 1;	/* Low i bits set */
+
+		KUNIT_EXPECT_EQ_MSG(test, hash_or[0][i], m,
+				    "OR of all hash_32(%d) results = %#x (%#x expected)",
+				    i, hash_or[0][i], m);
+		KUNIT_EXPECT_EQ_MSG(test, hash_or[1][i], m,
+				    "OR of all hash_64(%d) results = %#x (%#x expected)",
+				    i, hash_or[1][i], m);
+	}
+}
+
+static struct kunit_case hash_test_cases[] __refdata = {
+	KUNIT_CASE(test_string_or),
+	KUNIT_CASE(test_hash_or),
+	{}
+};
+
+static struct kunit_suite hash_test_suite = {
+	.name = "hash",
+	.test_cases = hash_test_cases,
+};
+
+
+kunit_test_suite(hash_test_suite);
+
+MODULE_DESCRIPTION("Test cases for <linux/hash.h> and <linux/stringhash.h>");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/test_kprobes.c a/lib/tests/test_kprobes.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/test_kprobes.c
@@ -0,0 +1,404 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * test_kprobes.c - simple sanity test for k*probes
+ *
+ * Copyright IBM Corp. 2008
+ */
+
+#include <linux/kernel.h>
+#include <linux/kprobes.h>
+#include <linux/random.h>
+#include <kunit/test.h>
+
+#define div_factor 3
+
+static u32 rand1, preh_val, posth_val;
+static u32 (*target)(u32 value);
+static u32 (*recursed_target)(u32 value);
+static u32 (*target2)(u32 value);
+static struct kunit *current_test;
+
+static unsigned long (*internal_target)(void);
+static unsigned long (*stacktrace_target)(void);
+static unsigned long (*stacktrace_driver)(void);
+static unsigned long target_return_address[2];
+
+static noinline u32 kprobe_target(u32 value)
+{
+	return (value / div_factor);
+}
+
+static noinline u32 kprobe_recursed_target(u32 value)
+{
+	return (value / div_factor);
+}
+
+static int kp_pre_handler(struct kprobe *p, struct pt_regs *regs)
+{
+	KUNIT_EXPECT_FALSE(current_test, preemptible());
+
+	preh_val = recursed_target(rand1);
+	return 0;
+}
+
+static void kp_post_handler(struct kprobe *p, struct pt_regs *regs,
+		unsigned long flags)
+{
+	u32 expval = recursed_target(rand1);
+
+	KUNIT_EXPECT_FALSE(current_test, preemptible());
+	KUNIT_EXPECT_EQ(current_test, preh_val, expval);
+
+	posth_val = preh_val + div_factor;
+}
+
+static struct kprobe kp = {
+	.symbol_name = "kprobe_target",
+	.pre_handler = kp_pre_handler,
+	.post_handler = kp_post_handler
+};
+
+static void test_kprobe(struct kunit *test)
+{
+	current_test = test;
+	KUNIT_EXPECT_EQ(test, 0, register_kprobe(&kp));
+	target(rand1);
+	unregister_kprobe(&kp);
+	KUNIT_EXPECT_NE(test, 0, preh_val);
+	KUNIT_EXPECT_NE(test, 0, posth_val);
+}
+
+static noinline u32 kprobe_target2(u32 value)
+{
+	return (value / div_factor) + 1;
+}
+
+static noinline unsigned long kprobe_stacktrace_internal_target(void)
+{
+	if (!target_return_address[0])
+		target_return_address[0] = (unsigned long)__builtin_return_address(0);
+	return target_return_address[0];
+}
+
+static noinline unsigned long kprobe_stacktrace_target(void)
+{
+	if (!target_return_address[1])
+		target_return_address[1] = (unsigned long)__builtin_return_address(0);
+
+	if (internal_target)
+		internal_target();
+
+	return target_return_address[1];
+}
+
+static noinline unsigned long kprobe_stacktrace_driver(void)
+{
+	if (stacktrace_target)
+		stacktrace_target();
+
+	/* This is for preventing inlining the function */
+	return (unsigned long)__builtin_return_address(0);
+}
+
+static int kp_pre_handler2(struct kprobe *p, struct pt_regs *regs)
+{
+	preh_val = (rand1 / div_factor) + 1;
+	return 0;
+}
+
+static void kp_post_handler2(struct kprobe *p, struct pt_regs *regs,
+		unsigned long flags)
+{
+	KUNIT_EXPECT_EQ(current_test, preh_val, (rand1 / div_factor) + 1);
+	posth_val = preh_val + div_factor;
+}
+
+static struct kprobe kp2 = {
+	.symbol_name = "kprobe_target2",
+	.pre_handler = kp_pre_handler2,
+	.post_handler = kp_post_handler2
+};
+
+static void test_kprobes(struct kunit *test)
+{
+	struct kprobe *kps[2] = {&kp, &kp2};
+
+	current_test = test;
+
+	/* addr and flags should be cleard for reusing kprobe. */
+	kp.addr = NULL;
+	kp.flags = 0;
+
+	KUNIT_EXPECT_EQ(test, 0, register_kprobes(kps, 2));
+	preh_val = 0;
+	posth_val = 0;
+	target(rand1);
+
+	KUNIT_EXPECT_NE(test, 0, preh_val);
+	KUNIT_EXPECT_NE(test, 0, posth_val);
+
+	preh_val = 0;
+	posth_val = 0;
+	target2(rand1);
+
+	KUNIT_EXPECT_NE(test, 0, preh_val);
+	KUNIT_EXPECT_NE(test, 0, posth_val);
+	unregister_kprobes(kps, 2);
+}
+
+static struct kprobe kp_missed = {
+	.symbol_name = "kprobe_recursed_target",
+	.pre_handler = kp_pre_handler,
+	.post_handler = kp_post_handler,
+};
+
+static void test_kprobe_missed(struct kunit *test)
+{
+	current_test = test;
+	preh_val = 0;
+	posth_val = 0;
+
+	KUNIT_EXPECT_EQ(test, 0, register_kprobe(&kp_missed));
+
+	recursed_target(rand1);
+
+	KUNIT_EXPECT_EQ(test, 2, kp_missed.nmissed);
+	KUNIT_EXPECT_NE(test, 0, preh_val);
+	KUNIT_EXPECT_NE(test, 0, posth_val);
+
+	unregister_kprobe(&kp_missed);
+}
+
+#ifdef CONFIG_KRETPROBES
+static u32 krph_val;
+
+static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	KUNIT_EXPECT_FALSE(current_test, preemptible());
+	krph_val = (rand1 / div_factor);
+	return 0;
+}
+
+static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	unsigned long ret = regs_return_value(regs);
+
+	KUNIT_EXPECT_FALSE(current_test, preemptible());
+	KUNIT_EXPECT_EQ(current_test, ret, rand1 / div_factor);
+	KUNIT_EXPECT_NE(current_test, krph_val, 0);
+	krph_val = rand1;
+	return 0;
+}
+
+static struct kretprobe rp = {
+	.handler	= return_handler,
+	.entry_handler  = entry_handler,
+	.kp.symbol_name = "kprobe_target"
+};
+
+static void test_kretprobe(struct kunit *test)
+{
+	current_test = test;
+	KUNIT_EXPECT_EQ(test, 0, register_kretprobe(&rp));
+	target(rand1);
+	unregister_kretprobe(&rp);
+	KUNIT_EXPECT_EQ(test, krph_val, rand1);
+}
+
+static int return_handler2(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	unsigned long ret = regs_return_value(regs);
+
+	KUNIT_EXPECT_EQ(current_test, ret, (rand1 / div_factor) + 1);
+	KUNIT_EXPECT_NE(current_test, krph_val, 0);
+	krph_val = rand1;
+	return 0;
+}
+
+static struct kretprobe rp2 = {
+	.handler	= return_handler2,
+	.entry_handler  = entry_handler,
+	.kp.symbol_name = "kprobe_target2"
+};
+
+static void test_kretprobes(struct kunit *test)
+{
+	struct kretprobe *rps[2] = {&rp, &rp2};
+
+	current_test = test;
+	/* addr and flags should be cleard for reusing kprobe. */
+	rp.kp.addr = NULL;
+	rp.kp.flags = 0;
+	KUNIT_EXPECT_EQ(test, 0, register_kretprobes(rps, 2));
+
+	krph_val = 0;
+	target(rand1);
+	KUNIT_EXPECT_EQ(test, krph_val, rand1);
+
+	krph_val = 0;
+	target2(rand1);
+	KUNIT_EXPECT_EQ(test, krph_val, rand1);
+	unregister_kretprobes(rps, 2);
+}
+
+#ifdef CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
+#define STACK_BUF_SIZE 16
+static unsigned long stack_buf[STACK_BUF_SIZE];
+
+static int stacktrace_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	unsigned long retval = regs_return_value(regs);
+	int i, ret;
+
+	KUNIT_EXPECT_FALSE(current_test, preemptible());
+	KUNIT_EXPECT_EQ(current_test, retval, target_return_address[1]);
+
+	/*
+	 * Test stacktrace inside the kretprobe handler, this will involves
+	 * kretprobe trampoline, but must include correct return address
+	 * of the target function.
+	 */
+	ret = stack_trace_save(stack_buf, STACK_BUF_SIZE, 0);
+	KUNIT_EXPECT_NE(current_test, ret, 0);
+
+	for (i = 0; i < ret; i++) {
+		if (stack_buf[i] == target_return_address[1])
+			break;
+	}
+	KUNIT_EXPECT_NE(current_test, i, ret);
+
+#if !IS_MODULE(CONFIG_KPROBES_SANITY_TEST)
+	/*
+	 * Test stacktrace from pt_regs at the return address. Thus the stack
+	 * trace must start from the target return address.
+	 */
+	ret = stack_trace_save_regs(regs, stack_buf, STACK_BUF_SIZE, 0);
+	KUNIT_EXPECT_NE(current_test, ret, 0);
+	KUNIT_EXPECT_EQ(current_test, stack_buf[0], target_return_address[1]);
+#endif
+
+	return 0;
+}
+
+static struct kretprobe rp3 = {
+	.handler	= stacktrace_return_handler,
+	.kp.symbol_name = "kprobe_stacktrace_target"
+};
+
+static void test_stacktrace_on_kretprobe(struct kunit *test)
+{
+	unsigned long myretaddr = (unsigned long)__builtin_return_address(0);
+
+	current_test = test;
+	rp3.kp.addr = NULL;
+	rp3.kp.flags = 0;
+
+	/*
+	 * Run the stacktrace_driver() to record correct return address in
+	 * stacktrace_target() and ensure stacktrace_driver() call is not
+	 * inlined by checking the return address of stacktrace_driver()
+	 * and the return address of this function is different.
+	 */
+	KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
+
+	KUNIT_ASSERT_EQ(test, 0, register_kretprobe(&rp3));
+	KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
+	unregister_kretprobe(&rp3);
+}
+
+static int stacktrace_internal_return_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
+{
+	unsigned long retval = regs_return_value(regs);
+	int i, ret;
+
+	KUNIT_EXPECT_FALSE(current_test, preemptible());
+	KUNIT_EXPECT_EQ(current_test, retval, target_return_address[0]);
+
+	/*
+	 * Test stacktrace inside the kretprobe handler for nested case.
+	 * The unwinder will find the kretprobe_trampoline address on the
+	 * return address, and kretprobe must solve that.
+	 */
+	ret = stack_trace_save(stack_buf, STACK_BUF_SIZE, 0);
+	KUNIT_EXPECT_NE(current_test, ret, 0);
+
+	for (i = 0; i < ret - 1; i++) {
+		if (stack_buf[i] == target_return_address[0]) {
+			KUNIT_EXPECT_EQ(current_test, stack_buf[i + 1], target_return_address[1]);
+			break;
+		}
+	}
+	KUNIT_EXPECT_NE(current_test, i, ret);
+
+#if !IS_MODULE(CONFIG_KPROBES_SANITY_TEST)
+	/* Ditto for the regs version. */
+	ret = stack_trace_save_regs(regs, stack_buf, STACK_BUF_SIZE, 0);
+	KUNIT_EXPECT_NE(current_test, ret, 0);
+	KUNIT_EXPECT_EQ(current_test, stack_buf[0], target_return_address[0]);
+	KUNIT_EXPECT_EQ(current_test, stack_buf[1], target_return_address[1]);
+#endif
+
+	return 0;
+}
+
+static struct kretprobe rp4 = {
+	.handler	= stacktrace_internal_return_handler,
+	.kp.symbol_name = "kprobe_stacktrace_internal_target"
+};
+
+static void test_stacktrace_on_nested_kretprobe(struct kunit *test)
+{
+	unsigned long myretaddr = (unsigned long)__builtin_return_address(0);
+	struct kretprobe *rps[2] = {&rp3, &rp4};
+
+	current_test = test;
+	rp3.kp.addr = NULL;
+	rp3.kp.flags = 0;
+
+	//KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
+
+	KUNIT_ASSERT_EQ(test, 0, register_kretprobes(rps, 2));
+	KUNIT_ASSERT_NE(test, myretaddr, stacktrace_driver());
+	unregister_kretprobes(rps, 2);
+}
+#endif /* CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE */
+
+#endif /* CONFIG_KRETPROBES */
+
+static int kprobes_test_init(struct kunit *test)
+{
+	target = kprobe_target;
+	target2 = kprobe_target2;
+	recursed_target = kprobe_recursed_target;
+	stacktrace_target = kprobe_stacktrace_target;
+	internal_target = kprobe_stacktrace_internal_target;
+	stacktrace_driver = kprobe_stacktrace_driver;
+	rand1 = get_random_u32_above(div_factor);
+	return 0;
+}
+
+static struct kunit_case kprobes_testcases[] = {
+	KUNIT_CASE(test_kprobe),
+	KUNIT_CASE(test_kprobes),
+	KUNIT_CASE(test_kprobe_missed),
+#ifdef CONFIG_KRETPROBES
+	KUNIT_CASE(test_kretprobe),
+	KUNIT_CASE(test_kretprobes),
+#ifdef CONFIG_ARCH_CORRECT_STACKTRACE_ON_KRETPROBE
+	KUNIT_CASE(test_stacktrace_on_kretprobe),
+	KUNIT_CASE(test_stacktrace_on_nested_kretprobe),
+#endif
+#endif
+	{}
+};
+
+static struct kunit_suite kprobes_test_suite = {
+	.name = "kprobes_test",
+	.init = kprobes_test_init,
+	.test_cases = kprobes_testcases,
+};
+
+kunit_test_suites(&kprobes_test_suite);
+
+MODULE_DESCRIPTION("simple sanity test for k*probes");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/test_linear_ranges.c a/lib/tests/test_linear_ranges.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/test_linear_ranges.c
@@ -0,0 +1,220 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * KUnit test for the linear_ranges helper.
+ *
+ * Copyright (C) 2020, ROHM Semiconductors.
+ * Author: Matti Vaittinen <matti.vaittien@xxxxxxxxxxxxxxxxx>
+ */
+#include <kunit/test.h>
+
+#include <linux/linear_range.h>
+
+/* First things first. I deeply dislike unit-tests. I have seen all the hell
+ * breaking loose when people who think the unit tests are "the silver bullet"
+ * to kill bugs get to decide how a company should implement testing strategy...
+ *
+ * Believe me, it may get _really_ ridiculous. It is tempting to think that
+ * walking through all the possible execution branches will nail down 100% of
+ * bugs. This may lead to ideas about demands to get certain % of "test
+ * coverage" - measured as line coverage. And that is one of the worst things
+ * you can do.
+ *
+ * Ask people to provide line coverage and they do. I've seen clever tools
+ * which generate test cases to test the existing functions - and by default
+ * these tools expect code to be correct and just generate checks which are
+ * passing when ran against current code-base. Run this generator and you'll get
+ * tests that do not test code is correct but just verify nothing changes.
+ * Problem is that testing working code is pointless. And if it is not
+ * working, your test must not assume it is working. You won't catch any bugs
+ * by such tests. What you can do is to generate a huge amount of tests.
+ * Especially if you were are asked to proivde 100% line-coverage x_x. So what
+ * does these tests - which are not finding any bugs now - do?
+ *
+ * They add inertia to every future development. I think it was Terry Pratchet
+ * who wrote someone having same impact as thick syrup has to chronometre.
+ * Excessive amount of unit-tests have this effect to development. If you do
+ * actually find _any_ bug from code in such environment and try fixing it...
+ * ...chances are you also need to fix the test cases. In sunny day you fix one
+ * test. But I've done refactoring which resulted 500+ broken tests (which had
+ * really zero value other than proving to managers that we do do "quality")...
+ *
+ * After this being said - there are situations where UTs can be handy. If you
+ * have algorithms which take some input and should produce output - then you
+ * can implement few, carefully selected simple UT-cases which test this. I've
+ * previously used this for example for netlink and device-tree data parsing
+ * functions. Feed some data examples to functions and verify the output is as
+ * expected. I am not covering all the cases but I will see the logic should be
+ * working.
+ *
+ * Here we also do some minor testing. I don't want to go through all branches
+ * or test more or less obvious things - but I want to see the main logic is
+ * working. And I definitely don't want to add 500+ test cases that break when
+ * some simple fix is done x_x. So - let's only add few, well selected tests
+ * which ensure as much logic is good as possible.
+ */
+
+/*
+ * Test Range 1:
+ * selectors:	2	3	4	5	6
+ * values (5):	10	20	30	40	50
+ *
+ * Test Range 2:
+ * selectors:	7	8	9	10
+ * values (4):	100	150	200	250
+ */
+
+#define RANGE1_MIN 10
+#define RANGE1_MIN_SEL 2
+#define RANGE1_STEP 10
+
+/* 2, 3, 4, 5, 6 */
+static const unsigned int range1_sels[] = { RANGE1_MIN_SEL, RANGE1_MIN_SEL + 1,
+					    RANGE1_MIN_SEL + 2,
+					    RANGE1_MIN_SEL + 3,
+					    RANGE1_MIN_SEL + 4 };
+/* 10, 20, 30, 40, 50 */
+static const unsigned int range1_vals[] = { RANGE1_MIN, RANGE1_MIN +
+					    RANGE1_STEP,
+					    RANGE1_MIN + RANGE1_STEP * 2,
+					    RANGE1_MIN + RANGE1_STEP * 3,
+					    RANGE1_MIN + RANGE1_STEP * 4 };
+
+#define RANGE2_MIN 100
+#define RANGE2_MIN_SEL 7
+#define RANGE2_STEP 50
+
+/*  7, 8, 9, 10 */
+static const unsigned int range2_sels[] = { RANGE2_MIN_SEL, RANGE2_MIN_SEL + 1,
+					    RANGE2_MIN_SEL + 2,
+					    RANGE2_MIN_SEL + 3 };
+/* 100, 150, 200, 250 */
+static const unsigned int range2_vals[] = { RANGE2_MIN, RANGE2_MIN +
+					    RANGE2_STEP,
+					    RANGE2_MIN + RANGE2_STEP * 2,
+					    RANGE2_MIN + RANGE2_STEP * 3 };
+
+#define RANGE1_NUM_VALS (ARRAY_SIZE(range1_vals))
+#define RANGE2_NUM_VALS (ARRAY_SIZE(range2_vals))
+#define RANGE_NUM_VALS (RANGE1_NUM_VALS + RANGE2_NUM_VALS)
+
+#define RANGE1_MAX_SEL (RANGE1_MIN_SEL + RANGE1_NUM_VALS - 1)
+#define RANGE1_MAX_VAL (range1_vals[RANGE1_NUM_VALS - 1])
+
+#define RANGE2_MAX_SEL (RANGE2_MIN_SEL + RANGE2_NUM_VALS - 1)
+#define RANGE2_MAX_VAL (range2_vals[RANGE2_NUM_VALS - 1])
+
+#define SMALLEST_SEL RANGE1_MIN_SEL
+#define SMALLEST_VAL RANGE1_MIN
+
+static struct linear_range testr[] = {
+	LINEAR_RANGE(RANGE1_MIN, RANGE1_MIN_SEL, RANGE1_MAX_SEL, RANGE1_STEP),
+	LINEAR_RANGE(RANGE2_MIN, RANGE2_MIN_SEL, RANGE2_MAX_SEL, RANGE2_STEP),
+};
+
+static void range_test_get_value(struct kunit *test)
+{
+	int ret, i;
+	unsigned int sel, val;
+
+	for (i = 0; i < RANGE1_NUM_VALS; i++) {
+		sel = range1_sels[i];
+		ret = linear_range_get_value_array(&testr[0], 2, sel, &val);
+		KUNIT_EXPECT_EQ(test, 0, ret);
+		KUNIT_EXPECT_EQ(test, val, range1_vals[i]);
+	}
+	for (i = 0; i < RANGE2_NUM_VALS; i++) {
+		sel = range2_sels[i];
+		ret = linear_range_get_value_array(&testr[0], 2, sel, &val);
+		KUNIT_EXPECT_EQ(test, 0, ret);
+		KUNIT_EXPECT_EQ(test, val, range2_vals[i]);
+	}
+	ret = linear_range_get_value_array(&testr[0], 2, sel + 1, &val);
+	KUNIT_EXPECT_NE(test, 0, ret);
+}
+
+static void range_test_get_selector_high(struct kunit *test)
+{
+	int ret, i;
+	unsigned int sel;
+	bool found;
+
+	for (i = 0; i < RANGE1_NUM_VALS; i++) {
+		ret = linear_range_get_selector_high(&testr[0], range1_vals[i],
+						     &sel, &found);
+		KUNIT_EXPECT_EQ(test, 0, ret);
+		KUNIT_EXPECT_EQ(test, sel, range1_sels[i]);
+		KUNIT_EXPECT_TRUE(test, found);
+	}
+
+	ret = linear_range_get_selector_high(&testr[0], RANGE1_MAX_VAL + 1,
+					     &sel, &found);
+	KUNIT_EXPECT_LE(test, ret, 0);
+
+	ret = linear_range_get_selector_high(&testr[0], RANGE1_MIN - 1,
+					     &sel, &found);
+	KUNIT_EXPECT_EQ(test, 0, ret);
+	KUNIT_EXPECT_FALSE(test, found);
+	KUNIT_EXPECT_EQ(test, sel, range1_sels[0]);
+}
+
+static void range_test_get_value_amount(struct kunit *test)
+{
+	int ret;
+
+	ret = linear_range_values_in_range_array(&testr[0], 2);
+	KUNIT_EXPECT_EQ(test, (int)RANGE_NUM_VALS, ret);
+}
+
+static void range_test_get_selector_low(struct kunit *test)
+{
+	int i, ret;
+	unsigned int sel;
+	bool found;
+
+	for (i = 0; i < RANGE1_NUM_VALS; i++) {
+		ret = linear_range_get_selector_low_array(&testr[0], 2,
+							  range1_vals[i], &sel,
+							  &found);
+		KUNIT_EXPECT_EQ(test, 0, ret);
+		KUNIT_EXPECT_EQ(test, sel, range1_sels[i]);
+		KUNIT_EXPECT_TRUE(test, found);
+	}
+	for (i = 0; i < RANGE2_NUM_VALS; i++) {
+		ret = linear_range_get_selector_low_array(&testr[0], 2,
+							  range2_vals[i], &sel,
+							  &found);
+		KUNIT_EXPECT_EQ(test, 0, ret);
+		KUNIT_EXPECT_EQ(test, sel, range2_sels[i]);
+		KUNIT_EXPECT_TRUE(test, found);
+	}
+
+	/*
+	 * Seek value greater than range max => get_selector_*_low should
+	 * return Ok - but set found to false as value is not in range
+	 */
+	ret = linear_range_get_selector_low_array(&testr[0], 2,
+					range2_vals[RANGE2_NUM_VALS - 1] + 1,
+					&sel, &found);
+
+	KUNIT_EXPECT_EQ(test, 0, ret);
+	KUNIT_EXPECT_EQ(test, sel, range2_sels[RANGE2_NUM_VALS - 1]);
+	KUNIT_EXPECT_FALSE(test, found);
+}
+
+static struct kunit_case range_test_cases[] = {
+	KUNIT_CASE(range_test_get_value_amount),
+	KUNIT_CASE(range_test_get_selector_high),
+	KUNIT_CASE(range_test_get_selector_low),
+	KUNIT_CASE(range_test_get_value),
+	{},
+};
+
+static struct kunit_suite range_test_module = {
+	.name = "linear-ranges-test",
+	.test_cases = range_test_cases,
+};
+
+kunit_test_suites(&range_test_module);
+
+MODULE_DESCRIPTION("KUnit test for the linear_ranges helper");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/test_list_sort.c a/lib/tests/test_list_sort.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/test_list_sort.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <kunit/test.h>
+
+#include <linux/kernel.h>
+#include <linux/list_sort.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+
+/*
+ * The pattern of set bits in the list length determines which cases
+ * are hit in list_sort().
+ */
+#define TEST_LIST_LEN (512+128+2) /* not including head */
+
+#define TEST_POISON1 0xDEADBEEF
+#define TEST_POISON2 0xA324354C
+
+struct debug_el {
+	unsigned int poison1;
+	struct list_head list;
+	unsigned int poison2;
+	int value;
+	unsigned int serial;
+};
+
+static void check(struct kunit *test, struct debug_el *ela, struct debug_el *elb)
+{
+	struct debug_el **elts = test->priv;
+
+	KUNIT_EXPECT_LT_MSG(test, ela->serial, (unsigned int)TEST_LIST_LEN, "incorrect serial");
+	KUNIT_EXPECT_LT_MSG(test, elb->serial, (unsigned int)TEST_LIST_LEN, "incorrect serial");
+
+	KUNIT_EXPECT_PTR_EQ_MSG(test, elts[ela->serial], ela, "phantom element");
+	KUNIT_EXPECT_PTR_EQ_MSG(test, elts[elb->serial], elb, "phantom element");
+
+	KUNIT_EXPECT_EQ_MSG(test, ela->poison1, TEST_POISON1, "bad poison");
+	KUNIT_EXPECT_EQ_MSG(test, ela->poison2, TEST_POISON2, "bad poison");
+
+	KUNIT_EXPECT_EQ_MSG(test, elb->poison1, TEST_POISON1, "bad poison");
+	KUNIT_EXPECT_EQ_MSG(test, elb->poison2, TEST_POISON2, "bad poison");
+}
+
+/* `priv` is the test pointer so check() can fail the test if the list is invalid. */
+static int cmp(void *priv, const struct list_head *a, const struct list_head *b)
+{
+	struct debug_el *ela, *elb;
+
+	ela = container_of(a, struct debug_el, list);
+	elb = container_of(b, struct debug_el, list);
+
+	check(priv, ela, elb);
+	return ela->value - elb->value;
+}
+
+static void list_sort_test(struct kunit *test)
+{
+	int i, count = 1;
+	struct debug_el *el, **elts;
+	struct list_head *cur;
+	LIST_HEAD(head);
+
+	elts = kunit_kcalloc(test, TEST_LIST_LEN, sizeof(*elts), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, elts);
+	test->priv = elts;
+
+	for (i = 0; i < TEST_LIST_LEN; i++) {
+		el = kunit_kmalloc(test, sizeof(*el), GFP_KERNEL);
+		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, el);
+
+		 /* force some equivalencies */
+		el->value = get_random_u32_below(TEST_LIST_LEN / 3);
+		el->serial = i;
+		el->poison1 = TEST_POISON1;
+		el->poison2 = TEST_POISON2;
+		elts[i] = el;
+		list_add_tail(&el->list, &head);
+	}
+
+	list_sort(test, &head, cmp);
+
+	for (cur = head.next; cur->next != &head; cur = cur->next) {
+		struct debug_el *el1;
+		int cmp_result;
+
+		KUNIT_ASSERT_PTR_EQ_MSG(test, cur->next->prev, cur,
+					"list is corrupted");
+
+		cmp_result = cmp(test, cur, cur->next);
+		KUNIT_ASSERT_LE_MSG(test, cmp_result, 0, "list is not sorted");
+
+		el = container_of(cur, struct debug_el, list);
+		el1 = container_of(cur->next, struct debug_el, list);
+		if (cmp_result == 0) {
+			KUNIT_ASSERT_LE_MSG(test, el->serial, el1->serial,
+					    "order of equivalent elements not preserved");
+		}
+
+		check(test, el, el1);
+		count++;
+	}
+	KUNIT_EXPECT_PTR_EQ_MSG(test, head.prev, cur, "list is corrupted");
+
+	KUNIT_EXPECT_EQ_MSG(test, count, TEST_LIST_LEN,
+			    "list length changed after sorting!");
+}
+
+static struct kunit_case list_sort_cases[] = {
+	KUNIT_CASE(list_sort_test),
+	{}
+};
+
+static struct kunit_suite list_sort_suite = {
+	.name = "list_sort",
+	.test_cases = list_sort_cases,
+};
+
+kunit_test_suites(&list_sort_suite);
+
+MODULE_DESCRIPTION("list_sort() KUnit test suite");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/test_sort.c a/lib/tests/test_sort.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/test_sort.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <kunit/test.h>
+
+#include <linux/sort.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+
+/* a simple boot-time regression test */
+
+#define TEST_LEN 1000
+
+static int cmpint(const void *a, const void *b)
+{
+	return *(int *)a - *(int *)b;
+}
+
+static void test_sort(struct kunit *test)
+{
+	int *a, i, r = 1;
+
+	a = kunit_kmalloc_array(test, TEST_LEN, sizeof(*a), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, a);
+
+	for (i = 0; i < TEST_LEN; i++) {
+		r = (r * 725861) % 6599;
+		a[i] = r;
+	}
+
+	sort(a, TEST_LEN, sizeof(*a), cmpint, NULL);
+
+	for (i = 0; i < TEST_LEN - 1; i++)
+		KUNIT_ASSERT_LE(test, a[i], a[i + 1]);
+
+	r = 48;
+
+	for (i = 0; i < TEST_LEN - 1; i++) {
+		r = (r * 725861) % 6599;
+		a[i] = r;
+	}
+
+	sort(a, TEST_LEN - 1, sizeof(*a), cmpint, NULL);
+
+	for (i = 0; i < TEST_LEN - 2; i++)
+		KUNIT_ASSERT_LE(test, a[i], a[i + 1]);
+}
+
+static struct kunit_case sort_test_cases[] = {
+	KUNIT_CASE(test_sort),
+	{}
+};
+
+static struct kunit_suite sort_test_suite = {
+	.name = "lib_sort",
+	.test_cases = sort_test_cases,
+};
+
+kunit_test_suites(&sort_test_suite);
+
+MODULE_DESCRIPTION("sort() KUnit test suite");
+MODULE_LICENSE("GPL");
diff --git a/lib/tests/usercopy_kunit.c a/lib/tests/usercopy_kunit.c
new file mode 100664
--- /dev/null
+++ a/lib/tests/usercopy_kunit.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Kernel module for testing copy_to/from_user infrastructure.
+ *
+ * Copyright 2013 Google Inc. All Rights Reserved
+ *
+ * Authors:
+ *      Kees Cook       <keescook@xxxxxxxxxxxx>
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/mman.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <kunit/test.h>
+
+/*
+ * Several 32-bit architectures support 64-bit {get,put}_user() calls.
+ * As there doesn't appear to be anything that can safely determine
+ * their capability at compile-time, we just have to opt-out certain archs.
+ */
+#if BITS_PER_LONG == 64 || (!(defined(CONFIG_ARM) && !defined(MMU)) && \
+			    !defined(CONFIG_M68K) &&		\
+			    !defined(CONFIG_MICROBLAZE) &&	\
+			    !defined(CONFIG_NIOS2) &&		\
+			    !defined(CONFIG_PPC32) &&		\
+			    !defined(CONFIG_SUPERH))
+# define TEST_U64
+#endif
+
+struct usercopy_test_priv {
+	char *kmem;
+	char __user *umem;
+	size_t size;
+};
+
+static bool is_zeroed(void *from, size_t size)
+{
+	return memchr_inv(from, 0x0, size) == NULL;
+}
+
+/* Test usage of check_nonzero_user(). */
+static void usercopy_test_check_nonzero_user(struct kunit *test)
+{
+	size_t start, end, i, zero_start, zero_end;
+	struct usercopy_test_priv *priv = test->priv;
+	char __user *umem = priv->umem;
+	char *kmem = priv->kmem;
+	size_t size = priv->size;
+
+	KUNIT_ASSERT_GE_MSG(test, size, 2 * PAGE_SIZE, "buffer too small");
+
+	/*
+	 * We want to cross a page boundary to exercise the code more
+	 * effectively. We also don't want to make the size we scan too large,
+	 * otherwise the test can take a long time and cause soft lockups. So
+	 * scan a 1024 byte region across the page boundary.
+	 */
+	size = 1024;
+	start = PAGE_SIZE - (size / 2);
+
+	kmem += start;
+	umem += start;
+
+	zero_start = size / 4;
+	zero_end = size - zero_start;
+
+	/*
+	 * We conduct a series of check_nonzero_user() tests on a block of
+	 * memory with the following byte-pattern (trying every possible
+	 * [start,end] pair):
+	 *
+	 *   [ 00 ff 00 ff ... 00 00 00 00 ... ff 00 ff 00 ]
+	 *
+	 * And we verify that check_nonzero_user() acts identically to
+	 * memchr_inv().
+	 */
+
+	memset(kmem, 0x0, size);
+	for (i = 1; i < zero_start; i += 2)
+		kmem[i] = 0xff;
+	for (i = zero_end; i < size; i += 2)
+		kmem[i] = 0xff;
+
+	KUNIT_EXPECT_EQ_MSG(test, copy_to_user(umem, kmem, size), 0,
+		"legitimate copy_to_user failed");
+
+	for (start = 0; start <= size; start++) {
+		for (end = start; end <= size; end++) {
+			size_t len = end - start;
+			int retval = check_zeroed_user(umem + start, len);
+			int expected = is_zeroed(kmem + start, len);
+
+			KUNIT_ASSERT_EQ_MSG(test, retval, expected,
+				"check_nonzero_user(=%d) != memchr_inv(=%d) mismatch (start=%zu, end=%zu)",
+				retval, expected, start, end);
+		}
+	}
+}
+
+/* Test usage of copy_struct_from_user(). */
+static void usercopy_test_copy_struct_from_user(struct kunit *test)
+{
+	char *umem_src = NULL, *expected = NULL;
+	struct usercopy_test_priv *priv = test->priv;
+	char __user *umem = priv->umem;
+	char *kmem = priv->kmem;
+	size_t size = priv->size;
+	size_t ksize, usize;
+
+	umem_src = kunit_kmalloc(test, size, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, umem_src);
+
+	expected = kunit_kmalloc(test, size, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected);
+
+	/* Fill umem with a fixed byte pattern. */
+	memset(umem_src, 0x3e, size);
+	KUNIT_ASSERT_EQ_MSG(test, copy_to_user(umem, umem_src, size), 0,
+		    "legitimate copy_to_user failed");
+
+	/* Check basic case -- (usize == ksize). */
+	ksize = size;
+	usize = size;
+
+	memcpy(expected, umem_src, ksize);
+
+	memset(kmem, 0x0, size);
+	KUNIT_EXPECT_EQ_MSG(test, copy_struct_from_user(kmem, ksize, umem, usize), 0,
+		    "copy_struct_from_user(usize == ksize) failed");
+	KUNIT_EXPECT_MEMEQ_MSG(test, kmem, expected, ksize,
+		    "copy_struct_from_user(usize == ksize) gives unexpected copy");
+
+	/* Old userspace case -- (usize < ksize). */
+	ksize = size;
+	usize = size / 2;
+
+	memcpy(expected, umem_src, usize);
+	memset(expected + usize, 0x0, ksize - usize);
+
+	memset(kmem, 0x0, size);
+	KUNIT_EXPECT_EQ_MSG(test, copy_struct_from_user(kmem, ksize, umem, usize), 0,
+		    "copy_struct_from_user(usize < ksize) failed");
+	KUNIT_EXPECT_MEMEQ_MSG(test, kmem, expected, ksize,
+		    "copy_struct_from_user(usize < ksize) gives unexpected copy");
+
+	/* New userspace (-E2BIG) case -- (usize > ksize). */
+	ksize = size / 2;
+	usize = size;
+
+	memset(kmem, 0x0, size);
+	KUNIT_EXPECT_EQ_MSG(test, copy_struct_from_user(kmem, ksize, umem, usize), -E2BIG,
+		    "copy_struct_from_user(usize > ksize) didn't give E2BIG");
+
+	/* New userspace (success) case -- (usize > ksize). */
+	ksize = size / 2;
+	usize = size;
+
+	memcpy(expected, umem_src, ksize);
+	KUNIT_EXPECT_EQ_MSG(test, clear_user(umem + ksize, usize - ksize), 0,
+		    "legitimate clear_user failed");
+
+	memset(kmem, 0x0, size);
+	KUNIT_EXPECT_EQ_MSG(test, copy_struct_from_user(kmem, ksize, umem, usize), 0,
+		    "copy_struct_from_user(usize > ksize) failed");
+	KUNIT_EXPECT_MEMEQ_MSG(test, kmem, expected, ksize,
+		    "copy_struct_from_user(usize > ksize) gives unexpected copy");
+}
+
+/*
+ * Legitimate usage: none of these copies should fail.
+ */
+static void usercopy_test_valid(struct kunit *test)
+{
+	struct usercopy_test_priv *priv = test->priv;
+	char __user *usermem = priv->umem;
+	char *kmem = priv->kmem;
+
+	memset(kmem, 0x3a, PAGE_SIZE * 2);
+	KUNIT_EXPECT_EQ_MSG(test, 0, copy_to_user(usermem, kmem, PAGE_SIZE),
+	     "legitimate copy_to_user failed");
+	memset(kmem, 0x0, PAGE_SIZE);
+	KUNIT_EXPECT_EQ_MSG(test, 0, copy_from_user(kmem, usermem, PAGE_SIZE),
+	     "legitimate copy_from_user failed");
+	KUNIT_EXPECT_MEMEQ_MSG(test, kmem, kmem + PAGE_SIZE, PAGE_SIZE,
+	     "legitimate usercopy failed to copy data");
+
+#define test_legit(size, check)						\
+	do {								\
+		size val_##size = (check);				\
+		KUNIT_EXPECT_EQ_MSG(test, 0,				\
+			put_user(val_##size, (size __user *)usermem),	\
+			"legitimate put_user (" #size ") failed");	\
+		val_##size = 0;						\
+		KUNIT_EXPECT_EQ_MSG(test, 0,				\
+			get_user(val_##size, (size __user *)usermem),	\
+			"legitimate get_user (" #size ") failed");	\
+		KUNIT_EXPECT_EQ_MSG(test, val_##size, check,		\
+			"legitimate get_user (" #size ") failed to do copy"); \
+	} while (0)
+
+	test_legit(u8,  0x5a);
+	test_legit(u16, 0x5a5b);
+	test_legit(u32, 0x5a5b5c5d);
+#ifdef TEST_U64
+	test_legit(u64, 0x5a5b5c5d6a6b6c6d);
+#endif
+#undef test_legit
+}
+
+/*
+ * Invalid usage: none of these copies should succeed.
+ */
+static void usercopy_test_invalid(struct kunit *test)
+{
+	struct usercopy_test_priv *priv = test->priv;
+	char __user *usermem = priv->umem;
+	char *bad_usermem = (char *)usermem;
+	char *kmem = priv->kmem;
+	u64 *kmem_u64 = (u64 *)kmem;
+
+	if (IS_ENABLED(CONFIG_ALTERNATE_USER_ADDRESS_SPACE) ||
+	    !IS_ENABLED(CONFIG_MMU)) {
+		kunit_skip(test, "Testing for kernel/userspace address confusion is only sensible on architectures with a shared address space");
+		return;
+	}
+
+	/* Prepare kernel memory with check values. */
+	memset(kmem, 0x5a, PAGE_SIZE);
+	memset(kmem + PAGE_SIZE, 0, PAGE_SIZE);
+
+	/* Reject kernel-to-kernel copies through copy_from_user(). */
+	KUNIT_EXPECT_NE_MSG(test, copy_from_user(kmem, (char __user *)(kmem + PAGE_SIZE),
+						 PAGE_SIZE), 0,
+		    "illegal all-kernel copy_from_user passed");
+
+	/* Destination half of buffer should have been zeroed. */
+	KUNIT_EXPECT_MEMEQ_MSG(test, kmem + PAGE_SIZE, kmem, PAGE_SIZE,
+		    "zeroing failure for illegal all-kernel copy_from_user");
+
+#if 0
+	/*
+	 * When running with SMAP/PAN/etc, this will Oops the kernel
+	 * due to the zeroing of userspace memory on failure. This needs
+	 * to be tested in LKDTM instead, since this test module does not
+	 * expect to explode.
+	 */
+	KUNIT_EXPECT_NE_MSG(test, copy_from_user(bad_usermem, (char __user *)kmem,
+						 PAGE_SIZE), 0,
+		    "illegal reversed copy_from_user passed");
+#endif
+	KUNIT_EXPECT_NE_MSG(test, copy_to_user((char __user *)kmem, kmem + PAGE_SIZE,
+					       PAGE_SIZE), 0,
+		    "illegal all-kernel copy_to_user passed");
+
+	KUNIT_EXPECT_NE_MSG(test, copy_to_user((char __user *)kmem, bad_usermem,
+					       PAGE_SIZE), 0,
+		    "illegal reversed copy_to_user passed");
+
+#define test_illegal(size, check)							\
+	do {										\
+		size val_##size = (check);						\
+		/* get_user() */							\
+		KUNIT_EXPECT_NE_MSG(test, get_user(val_##size, (size __user *)kmem), 0,	\
+		    "illegal get_user (" #size ") passed");				\
+		KUNIT_EXPECT_EQ_MSG(test, val_##size, 0,				\
+		    "zeroing failure for illegal get_user (" #size ")");		\
+		/* put_user() */							\
+		*kmem_u64 = 0xF09FA4AFF09FA4AF;						\
+		KUNIT_EXPECT_NE_MSG(test, put_user(val_##size, (size __user *)kmem), 0,	\
+		    "illegal put_user (" #size ") passed");				\
+		KUNIT_EXPECT_EQ_MSG(test, *kmem_u64, 0xF09FA4AFF09FA4AF,		\
+		    "illegal put_user (" #size ") wrote to kernel memory!");		\
+	} while (0)
+
+	test_illegal(u8,  0x5a);
+	test_illegal(u16, 0x5a5b);
+	test_illegal(u32, 0x5a5b5c5d);
+#ifdef TEST_U64
+	test_illegal(u64, 0x5a5b5c5d6a6b6c6d);
+#endif
+#undef test_illegal
+}
+
+static int usercopy_test_init(struct kunit *test)
+{
+	struct usercopy_test_priv *priv;
+	unsigned long user_addr;
+
+	if (!IS_ENABLED(CONFIG_MMU)) {
+		kunit_skip(test, "Userspace allocation testing not available on non-MMU systems");
+		return 0;
+	}
+
+	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
+	test->priv = priv;
+	priv->size = PAGE_SIZE * 2;
+
+	priv->kmem = kunit_kmalloc(test, priv->size, GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->kmem);
+
+	user_addr = kunit_vm_mmap(test, NULL, 0, priv->size,
+			    PROT_READ | PROT_WRITE | PROT_EXEC,
+			    MAP_ANONYMOUS | MAP_PRIVATE, 0);
+	KUNIT_ASSERT_NE_MSG(test, user_addr, 0,
+		"Could not create userspace mm");
+	KUNIT_ASSERT_LT_MSG(test, user_addr, (unsigned long)TASK_SIZE,
+		"Failed to allocate user memory");
+	priv->umem = (char __user *)user_addr;
+
+	return 0;
+}
+
+static struct kunit_case usercopy_test_cases[] = {
+	KUNIT_CASE(usercopy_test_valid),
+	KUNIT_CASE(usercopy_test_invalid),
+	KUNIT_CASE(usercopy_test_check_nonzero_user),
+	KUNIT_CASE(usercopy_test_copy_struct_from_user),
+	{}
+};
+
+static struct kunit_suite usercopy_test_suite = {
+	.name = "usercopy",
+	.init = usercopy_test_init,
+	.test_cases = usercopy_test_cases,
+};
+
+kunit_test_suites(&usercopy_test_suite);
+MODULE_AUTHOR("Kees Cook <kees@xxxxxxxxxx>");
+MODULE_DESCRIPTION("Kernel module for testing copy_to/from_user infrastructure");
+MODULE_LICENSE("GPL");
diff --git a/lib/usercopy_kunit.c a/lib/usercopy_kunit.c
deleted file mode 100644
--- a/lib/usercopy_kunit.c
+++ /dev/null
@@ -1,335 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Kernel module for testing copy_to/from_user infrastructure.
- *
- * Copyright 2013 Google Inc. All Rights Reserved
- *
- * Authors:
- *      Kees Cook       <keescook@xxxxxxxxxxxx>
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/mman.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <kunit/test.h>
-
-/*
- * Several 32-bit architectures support 64-bit {get,put}_user() calls.
- * As there doesn't appear to be anything that can safely determine
- * their capability at compile-time, we just have to opt-out certain archs.
- */
-#if BITS_PER_LONG == 64 || (!(defined(CONFIG_ARM) && !defined(MMU)) && \
-			    !defined(CONFIG_M68K) &&		\
-			    !defined(CONFIG_MICROBLAZE) &&	\
-			    !defined(CONFIG_NIOS2) &&		\
-			    !defined(CONFIG_PPC32) &&		\
-			    !defined(CONFIG_SUPERH))
-# define TEST_U64
-#endif
-
-struct usercopy_test_priv {
-	char *kmem;
-	char __user *umem;
-	size_t size;
-};
-
-static bool is_zeroed(void *from, size_t size)
-{
-	return memchr_inv(from, 0x0, size) == NULL;
-}
-
-/* Test usage of check_nonzero_user(). */
-static void usercopy_test_check_nonzero_user(struct kunit *test)
-{
-	size_t start, end, i, zero_start, zero_end;
-	struct usercopy_test_priv *priv = test->priv;
-	char __user *umem = priv->umem;
-	char *kmem = priv->kmem;
-	size_t size = priv->size;
-
-	KUNIT_ASSERT_GE_MSG(test, size, 2 * PAGE_SIZE, "buffer too small");
-
-	/*
-	 * We want to cross a page boundary to exercise the code more
-	 * effectively. We also don't want to make the size we scan too large,
-	 * otherwise the test can take a long time and cause soft lockups. So
-	 * scan a 1024 byte region across the page boundary.
-	 */
-	size = 1024;
-	start = PAGE_SIZE - (size / 2);
-
-	kmem += start;
-	umem += start;
-
-	zero_start = size / 4;
-	zero_end = size - zero_start;
-
-	/*
-	 * We conduct a series of check_nonzero_user() tests on a block of
-	 * memory with the following byte-pattern (trying every possible
-	 * [start,end] pair):
-	 *
-	 *   [ 00 ff 00 ff ... 00 00 00 00 ... ff 00 ff 00 ]
-	 *
-	 * And we verify that check_nonzero_user() acts identically to
-	 * memchr_inv().
-	 */
-
-	memset(kmem, 0x0, size);
-	for (i = 1; i < zero_start; i += 2)
-		kmem[i] = 0xff;
-	for (i = zero_end; i < size; i += 2)
-		kmem[i] = 0xff;
-
-	KUNIT_EXPECT_EQ_MSG(test, copy_to_user(umem, kmem, size), 0,
-		"legitimate copy_to_user failed");
-
-	for (start = 0; start <= size; start++) {
-		for (end = start; end <= size; end++) {
-			size_t len = end - start;
-			int retval = check_zeroed_user(umem + start, len);
-			int expected = is_zeroed(kmem + start, len);
-
-			KUNIT_ASSERT_EQ_MSG(test, retval, expected,
-				"check_nonzero_user(=%d) != memchr_inv(=%d) mismatch (start=%zu, end=%zu)",
-				retval, expected, start, end);
-		}
-	}
-}
-
-/* Test usage of copy_struct_from_user(). */
-static void usercopy_test_copy_struct_from_user(struct kunit *test)
-{
-	char *umem_src = NULL, *expected = NULL;
-	struct usercopy_test_priv *priv = test->priv;
-	char __user *umem = priv->umem;
-	char *kmem = priv->kmem;
-	size_t size = priv->size;
-	size_t ksize, usize;
-
-	umem_src = kunit_kmalloc(test, size, GFP_KERNEL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, umem_src);
-
-	expected = kunit_kmalloc(test, size, GFP_KERNEL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, expected);
-
-	/* Fill umem with a fixed byte pattern. */
-	memset(umem_src, 0x3e, size);
-	KUNIT_ASSERT_EQ_MSG(test, copy_to_user(umem, umem_src, size), 0,
-		    "legitimate copy_to_user failed");
-
-	/* Check basic case -- (usize == ksize). */
-	ksize = size;
-	usize = size;
-
-	memcpy(expected, umem_src, ksize);
-
-	memset(kmem, 0x0, size);
-	KUNIT_EXPECT_EQ_MSG(test, copy_struct_from_user(kmem, ksize, umem, usize), 0,
-		    "copy_struct_from_user(usize == ksize) failed");
-	KUNIT_EXPECT_MEMEQ_MSG(test, kmem, expected, ksize,
-		    "copy_struct_from_user(usize == ksize) gives unexpected copy");
-
-	/* Old userspace case -- (usize < ksize). */
-	ksize = size;
-	usize = size / 2;
-
-	memcpy(expected, umem_src, usize);
-	memset(expected + usize, 0x0, ksize - usize);
-
-	memset(kmem, 0x0, size);
-	KUNIT_EXPECT_EQ_MSG(test, copy_struct_from_user(kmem, ksize, umem, usize), 0,
-		    "copy_struct_from_user(usize < ksize) failed");
-	KUNIT_EXPECT_MEMEQ_MSG(test, kmem, expected, ksize,
-		    "copy_struct_from_user(usize < ksize) gives unexpected copy");
-
-	/* New userspace (-E2BIG) case -- (usize > ksize). */
-	ksize = size / 2;
-	usize = size;
-
-	memset(kmem, 0x0, size);
-	KUNIT_EXPECT_EQ_MSG(test, copy_struct_from_user(kmem, ksize, umem, usize), -E2BIG,
-		    "copy_struct_from_user(usize > ksize) didn't give E2BIG");
-
-	/* New userspace (success) case -- (usize > ksize). */
-	ksize = size / 2;
-	usize = size;
-
-	memcpy(expected, umem_src, ksize);
-	KUNIT_EXPECT_EQ_MSG(test, clear_user(umem + ksize, usize - ksize), 0,
-		    "legitimate clear_user failed");
-
-	memset(kmem, 0x0, size);
-	KUNIT_EXPECT_EQ_MSG(test, copy_struct_from_user(kmem, ksize, umem, usize), 0,
-		    "copy_struct_from_user(usize > ksize) failed");
-	KUNIT_EXPECT_MEMEQ_MSG(test, kmem, expected, ksize,
-		    "copy_struct_from_user(usize > ksize) gives unexpected copy");
-}
-
-/*
- * Legitimate usage: none of these copies should fail.
- */
-static void usercopy_test_valid(struct kunit *test)
-{
-	struct usercopy_test_priv *priv = test->priv;
-	char __user *usermem = priv->umem;
-	char *kmem = priv->kmem;
-
-	memset(kmem, 0x3a, PAGE_SIZE * 2);
-	KUNIT_EXPECT_EQ_MSG(test, 0, copy_to_user(usermem, kmem, PAGE_SIZE),
-	     "legitimate copy_to_user failed");
-	memset(kmem, 0x0, PAGE_SIZE);
-	KUNIT_EXPECT_EQ_MSG(test, 0, copy_from_user(kmem, usermem, PAGE_SIZE),
-	     "legitimate copy_from_user failed");
-	KUNIT_EXPECT_MEMEQ_MSG(test, kmem, kmem + PAGE_SIZE, PAGE_SIZE,
-	     "legitimate usercopy failed to copy data");
-
-#define test_legit(size, check)						\
-	do {								\
-		size val_##size = (check);				\
-		KUNIT_EXPECT_EQ_MSG(test, 0,				\
-			put_user(val_##size, (size __user *)usermem),	\
-			"legitimate put_user (" #size ") failed");	\
-		val_##size = 0;						\
-		KUNIT_EXPECT_EQ_MSG(test, 0,				\
-			get_user(val_##size, (size __user *)usermem),	\
-			"legitimate get_user (" #size ") failed");	\
-		KUNIT_EXPECT_EQ_MSG(test, val_##size, check,		\
-			"legitimate get_user (" #size ") failed to do copy"); \
-	} while (0)
-
-	test_legit(u8,  0x5a);
-	test_legit(u16, 0x5a5b);
-	test_legit(u32, 0x5a5b5c5d);
-#ifdef TEST_U64
-	test_legit(u64, 0x5a5b5c5d6a6b6c6d);
-#endif
-#undef test_legit
-}
-
-/*
- * Invalid usage: none of these copies should succeed.
- */
-static void usercopy_test_invalid(struct kunit *test)
-{
-	struct usercopy_test_priv *priv = test->priv;
-	char __user *usermem = priv->umem;
-	char *bad_usermem = (char *)usermem;
-	char *kmem = priv->kmem;
-	u64 *kmem_u64 = (u64 *)kmem;
-
-	if (IS_ENABLED(CONFIG_ALTERNATE_USER_ADDRESS_SPACE) ||
-	    !IS_ENABLED(CONFIG_MMU)) {
-		kunit_skip(test, "Testing for kernel/userspace address confusion is only sensible on architectures with a shared address space");
-		return;
-	}
-
-	/* Prepare kernel memory with check values. */
-	memset(kmem, 0x5a, PAGE_SIZE);
-	memset(kmem + PAGE_SIZE, 0, PAGE_SIZE);
-
-	/* Reject kernel-to-kernel copies through copy_from_user(). */
-	KUNIT_EXPECT_NE_MSG(test, copy_from_user(kmem, (char __user *)(kmem + PAGE_SIZE),
-						 PAGE_SIZE), 0,
-		    "illegal all-kernel copy_from_user passed");
-
-	/* Destination half of buffer should have been zeroed. */
-	KUNIT_EXPECT_MEMEQ_MSG(test, kmem + PAGE_SIZE, kmem, PAGE_SIZE,
-		    "zeroing failure for illegal all-kernel copy_from_user");
-
-#if 0
-	/*
-	 * When running with SMAP/PAN/etc, this will Oops the kernel
-	 * due to the zeroing of userspace memory on failure. This needs
-	 * to be tested in LKDTM instead, since this test module does not
-	 * expect to explode.
-	 */
-	KUNIT_EXPECT_NE_MSG(test, copy_from_user(bad_usermem, (char __user *)kmem,
-						 PAGE_SIZE), 0,
-		    "illegal reversed copy_from_user passed");
-#endif
-	KUNIT_EXPECT_NE_MSG(test, copy_to_user((char __user *)kmem, kmem + PAGE_SIZE,
-					       PAGE_SIZE), 0,
-		    "illegal all-kernel copy_to_user passed");
-
-	KUNIT_EXPECT_NE_MSG(test, copy_to_user((char __user *)kmem, bad_usermem,
-					       PAGE_SIZE), 0,
-		    "illegal reversed copy_to_user passed");
-
-#define test_illegal(size, check)							\
-	do {										\
-		size val_##size = (check);						\
-		/* get_user() */							\
-		KUNIT_EXPECT_NE_MSG(test, get_user(val_##size, (size __user *)kmem), 0,	\
-		    "illegal get_user (" #size ") passed");				\
-		KUNIT_EXPECT_EQ_MSG(test, val_##size, 0,				\
-		    "zeroing failure for illegal get_user (" #size ")");		\
-		/* put_user() */							\
-		*kmem_u64 = 0xF09FA4AFF09FA4AF;						\
-		KUNIT_EXPECT_NE_MSG(test, put_user(val_##size, (size __user *)kmem), 0,	\
-		    "illegal put_user (" #size ") passed");				\
-		KUNIT_EXPECT_EQ_MSG(test, *kmem_u64, 0xF09FA4AFF09FA4AF,		\
-		    "illegal put_user (" #size ") wrote to kernel memory!");		\
-	} while (0)
-
-	test_illegal(u8,  0x5a);
-	test_illegal(u16, 0x5a5b);
-	test_illegal(u32, 0x5a5b5c5d);
-#ifdef TEST_U64
-	test_illegal(u64, 0x5a5b5c5d6a6b6c6d);
-#endif
-#undef test_illegal
-}
-
-static int usercopy_test_init(struct kunit *test)
-{
-	struct usercopy_test_priv *priv;
-	unsigned long user_addr;
-
-	if (!IS_ENABLED(CONFIG_MMU)) {
-		kunit_skip(test, "Userspace allocation testing not available on non-MMU systems");
-		return 0;
-	}
-
-	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
-	test->priv = priv;
-	priv->size = PAGE_SIZE * 2;
-
-	priv->kmem = kunit_kmalloc(test, priv->size, GFP_KERNEL);
-	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->kmem);
-
-	user_addr = kunit_vm_mmap(test, NULL, 0, priv->size,
-			    PROT_READ | PROT_WRITE | PROT_EXEC,
-			    MAP_ANONYMOUS | MAP_PRIVATE, 0);
-	KUNIT_ASSERT_NE_MSG(test, user_addr, 0,
-		"Could not create userspace mm");
-	KUNIT_ASSERT_LT_MSG(test, user_addr, (unsigned long)TASK_SIZE,
-		"Failed to allocate user memory");
-	priv->umem = (char __user *)user_addr;
-
-	return 0;
-}
-
-static struct kunit_case usercopy_test_cases[] = {
-	KUNIT_CASE(usercopy_test_valid),
-	KUNIT_CASE(usercopy_test_invalid),
-	KUNIT_CASE(usercopy_test_check_nonzero_user),
-	KUNIT_CASE(usercopy_test_copy_struct_from_user),
-	{}
-};
-
-static struct kunit_suite usercopy_test_suite = {
-	.name = "usercopy",
-	.init = usercopy_test_init,
-	.test_cases = usercopy_test_cases,
-};
-
-kunit_test_suites(&usercopy_test_suite);
-MODULE_AUTHOR("Kees Cook <kees@xxxxxxxxxx>");
-MODULE_DESCRIPTION("Kernel module for testing copy_to/from_user infrastructure");
-MODULE_LICENSE("GPL");
--- a/MAINTAINERS~lib-move-kunit-tests-into-tests-subdirectory
+++ a/MAINTAINERS
@@ -3929,10 +3929,10 @@ F:	include/vdso/bits.h
 F:	lib/bitmap-str.c
 F:	lib/bitmap.c
 F:	lib/cpumask.c
-F:	lib/cpumask_kunit.c
 F:	lib/find_bit.c
 F:	lib/find_bit_benchmark.c
 F:	lib/test_bitmap.c
+F:	lib/tests/cpumask_kunit.c
 F:	tools/include/linux/bitfield.h
 F:	tools/include/linux/bitmap.h
 F:	tools/include/linux/bits.h
@@ -8911,9 +8911,10 @@ L:	linux-hardening@xxxxxxxxxxxxxxx
 S:	Supported
 T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
 F:	include/linux/fortify-string.h
-F:	lib/fortify_kunit.c
-F:	lib/memcpy_kunit.c
 F:	lib/test_fortify/*
+F:	lib/tests/fortify_kunit.c
+F:	lib/tests/memcpy_kunit.c
+F:	scripts/test_fortify.sh
 K:	\bunsafe_memcpy\b
 K:	\b__NO_FORTIFY\b
 
@@ -9578,9 +9579,9 @@ F:	include/linux/string.h
 F:	include/linux/string_choices.h
 F:	include/linux/string_helpers.h
 F:	lib/string.c
-F:	lib/string_kunit.c
 F:	lib/string_helpers.c
-F:	lib/string_helpers_kunit.c
+F:	lib/tests/string_helpers_kunit.c
+F:	lib/tests/string_kunit.c
 F:	scripts/coccinelle/api/string_choices.cocci
 
 GENERIC UIO DRIVER FOR PCI DEVICES
@@ -12743,7 +12744,7 @@ F:	Documentation/trace/kprobes.rst
 F:	include/asm-generic/kprobes.h
 F:	include/linux/kprobes.h
 F:	kernel/kprobes.c
-F:	lib/test_kprobes.c
+F:	lib/tests/test_kprobes.c
 F:	samples/kprobes
 
 KS0108 LCD CONTROLLER DRIVER
@@ -13087,7 +13088,7 @@ M:	Mark Brown <broonie@xxxxxxxxxx>
 R:	Matti Vaittinen <mazziesaccount@xxxxxxxxx>
 F:	include/linux/linear_range.h
 F:	lib/linear_ranges.c
-F:	lib/test_linear_ranges.c
+F:	lib/tests/test_linear_ranges.c
 
 LINUX FOR POWER MACINTOSH
 L:	linuxppc-dev@xxxxxxxxxxxxxxxx
@@ -13215,7 +13216,7 @@ M:	David Gow <davidgow@xxxxxxxxxx>
 L:	linux-kselftest@xxxxxxxxxxxxxxx
 L:	kunit-dev@xxxxxxxxxxxxxxxx
 S:	Maintained
-F:	lib/list-test.c
+F:	lib/tests/list-test.c
 
 LITEX PLATFORM
 M:	Karol Gugala <kgugala@xxxxxxxxxxxx>
@@ -21207,7 +21208,7 @@ M:	Jason A. Donenfeld <Jason@xxxxxxxxx>
 S:	Maintained
 F:	include/linux/siphash.h
 F:	lib/siphash.c
-F:	lib/siphash_kunit.c
+F:	lib/tests/siphash_kunit.c
 
 SIS 190 ETHERNET DRIVER
 M:	Francois Romieu <romieu@xxxxxxxxxxxxx>
_

Patches currently in -mm which might be from kees@xxxxxxxxxx are

lib-move-kunit-tests-into-tests-subdirectory.patch





[Index of Archives]     [Kernel Archive]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]

  Powered by Linux