hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/net/ethernet/netronome/nfp/bpf/main.c
....@@ -1,35 +1,5 @@
1
-/*
2
- * Copyright (C) 2017-2018 Netronome Systems, Inc.
3
- *
4
- * This software is dual licensed under the GNU General License Version 2,
5
- * June 1991 as shown in the file COPYING in the top-level directory of this
6
- * source tree or the BSD 2-Clause License provided below. You have the
7
- * option to license this software under the complete terms of either license.
8
- *
9
- * The BSD 2-Clause License:
10
- *
11
- * Redistribution and use in source and binary forms, with or
12
- * without modification, are permitted provided that the following
13
- * conditions are met:
14
- *
15
- * 1. Redistributions of source code must retain the above
16
- * copyright notice, this list of conditions and the following
17
- * disclaimer.
18
- *
19
- * 2. Redistributions in binary form must reproduce the above
20
- * copyright notice, this list of conditions and the following
21
- * disclaimer in the documentation and/or other materials
22
- * provided with the distribution.
23
- *
24
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
- * SOFTWARE.
32
- */
1
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2
+/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
333
344 #include <net/pkt_cls.h>
355
....@@ -45,7 +15,7 @@
4515
4616 const struct rhashtable_params nfp_bpf_maps_neutral_params = {
4717 .nelem_hint = 4,
48
- .key_len = FIELD_SIZEOF(struct bpf_map, id),
18
+ .key_len = sizeof_field(struct bpf_map, id),
4919 .key_offset = offsetof(struct nfp_bpf_neutral_map, map_id),
5020 .head_offset = offsetof(struct nfp_bpf_neutral_map, l),
5121 .automatic_shrinking = true,
....@@ -54,11 +24,14 @@
5424 static bool nfp_net_ebpf_capable(struct nfp_net *nn)
5525 {
5626 #ifdef __LITTLE_ENDIAN
57
- if (nn->cap & NFP_NET_CFG_CTRL_BPF &&
58
- nn_readb(nn, NFP_NET_CFG_BPF_ABI) == NFP_NET_BPF_ABI)
59
- return true;
60
-#endif
27
+ struct nfp_app_bpf *bpf = nn->app->priv;
28
+
29
+ return nn->cap & NFP_NET_CFG_CTRL_BPF &&
30
+ bpf->abi_version &&
31
+ nn_readb(nn, NFP_NET_CFG_BPF_ABI) == bpf->abi_version;
32
+#else
6133 return false;
34
+#endif
6235 }
6336
6437 static int
....@@ -187,35 +160,19 @@
187160 return 0;
188161 }
189162
190
-static int nfp_bpf_setup_tc_block(struct net_device *netdev,
191
- struct tc_block_offload *f)
192
-{
193
- struct nfp_net *nn = netdev_priv(netdev);
194
-
195
- if (f->binder_type != TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS)
196
- return -EOPNOTSUPP;
197
-
198
- switch (f->command) {
199
- case TC_BLOCK_BIND:
200
- return tcf_block_cb_register(f->block,
201
- nfp_bpf_setup_tc_block_cb,
202
- nn, nn, f->extack);
203
- case TC_BLOCK_UNBIND:
204
- tcf_block_cb_unregister(f->block,
205
- nfp_bpf_setup_tc_block_cb,
206
- nn);
207
- return 0;
208
- default:
209
- return -EOPNOTSUPP;
210
- }
211
-}
163
+static LIST_HEAD(nfp_bpf_block_cb_list);
212164
213165 static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev,
214166 enum tc_setup_type type, void *type_data)
215167 {
168
+ struct nfp_net *nn = netdev_priv(netdev);
169
+
216170 switch (type) {
217171 case TC_SETUP_BLOCK:
218
- return nfp_bpf_setup_tc_block(netdev, type_data);
172
+ return flow_block_cb_setup_simple(type_data,
173
+ &nfp_bpf_block_cb_list,
174
+ nfp_bpf_setup_tc_block_cb,
175
+ nn, nn, true);
219176 default:
220177 return -EOPNOTSUPP;
221178 }
....@@ -225,15 +182,21 @@
225182 nfp_bpf_check_mtu(struct nfp_app *app, struct net_device *netdev, int new_mtu)
226183 {
227184 struct nfp_net *nn = netdev_priv(netdev);
228
- unsigned int max_mtu;
185
+ struct nfp_bpf_vnic *bv;
186
+ struct bpf_prog *prog;
229187
230188 if (~nn->dp.ctrl & NFP_NET_CFG_CTRL_BPF)
231189 return 0;
232190
233
- max_mtu = nn_readb(nn, NFP_NET_CFG_BPF_INL_MTU) * 64 - 32;
234
- if (new_mtu > max_mtu) {
235
- nn_info(nn, "BPF offload active, MTU over %u not supported\n",
236
- max_mtu);
191
+ if (nn->xdp_hw.prog) {
192
+ prog = nn->xdp_hw.prog;
193
+ } else {
194
+ bv = nn->app_priv;
195
+ prog = bv->tc_prog;
196
+ }
197
+
198
+ if (nfp_bpf_offload_check_mtu(nn, prog, new_mtu)) {
199
+ nn_info(nn, "BPF offload active, potential packet access beyond hardware packet boundary");
237200 return -EBUSY;
238201 }
239202 return 0;
....@@ -342,6 +305,34 @@
342305 return 0;
343306 }
344307
308
+static int
309
+nfp_bpf_parse_cap_cmsg_multi_ent(struct nfp_app_bpf *bpf, void __iomem *value,
310
+ u32 length)
311
+{
312
+ bpf->cmsg_multi_ent = true;
313
+ return 0;
314
+}
315
+
316
+static int
317
+nfp_bpf_parse_cap_abi_version(struct nfp_app_bpf *bpf, void __iomem *value,
318
+ u32 length)
319
+{
320
+ if (length < 4) {
321
+ nfp_err(bpf->app->cpp, "truncated ABI version TLV: %d\n",
322
+ length);
323
+ return -EINVAL;
324
+ }
325
+
326
+ bpf->abi_version = readl(value);
327
+ if (bpf->abi_version < 2 || bpf->abi_version > 3) {
328
+ nfp_warn(bpf->app->cpp, "unsupported BPF ABI version: %d\n",
329
+ bpf->abi_version);
330
+ bpf->abi_version = 0;
331
+ }
332
+
333
+ return 0;
334
+}
335
+
345336 static int nfp_bpf_parse_capabilities(struct nfp_app *app)
346337 {
347338 struct nfp_cpp *cpp = app->pf->cpp;
....@@ -393,6 +384,16 @@
393384 length))
394385 goto err_release_free;
395386 break;
387
+ case NFP_BPF_CAP_TYPE_ABI_VERSION:
388
+ if (nfp_bpf_parse_cap_abi_version(app->priv, value,
389
+ length))
390
+ goto err_release_free;
391
+ break;
392
+ case NFP_BPF_CAP_TYPE_CMSG_MULTI_ENT:
393
+ if (nfp_bpf_parse_cap_cmsg_multi_ent(app->priv, value,
394
+ length))
395
+ goto err_release_free;
396
+ break;
396397 default:
397398 nfp_dbg(cpp, "unknown BPF capability: %d\n", type);
398399 break;
....@@ -414,6 +415,11 @@
414415 return -EINVAL;
415416 }
416417
418
+static void nfp_bpf_init_capabilities(struct nfp_app_bpf *bpf)
419
+{
420
+ bpf->abi_version = 2; /* Original BPF ABI version */
421
+}
422
+
417423 static int nfp_bpf_ndo_init(struct nfp_app *app, struct net_device *netdev)
418424 {
419425 struct nfp_app_bpf *bpf = app->priv;
....@@ -428,6 +434,25 @@
428434 bpf_offload_dev_netdev_unregister(bpf->bpf_dev, netdev);
429435 }
430436
437
+static int nfp_bpf_start(struct nfp_app *app)
438
+{
439
+ struct nfp_app_bpf *bpf = app->priv;
440
+
441
+ if (app->ctrl->dp.mtu < nfp_bpf_ctrl_cmsg_min_mtu(bpf)) {
442
+ nfp_err(bpf->app->cpp,
443
+ "ctrl channel MTU below min required %u < %u\n",
444
+ app->ctrl->dp.mtu, nfp_bpf_ctrl_cmsg_min_mtu(bpf));
445
+ return -EINVAL;
446
+ }
447
+
448
+ if (bpf->cmsg_multi_ent)
449
+ bpf->cmsg_cache_cnt = nfp_bpf_ctrl_cmsg_cache_cnt(bpf);
450
+ else
451
+ bpf->cmsg_cache_cnt = 1;
452
+
453
+ return 0;
454
+}
455
+
431456 static int nfp_bpf_init(struct nfp_app *app)
432457 {
433458 struct nfp_app_bpf *bpf;
....@@ -439,19 +464,32 @@
439464 bpf->app = app;
440465 app->priv = bpf;
441466
442
- skb_queue_head_init(&bpf->cmsg_replies);
443
- init_waitqueue_head(&bpf->cmsg_wq);
444467 INIT_LIST_HEAD(&bpf->map_list);
468
+
469
+ err = nfp_ccm_init(&bpf->ccm, app);
470
+ if (err)
471
+ goto err_free_bpf;
445472
446473 err = rhashtable_init(&bpf->maps_neutral, &nfp_bpf_maps_neutral_params);
447474 if (err)
448
- goto err_free_bpf;
475
+ goto err_clean_ccm;
476
+
477
+ nfp_bpf_init_capabilities(bpf);
449478
450479 err = nfp_bpf_parse_capabilities(app);
451480 if (err)
452481 goto err_free_neutral_maps;
453482
454
- bpf->bpf_dev = bpf_offload_dev_create();
483
+ if (bpf->abi_version < 3) {
484
+ bpf->cmsg_key_sz = CMSG_MAP_KEY_LW * 4;
485
+ bpf->cmsg_val_sz = CMSG_MAP_VALUE_LW * 4;
486
+ } else {
487
+ bpf->cmsg_key_sz = bpf->maps.max_key_sz;
488
+ bpf->cmsg_val_sz = bpf->maps.max_val_sz;
489
+ app->ctrl_mtu = nfp_bpf_ctrl_cmsg_mtu(bpf);
490
+ }
491
+
492
+ bpf->bpf_dev = bpf_offload_dev_create(&nfp_bpf_dev_ops, bpf);
455493 err = PTR_ERR_OR_ZERO(bpf->bpf_dev);
456494 if (err)
457495 goto err_free_neutral_maps;
....@@ -460,14 +498,11 @@
460498
461499 err_free_neutral_maps:
462500 rhashtable_destroy(&bpf->maps_neutral);
501
+err_clean_ccm:
502
+ nfp_ccm_clean(&bpf->ccm);
463503 err_free_bpf:
464504 kfree(bpf);
465505 return err;
466
-}
467
-
468
-static void nfp_check_rhashtable_empty(void *ptr, void *arg)
469
-{
470
- WARN_ON_ONCE(1);
471506 }
472507
473508 static void nfp_bpf_clean(struct nfp_app *app)
....@@ -475,7 +510,7 @@
475510 struct nfp_app_bpf *bpf = app->priv;
476511
477512 bpf_offload_dev_destroy(bpf->bpf_dev);
478
- WARN_ON(!skb_queue_empty(&bpf->cmsg_replies));
513
+ nfp_ccm_clean(&bpf->ccm);
479514 WARN_ON(!list_empty(&bpf->map_list));
480515 WARN_ON(bpf->maps_in_use || bpf->map_elems_in_use);
481516 rhashtable_free_and_destroy(&bpf->maps_neutral,
....@@ -491,6 +526,7 @@
491526
492527 .init = nfp_bpf_init,
493528 .clean = nfp_bpf_clean,
529
+ .start = nfp_bpf_start,
494530
495531 .check_mtu = nfp_bpf_check_mtu,
496532