diff options
Diffstat (limited to 'drivers/net/netdevsim/bpf.c')
-rw-r--r-- | drivers/net/netdevsim/bpf.c | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/drivers/net/netdevsim/bpf.c b/drivers/net/netdevsim/bpf.c index c36d2a768202..81444208b216 100644 --- a/drivers/net/netdevsim/bpf.c +++ b/drivers/net/netdevsim/bpf.c | |||
@@ -238,8 +238,8 @@ static int nsim_bpf_create_prog(struct netdevsim *ns, struct bpf_prog *prog) | |||
238 | state->state = "verify"; | 238 | state->state = "verify"; |
239 | 239 | ||
240 | /* Program id is not populated yet when we create the state. */ | 240 | /* Program id is not populated yet when we create the state. */ |
241 | sprintf(name, "%u", ns->prog_id_gen++); | 241 | sprintf(name, "%u", ns->sdev->prog_id_gen++); |
242 | state->ddir = debugfs_create_dir(name, ns->ddir_bpf_bound_progs); | 242 | state->ddir = debugfs_create_dir(name, ns->sdev->ddir_bpf_bound_progs); |
243 | if (IS_ERR_OR_NULL(state->ddir)) { | 243 | if (IS_ERR_OR_NULL(state->ddir)) { |
244 | kfree(state); | 244 | kfree(state); |
245 | return -ENOMEM; | 245 | return -ENOMEM; |
@@ -250,7 +250,7 @@ static int nsim_bpf_create_prog(struct netdevsim *ns, struct bpf_prog *prog) | |||
250 | &state->state, &nsim_bpf_string_fops); | 250 | &state->state, &nsim_bpf_string_fops); |
251 | debugfs_create_bool("loaded", 0400, state->ddir, &state->is_loaded); | 251 | debugfs_create_bool("loaded", 0400, state->ddir, &state->is_loaded); |
252 | 252 | ||
253 | list_add_tail(&state->l, &ns->bpf_bound_progs); | 253 | list_add_tail(&state->l, &ns->sdev->bpf_bound_progs); |
254 | 254 | ||
255 | prog->aux->offload->dev_priv = state; | 255 | prog->aux->offload->dev_priv = state; |
256 | 256 | ||
@@ -294,7 +294,7 @@ nsim_setup_prog_hw_checks(struct netdevsim *ns, struct netdev_bpf *bpf) | |||
294 | NSIM_EA(bpf->extack, "xdpoffload of non-bound program"); | 294 | NSIM_EA(bpf->extack, "xdpoffload of non-bound program"); |
295 | return -EINVAL; | 295 | return -EINVAL; |
296 | } | 296 | } |
297 | if (bpf->prog->aux->offload->netdev != ns->netdev) { | 297 | if (!bpf_offload_dev_match(bpf->prog, ns->netdev)) { |
298 | NSIM_EA(bpf->extack, "program bound to different dev"); | 298 | NSIM_EA(bpf->extack, "program bound to different dev"); |
299 | return -EINVAL; | 299 | return -EINVAL; |
300 | } | 300 | } |
@@ -497,7 +497,7 @@ nsim_bpf_map_alloc(struct netdevsim *ns, struct bpf_offloaded_map *offmap) | |||
497 | } | 497 | } |
498 | 498 | ||
499 | offmap->dev_ops = &nsim_bpf_map_ops; | 499 | offmap->dev_ops = &nsim_bpf_map_ops; |
500 | list_add_tail(&nmap->l, &ns->bpf_bound_maps); | 500 | list_add_tail(&nmap->l, &ns->sdev->bpf_bound_maps); |
501 | 501 | ||
502 | return 0; | 502 | return 0; |
503 | 503 | ||
@@ -582,8 +582,26 @@ int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf) | |||
582 | 582 | ||
583 | int nsim_bpf_init(struct netdevsim *ns) | 583 | int nsim_bpf_init(struct netdevsim *ns) |
584 | { | 584 | { |
585 | INIT_LIST_HEAD(&ns->bpf_bound_progs); | 585 | int err; |
586 | INIT_LIST_HEAD(&ns->bpf_bound_maps); | 586 | |
587 | if (ns->sdev->refcnt == 1) { | ||
588 | INIT_LIST_HEAD(&ns->sdev->bpf_bound_progs); | ||
589 | INIT_LIST_HEAD(&ns->sdev->bpf_bound_maps); | ||
590 | |||
591 | ns->sdev->ddir_bpf_bound_progs = | ||
592 | debugfs_create_dir("bpf_bound_progs", ns->sdev->ddir); | ||
593 | if (IS_ERR_OR_NULL(ns->sdev->ddir_bpf_bound_progs)) | ||
594 | return -ENOMEM; | ||
595 | |||
596 | ns->sdev->bpf_dev = bpf_offload_dev_create(); | ||
597 | err = PTR_ERR_OR_ZERO(ns->sdev->bpf_dev); | ||
598 | if (err) | ||
599 | return err; | ||
600 | } | ||
601 | |||
602 | err = bpf_offload_dev_netdev_register(ns->sdev->bpf_dev, ns->netdev); | ||
603 | if (err) | ||
604 | goto err_destroy_bdev; | ||
587 | 605 | ||
588 | debugfs_create_u32("bpf_offloaded_id", 0400, ns->ddir, | 606 | debugfs_create_u32("bpf_offloaded_id", 0400, ns->ddir, |
589 | &ns->bpf_offloaded_id); | 607 | &ns->bpf_offloaded_id); |
@@ -593,10 +611,6 @@ int nsim_bpf_init(struct netdevsim *ns) | |||
593 | &ns->bpf_bind_accept); | 611 | &ns->bpf_bind_accept); |
594 | debugfs_create_u32("bpf_bind_verifier_delay", 0600, ns->ddir, | 612 | debugfs_create_u32("bpf_bind_verifier_delay", 0600, ns->ddir, |
595 | &ns->bpf_bind_verifier_delay); | 613 | &ns->bpf_bind_verifier_delay); |
596 | ns->ddir_bpf_bound_progs = | ||
597 | debugfs_create_dir("bpf_bound_progs", ns->ddir); | ||
598 | if (IS_ERR_OR_NULL(ns->ddir_bpf_bound_progs)) | ||
599 | return -ENOMEM; | ||
600 | 614 | ||
601 | ns->bpf_tc_accept = true; | 615 | ns->bpf_tc_accept = true; |
602 | debugfs_create_bool("bpf_tc_accept", 0600, ns->ddir, | 616 | debugfs_create_bool("bpf_tc_accept", 0600, ns->ddir, |
@@ -615,13 +629,23 @@ int nsim_bpf_init(struct netdevsim *ns) | |||
615 | &ns->bpf_map_accept); | 629 | &ns->bpf_map_accept); |
616 | 630 | ||
617 | return 0; | 631 | return 0; |
632 | |||
633 | err_destroy_bdev: | ||
634 | if (ns->sdev->refcnt == 1) | ||
635 | bpf_offload_dev_destroy(ns->sdev->bpf_dev); | ||
636 | return err; | ||
618 | } | 637 | } |
619 | 638 | ||
620 | void nsim_bpf_uninit(struct netdevsim *ns) | 639 | void nsim_bpf_uninit(struct netdevsim *ns) |
621 | { | 640 | { |
622 | WARN_ON(!list_empty(&ns->bpf_bound_progs)); | ||
623 | WARN_ON(!list_empty(&ns->bpf_bound_maps)); | ||
624 | WARN_ON(ns->xdp.prog); | 641 | WARN_ON(ns->xdp.prog); |
625 | WARN_ON(ns->xdp_hw.prog); | 642 | WARN_ON(ns->xdp_hw.prog); |
626 | WARN_ON(ns->bpf_offloaded); | 643 | WARN_ON(ns->bpf_offloaded); |
644 | bpf_offload_dev_netdev_unregister(ns->sdev->bpf_dev, ns->netdev); | ||
645 | |||
646 | if (ns->sdev->refcnt == 1) { | ||
647 | WARN_ON(!list_empty(&ns->sdev->bpf_bound_progs)); | ||
648 | WARN_ON(!list_empty(&ns->sdev->bpf_bound_maps)); | ||
649 | bpf_offload_dev_destroy(ns->sdev->bpf_dev); | ||
650 | } | ||
627 | } | 651 | } |