Commit f324cda693e53b4fafdeb043f1e90fd5bd749dfb
Committed by
Greg Kroah-Hartman
1 parent
516e433a15
arm64: bpf: lift restriction on last instruction
commit 51c9fbb1b146f3336a93d398c439b6fbfe5ab489 upstream. Earlier implementation assumed last instruction is BPF_EXIT. Since this is no longer a restriction in eBPF, we remove this limitation. Per Alexei Starovoitov [1]: > classic BPF has a restriction that last insn is always BPF_RET. > eBPF doesn't have BPF_RET instruction and this restriction. > It has BPF_EXIT insn which can appear anywhere in the program > one or more times and it doesn't have to be last insn. [1] https://lkml.org/lkml/2014/11/27/2 Fixes: e54bcde3d69d ("arm64: eBPF JIT compiler") Acked-by: Alexei Starovoitov <ast@plumgrid.com> Signed-off-by: Zi Shen Lim <zlim.lnx@gmail.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 1 changed file with 8 additions and 5 deletions Side-by-side Diff
arch/arm64/net/bpf_jit_comp.c
... | ... | @@ -60,7 +60,7 @@ |
60 | 60 | const struct bpf_prog *prog; |
61 | 61 | int idx; |
62 | 62 | int tmp_used; |
63 | - int body_offset; | |
63 | + int epilogue_offset; | |
64 | 64 | int *offset; |
65 | 65 | u32 *image; |
66 | 66 | }; |
... | ... | @@ -130,8 +130,8 @@ |
130 | 130 | |
131 | 131 | static inline int epilogue_offset(const struct jit_ctx *ctx) |
132 | 132 | { |
133 | - int to = ctx->offset[ctx->prog->len - 1]; | |
134 | - int from = ctx->idx - ctx->body_offset; | |
133 | + int to = ctx->epilogue_offset; | |
134 | + int from = ctx->idx; | |
135 | 135 | |
136 | 136 | return to - from; |
137 | 137 | } |
... | ... | @@ -463,6 +463,8 @@ |
463 | 463 | } |
464 | 464 | /* function return */ |
465 | 465 | case BPF_JMP | BPF_EXIT: |
466 | + /* Optimization: when last instruction is EXIT, | |
467 | + simply fallthrough to epilogue. */ | |
466 | 468 | if (i == ctx->prog->len - 1) |
467 | 469 | break; |
468 | 470 | jmp_offset = epilogue_offset(ctx); |
469 | 471 | |
... | ... | @@ -685,11 +687,13 @@ |
685 | 687 | |
686 | 688 | /* 1. Initial fake pass to compute ctx->idx. */ |
687 | 689 | |
688 | - /* Fake pass to fill in ctx->offset. */ | |
690 | + /* Fake pass to fill in ctx->offset and ctx->tmp_used. */ | |
689 | 691 | if (build_body(&ctx)) |
690 | 692 | goto out; |
691 | 693 | |
692 | 694 | build_prologue(&ctx); |
695 | + | |
696 | + ctx.epilogue_offset = ctx.idx; | |
693 | 697 | build_epilogue(&ctx); |
694 | 698 | |
695 | 699 | /* Now we know the actual image size. */ |
... | ... | @@ -706,7 +710,6 @@ |
706 | 710 | |
707 | 711 | build_prologue(&ctx); |
708 | 712 | |
709 | - ctx.body_offset = ctx.idx; | |
710 | 713 | if (build_body(&ctx)) { |
711 | 714 | bpf_jit_binary_free(header); |
712 | 715 | goto out; |