Re: [PATCH bpf] LoongArch: bpf: zero-extend signed ALU32 div/mod results
Tiezhu Yang <[email protected]>
| Newsgroups | dev.linux.lists.loongarch,org.kernel.vger.bpf |
|---|---|
| Message-ID | <[email protected]> |
Cc: Huacai Chen <[email protected]> [email protected] On 2026/7/9 下午9:53, Nicholas Dudar wrote: > ALU32 operations write a 32-bit result and leave the upper 32 bits of > the BPF register zero. The LoongArch JIT sign-extends the result of > signed ALU32 BPF_DIV and BPF_MOD (off=1), so a negative 32-bit quotient > or remainder leaves bits 63:32 set in JITted code while the verifier > and interpreter model those bits as zero. > > Keep sign-extension on the operands, which signed divide needs, and > zero-extend the ALU32 result after the divide or modulo instruction, > matching the unsigned ALU32 div/mod paths and every other ALU32 > operation in this JIT. > > Fixes: 2425c9e002d2 ("LoongArch: BPF: Support signed div instructions") > Fixes: 7b6b13d32965 ("LoongArch: BPF: Support signed mod instructions") > Signed-off-by: Nicholas Dudar <[email protected]> > Assisted-by: Claude:claude-opus-4-8 > --- > Reported privately to [email protected] first; posting to the list > at the maintainer's request. The patch is the same. > > arch/loongarch/net/bpf_jit.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/arch/loongarch/net/bpf_jit.c b/arch/loongarch/net/bpf_jit.c > index 2738b4db1165..c91d474faba7 100644 > --- a/arch/loongarch/net/bpf_jit.c > +++ b/arch/loongarch/net/bpf_jit.c > @@ -835,7 +835,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext > move_reg(ctx, t1, src); > emit_sext_32(ctx, t1, is32); > emit_insn(ctx, divd, dst, dst, t1); > - emit_sext_32(ctx, dst, is32); > + emit_zext_32(ctx, dst, is32); > } > break; > > @@ -852,7 +852,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext > emit_sext_32(ctx, t1, is32); > emit_sext_32(ctx, dst, is32); > emit_insn(ctx, divd, dst, dst, t1); > - emit_sext_32(ctx, dst, is32); > + emit_zext_32(ctx, dst, is32); > } > break; > > @@ -870,7 +870,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext > move_reg(ctx, t1, src); > emit_sext_32(ctx, t1, is32); > emit_insn(ctx, modd, dst, dst, t1); > - emit_sext_32(ctx, dst, is32); > + emit_zext_32(ctx, dst, is32); > } > break; > > @@ -887,7 +887,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx, bool ext > emit_sext_32(ctx, t1, is32); > emit_sext_32(ctx, dst, is32); > emit_insn(ctx, modd, dst, dst, t1); > - emit_sext_32(ctx, dst, is32); > + emit_zext_32(ctx, dst, is32); > } > break; > > > base-commit: 0e35b9b6ec0ffcc5e23cbdec09f5c622ad532b53 Here is the link: https://lore.kernel.org/bpf/[email protected]/ When executing "sudo modprobe test_bpf" on LoongArch with v7.2-rc1, there are 4 failed testcases without this patch: test_bpf: #811 ALU32_SDIV_K: registers jited:1 ret 1354 != 1 (0x54a != 0x1)FAIL (1 times) test_bpf: #812 ALU32_SMOD_K: registers jited:1 ret 1354 != 1 (0x54a != 0x1)FAIL (1 times) test_bpf: #875 ALU32_SDIV_K: all immediate value magnitudes jited:1 ret 0 != 1 (0x0 != 0x1)FAIL (1 times) test_bpf: #876 ALU32_SMOD_K: all immediate value magnitudes jited:1 ret 0 != 1 (0x0 != 0x1)FAIL (1 times) But the failures were not present in v7.1, these regressions were exposed by commit c8f0ee969f76 ("bpf: Exhaustive test coverage for signed division and modulo"), which added these cases in v7.2-rc1. With the provided patch, all tests pass as expected. Acked-by: Tiezhu Yang <[email protected]> Tested-by: Tiezhu Yang <[email protected]> Thanks, Tiezhu