@@ -2510,6 +2510,12 @@ static bool is_struct_ops_tramp(const struct bpf_tramp_links *fentry_links)
25102510 fentry_links -> links [0 ]-> link .type == BPF_LINK_TYPE_STRUCT_OPS ;
25112511}
25122512
2513+ static void store_func_meta (struct jit_ctx * ctx , u64 func_meta , int func_meta_off )
2514+ {
2515+ emit_a64_mov_i64 (A64_R (10 ), func_meta , ctx );
2516+ emit (A64_STR64I (A64_R (10 ), A64_SP , func_meta_off ), ctx );
2517+ }
2518+
25132519/* Based on the x86's implementation of arch_prepare_bpf_trampoline().
25142520 *
25152521 * bpf prog and function entry before bpf trampoline hooked:
@@ -2533,7 +2539,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
25332539 int regs_off ;
25342540 int retval_off ;
25352541 int bargs_off ;
2536- int nfuncargs_off ;
2542+ int func_meta_off ;
25372543 int ip_off ;
25382544 int run_ctx_off ;
25392545 int oargs_off ;
@@ -2544,6 +2550,9 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
25442550 bool save_ret ;
25452551 __le32 * * branches = NULL ;
25462552 bool is_struct_ops = is_struct_ops_tramp (fentry );
2553+ int cookie_off , cookie_cnt , cookie_bargs_off ;
2554+ int fsession_cnt = bpf_fsession_cnt (tlinks );
2555+ u64 func_meta ;
25472556
25482557 /* trampoline stack layout:
25492558 * [ parent ip ]
@@ -2562,10 +2571,14 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
25622571 * [ ... ]
25632572 * SP + bargs_off [ arg reg 1 ] for bpf
25642573 *
2565- * SP + nfuncargs_off [ arg regs count ]
2574+ * SP + func_meta_off [ regs count, etc ]
25662575 *
25672576 * SP + ip_off [ traced function ] BPF_TRAMP_F_IP_ARG flag
25682577 *
2578+ * [ stack cookie N ]
2579+ * [ ... ]
2580+ * SP + cookie_off [ stack cookie 1 ]
2581+ *
25692582 * SP + run_ctx_off [ bpf_tramp_run_ctx ]
25702583 *
25712584 * [ stack arg N ]
@@ -2582,13 +2595,18 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
25822595 /* room for bpf_tramp_run_ctx */
25832596 stack_size += round_up (sizeof (struct bpf_tramp_run_ctx ), 8 );
25842597
2598+ cookie_off = stack_size ;
2599+ /* room for session cookies */
2600+ cookie_cnt = bpf_fsession_cookie_cnt (tlinks );
2601+ stack_size += cookie_cnt * 8 ;
2602+
25852603 ip_off = stack_size ;
25862604 /* room for IP address argument */
25872605 if (flags & BPF_TRAMP_F_IP_ARG )
25882606 stack_size += 8 ;
25892607
2590- nfuncargs_off = stack_size ;
2591- /* room for args count */
2608+ func_meta_off = stack_size ;
2609+ /* room for function metadata, such as regs count */
25922610 stack_size += 8 ;
25932611
25942612 bargs_off = stack_size ;
@@ -2646,9 +2664,9 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
26462664 emit (A64_STR64I (A64_R (10 ), A64_SP , ip_off ), ctx );
26472665 }
26482666
2649- /* save arg regs count */
2650- emit ( A64_MOVZ ( 1 , A64_R ( 10 ), nfuncargs , 0 ), ctx ) ;
2651- emit ( A64_STR64I ( A64_R ( 10 ), A64_SP , nfuncargs_off ), ctx );
2667+ /* save function metadata */
2668+ func_meta = nfuncargs ;
2669+ store_func_meta ( ctx , func_meta , func_meta_off );
26522670
26532671 /* save args for bpf */
26542672 save_args (ctx , bargs_off , oargs_off , m , a , false);
@@ -2666,10 +2684,27 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
26662684 emit_call ((const u64 )__bpf_tramp_enter , ctx );
26672685 }
26682686
2669- for (i = 0 ; i < fentry -> nr_links ; i ++ )
2687+ if (fsession_cnt ) {
2688+ /* clear all the session cookies' value */
2689+ emit (A64_MOVZ (1 , A64_R (10 ), 0 , 0 ), ctx );
2690+ for (int i = 0 ; i < cookie_cnt ; i ++ )
2691+ emit (A64_STR64I (A64_R (10 ), A64_SP , cookie_off + 8 * i ), ctx );
2692+ /* clear the return value to make sure fentry always gets 0 */
2693+ emit (A64_STR64I (A64_R (10 ), A64_SP , retval_off ), ctx );
2694+ }
2695+
2696+ cookie_bargs_off = (bargs_off - cookie_off ) / 8 ;
2697+ for (i = 0 ; i < fentry -> nr_links ; i ++ ) {
2698+ if (bpf_prog_calls_session_cookie (fentry -> links [i ])) {
2699+ u64 meta = func_meta | (cookie_bargs_off << BPF_TRAMP_COOKIE_INDEX_SHIFT );
2700+
2701+ store_func_meta (ctx , meta , func_meta_off );
2702+ cookie_bargs_off -- ;
2703+ }
26702704 invoke_bpf_prog (ctx , fentry -> links [i ], bargs_off ,
26712705 retval_off , run_ctx_off ,
26722706 flags & BPF_TRAMP_F_RET_FENTRY_RET );
2707+ }
26732708
26742709 if (fmod_ret -> nr_links ) {
26752710 branches = kcalloc (fmod_ret -> nr_links , sizeof (__le32 * ),
@@ -2701,9 +2736,22 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
27012736 * branches [i ] = cpu_to_le32 (A64_CBNZ (1 , A64_R (10 ), offset ));
27022737 }
27032738
2704- for (i = 0 ; i < fexit -> nr_links ; i ++ )
2739+ /* set the "is_return" flag for fsession */
2740+ func_meta |= (1ULL << BPF_TRAMP_IS_RETURN_SHIFT );
2741+ if (fsession_cnt )
2742+ store_func_meta (ctx , func_meta , func_meta_off );
2743+
2744+ cookie_bargs_off = (bargs_off - cookie_off ) / 8 ;
2745+ for (i = 0 ; i < fexit -> nr_links ; i ++ ) {
2746+ if (bpf_prog_calls_session_cookie (fexit -> links [i ])) {
2747+ u64 meta = func_meta | (cookie_bargs_off << BPF_TRAMP_COOKIE_INDEX_SHIFT );
2748+
2749+ store_func_meta (ctx , meta , func_meta_off );
2750+ cookie_bargs_off -- ;
2751+ }
27052752 invoke_bpf_prog (ctx , fexit -> links [i ], bargs_off , retval_off ,
27062753 run_ctx_off , false);
2754+ }
27072755
27082756 if (flags & BPF_TRAMP_F_CALL_ORIG ) {
27092757 im -> ip_epilogue = ctx -> ro_image + ctx -> idx ;
@@ -2753,6 +2801,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
27532801 return ctx -> idx ;
27542802}
27552803
2804+ bool bpf_jit_supports_fsession (void )
2805+ {
2806+ return true;
2807+ }
2808+
27562809int arch_bpf_trampoline_size (const struct btf_func_model * m , u32 flags ,
27572810 struct bpf_tramp_links * tlinks , void * func_addr )
27582811{
0 commit comments