diff options
-rw-r--r-- | tools/testing/selftests/bpf/veristat.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/veristat.c b/tools/testing/selftests/bpf/veristat.c index c72111dfb35d..06af5029885b 100644 --- a/tools/testing/selftests/bpf/veristat.c +++ b/tools/testing/selftests/bpf/veristat.c @@ -1062,6 +1062,41 @@ static int guess_prog_type_by_ctx_name(const char *ctx_name, return -ESRCH; } +/* Make sure only target program is referenced from struct_ops map, + * otherwise libbpf would automatically set autocreate for all + * referenced programs. + * See libbpf.c:bpf_object_adjust_struct_ops_autoload. + */ +static void mask_unrelated_struct_ops_progs(struct bpf_object *obj, + struct bpf_map *map, + struct bpf_program *prog) +{ + struct btf *btf = bpf_object__btf(obj); + const struct btf_type *t, *mt; + struct btf_member *m; + int i, moff; + size_t data_sz, ptr_sz = sizeof(void *); + void *data; + + t = btf__type_by_id(btf, bpf_map__btf_value_type_id(map)); + if (!btf_is_struct(t)) + return; + + data = bpf_map__initial_value(map, &data_sz); + for (i = 0; i < btf_vlen(t); i++) { + m = &btf_members(t)[i]; + mt = btf__type_by_id(btf, m->type); + if (!btf_is_ptr(mt)) + continue; + moff = m->offset / 8; + if (moff + ptr_sz > data_sz) + continue; + if (memcmp(data + moff, &prog, ptr_sz) == 0) + continue; + memset(data + moff, 0, ptr_sz); + } +} + static void fixup_obj(struct bpf_object *obj, struct bpf_program *prog, const char *filename) { struct bpf_map *map; @@ -1077,6 +1112,9 @@ static void fixup_obj(struct bpf_object *obj, struct bpf_program *prog, const ch case BPF_MAP_TYPE_INODE_STORAGE: case BPF_MAP_TYPE_CGROUP_STORAGE: break; + case BPF_MAP_TYPE_STRUCT_OPS: + mask_unrelated_struct_ops_progs(obj, map, prog); + break; default: if (bpf_map__max_entries(map) == 0) bpf_map__set_max_entries(map, 1); |