Skip to content

Commit d798872

Browse files
etsalanakryiko
authored andcommitted
libbpf: Delay feature gate check until object prepare time
Commit 728ff16 ("libbpf: Add gating for arena globals relocation feature") adds a feature gate check that loads a map and BPF program to test the running kernel supports large direct offsets for LDIMM64 instructions. This check is currently used to calculate arena symbol offsets during bpf_object__collect_relos, itself called by bpf_object_open. However, the program calling bpf_object_open may not have the permissions to load maps and programs. This is the case with the BPF selftests, where bpftool is invoked at compilation time during skeleton generation. This causes errors as the feature gate unexpectedly fails with -EPERM. Avoid this by moving all the use of the FEAT_LDIMM64_FULL_RANGE_OFF feature gate to BPF object preparation time instead. Fixes: 728ff16 ("libbpf: Add gating for arena globals relocation feature") Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20260217204345.548648-3-emil@etsalapatis.com
1 parent 7cefbb4 commit d798872

1 file changed

Lines changed: 13 additions & 7 deletions

File tree

tools/lib/bpf/libbpf.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3009,12 +3009,6 @@ static int init_arena_map_data(struct bpf_object *obj, struct bpf_map *map,
30093009
memcpy(obj->arena_data, data, data_sz);
30103010
obj->arena_data_sz = data_sz;
30113011

3012-
/* place globals at the end of the arena (if supported) */
3013-
if (kernel_supports(obj, FEAT_LDIMM64_FULL_RANGE_OFF))
3014-
obj->arena_data_off = mmap_sz - data_alloc_sz;
3015-
else
3016-
obj->arena_data_off = 0;
3017-
30183012
/* make bpf_map__init_value() work for ARENA maps */
30193013
map->mmaped = obj->arena_data;
30203014

@@ -4672,7 +4666,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
46724666
reloc_desc->type = RELO_DATA;
46734667
reloc_desc->insn_idx = insn_idx;
46744668
reloc_desc->map_idx = obj->arena_map_idx;
4675-
reloc_desc->sym_off = sym->st_value + obj->arena_data_off;
4669+
reloc_desc->sym_off = sym->st_value;
46764670

46774671
map = &obj->maps[obj->arena_map_idx];
46784672
pr_debug("prog '%s': found arena map %d (%s, sec %d, off %zu) for insn %u\n",
@@ -6386,6 +6380,10 @@ bpf_object__relocate_data(struct bpf_object *obj, struct bpf_program *prog)
63866380
case RELO_DATA:
63876381
map = &obj->maps[relo->map_idx];
63886382
insn[1].imm = insn[0].imm + relo->sym_off;
6383+
6384+
if (relo->map_idx == obj->arena_map_idx)
6385+
insn[1].imm += obj->arena_data_off;
6386+
63896387
if (obj->gen_loader) {
63906388
insn[0].src_reg = BPF_PSEUDO_MAP_IDX_VALUE;
63916389
insn[0].imm = relo->map_idx;
@@ -7387,6 +7385,14 @@ static int bpf_object__relocate(struct bpf_object *obj, const char *targ_btf_pat
73877385
bpf_object__sort_relos(obj);
73887386
}
73897387

7388+
/* place globals at the end of the arena (if supported) */
7389+
if (obj->arena_map_idx >= 0 && kernel_supports(obj, FEAT_LDIMM64_FULL_RANGE_OFF)) {
7390+
struct bpf_map *arena_map = &obj->maps[obj->arena_map_idx];
7391+
7392+
obj->arena_data_off = bpf_map_mmap_sz(arena_map) -
7393+
roundup(obj->arena_data_sz, sysconf(_SC_PAGE_SIZE));
7394+
}
7395+
73907396
/* Before relocating calls pre-process relocations and mark
73917397
* few ld_imm64 instructions that points to subprogs.
73927398
* Otherwise bpf_object__reloc_code() later would have to consider

0 commit comments

Comments
 (0)