[RESEND PATCH] powerpc64/bpf: fix JIT code size calculation of bpf trampoline
Naveen N Rao
naveen at kernel.org
Fri Apr 4 02:45:02 AEDT 2025
On Wed, Mar 26, 2025 at 08:04:22PM +0530, Hari Bathini wrote:
> The JIT compile of ldimm instructions can be anywhere between 1-5
> instructions long depending on the value being loaded.
>
> arch_bpf_trampoline_size() provides JIT size of the BPF trampoline
> before the buffer for JIT'ing it is allocated. BPF trampoline JIT
> code has ldimm instructions that need to load the value of pointer
> to struct bpf_tramp_image. But this pointer value is not same while
> calling arch_bpf_trampoline_size() & arch_prepare_bpf_trampoline().
> So, the size arrived at using arch_bpf_trampoline_size() can vary
> from the size needed in arch_prepare_bpf_trampoline(). When the
> number of ldimm instructions emitted in arch_bpf_trampoline_size()
> is less than the number of ldimm instructions emitted during the
> actual JIT compile of trampoline, the below warning is produced:
>
> WARNING: CPU: 8 PID: 204190 at arch/powerpc/net/bpf_jit_comp.c:981 __arch_prepare_bpf_trampoline.isra.0+0xd2c/0xdcc
>
> which is:
>
> /* Make sure the trampoline generation logic doesn't overflow */
> if (image && WARN_ON_ONCE(&image[ctx->idx] >
> (u32 *)rw_image_end - BPF_INSN_SAFETY)) {
>
> Pass NULL as the first argument to __arch_prepare_bpf_trampoline()
> call from arch_bpf_trampoline_size() function, to differentiate it
> from how arch_prepare_bpf_trampoline() calls it and ensure maximum
> possible instructions are emitted in arch_bpf_trampoline_size() for
> ldimm instructions that load a different value during the actual JIT
> compile of BPF trampoline.
>
> Fixes: d243b62b7bd3 ("powerpc64/bpf: Add support for bpf trampolines")
> Reported-by: Venkat Rao Bagalkote <venkat88 at linux.ibm.com>
> Closes: https://lore.kernel.org/all/6168bfc8-659f-4b5a-a6fb-90a916dde3b3@linux.ibm.com/
> Cc: stable at vger.kernel.org # v6.13+
> Signed-off-by: Hari Bathini <hbathini at linux.ibm.com>
> ---
>
> * Removed a redundant '/' accidently added in a comment and resending.
>
> arch/powerpc/net/bpf_jit_comp.c | 29 +++++++++++++++++++++++------
> 1 file changed, 23 insertions(+), 6 deletions(-)
>
> diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
> index 2991bb171a9b..c94717ccb2bd 100644
> --- a/arch/powerpc/net/bpf_jit_comp.c
> +++ b/arch/powerpc/net/bpf_jit_comp.c
> @@ -833,7 +833,12 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
> EMIT(PPC_RAW_STL(_R26, _R1, nvr_off + SZL));
>
> if (flags & BPF_TRAMP_F_CALL_ORIG) {
> - PPC_LI_ADDR(_R3, (unsigned long)im);
> + /*
> + * Emit maximum possible instructions while getting the size of
> + * bpf trampoline to ensure trampoline JIT code doesn't overflow.
> + */
> + PPC_LI_ADDR(_R3, im ? (unsigned long)im :
> + (unsigned long)(~(1UL << (BITS_PER_LONG - 1))));
We generally rely on a NULL 'image' to detect a dummy pass. See commit
d3921cbb6cd6 ("powerpc/bpf: Only pad length-variable code at initial
pass"), for instance. Have you considered updating PPC_LI64() and
PPC_LI32() to simply emit a fixed number of nops if image is NULL?
- Naveen
More information about the Linuxppc-dev
mailing list