@@ -926,19 +926,25 @@ static void restore_stack_args(int nr_stack_args, int args_off, int stk_arg_off,
926926 }
927927}
928928
929+ static void emit_store_stack_imm64 (u8 reg , int stack_off , u64 imm64 ,
930+ struct rv_jit_context * ctx )
931+ {
932+ /* Load imm64 into reg and store it at [FP + stack_off]. */
933+ emit_imm (reg , (s64 )imm64 , ctx );
934+ emit_sd (RV_REG_FP , stack_off , reg , ctx );
935+ }
936+
929937static int invoke_bpf_prog (struct bpf_tramp_link * l , int args_off , int retval_off ,
930938 int run_ctx_off , bool save_ret , struct rv_jit_context * ctx )
931939{
932940 int ret , branch_off ;
933941 struct bpf_prog * p = l -> link .prog ;
934942 int cookie_off = offsetof(struct bpf_tramp_run_ctx , bpf_cookie );
935943
936- if (l -> cookie ) {
937- emit_imm (RV_REG_T1 , l -> cookie , ctx );
938- emit_sd (RV_REG_FP , - run_ctx_off + cookie_off , RV_REG_T1 , ctx );
939- } else {
944+ if (l -> cookie )
945+ emit_store_stack_imm64 (RV_REG_T1 , - run_ctx_off + cookie_off , l -> cookie , ctx );
946+ else
940947 emit_sd (RV_REG_FP , - run_ctx_off + cookie_off , RV_REG_ZERO , ctx );
941- }
942948
943949 /* arg1: prog */
944950 emit_imm (RV_REG_A0 , (const s64 )p , ctx );
@@ -990,6 +996,29 @@ static int invoke_bpf_prog(struct bpf_tramp_link *l, int args_off, int retval_of
990996 return ret ;
991997}
992998
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+
9931022static int __arch_prepare_bpf_trampoline (struct bpf_tramp_image * im ,
9941023 const struct btf_func_model * m ,
9951024 struct bpf_tramp_links * tlinks ,
@@ -999,13 +1028,15 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
9991028 int i , ret , offset ;
10001029 int * branches_off = NULL ;
10011030 int stack_size = 0 , nr_arg_slots = 0 ;
1002- 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 ;
10031033 struct bpf_tramp_links * fentry = & tlinks [BPF_TRAMP_FENTRY ];
10041034 struct bpf_tramp_links * fexit = & tlinks [BPF_TRAMP_FEXIT ];
10051035 struct bpf_tramp_links * fmod_ret = & tlinks [BPF_TRAMP_MODIFY_RETURN ];
10061036 bool is_struct_ops = flags & BPF_TRAMP_F_INDIRECT ;
10071037 void * orig_call = func_addr ;
10081038 bool save_ret ;
1039+ u64 func_meta ;
10091040 u32 insn ;
10101041
10111042 /* Two types of generated trampoline stack layout:
@@ -1036,10 +1067,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
10361067 * [ ... ]
10371068 * FP - args_off [ arg1 ]
10381069 *
1039- * FP - nregs_off [ regs count ]
1070+ * FP - func_meta_off [ regs count, etc ]
10401071 *
10411072 * FP - ip_off [ traced func ] BPF_TRAMP_F_IP_ARG
10421073 *
1074+ * [ stack cookie N ]
1075+ * [ ... ]
1076+ * FP - cookie_off [ stack cookie 1 ]
1077+ *
10431078 * FP - run_ctx_off [ bpf_tramp_run_ctx ]
10441079 *
10451080 * FP - sreg_off [ callee saved reg ]
@@ -1071,14 +1106,20 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
10711106 stack_size += nr_arg_slots * 8 ;
10721107 args_off = stack_size ;
10731108
1109+ /* function metadata, such as regs count */
10741110 stack_size += 8 ;
1075- nregs_off = stack_size ;
1111+ func_meta_off = stack_size ;
10761112
10771113 if (flags & BPF_TRAMP_F_IP_ARG ) {
10781114 stack_size += 8 ;
10791115 ip_off = stack_size ;
10801116 }
10811117
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+
10821123 stack_size += round_up (sizeof (struct bpf_tramp_run_ctx ), 8 );
10831124 run_ctx_off = stack_size ;
10841125
@@ -1123,26 +1164,32 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
11231164 emit_sd (RV_REG_FP , - sreg_off , RV_REG_S1 , ctx );
11241165
11251166 /* store ip address of the traced function */
1126- if (flags & BPF_TRAMP_F_IP_ARG ) {
1127- emit_imm (RV_REG_T1 , (const s64 )func_addr , ctx );
1128- emit_sd (RV_REG_FP , - ip_off , RV_REG_T1 , ctx );
1129- }
1167+ if (flags & BPF_TRAMP_F_IP_ARG )
1168+ emit_store_stack_imm64 (RV_REG_T1 , - ip_off , (u64 )func_addr , ctx );
11301169
1131- emit_li ( RV_REG_T1 , nr_arg_slots , ctx ) ;
1132- emit_sd ( RV_REG_FP , - nregs_off , RV_REG_T1 , ctx );
1170+ func_meta = nr_arg_slots ;
1171+ emit_store_stack_imm64 ( RV_REG_T1 , - func_meta_off , func_meta , ctx );
11331172
11341173 store_args (nr_arg_slots , args_off , ctx );
11351174
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+
11361183 if (flags & BPF_TRAMP_F_CALL_ORIG ) {
11371184 emit_imm (RV_REG_A0 , ctx -> insns ? (const s64 )im : RV_MAX_COUNT_IMM , ctx );
11381185 ret = emit_call ((const u64 )__bpf_tramp_enter , true, ctx );
11391186 if (ret )
11401187 return ret ;
11411188 }
11421189
1143- for ( i = 0 ; i < fentry -> nr_links ; i ++ ) {
1144- ret = invoke_bpf_prog (fentry -> links [ i ] , args_off , retval_off , run_ctx_off ,
1145- 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 );
11461193 if (ret )
11471194 return ret ;
11481195 }
@@ -1189,9 +1236,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
11891236 * (u32 * )(ctx -> insns + branches_off [i ]) = insn ;
11901237 }
11911238
1192- for (i = 0 ; i < fexit -> nr_links ; i ++ ) {
1193- ret = invoke_bpf_prog (fexit -> links [i ], args_off , retval_off ,
1194- 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 );
11951247 if (ret )
11961248 goto out ;
11971249 }
@@ -2091,3 +2143,8 @@ bool bpf_jit_inlines_helper_call(s32 imm)
20912143 return false;
20922144 }
20932145}
2146+
2147+ bool bpf_jit_supports_fsession (void )
2148+ {
2149+ return true;
2150+ }
0 commit comments