From: Yonghong Song <yonghong.song@linux.dev>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Eduard Zingerman <eddyz87@gmail.com>,
kernel-team@fb.com
Subject: [PATCH bpf v2 3/3] selftests/bpf: Add tests for >8 byte return value and 128-bit arguments
Date: Fri, 10 Jul 2026 11:22:19 -0700 [thread overview]
Message-ID: <20260710182219.1092246-1-yonghong.song@linux.dev> (raw)
In-Reply-To: <20260710182204.1085329-1-yonghong.song@linux.dev>
The BPF trampoline preserves only 8 bytes of the target's return value
(R0), so attaching an fexit/fmod_ret/fsession program to a function that
returns a >8 byte value is now rejected by the verifier. Add a bpf_testmod
function returning __int128 and an fexit program that targets it. The
program is expected to fail to load with the "with a >8 byte return value
is not supported for this attach type" message.
A 128-bit __int128 argument is passed in a register pair and occupies two
trampoline context slots. Add a bpf_testmod function taking an __int128
argument between two scalar arguments and an fexit program that reads the
surrounding argument and the return value, verifying that the trampoline
reserves enough stack for the 128-bit argument.
__int128 is only available on 64-bit targets (where the compiler defines
__SIZEOF_INT128__). The argument test additionally depends on the calling
convention: x86_64 and arm64 pass an __int128 in a register pair as the
trampoline expects, while other architectures pass it differently (e.g.
s390x passes larger arguments by reference), so that subtest runs only on
x86_64 and arm64 and is skipped elsewhere.
Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
---
.../bpf/prog_tests/tracing_failure.c | 12 +++++++
.../selftests/bpf/prog_tests/tracing_struct.c | 36 +++++++++++++++++++
.../selftests/bpf/progs/tracing_failure.c | 6 ++++
.../bpf/progs/tracing_struct_int128.c | 18 ++++++++++
.../selftests/bpf/test_kmods/bpf_testmod.c | 21 +++++++++++
5 files changed, 93 insertions(+)
create mode 100644 tools/testing/selftests/bpf/progs/tracing_struct_int128.c
diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_failure.c b/tools/testing/selftests/bpf/prog_tests/tracing_failure.c
index f9f9e1cb87bf..345dd21ad621 100644
--- a/tools/testing/selftests/bpf/prog_tests/tracing_failure.c
+++ b/tools/testing/selftests/bpf/prog_tests/tracing_failure.c
@@ -76,6 +76,16 @@ static void test_fexit_noreturns(void)
"Attaching fexit/fsession/fmod_ret to __noreturn function 'do_exit' is rejected.");
}
+static void test_fexit_int128_ret(void)
+{
+#ifdef __SIZEOF_INT128__
+ test_tracing_fail_prog("fexit_int128_ret",
+ "with a >8 byte return value is not supported for this attach type");
+#else
+ test__skip();
+#endif
+}
+
void test_tracing_failure(void)
{
if (test__start_subtest("bpf_spin_lock"))
@@ -86,4 +96,6 @@ void test_tracing_failure(void)
test_tracing_deny();
if (test__start_subtest("fexit_noreturns"))
test_fexit_noreturns();
+ if (test__start_subtest("fexit_int128_ret"))
+ test_fexit_int128_ret();
}
diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_struct.c b/tools/testing/selftests/bpf/prog_tests/tracing_struct.c
index 6f8c0bfb0415..d32198ee02df 100644
--- a/tools/testing/selftests/bpf/prog_tests/tracing_struct.c
+++ b/tools/testing/selftests/bpf/prog_tests/tracing_struct.c
@@ -4,6 +4,7 @@
#include <test_progs.h>
#include "tracing_struct.skel.h"
#include "tracing_struct_many_args.skel.h"
+#include "tracing_struct_int128.skel.h"
static void test_struct_args(void)
{
@@ -112,6 +113,39 @@ static void test_struct_many_args(void)
tracing_struct_many_args__destroy(skel);
}
+static void test_int128_args(void)
+{
+ /*
+ * __int128 arguments are passed in a register pair on x86_64 and
+ * arm64, which the trampoline packs into two context slots. Other
+ * architectures pass a __int128 differently (e.g. s390x passes larger
+ * arguments by reference), so only exercise this on x86_64 and arm64.
+ */
+#if defined(__x86_64__) || defined(__aarch64__)
+ struct tracing_struct_int128 *skel;
+ int err;
+
+ skel = tracing_struct_int128__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "tracing_struct_int128__open_and_load"))
+ return;
+
+ err = tracing_struct_int128__attach(skel);
+ if (!ASSERT_OK(err, "tracing_struct_int128__attach"))
+ goto destroy_skel;
+
+ ASSERT_OK(trigger_module_test_read(256), "trigger_read");
+
+ ASSERT_EQ(skel->bss->t_a, 1, "t:a");
+ ASSERT_EQ(skel->bss->t_c, 3, "t:c");
+ ASSERT_EQ(skel->bss->t_ret, 6, "t ret");
+
+destroy_skel:
+ tracing_struct_int128__destroy(skel);
+#else
+ test__skip();
+#endif
+}
+
static void test_union_args(void)
{
struct tracing_struct *skel;
@@ -145,6 +179,8 @@ void test_tracing_struct(void)
test_struct_args();
if (test__start_subtest("struct_many_args"))
test_struct_many_args();
+ if (test__start_subtest("int128_args"))
+ test_int128_args();
if (test__start_subtest("union_args"))
test_union_args();
}
diff --git a/tools/testing/selftests/bpf/progs/tracing_failure.c b/tools/testing/selftests/bpf/progs/tracing_failure.c
index 65e485c4468c..f7a095767679 100644
--- a/tools/testing/selftests/bpf/progs/tracing_failure.c
+++ b/tools/testing/selftests/bpf/progs/tracing_failure.c
@@ -30,3 +30,9 @@ int BPF_PROG(fexit_noreturns)
{
return 0;
}
+
+SEC("?fexit/bpf_testmod_test_int128_ret")
+int BPF_PROG(fexit_int128_ret)
+{
+ return 0;
+}
diff --git a/tools/testing/selftests/bpf/progs/tracing_struct_int128.c b/tools/testing/selftests/bpf/progs/tracing_struct_int128.c
new file mode 100644
index 000000000000..5f20dd4fdd9d
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/tracing_struct_int128.c
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2026 Meta Platforms, Inc. and affiliates. */
+#include <vmlinux.h>
+#include <bpf/bpf_tracing.h>
+#include <bpf/bpf_helpers.h>
+
+long t_a, t_c, t_ret;
+
+SEC("fexit/bpf_testmod_test_int128_arg")
+int test_int128_arg_fexit(unsigned long long *ctx)
+{
+ t_a = (int)ctx[0];
+ t_c = (long)ctx[3];
+ t_ret = (long)ctx[4];
+ return 0;
+}
+
+char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
index 30f1cd23093c..a0ad810b5ddc 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
@@ -161,6 +161,22 @@ bpf_testmod_test_arg_ptr_to_struct(struct bpf_testmod_struct_arg_1 *a) {
return bpf_testmod_test_struct_arg_result;
}
+#ifdef __SIZEOF_INT128__
+noinline __int128
+bpf_testmod_test_int128_ret(int a)
+{
+ bpf_testmod_test_struct_arg_result = a;
+ return (__int128)a;
+}
+
+noinline long
+bpf_testmod_test_int128_arg(int a, __int128 b, long c)
+{
+ bpf_testmod_test_struct_arg_result = a + (long)b + c;
+ return bpf_testmod_test_struct_arg_result;
+}
+#endif
+
__weak noinline void bpf_testmod_looooooooooooooooooooooooooooooong_name(void)
{
}
@@ -514,6 +530,11 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
(void)bpf_testmod_test_arg_ptr_to_struct(&struct_arg1_2);
+#ifdef __SIZEOF_INT128__
+ (void)bpf_testmod_test_int128_ret(i);
+ (void)bpf_testmod_test_int128_arg(1, (__int128)2, 3);
+#endif
+
(void)trace_bpf_testmod_test_raw_tp_null_tp(NULL);
bpf_testmod_test_struct_ops3();
--
2.53.0-Meta
next prev parent reply other threads:[~2026-07-10 18:22 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 18:22 [PATCH bpf v2 0/3] bpf: Fix trampoline handling of 128-bit values Yonghong Song
2026-07-10 18:22 ` [PATCH bpf v2 1/3] bpf: Reject >8 byte return values on return-reading trampoline paths Yonghong Song
2026-07-10 18:22 ` [PATCH bpf v2 2/3] bpf, x86: Fix trampoline stack size for 128-bit arguments Yonghong Song
2026-07-10 18:22 ` Yonghong Song [this message]
2026-07-10 18:38 ` [PATCH bpf v2 3/3] selftests/bpf: Add tests for >8 byte return value and " sashiko-bot
2026-07-10 19:13 ` Yonghong Song
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=20260710182219.1092246-1-yonghong.song@linux.dev \
--to=yonghong.song@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=kernel-team@fb.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