Message ID | 20240326224943.86912-3-puranjay12@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | bpf,riscv: Add support for BPF Arena | expand |
On 2024/3/27 6:49, Puranjay Mohan wrote: > LLVM generates bpf_addr_space_cast instruction while translating > pointers between native (zero) address space and > __attribute__((address_space(N))). The addr_space=0 is reserved as > bpf_arena address space. > > rY = addr_space_cast(rX, 0, 1) is processed by the verifier and > converted to normal 32-bit move: wX = wY > > rY = addr_space_cast(rX, 1, 0) has to be converted by JIT. > > Signed-off-by: Puranjay Mohan <puranjay12@gmail.com> > --- > arch/riscv/net/bpf_jit.h | 1 + > arch/riscv/net/bpf_jit_comp64.c | 14 ++++++++++++++ > arch/riscv/net/bpf_jit_core.c | 1 + > 3 files changed, 16 insertions(+) > > diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h > index 8a47da08dd9c..5fc374ed98ea 100644 > --- a/arch/riscv/net/bpf_jit.h > +++ b/arch/riscv/net/bpf_jit.h > @@ -82,6 +82,7 @@ struct rv_jit_context { > unsigned long flags; > int stack_size; > u64 arena_vm_start; > + u64 user_vm_start; > }; > > /* Convert from ninsns to bytes. */ > diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c > index 73726f455f6b..77ea306452d4 100644 > --- a/arch/riscv/net/bpf_jit_comp64.c > +++ b/arch/riscv/net/bpf_jit_comp64.c > @@ -1081,6 +1081,15 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, > /* dst = src */ > case BPF_ALU | BPF_MOV | BPF_X: > case BPF_ALU64 | BPF_MOV | BPF_X: > + if (insn_is_cast_user(insn)) { > + emit_mv(RV_REG_T1, rs, ctx); > + emit_zextw(RV_REG_T1, RV_REG_T1, ctx); > + emit_imm(rd, (ctx->user_vm_start >> 32) << 32, ctx); > + emit(rv_beq(RV_REG_T1, RV_REG_ZERO, 4), ctx); > + emit_or(RV_REG_T1, rd, RV_REG_T1, ctx); > + emit_mv(rd, RV_REG_T1, ctx); > + break; > + } > if (imm == 1) { > /* Special mov32 for zext */ > emit_zextw(rd, rd, ctx); > @@ -2026,3 +2035,8 @@ bool bpf_jit_supports_ptr_xchg(void) > { > return true; > } > + > +bool bpf_jit_supports_arena(void) > +{ > + return true; > +} > diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c > index 9ab739b9f9a2..8a69d6d81e32 100644 > --- a/arch/riscv/net/bpf_jit_core.c > +++ b/arch/riscv/net/bpf_jit_core.c > @@ -81,6 +81,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) > } > > ctx->arena_vm_start = bpf_arena_get_kern_vm_start(prog->aux->arena); > + ctx->user_vm_start = bpf_arena_get_user_vm_start(prog->aux->arena); > ctx->prog = prog; > ctx->offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL); > if (!ctx->offset) { Reviewed-by: Pu Lehui <pulehui@huawei.com> Tested-by: Pu Lehui <pulehui@huawei.com>
diff --git a/arch/riscv/net/bpf_jit.h b/arch/riscv/net/bpf_jit.h index 8a47da08dd9c..5fc374ed98ea 100644 --- a/arch/riscv/net/bpf_jit.h +++ b/arch/riscv/net/bpf_jit.h @@ -82,6 +82,7 @@ struct rv_jit_context { unsigned long flags; int stack_size; u64 arena_vm_start; + u64 user_vm_start; }; /* Convert from ninsns to bytes. */ diff --git a/arch/riscv/net/bpf_jit_comp64.c b/arch/riscv/net/bpf_jit_comp64.c index 73726f455f6b..77ea306452d4 100644 --- a/arch/riscv/net/bpf_jit_comp64.c +++ b/arch/riscv/net/bpf_jit_comp64.c @@ -1081,6 +1081,15 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx, /* dst = src */ case BPF_ALU | BPF_MOV | BPF_X: case BPF_ALU64 | BPF_MOV | BPF_X: + if (insn_is_cast_user(insn)) { + emit_mv(RV_REG_T1, rs, ctx); + emit_zextw(RV_REG_T1, RV_REG_T1, ctx); + emit_imm(rd, (ctx->user_vm_start >> 32) << 32, ctx); + emit(rv_beq(RV_REG_T1, RV_REG_ZERO, 4), ctx); + emit_or(RV_REG_T1, rd, RV_REG_T1, ctx); + emit_mv(rd, RV_REG_T1, ctx); + break; + } if (imm == 1) { /* Special mov32 for zext */ emit_zextw(rd, rd, ctx); @@ -2026,3 +2035,8 @@ bool bpf_jit_supports_ptr_xchg(void) { return true; } + +bool bpf_jit_supports_arena(void) +{ + return true; +} diff --git a/arch/riscv/net/bpf_jit_core.c b/arch/riscv/net/bpf_jit_core.c index 9ab739b9f9a2..8a69d6d81e32 100644 --- a/arch/riscv/net/bpf_jit_core.c +++ b/arch/riscv/net/bpf_jit_core.c @@ -81,6 +81,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) } ctx->arena_vm_start = bpf_arena_get_kern_vm_start(prog->aux->arena); + ctx->user_vm_start = bpf_arena_get_user_vm_start(prog->aux->arena); ctx->prog = prog; ctx->offset = kcalloc(prog->len, sizeof(int), GFP_KERNEL); if (!ctx->offset) {
LLVM generates bpf_addr_space_cast instruction while translating pointers between native (zero) address space and __attribute__((address_space(N))). The addr_space=0 is reserved as bpf_arena address space. rY = addr_space_cast(rX, 0, 1) is processed by the verifier and converted to normal 32-bit move: wX = wY rY = addr_space_cast(rX, 1, 0) has to be converted by JIT. Signed-off-by: Puranjay Mohan <puranjay12@gmail.com> --- arch/riscv/net/bpf_jit.h | 1 + arch/riscv/net/bpf_jit_comp64.c | 14 ++++++++++++++ arch/riscv/net/bpf_jit_core.c | 1 + 3 files changed, 16 insertions(+)