Linux Kernel Selftest development
 help / color / mirror / Atom feed
* [PATCH v2] selftests: harness: Support KCOV.
@ 2025-10-28  2:42 Kuniyuki Iwashima
  2025-11-06  8:50 ` kernel test robot
  2025-11-06 21:42 ` Shuah Khan
  0 siblings, 2 replies; 4+ messages in thread
From: Kuniyuki Iwashima @ 2025-10-28  2:42 UTC (permalink / raw)
  To: Shuah Khan; +Cc: Kuniyuki Iwashima, Kuniyuki Iwashima, linux-kselftest

While writing a selftest with kselftest_harness.h, I often want to
check which paths are actually exercised.

Let's support generating KCOV coverage data.

We can specify the output directory via the KCOV_OUTPUT environment
variable, and the number of instructions to collect via the KCOV_SLOTS
environment variable.

  # KCOV_OUTPUT=$PWD/kcov KCOV_SLOTS=$((4096 * 2)) \
    ./tools/testing/selftests/net/af_unix/scm_inq

Both variables can also be specified as the make variable.

  # make -C tools/testing/selftests/ \
    KCOV_OUTPUT=$PWD/kcov KCOV_SLOTS=$((4096 * 4)) \
    kselftest_override_timeout=60 TARGETS=net/af_unix run_tests

