The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Yunseong Kim <yunseong.kim@est.tech>
To: "Ingo Molnar" <mingo@redhat.com>,
	"Peter Zijlstra" <peterz@infradead.org>,
	"Juri Lelli" <juri.lelli@redhat.com>,
	"Vincent Guittot" <vincent.guittot@linaro.org>,
	"Dietmar Eggemann" <dietmar.eggemann@arm.com>,
	"Steven Rostedt" <rostedt@goodmis.org>,
	"Ben Segall" <bsegall@google.com>, "Mel Gorman" <mgorman@suse.de>,
	"Valentin Schneider" <vschneid@redhat.com>,
	"K Prateek Nayak" <kprateek.nayak@amd.com>,
	"Andrey Konovalov" <andreyknvl@gmail.com>,
	"Alexander Potapenko" <glider@google.com>,
	"Dmitry Vyukov" <dvyukov@google.com>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Boqun Feng" <boqun@kernel.org>, "Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <lossin@kernel.org>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Danilo Krummrich" <dakr@kernel.org>,
	"Nathan Chancellor" <nathan@kernel.org>,
	"Nicolas Schier" <nsc@kernel.org>,
	"Nick Desaulniers" <nick.desaulniers+lkml@gmail.com>,
	"Bill Wendling" <morbo@google.com>,
	"Justin Stitt" <justinstitt@google.com>,
	"Kees Cook" <kees@kernel.org>,
	"David Hildenbrand" <david@kernel.org>,
	"Lorenzo Stoakes" <ljs@kernel.org>,
	"Liam R. Howlett" <liam@infradead.org>,
	"Vlastimil Babka" <vbabka@kernel.org>,
	"Mike Rapoport" <rppt@kernel.org>,
	"Suren Baghdasaryan" <surenb@google.com>,
	"Michal Hocko" <mhocko@suse.com>, "Shuah Khan" <shuah@kernel.org>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Shuah Khan" <skhan@linuxfoundation.org>,
	"Yunseong Kim" <yunseong.kim@est.tech>
Cc: linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com,
	 rust-for-linux@vger.kernel.org, linux-kbuild@vger.kernel.org,
	 llvm@lists.linux.dev, linux-mm@kvack.org,
	linux-kselftest@vger.kernel.org,  workflows@vger.kernel.org,
	linux-doc@vger.kernel.org,  Yeoreum Yun <yeoreum.yun@arm.com>
Subject: [RFC PATCH v2 13/14] selftests/kcov_dataflow: add binderfs ioctl capture test
Date: Thu, 11 Jun 2026 18:21:15 +0200	[thread overview]
Message-ID: <20260611-b4-kcov-dataflow-v2-v2-13-0a261da3987c@est.tech> (raw)
In-Reply-To: <20260611-b4-kcov-dataflow-v2-v2-0-0a261da3987c@est.tech>

Exercise the binder driver via binderfs with kcov_dataflow recording
active. Verifies that function argument records are captured at binder
ioctl boundaries (BINDER_VERSION, BINDER_SET_MAX_THREADS).

Requires CONFIG_ANDROID_BINDER_IPC=y and CONFIG_ANDROID_BINDERFS=y.
Gracefully skips if binderfs is not available.

Build and test:

  export PATH=$PWD/../llvm-project/build/bin:$PATH
  vng --build \
    --configitem CONFIG_KCOV=y \
    --configitem CONFIG_KCOV_DATAFLOW_ARGS=y \
    --configitem CONFIG_KCOV_DATAFLOW_RET=y \
    --configitem CONFIG_KCOV_DATAFLOW_INSTRUMENT_ALL=y \
    --configitem CONFIG_DEBUG_INFO=y \
    --configitem CONFIG_ANDROID_BINDER_IPC=y \
    --configitem CONFIG_ANDROID_BINDERFS=y \
    LLVM=1 CC=clang

  make -C tools/testing/selftests/kcov_dataflow/binderfs
  vng --user root --exec \
    tools/testing/selftests/kcov_dataflow/binderfs/binderfs_test

