aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/arraymap.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/arraymap.c')
-rw-r--r--kernel/bpf/arraymap.c55
1 files changed, 34 insertions, 21 deletions
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 172dc8ee0e3b..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 */
338int 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 */
338int bpf_fd_array_map_update_elem(struct bpf_map *map, struct file *map_file, 358int 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
423static 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 */
404void bpf_fd_array_map_clear(struct bpf_map *map) 429void 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
423static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file, 449static struct bpf_event_entry *bpf_event_entry_gen(struct file *perf_file,
@@ -452,38 +478,24 @@ static void bpf_event_entry_free_rcu(struct bpf_event_entry *ee)
452static void *perf_event_fd_array_get_ptr(struct bpf_map *map, 478static void *perf_event_fd_array_get_ptr(struct bpf_map *map,
453 struct file *map_file, int fd) 479 struct file *map_file, int fd)
454{ 480{
455 const struct perf_event_attr *attr;
456 struct bpf_event_entry *ee; 481 struct bpf_event_entry *ee;
457 struct perf_event *event; 482 struct perf_event *event;
458 struct file *perf_file; 483 struct file *perf_file;
484 u64 value;
459 485
460 perf_file = perf_event_get(fd); 486 perf_file = perf_event_get(fd);
461 if (IS_ERR(perf_file)) 487 if (IS_ERR(perf_file))
462 return perf_file; 488 return perf_file;
463 489
490 ee = ERR_PTR(-EOPNOTSUPP);
464 event = perf_file->private_data; 491 event = perf_file->private_data;
465 ee = ERR_PTR(-EINVAL); 492 if (perf_event_read_local(event, &value) == -EOPNOTSUPP)
466
467 attr = perf_event_attrs(event);
468 if (IS_ERR(attr) || attr->inherit)
469 goto err_out; 493 goto err_out;
470 494
471 switch (attr->type) { 495 ee = bpf_event_entry_gen(perf_file, map_file);
472 case PERF_TYPE_SOFTWARE: 496 if (ee)
473 if (attr->config != PERF_COUNT_SW_BPF_OUTPUT) 497 return ee;
474 goto err_out; 498 ee = ERR_PTR(-ENOMEM);
475 /* fall-through */
476 case PERF_TYPE_RAW:
477 case PERF_TYPE_HARDWARE:
478 ee = bpf_event_entry_gen(perf_file, map_file);
479 if (ee)
480 return ee;
481 ee = ERR_PTR(-ENOMEM);
482 /* fall-through */
483 default:
484 break;
485 }
486
487err_out: 499err_out:
488 fput(perf_file); 500 fput(perf_file);
489 return ee; 501 return ee;
@@ -599,4 +611,5 @@ const struct bpf_map_ops array_of_maps_map_ops = {
599 .map_delete_elem = fd_array_map_delete_elem, 611 .map_delete_elem = fd_array_map_delete_elem,
600 .map_fd_get_ptr = bpf_map_fd_get_ptr, 612 .map_fd_get_ptr = bpf_map_fd_get_ptr,
601 .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,
602}; 615};