Add new helper: long bpf_btf_find_by_name_kind(char *name, int name_sz, u32 kind, int flags) Description Find BTF type with given name and kind in vmlinux BTF or in module's BTFs. Return Returns btf_id and btf_obj_fd in lower and upper 32 bits. It will be used by loader program to find btf_id to attach the program to and to find btf_ids of ksyms.
Unified · Split
| @@ -1974,6 +1974,7 @@ extern const struct bpf_func_proto bpf_get_socket_ptr_cookie_proto; · 1973 unmodified lines | |||
| 1974 | extern const struct bpf_func_proto bpf_task_storage_get_proto; | 1974 | extern const struct bpf_func_proto bpf_task_storage_get_proto; |
| 1975 | extern const struct bpf_func_proto bpf_task_storage_delete_proto; | 1975 | extern const struct bpf_func_proto bpf_task_storage_delete_proto; |
| 1976 | extern const struct bpf_func_proto bpf_for_each_map_elem_proto; | 1976 | extern const struct bpf_func_proto bpf_for_each_map_elem_proto; |
| 1977 | extern const struct bpf_func_proto bpf_btf_find_by_name_kind_proto; | ||
| 1977 | 1978 | ||
| 1978 | const struct bpf_func_proto *bpf_tracing_func_proto( | 1979 | const struct bpf_func_proto *bpf_tracing_func_proto( |
| 1979 | enum bpf_func_id func_id, const struct bpf_prog *prog); | 1980 | enum bpf_func_id func_id, const struct bpf_prog *prog); |
| @@ -4748,6 +4748,12 @@ union bpf_attr { · 4747 unmodified lines | |||
| 4748 | * Execute bpf syscall with given arguments. | 4748 | * Execute bpf syscall with given arguments. |
| 4749 | * Return | 4749 | * Return |
| 4750 | * A syscall result. | 4750 | * A syscall result. |
| 4751 | * | ||
| 4752 | * long bpf_btf_find_by_name_kind(char *name, int name_sz, u32 kind, int flags) | ||
| 4753 | * Description | ||
| 4754 | * Find BTF type with given name and kind in vmlinux BTF or in module's BTFs. | ||
| 4755 | * Return | ||
| 4756 | * Returns btf_id and btf_obj_fd in lower and upper 32 bits. | ||
| 4751 | */ | 4757 | */ |
| 4752 | #define __BPF_FUNC_MAPPER(FN) \ | 4758 | #define __BPF_FUNC_MAPPER(FN) \ |
| 4753 | FN(unspec), \ | 4759 | FN(unspec), \ |
| @@ -4917,6 +4923,7 @@ union bpf_attr { · 163 unmodified lines | |||
| 4917 | FN(for_each_map_elem), \ | 4923 | FN(for_each_map_elem), \ |
| 4918 | FN(snprintf), \ | 4924 | FN(snprintf), \ |
| 4919 | FN(sys_bpf), \ | 4925 | FN(sys_bpf), \ |
| 4926 | FN(btf_find_by_name_kind), \ | ||
| 4920 | /* */ | 4927 | /* */ |
| 4921 | 4928 | ||
| 4922 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper | 4929 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper |
| @@ -6085,3 +6085,65 @@ struct module *btf_try_get_module(const struct btf *btf) · 6084 unmodified lines | |||
| 6085 | 6085 | ||
| 6086 | return res; | 6086 | return res; |
| 6087 | } | 6087 | } |
| 6088 | |||
| 6089 | BPF_CALL_4(bpf_btf_find_by_name_kind, char *, name, int, name_sz, u32, kind, int, flags) | ||
| 6090 | { | ||
| 6091 | struct btf *btf; | ||
| 6092 | long ret; | ||
| 6093 | |||
| 6094 | if (flags) | ||
| 6095 | return -EINVAL; | ||
| 6096 | |||
| 6097 | if (name_sz <= 1 || name[name_sz - 1]) | ||
| 6098 | return -EINVAL; | ||
| 6099 | |||
| 6100 | btf = bpf_get_btf_vmlinux(); | ||
| 6101 | if (IS_ERR(btf)) | ||
| 6102 | return PTR_ERR(btf); | ||
| 6103 | |||
| 6104 | ret = btf_find_by_name_kind(btf, name, kind); | ||
| 6105 | /* ret is never zero, since btf_find_by_name_kind returns | ||
| 6106 | * positive btf_id or negative error. | ||
| 6107 | */ | ||
| 6108 | if (ret < 0) { | ||
| 6109 | struct btf *mod_btf; | ||
| 6110 | int id; | ||
| 6111 | |||
| 6112 | /* If name is not found in vmlinux's BTF then search in module's BTFs */ | ||
| 6113 | spin_lock_bh(&btf_idr_lock); | ||
| 6114 | idr_for_each_entry(&btf_idr, mod_btf, id) { | ||
| 6115 | if (!btf_is_module(mod_btf)) | ||
| 6116 | continue; | ||
| 6117 | /* linear search could be slow hence unlock/lock | ||
| 6118 | * the IDR to avoiding holding it for too long | ||
| 6119 | */ | ||
| 6120 | btf_get(mod_btf); | ||
| 6121 | spin_unlock_bh(&btf_idr_lock); | ||
| 6122 | ret = btf_find_by_name_kind(mod_btf, name, kind); | ||
| 6123 | if (ret > 0) { | ||
| 6124 | int btf_obj_fd; | ||
| 6125 | |||
| 6126 | btf_obj_fd = __btf_new_fd(mod_btf); | ||
| 6127 | if (btf_obj_fd < 0) { | ||
| 6128 | btf_put(mod_btf); | ||
| 6129 | return btf_obj_fd; | ||
| 6130 | } | ||
| 6131 | return ret | (((u64)btf_obj_fd) << 32); | ||
| 6132 | } | ||
| 6133 | spin_lock_bh(&btf_idr_lock); | ||
| 6134 | btf_put(mod_btf); | ||
| 6135 | } | ||
| 6136 | spin_unlock_bh(&btf_idr_lock); | ||
| 6137 | } | ||
| 6138 | return ret; | ||
| 6139 | } | ||
| 6140 | |||
| 6141 | const struct bpf_func_proto bpf_btf_find_by_name_kind_proto = { | ||
| 6142 | .func = bpf_btf_find_by_name_kind, | ||
| 6143 | .gpl_only = false, | ||
| 6144 | .ret_type = RET_INTEGER, | ||
| 6145 | .arg1_type = ARG_PTR_TO_MEM, | ||
| 6146 | .arg2_type = ARG_CONST_SIZE, | ||
| 6147 | .arg3_type = ARG_ANYTHING, | ||
| 6148 | .arg4_type = ARG_ANYTHING, | ||
| 6149 | }; | ||
| @@ -4584,6 +4584,8 @@ syscall_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 4583 unmodified lines | |||
| 4584 | switch (func_id) { | 4584 | switch (func_id) { |
| 4585 | case BPF_FUNC_sys_bpf: | 4585 | case BPF_FUNC_sys_bpf: |
| 4586 | return &bpf_sys_bpf_proto; | 4586 | return &bpf_sys_bpf_proto; |
| 4587 | case BPF_FUNC_btf_find_by_name_kind: | ||
| 4588 | return &bpf_btf_find_by_name_kind_proto; | ||
| 4587 | default: | 4589 | default: |
| 4588 | return tracing_prog_func_proto(func_id, prog); | 4590 | return tracing_prog_func_proto(func_id, prog); |
| 4589 | } | 4591 | } |
| @@ -4748,6 +4748,12 @@ union bpf_attr { · 4747 unmodified lines | |||
| 4748 | * Execute bpf syscall with given arguments. | 4748 | * Execute bpf syscall with given arguments. |
| 4749 | * Return | 4749 | * Return |
| 4750 | * A syscall result. | 4750 | * A syscall result. |
| 4751 | * | ||
| 4752 | * long bpf_btf_find_by_name_kind(char *name, int name_sz, u32 kind, int flags) | ||
| 4753 | * Description | ||
| 4754 | * Find BTF type with given name and kind in vmlinux BTF or in module's BTFs. | ||
| 4755 | * Return | ||
| 4756 | * Returns btf_id and btf_obj_fd in lower and upper 32 bits. | ||
| 4751 | */ | 4757 | */ |
| 4752 | #define __BPF_FUNC_MAPPER(FN) \ | 4758 | #define __BPF_FUNC_MAPPER(FN) \ |
| 4753 | FN(unspec), \ | 4759 | FN(unspec), \ |
| @@ -4917,6 +4923,7 @@ union bpf_attr { · 163 unmodified lines | |||
| 4917 | FN(for_each_map_elem), \ | 4923 | FN(for_each_map_elem), \ |
| 4918 | FN(snprintf), \ | 4924 | FN(snprintf), \ |
| 4919 | FN(sys_bpf), \ | 4925 | FN(sys_bpf), \ |
| 4926 | FN(btf_find_by_name_kind), \ | ||
| 4920 | /* */ | 4927 | /* */ |
| 4921 | 4928 | ||
| 4922 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper | 4929 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper |