All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH bpf-next v2] libbpf: Add gating for arena globals relocation feature
@ 2026-02-09 23:48 Emil Tsalapatis
  2026-02-10  0:11 ` Emil Tsalapatis
  2026-02-10  0:16 ` bot+bpf-ci
  0 siblings, 2 replies; 4+ messages in thread
From: Emil Tsalapatis @ 2026-02-09 23:48 UTC (permalink / raw)
  To: bpf
  Cc: andrii, ast, daniel, eddyz87, martin.lau, memxor, song,
	yonghong.song, Emil Tsalapatis

Add feature gating for the arena globals relocation introduced in
commit c1f61171d44b. The commit depends on a previous commit in the
same patchset that is absent from older kernels (12a1fe6e12db,
"bpf/verifier: Do not limit maximum direct offset into arena map").
Without this commit, arena globals relocation with arenas >= 512MiB
fails to load and breaks libbpf's backwards compatibility.

Introduce a libbpf feature to check whether the running kernel includes
patch 12a1fe6e12db, and only relocate arena globals if it does.

CHANGELOG
---------

v1 -> v2 (https://lore.kernel.org/bpf/20260209210240.2051209-1-emil@etsalapatis.com/)

- Reworked test to use simpler array-based program (Andrii)

Fixes: c1f61171d44b ("libbpf: Move arena globals to the end of the arena")
Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com>
---
 tools/lib/bpf/features.c        | 92 +++++++++++++++++++++++++++++++++
 tools/lib/bpf/libbpf.c          |  7 ++-
 tools/lib/bpf/libbpf_internal.h |  2 +
 3 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/tools/lib/bpf/features.c b/tools/lib/bpf/features.c
index b842b83e2480..b1a088dd83ac 100644
--- a/tools/lib/bpf/features.c
+++ b/tools/lib/bpf/features.c
@@ -506,6 +506,95 @@ static int probe_kern_arg_ctx_tag(int token_fd)
 	return probe_fd(prog_fd);
 }
 
+static int probe_kern_arena_global_reloc(int token_fd)
+{
+	const size_t bufsz = 1024;
+	int btf_fd, prog_fd, map;
+	char log_buf[bufsz];
+	int ret;
+	static const char strs[] = "\0f\0";
+	const __u32 types[] = {
+		/* [1] FUNC_PROTO `void(void)` */
+		BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 0), 0),
+		/* [2] FUNC 'f' -> FUNC_PROTO (main prog) */
+		BTF_TYPE_ENC(1 /* "f" */, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 1),
+	};
+	LIBBPF_OPTS(bpf_map_create_opts, map_opts,
+		.token_fd = token_fd,
+		.map_flags = token_fd ? BPF_F_TOKEN_FD : 0,
+	);
+	LIBBPF_OPTS(bpf_prog_load_opts, prog_opts,
+		.token_fd = token_fd,
+		.prog_flags = BPF_F_SLEEPABLE | (token_fd ? BPF_F_TOKEN_FD : 0),
+		.log_buf = log_buf,
+		.log_size = bufsz,
+	);
+	struct bpf_insn insns[] = {
+		BPF_LD_MAP_VALUE(BPF_REG_1, 0, 1UL << 30),
+		BPF_EXIT_INSN(),
+	};
+	const struct bpf_func_info_min func_infos[] = {
+		{ 0, 2 }, /* main prog -> FUNC 'f' */
+	};
+	int insn_cnt = ARRAY_SIZE(insns);
+
+	btf_fd = libbpf__load_raw_btf((char *)types, sizeof(types), strs, sizeof(strs), token_fd);
+	if (btf_fd < 0)
+		return 0; /* BTF not supported at all */
+
+	map = bpf_map_create(BPF_MAP_TYPE_ARRAY, "arr", sizeof(int), 1, 1, &map_opts);
+	if (map < 0) {
+		ret = -errno;
+		pr_warn("Error in %s(): %s. Couldn't create simple array map.\n",
+			__func__, errstr(ret));
+		close(btf_fd);
+		return ret;
+	}
+	insns[0].imm = map;
+
+	prog_opts.prog_btf_fd = btf_fd;
+	prog_opts.func_info = &func_infos;
+	prog_opts.func_info_cnt = ARRAY_SIZE(func_infos);
+	prog_opts.func_info_rec_size = sizeof(func_infos[0]);
+
+	prog_fd = bpf_prog_load(BPF_PROG_TYPE_SYSCALL, "global_reloc", "GPL", insns, insn_cnt, &prog_opts);
+
+	ret = -errno;
+	close(map);
+	close(btf_fd);
+
+	if (prog_fd >= 0) {
+		pr_warn("Error in %s(): Program loading unexpectedly succeeded.\n",
+			__func__);
+		close(prog_fd);
+		return -EINVAL;
+	}
+
+	/* Be conservative and NULL terminate the buffer to ensure strstr terminates. */
+	log_buf[bufsz - 1] = '\0';
+
+	/*
+	 * Feature is allowed if we're not failing with the error message "direct value
+	 * offset of %u is not allowed that was removed in 12a1fe6e12db
+	 * ("bpf/verifier: Do not limit maximum direct offset into arena map").
+	 * Instead, we should be failing with the message "invalid access to map value
+	 * pointer". Ensure we match with one of the two and we're not failing with a
+	 * different, unexpected message.
+	 */
+	if (strstr(log_buf, "direct value offset of"))
+		return 0;
+
+	if (strstr(log_buf, "invalid access to map value pointer") == NULL) {
+		pr_warn("Error in %s(): Program unexpectedly failed with message: %s.\n",
+			__func__, log_buf);
+		return ret;
+	}
+
+	/* Feature is on. */
+
+	return 1;
+}
+
 typedef int (*feature_probe_fn)(int /* token_fd */);
 
 static struct kern_feature_cache feature_cache;
