Skip to content

Commit 6fab063

Browse files
Abhishek Dubeymaddy-kerneldev
authored andcommitted
powerpc64/bpf: Implement fsession support
Implement JIT support for fsession in powerpc64 trampoline. The trampoline stack now accommodate session cookies and function metadata in place of function argument. fentry/fexit programs consume corresponding function metadata. This mirrors existing x86 behavior and enable session cookies on powerpc64. # ./test_progs -t fsession #135/1 fsession_test/fsession_test:OK #135/2 fsession_test/fsession_reattach:OK #135/3 fsession_test/fsession_cookie:OK #135 fsession_test:OK Summary: 1/3 PASSED, 0 SKIPPED, 0 FAILED Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com> Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com> Acked-by: Hari Bathini <hbathini@linux.ibm.com> Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com> Link: https://patch.msgid.link/20260401141043.41513-1-adubey@linux.ibm.com
1 parent e640bcd commit 6fab063

3 files changed

Lines changed: 87 additions & 11 deletions

File tree

arch/powerpc/net/bpf_jit.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,9 @@ void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx);
218218
void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx);
219219
void bpf_jit_realloc_regs(struct codegen_context *ctx);
220220
int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr);
221-
221+
void prepare_for_fsession_fentry(u32 *image, struct codegen_context *ctx, int cookie_cnt,
222+
int cookie_off, int retval_off);
223+
void store_func_meta(u32 *image, struct codegen_context *ctx, u64 func_meta, int func_meta_off);
222224
int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass,
223225
struct codegen_context *ctx, int insn_idx,
224226
int jmp_off, int dst_reg, u32 code);

arch/powerpc/net/bpf_jit_comp.c

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,11 @@ bool bpf_jit_supports_private_stack(void)
540540
return IS_ENABLED(CONFIG_PPC64);
541541
}
542542

543+
bool bpf_jit_supports_fsession(void)
544+
{
545+
return IS_ENABLED(CONFIG_PPC64);
546+
}
547+
543548
bool bpf_jit_supports_arena(void)
544549
{
545550
return IS_ENABLED(CONFIG_PPC64);
@@ -812,12 +817,16 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
812817
struct bpf_tramp_links *tlinks,
813818
void *func_addr)
814819
{
815-
int regs_off, nregs_off, ip_off, run_ctx_off, retval_off, nvr_off, alt_lr_off, r4_off = 0;
820+
int regs_off, func_meta_off, ip_off, run_ctx_off, retval_off;
821+
int nvr_off, alt_lr_off, r4_off = 0;
816822
struct bpf_tramp_links *fmod_ret = &tlinks[BPF_TRAMP_MODIFY_RETURN];
817823
struct bpf_tramp_links *fentry = &tlinks[BPF_TRAMP_FENTRY];
818824
struct bpf_tramp_links *fexit = &tlinks[BPF_TRAMP_FEXIT];
819825
int i, ret, nr_regs, retaddr_off, bpf_frame_size = 0;
820826
struct codegen_context codegen_ctx, *ctx;
827+
int cookie_off, cookie_cnt, cookie_ctx_off;
828+
int fsession_cnt = bpf_fsession_cnt(tlinks);
829+
u64 func_meta;
821830
u32 *image = (u32 *)rw_image;
822831
ppc_inst_t branch_insn;
823832
u32 *branches = NULL;
@@ -853,9 +862,11 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
853862
* [ reg argN ]
854863
* [ ... ]
855864
* regs_off [ reg_arg1 ] prog_ctx
856-
* nregs_off [ args count ] ((u64 *)prog_ctx)[-1]
865+
* func_meta_off [ args count ] ((u64 *)prog_ctx)[-1]
857866
* ip_off [ traced function ] ((u64 *)prog_ctx)[-2]
867+
* [ stack cookieN ]
858868
* [ ... ]
869+
* cookie_off [ stack cookie1 ]
859870
* run_ctx_off [ bpf_tramp_run_ctx ]
860871
* [ reg argN ]
861872
* [ ... ]
@@ -887,16 +898,21 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
887898
run_ctx_off = bpf_frame_size;
888899
bpf_frame_size += round_up(sizeof(struct bpf_tramp_run_ctx), SZL);
889900

901+
/* room for session cookies */
902+
cookie_off = bpf_frame_size;
903+
cookie_cnt = bpf_fsession_cookie_cnt(tlinks);
904+
bpf_frame_size += cookie_cnt * 8;
905+
890906
/* Room for IP address argument */
891907
ip_off = bpf_frame_size;
892908
if (flags & BPF_TRAMP_F_IP_ARG)
893909
bpf_frame_size += SZL;
894910

895-
/* Room for args count */
896-
nregs_off = bpf_frame_size;
911+
/* Room for function metadata, arg regs count */
912+
func_meta_off = bpf_frame_size;
897913
bpf_frame_size += SZL;
898914

899-
/* Room for args */
915+
/* Room for arg regs */
900916
regs_off = bpf_frame_size;
901917
bpf_frame_size += nr_regs * SZL;
902918

@@ -995,9 +1011,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
9951011
EMIT(PPC_RAW_STL(_R3, _R1, retaddr_off));
9961012
}
9971013

