Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

powerpc64/bpf: use consistent tailcall offset in trampoline

Ideally, the offset used to load the tail call info field and to find
the pass by reference address for tail call field should be the same.
But while setting up the tail call info in the trampoline, this was
not followed. This can be misleading and can lead to unpredictable
results if and when bpf_has_stack_frame() ends up returning true
for trampoline frame. Since commit 15513beeb673 ("powerpc64/bpf:
Moving tail_call_cnt to bottom of frame") and commit 2ed2d8f6fb38
("powerpc64/bpf: Support tailcalls with subprogs") ensured tail call
field is at the bottom of the stack frame for BPF programs as well as
BPF trampoline, avoid relying on bpf_jit_stack_tailcallinfo_offset()
and bpf_has_stack_frame() for trampoline frame and always calculate
tail call field offset with reference to older frame.

Fixes: 2ed2d8f6fb38 ("powerpc64/bpf: Support tailcalls with subprogs")
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260303181031.390073-4-hbathini@linux.ibm.com

authored by

Hari Bathini and committed by
Madhavan Srinivasan
3727d6ec 15782026

+9 -13
-5
arch/powerpc/net/bpf_jit.h
··· 81 81 82 82 #ifdef CONFIG_PPC64 83 83 84 - /* for gpr non volatile registers BPG_REG_6 to 10 */ 85 - #define BPF_PPC_STACK_SAVE (6 * 8) 86 - 87 84 /* If dummy pass (!image), account for maximum possible instructions */ 88 85 #define PPC_LI64(d, i) do { \ 89 86 if (!image) \ ··· 216 219 int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass, 217 220 struct codegen_context *ctx, int insn_idx, 218 221 int jmp_off, int dst_reg, u32 code); 219 - 220 - int bpf_jit_stack_tailcallinfo_offset(struct codegen_context *ctx); 221 222 #endif 222 223 223 224 #endif
+5 -7
arch/powerpc/net/bpf_jit_comp.c
··· 642 642 int bpf_dummy_frame_size, int r4_off) 643 643 { 644 644 if (IS_ENABLED(CONFIG_PPC64)) { 645 - /* See Generated stack layout */ 646 - int tailcallinfo_offset = BPF_PPC_TAILCALL; 647 - 648 645 /* 649 646 * func_frame_offset = ...(1) 650 647 * bpf_dummy_frame_size + trampoline_frame_size 651 648 */ 652 649 EMIT(PPC_RAW_LD(_R4, _R1, func_frame_offset)); 653 - EMIT(PPC_RAW_LD(_R3, _R4, -tailcallinfo_offset)); 650 + /* Refer to trampoline's Generated stack layout */ 651 + EMIT(PPC_RAW_LD(_R3, _R4, -BPF_PPC_TAILCALL)); 654 652 655 653 /* 656 654 * Setting the tail_call_info in trampoline's frame ··· 656 658 */ 657 659 EMIT(PPC_RAW_CMPLWI(_R3, MAX_TAIL_CALL_CNT)); 658 660 PPC_BCC_CONST_SHORT(COND_GT, 8); 659 - EMIT(PPC_RAW_ADDI(_R3, _R4, bpf_jit_stack_tailcallinfo_offset(ctx))); 661 + EMIT(PPC_RAW_ADDI(_R3, _R4, -BPF_PPC_TAILCALL)); 660 662 /* 661 663 * From ...(1) above: 662 664 * trampoline_frame_bottom = ...(2) ··· 664 666 * 665 667 * Using ...(2) derived above: 666 668 * trampoline_tail_call_info_offset = ...(3) 667 - * trampoline_frame_bottom - tailcallinfo_offset 669 + * trampoline_frame_bottom - BPF_PPC_TAILCALL 668 670 * 669 671 * From ...(3): 670 672 * Use trampoline_tail_call_info_offset to write reference of main's 671 673 * tail_call_info in trampoline frame. 672 674 */ 673 675 EMIT(PPC_RAW_STL(_R3, _R1, (func_frame_offset - bpf_dummy_frame_size) 674 - - tailcallinfo_offset)); 676 + - BPF_PPC_TAILCALL)); 675 677 } else { 676 678 /* See bpf_jit_stack_offsetof() and BPF_PPC_TC */ 677 679 EMIT(PPC_RAW_LL(_R4, _R1, r4_off));
+4 -1
arch/powerpc/net/bpf_jit_comp64.c
··· 42 42 * exception boundary. 43 43 */ 44 44 45 + /* BPF non-volatile registers save area size */ 46 + #define BPF_PPC_STACK_SAVE (6 * 8) 47 + 45 48 /* for bpf JIT code internal usage */ 46 49 #define BPF_PPC_STACK_LOCALS 24 47 50 /* ··· 151 148 } 152 149 } 153 150 154 - int bpf_jit_stack_tailcallinfo_offset(struct codegen_context *ctx) 151 + static int bpf_jit_stack_tailcallinfo_offset(struct codegen_context *ctx) 155 152 { 156 153 return bpf_jit_stack_local(ctx) + BPF_PPC_STACK_LOCALS + BPF_PPC_STACK_SAVE; 157 154 }