Skip to content

Commit 1e692f0

Browse files
lukenelsAlexei Starovoitov
authored andcommitted
bpf, riscv: clear high 32 bits for ALU32 add/sub/neg/lsh/rsh/arsh
In BPF, 32-bit ALU operations should zero-extend their results into the 64-bit registers. The current BPF JIT on RISC-V emits incorrect instructions that perform sign extension only (e.g., addw, subw) on 32-bit add, sub, lsh, rsh, arsh, and neg. This behavior diverges from the interpreter and JITs for other architectures. This patch fixes the bugs by performing zero extension on the destination register of 32-bit ALU operations. Fixes: 2353ecc ("bpf, riscv: add BPF JIT for RV64G") Cc: Xi Wang <[email protected]> Signed-off-by: Luke Nelson <[email protected]> Acked-by: Song Liu <[email protected]> Acked-by: Björn Töpel <[email protected]> Reviewed-by: Palmer Dabbelt <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent cfd4921 commit 1e692f0

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

arch/riscv/net/bpf_jit_comp.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,10 +751,14 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
751751
case BPF_ALU | BPF_ADD | BPF_X:
752752
case BPF_ALU64 | BPF_ADD | BPF_X:
753753
emit(is64 ? rv_add(rd, rd, rs) : rv_addw(rd, rd, rs), ctx);
754+
if (!is64)
755+
emit_zext_32(rd, ctx);
754756
break;
755757
case BPF_ALU | BPF_SUB | BPF_X:
756758
case BPF_ALU64 | BPF_SUB | BPF_X:
757759
emit(is64 ? rv_sub(rd, rd, rs) : rv_subw(rd, rd, rs), ctx);
760+
if (!is64)
761+
emit_zext_32(rd, ctx);
758762
break;
759763
case BPF_ALU | BPF_AND | BPF_X:
760764
case BPF_ALU64 | BPF_AND | BPF_X:
@@ -795,21 +799,29 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
795799
case BPF_ALU | BPF_LSH | BPF_X:
796800
case BPF_ALU64 | BPF_LSH | BPF_X:
797801
emit(is64 ? rv_sll(rd, rd, rs) : rv_sllw(rd, rd, rs), ctx);
802+
if (!is64)
803+
emit_zext_32(rd, ctx);
798804
break;
799805
case BPF_ALU | BPF_RSH | BPF_X:
800806
case BPF_ALU64 | BPF_RSH | BPF_X:
801807
emit(is64 ? rv_srl(rd, rd, rs) : rv_srlw(rd, rd, rs), ctx);
808+
if (!is64)
809+
emit_zext_32(rd, ctx);
802810
break;
803811
case BPF_ALU | BPF_ARSH | BPF_X:
804812
case BPF_ALU64 | BPF_ARSH | BPF_X:
805813
emit(is64 ? rv_sra(rd, rd, rs) : rv_sraw(rd, rd, rs), ctx);
814+
if (!is64)
815+
emit_zext_32(rd, ctx);
806816
break;
807817

808818
/* dst = -dst */
809819
case BPF_ALU | BPF_NEG:
810820
case BPF_ALU64 | BPF_NEG:
811821
emit(is64 ? rv_sub(rd, RV_REG_ZERO, rd) :
812822
rv_subw(rd, RV_REG_ZERO, rd), ctx);
823+
if (!is64)
824+
emit_zext_32(rd, ctx);
813825
break;
814826

815827
/* dst = BSWAP##imm(dst) */
@@ -964,14 +976,20 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
964976
case BPF_ALU | BPF_LSH | BPF_K:
965977
case BPF_ALU64 | BPF_LSH | BPF_K:
966978
emit(is64 ? rv_slli(rd, rd, imm) : rv_slliw(rd, rd, imm), ctx);
979+
if (!is64)
980+
emit_zext_32(rd, ctx);
967981
break;
968982
case BPF_ALU | BPF_RSH | BPF_K:
969983
case BPF_ALU64 | BPF_RSH | BPF_K:
970984
emit(is64 ? rv_srli(rd, rd, imm) : rv_srliw(rd, rd, imm), ctx);
985+
if (!is64)
986+
emit_zext_32(rd, ctx);
971987
break;
972988
case BPF_ALU | BPF_ARSH | BPF_K:
973989
case BPF_ALU64 | BPF_ARSH | BPF_K:
974990
emit(is64 ? rv_srai(rd, rd, imm) : rv_sraiw(rd, rd, imm), ctx);
991+
if (!is64)
992+
emit_zext_32(rd, ctx);
975993
break;
976994

977995
/* JUMP off */

0 commit comments

Comments
 (0)