BPF `STRUCT_OPS` maps (such as `sched_ext_ops` maps) require resolving and plumbing the kernel-side structure value type ID (`btf_vmlinux_value_type_id`) into the BPF map creation system call attributes. Additionally, when `btf_vmlinux_value_type_id` is supplied, the kernel requires a valid userspace BTF file descriptor (`btf_fd`) to be supplied to verify types. Previously, the `gen_loader` map creation generator (`bpf_gen__map_create()`) omitted plumbing `btf_vmlinux_value_type_id`. Furthermore, `gen_loader.c` only copied the loaded `btf_fd` from the stack to the attributes blob if `btf_value_type_id` was non-zero. Because `STRUCT_OPS` maps explicitly zero out `btf_value_type_id`, the loader program skipped copying `btf_fd`, leaving it as `0` (standard input), which caused the kernel's `btf_get_by_fd(0)` check to fail. Fix this by: 1. Copying `btf_vmlinux_value_type_id` from the options inside `bpf_gen__map_create()`. 2. Modifying the `btf_fd` copying condition to populate `btf_fd` if either `btf_value_type_id` OR `btf_vmlinux_value_type_id` is set. Signed-off-by: Siddharth Nayyar --- tools/lib/bpf/gen_loader.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c index cd5c2543f54d..a9be0c241025 100644 --- a/tools/lib/bpf/gen_loader.c +++ b/tools/lib/bpf/gen_loader.c @@ -525,13 +525,14 @@ void bpf_gen__map_create(struct bpf_gen *gen, attr.max_entries = tgt_endian(max_entries); attr.btf_key_type_id = tgt_endian(map_attr->btf_key_type_id); attr.btf_value_type_id = tgt_endian(map_attr->btf_value_type_id); + attr.btf_vmlinux_value_type_id = tgt_endian(map_attr->btf_vmlinux_value_type_id); map_create_attr = add_data(gen, &attr, attr_size); pr_debug("gen: map_create: %s idx %d type %d value_type_id %d, attr: off %d size %d\n", map_name, map_idx, map_type, map_attr->btf_value_type_id, map_create_attr, attr_size); - if (map_attr->btf_value_type_id) + if (map_attr->btf_value_type_id || map_attr->btf_vmlinux_value_type_id) /* populate union bpf_attr with btf_fd saved in the stack earlier */ move_stack2blob(gen, attr_field(map_create_attr, btf_fd), 4, stack_off(btf_fd)); -- 2.54.0.746.g67dd491aae-goog