diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c3dbe64e628e..208ed162bcc0 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -114,6 +114,18 @@ config WIREGUARD_DEBUG
 
 	  Say N here unless you know what you're doing.
 
+config WIREGUARD_KUNIT_TEST
+	tristate "KUnit tests for WireGuard"
+	default KUNIT_ALL_TESTS
+	depends on KUNIT && WIREGUARD
+	help
+	  This enables KUnit tests for Wireguard.
+
+	  For more information on KUnit and unit tests in general please refer
+	  to the KUnit documentation in Documentation/dev-tools/kunit/.
+
+	  Say N here unless you know what you're doing.
+
 config EQUALIZER
 	tristate "EQL (serial line load balancing) support"
 	help
diff --git a/drivers/net/wireguard/selftest/counter.c b/drivers/net/wireguard/counter_test.c
similarity index 73%
rename from drivers/net/wireguard/selftest/counter.c
rename to drivers/net/wireguard/counter_test.c
index ec3c156bf91b..167153fc249f 100644
--- a/drivers/net/wireguard/selftest/counter.c
+++ b/drivers/net/wireguard/counter_test.c
@@ -3,32 +3,23 @@
  * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
  */
 
-#ifdef DEBUG
-bool __init wg_packet_counter_selftest(void)
+#include <kunit/test.h>
+
+static void wg_packet_counter_test(struct kunit *test)
 {
 	struct noise_replay_counter *counter;
-	unsigned int test_num = 0, i;
-	bool success = true;
+	unsigned int i;
 
-	counter = kmalloc(sizeof(*counter), GFP_KERNEL);
-	if (unlikely(!counter)) {
-		pr_err("nonce counter self-test malloc: FAIL\n");
-		return false;
-	}
+	counter = kunit_kmalloc(test, sizeof(*counter), GFP_KERNEL);
+	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, counter);
 
 #define T_INIT do {                                    \
 		memset(counter, 0, sizeof(*counter));  \
 		spin_lock_init(&counter->lock);        \
 	} while (0)
 #define T_LIM (COUNTER_WINDOW_SIZE + 1)
-#define T(n, v) do {                                                  \
-		++test_num;                                           \
-		if (counter_validate(counter, n) != (v)) {            \
-			pr_err("nonce counter self-test %u: FAIL\n",  \
-			       test_num);                             \
-			success = false;                              \
-		}                                                     \
-	} while (0)
+#define T(n, v) \
+		KUNIT_EXPECT_EQ(test, counter_validate(counter, n), v)
 
 	T_INIT;
 	/*  1 */ T(0, true);
@@ -102,10 +93,18 @@ bool __init wg_packet_counter_selftest(void)
 #undef T
 #undef T_LIM
 #undef T_INIT
-
-	if (success)
-		pr_info("nonce counter self-tests: pass\n");
-	kfree(counter);
-	return success;
 }
-#endif
+
+static struct kunit_case wg_packet_counter_test_cases[] = {
+	KUNIT_CASE(wg_packet_counter_test),
+	{}
+};
+
+static struct kunit_suite wg_packet_counter_test_suite = {
+	.name = "wg_packet_counter",
+	.test_cases = wg_packet_counter_test_cases,
+};
+
+kunit_test_suites(&wg_packet_counter_test_suite);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wireguard/main.c b/drivers/net/wireguard/main.c
index 7a7d5f1a80fc..bfd3312d5133 100644
--- a/drivers/net/wireguard/main.c
+++ b/drivers/net/wireguard/main.c
@@ -22,8 +22,7 @@ static int __init mod_init(void)
 	int ret;
 
 #ifdef DEBUG
-	if (!wg_allowedips_selftest() || !wg_packet_counter_selftest() ||
-	    !wg_ratelimiter_selftest())
+	if (!wg_allowedips_selftest())
 		return -ENOTRECOVERABLE;
 #endif
 	wg_noise_init();
diff --git a/drivers/net/wireguard/queueing.h b/drivers/net/wireguard/queueing.h
index dfb674e03076..5d428ddf176f 100644
--- a/drivers/net/wireguard/queueing.h
+++ b/drivers/net/wireguard/queueing.h
@@ -186,8 +186,4 @@ static inline void wg_queue_enqueue_per_peer_napi(struct sk_buff *skb,
 	wg_peer_put(peer);
 }
 
-#ifdef DEBUG
-bool wg_packet_counter_selftest(void);
-#endif
-
 #endif /* _WG_QUEUEING_H */