998-
/* Save function arg count -- see bpf_get_func_arg_cnt() */
999-
EMIT(PPC_RAW_LI(_R3, nr_regs));
1000-
EMIT(PPC_RAW_STL(_R3, _R1, nregs_off));
1014+
/* Save function arg regs count -- see bpf_get_func_arg_cnt() */
1015+
func_meta = nr_regs;
1016+
store_func_meta(image, ctx, func_meta, func_meta_off);
10011017

10021018
/* Save nv regs */
10031019
EMIT(PPC_RAW_STL(_R25, _R1, nvr_off));
@@ -1011,10 +1027,28 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
10111027
return ret;
10121028
}
10131029

1014-
for (i = 0; i < fentry->nr_links; i++)
1030+
if (fsession_cnt) {
1031+
/*
1032+
* Clear all the session cookies' values
1033+
* Clear the return value to make sure fentry always get 0
1034+
*/
1035+
prepare_for_fsession_fentry(image, ctx, cookie_cnt, cookie_off, retval_off);
1036+
}
1037+
1038+
cookie_ctx_off = (regs_off - cookie_off) / 8;
1039+
1040+
for (i = 0; i < fentry->nr_links; i++) {
1041+
if (bpf_prog_calls_session_cookie(fentry->links[i])) {
1042+
u64 meta = func_meta | (cookie_ctx_off << BPF_TRAMP_COOKIE_INDEX_SHIFT);
1043+
1044+
store_func_meta(image, ctx, meta, func_meta_off);
1045+
cookie_ctx_off--;
1046+
}
1047+
10151048
if (invoke_bpf_prog(image, ro_image, ctx, fentry->links[i], regs_off, retval_off,
10161049
run_ctx_off, flags & BPF_TRAMP_F_RET_FENTRY_RET))
10171050
return -EINVAL;
1051+
}
10181052

10191053
if (fmod_ret->nr_links) {
10201054
branches = kcalloc(fmod_ret->nr_links, sizeof(u32), GFP_KERNEL);
@@ -1076,12 +1110,27 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
10761110
image[branches[i]] = ppc_inst_val(branch_insn);
10771111
}
10781112

1079-
for (i = 0; i < fexit->nr_links; i++)
1113+
/* set the "is_return" flag for fsession */
1114+
func_meta |= (1ULL << BPF_TRAMP_IS_RETURN_SHIFT);
1115+
if (fsession_cnt)
1116+
store_func_meta(image, ctx, func_meta, func_meta_off);
1117+
1118+
cookie_ctx_off = (regs_off - cookie_off) / 8;
1119+
1120+
for (i = 0; i < fexit->nr_links; i++) {
1121+
if (bpf_prog_calls_session_cookie(fexit->links[i])) {
1122+
u64 meta = func_meta | (cookie_ctx_off << BPF_TRAMP_COOKIE_INDEX_SHIFT);
1123+
1124+
store_func_meta(image, ctx, meta, func_meta_off);
1125+
cookie_ctx_off--;
1126+
}
1127+
10801128
if (invoke_bpf_prog(image, ro_image, ctx, fexit->links[i], regs_off, retval_off,
10811129
run_ctx_off, false)) {
10821130
ret = -EINVAL;
10831131
goto cleanup;
10841132
}
1133+
}
10851134

10861135
if (flags & BPF_TRAMP_F_CALL_ORIG) {
10871136
if (ro_image) /* image is NULL for dummy pass */

arch/powerpc/net/bpf_jit_comp64.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,31 @@ static int bpf_jit_stack_offsetof(struct codegen_context *ctx, int reg)
179179
BUG();
180180
}
181181

182+
void prepare_for_fsession_fentry(u32 *image, struct codegen_context *ctx, int cookie_cnt,
183+
int cookie_off, int retval_off)
184+
{
185+
EMIT(PPC_RAW_LI(bpf_to_ppc(TMP_REG_1), 0));
186+
187+
for (int i = 0; i < cookie_cnt; i++)
188+
EMIT(PPC_RAW_STD(bpf_to_ppc(TMP_REG_1), _R1, cookie_off + 8 * i));
189+
EMIT(PPC_RAW_STD(bpf_to_ppc(TMP_REG_1), _R1, retval_off));
190+
}
191+
192+
void store_func_meta(u32 *image, struct codegen_context *ctx,
193+
u64 func_meta, int func_meta_off)
194+
{
195+
/*
196+
* Store func_meta to stack at [R1 + func_meta_off] = func_meta
197+
*
198+
* func_meta :
199+
* bit[63]: is_return flag
200+
* byte[1]: cookie offset from ctx
201+
* byte[0]: args count
202+
*/
203+
PPC_LI64(bpf_to_ppc(TMP_REG_1), func_meta);
204+
EMIT(PPC_RAW_STD(bpf_to_ppc(TMP_REG_1), _R1, func_meta_off));
205+
}
206+
182207
void bpf_jit_realloc_regs(struct codegen_context *ctx)
183208
{
184209
}

0 commit comments

Comments
 (0)