Skip to content

Commit fe121ee

Browse files
bjotoborkmann
authored andcommitted
bpf, riscv: clear target register high 32-bits for and/or/xor on ALU32
When using 32-bit subregisters (ALU32), the RISC-V JIT would not clear the high 32-bits of the target register and therefore generate incorrect code. E.g., in the following code: $ cat test.c unsigned int f(unsigned long long a, unsigned int b) { return (unsigned int)a & b; } $ clang-9 -target bpf -O2 -emit-llvm -S test.c -o - | \ llc-9 -mattr=+alu32 -mcpu=v3 .text .file "test.c" .globl f .p2align 3 .type f,@function f: r0 = r1 w0 &= w2 exit .Lfunc_end0: .size f, .Lfunc_end0-f The JIT would not clear the high 32-bits of r0 after the and-operation, which in this case might give an incorrect return value. After this patch, that is not the case, and the upper 32-bits are cleared. Reported-by: Jiong Wang <[email protected]> Fixes: 2353ecc ("bpf, riscv: add BPF JIT for RV64G") Signed-off-by: Björn Töpel <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]>
1 parent a195cef commit fe121ee

File tree

1 file changed

+6
-0
lines changed

1 file changed

+6
-0
lines changed

arch/riscv/net/bpf_jit_comp.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,14 +759,20 @@ static int emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
759759
case BPF_ALU | BPF_AND | BPF_X:
760760
case BPF_ALU64 | BPF_AND | BPF_X:
761761
emit(rv_and(rd, rd, rs), ctx);
762+
if (!is64)
763+
emit_zext_32(rd, ctx);
762764
break;
763765
case BPF_ALU | BPF_OR | BPF_X:
764766
case BPF_ALU64 | BPF_OR | BPF_X:
765767
emit(rv_or(rd, rd, rs), ctx);
768+
if (!is64)
769+
emit_zext_32(rd, ctx);
766770
break;
767771
case BPF_ALU | BPF_XOR | BPF_X:
768772
case BPF_ALU64 | BPF_XOR | BPF_X:
769773
emit(rv_xor(rd, rd, rs), ctx);
774+
if (!is64)
775+
emit_zext_32(rd, ctx);
770776
break;
771777
case BPF_ALU | BPF_MUL | BPF_X:
772778
case BPF_ALU64 | BPF_MUL | BPF_X:

0 commit comments

Comments
 (0)