From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from 66-220-144-178.mail-mxout.facebook.com (66-220-144-178.mail-mxout.facebook.com [66.220.144.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B205E379C59 for ; Fri, 10 Jul 2026 18:22:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=66.220.144.178 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783707743; cv=none; b=L6UccKPLQxcFBZtjPw3MhPZ21H+wwXbvspln2QRqyMm71nDEkErAnXSWUUWOZg8V7woiJb4sJJnQ1SV1KAzhPxgvseMsus2K7Cotr0W7mVMQXSmWWtdIJCWJu92yLlfToRAjGTWAqVsT1yCZmxTmvZmciPTrHGhy/qOWKASJhTg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783707743; c=relaxed/simple; bh=iM8yfE0HWznVfmZdQvJXmZ06B2Azp/S9wTdKiN6ao1A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Xv/6mpHoBNuE+GXvu4anDJfvcMAmfZkJI3P+56G2yRARYqfzSUA8kMdt8TtutfG6fo3WO4IbTSJptfy7DH9tMfgc0SZ7q+HXFbrcKqo102FUC/LB9R1W981DO7mUl7Qwgywn0Y/jxbV9jCG6bZwR6IVRJMAmsHbSR2SnTsP966s= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev; spf=fail smtp.mailfrom=linux.dev; arc=none smtp.client-ip=66.220.144.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=fail smtp.mailfrom=linux.dev Received: by devvm16039.vll0.facebook.com (Postfix, from userid 128203) id A6B351D718DB26; Fri, 10 Jul 2026 11:22:19 -0700 (PDT) From: Yonghong Song To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Andrii Nakryiko , Daniel Borkmann , Eduard Zingerman , 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 Message-ID: <20260710182219.1092246-1-yonghong.song@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260710182204.1085329-1-yonghong.song@linux.dev> References: <20260710182204.1085329-1-yonghong.song@linux.dev> Precedence: bulk X-Mailing-List: bpf@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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_testmo= d 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 --- .../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_int1= 28.c diff --git a/tools/testing/selftests/bpf/prog_tests/tracing_failure.c b/t= ools/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."); } =20 +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/to= ols/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 #include "tracing_struct.skel.h" #include "tracing_struct_many_args.skel.h" +#include "tracing_struct_int128.skel.h" =20 static void test_struct_args(void) { @@ -112,6 +113,39 @@ static void test_struct_many_args(void) tracing_struct_many_args__destroy(skel); } =20 +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 =3D tracing_struct_int128__open_and_load(); + if (!ASSERT_OK_PTR(skel, "tracing_struct_int128__open_and_load")) + return; + + err =3D 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 +#include +#include + +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 =3D (int)ctx[0]; + t_c =3D (long)ctx[3]; + t_ret =3D (long)ctx[4]; + return 0; +} + +char _license[] SEC("license") =3D "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_testmo= d_struct_arg_1 *a) { return bpf_testmod_test_struct_arg_result; } =20 +#ifdef __SIZEOF_INT128__ +noinline __int128 +bpf_testmod_test_int128_ret(int a) +{ + bpf_testmod_test_struct_arg_result =3D a; + return (__int128)a; +} + +noinline long +bpf_testmod_test_int128_arg(int a, __int128 b, long c) +{ + bpf_testmod_test_struct_arg_result =3D 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 kobj= ect *kobj, =20 (void)bpf_testmod_test_arg_ptr_to_struct(&struct_arg1_2); =20 +#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); =20 bpf_testmod_test_struct_ops3(); --=20 2.53.0-Meta