diff options
author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2018-03-28 20:48:30 -0400 |
---|---|---|
committer | Alexei Starovoitov <ast@kernel.org> | 2018-03-28 22:36:13 -0400 |
commit | 289c5b763018be846900da706dc582e572a13864 (patch) | |
tree | 83243765db828050c143aa3c96937dbdfdb3f470 | |
parent | 2f46e0c1273512cbdb944f5a50cc93cf0888c3d7 (diff) |
nfp: bpf: add helper for basic map call checks
Add a verifier helper for performing the basic state checks
before a call to a map helper.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
Reviewed-by: Jiong Wang <jiong.wang@netronome.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-rw-r--r-- | drivers/net/ethernet/netronome/nfp/bpf/verifier.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c index 45aa11fcdcad..acfc4d798116 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c | |||
@@ -139,6 +139,28 @@ nfp_bpf_stack_arg_ok(const char *fname, struct bpf_verifier_env *env, | |||
139 | return true; | 139 | return true; |
140 | } | 140 | } |
141 | 141 | ||
142 | static bool | ||
143 | nfp_bpf_map_call_ok(const char *fname, struct bpf_verifier_env *env, | ||
144 | struct nfp_insn_meta *meta, | ||
145 | u32 helper_tgt, const struct bpf_reg_state *reg1) | ||
146 | { | ||
147 | if (!helper_tgt) { | ||
148 | pr_vlog(env, "%s: not supported by FW\n", fname); | ||
149 | return false; | ||
150 | } | ||
151 | |||
152 | /* Rest of the checks is only if we re-parse the same insn */ | ||
153 | if (!meta->func_id) | ||
154 | return true; | ||
155 | |||
156 | if (meta->arg1.map_ptr != reg1->map_ptr) { | ||
157 | pr_vlog(env, "%s: called for different map\n", fname); | ||
158 | return false; | ||
159 | } | ||
160 | |||
161 | return true; | ||
162 | } | ||
163 | |||
142 | static int | 164 | static int |
143 | nfp_bpf_check_call(struct nfp_prog *nfp_prog, struct bpf_verifier_env *env, | 165 | nfp_bpf_check_call(struct nfp_prog *nfp_prog, struct bpf_verifier_env *env, |
144 | struct nfp_insn_meta *meta) | 166 | struct nfp_insn_meta *meta) |
@@ -163,23 +185,11 @@ nfp_bpf_check_call(struct nfp_prog *nfp_prog, struct bpf_verifier_env *env, | |||
163 | break; | 185 | break; |
164 | 186 | ||
165 | case BPF_FUNC_map_lookup_elem: | 187 | case BPF_FUNC_map_lookup_elem: |
166 | if (!bpf->helpers.map_lookup) { | 188 | if (!nfp_bpf_map_call_ok("map_lookup", env, meta, |
167 | pr_vlog(env, "map_lookup: not supported by FW\n"); | 189 | bpf->helpers.map_lookup, reg1) || |
168 | return -EOPNOTSUPP; | 190 | !nfp_bpf_stack_arg_ok("map_lookup", env, reg2, |
169 | } | ||
170 | |||
171 | if (!nfp_bpf_stack_arg_ok("map_lookup", env, reg2, | ||
172 | meta->func_id ? &meta->arg2 : NULL)) | 191 | meta->func_id ? &meta->arg2 : NULL)) |
173 | return -EOPNOTSUPP; | 192 | return -EOPNOTSUPP; |
174 | |||
175 | /* Rest of the checks is only if we re-parse the same insn */ | ||
176 | if (!meta->func_id) | ||
177 | break; | ||
178 | |||
179 | if (meta->arg1.map_ptr != reg1->map_ptr) { | ||
180 | pr_vlog(env, "map_lookup: called for different map\n"); | ||
181 | return -EOPNOTSUPP; | ||
182 | } | ||
183 | break; | 193 | break; |
184 | default: | 194 | default: |
185 | pr_vlog(env, "unsupported function id: %d\n", func_id); | 195 | pr_vlog(env, "unsupported function id: %d\n", func_id); |