Result:

  TAP version 13
  1..3
  ok 1 kcov_dataflow.binderfs_setup
  ok 2 kcov_dataflow.binderfs_captured # 636 words
  ok 3 kcov_dataflow.binderfs_valid_records
  # Totals: pass:3 fail:0 skip:0
  #
  # Captured call records:
  #   ENTRY pc=0xffffffff... arg=0x4           (fd)
  #   ENTRY pc=0xffffffff... arg=0xc0046209    (BINDER_VERSION)
  #   ENTRY pc=0xffffffff... arg=0x0           (binder_get_thread)
  #   RET   pc=0xffffffff... ret=0x0           (success)
  #   ENTRY pc=0xffffffff... arg=0x40046205    (SET_MAX_THREADS)
  #   ENTRY pc=0xffffffff... arg=0x4           (_copy_from_user size)

Cc: Alexander Potapenko <glider@google.com>
Assisted-by: Claude:claude-opus-4-6 [kiro-chat]
Signed-off-by: Yunseong Kim <yunseong.kim@est.tech>
---
 tools/testing/selftests/kcov_dataflow/.gitignore   |   1 +
 .../selftests/kcov_dataflow/binderfs/Makefile      |   4 +
 .../kcov_dataflow/binderfs/binderfs_test.c         | 177 +++++++++++++++++++++
 .../selftests/kcov_dataflow/run_binderfs.sh        |  13 ++
 4 files changed, 195 insertions(+)

diff --git a/tools/testing/selftests/kcov_dataflow/.gitignore b/tools/testing/selftests/kcov_dataflow/.gitignore
index f71fc89580f8..da4c189ad3be 100644
--- a/tools/testing/selftests/kcov_dataflow/.gitignore
+++ b/tools/testing/selftests/kcov_dataflow/.gitignore
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 user_ioctl/user_ioctl
+binderfs/binderfs_test
 *.o
 *.ko
 *.mod
