]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
nfp: bpf: account for BPF-to-BPF calls when preparing nfp JIT
authorQuentin Monnet <quentin.monnet@netronome.com>
Sun, 7 Oct 2018 11:56:51 +0000 (12:56 +0100)
committerDaniel Borkmann <daniel@iogearbox.net>
Mon, 8 Oct 2018 08:24:13 +0000 (10:24 +0200)
Similarly to "exit" or "helper call" instructions, BPF-to-BPF calls will
require additional processing before translation starts, in order to
record and mark jump destinations.

We also mark the instructions where each subprogram begins. This will be
used in a following commit to determine where to add prologues for
subprograms.

Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jiong Wang <jiong.wang@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
drivers/net/ethernet/netronome/nfp/bpf/jit.c
drivers/net/ethernet/netronome/nfp/bpf/main.h

index 98a94ca36bfa0abbc838c67c4b690f10e87ff6c3..ccb80a5ac828682b4f5e3344b2fd7c08927cc422 100644 (file)
@@ -4018,20 +4018,35 @@ void nfp_bpf_jit_prepare(struct nfp_prog *nfp_prog, unsigned int cnt)
 
        /* Another pass to record jump information. */
        list_for_each_entry(meta, &nfp_prog->insns, l) {
+               struct nfp_insn_meta *dst_meta;
                u64 code = meta->insn.code;
+               unsigned int dst_idx;
+               bool pseudo_call;
 
-               if (BPF_CLASS(code) == BPF_JMP && BPF_OP(code) != BPF_EXIT &&
-                   BPF_OP(code) != BPF_CALL) {
-                       struct nfp_insn_meta *dst_meta;
-                       unsigned short dst_indx;
+               if (BPF_CLASS(code) != BPF_JMP)
+                       continue;
+               if (BPF_OP(code) == BPF_EXIT)
+                       continue;
+               if (is_mbpf_helper_call(meta))
+                       continue;
 
-                       dst_indx = meta->n + 1 + meta->insn.off;
-                       dst_meta = nfp_bpf_goto_meta(nfp_prog, meta, dst_indx,
-                                                    cnt);
+               /* If opcode is BPF_CALL at this point, this can only be a
+                * BPF-to-BPF call (a.k.a pseudo call).
+                */
+               pseudo_call = BPF_OP(code) == BPF_CALL;
 
-                       meta->jmp_dst = dst_meta;
-                       dst_meta->flags |= FLAG_INSN_IS_JUMP_DST;
-               }
+               if (pseudo_call)
+                       dst_idx = meta->n + 1 + meta->insn.imm;
+               else
+                       dst_idx = meta->n + 1 + meta->insn.off;
+
+               dst_meta = nfp_bpf_goto_meta(nfp_prog, meta, dst_idx, cnt);
+
+               if (pseudo_call)
+                       dst_meta->flags |= FLAG_INSN_IS_SUBPROG_START;
+
+               dst_meta->flags |= FLAG_INSN_IS_JUMP_DST;
+               meta->jmp_dst = dst_meta;
        }
 }
 
index 853a5346378cfada6f8ea8ae3bb6f39970ea3ba7..20a98ce4b345824165da43d8954a67fad83ab1e2 100644 (file)
@@ -262,7 +262,8 @@ struct nfp_bpf_reg_state {
        bool var_off;
 };
 
-#define FLAG_INSN_IS_JUMP_DST  BIT(0)
+#define FLAG_INSN_IS_JUMP_DST                  BIT(0)
+#define FLAG_INSN_IS_SUBPROG_START             BIT(1)
 
 /**
  * struct nfp_insn_meta - BPF instruction wrapper