diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c
index 03f64ce1dda6..f8064cd58783 100644
--- a/tools/testing/selftests/nolibc/nolibc-test.c
+++ b/tools/testing/selftests/nolibc/nolibc-test.c
@@ -41,12 +41,13 @@
 #endif
 #endif
 
+#define inline __inline__
+#include "../kselftest.h"
+
 /* for the type of int_fast16_t and int_fast32_t, musl differs from glibc and nolibc */
 #define SINT_MAX_OF_TYPE(type) (((type)1 << (sizeof(type) * 8 - 2)) - (type)1 + ((type)1 << (sizeof(type) * 8 - 2)))
 #define SINT_MIN_OF_TYPE(type) (-SINT_MAX_OF_TYPE(type) - 1)
 
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-
 /* will be used to test initialization of environ */
 static char **test_envp;
 
@@ -59,6 +60,8 @@ static int test_argc;
 /* will be used by some test cases as readable file, please don't write it */
 static const char *argv0;
 
+static const char *test_name;
+
 /* definition of a series of tests */
 struct test {
 	const char *name;              /* test name */
@@ -197,15 +200,11 @@ static int expect_nz(int expr, int llen)
 
 
 #define EXPECT_EQ(cond, expr, val)				\
-	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_eq(expr, llen, val); } while (0)
+	do { if (!(cond)) ksft_test_result_skip2(test_name, "%s\n", #cond); else expect_eq(expr, val); } while (0)
 
-static int expect_eq(uint64_t expr, int llen, uint64_t val)
+static int expect_eq(uint64_t expr, uint64_t val)
 {
-	int ret = !(expr == val);
-
-	llen += printf(" = %lld ", (long long)expr);
-	result(llen, ret ? FAIL : OK);
-	return ret;
+	ksft_test_result(expr = val, "%s = %lld\n", test_name, (long long) expr);
 }
 
 
@@ -223,15 +222,11 @@ static int expect_ne(int expr, int llen, int val)
 
 
 #define EXPECT_GE(cond, expr, val)				\
-	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ge(expr, llen, val); } while (0)
+	do { if (!(cond)) ksft_test_result_skip2(test_name, "%s\n", #cond); else expect_ge(expr, val); } while (0)
 
-static int expect_ge(int expr, int llen, int val)
+static int expect_ge(int expr, int val)
 {
-	int ret = !(expr >= val);
-
-	llen += printf(" = %d ", expr);
-	result(llen, ret ? FAIL : OK);
-	return ret;
+	ksft_test_result(expr >= val, "%s = %d\n", test_name, expr);
 }
 
 
@@ -376,37 +371,19 @@ static int expect_ptrzr(const void *expr, int llen)
 
 
 #define EXPECT_PTRNZ(cond, expr)				\
-	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrnz(expr, llen); } while (0)
+	do { if (!(cond)) ksft_test_result_skip("%s: %s\n", test_name, #cond); else expect_ptrnz(expr); } while (0)
 
-static int expect_ptrnz(const void *expr, int llen)
+static int expect_ptrnz(const void *expr)
 {
-	int ret = 0;
-
-	llen += printf(" = <%p> ", expr);
-	if (!expr) {
-		ret = 1;
-		result(llen, FAIL);
-	} else {
-		result(llen, OK);
-	}
-	return ret;
+	ksft_test_result(expr, "%s = <%p>\n", test_name, expr);
 }
 
 #define EXPECT_PTREQ(cond, expr, cmp)				\
-	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptreq(expr, llen, cmp); } while (0)
+	do { if (!(cond)) ksft_test_result_skip("%s: %s\n", test_name, #cond); else expect_ptreq(expr, cmp); } while (0)
 
-static int expect_ptreq(const void *expr, int llen, const void *cmp)
+static void expect_ptreq(const void *expr, const void *cmp)
 {
-	int ret = 0;
-
-	llen += printf(" = <%p> ", expr);
-	if (expr != cmp) {
-		ret = 1;
-		result(llen, FAIL);
-	} else {
-		result(llen, OK);
-	}
-	return ret;
+	ksft_test_result(expr == cmp, "%s = <%p>\n", test_name, expr);
 }
 
 #define EXPECT_PTRNE(cond, expr, cmp)				\
@@ -439,41 +416,28 @@ static int expect_ptrge(const void *expr, int llen, const void *cmp)
 }
 
 #define EXPECT_PTRGT(cond, expr, cmp)				\
-	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrgt(expr, llen, cmp); } while (0)
+	do { if (!(cond)) ksft_test_result_skip2(test_name, "%s\n", #cond); else expect_ptrgt(expr, cmp); } while (0)
 
-static int expect_ptrgt(const void *expr, int llen, const void *cmp)
+static void expect_ptrgt(const void *expr, const void *cmp)
 {
-	int ret = !(expr > cmp);
-
-	llen += printf(" = <%p> ", expr);
-	result(llen, ret ? FAIL : OK);
-	return ret;
+	ksft_test_result(expr > cmp, "%s = <%p>\n", test_name, expr);
 }
 
-
 #define EXPECT_PTRLE(cond, expr, cmp)				\
-	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrle(expr, llen, cmp); } while (0)
+	do { if (!(cond)) ksft_test_result_skip("%s: %s\n", test_name, #cond); else expect_ptrle(expr, cmp); } while (0)
 
 static int expect_ptrle(const void *expr, int llen, const void *cmp)
 {
-	int ret = !(expr <= cmp);
-
-	llen += printf(" = <%p> ", expr);
-	result(llen, ret ? FAIL : OK);
-	return ret;
+	ksft_test_result(expr <= cmp, "%s = <%p>\n", test_name, expr);
 }
 
 
 #define EXPECT_PTRLT(cond, expr, cmp)				\
-	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_ptrlt(expr, llen, cmp); } while (0)
+	do { if (!(cond)) ksft_test_result_skip2(test_name, "%s\n", #cond); else expect_ptrlt(expr, cmp); } while (0)
 
-static int expect_ptrlt(const void *expr, int llen, const void *cmp)
+static int expect_ptrlt(const void *expr, const void *cmp)
 {
-	int ret = !(expr < cmp);
-
-	llen += printf(" = <%p> ", expr);
-	result(llen, ret ? FAIL : OK);
-	return ret;
+	ksft_test_result(expr < cmp, "%s = <%p>\n", test_name, expr);
 }
 
 #define EXPECT_PTRER2(cond, expr, expret, experr1, experr2)		\
@@ -520,20 +484,11 @@ static int expect_strzr(const char *expr, int llen)
 
 
 #define EXPECT_STRNZ(cond, expr)				\
-	do { if (!(cond)) result(llen, SKIPPED); else ret += expect_strnz(expr, llen); } while (0)
+	do { if (!(cond)) ksft_test_result_skip("%s: %s\n", test_name, #cond); else expect_strnz(expr); } while (0)
 
-static int expect_strnz(const char *expr, int llen)
+static int expect_strnz(const char *expr)
 {
-	int ret = 0;
-
-	llen += printf(" = <%s> ", expr);
-	if (!expr) {
-		ret = 1;
-		result(llen, FAIL);
-	} else {
-		result(llen, OK);
-	}
-	return ret;
+	ksft_test_result(expr, "%s = <%p>\n", test_name, expr);
 }
 
 
@@ -575,7 +530,7 @@ static int expect_strne(const char *expr, int llen, const char *cmp)
 
 /* declare tests based on line numbers. There must be exactly one test per line. */
 #define CASE_TEST(name) \
-	case __LINE__: llen += printf("%d %s", test, #name);
+	case __LINE__: test_name = #name;
 
 #define SWITCH_TEST \
 	int _tests_start = __LINE__; switch (test + __LINE__ + 1) {
@@ -1187,10 +1142,12 @@ int prepare(void)
 static const struct test test_names[] = {
 	/* add new tests here */
 	{ .name = "startup",    .func = run_startup    },
+	/*
 	{ .name = "syscall",    .func = run_syscall    },
 	{ .name = "stdlib",     .func = run_stdlib     },
 	{ .name = "vfprintf",   .func = run_vfprintf   },
 	{ .name = "protection", .func = run_protection },
+	*/
 };
 
 int is_setting_valid(char *test)
@@ -1317,16 +1274,19 @@ int main(int argc, char **argv, char **envp)
 		} while (test && *test);
 	} else {
 		/* no test mentioned, run everything */
+
+		ksft_print_header_ktap();
+		int total = 0;
+		for (idx = 0; idx < ARRAY_SIZE(test_names); idx++)
+			total += count_subtests(&test_names[idx]);
+		ksft_set_plan(total);
+
 		for (idx = 0; idx < ARRAY_SIZE(test_names); idx++) {
-			printf("Running test '%s'\n", test_names[idx].name);
 			err = test_names[idx].func(min, max);
 			ret += err;
-			printf("Errors during this test: %d\n\n", err);
 		}
 	}
 
-	printf("Total number of errors: %d\n", ret);
-
 	if (getpid() == 1) {
 		/* we're running as init, there's no other process on the
 		 * system, thus likely started from a VM for a quick check.
@@ -1335,7 +1295,7 @@ int main(int argc, char **argv, char **envp)
 		 * cleanly will often be reported as a success. This allows
 		 * to use the output of this program for bisecting kernels.
 		 */
-		printf("Leaving init with final status: %d\n", !!ret);
+		ksft_print_msg("Leaving init with final status: %d\n", !!ret);
 		if (ret == 0)
 			reboot(RB_POWER_OFF);
 #if defined(__x86_64__)
@@ -1349,6 +1309,7 @@ int main(int argc, char **argv, char **envp)
 #endif
 	}
 
-	printf("Exiting with status %d\n", !!ret);
+	ksft_print_msg("Exiting with status %d\n", !!ret);
+	ksft_finished();
 	return !!ret;
 }
diff --git a/tools/testing/selftests/nolibc/run-all-tests.sh b/tools/testing/selftests/nolibc/run-all-tests.sh
new file mode 100755
index 000000000000..8f37b8b36ef4
--- /dev/null
+++ b/tools/testing/selftests/nolibc/run-all-tests.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+set -o pipefail
+
+archs=(arm64 x86_64 riscv64)
+
+echo "KTAP version 1"
+echo "1..${#archs[@]}"
+
+for i in "${!archs[@]}"; do
+	arch="${archs[$i]}"
+	./libc-test | sed -e 's/^/  /'
+	rc=$?
+
+	if [ $rc -eq 0 ]; then
+		res=ok
+	else
+		res="not ok"
+	fi
+
+	echo "$res $(( i + 1 )) $arch"
+done