diff --git a/tools/testing/selftests/kcov_dataflow/binderfs/Makefile b/tools/testing/selftests/kcov_dataflow/binderfs/Makefile
new file mode 100644
index 000000000000..9f1588512dba
--- /dev/null
+++ b/tools/testing/selftests/kcov_dataflow/binderfs/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
+TEST_GEN_PROGS := binderfs_test
+CFLAGS += -Wall -O2
+include ../../lib.mk
diff --git a/tools/testing/selftests/kcov_dataflow/binderfs/binderfs_test.c b/tools/testing/selftests/kcov_dataflow/binderfs/binderfs_test.c
new file mode 100644
index 000000000000..ce9b49aa0b9f
--- /dev/null
+++ b/tools/testing/selftests/kcov_dataflow/binderfs/binderfs_test.c
@@ -0,0 +1,177 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * binderfs selftest for kcov_dataflow
+ *
+ * Exercises the binder driver via binderfs with kcov_dataflow recording
+ * active, then verifies that function argument records were captured at
+ * binder ioctl boundaries.
+ *
+ * Requires: CONFIG_ANDROID_BINDER_IPC=y (or _RUST), CONFIG_ANDROID_BINDERFS=y
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <linux/android/binder.h>
+#include <linux/android/binderfs.h>
+
+#define KCOV_DF_INIT_TRACK	_IOR('d', 1, unsigned long)
+#define KCOV_DF_ENABLE		_IO('d', 100)
+#define KCOV_DF_DISABLE		_IO('d', 101)
+
+#define BUF_SIZE	(1 << 20)
+#define BINDERFS_PATH	"/tmp/binderfs_test"
+#define BINDER_DEV	BINDERFS_PATH "/my_binder"
+
+static int setup_binderfs(void)
+{
+	struct binderfs_device dev = {};
+
+	mkdir(BINDERFS_PATH, 0755);
+
+	if (mount("binder", BINDERFS_PATH, "binder", 0, NULL)) {
+		if (errno == ENODEV || errno == ENOENT) {
+			printf("SKIP: binderfs not available\n");
+			return -1;
+		}
+		perror("mount binderfs");
+		return -1;
+	}
+
+	/* Create a binder device via BINDER_CTL_ADD ioctl */
+	int ctl_fd;
+
+	ctl_fd = open(BINDERFS_PATH "/binder-control", O_RDONLY);
+	if (ctl_fd < 0) {
+		perror("open binder-control");
+		umount(BINDERFS_PATH);
+		return -1;
+	}
+
+	strcpy(dev.name, "my_binder");
+	if (ioctl(ctl_fd, BINDER_CTL_ADD, &dev) && errno != EEXIST) {
+		perror("BINDER_CTL_ADD");
+		close(ctl_fd);
+		umount(BINDERFS_PATH);
+		return -1;
+	}
+	close(ctl_fd);
+	return 0;
+}
+
+static void cleanup_binderfs(void)
+{
+	umount(BINDERFS_PATH);
+	rmdir(BINDERFS_PATH);
+}
+
+int main(void)
+{
+	uint64_t *buf;
+	int df_fd, binder_fd;
+	uint64_t total;
+	int valid = 0;
+
+	printf("TAP version 13\n");
+	printf("1..3\n");
+
+	/* Setup binderfs */
+	if (setup_binderfs()) {
+		printf("ok 1 # SKIP binderfs not available\n");
+		printf("ok 2 # SKIP\n");
+		printf("ok 3 # SKIP\n");
+		return 0;
+	}
+
+	/* Open kcov_dataflow */
+	df_fd = open("/sys/kernel/debug/kcov_dataflow", O_RDWR);
+	if (df_fd < 0) {
+		printf("not ok 1 cannot open kcov_dataflow\n");
+		cleanup_binderfs();
+		return 1;
+	}
+
+	if (ioctl(df_fd, KCOV_DF_INIT_TRACK, BUF_SIZE)) {
+		printf("not ok 1 INIT_TRACK failed\n");
+		close(df_fd);
+		cleanup_binderfs();
+		return 1;
+	}
+
+	buf = mmap(NULL, BUF_SIZE * sizeof(uint64_t),
+		   PROT_READ | PROT_WRITE, MAP_SHARED, df_fd, 0);
+	if (buf == MAP_FAILED) {
+		printf("not ok 1 mmap failed\n");
+		close(df_fd);
+		cleanup_binderfs();
+		return 1;
+	}
+
+	printf("ok 1 kcov_dataflow.binderfs_setup\n");
+
+	/* Open binder device */
+	binder_fd = open(BINDER_DEV, O_RDWR | O_CLOEXEC);
+	if (binder_fd < 0) {
+		printf("not ok 2 cannot open %s: %s\n", BINDER_DEV,
+		       strerror(errno));
+		munmap(buf, BUF_SIZE * sizeof(uint64_t));
+		close(df_fd);
+		cleanup_binderfs();
+		return 1;
+	}
+
+	/* Enable recording and exercise binder ioctls */
+	ioctl(df_fd, KCOV_DF_ENABLE, 0);
+	__atomic_store_n(&buf[0], 0, __ATOMIC_RELAXED);
+
+	/* BINDER_VERSION - simple ioctl that exercises the binder path */
+	struct binder_version ver = {};
+
+	ioctl(binder_fd, BINDER_VERSION, &ver);
+
+	/* BINDER_SET_MAX_THREADS */
+	uint32_t max_threads = 4;
+
+	ioctl(binder_fd, BINDER_SET_MAX_THREADS, &max_threads);
+
+	ioctl(df_fd, KCOV_DF_DISABLE, 0);
+
+	total = __atomic_load_n(&buf[0], __ATOMIC_RELAXED);
+	close(binder_fd);
+
+	if (total > 0)
+		printf("ok 2 kcov_dataflow.binderfs_captured # %lu words\n",
+		       (unsigned long)total);
+	else
+		printf("not ok 2 kcov_dataflow.binderfs_captured # 0 words\n");
+
+	/* Verify at least one record has valid header (type 0xE or 0xF) */
+
+	if (total > 3) {
+		uint64_t hdr = buf[1];
+		uint32_t type = (hdr >> 28) & 0xF;
+
+		if (type == 0xE || type == 0xF)
+			valid = 1;
+	}
+
+	if (valid)
+		printf("ok 3 kcov_dataflow.binderfs_valid_records\n");
+	else
+		printf("not ok 3 kcov_dataflow.binderfs_valid_records\n");
+
+	printf("# Totals: pass:%d fail:%d skip:0\n",
+	       valid ? 3 : 2, valid ? 0 : 1);
+
+	munmap(buf, BUF_SIZE * sizeof(uint64_t));
+	close(df_fd);
+	cleanup_binderfs();
+	return valid ? 0 : 1;
+}
diff --git a/tools/testing/selftests/kcov_dataflow/run_binderfs.sh b/tools/testing/selftests/kcov_dataflow/run_binderfs.sh
new file mode 100755
index 000000000000..5376e5350061
--- /dev/null
+++ b/tools/testing/selftests/kcov_dataflow/run_binderfs.sh
@@ -0,0 +1,13 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Test binderfs ioctl capture via kcov_dataflow
+DIR="$(dirname "$0")"
+BIN="$DIR/binderfs/binderfs_test"
+
+if [ ! -f "$BIN" ]; then
+	echo "SKIP: $BIN not found"
+	echo "Build: make -C tools/testing/selftests/kcov_dataflow/binderfs"
+	exit 4
+fi
+
+exec "$BIN"