@@ -581,6 +670,9 @@ static struct kern_feature_desc {
 	[FEAT_BTF_QMARK_DATASEC] = {
 		"BTF DATASEC names starting from '?'", probe_kern_btf_qmark_datasec,
 	},
+	[FEAT_ARENA_GLOBAL_RELOC] = {
+		"Relocatable arena globals support", probe_kern_arena_global_reloc,
+	},
 };
 
 bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 0c8bf0b5cce4..0aeb740a5f47 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -3009,8 +3009,11 @@ static int init_arena_map_data(struct bpf_object *obj, struct bpf_map *map,
 	memcpy(obj->arena_data, data, data_sz);
 	obj->arena_data_sz = data_sz;
 
-	/* place globals at the end of the arena */
-	obj->arena_data_off = mmap_sz - data_alloc_sz;
+	/* place globals at the end of the arena (if supported) */
+	if (kernel_supports(obj, FEAT_ARENA_GLOBAL_RELOC))
+		obj->arena_data_off = mmap_sz - data_alloc_sz;
+	else
+		obj->arena_data_off = 0;
 
 	/* make bpf_map__init_value() work for ARENA maps */
 	map->mmaped = obj->arena_data;
diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_internal.h
index fc59b21b51b5..e0223a6e4c95 100644
--- a/tools/lib/bpf/libbpf_internal.h
+++ b/tools/lib/bpf/libbpf_internal.h
@@ -392,6 +392,8 @@ enum kern_feature_id {
 	FEAT_ARG_CTX_TAG,
 	/* Kernel supports '?' at the front of datasec names */
 	FEAT_BTF_QMARK_DATASEC,
+	/* Kernel supports relocating arena globals to end of the arena */
+	FEAT_ARENA_GLOBAL_RELOC,
 	__FEAT_CNT,
 };
 
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-02-10  0:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-09 23:48 [PATCH bpf-next v2] libbpf: Add gating for arena globals relocation feature Emil Tsalapatis
2026-02-10  0:11 ` Emil Tsalapatis
2026-02-10  0:26   ` Emil Tsalapatis
2026-02-10  0:16 ` bot+bpf-ci

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.