Commit 15782026 authored by Hari Bathini's avatar Hari Bathini Committed by Madhavan Srinivasan
Browse files

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: default avatarAbhishek Dubey <adubey@linux.ibm.com>
Fixes: d243b62b ("powerpc64/bpf: Add support for bpf trampolines")
Cc: stable@vger.kernel.org
Tested-by: default avatarVenkat Rao Bagalkote <venkat88@linux.ibm.com>
Signed-off-by: default avatarHari Bathini <hbathini@linux.ibm.com>
Signed-off-by: default avatarMadhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260303181031.390073-3-hbathini@linux.ibm.com
parent 521bd39d
Loading
Loading
Loading
Loading
+19 −9
Original line number Diff line number Diff line
@@ -785,9 +785,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
	 *       retval_off             [ return value      ]
	 *                              [ reg argN          ]
	 *                              [ ...               ]
	 *       regs_off               [ reg_arg1          ] prog ctx context
	 *       nregs_off              [ args count        ]
	 *       ip_off                 [ traced function   ]
	 *       regs_off               [ reg_arg1          ] prog_ctx
	 *       nregs_off              [ args count        ] ((u64 *)prog_ctx)[-1]
	 *       ip_off                 [ traced function   ] ((u64 *)prog_ctx)[-2]
	 *                              [ ...               ]
	 *       run_ctx_off            [ bpf_tramp_run_ctx ]
	 *                              [ reg argN          ]
@@ -895,7 +895,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im

	bpf_trampoline_save_args(image, ctx, func_frame_offset, nr_regs, regs_off);

	/* Save our return address */
	/* Save our LR/return address */
	EMIT(PPC_RAW_MFLR(_R3));
	if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE))
		EMIT(PPC_RAW_STL(_R3, _R1, alt_lr_off));
@@ -903,24 +903,34 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
		EMIT(PPC_RAW_STL(_R3, _R1, bpf_frame_size + PPC_LR_STKOFF));

	/*
	 * Save ip address of the traced function.
	 * We could recover this from LR, but we will need to address for OOL trampoline,
	 * and optional GEP area.
	 * Derive IP address of the traced function.
	 * In case of CONFIG_PPC_FTRACE_OUT_OF_LINE or BPF program, LR points to the instruction
	 * after the 'bl' instruction in the OOL stub. Refer to ftrace_init_ool_stub() and
	 * bpf_arch_text_poke() for OOL stub of kernel functions and bpf programs respectively.
	 * Relevant stub sequence:
	 *
	 *               bl <tramp>
	 *   LR (R3) =>  mtlr r0
	 *               b <func_addr+4>
	 *
	 * Recover kernel function/bpf program address from the unconditional
	 * branch instruction at the end of OOL stub.
	 */
	if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) || flags & BPF_TRAMP_F_IP_ARG) {
		EMIT(PPC_RAW_LWZ(_R4, _R3, 4));
		EMIT(PPC_RAW_SLWI(_R4, _R4, 6));
		EMIT(PPC_RAW_SRAWI(_R4, _R4, 6));
		EMIT(PPC_RAW_ADD(_R3, _R3, _R4));
		EMIT(PPC_RAW_ADDI(_R3, _R3, 4));
	}

	if (flags & BPF_TRAMP_F_IP_ARG)
		EMIT(PPC_RAW_STL(_R3, _R1, ip_off));

	if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE))
	if (IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE)) {
		/* Fake our LR for unwind */
		EMIT(PPC_RAW_ADDI(_R3, _R3, 4));
		EMIT(PPC_RAW_STL(_R3, _R1, bpf_frame_size + PPC_LR_STKOFF));
	}

	/* Save function arg count -- see bpf_get_func_arg_cnt() */
	EMIT(PPC_RAW_LI(_R3, nr_regs));