@@ -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+
543548bool 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 */
0 commit comments