diff options
| author | Nicholas Dudar <main.kalliope@gmail.com> | 2026-07-23 22:27:35 +0800 |
|---|---|---|
| committer | Huacai Chen <chenhuacai@loongson.cn> | 2026-07-23 22:27:35 +0800 |
| commit | dacd348b8a993373576fe2ee2d8b114740ba57a6 (patch) | |
| tree | 7d439988c7fb6729745c1f2434234065ea070398 /arch | |
| parent | 73555fdab5e1e4f24ca000c41a616b34edf4b55d (diff) | |
| download | linux-next-dacd348b8a993373576fe2ee2d8b114740ba57a6.tar.gz linux-next-dacd348b8a993373576fe2ee2d8b114740ba57a6.zip | |
LoongArch: BPF: Zero-extend signed ALU32 div/mod results
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")
Assisted-by: Claude:claude-opus-4-8
Acked-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Tested-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Nicholas Dudar <main.kalliope@gmail.com>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/loongarch/net/bpf_jit.c | 8 |
1 files 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; |
