From: Martin KaFai Lau <martin.lau@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>,
Yonghong Song <yonghong.song@linux.dev>,
Amery Hung <ameryhung@gmail.com>,
kernel-team@meta.com
Subject: [PATCH v2 bpf-next 8/8] selftests/bpf: Add kfunc call test in gen_prologue and gen_epilogue
Date: Wed, 21 Aug 2024 16:34:38 -0700 [thread overview]
Message-ID: <20240821233440.1855263-9-martin.lau@linux.dev> (raw)
In-Reply-To: <20240821233440.1855263-1-martin.lau@linux.dev>
From: Martin KaFai Lau <martin.lau@kernel.org>
This patch changes the .gen_pro/epilogue of the bpf_testmod_st_ops
to call kfunc. It will call the inc10 and inc100 kfunc.
The __xlated instructions have been adjusted accordinly.
The same goes for the __retval.
The inc100 kfunc is newly added in this patch which does
args->a += 100. Note that it is not in the register_btf_kfunc_id_set(),
so no need to declare in the bpf_testmod_kfunc.h.
It is enclosed with __bpf_kfunc_{start,end}_defs to avoid the
compiler warning.
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
---
.../selftests/bpf/bpf_testmod/bpf_testmod.c | 42 +++++++++++-
.../selftests/bpf/prog_tests/pro_epilogue.c | 4 +-
.../selftests/bpf/progs/pro_epilogue_kfunc.c | 68 ++++++++++++-------
.../bpf/progs/pro_epilogue_subprog.c | 58 ++++++++++------
4 files changed, 123 insertions(+), 49 deletions(-)
diff --git a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
index 4c75346376d9..6f745d29e124 100644
--- a/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/bpf_testmod/bpf_testmod.c
@@ -966,6 +966,16 @@ __bpf_kfunc int bpf_kfunc_st_ops_inc10(struct st_ops_args *args)
return args->a;
}
+__bpf_kfunc_start_defs();
+
+__bpf_kfunc int bpf_kfunc_st_ops_inc100(struct st_ops_args *args)
+{
+ args->a += 100;
+ return args->a;
+}
+
+__bpf_kfunc_end_defs();
+
BTF_KFUNCS_START(bpf_testmod_check_kfunc_ids)
BTF_ID_FLAGS(func, bpf_testmod_test_mod_kfunc)
BTF_ID_FLAGS(func, bpf_kfunc_call_test1)
@@ -1140,6 +1150,10 @@ static int bpf_test_mod_st_ops__test_pro_epilogue(struct st_ops_args *args)
return 0;
}
+BTF_ID_LIST(st_ops_epilogue_kfunc_list)
+BTF_ID(func, bpf_kfunc_st_ops_inc10)
+BTF_ID(func, bpf_kfunc_st_ops_inc100)
+
static int st_ops_gen_prologue(struct bpf_insn *insn_buf, bool direct_write,
const struct bpf_prog *prog, struct module **module)
{
@@ -1153,13 +1167,28 @@ static int st_ops_gen_prologue(struct bpf_insn *insn_buf, bool direct_write,
* r7 = r6->a;
* r7 += 1000;
* r6->a = r7;
+ * r7 = r1;
+ * r1 = r6;
+ * bpf_kfunc_st_ops_in10(r1)
+ * r1 = r6;
+ * bpf_kfunc_st_ops_in100(r1)
+ * r1 = r7;
*/
*insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0);
*insn++ = BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6, offsetof(struct st_ops_args, a));
*insn++ = BPF_ALU32_IMM(BPF_ADD, BPF_REG_7, 1000);
*insn++ = BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7, offsetof(struct st_ops_args, a));
+ *insn++ = BPF_MOV64_REG(BPF_REG_7, BPF_REG_1);
+ *insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
+ *insn++ = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0,
+ st_ops_epilogue_kfunc_list[0]);
+ *insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
+ *insn++ = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0,
+ st_ops_epilogue_kfunc_list[1]);
+ *insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_7);
*insn++ = prog->insnsi[0];
+ *module = THIS_MODULE;
return insn - insn_buf;
}
@@ -1177,7 +1206,10 @@ static int st_ops_gen_epilogue(struct bpf_insn *insn_buf, const struct bpf_prog
* r6 = r1->a;
* r6 += 10000;
* r1->a = r6;
- * r0 = r6;
+ * r6 = r1;
+ * bpf_kfunc_st_ops_in10(r1)
+ * r1 = r6;
+ * bpf_kfunc_st_ops_in100(r1)
* r0 *= 2;
* BPF_EXIT;
*/
@@ -1186,10 +1218,16 @@ static int st_ops_gen_epilogue(struct bpf_insn *insn_buf, const struct bpf_prog
*insn++ = BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, offsetof(struct st_ops_args, a));
*insn++ = BPF_ALU32_IMM(BPF_ADD, BPF_REG_6, 10000);
*insn++ = BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_6, offsetof(struct st_ops_args, a));
- *insn++ = BPF_MOV32_REG(BPF_REG_0, BPF_REG_6);
+ *insn++ = BPF_MOV64_REG(BPF_REG_6, BPF_REG_1);
+ *insn++ = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0,
+ st_ops_epilogue_kfunc_list[0]);
+ *insn++ = BPF_MOV64_REG(BPF_REG_1, BPF_REG_6);
+ *insn++ = BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 0,
+ st_ops_epilogue_kfunc_list[1]);
*insn++ = BPF_ALU32_IMM(BPF_MUL, BPF_REG_0, 2);
*insn++ = BPF_EXIT_INSN();
+ *module = THIS_MODULE;
return insn - insn_buf;
}
diff --git a/tools/testing/selftests/bpf/prog_tests/pro_epilogue.c b/tools/testing/selftests/bpf/prog_tests/pro_epilogue.c
index 98de677c55a9..db6e98096335 100644
--- a/tools/testing/selftests/bpf/prog_tests/pro_epilogue.c
+++ b/tools/testing/selftests/bpf/prog_tests/pro_epilogue.c
@@ -34,8 +34,8 @@ static void test_tailcall(void)
prog_fd = bpf_program__fd(skel->progs.syscall_epilogue_tailcall);
err = bpf_prog_test_run_opts(prog_fd, &topts);
ASSERT_OK(err, "bpf_prog_test_run_opts");
- ASSERT_EQ(args.a, 10001, "args.a");
- ASSERT_EQ(topts.retval, 10001 * 2, "topts.retval");
+ ASSERT_EQ(args.a, 10111, "args.a");
+ ASSERT_EQ(topts.retval, 10111 * 2, "topts.retval");
done:
epilogue_tailcall__destroy(skel);
diff --git a/tools/testing/selftests/bpf/progs/pro_epilogue_kfunc.c b/tools/testing/selftests/bpf/progs/pro_epilogue_kfunc.c
index 7d1124cf4942..2bd306f16610 100644
--- a/tools/testing/selftests/bpf/progs/pro_epilogue_kfunc.c
+++ b/tools/testing/selftests/bpf/progs/pro_epilogue_kfunc.c
@@ -28,13 +28,19 @@ __xlated("0: r6 = *(u64 *)(r1 +0)")
__xlated("1: r7 = *(u32 *)(r6 +0)")
__xlated("2: w7 += 1000")
__xlated("3: *(u32 *)(r6 +0) = r7")
-/* main prog */
-__xlated("4: r1 = *(u64 *)(r1 +0)")
-__xlated("5: r6 = r1")
+__xlated("4: r7 = r1")
+__xlated("5: r1 = r6")
__xlated("6: call kernel-function")
__xlated("7: r1 = r6")
-__xlated("8: call pc+1")
-__xlated("9: exit")
+__xlated("8: call kernel-function")
+__xlated("9: r1 = r7")
+/* main prog */
+__xlated("10: r1 = *(u64 *)(r1 +0)")
+__xlated("11: r6 = r1")
+__xlated("12: call kernel-function")
+__xlated("13: r1 = r6")
+__xlated("14: call pc+1")
+__xlated("15: exit")
SEC("struct_ops/test_prologue_kfunc")
__naked int test_prologue_kfunc(void)
{
@@ -65,9 +71,12 @@ __xlated("7: r1 = *(u64 *)(r1 +0)")
__xlated("8: r6 = *(u32 *)(r1 +0)")
__xlated("9: w6 += 10000")
__xlated("10: *(u32 *)(r1 +0) = r6")
-__xlated("11: w0 = w6")
-__xlated("12: w0 *= 2")
-__xlated("13: exit")
+__xlated("11: r6 = r1")
+__xlated("12: call kernel-function")
+__xlated("13: r1 = r6")
+__xlated("14: call kernel-function")
+__xlated("15: w0 *= 2")
+__xlated("16: exit")
SEC("struct_ops/test_epilogue_kfunc")
__naked int test_epilogue_kfunc(void)
{
@@ -89,23 +98,32 @@ __xlated("0: r6 = *(u64 *)(r1 +0)")
__xlated("1: r7 = *(u32 *)(r6 +0)")
__xlated("2: w7 += 1000")
__xlated("3: *(u32 *)(r6 +0) = r7")
+__xlated("4: r7 = r1")
+__xlated("5: r1 = r6")
+__xlated("6: call kernel-function")
+__xlated("7: r1 = r6")
+__xlated("8: call kernel-function")
+__xlated("9: r1 = r7")
/* save __u64 *ctx to stack */
-__xlated("4: *(u64 *)(r10 -8) = r1")
+__xlated("10: *(u64 *)(r10 -8) = r1")
/* main prog */
-__xlated("5: r1 = *(u64 *)(r1 +0)")
-__xlated("6: r6 = r1")
-__xlated("7: call kernel-function")
-__xlated("8: r1 = r6")
-__xlated("9: call pc+")
-/* epilogue */
-__xlated("10: r1 = *(u64 *)(r10 -8)")
__xlated("11: r1 = *(u64 *)(r1 +0)")
-__xlated("12: r6 = *(u32 *)(r1 +0)")
-__xlated("13: w6 += 10000")
-__xlated("14: *(u32 *)(r1 +0) = r6")
-__xlated("15: w0 = w6")
-__xlated("16: w0 *= 2")
-__xlated("17: exit")
+__xlated("12: r6 = r1")
+__xlated("13: call kernel-function")
+__xlated("14: r1 = r6")
+__xlated("15: call pc+")
+/* epilogue */
+__xlated("16: r1 = *(u64 *)(r10 -8)")
+__xlated("17: r1 = *(u64 *)(r1 +0)")
+__xlated("18: r6 = *(u32 *)(r1 +0)")
+__xlated("19: w6 += 10000")
+__xlated("20: *(u32 *)(r1 +0) = r6")
+__xlated("21: r6 = r1")
+__xlated("22: call kernel-function")
+__xlated("23: r1 = r6")
+__xlated("24: call kernel-function")
+__xlated("25: w0 *= 2")
+__xlated("26: exit")
SEC("struct_ops/test_pro_epilogue_kfunc")
__naked int test_pro_epilogue_kfunc(void)
{
@@ -122,7 +140,7 @@ __naked int test_pro_epilogue_kfunc(void)
}
SEC("syscall")
-__retval(1011) /* PROLOGUE_A [1000] + KFUNC_INC10 + SUBPROG_A [1] */
+__retval(1121) /* PROLOGUE_A [1110] + KFUNC_INC10 + SUBPROG_A [1] */
int syscall_prologue_kfunc(void *ctx)
{
struct st_ops_args args = {};
@@ -131,7 +149,7 @@ int syscall_prologue_kfunc(void *ctx)
}
SEC("syscall")
-__retval(20022) /* (KFUNC_INC10 + SUBPROG_A [1] + EPILOGUE_A [10000]) * 2 */
+__retval(20242) /* (KFUNC_INC10 + SUBPROG_A [1] + EPILOGUE_A [10110]) * 2 */
int syscall_epilogue_kfunc(void *ctx)
{
struct st_ops_args args = {};
@@ -140,7 +158,7 @@ int syscall_epilogue_kfunc(void *ctx)
}
SEC("syscall")
-__retval(22022) /* (PROLOGUE_A [1000] + KFUNC_INC10 + SUBPROG_A [1] + EPILOGUE_A [10000]) * 2 */
+__retval(22462) /* (PROLOGUE_A [1110] + KFUNC_INC10 + SUBPROG_A [1] + EPILOGUE_A [10110]) * 2 */
int syscall_pro_epilogue_kfunc(void *ctx)
{
struct st_ops_args args = {};
diff --git a/tools/testing/selftests/bpf/progs/pro_epilogue_subprog.c b/tools/testing/selftests/bpf/progs/pro_epilogue_subprog.c
index c91b1bf30e37..3d9cc25c024b 100644
--- a/tools/testing/selftests/bpf/progs/pro_epilogue_subprog.c
+++ b/tools/testing/selftests/bpf/progs/pro_epilogue_subprog.c
@@ -21,10 +21,16 @@ __xlated("0: r6 = *(u64 *)(r1 +0)")
__xlated("1: r7 = *(u32 *)(r6 +0)")
__xlated("2: w7 += 1000")
__xlated("3: *(u32 *)(r6 +0) = r7")
+__xlated("4: r7 = r1")
+__xlated("5: r1 = r6")
+__xlated("6: call kernel-function")
+__xlated("7: r1 = r6")
+__xlated("8: call kernel-function")
+__xlated("9: r1 = r7")
/* main prog */
-__xlated("4: r1 = *(u64 *)(r1 +0)")
-__xlated("5: call pc+1")
-__xlated("6: exit")
+__xlated("10: r1 = *(u64 *)(r1 +0)")
+__xlated("11: call pc+1")
+__xlated("12: exit")
SEC("struct_ops/test_prologue_subprog")
__naked int test_prologue_subprog(void)
{
@@ -47,9 +53,12 @@ __xlated("4: r1 = *(u64 *)(r1 +0)")
__xlated("5: r6 = *(u32 *)(r1 +0)")
__xlated("6: w6 += 10000")
__xlated("7: *(u32 *)(r1 +0) = r6")
-__xlated("8: w0 = w6")
-__xlated("9: w0 *= 2")
-__xlated("10: exit")
+__xlated("8: r6 = r1")
+__xlated("9: call kernel-function")
+__xlated("10: r1 = r6")
+__xlated("11: call kernel-function")
+__xlated("12: w0 *= 2")
+__xlated("13: exit")
SEC("struct_ops/test_epilogue_subprog")
__naked int test_epilogue_subprog(void)
{
@@ -66,20 +75,29 @@ __xlated("0: r6 = *(u64 *)(r1 +0)")
__xlated("1: r7 = *(u32 *)(r6 +0)")
__xlated("2: w7 += 1000")
__xlated("3: *(u32 *)(r6 +0) = r7")
+__xlated("4: r7 = r1")
+__xlated("5: r1 = r6")
+__xlated("6: call kernel-function")
+__xlated("7: r1 = r6")
+__xlated("8: call kernel-function")
+__xlated("9: r1 = r7")
/* save __u64 *ctx to stack */
-__xlated("4: *(u64 *)(r10 -8) = r1")
+__xlated("10: *(u64 *)(r10 -8) = r1")
/* main prog */
-__xlated("5: r1 = *(u64 *)(r1 +0)")
-__xlated("6: call pc+")
+__xlated("11: r1 = *(u64 *)(r1 +0)")
+__xlated("12: call pc+")
/* epilogue */
-__xlated("7: r1 = *(u64 *)(r10 -8)")
-__xlated("8: r1 = *(u64 *)(r1 +0)")
-__xlated("9: r6 = *(u32 *)(r1 +0)")
-__xlated("10: w6 += 10000")
-__xlated("11: *(u32 *)(r1 +0) = r6")
-__xlated("12: w0 = w6")
-__xlated("13: w0 *= 2")
-__xlated("14: exit")
+__xlated("13: r1 = *(u64 *)(r10 -8)")
+__xlated("14: r1 = *(u64 *)(r1 +0)")
+__xlated("15: r6 = *(u32 *)(r1 +0)")
+__xlated("16: w6 += 10000")
+__xlated("17: *(u32 *)(r1 +0) = r6")
+__xlated("18: r6 = r1")
+__xlated("19: call kernel-function")
+__xlated("20: r1 = r6")
+__xlated("21: call kernel-function")
+__xlated("22: w0 *= 2")
+__xlated("23: exit")
SEC("struct_ops/test_pro_epilogue_subprog")
__naked int test_pro_epilogue_subprog(void)
{
@@ -91,7 +109,7 @@ __naked int test_pro_epilogue_subprog(void)
}
SEC("syscall")
-__retval(1001) /* PROLOGUE_A [1000] + SUBPROG_A [1] */
+__retval(1111) /* PROLOGUE_A [1110] + SUBPROG_A [1] */
int syscall_prologue_subprog(void *ctx)
{
struct st_ops_args args = {};
@@ -100,7 +118,7 @@ int syscall_prologue_subprog(void *ctx)
}
SEC("syscall")
-__retval(20002) /* (SUBPROG_A [1] + EPILOGUE_A [10000]) * 2 */
+__retval(20222) /* (SUBPROG_A [1] + EPILOGUE_A [10110]) * 2 */
int syscall_epilogue_subprog(void *ctx)
{
struct st_ops_args args = {};
@@ -109,7 +127,7 @@ int syscall_epilogue_subprog(void *ctx)
}
SEC("syscall")
-__retval(22002) /* (PROLOGUE_A [1000] + SUBPROG_A [1] + EPILOGUE_A [10000]) * 2 */
+__retval(22442) /* (PROLOGUE_A [1110] + SUBPROG_A [1] + EPILOGUE_A [10110]) * 2 */
int syscall_pro_epilogue_subprog(void *ctx)
{
struct st_ops_args args = {};
--
2.43.5
prev parent reply other threads:[~2024-08-21 23:35 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-21 23:34 [PATCH v2 bpf-next 0/8] bpf: Add gen_epilogue and allow kfunc call in pro/epilogue Martin KaFai Lau
2024-08-21 23:34 ` [PATCH v2 bpf-next 1/8] bpf: Add gen_epilogue to bpf_verifier_ops Martin KaFai Lau
2024-08-22 0:22 ` Alexei Starovoitov
2024-08-22 0:30 ` Eduard Zingerman
2024-08-22 0:34 ` Alexei Starovoitov
2024-08-22 0:38 ` Eduard Zingerman
2024-08-22 0:52 ` Martin KaFai Lau
2024-08-21 23:34 ` [PATCH v2 bpf-next 2/8] bpf: Export bpf_base_func_proto Martin KaFai Lau
2024-08-21 23:34 ` [PATCH v2 bpf-next 3/8] selftests/bpf: attach struct_ops maps before test prog runs Martin KaFai Lau
2024-08-21 23:34 ` [PATCH v2 bpf-next 4/8] selftests/bpf: Test gen_prologue and gen_epilogue Martin KaFai Lau
2024-08-21 23:34 ` [PATCH v2 bpf-next 5/8] selftests/bpf: Add tailcall epilogue test Martin KaFai Lau
2024-08-21 23:34 ` [PATCH v2 bpf-next 6/8] bpf: Add module parameter to gen_prologue and gen_epilogue Martin KaFai Lau
2024-08-21 23:34 ` [PATCH v2 bpf-next 7/8] bpf: Allow pro/epilogue to call kfunc Martin KaFai Lau
2024-08-22 1:32 ` Alexei Starovoitov
2024-08-22 6:09 ` Martin KaFai Lau
2024-08-22 13:47 ` Alexei Starovoitov
2024-08-22 17:38 ` Martin KaFai Lau
2024-08-22 17:58 ` Alexei Starovoitov
2024-08-21 23:34 ` Martin KaFai Lau [this message]
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=20240821233440.1855263-9-martin.lau@linux.dev \
--to=martin.lau@linux.dev \
--cc=ameryhung@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=kernel-team@meta.com \
--cc=yonghong.song@linux.dev \
/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