bpf, arm64: save 4 bytes in prologue when ebpf insns came from cbpf
authorDaniel Borkmann <daniel@iogearbox.net>
Mon, 14 May 2018 21:22:33 +0000 (23:22 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Tue, 15 May 2018 02:11:45 +0000 (19:11 -0700)
We can trivially save 4 bytes in prologue for cBPF since tail calls
can never be used from there. The register push/pop is pairwise,
here, x25 (fp) and x26 (tcc), so no point in changing that, only
reset to zero is not needed.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
arch/arm64/net/bpf_jit_comp.c

index c8a2620..a6fdaea 100644 (file)
@@ -185,7 +185,7 @@ static inline int epilogue_offset(const struct jit_ctx *ctx)
 /* Tail call offset to jump into */
 #define PROLOGUE_OFFSET 7
 
-static int build_prologue(struct jit_ctx *ctx)
+static int build_prologue(struct jit_ctx *ctx, bool ebpf_from_cbpf)
 {
        const struct bpf_prog *prog = ctx->prog;
        const u8 r6 = bpf2a64[BPF_REG_6];
@@ -232,14 +232,16 @@ static int build_prologue(struct jit_ctx *ctx)
        /* Set up BPF prog stack base register */
        emit(A64_MOV(1, fp, A64_SP), ctx);
 
-       /* Initialize tail_call_cnt */
-       emit(A64_MOVZ(1, tcc, 0, 0), ctx);
+       if (!ebpf_from_cbpf) {
+               /* Initialize tail_call_cnt */
+               emit(A64_MOVZ(1, tcc, 0, 0), ctx);
 
-       cur_offset = ctx->idx - idx0;
-       if (cur_offset != PROLOGUE_OFFSET) {
-               pr_err_once("PROLOGUE_OFFSET = %d, expected %d!\n",
-                           cur_offset, PROLOGUE_OFFSET);
-               return -1;
+               cur_offset = ctx->idx - idx0;
+               if (cur_offset != PROLOGUE_OFFSET) {
+                       pr_err_once("PROLOGUE_OFFSET = %d, expected %d!\n",
+                                   cur_offset, PROLOGUE_OFFSET);
+                       return -1;
+               }
        }
 
        ctx->stack_size = STACK_ALIGN(prog->aux->stack_depth);
@@ -806,6 +808,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
        struct bpf_prog *tmp, *orig_prog = prog;
        struct bpf_binary_header *header;
        struct arm64_jit_data *jit_data;
+       bool was_classic = bpf_prog_was_classic(prog);
        bool tmp_blinded = false;
        bool extra_pass = false;
        struct jit_ctx ctx;
@@ -860,7 +863,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
                goto out_off;
        }
 
-       if (build_prologue(&ctx)) {
+       if (build_prologue(&ctx, was_classic)) {
                prog = orig_prog;
                goto out_off;
        }
@@ -883,7 +886,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 skip_init_ctx:
        ctx.idx = 0;
 
-       build_prologue(&ctx);
+       build_prologue(&ctx, was_classic);
 
        if (build_body(&ctx)) {
                bpf_jit_binary_free(header);