]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - kernel/bpf/syscall.c
bpf: Add syscall lookup support for fd array and htab
[linux.git] / kernel / bpf / syscall.c
index 8942c820d620a15ef38ff6904c0a2f647cdab7be..4409ccca88310622d74ab57b21b63ae3469aaebe 100644 (file)
 #include <linux/kernel.h>
 #include <linux/idr.h>
 
+#define IS_FD_ARRAY(map) ((map)->map_type == BPF_MAP_TYPE_PROG_ARRAY || \
+                          (map)->map_type == BPF_MAP_TYPE_PERF_EVENT_ARRAY || \
+                          (map)->map_type == BPF_MAP_TYPE_CGROUP_ARRAY || \
+                          (map)->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS)
+#define IS_FD_HASH(map) ((map)->map_type == BPF_MAP_TYPE_HASH_OF_MAPS)
+#define IS_FD_MAP(map) (IS_FD_ARRAY(map) || IS_FD_HASH(map))
+
 DEFINE_PER_CPU(int, bpf_prog_active);
 static DEFINE_IDR(prog_idr);
 static DEFINE_SPINLOCK(prog_idr_lock);
@@ -411,6 +418,8 @@ static int map_lookup_elem(union bpf_attr *attr)
            map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
            map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY)
                value_size = round_up(map->value_size, 8) * num_possible_cpus();
+       else if (IS_FD_MAP(map))
+               value_size = sizeof(u32);
        else
                value_size = map->value_size;
 
@@ -426,9 +435,10 @@ static int map_lookup_elem(union bpf_attr *attr)
                err = bpf_percpu_array_copy(map, key, value);
        } else if (map->map_type == BPF_MAP_TYPE_STACK_TRACE) {
                err = bpf_stackmap_copy(map, key, value);
-       } else if (map->map_type == BPF_MAP_TYPE_ARRAY_OF_MAPS ||
-                  map->map_type == BPF_MAP_TYPE_HASH_OF_MAPS) {
-               err = -ENOTSUPP;
+       } else if (IS_FD_ARRAY(map)) {
+               err = bpf_fd_array_map_lookup_elem(map, key, value);
+       } else if (IS_FD_HASH(map)) {
+               err = bpf_fd_htab_map_lookup_elem(map, key, value);
        } else {
                rcu_read_lock();
                ptr = map->ops->map_lookup_elem(map, key);