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: fix the address returned by bpf_get_func_ip

bpf_get_func_ip() helper function returns the address of the traced
function. It relies on the IP address stored at ctx - 16 by the bpf
trampoline. On 64-bit powerpc, this address is recovered from LR
accounting for OOL trampoline. But the address stored here was off
by 4-bytes. Ensure the address is the actual start of the traced
function.

Reported-by: Abhishek Dubey <adubey@linux.ibm.com>
Fixes: d243b62b7bd3 ("powerpc64/bpf: Add support for bpf trampolines")
Cc: stable@vger.kernel.org
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
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-3-hbathini@linux.ibm.com

authored by

Hari Bathini and committed by
Madhavan Srinivasan
15782026 521bd39d

+19 -9
+19 -9
arch/powerpc/net/bpf_jit_comp.c
··· 785 785 * retval_off [ return value ] 786 786 * [ reg argN ] 787 787 * [ ... ] 788 - * regs_off [ reg_arg1 ] prog ctx context 789 - * nregs_off [ args count ] 790 - * ip_off [ traced function ] 788 + * regs_off [ reg_arg1 ] prog_ctx 789 + * nregs_off [ args count ] ((u64 *)prog_ctx)[-1] 790 + * ip_off [ traced function ] ((u64 *)prog_ctx)[-2] 791 791 * [ ... ] 792 792 * run_ctx_off [ bpf_tramp_run_ctx ] 793 793 * [ reg argN ] ··· 895 895 896 896 bpf_trampoline_save_args(image, ctx, func_frame_offset, nr_regs, regs_off); 897 897 898 - /* Save our return address */ 898 + /* Save our LR/return address */ 899 899 EMIT(PPC_RAW_MFLR(_R3)); 900 900 if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) 901 901 EMIT(PPC_RAW_STL(_R3, _R1, alt_lr_off)); ··· 903 903 EMIT(PPC_RAW_STL(_R3, _R1, bpf_frame_size + PPC_LR_STKOFF)); 904 904 905 905 /* 906 - * Save ip address of the traced function. 907 - * We could recover this from LR, but we will need to address for OOL trampoline, 908 - * and optional GEP area. 906 + * Derive IP address of the traced function. 907 + * In case of CONFIG_PPC_FTRACE_OUT_OF_LINE or BPF program, LR points to the instruction 908 + * after the 'bl' instruction in the OOL stub. Refer to ftrace_init_ool_stub() and 909 + * bpf_arch_text_poke() for OOL stub of kernel functions and bpf programs respectively. 910 + * Relevant stub sequence: 911 + * 912 + * bl <tramp> 913 + * LR (R3) => mtlr r0 914 + * b <func_addr+4> 915 + * 916 + * Recover kernel function/bpf program address from the unconditional 917 + * branch instruction at the end of OOL stub. 909 918 */ 910 919 if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) || flags & BPF_TRAMP_F_IP_ARG) { 911 920 EMIT(PPC_RAW_LWZ(_R4, _R3, 4)); 912 921 EMIT(PPC_RAW_SLWI(_R4, _R4, 6)); 913 922 EMIT(PPC_RAW_SRAWI(_R4, _R4, 6)); 914 923 EMIT(PPC_RAW_ADD(_R3, _R3, _R4)); 915 - EMIT(PPC_RAW_ADDI(_R3, _R3, 4)); 916 924 } 917 925 918 926 if (flags & BPF_TRAMP_F_IP_ARG) 919 927 EMIT(PPC_RAW_STL(_R3, _R1, ip_off)); 920 928 921 - if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) 929 + if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) { 922 930 /* Fake our LR for unwind */ 931 + EMIT(PPC_RAW_ADDI(_R3, _R3, 4)); 923 932 EMIT(PPC_RAW_STL(_R3, _R1, bpf_frame_size + PPC_LR_STKOFF)); 933 + } 924 934 925 935 /* Save function arg count -- see bpf_get_func_arg_cnt() */ 926 936 EMIT(PPC_RAW_LI(_R3, nr_regs));