diff --git a/drivers/net/wireguard/ratelimiter.c b/drivers/net/wireguard/ratelimiter.c
index 3fedd1d21f5e..f7a7c48aee40 100644
--- a/drivers/net/wireguard/ratelimiter.c
+++ b/drivers/net/wireguard/ratelimiter.c
@@ -220,4 +220,6 @@ void wg_ratelimiter_uninit(void)
 	mutex_unlock(&init_lock);
 }
 
-#include "selftest/ratelimiter.c"
+#if IS_ENABLED(CONFIG_WIREGUARD_KUNIT_TEST)
+#include "ratelimiter_test.c"
+#endif
diff --git a/drivers/net/wireguard/selftest/ratelimiter.c b/drivers/net/wireguard/ratelimiter_test.c
similarity index 85%
rename from drivers/net/wireguard/selftest/ratelimiter.c
rename to drivers/net/wireguard/ratelimiter_test.c
index 007cd4457c5f..a49f508cccb2 100644
--- a/drivers/net/wireguard/selftest/ratelimiter.c
+++ b/drivers/net/wireguard/ratelimiter_test.c
@@ -3,8 +3,7 @@
  * Copyright (C) 2015-2019 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.
  */
 
-#ifdef DEBUG
-
+#include <kunit/test.h>
 #include <linux/jiffies.h>
 
 static const struct {
@@ -32,7 +31,7 @@ static __init unsigned int maximum_jiffies_at_index(int index)
 
 static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
 			       struct sk_buff *skb6, struct ipv6hdr *hdr6,
-			       int *test)
+			       int *test_num)
 {
 	unsigned long loop_start_time;
 	int i;
@@ -51,7 +50,7 @@ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
 		if (wg_ratelimiter_allow(skb4, &init_net) !=
 					expected_results[i].result)
 			return -EXFULL;
-		++(*test);
+		++(*test_num);
 
 		hdr4->saddr = htonl(ntohl(hdr4->saddr) + i + 1);
 		if (time_is_before_jiffies(loop_start_time +
@@ -59,7 +58,7 @@ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
 			return -ETIMEDOUT;
 		if (!wg_ratelimiter_allow(skb4, &init_net))
 			return -EXFULL;
-		++(*test);
+		++(*test_num);
 
 		hdr4->saddr = htonl(ntohl(hdr4->saddr) - i - 1);
 
@@ -72,7 +71,7 @@ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
 		if (wg_ratelimiter_allow(skb6, &init_net) !=
 					expected_results[i].result)
 			return -EXFULL;
-		++(*test);
+		++(*test_num);
 
 		hdr6->saddr.in6_u.u6_addr32[0] =
 			htonl(ntohl(hdr6->saddr.in6_u.u6_addr32[0]) + i + 1);
@@ -81,7 +80,7 @@ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
 			return -ETIMEDOUT;
 		if (!wg_ratelimiter_allow(skb6, &init_net))
 			return -EXFULL;
-		++(*test);
+		++(*test_num);
 
 		hdr6->saddr.in6_u.u6_addr32[0] =
 			htonl(ntohl(hdr6->saddr.in6_u.u6_addr32[0]) - i - 1);
@@ -95,7 +94,7 @@ static __init int timings_test(struct sk_buff *skb4, struct iphdr *hdr4,
 }
 
 static __init int capacity_test(struct sk_buff *skb4, struct iphdr *hdr4,
-				int *test)
+				int *test_num)
 {
 	int i;
 
@@ -104,45 +103,45 @@ static __init int capacity_test(struct sk_buff *skb4, struct iphdr *hdr4,
 
 	if (atomic_read(&total_entries))
 		return -EXFULL;
-	++(*test);
+	++(*test_num);
 
 	for (i = 0; i <= max_entries; ++i) {
 		hdr4->saddr = htonl(i);
 		if (wg_ratelimiter_allow(skb4, &init_net) != (i != max_entries))
 			return -EXFULL;
-		++(*test);
+		++(*test_num);
 	}
 	return 0;
 }
 
-bool __init wg_ratelimiter_selftest(void)
+static void wg_ratelimiter_test(struct kunit *test)
 {
 	enum { TRIALS_BEFORE_GIVING_UP = 5000 };
 	bool success = false;
-	int test = 0, trials;
+	int test_num = 0, trials;
 	struct sk_buff *skb4, *skb6 = NULL;
 	struct iphdr *hdr4;
 	struct ipv6hdr *hdr6 = NULL;
 
 	if (IS_ENABLED(CONFIG_KASAN) || IS_ENABLED(CONFIG_UBSAN))
-		return true;
+		return;
 
 	BUILD_BUG_ON(MSEC_PER_SEC % PACKETS_PER_SECOND != 0);
 
 	if (wg_ratelimiter_init())
 		goto out;
-	++test;
+	++test_num;
 	if (wg_ratelimiter_init()) {
 		wg_ratelimiter_uninit();
 		goto out;
 	}
-	++test;
+	++test_num;
 	if (wg_ratelimiter_init()) {
 		wg_ratelimiter_uninit();
 		wg_ratelimiter_uninit();
 		goto out;
 	}
-	++test;
+	++test_num;
 
 	skb4 = alloc_skb(sizeof(struct iphdr), GFP_KERNEL);
 	if (unlikely(!skb4))
@@ -151,7 +150,7 @@ bool __init wg_ratelimiter_selftest(void)
 	hdr4 = (struct iphdr *)skb_put(skb4, sizeof(*hdr4));
 	hdr4->saddr = htonl(8182);
 	skb_reset_network_header(skb4);
-	++test;
+	++test_num;
 
 #if IS_ENABLED(CONFIG_IPV6)
 	skb6 = alloc_skb(sizeof(struct ipv6hdr), GFP_KERNEL);
@@ -164,7 +163,7 @@ bool __init wg_ratelimiter_selftest(void)
 	hdr6->saddr.in6_u.u6_addr32[0] = htonl(1212);
 	hdr6->saddr.in6_u.u6_addr32[1] = htonl(289188);
 	skb_reset_network_header(skb6);
-	++test;
+	++test_num;
 #endif
 
 	for (trials = TRIALS_BEFORE_GIVING_UP;;) {
@@ -173,16 +172,16 @@ bool __init wg_ratelimiter_selftest(void)
 		ret = timings_test(skb4, hdr4, skb6, hdr6, &test_count);
 		if (ret == -ETIMEDOUT) {
 			if (!trials--) {
-				test += test_count;
+				test_num += test_count;
 				goto err;
 			}
 			msleep(500);
 			continue;
 		} else if (ret < 0) {
-			test += test_count;
+			test_num += test_count;
 			goto err;
 		} else {
-			test += test_count;
+			test_num += test_count;
 			break;
 		}
 	}
@@ -192,13 +191,13 @@ bool __init wg_ratelimiter_selftest(void)
 
 		if (capacity_test(skb4, hdr4, &test_count) < 0) {
 			if (!trials--) {
-				test += test_count;
+				test_num += test_count;
 				goto err;
 			}
 			msleep(50);
 			continue;
 		}
-		test += test_count;
+		test_num += test_count;
 		break;
 	}
 
@@ -216,11 +215,20 @@ bool __init wg_ratelimiter_selftest(void)
 	/* Uninit one extra time to check underflow detection. */
 	wg_ratelimiter_uninit();
 out:
-	if (success)
-		pr_info("ratelimiter self-tests: pass\n");
-	else
-		pr_err("ratelimiter self-test %d: FAIL\n", test);
-
-	return success;
+	if (!success)
+		KUNIT_FAIL(test, "test #%d failed", test_num);
 }
-#endif
+
+static struct kunit_case wg_ratelimiter_test_cases[] = {
+	KUNIT_CASE(wg_ratelimiter_test),
+	{}
+};
+
+static struct kunit_suite wg_ratelimiter_test_suite = {
+	.name = "wg_ratelimiter",
+	.test_cases = wg_ratelimiter_test_cases,
+};
+
+kunit_test_suites(&wg_ratelimiter_test_suite);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wireguard/receive.c b/drivers/net/wireguard/receive.c
index 2c9551ea6dc7..30d3d9685e8d 100644
--- a/drivers/net/wireguard/receive.c
+++ b/drivers/net/wireguard/receive.c
@@ -336,8 +336,6 @@ static bool counter_validate(struct noise_replay_counter *counter, u64 their_cou
 	return ret;
 }
 
-#include "selftest/counter.c"
-
 static void wg_packet_consume_data_done(struct wg_peer *peer,
 					struct sk_buff *skb,
 					struct endpoint *endpoint)
@@ -588,3 +586,7 @@ void wg_packet_receive(struct wg_device *wg, struct sk_buff *skb)
 err:
 	dev_kfree_skb(skb);
 }
+
+#if IS_ENABLED(CONFIG_WIREGUARD_KUNIT_TEST)
+#include "counter_test.c"
+#endif
