@@ -361,6 +361,7 @@ struct bpf_prog_offload_ops {
struct bpf_insn *insn);
int (*remove_insns)(struct bpf_verifier_env *env, u32 off, u32 cnt);
/* program management callbacks */
+ int (*setup)(struct bpf_prog *prog);
int (*prepare)(struct bpf_prog *prog);
int (*translate)(struct bpf_prog *prog);
void (*destroy)(struct bpf_prog *prog);
@@ -418,6 +418,7 @@ static inline struct bpf_reg_state *cur_regs(struct bpf_verifier_env *env)
return cur_func(env)->regs;
}
+int bpf_prog_offload_verifier_setup(struct bpf_prog *prog);
int bpf_prog_offload_verifier_prep(struct bpf_prog *prog);
int bpf_prog_offload_verify_insn(struct bpf_verifier_env *env,
int insn_idx, int prev_insn_idx);
@@ -124,6 +124,20 @@ int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr)
return err;
}
+int bpf_prog_offload_verifier_setup(struct bpf_prog *prog)
+{
+ struct bpf_prog_offload *offload;
+ int ret = 0;
+
+ down_read(&bpf_devs_lock);
+ offload = prog->aux->offload;
+ if (offload && offload->offdev->ops->setup)
+ ret = offload->offdev->ops->setup(prog);
+ up_read(&bpf_devs_lock);
+
+ return ret;
+}
+
int bpf_prog_offload_verifier_prep(struct bpf_prog *prog)
{
struct bpf_prog_offload *offload;
@@ -9737,6 +9737,12 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr,
env->allow_ptr_leaks = is_priv;
+ if (bpf_prog_is_dev_bound(env->prog->aux)) {
+ ret = bpf_prog_offload_verifier_setup(env->prog);
+ if (ret)
+ goto skip_full_check;
+ }
+
if (is_priv)
env->test_state_freq = attr->prog_flags & BPF_F_TEST_STATE_FREQ;