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 <venka...@linux.ibm.com>
> Closes: 
> https://lore.kernel.org/all/6168bfc8-659f-4b5a-a6fb-90a916dde...@linux.ibm.com/
> Cc: sta...@vger.kernel.org # v6.13+
> Signed-off-by: Hari Bathini <hbath...@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


Reply via email to