From: Jakub Kicinski Date: Fri, 15 Dec 2017 05:29:17 +0000 (-0800) Subject: nfp: bpf: prepare for call support X-Git-Tag: v4.19~1702^2~346^2~5^2~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2cb230bdedb1b422507359ebc39d8f134300bf01;p=platform%2Fkernel%2Flinux-rpi3.git nfp: bpf: prepare for call support Add skeleton of verifier checks and translation handler for call instructions. Make sure jump target resolution will not treat them as jumps. Signed-off-by: Jakub Kicinski Signed-off-by: Daniel Borkmann --- diff --git a/drivers/net/ethernet/netronome/nfp/bpf/jit.c b/drivers/net/ethernet/netronome/nfp/bpf/jit.c index 3419ad4..7afdc6d 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/jit.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/jit.c @@ -1930,6 +1930,15 @@ static int jne_reg(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) return wrp_test_reg(nfp_prog, meta, ALU_OP_XOR, BR_BNE); } +static int call(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) +{ + switch (meta->insn.imm) { + default: + WARN_ONCE(1, "verifier allowed unsupported function\n"); + return -EOPNOTSUPP; + } +} + static int goto_out(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) { wrp_br_special(nfp_prog, BR_UNC, OP_BR_GO_OUT); @@ -2002,6 +2011,7 @@ static const instr_cb_t instr_cb[256] = { [BPF_JMP | BPF_JLE | BPF_X] = jle_reg, [BPF_JMP | BPF_JSET | BPF_X] = jset_reg, [BPF_JMP | BPF_JNE | BPF_X] = jne_reg, + [BPF_JMP | BPF_CALL] = call, [BPF_JMP | BPF_EXIT] = goto_out, }; @@ -2026,6 +2036,8 @@ static int nfp_fixup_branches(struct nfp_prog *nfp_prog) list_for_each_entry(meta, &nfp_prog->insns, l) { if (meta->skip) continue; + if (meta->insn.code == (BPF_JMP | BPF_CALL)) + continue; if (BPF_CLASS(meta->insn.code) != BPF_JMP) continue; diff --git a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c index d2bf29c..3b940b6 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c @@ -69,6 +69,20 @@ nfp_bpf_goto_meta(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta, } static int +nfp_bpf_check_call(struct nfp_prog *nfp_prog, struct nfp_insn_meta *meta) +{ + u32 func_id = meta->insn.imm; + + switch (func_id) { + default: + pr_warn("unsupported function id: %d\n", func_id); + return -EOPNOTSUPP; + } + + return 0; +} + +static int nfp_bpf_check_exit(struct nfp_prog *nfp_prog, struct bpf_verifier_env *env) { @@ -177,6 +191,8 @@ nfp_verify_insn(struct bpf_verifier_env *env, int insn_idx, int prev_insn_idx) return -EINVAL; } + if (meta->insn.code == (BPF_JMP | BPF_CALL)) + return nfp_bpf_check_call(nfp_prog, meta); if (meta->insn.code == (BPF_JMP | BPF_EXIT)) return nfp_bpf_check_exit(nfp_prog, env);