[RFC PATCH v2 10/14] selftests/kcov_dataflow: add eight_args_c test module

1 view
Skip to first unread message

Yunseong Kim

unread,
Jun 11, 2026, 12:22:01 PMJun 11
to Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot, Dietmar Eggemann, Steven Rostedt, Ben Segall, Mel Gorman, Valentin Schneider, K Prateek Nayak, Andrey Konovalov, Alexander Potapenko, Dmitry Vyukov, Andrew Morton, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, Nathan Chancellor, Nicolas Schier, Nick Desaulniers, Bill Wendling, Justin Stitt, Kees Cook, David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Shuah Khan, Jonathan Corbet, Shuah Khan, Yunseong Kim, linux-...@vger.kernel.org, kasa...@googlegroups.com, rust-fo...@vger.kernel.org, linux-...@vger.kernel.org, ll...@lists.linux.dev, linu...@kvack.org, linux-k...@vger.kernel.org, work...@vger.kernel.org, linu...@vger.kernel.org, Yeoreum Yun
C module exercising 1-8 argument functions plus struct pointer.
Verifies register-passed (1-6) and stack-passed (7-8) arguments.

Test:

make LLVM=1 CC=clang \
M=tools/testing/selftests/kcov_dataflow/eight_args_c modules
vng --user root --exec \
"python3 tools/testing/selftests/kcov_dataflow/trigger-view.py \
eight_args_c -C 8 --ko \
tools/testing/selftests/kcov_dataflow/eight_args_c/eight_args_c.ko"

Result:

# Loaded eight_args_c
# Captured 6195 words
# 578 records
# showing 65 records with context=8 around eight_args_c

vfs_write(0x0)
0x0 = full_proxy_write()
full_proxy_write(0x0, 0x1, 0x0)
0x8200080 = __debugfs_file_get()
__debugfs_file_get(0x0)
0x0 = __debugfs_file_get()
0x0 = trigger_write [eight_args_c]()
trigger_write [eight_args_c](0x0, 0x1, 0x0)
df_func2 [eight_args_c](0x11, 0x22)
0x33 = df_func2 [eight_args_c]()
df_func3 [eight_args_c](0x11, 0x22, 0x33)
0x66 = df_func3 [eight_args_c]()
df_func4 [eight_args_c](0x11, 0x22, 0x33, 0x44)
0xaa = df_func4 [eight_args_c]()
df_func5 [eight_args_c](0x11, 0x22, 0x33, 0x44, 0x55)
0xff = df_func5 [eight_args_c]()
df_func6 [eight_args_c](0x11, 0x22, 0x33, 0x44, 0x55, 0x66)
0x165 = df_func6 [eight_args_c]()
df_func7 [eight_args_c](0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77)
0x1dc = df_func7 [eight_args_c]()
df_func8 [eight_args_c](0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88)
0x264 = df_func8 [eight_args_c]()
df_func_struct [eight_args_c](0xaaaa)
0x16665 = df_func_struct [eight_args_c]()
0x1 = trigger_write [eight_args_c]()
0x1 = full_proxy_write()
0x1 = vfs_write()
0x1 = ksys_write()
0x1 = __x64_sys_write()
0x0 = fpregs_assert_state_consistent()
0xba5748 = __x64_sys_close()
file_close_fd(0x4)
0x0 = file_close_fd()

Cc: Alexander Potapenko <gli...@google.com>
Assisted-by: Claude:claude-opus-4-6 [kiro-chat]
Link: https://github.com/yskzalloc/kcov-dataflow/actions
Signed-off-by: Yunseong Kim <yunseo...@est.tech>
---
tools/testing/selftests/kcov_dataflow/Makefile | 1 +
tools/testing/selftests/kcov_dataflow/README.rst | 6 ++
.../selftests/kcov_dataflow/eight_args_c/Makefile | 3 +
.../kcov_dataflow/eight_args_c/eight_args_c.c | 95 ++++++++++++++++++++++
.../selftests/kcov_dataflow/run_eight_args_c.sh | 35 ++++++++
5 files changed, 140 insertions(+)

diff --git a/tools/testing/selftests/kcov_dataflow/Makefile b/tools/testing/selftests/kcov_dataflow/Makefile
index b9fc1c5f0104..3a42c54e954d 100644
--- a/tools/testing/selftests/kcov_dataflow/Makefile
+++ b/tools/testing/selftests/kcov_dataflow/Makefile
@@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
TEST_GEN_PROGS := user_ioctl/user_ioctl
+TEST_PROGS := run_eight_args_c.sh
include ../lib.mk
diff --git a/tools/testing/selftests/kcov_dataflow/README.rst b/tools/testing/selftests/kcov_dataflow/README.rst
index 8b650a62acb1..e93b4e573504 100644
--- a/tools/testing/selftests/kcov_dataflow/README.rst
+++ b/tools/testing/selftests/kcov_dataflow/README.rst
@@ -35,3 +35,9 @@ trigger-view.py

