aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
authorMartin KaFai Lau <kafai@fb.com>2017-06-28 02:08:34 -0400
committerDavid S. Miller <davem@davemloft.net>2017-06-29 13:13:25 -0400
commit14dc6f04f49dc12614d7e90928b495b8d73cd471 (patch)
tree159ebddef04be2ae417c503ab46593be570c680f /kernel/bpf/syscall.c
parent77b0d3617738e532bae683bf9d88ea35fff223e5 (diff)
bpf: Add syscall lookup support for fd array and htab
This patch allows userspace to do BPF_MAP_LOOKUP_ELEM on BPF_MAP_TYPE_PROG_ARRAY, BPF_MAP_TYPE_ARRAY_OF_MAPS and BPF_MAP_TYPE_HASH_OF_MAPS. The lookup returns a prog-id or map-id to the userspace. The userspace can then use the BPF_PROG_GET_FD_BY_ID or BPF_MAP_GET_FD_BY_ID to get a fd. Signed-off-by: Martin KaFai Lau <kafai@fb.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 8942c820d620..4409ccca8831 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -24,6 +24,13 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/idr.h> 25#include <linux/idr.h>
26 26
27#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
28 (map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
29 (map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
30 (map)->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS)
31#define IS_FD_HASH(map) ((map)->map_type == BPF_MAP_TYPE_HASH_OF_MAPS)
32#define IS_FD_MAP(map) (IS_FD_ARRAY(map) || IS_FD_HASH(map))
33
27DEFINE_PER_CPU(int, bpf_prog_active); 34DEFINE_PER_CPU(int, bpf_prog_active);
28static DEFINE_IDR(prog_idr); 35static DEFINE_IDR(prog_idr);
29static DEFINE_SPINLOCK(prog_idr_lock); 36static DEFINE_SPINLOCK(prog_idr_lock);
@@ -411,6 +418,8 @@ static int map_lookup_elem(union bpf_attr *attr)
411 map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH || 418 map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
412 map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) 419 map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY)
413 value_size = round_up(map->value_size, 8) * num_possible_cpus(); 420 value_size = round_up(map->value_size, 8) * num_possible_cpus();
421 else if (IS_FD_MAP(map))
422 value_size = sizeof(u32);
414 else 423 else
415 value_size = map->value_size; 424 value_size = map->value_size;
416 425
@@ -426,9 +435,10 @@ static int map_lookup_elem(union bpf_attr *attr)
426 err = bpf_percpu_array_copy(map, key, value); 435 err = bpf_percpu_array_copy(map, key, value);
427 } else if (map->map_type == BPF_MAP_TYPE_STACK_TRACE) { 436 } else if (map->map_type == BPF_MAP_TYPE_STACK_TRACE) {
428 err = bpf_stackmap_copy(map, key, value); 437 err = bpf_stackmap_copy(map, key, value);
429 } else if (map->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS || 438 } else if (IS_FD_ARRAY(map)) {
430 map->map_type == BPF_MAP_TYPE_HASH_OF_MAPS) { 439 err = bpf_fd_array_map_lookup_elem(map, key, value);
431 err = -ENOTSUPP; 440 } else if (IS_FD_HASH(map)) {
441 err = bpf_fd_htab_map_lookup_elem(map, key, value);
432 } else { 442 } else {
433 rcu_read_lock(); 443 rcu_read_lock();
434 ptr = map->ops->map_lookup_elem(map, key); 444 ptr = map->ops->map_lookup_elem(map, key);