]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
LoongArch: BPF: Use move_addr() for BPF_PSEUDO_FUNC
authorHengqi Chen <hengqi.chen@gmail.com>
Sun, 30 Mar 2025 08:31:09 +0000 (16:31 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 10 Apr 2025 12:39:36 +0000 (14:39 +0200)
commit 52266f1015a8b5aabec7d127f83d105f702b388e upstream.

Vincent reported that running XDP synproxy program on LoongArch results
in the following error:

    JIT doesn't support bpf-to-bpf calls

With dmesg:

    multi-func JIT bug 1391 != 1390

The root cause is that verifier will refill the imm with the correct
addresses of bpf_calls for BPF_PSEUDO_FUNC instructions and then run
the last pass of JIT. So we generate different JIT code for the same
instruction in two passes (one for placeholder and the other for the
real address). Let's use move_addr() instead.

See commit 64f50f6575721ef0 ("LoongArch, bpf: Use 4 instructions for
function address in JIT") for a similar fix.

Cc: stable@vger.kernel.org
Fixes: 69c087ba6225 ("bpf: Add bpf_for_each_map_elem() helper")
Fixes: bb035ef0cc91 ("LoongArch: BPF: Support mixing bpf2bpf and tailcalls")
Reported-by: Vincent Li <vincent.mc.li@gmail.com>
Tested-by: Vincent Li <vincent.mc.li@gmail.com>
Closes: https://lore.kernel.org/loongarch/CAK3+h2yfM9FTNiXvEQBkvtuoJrvzmN4c_NZsFXqEk4Cj1tsBNA@mail.gmail.com/T/#u
Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/loongarch/net/bpf_jit.c

index f532d6ef16e54ab49c9aa3c9130b019311905fef..fa1500d4aa3e3a3424468b20e634709fd4c54d96 100644 (file)
@@ -935,7 +935,10 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext
        {
                const u64 imm64 = (u64)(insn + 1)->imm << 32 | (u32)insn->imm;
 
-               move_imm(ctx, dst, imm64, is32);
+               if (bpf_pseudo_func(insn))
+                       move_addr(ctx, dst, imm64);
+               else
+                       move_imm(ctx, dst, imm64, is32);
                return 1;
        }