@@ -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;
}
@@ -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);
@@ -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 = {};
@@ -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 = {};