hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/net/netdevsim/bpf.c
....@@ -27,7 +27,7 @@
2727 bpf_verifier_log_write(env, "[netdevsim] " fmt, ##__VA_ARGS__)
2828
2929 struct nsim_bpf_bound_prog {
30
- struct netdevsim *ns;
30
+ struct nsim_dev *nsim_dev;
3131 struct bpf_prog *prog;
3232 struct dentry *ddir;
3333 const char *state;
....@@ -48,7 +48,7 @@
4848 struct list_head l;
4949 };
5050
51
-static int nsim_debugfs_bpf_string_read(struct seq_file *file, void *data)
51
+static int nsim_bpf_string_show(struct seq_file *file, void *data)
5252 {
5353 const char **str = file->private;
5454
....@@ -57,38 +57,32 @@
5757
5858 return 0;
5959 }
60
-
61
-static int nsim_debugfs_bpf_string_open(struct inode *inode, struct file *f)
62
-{
63
- return single_open(f, nsim_debugfs_bpf_string_read, inode->i_private);
64
-}
65
-
66
-static const struct file_operations nsim_bpf_string_fops = {
67
- .owner = THIS_MODULE,
68
- .open = nsim_debugfs_bpf_string_open,
69
- .release = single_release,
70
- .read = seq_read,
71
- .llseek = seq_lseek
72
-};
60
+DEFINE_SHOW_ATTRIBUTE(nsim_bpf_string);
7361
7462 static int
7563 nsim_bpf_verify_insn(struct bpf_verifier_env *env, int insn_idx, int prev_insn)
7664 {
7765 struct nsim_bpf_bound_prog *state;
66
+ int ret = 0;
7867
7968 state = env->prog->aux->offload->dev_priv;
80
- if (state->ns->bpf_bind_verifier_delay && !insn_idx)
81
- msleep(state->ns->bpf_bind_verifier_delay);
69
+ if (state->nsim_dev->bpf_bind_verifier_delay && !insn_idx)
70
+ msleep(state->nsim_dev->bpf_bind_verifier_delay);
8271
83
- if (insn_idx == env->prog->len - 1)
72
+ if (insn_idx == env->prog->len - 1) {
8473 pr_vlog(env, "Hello from netdevsim!\n");
8574
86
- return 0;
75
+ if (!state->nsim_dev->bpf_bind_verifier_accept)
76
+ ret = -EOPNOTSUPP;
77
+ }
78
+
79
+ return ret;
8780 }
8881
89
-static const struct bpf_prog_offload_ops nsim_bpf_analyzer_ops = {
90
- .insn_hook = nsim_bpf_verify_insn,
91
-};
82
+static int nsim_bpf_finalize(struct bpf_verifier_env *env)
83
+{
84
+ return 0;
85
+}
9286
9387 static bool nsim_xdp_offload_active(struct netdevsim *ns)
9488 {
....@@ -201,9 +195,6 @@
201195 {
202196 int err;
203197
204
- if (!xdp_attachment_flags_ok(xdp, bpf))
205
- return -EBUSY;
206
-
207198 if (bpf->command == XDP_SETUP_PROG && !ns->bpf_xdpdrv_accept) {
208199 NSIM_EA(bpf->extack, "driver XDP disabled in DebugFS");
209200 return -EOPNOTSUPP;
....@@ -224,25 +215,28 @@
224215 return 0;
225216 }
226217
227
-static int nsim_bpf_create_prog(struct netdevsim *ns, struct bpf_prog *prog)
218
+static int nsim_bpf_create_prog(struct nsim_dev *nsim_dev,
219
+ struct bpf_prog *prog)
228220 {
229221 struct nsim_bpf_bound_prog *state;
230222 char name[16];
223
+ int ret;
231224
232225 state = kzalloc(sizeof(*state), GFP_KERNEL);
233226 if (!state)
234227 return -ENOMEM;
235228
236
- state->ns = ns;
229
+ state->nsim_dev = nsim_dev;
237230 state->prog = prog;
238231 state->state = "verify";
239232
240233 /* Program id is not populated yet when we create the state. */
241
- sprintf(name, "%u", ns->sdev->prog_id_gen++);
242
- state->ddir = debugfs_create_dir(name, ns->sdev->ddir_bpf_bound_progs);
243
- if (IS_ERR_OR_NULL(state->ddir)) {
234
+ sprintf(name, "%u", nsim_dev->prog_id_gen++);
235
+ state->ddir = debugfs_create_dir(name, nsim_dev->ddir_bpf_bound_progs);
236
+ if (IS_ERR(state->ddir)) {
237
+ ret = PTR_ERR(state->ddir);
244238 kfree(state);
245
- return -ENOMEM;
239
+ return ret;
246240 }
247241
248242 debugfs_create_u32("id", 0400, state->ddir, &prog->aux->id);
....@@ -250,10 +244,29 @@
250244 &state->state, &nsim_bpf_string_fops);
251245 debugfs_create_bool("loaded", 0400, state->ddir, &state->is_loaded);
252246
253
- list_add_tail(&state->l, &ns->sdev->bpf_bound_progs);
247
+ list_add_tail(&state->l, &nsim_dev->bpf_bound_progs);
254248
255249 prog->aux->offload->dev_priv = state;
256250
251
+ return 0;
252
+}
253
+
254
+static int nsim_bpf_verifier_prep(struct bpf_prog *prog)
255
+{
256
+ struct nsim_dev *nsim_dev =
257
+ bpf_offload_dev_priv(prog->aux->offload->offdev);
258
+
259
+ if (!nsim_dev->bpf_bind_accept)
260
+ return -EOPNOTSUPP;
261
+
262
+ return nsim_bpf_create_prog(nsim_dev, prog);
263
+}
264
+
265
+static int nsim_bpf_translate(struct bpf_prog *prog)
266
+{
267
+ struct nsim_bpf_bound_prog *state = prog->aux->offload->dev_priv;
268
+
269
+ state->state = "xlated";
257270 return 0;
258271 }
259272
....@@ -268,6 +281,14 @@
268281 list_del(&state->l);
269282 kfree(state);
270283 }
284
+
285
+static const struct bpf_prog_offload_ops nsim_bpf_dev_ops = {
286
+ .insn_hook = nsim_bpf_verify_insn,
287
+ .finalize = nsim_bpf_finalize,
288
+ .prepare = nsim_bpf_verifier_prep,
289
+ .translate = nsim_bpf_translate,
290
+ .destroy = nsim_bpf_destroy_prog,
291
+};
271292
272293 static int nsim_setup_prog_checks(struct netdevsim *ns, struct netdev_bpf *bpf)
273294 {
....@@ -330,10 +351,12 @@
330351 {
331352 struct nsim_bpf_bound_map *nmap = offmap->dev_priv;
332353
333
- nmap->entry[idx].key = kmalloc(offmap->map.key_size, GFP_USER);
354
+ nmap->entry[idx].key = kmalloc(offmap->map.key_size,
355
+ GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
334356 if (!nmap->entry[idx].key)
335357 return -ENOMEM;
336
- nmap->entry[idx].value = kmalloc(offmap->map.value_size, GFP_USER);
358
+ nmap->entry[idx].value = kmalloc(offmap->map.value_size,
359
+ GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
337360 if (!nmap->entry[idx].value) {
338361 kfree(nmap->entry[idx].key);
339362 nmap->entry[idx].key = NULL;
....@@ -475,7 +498,7 @@
475498 if (offmap->map.map_flags)
476499 return -EINVAL;
477500
478
- nmap = kzalloc(sizeof(*nmap), GFP_USER);
501
+ nmap = kzalloc(sizeof(*nmap), GFP_KERNEL_ACCOUNT);
479502 if (!nmap)
480503 return -ENOMEM;
481504
....@@ -498,7 +521,7 @@
498521 }
499522
500523 offmap->dev_ops = &nsim_bpf_map_ops;
501
- list_add_tail(&nmap->l, &ns->sdev->bpf_bound_maps);
524
+ list_add_tail(&nmap->l, &ns->nsim_dev->bpf_bound_maps);
502525
503526 return 0;
504527
....@@ -528,34 +551,11 @@
528551 int nsim_bpf(struct net_device *dev, struct netdev_bpf *bpf)
529552 {
530553 struct netdevsim *ns = netdev_priv(dev);
531
- struct nsim_bpf_bound_prog *state;
532554 int err;
533555
534556 ASSERT_RTNL();
535557
536558 switch (bpf->command) {
537
- case BPF_OFFLOAD_VERIFIER_PREP:
538
- if (!ns->bpf_bind_accept)
539
- return -EOPNOTSUPP;
540
-
541
- err = nsim_bpf_create_prog(ns, bpf->verifier.prog);
542
- if (err)
543
- return err;
544
-
545
- bpf->verifier.ops = &nsim_bpf_analyzer_ops;
546
- return 0;
547
- case BPF_OFFLOAD_TRANSLATE:
548
- state = bpf->offload.prog->aux->offload->dev_priv;
549
-
550
- state->state = "xlated";
551
- return 0;
552
- case BPF_OFFLOAD_DESTROY:
553
- nsim_bpf_destroy_prog(bpf->offload.prog);
554
- return 0;
555
- case XDP_QUERY_PROG:
556
- return xdp_attachment_query(&ns->xdp, bpf);
557
- case XDP_QUERY_PROG_HW:
558
- return xdp_attachment_query(&ns->xdp_hw, bpf);
559559 case XDP_SETUP_PROG:
560560 err = nsim_setup_prog_checks(ns, bpf);
561561 if (err)
....@@ -581,60 +581,71 @@
581581 }
582582 }
583583
584
-int nsim_bpf_init(struct netdevsim *ns)
584
+int nsim_bpf_dev_init(struct nsim_dev *nsim_dev)
585585 {
586586 int err;
587587
588
- if (ns->sdev->refcnt == 1) {
589
- INIT_LIST_HEAD(&ns->sdev->bpf_bound_progs);
590
- INIT_LIST_HEAD(&ns->sdev->bpf_bound_maps);
588
+ INIT_LIST_HEAD(&nsim_dev->bpf_bound_progs);
589
+ INIT_LIST_HEAD(&nsim_dev->bpf_bound_maps);
591590
592
- ns->sdev->ddir_bpf_bound_progs =
593
- debugfs_create_dir("bpf_bound_progs", ns->sdev->ddir);
594
- if (IS_ERR_OR_NULL(ns->sdev->ddir_bpf_bound_progs))
595
- return -ENOMEM;
591
+ nsim_dev->ddir_bpf_bound_progs = debugfs_create_dir("bpf_bound_progs",
592
+ nsim_dev->ddir);
593
+ if (IS_ERR(nsim_dev->ddir_bpf_bound_progs))
594
+ return PTR_ERR(nsim_dev->ddir_bpf_bound_progs);
596595
597
- ns->sdev->bpf_dev = bpf_offload_dev_create();
598
- err = PTR_ERR_OR_ZERO(ns->sdev->bpf_dev);
599
- if (err)
600
- return err;
601
- }
602
-
603
- err = bpf_offload_dev_netdev_register(ns->sdev->bpf_dev, ns->netdev);
596
+ nsim_dev->bpf_dev = bpf_offload_dev_create(&nsim_bpf_dev_ops, nsim_dev);
597
+ err = PTR_ERR_OR_ZERO(nsim_dev->bpf_dev);
604598 if (err)
605
- goto err_destroy_bdev;
599
+ return err;
606600
607
- debugfs_create_u32("bpf_offloaded_id", 0400, ns->ddir,
601
+ nsim_dev->bpf_bind_accept = true;
602
+ debugfs_create_bool("bpf_bind_accept", 0600, nsim_dev->ddir,
603
+ &nsim_dev->bpf_bind_accept);
604
+ debugfs_create_u32("bpf_bind_verifier_delay", 0600, nsim_dev->ddir,
605
+ &nsim_dev->bpf_bind_verifier_delay);
606
+ nsim_dev->bpf_bind_verifier_accept = true;
607
+ debugfs_create_bool("bpf_bind_verifier_accept", 0600, nsim_dev->ddir,
608
+ &nsim_dev->bpf_bind_verifier_accept);
609
+ return 0;
610
+}
611
+
612
+void nsim_bpf_dev_exit(struct nsim_dev *nsim_dev)
613
+{
614
+ WARN_ON(!list_empty(&nsim_dev->bpf_bound_progs));
615
+ WARN_ON(!list_empty(&nsim_dev->bpf_bound_maps));
616
+ bpf_offload_dev_destroy(nsim_dev->bpf_dev);
617
+}
618
+
619
+int nsim_bpf_init(struct netdevsim *ns)
620
+{
621
+ struct dentry *ddir = ns->nsim_dev_port->ddir;
622
+ int err;
623
+
624
+ err = bpf_offload_dev_netdev_register(ns->nsim_dev->bpf_dev,
625
+ ns->netdev);
626
+ if (err)
627
+ return err;
628
+
629
+ debugfs_create_u32("bpf_offloaded_id", 0400, ddir,
608630 &ns->bpf_offloaded_id);
609631
610
- ns->bpf_bind_accept = true;
611
- debugfs_create_bool("bpf_bind_accept", 0600, ns->ddir,
612
- &ns->bpf_bind_accept);
613
- debugfs_create_u32("bpf_bind_verifier_delay", 0600, ns->ddir,
614
- &ns->bpf_bind_verifier_delay);
615
-
616632 ns->bpf_tc_accept = true;
617
- debugfs_create_bool("bpf_tc_accept", 0600, ns->ddir,
633
+ debugfs_create_bool("bpf_tc_accept", 0600, ddir,
618634 &ns->bpf_tc_accept);
619
- debugfs_create_bool("bpf_tc_non_bound_accept", 0600, ns->ddir,
635
+ debugfs_create_bool("bpf_tc_non_bound_accept", 0600, ddir,
620636 &ns->bpf_tc_non_bound_accept);
621637 ns->bpf_xdpdrv_accept = true;
622
- debugfs_create_bool("bpf_xdpdrv_accept", 0600, ns->ddir,
638
+ debugfs_create_bool("bpf_xdpdrv_accept", 0600, ddir,
623639 &ns->bpf_xdpdrv_accept);
624640 ns->bpf_xdpoffload_accept = true;
625
- debugfs_create_bool("bpf_xdpoffload_accept", 0600, ns->ddir,
641
+ debugfs_create_bool("bpf_xdpoffload_accept", 0600, ddir,
626642 &ns->bpf_xdpoffload_accept);
627643
628644 ns->bpf_map_accept = true;
629
- debugfs_create_bool("bpf_map_accept", 0600, ns->ddir,
645
+ debugfs_create_bool("bpf_map_accept", 0600, ddir,
630646 &ns->bpf_map_accept);
631647
632648 return 0;
633
-
634
-err_destroy_bdev:
635
- if (ns->sdev->refcnt == 1)
636
- bpf_offload_dev_destroy(ns->sdev->bpf_dev);
637
- return err;
638649 }
639650
640651 void nsim_bpf_uninit(struct netdevsim *ns)
....@@ -642,11 +653,5 @@
642653 WARN_ON(ns->xdp.prog);
643654 WARN_ON(ns->xdp_hw.prog);
644655 WARN_ON(ns->bpf_offloaded);
645
- bpf_offload_dev_netdev_unregister(ns->sdev->bpf_dev, ns->netdev);
646
-
647
- if (ns->sdev->refcnt == 1) {
648
- WARN_ON(!list_empty(&ns->sdev->bpf_bound_progs));
649
- WARN_ON(!list_empty(&ns->sdev->bpf_bound_maps));
650
- bpf_offload_dev_destroy(ns->sdev->bpf_dev);
651
- }
656
+ bpf_offload_dev_netdev_unregister(ns->nsim_dev->bpf_dev, ns->netdev);
652657 }