@@ -996,6 +996,29 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of
996996 return ret ;
997997}
998998
999+ static int invoke_bpf (struct bpf_tramp_links * tl , int args_off , int retval_off ,
1000+ int run_ctx_off , int func_meta_off , bool save_ret , u64 func_meta ,
1001+ int cookie_off , struct rv_jit_context * ctx )
1002+ {
1003+ int i , cur_cookie = (cookie_off - args_off ) / 8 ;
1004+
1005+ for (i = 0 ; i < tl -> nr_links ; i ++ ) {
1006+ int err ;
1007+
1008+ if (bpf_prog_calls_session_cookie (tl -> links [i ])) {
1009+ u64 meta = func_meta | ((u64 )cur_cookie << BPF_TRAMP_COOKIE_INDEX_SHIFT );
1010+
1011+ emit_store_stack_imm64 (RV_REG_T1 , - func_meta_off , meta , ctx );
1012+ cur_cookie -- ;
1013+ }
1014+ err = invoke_bpf_prog (tl -> links [i ], args_off , retval_off , run_ctx_off ,
1015+ save_ret , ctx );
1016+ if (err )
1017+ return err ;
1018+ }
1019+ return 0 ;
1020+ }
1021+
9991022static int __arch_prepare_bpf_trampoline (struct bpf_tramp_image * im ,
10001023 const struct btf_func_model * m ,
10011024 struct bpf_tramp_links * tlinks ,
@@ -1005,13 +1028,15 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
10051028 int i , ret , offset ;
10061029 int * branches_off = NULL ;
10071030 int stack_size = 0 , nr_arg_slots = 0 ;
1008- int retval_off , args_off , nregs_off , ip_off , run_ctx_off , sreg_off , stk_arg_off ;
1031+ int retval_off , args_off , func_meta_off , ip_off , run_ctx_off , sreg_off , stk_arg_off ;
1032+ int cookie_off , cookie_cnt ;
10091033 struct bpf_tramp_links * fentry = & tlinks [BPF_TRAMP_FENTRY ];
10101034 struct bpf_tramp_links * fexit = & tlinks [BPF_TRAMP_FEXIT ];
10111035 struct bpf_tramp_links * fmod_ret = & tlinks [BPF_TRAMP_MODIFY_RETURN ];
10121036 bool is_struct_ops = flags & BPF_TRAMP_F_INDIRECT ;
10131037 void * orig_call = func_addr ;
10141038 bool save_ret ;
1039+ u64 func_meta ;
10151040 u32 insn ;
10161041
10171042 /* Two types of generated trampoline stack layout:
@@ -1042,10 +1067,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
10421067 * [ ... ]
10431068 * FP - args_off [ arg1 ]
10441069 *
1045- * FP - nregs_off [ regs count ]
1070+ * FP - func_meta_off [ regs count, etc ]
10461071 *
10471072 * FP - ip_off [ traced func ] BPF_TRAMP_F_IP_ARG
10481073 *
1074+ * [ stack cookie N ]
1075+ * [ ... ]
1076+ * FP - cookie_off [ stack cookie 1 ]
1077+ *
10491078 * FP - run_ctx_off [ bpf_tramp_run_ctx ]
10501079 *
10511080 * FP - sreg_off [ callee saved reg ]
@@ -1077,14 +1106,20 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
10771106 stack_size += nr_arg_slots * 8 ;
10781107 args_off = stack_size ;
10791108
1109+ /* function metadata, such as regs count */
10801110 stack_size += 8 ;
1081- nregs_off = stack_size ;
1111+ func_meta_off = stack_size ;
10821112
10831113 if (flags & BPF_TRAMP_F_IP_ARG ) {
10841114 stack_size += 8 ;
10851115 ip_off = stack_size ;
10861116 }
10871117
1118+ cookie_cnt = bpf_fsession_cookie_cnt (tlinks );
1119+ /* room for session cookies */
1120+ stack_size += cookie_cnt * 8 ;
1121+ cookie_off = stack_size ;
1122+
10881123 stack_size += round_up (sizeof (struct bpf_tramp_run_ctx ), 8 );
10891124 run_ctx_off = stack_size ;
10901125
@@ -1132,20 +1167,29 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
11321167 if (flags & BPF_TRAMP_F_IP_ARG )
11331168 emit_store_stack_imm64 (RV_REG_T1 , - ip_off , (u64 )func_addr , ctx );
11341169
1135- emit_store_stack_imm64 (RV_REG_T1 , - nregs_off , nr_arg_slots , ctx );
1170+ func_meta = nr_arg_slots ;
1171+ emit_store_stack_imm64 (RV_REG_T1 , - func_meta_off , func_meta , ctx );
11361172
11371173 store_args (nr_arg_slots , args_off , ctx );
11381174
1175+ if (bpf_fsession_cnt (tlinks )) {
1176+ /* clear all session cookies' value */
1177+ for (i = 0 ; i < cookie_cnt ; i ++ )
1178+ emit_sd (RV_REG_FP , - cookie_off + 8 * i , RV_REG_ZERO , ctx );
1179+ /* clear return value to make sure fentry always get 0 */
1180+ emit_sd (RV_REG_FP , - retval_off , RV_REG_ZERO , ctx );
1181+ }
1182+
11391183 if (flags & BPF_TRAMP_F_CALL_ORIG ) {
11401184 emit_imm (RV_REG_A0 , ctx -> insns ? (const s64 )im : RV_MAX_COUNT_IMM , ctx );
11411185 ret = emit_call ((const u64 )__bpf_tramp_enter , true, ctx );
11421186 if (ret )
11431187 return ret ;
11441188 }
11451189
1146- for ( i = 0 ; i < fentry -> nr_links ; i ++ ) {
1147- ret = invoke_bpf_prog (fentry -> links [ i ] , args_off , retval_off , run_ctx_off ,
1148- flags & BPF_TRAMP_F_RET_FENTRY_RET , ctx );
1190+ if ( fentry -> nr_links ) {
1191+ ret = invoke_bpf (fentry , args_off , retval_off , run_ctx_off , func_meta_off ,
1192+ flags & BPF_TRAMP_F_RET_FENTRY_RET , func_meta , cookie_off , ctx );
11491193 if (ret )
11501194 return ret ;
11511195 }
@@ -1192,9 +1236,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
11921236 * (u32 * )(ctx -> insns + branches_off [i ]) = insn ;
11931237 }
11941238
1195- for (i = 0 ; i < fexit -> nr_links ; i ++ ) {
1196- ret = invoke_bpf_prog (fexit -> links [i ], args_off , retval_off ,
1197- run_ctx_off , false, ctx );
1239+ /* set "is_return" flag for fsession */
1240+ func_meta |= (1ULL << BPF_TRAMP_IS_RETURN_SHIFT );
1241+ if (bpf_fsession_cnt (tlinks ))
1242+ emit_store_stack_imm64 (RV_REG_T1 , - func_meta_off , func_meta , ctx );
1243+
1244+ if (fexit -> nr_links ) {
1245+ ret = invoke_bpf (fexit , args_off , retval_off , run_ctx_off , func_meta_off ,
1246+ false, func_meta , cookie_off , ctx );
11981247 if (ret )
11991248 goto out ;
12001249 }
@@ -2094,3 +2143,8 @@ bool bpf_jit_inlines_helper_call(s32 imm)
20942143 return false;
20952144 }
20962145}
2146+
2147+ bool bpf_jit_supports_fsession (void )
2148+ {
2149+ return true;
2150+ }
0 commit comments