python3 trigger-view.py <module_name>
python3 trigger-view.py <module_name> --raw
+
+eight_args_c/
+ C module with 1-8 argument functions + struct pointer::
+
+ make LLVM=1 CC=clang M=tools/testing/selftests/kcov_dataflow/eight_args_c modules
+ python3 trigger-view.py eight_args_c
diff --git a/tools/testing/selftests/kcov_dataflow/eight_args_c/Makefile b/tools/testing/selftests/kcov_dataflow/eight_args_c/Makefile
new file mode 100644
index 000000000000..aad45c7e3863
--- /dev/null
+++ b/tools/testing/selftests/kcov_dataflow/eight_args_c/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+obj-m := eight_args_c.o
+KCOV_DATAFLOW_eight_args_c.o := y
diff --git a/tools/testing/selftests/kcov_dataflow/eight_args_c/eight_args_c.c b/tools/testing/selftests/kcov_dataflow/eight_args_c/eight_args_c.c
new file mode 100644
index 000000000000..09fbbbf8d14b
--- /dev/null
+++ b/tools/testing/selftests/kcov_dataflow/eight_args_c/eight_args_c.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * eight_args_c.c - Verify kcov_dataflow captures 1-8 argument functions.
+ *
+ * Write to /sys/kernel/debug/kcov_dataflow_test/trigger to invoke all
+ * eight functions and a struct-pointer function. Use with the
+ * kcov_dataflow selftest to verify correct capture of register-passed
+ * (1-6) and stack-passed (7-8) arguments on x86_64.
+ */
+#include <linux/module.h>
+#include <linux/debugfs.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("KCOV dataflow 8-argument stress test");
+
+struct pair {
+ u32 x;
+ u32 y;
+};
+
+/* Prototypes */
+u64 df_func1(u64 a1);
+u64 df_func2(u64 a1, u64 a2);
+u64 df_func3(u64 a1, u64 a2, u64 a3);
+u64 df_func4(u64 a1, u64 a2, u64 a3, u64 a4);
+u64 df_func5(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5);
+u64 df_func6(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6);
+u64 df_func7(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6, u64 a7);
+u64 df_func8(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6, u64 a7,
+ u64 a8);
+u64 df_func_struct(struct pair *p);
+
+/* Implementations - noinline ensures trace callbacks are emitted */
+#define DEF_FUNC(name, ret_expr, ...) \
+noinline u64 name(__VA_ARGS__) { return (ret_expr); } \
+EXPORT_SYMBOL(name)
+
+DEF_FUNC(df_func1, a1, u64 a1);
+DEF_FUNC(df_func2, a1 + a2, u64 a1, u64 a2);
+DEF_FUNC(df_func3, a1 + a2 + a3, u64 a1, u64 a2, u64 a3);
+DEF_FUNC(df_func4, a1 + a2 + a3 + a4, u64 a1, u64 a2, u64 a3, u64 a4);
+DEF_FUNC(df_func5, a1 + a2 + a3 + a4 + a5,
+ u64 a1, u64 a2, u64 a3, u64 a4, u64 a5);
+DEF_FUNC(df_func6, a1 + a2 + a3 + a4 + a5 + a6,
+ u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6);
+DEF_FUNC(df_func7, a1 + a2 + a3 + a4 + a5 + a6 + a7,
+ u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6, u64 a7);
+DEF_FUNC(df_func8, a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8,
+ u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6, u64 a7, u64 a8);
+
+noinline u64 df_func_struct(struct pair *p)
+{
+ return (u64)p->x + (u64)p->y;
+}
+EXPORT_SYMBOL(df_func_struct);
+
+static struct dentry *test_dir;
+
+static ssize_t trigger_write(struct file *f, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct pair p = { .x = 0xAAAA, .y = 0xBBBB };
+ volatile u64 sum = 0;
+
+ sum += df_func1(0x11);
+ sum += df_func2(0x11, 0x22);
+ sum += df_func3(0x11, 0x22, 0x33);
+ sum += df_func4(0x11, 0x22, 0x33, 0x44);
+ sum += df_func5(0x11, 0x22, 0x33, 0x44, 0x55);
+ sum += df_func6(0x11, 0x22, 0x33, 0x44, 0x55, 0x66);
+ sum += df_func7(0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77);
+ sum += df_func8(0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88);
+ sum += df_func_struct(&p);
+
+ return count;
+}
+
+static const struct file_operations trigger_fops = {
+ .write = trigger_write,
+};
+
+static int __init eight_args_init(void)
+{
+ test_dir = debugfs_create_dir("kcov_dataflow_test", NULL);
+ debugfs_create_file("trigger", 0200, test_dir, NULL, &trigger_fops);
+ return 0;
+}
+
+static void __exit eight_args_exit(void)
+{
+ debugfs_remove_recursive(test_dir);
+}
+
+module_init(eight_args_init);
+module_exit(eight_args_exit);
diff --git a/tools/testing/selftests/kcov_dataflow/run_eight_args_c.sh b/tools/testing/selftests/kcov_dataflow/run_eight_args_c.sh
new file mode 100755
index 000000000000..d24092e920ff
--- /dev/null
+++ b/tools/testing/selftests/kcov_dataflow/run_eight_args_c.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Test eight_args_c module capture via kcov_dataflow
+DIR="$(dirname "$0")"
+KO="$DIR/eight_args_c/eight_args_c.ko"
+
+if [ ! -f "$KO" ]; then
+ echo "SKIP: $KO not found"
+ echo "Build: make LLVM=1 CC=clang M=...eight_args_c modules"
+ exit 4 # kselftest SKIP
+fi
+
+if [ ! -e /sys/kernel/debug/kcov_dataflow ]; then
+ echo "SKIP: kcov_dataflow not available"
+ exit 4
+fi
+
+OUTPUT=$(python3 "$DIR/trigger-view.py" eight_args_c --ko "$KO" --raw 2>&1)
+RC=$?
+
+if [ $RC -ne 0 ]; then
+ echo "FAIL: trigger-and-view exited with $RC"
+ echo "$OUTPUT"
+ exit 1
+fi
+
+RECORDS=$(echo "$OUTPUT" | grep -c "^\[ENTRY\]\|^\[RET")
+if [ "$RECORDS" -gt 0 ]; then
+ echo "PASS: captured $RECORDS records from eight_args_c"
+ exit 0
+else
+ echo "FAIL: no records captured"
+ echo "$OUTPUT"
+ exit 1
+fi

--
2.43.0

Reply all
Reply to author
Forward
0 new messages