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.
Showing the changes to kernel (2 of 5 files). Show all
Unified · Split
| @@ -6085,3 +6085,65 @@ struct module *btf_try_get_module(const struct btf *btf) · 6084 unmodified lines | ||
| 6085 | 6085 | |
| 6086 | 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 | 4584 | switch (func_id) { |
| 4585 | 4585 | case BPF_FUNC_sys_bpf: |
| 4586 | 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 | 4589 | default: |
| 4588 | 4590 | return tracing_prog_func_proto(func_id, prog); |
| 4589 | 4591 | } |