A light skeleton does not call bpf_prog_load(): its loader program builds the attr itself, so a program loaded this way reached the kernel without its table and was refused with "unreachable insn". Carry the table the way func_info and line_info are carried: the records in the loader's blob, the count and record size in the attr, and a relocation for the blob's address. Only a program with records grows the attr to cleanup_info_cnt, so light skeletons without them are unchanged. Signed-off-by: Yonghong Song --- tools/lib/bpf/gen_loader.c | 29 ++++++++++++++++++++++++++--- tools/lib/bpf/libbpf_internal.h | 7 +++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c index 251392aa8b41..0aa87ea685e7 100644 --- a/tools/lib/bpf/gen_loader.c +++ b/tools/lib/bpf/gen_loader.c @@ -994,13 +994,15 @@ static void cleanup_relos(struct bpf_gen *gen, int insns) cleanup_core_relo(gen); } -/* Convert func, line, and core relo info blobs to target endianness */ +/* Convert func, line, core relo and cleanup info blobs to target endianness */ static void info_blob_bswap(struct bpf_gen *gen, int func_info, int line_info, - int core_relos, struct bpf_prog_load_opts *load_attr) + int core_relos, int cleanup_info, + struct bpf_prog_load_opts *load_attr) { struct bpf_func_info *fi = gen->data_start + func_info; struct bpf_line_info *li = gen->data_start + line_info; struct bpf_core_relo *cr = gen->data_start + core_relos; + struct bpf_cleanup_info *ci = gen->data_start + cleanup_info; int i; for (i = 0; i < load_attr->func_info_cnt; i++) @@ -1011,6 +1013,9 @@ static void info_blob_bswap(struct bpf_gen *gen, int func_info, int line_info, for (i = 0; i < gen->core_relo_cnt; i++) bpf_core_relo_bswap(cr++); + + for (i = 0; i < load_attr->cleanup_info_cnt; i++) + bpf_cleanup_info_bswap(ci++); } void bpf_gen__prog_load(struct bpf_gen *gen, @@ -1024,10 +1029,15 @@ void bpf_gen__prog_load(struct bpf_gen *gen, load_attr->line_info_rec_size; int core_relo_tot_sz = gen->core_relo_cnt * sizeof(struct bpf_core_relo); + int cleanup_info_tot_sz = load_attr->cleanup_info_cnt * + load_attr->cleanup_info_rec_size; int prog_load_attr, license_off, insns_off, func_info, line_info, core_relos; int attr_size = offsetofend(union bpf_attr, core_relo_rec_size); + int cleanup_info; union bpf_attr attr; + if (load_attr->cleanup_info_cnt) + attr_size = offsetofend(union bpf_attr, cleanup_info_cnt); memset(&attr, 0, attr_size); /* add license string to blob of bytes */ license_off = add_data(gen, license, strlen(license) + 1); @@ -1074,9 +1084,17 @@ void bpf_gen__prog_load(struct bpf_gen *gen, core_relos, gen->core_relo_cnt, sizeof(struct bpf_core_relo)); + attr.cleanup_info_rec_size = tgt_endian(load_attr->cleanup_info_rec_size); + attr.cleanup_info_cnt = tgt_endian(load_attr->cleanup_info_cnt); + cleanup_info = add_data(gen, load_attr->cleanup_info, cleanup_info_tot_sz); + pr_debug("gen: prog_load: cleanup_info: off %d cnt %u rec size %u\n", + cleanup_info, load_attr->cleanup_info_cnt, + load_attr->cleanup_info_rec_size); + /* convert all info blobs to target endianness */ if (gen->swapped_endian && !gen->error) - info_blob_bswap(gen, func_info, line_info, core_relos, load_attr); + info_blob_bswap(gen, func_info, line_info, core_relos, cleanup_info, + load_attr); libbpf_strlcpy(attr.prog_name, prog_name, sizeof(attr.prog_name)); prog_load_attr = add_data(gen, &attr, attr_size); @@ -1098,6 +1116,11 @@ void bpf_gen__prog_load(struct bpf_gen *gen, /* populate union bpf_attr with a pointer to core_relos */ emit_rel_store(gen, attr_field(prog_load_attr, core_relos), core_relos); + /* with no records there is no blob of them to point the attr at */ + if (load_attr->cleanup_info_cnt) + emit_rel_store(gen, attr_field(prog_load_attr, cleanup_info), + cleanup_info); + /* populate union bpf_attr fd_array with a pointer to data where map_fds are saved */ emit_rel_store(gen, attr_field(prog_load_attr, fd_array), gen->fd_array); diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h index f1630f03d5f5..9d341839ca74 100644 --- a/tools/lib/bpf/libbpf_internal.h +++ b/tools/lib/bpf/libbpf_internal.h @@ -572,6 +572,13 @@ static inline void bpf_core_relo_bswap(struct bpf_core_relo *i) i->kind = bswap_32(i->kind); } +static inline void bpf_cleanup_info_bswap(struct bpf_cleanup_info *i) +{ + i->begin_off = bswap_32(i->begin_off); + i->end_off = bswap_32(i->end_off); + i->landing_pad_off = bswap_32(i->landing_pad_off); +} + enum btf_field_iter_kind { BTF_FIELD_ITER_IDS, BTF_FIELD_ITER_STRS, -- 2.53.0-Meta