aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2018-08-11 19:59:17 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-08-12 18:52:45 -0400
commite8d2bec0457962e8f348a9a3627b398f7fe5c5fc (patch)
tree9bda920c6a2940980aeb18a79b827b11e3f1cb0d /kernel/bpf/syscall.c
parent9d6f417714c3aaf67b23ffdc1d2b036cce3ecc1c (diff)
bpf: decouple btf from seq bpf fs dump and enable more maps
Commit a26ca7c982cb ("bpf: btf: Add pretty print support to the basic arraymap") and 699c86d6ec21 ("bpf: btf: add pretty print for hash/lru_hash maps") enabled support for BTF and dumping via BPF fs for array and hash/lru map. However, both can be decoupled from each other such that regular BPF maps can be supported for attaching BTF key/value information, while not all maps necessarily need to dump via map_seq_show_elem() callback. The basic sanity check which is a prerequisite for all maps is that key/value size has to match in any case, and some maps can have extra checks via map_check_btf() callback, e.g. probing certain types or indicating no support in general. With that we can also enable retrieving BTF info for per-cpu map types and lpm. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Acked-by: Yonghong Song <yhs@fb.com>
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 57f4d076141b..43727ed0d94a 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -103,6 +103,7 @@ int bpf_check_uarg_tail_zero(void __user *uaddr,
103const struct bpf_map_ops bpf_map_offload_ops = { 103const struct bpf_map_ops bpf_map_offload_ops = {
104 .map_alloc = bpf_map_offload_map_alloc, 104 .map_alloc = bpf_map_offload_map_alloc,
105 .map_free = bpf_map_offload_map_free, 105 .map_free = bpf_map_offload_map_free,
106 .map_check_btf = map_check_no_btf,
106}; 107};
107 108
108static struct bpf_map *find_and_alloc_map(union bpf_attr *attr) 109static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
@@ -455,6 +456,34 @@ static int bpf_obj_name_cpy(char *dst, const char *src)
455 return 0; 456 return 0;
456} 457}
457 458
459int map_check_no_btf(const struct bpf_map *map,
460 const struct btf_type *key_type,
461 const struct btf_type *value_type)
462{
463 return -ENOTSUPP;
464}
465
466static int map_check_btf(const struct bpf_map *map, const struct btf *btf,
467 u32 btf_key_id, u32 btf_value_id)
468{
469 const struct btf_type *key_type, *value_type;
470 u32 key_size, value_size;
471 int ret = 0;
472
473 key_type = btf_type_id_size(btf, &btf_key_id, &key_size);
474 if (!key_type || key_size != map->key_size)
475 return -EINVAL;
476
477 value_type = btf_type_id_size(btf, &btf_value_id, &value_size);
478 if (!value_type || value_size != map->value_size)
479 return -EINVAL;
480
481 if (map->ops->map_check_btf)
482 ret = map->ops->map_check_btf(map, key_type, value_type);
483
484 return ret;
485}
486
458#define BPF_MAP_CREATE_LAST_FIELD btf_value_type_id 487#define BPF_MAP_CREATE_LAST_FIELD btf_value_type_id
459/* called via syscall */ 488/* called via syscall */
460static int map_create(union bpf_attr *attr) 489static int map_create(union bpf_attr *attr)
@@ -489,8 +518,7 @@ static int map_create(union bpf_attr *attr)
489 atomic_set(&map->refcnt, 1); 518 atomic_set(&map->refcnt, 1);
490 atomic_set(&map->usercnt, 1); 519 atomic_set(&map->usercnt, 1);
491 520
492 if (bpf_map_support_seq_show(map) && 521 if (attr->btf_key_type_id || attr->btf_value_type_id) {
493 (attr->btf_key_type_id || attr->btf_value_type_id)) {
494 struct btf *btf; 522 struct btf *btf;
495 523
496 if (!attr->btf_key_type_id || !attr->btf_value_type_id) { 524 if (!attr->btf_key_type_id || !attr->btf_value_type_id) {
@@ -504,8 +532,8 @@ static int map_create(union bpf_attr *attr)
504 goto free_map_nouncharge; 532 goto free_map_nouncharge;
505 } 533 }
506 534
507 err = map->ops->map_check_btf(map, btf, attr->btf_key_type_id, 535 err = map_check_btf(map, btf, attr->btf_key_type_id,
508 attr->btf_value_type_id); 536 attr->btf_value_type_id);
509 if (err) { 537 if (err) {
510 btf_put(btf); 538 btf_put(btf);
511 goto free_map_nouncharge; 539 goto free_map_nouncharge;