The coverage data can be simply decoded with addr2line:

  $ cat kcov/* | sort | uniq | addr2line -e vmlinux | grep unix
  net/unix/af_unix.c:1056
  net/unix/af_unix.c:3138
  net/unix/af_unix.c:3834
  net/unix/af_unix.c:3838
  net/unix/af_unix.c:311 (discriminator 2)
  ...

or more nicely with a script embedded in vock [0]:

  $ cat kcov/* | sort | uniq > local.log
  $ python3 ~/kernel/tools/vock/report.py \
    --kernel-src ./ --vmlinux ./vmlinux \
    --mode local --local-log local.log --filter unix
  ...
  ------------------------------- Coverage Report --------------------------------
  📄 net/unix/af_unix.c (276 lines)
   ...
  942 | static int unix_setsockopt(struct socket *sock, int level, int optname,
  943 | 			   sockptr_t optval, unsigned int optlen)
  944 | {
   ...
  961 | 	switch (optname) {
  962 | 	case SO_INQ:
  963 > 		if (sk->sk_type != SOCK_STREAM)
  964 | 			return -EINVAL;
  965 |
  966 > 		if (val > 1 || val < 0)
  967 | 			return -EINVAL;
  968 |
  969 > 		WRITE_ONCE(u->recvmsg_inq, val);
  970 | 		break;

Link: https://github.com/kzall0c/vock/blob/f3d97de9954f9df758c0ab287ca7e24e654288c7/report.py #[0]
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
v2: Support TEST()
v1: https://lore.kernel.org/linux-kselftest/20251017084022.3721950-1-kuniyu@google.com/
---
 Documentation/dev-tools/kselftest.rst       |  41 ++++++
 tools/testing/selftests/Makefile            |  14 ++-
 tools/testing/selftests/kselftest_harness.h | 133 +++++++++++++++++++-
 3 files changed, 178 insertions(+), 10 deletions(-)

diff --git a/Documentation/dev-tools/kselftest.rst b/Documentation/dev-tools/kselftest.rst
index 18c2da67fae4..5c2b92ac4a30 100644
--- a/Documentation/dev-tools/kselftest.rst
+++ b/Documentation/dev-tools/kselftest.rst
@@ -200,6 +200,47 @@ You can look at the TAP output to see if you ran into the timeout. Test
 runners which know a test must run under a specific time can then optionally
 treat these timeouts then as fatal.
 
+KCOV for selftests
+==================
+
+Selftests built with `kselftest_harness.h` natively support generating
+KCOV coverage data.  See :doc:`KCOV: code coverage for fuzzing </dev-tools/kcov>`
+for prerequisites.
+
+You can specify the output directory with the `KCOV_OUTPUT` environment
+variable.  Additionally, you can specify the number of instructions to
+collect with the `KCOV_SLOTS` environment variable ::
+
+  # KCOV_OUTPUT=$PWD/kcov KCOV_SLOTS=$((4096 * 2)) \
+        ./tools/testing/selftests/net/af_unix/scm_inq
+
+In the output directory, a coverage file is generated for each test
+case in the selftest ::
+
+  $ ls kcov/
+  scm_inq.dgram.basic  scm_inq.seqpacket.basic  scm_inq.stream.basic
+
+The default value of `KCOV_SLOTS` is `4096`, and `KCOV_SLOTS` multiplied
+by `sizeof(unsigned long)` must be multiple of `4096`, so the smallest
+value is `512`.
+
+Both `KCOV_OUTPUT` and `KCOV_SLOTS` can be specified as the variables
+on the `make` command line ::
+
+  # make -C tools/testing/selftests/ \
+        kselftest_override_timeout=60 \
+        KCOV_OUTPUT=$PWD/kcov KCOV_SLOTS=$((4096 * 4)) \
+        TARGETS=net/af_unix run_tests
+
+The collected data can be decoded with `addr2line` ::
+
+  $ cat kcov/* | sort | uniq | addr2line -e vmlinux | grep unix
+  net/unix/af_unix.c:1056
+  net/unix/af_unix.c:3138
+  net/unix/af_unix.c:3834
+  net/unix/af_unix.c:3838
+  ...
+
 Packaging selftests
 ===================
 
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index c46ebdb9b8ef..40e70fb1a347 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -218,12 +218,14 @@ all:
 	done; exit $$ret;
 
 run_tests: all
-	@for TARGET in $(TARGETS); do \
-		BUILD_TARGET=$$BUILD/$$TARGET;	\
-		$(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests \
-				SRC_PATH=$(shell readlink -e $$(pwd)) \
-				OBJ_PATH=$(BUILD)                   \
-				O=$(abs_objtree);		    \
+	@for TARGET in $(TARGETS); do				\
+		BUILD_TARGET=$$BUILD/$$TARGET;			\
+		$(MAKE) OUTPUT=$$BUILD_TARGET			\
+			KCOV_OUTPUT=$(abspath $(KCOV_OUTPUT))	\
+			-C $$TARGET run_tests			\
+			SRC_PATH=$(shell readlink -e $$(pwd))	\
+			OBJ_PATH=$(BUILD)			\
+			O=$(abs_objtree);			\
 	done;
 
 hotplug:
diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h
index 3f66e862e83e..5b7a01722981 100644
--- a/tools/testing/selftests/kselftest_harness.h
+++ b/tools/testing/selftests/kselftest_harness.h
@@ -56,6 +56,8 @@
 #include <asm/types.h>
 #include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <linux/kcov.h>
 #include <linux/unistd.h>
 #include <poll.h>
 #include <stdbool.h>
@@ -63,7 +65,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/ioctl.h>
 #include <sys/mman.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
@@ -175,9 +179,12 @@
 	static void test_name(struct __test_metadata *_metadata); \
 	static void wrapper_##test_name( \
 		struct __test_metadata *_metadata, \
-		struct __fixture_variant_metadata __attribute__((unused)) *variant) \
+		struct __fixture_variant_metadata __attribute__((unused)) *variant, \
+		char *test_full_name) \
 	{ \
+		enable_kcov(_metadata); \
 		test_name(_metadata); \
+		disable_kcov(_metadata, test_full_name); \
 	} \
 	static struct __test_metadata _##test_name##_object = \
 		{ .name = #test_name, \
@@ -401,7 +408,8 @@
 		const FIXTURE_VARIANT(fixture_name) *variant); \
 	static void wrapper_##fixture_name##_##test_name( \
 		struct __test_metadata *_metadata, \
-		struct __fixture_variant_metadata *variant) \
+		struct __fixture_variant_metadata *variant, \
+		char *test_full_name) \
 	{ \
 		/* fixture data is alloced, setup, and torn down per call. */ \
 		FIXTURE_DATA(fixture_name) self_private, *self = NULL; \
@@ -430,7 +438,9 @@
 			if (_metadata->exit_code) \
 				_exit(0); \
 			*_metadata->no_teardown = false; \
+			enable_kcov(_metadata); \
 			fixture_name##_##test_name(_metadata, self, variant->data); \
+			disable_kcov(_metadata, test_full_name); \
 			_metadata->teardown_fn(false, _metadata, self, variant->data); \
 			_exit(0); \
 		} else if (child < 0 || child != waitpid(child, &status, 0)) { \
@@ -470,6 +480,8 @@
 		object->teardown_fn = &wrapper_##fixture_name##_##test_name##_teardown; \
 		object->termsig = signal; \
 		object->timeout = tmout; \
+		object->kcov_fd = -1; \
+		object->kcov_slots = -1; \
 		_##fixture_name##_##test_name##_object = object; \
 		__register_test(object); \
 	} \