-- 
2.43.0


  parent reply	other threads:[~2026-06-11 16:22 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-11 16:21 [RFC PATCH v2 00/14] kcov: add per-task dataflow tracking for function arguments/return values Yunseong Kim
2026-06-11 16:21 ` [RFC PATCH v2 01/14] " Yunseong Kim
2026-06-12  7:34   ` Alexander Potapenko
2026-06-12 12:51     ` Yunseong Kim
2026-06-12 11:37   ` Julian Braha
2026-06-12 12:48     ` Yunseong Kim
2026-06-11 16:21 ` [RFC PATCH v2 02/14] kcov: fix INIT_TRACK race in kcov_dataflow Yunseong Kim
2026-06-12  6:55   ` Alexander Potapenko
2026-06-12  7:25     ` Yunseong Kim
2026-06-12  8:00       ` Alexander Potapenko
2026-06-12 13:11         ` Yunseong Kim
2026-06-11 16:21 ` [RFC PATCH v2 03/14] kcov: add barriers to recursion guard in kcov_df_write Yunseong Kim
2026-06-12  7:30   ` Alexander Potapenko
2026-06-12 12:55     ` Yunseong Kim
2026-06-11 16:21 ` [RFC PATCH v2 04/14] kcov: reject enable on multiple dataflow fds simultaneously Yunseong Kim
2026-06-12  7:32   ` Alexander Potapenko
2026-06-11 16:21 ` [RFC PATCH v2 05/14] kcov: clear dataflow fields on fork Yunseong Kim
2026-06-11 16:21 ` [RFC PATCH v2 06/14] kcov: clean up dataflow state on task exit Yunseong Kim
2026-06-11 16:21 ` [RFC PATCH v2 07/14] kcov: exclude kcov_dataflow.o from sanitizer instrumentation Yunseong Kim
2026-06-11 16:21 ` [RFC PATCH v2 08/14] selftests/kcov_dataflow: add trigger-view.py Yunseong Kim
2026-06-11 16:21 ` [RFC PATCH v2 09/14] selftests/kcov_dataflow: add ioctl interface selftest Yunseong Kim
2026-06-11 16:21 ` [RFC PATCH v2 10/14] selftests/kcov_dataflow: add eight_args_c test module Yunseong Kim
2026-06-11 16:21 ` [RFC PATCH v2 11/14] selftests/kcov_dataflow: add eight_args_rust " Yunseong Kim
2026-06-11 16:21 ` [RFC PATCH v2 12/14] selftests/kcov_dataflow: add rust_ffi_contract " Yunseong Kim
2026-06-11 16:21 ` Yunseong Kim [this message]
2026-06-11 16:21 ` [RFC PATCH v2 14/14] Documentation: add kcov-dataflow.rst Yunseong Kim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260611-b4-kcov-dataflow-v2-v2-13-0a261da3987c@est.tech \
    --to=yunseong.kim@est.tech \
    --cc=a.hindborg@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=aliceryhl@google.com \
    --cc=andreyknvl@gmail.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun@kernel.org \
    --cc=bsegall@google.com \
    --cc=corbet@lwn.net \
    --cc=dakr@kernel.org \
    --cc=david@kernel.org \
    --cc=dietmar.eggemann@arm.com \
    --cc=dvyukov@google.com \
    --cc=gary@garyguo.net \
    --cc=glider@google.com \
    --cc=juri.lelli@redhat.com \
    --cc=justinstitt@google.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=kees@kernel.org \
    --cc=kprateek.nayak@amd.com \
    --cc=liam@infradead.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=lossin@kernel.org \
    --cc=mgorman@suse.de \
    --cc=mhocko@suse.com \
    --cc=mingo@redhat.com \
    --cc=morbo@google.com \
    --cc=nathan@kernel.org \
    --cc=nick.desaulniers+lkml@gmail.com \
    --cc=nsc@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=rppt@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=shuah@kernel.org \
    --cc=skhan@linuxfoundation.org \
    --cc=surenb@google.com \
    --cc=tmgross@umich.edu \
    --cc=vbabka@kernel.org \
    --cc=vincent.guittot@linaro.org \
    --cc=vschneid@redhat.com \
    --cc=workflows@vger.kernel.org \
    --cc=yeoreum.yun@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox