diff options
Diffstat (limited to 'kernel/bpf/arraymap.c')
-rw-r--r-- | kernel/bpf/arraymap.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c index ecb43542246e..d771a3872500 100644 --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c | |||
@@ -335,6 +335,26 @@ static void *fd_array_map_lookup_elem(struct bpf_map *map, void *key) | |||
335 | } | 335 | } |
336 | 336 | ||
337 | /* only called from syscall */ | 337 | /* only called from syscall */ |
338 | int bpf_fd_array_map_lookup_elem(struct bpf_map *map, void *key, u32 *value) | ||
339 | { | ||
340 | void **elem, *ptr; | ||
341 | int ret = 0; | ||
342 | |||
343 | if (!map->ops->map_fd_sys_lookup_elem) | ||
344 | return -ENOTSUPP; | ||
345 | |||
346 | rcu_read_lock(); | ||
347 | elem = array_map_lookup_elem(map, key); | ||
348 | if (elem && (ptr = READ_ONCE(*elem))) | ||
349 | *value = map->ops->map_fd_sys_lookup_elem(ptr); | ||
350 | else | ||
351 | ret = -ENOENT; | ||
352 | rcu_read_unlock(); | ||
353 | |||
354 | return ret; | ||
355 | } | ||
356 | |||
357 | /* only called from syscall */ | ||
338 | int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file, | 358 | int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file, |
339 | void *key, void *value, u64 map_flags) | 359 | void *key, void *value, u64 map_flags) |
340 | { | 360 | { |
@@ -400,6 +420,11 @@ static void prog_fd_array_put_ptr(void *ptr) | |||
400 | bpf_prog_put(ptr); | 420 | bpf_prog_put(ptr); |
401 | } | 421 | } |
402 | 422 | ||
423 | static u32 prog_fd_array_sys_lookup_elem(void *ptr) | ||
424 | { | ||
425 | return ((struct bpf_prog *)ptr)->aux->id; | ||
426 | } | ||
427 | |||
403 | /* decrement refcnt of all bpf_progs that are stored in this map */ | 428 | /* decrement refcnt of all bpf_progs that are stored in this map */ |
404 | void bpf_fd_array_map_clear(struct bpf_map *map) | 429 | void bpf_fd_array_map_clear(struct bpf_map *map) |
405 | { | 430 | { |
@@ -418,6 +443,7 @@ const struct bpf_map_ops prog_array_map_ops = { | |||
418 | .map_delete_elem = fd_array_map_delete_elem, | 443 | .map_delete_elem = fd_array_map_delete_elem, |
419 | .map_fd_get_ptr = prog_fd_array_get_ptr, | 444 | .map_fd_get_ptr = prog_fd_array_get_ptr, |
420 | .map_fd_put_ptr = prog_fd_array_put_ptr, | 445 | .map_fd_put_ptr = prog_fd_array_put_ptr, |
446 | .map_fd_sys_lookup_elem = prog_fd_array_sys_lookup_elem, | ||
421 | }; | 447 | }; |
422 | 448 | ||
423 | static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file, | 449 | static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file, |
@@ -585,4 +611,5 @@ const struct bpf_map_ops array_of_maps_map_ops = { | |||
585 | .map_delete_elem = fd_array_map_delete_elem, | 611 | .map_delete_elem = fd_array_map_delete_elem, |
586 | .map_fd_get_ptr = bpf_map_fd_get_ptr, | 612 | .map_fd_get_ptr = bpf_map_fd_get_ptr, |
587 | .map_fd_put_ptr = bpf_map_fd_put_ptr, | 613 | .map_fd_put_ptr = bpf_map_fd_put_ptr, |
614 | .map_fd_sys_lookup_elem = bpf_map_fd_sys_lookup_elem, | ||
588 | }; | 615 | }; |