@@ -908,7 +920,8 @@ __register_fixture_variant(struct __fixture_metadata *f,
 struct __test_metadata {
 	const char *name;
 	void (*fn)(struct __test_metadata *,
-		   struct __fixture_variant_metadata *);
+		   struct __fixture_variant_metadata *,
+		   char *test_name);
 	pid_t pid;	/* pid of test when being run */
 	struct __fixture_metadata *fixture;
 	void (*teardown_fn)(bool in_parent, struct __test_metadata *_metadata,
@@ -923,6 +936,10 @@ struct __test_metadata {
 	const void *variant;
 	struct __test_results *results;
 	struct __test_metadata *prev, *next;
+	int kcov_fd;
+	int kcov_slots;
+	char *kcov_dir;
+	unsigned long *kcov_mem;
 };
 
 static inline bool __test_passed(struct __test_metadata *metadata)
@@ -1185,6 +1202,114 @@ static bool test_enabled(int argc, char **argv,
 	return !has_positive;
 }
 
+#define KCOV_SLOTS 4096
+
+static void enable_kcov(struct __test_metadata *t)
+{
+	char *slots;
+	int err;
+
+	t->kcov_dir = getenv("KCOV_OUTPUT");
+	if (!t->kcov_dir || *t->kcov_dir == '\0')
+		return;
+
+	slots = getenv("KCOV_SLOTS");
+	if (slots && *slots != '\0')
+		sscanf(slots, "%d", &t->kcov_slots);
+	if (t->kcov_slots <= 0)
+		t->kcov_slots = KCOV_SLOTS;
+
+	t->kcov_fd = open("/sys/kernel/debug/kcov", O_RDWR);
+	if (t->kcov_fd < 0) {
+		ksft_print_msg("ERROR OPENING KCOV FD\n");
+		goto err;
+	}
+
+	err = ioctl(t->kcov_fd, KCOV_INIT_TRACE, t->kcov_slots);
+	if (err) {
+		ksft_print_msg("ERROR INITIALISING KCOV\n");
+		goto err;
+	}
+
+	t->kcov_mem = mmap(NULL, sizeof(unsigned long) * t->kcov_slots,
+			   PROT_READ | PROT_WRITE, MAP_SHARED, t->kcov_fd, 0);
+	if ((void *)t->kcov_mem == MAP_FAILED) {
+		ksft_print_msg("ERROR ALLOCATING MEMORY FOR KCOV\n");
+		goto err;
+	}
+
+	err = ioctl(t->kcov_fd, KCOV_ENABLE, KCOV_TRACE_PC);
+	if (err) {
+		ksft_print_msg("ERROR ENABLING KCOV\n");
+		goto err;
+	}
+
+	__atomic_store_n(&t->kcov_mem[0], 0, __ATOMIC_RELAXED);
+	return;
+err:
+	t->exit_code = KSFT_FAIL;
+	_exit(KSFT_FAIL);
+}
+
+static void disable_kcov(struct __test_metadata *t, char *test_name)
+{
+	int slots, err, dir, fd, i;
+
+	if (t->kcov_fd == -1)
+		return;
+
+	slots = __atomic_load_n(&t->kcov_mem[0], __ATOMIC_RELAXED);
+	if (slots == t->kcov_slots - 1)
+		ksft_print_msg("Set KCOV_SLOTS to a value greater than %d\n", t->kcov_slots);
+
+	err = ioctl(t->kcov_fd, KCOV_DISABLE, 0);
+	if (err) {
+		ksft_print_msg("ERROR DISABLING KCOV\n");
+		goto out;
+	}
+
+	err = mkdir(t->kcov_dir, 0755);
+	if (err == -1 && errno != EEXIST) {
+		ksft_print_msg("ERROR CREATING '%s'\n", t->kcov_dir);
+		goto out;
+	}
+	err = 0;
+
+	dir = open(t->kcov_dir, O_DIRECTORY);
+	if (dir < 0) {
+		ksft_print_msg("ERROR OPENING %s\n", t->kcov_dir);
+		err = dir;
+		goto out;
+	}
+
+	fd = openat(dir, test_name, O_RDWR | O_CREAT | O_TRUNC);
+
+	close(dir);
+
+	if (fd == -1) {
+		ksft_print_msg("ERROR CREATING '%s' at '%s'\n", test_name, t->kcov_dir);
+		err = fd;
+		goto out;
+	}
+
+	for (i = 0; i < slots; i++) {
+		char buf[64];
+		int size;
+
+		size = snprintf(buf, 64, "0x%lx\n", t->kcov_mem[i + 1]);
+		write(fd, buf, size);
+	}
+
+out:
+	munmap(t->kcov_mem, sizeof(t->kcov_mem[0]) * t->kcov_slots);
+	close(t->kcov_fd);
+
+	if (err) {
+		t->exit_code = KSFT_FAIL;
+		_exit(KSFT_FAIL);
+	}
+}
+
 static void __run_test(struct __fixture_metadata *f,
 		       struct __fixture_variant_metadata *variant,
 		       struct __test_metadata *t)
@@ -1216,7 +1341,7 @@ static void __run_test(struct __fixture_metadata *f,
 		t->exit_code = KSFT_FAIL;
 	} else if (child == 0) {
 		setpgrp();
-		t->fn(t, variant);
+		t->fn(t, variant, test_name);
 		_exit(t->exit_code);
 	} else {
 		t->pid = child;
-- 
2.51.1.838.g19442a804e-goog


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] selftests: harness: Support KCOV.
  2025-10-28  2:42 [PATCH v2] selftests: harness: Support KCOV Kuniyuki Iwashima
@ 2025-11-06  8:50 ` kernel test robot
  2025-11-06 21:42 ` Shuah Khan
  1 sibling, 0 replies; 4+ messages in thread
From: kernel test robot @ 2025-11-06  8:50 UTC (permalink / raw)
  To: Kuniyuki Iwashima
  Cc: oe-lkp, lkp, linux-kselftest, Shuah Khan, Kuniyuki Iwashima,
	Kuniyuki Iwashima, oliver.sang



Hello,

kernel test robot noticed "segfault_at_ip_sp_error" on:

commit: c849d8e404a7b145b33c184042234e903ce72c7c ("[PATCH v2] selftests: harness: Support KCOV.")
url: https://github.com/intel-lab-lkp/linux/commits/Kuniyuki-Iwashima/selftests-harness-Support-KCOV/20251028-104538
base: https://git.kernel.org/cgit/linux/kernel/git/shuah/linux-kselftest.git next
patch link: https://lore.kernel.org/all/20251028024339.2028774-1-kuniyu@google.com/
patch subject: [PATCH v2] selftests: harness: Support KCOV.

in testcase: kernel-selftests
version: kernel-selftests-x86_64-8bb886cb8f3a-1_20251104
with following parameters:

	group: syscall_user_dispatch



config: x86_64-rhel-9.4-kselftests
compiler: gcc-14
test machine: 36 threads 1 sockets Intel(R) Core(TM) i9-9980XE CPU @ 3.00GHz (Skylake) with 32G memory

(please refer to attached dmesg/kmsg for entire log/backtrace)



If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202511061615.3c5824f3-lkp@intel.com




kern  :info  : [   72.507647] [   T2520] sud_test[2520]: segfault at 0 ip 0000558da6f1242c sp 00007fffd6f2faf0 error 4 in sud_test[342c,558da6f11000+5000] likely on CPU 23 (core 8, socket 0)
kern  :info  : [   72.508965] [   T2520] Code: 48 89 e5 48 83 ec 70 48 89 7d 98 48 89 75 90 48 8b 45 98 8b 40 70 83 f8 ff 0f 84 36 02 00 00 48 8b 45 98 48 8b 80 80 00 00 00 <48> 8b 00 89 45 f4 48 8b 45 98 8b 40 74 83 e8 01 39 45 f4 75 1d 48
All code
========
   0:	48 89 e5             	mov    %rsp,%rbp
   3:	48 83 ec 70          	sub    $0x70,%rsp
   7:	48 89 7d 98          	mov    %rdi,-0x68(%rbp)
   b:	48 89 75 90          	mov    %rsi,-0x70(%rbp)
   f:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  13:	8b 40 70             	mov    0x70(%rax),%eax
  16:	83 f8 ff             	cmp    $0xffffffff,%eax
  19:	0f 84 36 02 00 00    	je     0x255
  1f:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  23:	48 8b 80 80 00 00 00 	mov    0x80(%rax),%rax
  2a:*	48 8b 00             	mov    (%rax),%rax		<-- trapping instruction
  2d:	89 45 f4             	mov    %eax,-0xc(%rbp)
  30:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  34:	8b 40 74             	mov    0x74(%rax),%eax
  37:	83 e8 01             	sub    $0x1,%eax
  3a:	39 45 f4             	cmp    %eax,-0xc(%rbp)
  3d:	75 1d                	jne    0x5c
  3f:	48                   	rex.W

Code starting with the faulting instruction
===========================================
   0:	48 8b 00             	mov    (%rax),%rax
   3:	89 45 f4             	mov    %eax,-0xc(%rbp)
   6:	48 8b 45 98          	mov    -0x68(%rbp),%rax
   a:	8b 40 74             	mov    0x74(%rax),%eax
   d:	83 e8 01             	sub    $0x1,%eax
  10:	39 45 f4             	cmp    %eax,-0xc(%rbp)
  13:	75 1d                	jne    0x32
  15:	48                   	rex.W
kern  :info  : [   72.511780] [   T2521] sud_test[2521]: segfault at 0 ip 0000558da6f1242c sp 00007fffd6f2faf0 error 4 in sud_test[342c,558da6f11000+5000] likely on CPU 23 (core 8, socket 0)
kern  :info  : [   72.513080] [   T2521] Code: 48 89 e5 48 83 ec 70 48 89 7d 98 48 89 75 90 48 8b 45 98 8b 40 70 83 f8 ff 0f 84 36 02 00 00 48 8b 45 98 48 8b 80 80 00 00 00 <48> 8b 00 89 45 f4 48 8b 45 98 8b 40 74 83 e8 01 39 45 f4 75 1d 48
All code
========
   0:	48 89 e5             	mov    %rsp,%rbp
   3:	48 83 ec 70          	sub    $0x70,%rsp
   7:	48 89 7d 98          	mov    %rdi,-0x68(%rbp)
   b:	48 89 75 90          	mov    %rsi,-0x70(%rbp)
   f:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  13:	8b 40 70             	mov    0x70(%rax),%eax
  16:	83 f8 ff             	cmp    $0xffffffff,%eax
  19:	0f 84 36 02 00 00    	je     0x255
  1f:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  23:	48 8b 80 80 00 00 00 	mov    0x80(%rax),%rax
  2a:*	48 8b 00             	mov    (%rax),%rax		<-- trapping instruction
  2d:	89 45 f4             	mov    %eax,-0xc(%rbp)
  30:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  34:	8b 40 74             	mov    0x74(%rax),%eax
  37:	83 e8 01             	sub    $0x1,%eax
  3a:	39 45 f4             	cmp    %eax,-0xc(%rbp)
  3d:	75 1d                	jne    0x5c
  3f:	48                   	rex.W

Code starting with the faulting instruction
===========================================
   0:	48 8b 00             	mov    (%rax),%rax
   3:	89 45 f4             	mov    %eax,-0xc(%rbp)
   6:	48 8b 45 98          	mov    -0x68(%rbp),%rax
   a:	8b 40 74             	mov    0x74(%rax),%eax
   d:	83 e8 01             	sub    $0x1,%eax
  10:	39 45 f4             	cmp    %eax,-0xc(%rbp)
  13:	75 1d                	jne    0x32
  15:	48                   	rex.W
user  :notice: [   72.516773] [    T622] update-alternatives: warning: skip creation of /usr/share/man/man1/traceroute6.1.gz because associated file /usr/share/man/man1/traceroute6.db.1.gz (of link group traceroute6) doesn't exist

kern  :info  : [   72.517057] [   T2523] sud_test[2523]: segfault at 0 ip 0000558da6f1242c sp 00007fffd6f2faf0 error 4 in sud_test[342c,558da6f11000+5000] likely on CPU 27 (core 16, socket 0)
kern  :info  : [   72.519874] [   T2523] Code: 48 89 e5 48 83 ec 70 48 89 7d 98 48 89 75 90 48 8b 45 98 8b 40 70 83 f8 ff 0f 84 36 02 00 00 48 8b 45 98 48 8b 80 80 00 00 00 <48> 8b 00 89 45 f4 48 8b 45 98 8b 40 74 83 e8 01 39 45 f4 75 1d 48
All code
========
   0:	48 89 e5             	mov    %rsp,%rbp
   3:	48 83 ec 70          	sub    $0x70,%rsp
   7:	48 89 7d 98          	mov    %rdi,-0x68(%rbp)
   b:	48 89 75 90          	mov    %rsi,-0x70(%rbp)
   f:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  13:	8b 40 70             	mov    0x70(%rax),%eax
  16:	83 f8 ff             	cmp    $0xffffffff,%eax
  19:	0f 84 36 02 00 00    	je     0x255
  1f:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  23:	48 8b 80 80 00 00 00 	mov    0x80(%rax),%rax
  2a:*	48 8b 00             	mov    (%rax),%rax		<-- trapping instruction
  2d:	89 45 f4             	mov    %eax,-0xc(%rbp)
  30:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  34:	8b 40 74             	mov    0x74(%rax),%eax
  37:	83 e8 01             	sub    $0x1,%eax
  3a:	39 45 f4             	cmp    %eax,-0xc(%rbp)
  3d:	75 1d                	jne    0x5c
  3f:	48                   	rex.W

Code starting with the faulting instruction
===========================================
   0:	48 8b 00             	mov    (%rax),%rax
   3:	89 45 f4             	mov    %eax,-0xc(%rbp)
   6:	48 8b 45 98          	mov    -0x68(%rbp),%rax
   a:	8b 40 74             	mov    0x74(%rax),%eax
   d:	83 e8 01             	sub    $0x1,%eax
  10:	39 45 f4             	cmp    %eax,-0xc(%rbp)
  13:	75 1d                	jne    0x32
  15:	48                   	rex.W
user  :notice: [   72.521352] [    T622] update-alternatives: warning: skip creation of /usr/share/man/man1/lft.1.gz because associated file /usr/share/man/man1/lft.db.1.gz (of link group lft) doesn't exist

kern  :info  : [   72.522679] [   T2524] sud_test[2524]: segfault at 0 ip 0000558da6f1242c sp 00007fffd6f2faf0 error 4 in sud_test[342c,558da6f11000+5000] likely on CPU 23 (core 8, socket 0)
kern  :info  : [   72.524467] [   T2524] Code: 48 89 e5 48 83 ec 70 48 89 7d 98 48 89 75 90 48 8b 45 98 8b 40 70 83 f8 ff 0f 84 36 02 00 00 48 8b 45 98 48 8b 80 80 00 00 00 <48> 8b 00 89 45 f4 48 8b 45 98 8b 40 74 83 e8 01 39 45 f4 75 1d 48
All code
========
   0:	48 89 e5             	mov    %rsp,%rbp
   3:	48 83 ec 70          	sub    $0x70,%rsp
   7:	48 89 7d 98          	mov    %rdi,-0x68(%rbp)
   b:	48 89 75 90          	mov    %rsi,-0x70(%rbp)
   f:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  13:	8b 40 70             	mov    0x70(%rax),%eax
  16:	83 f8 ff             	cmp    $0xffffffff,%eax
  19:	0f 84 36 02 00 00    	je     0x255
  1f:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  23:	48 8b 80 80 00 00 00 	mov    0x80(%rax),%rax
  2a:*	48 8b 00             	mov    (%rax),%rax		<-- trapping instruction
  2d:	89 45 f4             	mov    %eax,-0xc(%rbp)
  30:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  34:	8b 40 74             	mov    0x74(%rax),%eax
  37:	83 e8 01             	sub    $0x1,%eax
  3a:	39 45 f4             	cmp    %eax,-0xc(%rbp)
  3d:	75 1d                	jne    0x5c
  3f:	48                   	rex.W

Code starting with the faulting instruction
===========================================
   0:	48 8b 00             	mov    (%rax),%rax
   3:	89 45 f4             	mov    %eax,-0xc(%rbp)
   6:	48 8b 45 98          	mov    -0x68(%rbp),%rax
   a:	8b 40 74             	mov    0x74(%rax),%eax
   d:	83 e8 01             	sub    $0x1,%eax
  10:	39 45 f4             	cmp    %eax,-0xc(%rbp)
  13:	75 1d                	jne    0x32
  15:	48                   	rex.W
user  :notice: [   72.526246] [    T622] update-alternatives: warning: skip creation of /usr/share/man/man1/traceproto.1.gz because associated file /usr/share/man/man1/traceproto.db.1.gz (of link group traceproto) doesn't exist

kern  :info  : [   72.529475] [   T2525] sud_test[2525]: segfault at 0 ip 0000558da6f1242c sp 00007fffd6f2faf0 error 4 in sud_test[342c,558da6f11000+5000] likely on CPU 16 (core 26, socket 0)
kern  :info  : [   72.530789] [   T2525] Code: 48 89 e5 48 83 ec 70 48 89 7d 98 48 89 75 90 48 8b 45 98 8b 40 70 83 f8 ff 0f 84 36 02 00 00 48 8b 45 98 48 8b 80 80 00 00 00 <48> 8b 00 89 45 f4 48 8b 45 98 8b 40 74 83 e8 01 39 45 f4 75 1d 48
All code
========
   0:	48 89 e5             	mov    %rsp,%rbp
   3:	48 83 ec 70          	sub    $0x70,%rsp
   7:	48 89 7d 98          	mov    %rdi,-0x68(%rbp)
   b:	48 89 75 90          	mov    %rsi,-0x70(%rbp)
   f:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  13:	8b 40 70             	mov    0x70(%rax),%eax
  16:	83 f8 ff             	cmp    $0xffffffff,%eax
  19:	0f 84 36 02 00 00    	je     0x255
  1f:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  23:	48 8b 80 80 00 00 00 	mov    0x80(%rax),%rax
  2a:*	48 8b 00             	mov    (%rax),%rax		<-- trapping instruction
  2d:	89 45 f4             	mov    %eax,-0xc(%rbp)
  30:	48 8b 45 98          	mov    -0x68(%rbp),%rax
  34:	8b 40 74             	mov    0x74(%rax),%eax
  37:	83 e8 01             	sub    $0x1,%eax
  3a:	39 45 f4             	cmp    %eax,-0xc(%rbp)
  3d:	75 1d                	jne    0x5c
  3f:	48                   	rex.W

Code starting with the faulting instruction
===========================================
   0:	48 8b 00             	mov    (%rax),%rax
   3:	89 45 f4             	mov    %eax,-0xc(%rbp)
   6:	48 8b 45 98          	mov    -0x68(%rbp),%rax
   a:	8b 40 74             	mov    0x74(%rax),%eax
   d:	83 e8 01             	sub    $0x1,%eax
  10:	39 45 f4             	cmp    %eax,-0xc(%rbp)
  13:	75 1d                	jne    0x32
  15:	48                   	rex.W


The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20251106/202511061615.3c5824f3-lkp@intel.com



-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] selftests: harness: Support KCOV.
  2025-10-28  2:42 [PATCH v2] selftests: harness: Support KCOV Kuniyuki Iwashima
  2025-11-06  8:50 ` kernel test robot
@ 2025-11-06 21:42 ` Shuah Khan
  2025-11-07  7:08   ` Kuniyuki Iwashima
  1 sibling, 1 reply; 4+ messages in thread
From: Shuah Khan @ 2025-11-06 21:42 UTC (permalink / raw)
  To: Kuniyuki Iwashima, Shuah Khan
  Cc: Kuniyuki Iwashima, linux-kselftest, Shuah Khan

On 10/27/25 20:42, Kuniyuki Iwashima wrote:
> While writing a selftest with kselftest_harness.h, I often want to
> check which paths are actually exercised.
> 
> Let's support generating KCOV coverage data.
> 
> We can specify the output directory via the KCOV_OUTPUT environment
> variable, and the number of instructions to collect via the KCOV_SLOTS
> environment variable.
> 
>    # KCOV_OUTPUT=$PWD/kcov KCOV_SLOTS=$((4096 * 2)) \
>      ./tools/testing/selftests/net/af_unix/scm_inq
> 
> Both variables can also be specified as the make variable.
> 
>    # make -C tools/testing/selftests/ \
>      KCOV_OUTPUT=$PWD/kcov KCOV_SLOTS=$((4096 * 4)) \
>      kselftest_override_timeout=60 TARGETS=net/af_unix run_tests
> 
> The coverage data can be simply decoded with addr2line:
> 
>    $ cat kcov/* | sort | uniq | addr2line -e vmlinux | grep unix
>    net/unix/af_unix.c:1056
>    net/unix/af_unix.c:3138
>    net/unix/af_unix.c:3834
>    net/unix/af_unix.c:3838
>    net/unix/af_unix.c:311 (discriminator 2)
>    ...
> 
> or more nicely with a script embedded in vock [0]:
> 
>    $ cat kcov/* | sort | uniq > local.log
>    $ python3 ~/kernel/tools/vock/report.py \
>      --kernel-src ./ --vmlinux ./vmlinux \
>      --mode local --local-log local.log --filter unix
>    ...
>    ------------------------------- Coverage Report --------------------------------
>    📄 net/unix/af_unix.c (276 lines)
>     ...
>    942 | static int unix_setsockopt(struct socket *sock, int level, int optname,
>    943 | 			   sockptr_t optval, unsigned int optlen)
>    944 | {
>     ...
>    961 | 	switch (optname) {
>    962 | 	case SO_INQ:
>    963 > 		if (sk->sk_type != SOCK_STREAM)
>    964 | 			return -EINVAL;
>    965 |
>    966 > 		if (val > 1 || val < 0)
>    967 | 			return -EINVAL;
>    968 |
>    969 > 		WRITE_ONCE(u->recvmsg_inq, val);
>    970 | 		break;
> 
> Link: https://github.com/kzall0c/vock/blob/f3d97de9954f9df758c0ab287ca7e24e654288c7/report.py #[0]
> Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
> ---
> v2: Support TEST()
> v1: https://lore.kernel.org/linux-kselftest/20251017084022.3721950-1-kuniyu@google.com/
> ---
>   Documentation/dev-tools/kselftest.rst       |  41 ++++++
>   tools/testing/selftests/Makefile            |  14 ++-
>   tools/testing/selftests/kselftest_harness.h | 133 +++++++++++++++++++-
>   3 files changed, 178 insertions(+), 10 deletions(-)
> 

I am okay with kcov support being added. You probably have to fix a few things.
kernel test robot is still complaining on v2.

thanks,
-- Shuah

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] selftests: harness: Support KCOV.
  2025-11-06 21:42 ` Shuah Khan
@ 2025-11-07  7:08   ` Kuniyuki Iwashima
  0 siblings, 0 replies; 4+ messages in thread
From: Kuniyuki Iwashima @ 2025-11-07  7:08 UTC (permalink / raw)
  To: Shuah Khan; +Cc: Shuah Khan, Kuniyuki Iwashima, linux-kselftest

On Thu, Nov 6, 2025 at 1:42 PM Shuah Khan <skhan@linuxfoundation.org> wrote:
>
> On 10/27/25 20:42, Kuniyuki Iwashima wrote:
> > While writing a selftest with kselftest_harness.h, I often want to
> > check which paths are actually exercised.
> >
> > Let's support generating KCOV coverage data.
> >
> > We can specify the output directory via the KCOV_OUTPUT environment
> > variable, and the number of instructions to collect via the KCOV_SLOTS
> > environment variable.
> >
> >    # KCOV_OUTPUT=$PWD/kcov KCOV_SLOTS=$((4096 * 2)) \
> >      ./tools/testing/selftests/net/af_unix/scm_inq
> >
> > Both variables can also be specified as the make variable.
> >
> >    # make -C tools/testing/selftests/ \
> >      KCOV_OUTPUT=$PWD/kcov KCOV_SLOTS=$((4096 * 4)) \
> >      kselftest_override_timeout=60 TARGETS=net/af_unix run_tests
> >
> > The coverage data can be simply decoded with addr2line:
> >
> >    $ cat kcov/* | sort | uniq | addr2line -e vmlinux | grep unix
> >    net/unix/af_unix.c:1056
> >    net/unix/af_unix.c:3138
> >    net/unix/af_unix.c:3834
> >    net/unix/af_unix.c:3838
> >    net/unix/af_unix.c:311 (discriminator 2)
> >    ...
> >
> > or more nicely with a script embedded in vock [0]:
> >
> >    $ cat kcov/* | sort | uniq > local.log
> >    $ python3 ~/kernel/tools/vock/report.py \
> >      --kernel-src ./ --vmlinux ./vmlinux \
> >      --mode local --local-log local.log --filter unix
> >    ...
> >    ------------------------------- Coverage Report --------------------------------
> >    📄 net/unix/af_unix.c (276 lines)
> >     ...
> >    942 | static int unix_setsockopt(struct socket *sock, int level, int optname,
> >    943 |                         sockptr_t optval, unsigned int optlen)
> >    944 | {
> >     ...
> >    961 |      switch (optname) {
> >    962 |      case SO_INQ:
> >    963 >              if (sk->sk_type != SOCK_STREAM)
> >    964 |                      return -EINVAL;
> >    965 |
> >    966 >              if (val > 1 || val < 0)
> >    967 |                      return -EINVAL;
> >    968 |
> >    969 >              WRITE_ONCE(u->recvmsg_inq, val);
> >    970 |              break;
> >
> > Link: https://github.com/kzall0c/vock/blob/f3d97de9954f9df758c0ab287ca7e24e654288c7/report.py #[0]
> > Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
> > ---
> > v2: Support TEST()
> > v1: https://lore.kernel.org/linux-kselftest/20251017084022.3721950-1-kuniyu@google.com/
> > ---
> >   Documentation/dev-tools/kselftest.rst       |  41 ++++++
> >   tools/testing/selftests/Makefile            |  14 ++-
> >   tools/testing/selftests/kselftest_harness.h | 133 +++++++++++++++++++-
> >   3 files changed, 178 insertions(+), 10 deletions(-)
> >
>
> I am okay with kcov support being added. You probably have to fix a few things.
> kernel test robot is still complaining on v2.

Thank you, Shuah!
Will fix the issue in v3.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-11-07  7:08 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-28  2:42 [PATCH v2] selftests: harness: Support KCOV Kuniyuki Iwashima
2025-11-06  8:50 ` kernel test robot
2025-11-06 21:42 ` Shuah Khan
2025-11-07  7:08   ` Kuniyuki Iwashima

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox