@@ -206,6 +206,9 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
206206 cgctx .stack_size = round_up (fp -> aux -> stack_depth , 16 );
207207 cgctx .arena_vm_start = bpf_arena_get_kern_vm_start (fp -> aux -> arena );
208208 cgctx .user_vm_start = bpf_arena_get_user_vm_start (fp -> aux -> arena );
209+ cgctx .is_subprog = bpf_is_subprog (fp );
210+ cgctx .exception_boundary = fp -> aux -> exception_boundary ;
211+ cgctx .exception_cb = fp -> aux -> exception_cb ;
209212
210213 /* Scouting faux-generate pass 0 */
211214 if (bpf_jit_build_body (fp , NULL , NULL , & cgctx , addrs , 0 , false)) {
@@ -435,6 +438,16 @@ void bpf_jit_free(struct bpf_prog *fp)
435438 bpf_prog_unlock_free (fp );
436439}
437440
441+ bool bpf_jit_supports_exceptions (void )
442+ {
443+ return IS_ENABLED (CONFIG_PPC64 );
444+ }
445+
446+ bool bpf_jit_supports_subprog_tailcalls (void )
447+ {
448+ return IS_ENABLED (CONFIG_PPC64 );
449+ }
450+
438451bool bpf_jit_supports_kfunc_call (void )
439452{
440453 return true;
@@ -617,15 +630,50 @@ static int invoke_bpf_mod_ret(u32 *image, u32 *ro_image, struct codegen_context
617630 return 0 ;
618631}
619632
620- static void bpf_trampoline_setup_tail_call_cnt (u32 * image , struct codegen_context * ctx ,
621- int func_frame_offset , int r4_off )
633+ /*
634+ * Refer __arch_prepare_bpf_trampoline() for stack component details.
635+ *
636+ * The tailcall count/reference is present in caller's stack frame. The
637+ * tail_call_info is saved at the same offset on the trampoline frame
638+ * for the traced function (BPF subprog/callee) to fetch it.
639+ */
640+ static void bpf_trampoline_setup_tail_call_info (u32 * image , struct codegen_context * ctx ,
641+ int func_frame_offset ,
642+ int bpf_dummy_frame_size , int r4_off )
622643{
623644 if (IS_ENABLED (CONFIG_PPC64 )) {
624- /* See bpf_jit_stack_tailcallcnt() */
625- int tailcallcnt_offset = 7 * 8 ;
645+ /* See Generated stack layout */
646+ int tailcallinfo_offset = BPF_PPC_TAILCALL ;
647+
648+ /*
649+ * func_frame_offset = ...(1)
650+ * bpf_dummy_frame_size + trampoline_frame_size
651+ */
652+ EMIT (PPC_RAW_LD (_R4 , _R1 , func_frame_offset ));
653+ EMIT (PPC_RAW_LD (_R3 , _R4 , - tailcallinfo_offset ));
626654
627- EMIT (PPC_RAW_LL (_R3 , _R1 , func_frame_offset - tailcallcnt_offset ));
628- EMIT (PPC_RAW_STL (_R3 , _R1 , - tailcallcnt_offset ));
655+ /*
656+ * Setting the tail_call_info in trampoline's frame
657+ * depending on if previous frame had value or reference.
658+ */
659+ EMIT (PPC_RAW_CMPLWI (_R3 , MAX_TAIL_CALL_CNT ));
660+ PPC_BCC_CONST_SHORT (COND_GT , 8 );
661+ EMIT (PPC_RAW_ADDI (_R3 , _R4 , bpf_jit_stack_tailcallinfo_offset (ctx )));
662+ /*
663+ * From ...(1) above:
664+ * trampoline_frame_bottom = ...(2)
665+ * func_frame_offset - bpf_dummy_frame_size
666+ *
667+ * Using ...(2) derived above:
668+ * trampoline_tail_call_info_offset = ...(3)
669+ * trampoline_frame_bottom - tailcallinfo_offset
670+ *
671+ * From ...(3):
672+ * Use trampoline_tail_call_info_offset to write reference of main's
673+ * tail_call_info in trampoline frame.
674+ */
675+ EMIT (PPC_RAW_STL (_R3 , _R1 , (func_frame_offset - bpf_dummy_frame_size )
676+ - tailcallinfo_offset ));
629677 } else {
630678 /* See bpf_jit_stack_offsetof() and BPF_PPC_TC */
631679 EMIT (PPC_RAW_LL (_R4 , _R1 , r4_off ));
@@ -635,14 +683,11 @@ static void bpf_trampoline_setup_tail_call_cnt(u32 *image, struct codegen_contex
635683static void bpf_trampoline_restore_tail_call_cnt (u32 * image , struct codegen_context * ctx ,
636684 int func_frame_offset , int r4_off )
637685{
638- if (IS_ENABLED (CONFIG_PPC64 )) {
639- /* See bpf_jit_stack_tailcallcnt() */
640- int tailcallcnt_offset = 7 * 8 ;
641-
642- EMIT (PPC_RAW_LL (_R3 , _R1 , - tailcallcnt_offset ));
643- EMIT (PPC_RAW_STL (_R3 , _R1 , func_frame_offset - tailcallcnt_offset ));
644- } else {
645- /* See bpf_jit_stack_offsetof() and BPF_PPC_TC */
686+ if (IS_ENABLED (CONFIG_PPC32 )) {
687+ /*
688+ * Restore tailcall for 32-bit powerpc
689+ * See bpf_jit_stack_offsetof() and BPF_PPC_TC
690+ */
646691 EMIT (PPC_RAW_STL (_R4 , _R1 , r4_off ));
647692 }
648693}
@@ -731,6 +776,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
731776 * LR save area [ r0 save (64-bit) ] | header
732777 * [ r0 save (32-bit) ] |
733778 * dummy frame for unwind [ back chain 1 ] --
779+ * [ tail_call_info ] optional - 64-bit powerpc
734780 * [ padding ] align stack frame
735781 * r4_off [ r4 (tailcallcnt) ] optional - 32-bit powerpc
736782 * alt_lr_off [ real lr (ool stub)] optional - actual lr
@@ -812,6 +858,14 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
812858 }
813859 }
814860
861+ /*
862+ * Save tailcall count pointer at the same offset on the
863+ * stack where subprogs expect it
864+ */
865+ if ((flags & BPF_TRAMP_F_CALL_ORIG ) &&
866+ (flags & BPF_TRAMP_F_TAIL_CALL_CTX ))
867+ bpf_frame_size += BPF_PPC_TAILCALL ;
868+
815869 /* Padding to align stack frame, if any */
816870 bpf_frame_size = round_up (bpf_frame_size , SZL * 2 );
817871
@@ -913,7 +967,8 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
913967
914968 /* Replicate tail_call_cnt before calling the original BPF prog */
915969 if (flags & BPF_TRAMP_F_TAIL_CALL_CTX )
916- bpf_trampoline_setup_tail_call_cnt (image , ctx , func_frame_offset , r4_off );
970+ bpf_trampoline_setup_tail_call_info (image , ctx , func_frame_offset ,
971+ bpf_dummy_frame_size , r4_off );
917972
918973 /* Restore args */
919974 bpf_trampoline_restore_args_stack (image , ctx , func_frame_offset , nr_regs , regs_off );
0 commit comments