On 12/14/23 18:44, Martin KaFai Lau wrote:
On 12/8/23 4:27 PM, thinker.li@xxxxxxxxx wrote:
@@ -681,15 +682,30 @@ static struct bpf_map
*bpf_struct_ops_map_alloc(union bpf_attr *attr)
struct bpf_struct_ops_map *st_map;
const struct btf_type *t, *vt;
struct bpf_map *map;
+ struct btf *btf;
int ret;
- st_ops_desc = bpf_struct_ops_find_value(btf_vmlinux,
attr->btf_vmlinux_value_type_id);
- if (!st_ops_desc)
- return ERR_PTR(-ENOTSUPP);
+ if (attr->value_type_btf_obj_fd) {
+ /* The map holds btf for its whole life time. */
+ btf = btf_get_by_fd(attr->value_type_btf_obj_fd);
+ if (IS_ERR(btf))
+ return ERR_PTR(PTR_ERR(btf));
return ERR_CAST(btf);
It needs to check for btf_is_module:
if (!btf_is_module(btf)) {
btf_put(btf);
return ERR_PTR(-EINVAL);
}
Even btf is btf_vmlinux the kernel's btf, it still works.
Although libbpf pass 0 as the value of value_type_btf_obj_fd for
btf_vmlinux now, it should be OK for a user space loader to
pass a fd of btf_vmlinux.
WDYT?
+ } else {
+ btf = btf_vmlinux;
+ btf_get(btf);
btf_vmlinux could be NULL or a ERR_PTR? Lets take this chance to use
bpf_get_btf_vmlinux():
btf = bpf_get_btf_vmlinux();
if (IS_ERR(btf))
return ERR_CAST(btf);
Sure!
Going back to patch 4. This should be the only case that btf will be
NULL or ERR_PTR?
will continue the remaining review later tonight.
pw-bot: cr
+ }
+
+ st_ops_desc = bpf_struct_ops_find_value(btf,
attr->btf_vmlinux_value_type_id);
+ if (!st_ops_desc) {
+ ret = -ENOTSUPP;
+ goto errout;
+ }
vt = st_ops_desc->value_type;
- if (attr->value_size != vt->size)
- return ERR_PTR(-EINVAL);
+ if (attr->value_size != vt->size) {
+ ret = -EINVAL;
+ goto errout;
+ }
t = st_ops_desc->type;