[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20260119-skb-meta-bpf-emit-call-from-prologue-v1-4-e8b88d6430d8@cloudflare.com>
Date: Mon, 19 Jan 2026 20:53:54 +0100
From: Jakub Sitnicki <jakub@...udflare.com>
To: bpf@...r.kernel.org
Cc: Alexei Starovoitov <ast@...nel.org>,
Daniel Borkmann <daniel@...earbox.net>,
John Fastabend <john.fastabend@...il.com>,
Andrii Nakryiko <andrii@...nel.org>,
Martin KaFai Lau <martin.lau@...ux.dev>,
Eduard Zingerman <eddyz87@...il.com>, Song Liu <song@...nel.org>,
Yonghong Song <yonghong.song@...ux.dev>, KP Singh <kpsingh@...nel.org>,
Stanislav Fomichev <sdf@...ichev.me>, Hao Luo <haoluo@...gle.com>,
Jiri Olsa <jolsa@...nel.org>, Amery Hung <ameryhung@...il.com>,
netdev@...r.kernel.org, kernel-team@...udflare.com
Subject: [PATCH bpf-next 4/4] selftests/bpf: Remove tests for
prologue/epilogue with kfuncs
Remove pro_epilogue_with_kfunc test program and its supporting code in
bpf_testmod. This test exercised calling kfuncs from prologue and epilogue,
which is no longer supported after the switch to direct helper calls.
Signed-off-by: Jakub Sitnicki <jakub@...udflare.com>
---
.../selftests/bpf/prog_tests/pro_epilogue.c | 2 -
.../selftests/bpf/progs/pro_epilogue_with_kfunc.c | 88 ---------------------
.../testing/selftests/bpf/test_kmods/bpf_testmod.c | 92 ----------------------
3 files changed, 182 deletions(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/pro_epilogue.c b/tools/testing/selftests/bpf/prog_tests/pro_epilogue.c
index 5d3c00a08a88..509883e6823a 100644
--- a/tools/testing/selftests/bpf/prog_tests/pro_epilogue.c
+++ b/tools/testing/selftests/bpf/prog_tests/pro_epilogue.c
@@ -6,7 +6,6 @@
#include "epilogue_tailcall.skel.h"
#include "pro_epilogue_goto_start.skel.h"
#include "epilogue_exit.skel.h"
-#include "pro_epilogue_with_kfunc.skel.h"
struct st_ops_args {
__u64 a;
@@ -56,7 +55,6 @@ void test_pro_epilogue(void)
RUN_TESTS(pro_epilogue);
RUN_TESTS(pro_epilogue_goto_start);
RUN_TESTS(epilogue_exit);
- RUN_TESTS(pro_epilogue_with_kfunc);
if (test__start_subtest("tailcall"))
test_tailcall();
}
diff --git a/tools/testing/selftests/bpf/progs/pro_epilogue_with_kfunc.c b/tools/testing/selftests/bpf/progs/pro_epilogue_with_kfunc.c
deleted file mode 100644
index a5a8f08ac8fb..000000000000
--- a/tools/testing/selftests/bpf/progs/pro_epilogue_with_kfunc.c
+++ /dev/null
@@ -1,88 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
-
-#include <vmlinux.h>
-#include <bpf/bpf_tracing.h>
-#include "bpf_misc.h"
-#include "../test_kmods/bpf_testmod.h"
-#include "../test_kmods/bpf_testmod_kfunc.h"
-
-char _license[] SEC("license") = "GPL";
-
-void __kfunc_btf_root(void)
-{
- bpf_kfunc_st_ops_inc10(NULL);
-}
-
-static __noinline __used int subprog(struct st_ops_args *args)
-{
- args->a += 1;
- return args->a;
-}
-
-__success
-/* prologue */
-__xlated("0: r8 = r1")
-__xlated("1: r1 = 0")
-__xlated("2: call kernel-function")
-__xlated("3: if r0 != 0x0 goto pc+5")
-__xlated("4: r6 = *(u64 *)(r8 +0)")
-__xlated("5: r7 = *(u64 *)(r6 +0)")
-__xlated("6: r7 += 1000")
-__xlated("7: *(u64 *)(r6 +0) = r7")
-__xlated("8: goto pc+2")
-__xlated("9: r1 = r0")
-__xlated("10: call kernel-function")
-__xlated("11: r1 = r8")
-/* save __u64 *ctx to stack */
-__xlated("12: *(u64 *)(r10 -8) = r1")
-/* main prog */
-__xlated("13: r1 = *(u64 *)(r1 +0)")
-__xlated("14: r6 = r1")
-__xlated("15: call kernel-function")
-__xlated("16: r1 = r6")
-__xlated("17: call pc+")
-/* epilogue */
-__xlated("18: r1 = 0")
-__xlated("19: r6 = 0")
-__xlated("20: call kernel-function")
-__xlated("21: if r0 != 0x0 goto pc+6")
-__xlated("22: r1 = *(u64 *)(r10 -8)")
-__xlated("23: r1 = *(u64 *)(r1 +0)")
-__xlated("24: r6 = *(u64 *)(r1 +0)")
-__xlated("25: r6 += 10000")
-__xlated("26: *(u64 *)(r1 +0) = r6")
-__xlated("27: goto pc+2")
-__xlated("28: r1 = r0")
-__xlated("29: call kernel-function")
-__xlated("30: r0 = r6")
-__xlated("31: r0 *= 2")
-__xlated("32: exit")
-SEC("struct_ops/test_pro_epilogue")
-__naked int test_kfunc_pro_epilogue(void)
-{
- asm volatile (
- "r1 = *(u64 *)(r1 +0);"
- "r6 = r1;"
- "call %[bpf_kfunc_st_ops_inc10];"
- "r1 = r6;"
- "call subprog;"
- "exit;"
- :
- : __imm(bpf_kfunc_st_ops_inc10)
- : __clobber_all);
-}
-
-SEC("syscall")
-__retval(22022) /* (PROLOGUE_A [1000] + KFUNC_INC10 + SUBPROG_A [1] + EPILOGUE_A [10000]) * 2 */
-int syscall_pro_epilogue(void *ctx)
-{
- struct st_ops_args args = {};
-
- return bpf_kfunc_st_ops_test_pro_epilogue(&args);
-}
-
-SEC(".struct_ops.link")
-struct bpf_testmod_st_ops pro_epilogue_with_kfunc = {
- .test_pro_epilogue = (void *)test_kfunc_pro_epilogue,
-};
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
index bc07ce9d5477..1a5c163455de 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
@@ -1400,85 +1400,6 @@ static int bpf_test_mod_st_ops__test_pro_epilogue(struct st_ops_args *args)
return 0;
}
-static int bpf_cgroup_from_id_id;
-static int bpf_cgroup_release_id;
-
-static int st_ops_gen_prologue_with_kfunc(struct bpf_insn *insn_buf, bool direct_write,
- const struct bpf_prog *prog)
-{
- struct bpf_insn *insn = insn_buf;
-
- /* r8 = r1; // r8 will be "u64 *ctx".
- * r1 = 0;
- * r0 = bpf_cgroup_from_id(r1);
- * if r0 != 0 goto pc+5;
- * r6 = r8[0]; // r6 will be "struct st_ops *args".
- * r7 = r6->a;
- * r7 += 1000;
- * r6->a = r7;
- * goto pc+2;
- * r1 = r0;
- * bpf_cgroup_release(r1);
- * r1 = r8;
- */
- *insn++ = BPF_MOV64_REG(BPF_REG_8, BPF_REG_1);
- *insn++ = BPF_MOV64_IMM(BPF_REG_1, 0);
- *insn++ = BPF_CALL_KFUNC(0, bpf_cgroup_from_id_id);
- *insn++ = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 5);
- *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_8, 0);
- *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_7, BPF_REG_6, offsetof(struct st_ops_args, a));
- *insn++ = BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, 1000);
- *insn++ = BPF_STX_MEM(BPF_DW, BPF_REG_6, BPF_REG_7, offsetof(struct st_ops_args, a));
- *insn++ = BPF_JMP_IMM(BPF_JA, 0, 0, 2);
- *insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_0);
- *insn++ = BPF_CALL_KFUNC(0, bpf_cgroup_release_id);
- *insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_8);
- *insn++ = prog->insnsi[0];
-
- return insn - insn_buf;
-}
-
-static int st_ops_gen_epilogue_with_kfunc(struct bpf_insn *insn_buf, const struct bpf_prog *prog,
- s16 ctx_stack_off)
-{
- struct bpf_insn *insn = insn_buf;
-
- /* r1 = 0;
- * r6 = 0;
- * r0 = bpf_cgroup_from_id(r1);
- * if r0 != 0 goto pc+6;
- * r1 = stack[ctx_stack_off]; // r1 will be "u64 *ctx"
- * r1 = r1[0]; // r1 will be "struct st_ops *args"
- * r6 = r1->a;
- * r6 += 10000;
- * r1->a = r6;
- * goto pc+2
- * r1 = r0;
- * bpf_cgroup_release(r1);
- * r0 = r6;
- * r0 *= 2;
- * BPF_EXIT;
- */
- *insn++ = BPF_MOV64_IMM(BPF_REG_1, 0);
- *insn++ = BPF_MOV64_IMM(BPF_REG_6, 0);
- *insn++ = BPF_CALL_KFUNC(0, bpf_cgroup_from_id_id);
- *insn++ = BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 6);
- *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_FP, ctx_stack_off);
- *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0);
- *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, offsetof(struct st_ops_args, a));
- *insn++ = BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, 10000);
- *insn++ = BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_6, offsetof(struct st_ops_args, a));
- *insn++ = BPF_JMP_IMM(BPF_JA, 0, 0, 2);
- *insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_0);
- *insn++ = BPF_CALL_KFUNC(0, bpf_cgroup_release_id);
- *insn++ = BPF_MOV64_REG(BPF_REG_0, BPF_REG_6);
- *insn++ = BPF_ALU64_IMM(BPF_MUL, BPF_REG_0, 2);
- *insn++ = BPF_EXIT_INSN();
-
- return insn - insn_buf;
-}
-
-#define KFUNC_PRO_EPI_PREFIX "test_kfunc_"
static int st_ops_gen_prologue(struct bpf_insn *insn_buf, bool direct_write,
const struct bpf_prog *prog)
{
@@ -1488,9 +1409,6 @@ static int st_ops_gen_prologue(struct bpf_insn *insn_buf, bool direct_write,
strcmp(prog->aux->attach_func_name, "test_pro_epilogue"))
return 0;
- if (!strncmp(prog->aux->name, KFUNC_PRO_EPI_PREFIX, strlen(KFUNC_PRO_EPI_PREFIX)))
- return st_ops_gen_prologue_with_kfunc(insn_buf, direct_write, prog);
-
/* r6 = r1[0]; // r6 will be "struct st_ops *args". r1 is "u64 *ctx".
* r7 = r6->a;
* r7 += 1000;
@@ -1514,9 +1432,6 @@ static int st_ops_gen_epilogue(struct bpf_insn *insn_buf, const struct bpf_prog
strcmp(prog->aux->attach_func_name, "test_pro_epilogue"))
return 0;
- if (!strncmp(prog->aux->name, KFUNC_PRO_EPI_PREFIX, strlen(KFUNC_PRO_EPI_PREFIX)))
- return st_ops_gen_epilogue_with_kfunc(insn_buf, prog, ctx_stack_off);
-
/* r1 = stack[ctx_stack_off]; // r1 will be "u64 *ctx"
* r1 = r1[0]; // r1 will be "struct st_ops *args"
* r6 = r1->a;
@@ -1587,13 +1502,6 @@ static void st_ops_unreg(void *kdata, struct bpf_link *link)
static int st_ops_init(struct btf *btf)
{
- struct btf *kfunc_btf;
-
- bpf_cgroup_from_id_id = bpf_find_btf_id("bpf_cgroup_from_id", BTF_KIND_FUNC, &kfunc_btf);
- bpf_cgroup_release_id = bpf_find_btf_id("bpf_cgroup_release", BTF_KIND_FUNC, &kfunc_btf);
- if (bpf_cgroup_from_id_id < 0 || bpf_cgroup_release_id < 0)
- return -EINVAL;
-
return 0;
}
--
2.43.0
Powered by blists - more mailing lists