mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-01 00:58:39 +02:00 
			
		
		
		
	bpf: call verifier_prep from its callback in struct bpf_offload_dev
In a way similar to the change previously brought to the verify_insn hook and to the finalize callback, switch to the newly added ops in struct bpf_prog_offload for calling the functions used to prepare driver verifiers. Since the dev_ops pointer in struct bpf_prog_offload is no longer used by any callback, we can now remove it from struct bpf_prog_offload. Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com> Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
		
							parent
							
								
									6dc18fa6f4
								
							
						
					
					
						commit
						00db12c3d1
					
				
					 5 changed files with 32 additions and 41 deletions
				
			
		|  | @ -188,10 +188,11 @@ static void nfp_prog_free(struct nfp_prog *nfp_prog) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int | static int | ||||||
| nfp_bpf_verifier_prep(struct nfp_app *app, struct nfp_net *nn, | nfp_bpf_verifier_prep(struct net_device *netdev, struct bpf_verifier_env *env) | ||||||
| 		      struct netdev_bpf *bpf) |  | ||||||
| { | { | ||||||
| 	struct bpf_prog *prog = bpf->verifier.prog; | 	struct nfp_net *nn = netdev_priv(netdev); | ||||||
|  | 	struct bpf_prog *prog = env->prog; | ||||||
|  | 	struct nfp_app *app = nn->app; | ||||||
| 	struct nfp_prog *nfp_prog; | 	struct nfp_prog *nfp_prog; | ||||||
| 	int ret; | 	int ret; | ||||||
| 
 | 
 | ||||||
|  | @ -209,7 +210,6 @@ nfp_bpf_verifier_prep(struct nfp_app *app, struct nfp_net *nn, | ||||||
| 		goto err_free; | 		goto err_free; | ||||||
| 
 | 
 | ||||||
| 	nfp_prog->verifier_meta = nfp_prog_first_meta(nfp_prog); | 	nfp_prog->verifier_meta = nfp_prog_first_meta(nfp_prog); | ||||||
| 	bpf->verifier.ops = &nfp_bpf_dev_ops; |  | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| 
 | 
 | ||||||
|  | @ -422,8 +422,6 @@ nfp_bpf_map_free(struct nfp_app_bpf *bpf, struct bpf_offloaded_map *offmap) | ||||||
| int nfp_ndo_bpf(struct nfp_app *app, struct nfp_net *nn, struct netdev_bpf *bpf) | int nfp_ndo_bpf(struct nfp_app *app, struct nfp_net *nn, struct netdev_bpf *bpf) | ||||||
| { | { | ||||||
| 	switch (bpf->command) { | 	switch (bpf->command) { | ||||||
| 	case BPF_OFFLOAD_VERIFIER_PREP: |  | ||||||
| 		return nfp_bpf_verifier_prep(app, nn, bpf); |  | ||||||
| 	case BPF_OFFLOAD_TRANSLATE: | 	case BPF_OFFLOAD_TRANSLATE: | ||||||
| 		return nfp_bpf_translate(nn, bpf->offload.prog); | 		return nfp_bpf_translate(nn, bpf->offload.prog); | ||||||
| 	case BPF_OFFLOAD_DESTROY: | 	case BPF_OFFLOAD_DESTROY: | ||||||
|  | @ -605,4 +603,5 @@ int nfp_net_bpf_offload(struct nfp_net *nn, struct bpf_prog *prog, | ||||||
| const struct bpf_prog_offload_ops nfp_bpf_dev_ops = { | const struct bpf_prog_offload_ops nfp_bpf_dev_ops = { | ||||||
| 	.insn_hook	= nfp_verify_insn, | 	.insn_hook	= nfp_verify_insn, | ||||||
| 	.finalize	= nfp_bpf_finalize, | 	.finalize	= nfp_bpf_finalize, | ||||||
|  | 	.prepare	= nfp_bpf_verifier_prep, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -91,11 +91,6 @@ static int nsim_bpf_finalize(struct bpf_verifier_env *env) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct bpf_prog_offload_ops nsim_bpf_dev_ops = { |  | ||||||
| 	.insn_hook	= nsim_bpf_verify_insn, |  | ||||||
| 	.finalize	= nsim_bpf_finalize, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| static bool nsim_xdp_offload_active(struct netdevsim *ns) | static bool nsim_xdp_offload_active(struct netdevsim *ns) | ||||||
| { | { | ||||||
| 	return ns->xdp_hw.prog; | 	return ns->xdp_hw.prog; | ||||||
|  | @ -263,6 +258,17 @@ static int nsim_bpf_create_prog(struct netdevsim *ns, struct bpf_prog *prog) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static int | ||||||
|  | nsim_bpf_verifier_prep(struct net_device *dev, struct bpf_verifier_env *env) | ||||||
|  | { | ||||||
|  | 	struct netdevsim *ns = netdev_priv(dev); | ||||||
|  | 
 | ||||||
|  | 	if (!ns->bpf_bind_accept) | ||||||
|  | 		return -EOPNOTSUPP; | ||||||
|  | 
 | ||||||
|  | 	return nsim_bpf_create_prog(ns, env->prog); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void nsim_bpf_destroy_prog(struct bpf_prog *prog) | static void nsim_bpf_destroy_prog(struct bpf_prog *prog) | ||||||
| { | { | ||||||
| 	struct nsim_bpf_bound_prog *state; | 	struct nsim_bpf_bound_prog *state; | ||||||
|  | @ -275,6 +281,12 @@ static void nsim_bpf_destroy_prog(struct bpf_prog *prog) | ||||||
| 	kfree(state); | 	kfree(state); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static const struct bpf_prog_offload_ops nsim_bpf_dev_ops = { | ||||||
|  | 	.insn_hook	= nsim_bpf_verify_insn, | ||||||
|  | 	.finalize	= nsim_bpf_finalize, | ||||||
|  | 	.prepare	= nsim_bpf_verifier_prep, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| static int nsim_setup_prog_checks(struct netdevsim *ns, struct netdev_bpf *bpf) | static int nsim_setup_prog_checks(struct netdevsim *ns, struct netdev_bpf *bpf) | ||||||
| { | { | ||||||
| 	if (bpf->prog && bpf->prog->aux->offload) { | 	if (bpf->prog && bpf->prog->aux->offload) { | ||||||
|  | @ -539,16 +551,6 @@ int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf) | ||||||
| 	ASSERT_RTNL(); | 	ASSERT_RTNL(); | ||||||
| 
 | 
 | ||||||
| 	switch (bpf->command) { | 	switch (bpf->command) { | ||||||
| 	case BPF_OFFLOAD_VERIFIER_PREP: |  | ||||||
| 		if (!ns->bpf_bind_accept) |  | ||||||
| 			return -EOPNOTSUPP; |  | ||||||
| 
 |  | ||||||
| 		err = nsim_bpf_create_prog(ns, bpf->verifier.prog); |  | ||||||
| 		if (err) |  | ||||||
| 			return err; |  | ||||||
| 
 |  | ||||||
| 		bpf->verifier.ops = &nsim_bpf_dev_ops; |  | ||||||
| 		return 0; |  | ||||||
| 	case BPF_OFFLOAD_TRANSLATE: | 	case BPF_OFFLOAD_TRANSLATE: | ||||||
| 		state = bpf->offload.prog->aux->offload->dev_priv; | 		state = bpf->offload.prog->aux->offload->dev_priv; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -268,6 +268,7 @@ struct bpf_prog_offload_ops { | ||||||
| 	int (*insn_hook)(struct bpf_verifier_env *env, | 	int (*insn_hook)(struct bpf_verifier_env *env, | ||||||
| 			 int insn_idx, int prev_insn_idx); | 			 int insn_idx, int prev_insn_idx); | ||||||
| 	int (*finalize)(struct bpf_verifier_env *env); | 	int (*finalize)(struct bpf_verifier_env *env); | ||||||
|  | 	int (*prepare)(struct net_device *netdev, struct bpf_verifier_env *env); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct bpf_prog_offload { | struct bpf_prog_offload { | ||||||
|  | @ -277,7 +278,6 @@ struct bpf_prog_offload { | ||||||
| 	void			*dev_priv; | 	void			*dev_priv; | ||||||
| 	struct list_head	offloads; | 	struct list_head	offloads; | ||||||
| 	bool			dev_state; | 	bool			dev_state; | ||||||
| 	const struct bpf_prog_offload_ops *dev_ops; |  | ||||||
| 	void			*jited_image; | 	void			*jited_image; | ||||||
| 	u32			jited_len; | 	u32			jited_len; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -863,7 +863,6 @@ enum bpf_netdev_command { | ||||||
| 	XDP_QUERY_PROG, | 	XDP_QUERY_PROG, | ||||||
| 	XDP_QUERY_PROG_HW, | 	XDP_QUERY_PROG_HW, | ||||||
| 	/* BPF program for offload callbacks, invoked at program load time. */ | 	/* BPF program for offload callbacks, invoked at program load time. */ | ||||||
| 	BPF_OFFLOAD_VERIFIER_PREP, |  | ||||||
| 	BPF_OFFLOAD_TRANSLATE, | 	BPF_OFFLOAD_TRANSLATE, | ||||||
| 	BPF_OFFLOAD_DESTROY, | 	BPF_OFFLOAD_DESTROY, | ||||||
| 	BPF_OFFLOAD_MAP_ALLOC, | 	BPF_OFFLOAD_MAP_ALLOC, | ||||||
|  | @ -891,11 +890,6 @@ struct netdev_bpf { | ||||||
| 			/* flags with which program was installed */ | 			/* flags with which program was installed */ | ||||||
| 			u32 prog_flags; | 			u32 prog_flags; | ||||||
| 		}; | 		}; | ||||||
| 		/* BPF_OFFLOAD_VERIFIER_PREP */ |  | ||||||
| 		struct { |  | ||||||
| 			struct bpf_prog *prog; |  | ||||||
| 			const struct bpf_prog_offload_ops *ops; /* callee set */ |  | ||||||
| 		} verifier; |  | ||||||
| 		/* BPF_OFFLOAD_TRANSLATE, BPF_OFFLOAD_DESTROY */ | 		/* BPF_OFFLOAD_TRANSLATE, BPF_OFFLOAD_DESTROY */ | ||||||
| 		struct { | 		struct { | ||||||
| 			struct bpf_prog *prog; | 			struct bpf_prog *prog; | ||||||
|  |  | ||||||
|  | @ -142,21 +142,17 @@ static int __bpf_offload_ndo(struct bpf_prog *prog, enum bpf_netdev_command cmd, | ||||||
| 
 | 
 | ||||||
| int bpf_prog_offload_verifier_prep(struct bpf_verifier_env *env) | int bpf_prog_offload_verifier_prep(struct bpf_verifier_env *env) | ||||||
| { | { | ||||||
| 	struct netdev_bpf data = {}; | 	struct bpf_prog_offload *offload; | ||||||
| 	int err; | 	int ret = -ENODEV; | ||||||
| 
 | 
 | ||||||
| 	data.verifier.prog = env->prog; | 	down_read(&bpf_devs_lock); | ||||||
|  | 	offload = env->prog->aux->offload; | ||||||
|  | 	if (offload) | ||||||
|  | 		ret = offload->offdev->ops->prepare(offload->netdev, env); | ||||||
|  | 	offload->dev_state = !ret; | ||||||
|  | 	up_read(&bpf_devs_lock); | ||||||
| 
 | 
 | ||||||
| 	rtnl_lock(); | 	return ret; | ||||||
| 	err = __bpf_offload_ndo(env->prog, BPF_OFFLOAD_VERIFIER_PREP, &data); |  | ||||||
| 	if (err) |  | ||||||
| 		goto exit_unlock; |  | ||||||
| 
 |  | ||||||
| 	env->prog->aux->offload->dev_ops = data.verifier.ops; |  | ||||||
| 	env->prog->aux->offload->dev_state = true; |  | ||||||
| exit_unlock: |  | ||||||
| 	rtnl_unlock(); |  | ||||||
| 	return err; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int bpf_prog_offload_verify_insn(struct bpf_verifier_env *env, | int bpf_prog_offload_verify_insn(struct bpf_verifier_env *env, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Quentin Monnet
						Quentin Monnet