| From c6110222c6f49ea68169f353565eb865488a8619 Mon Sep 17 00:00:00 2001 |
| From: Daniel Borkmann <daniel@iogearbox.net> |
| Date: Tue, 14 May 2019 01:18:55 +0200 |
| Subject: bpf: add map_lookup_elem_sys_only for lookups from syscall side |
| |
| From: Daniel Borkmann <daniel@iogearbox.net> |
| |
| commit c6110222c6f49ea68169f353565eb865488a8619 upstream. |
| |
| Add a callback map_lookup_elem_sys_only() that map implementations |
| could use over map_lookup_elem() from system call side in case the |
| map implementation needs to handle the latter differently than from |
| the BPF data path. If map_lookup_elem_sys_only() is set, this will |
| be preferred pick for map lookups out of user space. This hook is |
| used in a follow-up fix for LRU map, but once development window |
| opens, we can convert other map types from map_lookup_elem() (here, |
| the one called upon BPF_MAP_LOOKUP_ELEM cmd is meant) over to use |
| the callback to simplify and clean up the latter. |
| |
| Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> |
| Acked-by: Martin KaFai Lau <kafai@fb.com> |
| Signed-off-by: Alexei Starovoitov <ast@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| |
| --- |
| include/linux/bpf.h | 1 + |
| kernel/bpf/syscall.c | 5 ++++- |
| 2 files changed, 5 insertions(+), 1 deletion(-) |
| |
| --- a/include/linux/bpf.h |
| +++ b/include/linux/bpf.h |
| @@ -34,6 +34,7 @@ struct bpf_map_ops { |
| void (*map_free)(struct bpf_map *map); |
| int (*map_get_next_key)(struct bpf_map *map, void *key, void *next_key); |
| void (*map_release_uref)(struct bpf_map *map); |
| + void *(*map_lookup_elem_sys_only)(struct bpf_map *map, void *key); |
| |
| /* funcs callable from userspace and from eBPF programs */ |
| void *(*map_lookup_elem)(struct bpf_map *map, void *key); |
| --- a/kernel/bpf/syscall.c |
| +++ b/kernel/bpf/syscall.c |
| @@ -721,7 +721,10 @@ static int map_lookup_elem(union bpf_att |
| err = bpf_fd_reuseport_array_lookup_elem(map, key, value); |
| } else { |
| rcu_read_lock(); |
| - ptr = map->ops->map_lookup_elem(map, key); |
| + if (map->ops->map_lookup_elem_sys_only) |
| + ptr = map->ops->map_lookup_elem_sys_only(map, key); |
| + else |
| + ptr = map->ops->map_lookup_elem(map, key); |
| if (ptr) |
| memcpy(value, ptr, value_size); |
| rcu_read_unlock(); |