This patch centre find_subprog and add_subprog to cfg.c. Signed-off-by: Jiong Wang <jiong.w...@netronome.com> --- kernel/bpf/cfg.c | 41 +++++++++++++++++++++++++++++++++++++++++ kernel/bpf/cfg.h | 2 ++ kernel/bpf/verifier.c | 42 ------------------------------------------ 3 files changed, 43 insertions(+), 42 deletions(-)
diff --git a/kernel/bpf/cfg.c b/kernel/bpf/cfg.c index 7ce1472..a34a95c 100644 --- a/kernel/bpf/cfg.c +++ b/kernel/bpf/cfg.c @@ -6,8 +6,10 @@ */ #include <linux/bpf_verifier.h> +#include <linux/bsearch.h> #include <linux/list.h> #include <linux/slab.h> +#include <linux/sort.h> #include "cfg.h" @@ -611,6 +613,45 @@ bool subprog_has_loop(struct bpf_subprog_info *subprog) return false; } +static int cmp_subprogs(const void *a, const void *b) +{ + return ((struct bpf_subprog_info *)a)->start - + ((struct bpf_subprog_info *)b)->start; +} + +int find_subprog(struct bpf_verifier_env *env, int off) +{ + struct bpf_subprog_info *p; + + p = bsearch(&off, env->subprog_info, env->subprog_cnt, + sizeof(env->subprog_info[0]), cmp_subprogs); + if (!p) + return -ENOENT; + return p - env->subprog_info; +} + +int add_subprog(struct bpf_verifier_env *env, int off) +{ + int insn_cnt = env->prog->len; + int ret; + + if (off >= insn_cnt || off < 0) { + bpf_verifier_log_write(env, "call to invalid destination\n"); + return -EINVAL; + } + ret = find_subprog(env, off); + if (ret >= 0) + return 0; + if (env->subprog_cnt >= BPF_MAX_SUBPROGS) { + bpf_verifier_log_write(env, "too many subprograms\n"); + return -E2BIG; + } + env->subprog_info[env->subprog_cnt++].start = off; + sort(env->subprog_info, env->subprog_cnt, + sizeof(env->subprog_info[0]), cmp_subprogs, NULL); + return 0; +} + static void subprog_free_edge(struct bb_node *bb) { struct list_head *succs = &bb->e_succs; diff --git a/kernel/bpf/cfg.h b/kernel/bpf/cfg.h index 02729a9..57eab9b 100644 --- a/kernel/bpf/cfg.h +++ b/kernel/bpf/cfg.h @@ -8,6 +8,8 @@ #ifndef __BPF_CFG_H__ #define __BPF_CFG_H__ +int add_subprog(struct bpf_verifier_env *env, int off); +int find_subprog(struct bpf_verifier_env *env, int off); int subprog_add_bb_edges(struct bpf_insn *insns, struct list_head *bb_list); int subprog_append_bb(struct list_head *bb_list, int head); int subprog_build_dom_info(struct bpf_verifier_env *env, diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 46d5eae..72bda84 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -20,8 +20,6 @@ #include <linux/file.h> #include <linux/vmalloc.h> #include <linux/stringify.h> -#include <linux/bsearch.h> -#include <linux/sort.h> #include "cfg.h" #include "disasm.h" @@ -737,46 +735,6 @@ enum reg_arg_type { DST_OP_NO_MARK /* same as above, check only, don't mark */ }; -static int cmp_subprogs(const void *a, const void *b) -{ - return ((struct bpf_subprog_info *)a)->start - - ((struct bpf_subprog_info *)b)->start; -} - -static int find_subprog(struct bpf_verifier_env *env, int off) -{ - struct bpf_subprog_info *p; - - p = bsearch(&off, env->subprog_info, env->subprog_cnt, - sizeof(env->subprog_info[0]), cmp_subprogs); - if (!p) - return -ENOENT; - return p - env->subprog_info; - -} - -static int add_subprog(struct bpf_verifier_env *env, int off) -{ - int insn_cnt = env->prog->len; - int ret; - - if (off >= insn_cnt || off < 0) { - verbose(env, "call to invalid destination\n"); - return -EINVAL; - } - ret = find_subprog(env, off); - if (ret >= 0) - return 0; - if (env->subprog_cnt >= BPF_MAX_SUBPROGS) { - verbose(env, "too many subprograms\n"); - return -E2BIG; - } - env->subprog_info[env->subprog_cnt++].start = off; - sort(env->subprog_info, env->subprog_cnt, - sizeof(env->subprog_info[0]), cmp_subprogs, NULL); - return 0; -} - static int check_subprogs(struct bpf_verifier_env *env) { int i, ret, subprog_start, subprog_end, off, cur_subprog = 0; -- 2.7.4