All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eduard Zingerman <eddyz87@gmail.com>
To: bpf@vger.kernel.org, ast@kernel.org
Cc: andrii@kernel.org, daniel@iogearbox.net, martin.lau@linux.dev,
	kernel-team@fb.com, yonghong.song@linux.dev, memxor@gmail.com,
	Eduard Zingerman <eddyz87@gmail.com>
Subject: [RFC bpf-next 05/11] bpf: dynamic allocation for bpf_verifier_env->subprog_info
Date: Thu,  7 Nov 2024 09:50:34 -0800	[thread overview]
Message-ID: <20241107175040.1659341-6-eddyz87@gmail.com> (raw)
In-Reply-To: <20241107175040.1659341-1-eddyz87@gmail.com>

Follow-up patches use add_hidden_subprog() to inject inlinable kfunc
bodies into bpf program as subprograms. At the moment only one hidden
subprogram is allowed, as bpf_verifier_env->subprog_info is allocated
in advance as array of fixed size. This patch removes the limitation
by using dynamic memory allocation for this array.

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
 include/linux/bpf_verifier.h |  3 ++-
 kernel/bpf/verifier.c        | 29 ++++++++++++++++++++++-------
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index ed4eacfd4db7..b683dc3ede4a 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -738,7 +738,7 @@ struct bpf_verifier_env {
 	struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */
 	const struct bpf_line_info *prev_linfo;
 	struct bpf_verifier_log log;
-	struct bpf_subprog_info subprog_info[BPF_MAX_SUBPROGS + 2]; /* max + 2 for the fake and exception subprogs */
+	struct bpf_subprog_info *subprog_info;
 	union {
 		struct bpf_idmap idmap_scratch;
 		struct bpf_idset idset_scratch;
@@ -751,6 +751,7 @@ struct bpf_verifier_env {
 	struct backtrack_state bt;
 	struct bpf_jmp_history_entry *cur_hist_ent;
 	u32 pass_cnt; /* number of times do_check() was called */
+	u32 subprog_cap;
 	u32 subprog_cnt;
 	/* number of instructions analyzed by the verifier */
 	u32 prev_insn_processed, insn_processed;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index b86308896358..d4ea7fd8a967 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -19419,7 +19419,7 @@ static int adjust_jmp_off(struct bpf_prog *prog, u32 tgt_idx, u32 delta)
 static int adjust_subprog_starts_after_remove(struct bpf_verifier_env *env,
 					      u32 off, u32 cnt)
 {
-	int i, j;
+	int i, j, first_hidden = env->subprog_cnt - env->hidden_subprog_cnt;
 
 	/* find first prog starting at or after off (first to remove) */
 	for (i = 0; i < env->subprog_cnt; i++)
@@ -19446,6 +19446,8 @@ static int adjust_subprog_starts_after_remove(struct bpf_verifier_env *env,
 			env->subprog_info + j,
 			sizeof(*env->subprog_info) * move);
 		env->subprog_cnt -= j - i;
+		if (first_hidden <= j - 1)
+			env->hidden_subprog_cnt -= j - first_hidden;
 
 		/* remove func_info */
 		if (aux->func_info) {
@@ -21215,15 +21217,20 @@ static int resolve_kfunc_calls(struct bpf_verifier_env *env)
 /* The function requires that first instruction in 'patch' is insnsi[prog->len - 1] */
 static int add_hidden_subprog(struct bpf_verifier_env *env, struct bpf_insn *patch, int len)
 {
-	struct bpf_subprog_info *info = env->subprog_info;
+	struct bpf_subprog_info *info, *tmp;
 	int cnt = env->subprog_cnt;
 	struct bpf_prog *prog;
 
-	/* We only reserve one slot for hidden subprogs in subprog_info. */
-	if (env->hidden_subprog_cnt) {
-		verbose(env, "verifier internal error: only one hidden subprog supported\n");
-		return -EFAULT;
+	if (cnt == env->subprog_cap) {
+		env->subprog_cap *= 2;
+		tmp = vrealloc(env->subprog_info,
+			       array_size(sizeof(*env->subprog_info), env->subprog_cap + 1),
+			       GFP_KERNEL | __GFP_ZERO);
+		if (!tmp)
+			return -ENOMEM;
+		env->subprog_info = tmp;
 	}
+	info = env->subprog_info;
 	/* We're not patching any existing instruction, just appending the new
 	 * ones for the hidden subprog. Hence all of the adjustment operations
 	 * in bpf_patch_insn_data are no-ops.
@@ -23122,6 +23129,13 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
 	ret = -ENOMEM;
 	if (!env->insn_aux_data)
 		goto err_free_env;
+	env->subprog_cap = BPF_MAX_SUBPROGS;
+	env->subprog_info = vzalloc(array_size(sizeof(*env->subprog_info),
+					       env->subprog_cap + 1 /* max + 1 for the fake subprog */));
+	if (!env->subprog_info) {
+		ret = -ENOMEM;
+		goto err_free_env;
+	}
 	for (i = 0; i < len; i++)
 		env->insn_aux_data[i].orig_idx = i;
 	env->prog = *prog;
@@ -23353,8 +23367,9 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
 err_unlock:
 	if (!is_priv)
 		mutex_unlock(&bpf_verifier_lock);
-	vfree(env->insn_aux_data);
 err_free_env:
+	vfree(env->subprog_info);
+	vfree(env->insn_aux_data);
 	kvfree(env);
 	return ret;
 }
-- 
2.47.0


  parent reply	other threads:[~2024-11-07 17:51 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-07 17:50 [RFC bpf-next 00/11] bpf: inlinable kfuncs for BPF Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 01/11] bpf: use branch predictions in opt_hard_wire_dead_code_branches() Eduard Zingerman
2024-11-14 22:20   ` Eduard Zingerman
2024-11-15  0:17     ` Andrii Nakryiko
2024-11-15  0:19       ` Andrii Nakryiko
2024-11-15  0:50         ` Eduard Zingerman
2024-11-15  3:03           ` Andrii Nakryiko
2024-11-15  0:20       ` Eduard Zingerman
2024-11-15  0:27         ` Alexei Starovoitov
2024-11-15  0:33           ` Eduard Zingerman
2024-11-15  0:38             ` Alexei Starovoitov
2024-11-15  0:43               ` Eduard Zingerman
2024-11-15  0:16   ` Andrii Nakryiko
2024-11-07 17:50 ` [RFC bpf-next 02/11] selftests/bpf: tests for opt_hard_wire_dead_code_branches() Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 03/11] bpf: shared BPF/native kfuncs Eduard Zingerman
2024-11-08  1:43   ` kernel test robot
2024-11-08 20:43   ` Toke Høiland-Jørgensen
2024-11-08 21:25     ` Eduard Zingerman
2024-11-11 18:41       ` Toke Høiland-Jørgensen
2024-11-15  0:27   ` Andrii Nakryiko
2024-11-07 17:50 ` [RFC bpf-next 04/11] bpf: allow specifying inlinable kfuncs in modules Eduard Zingerman
2024-11-09  6:57   ` kernel test robot
2024-11-09  7:07   ` kernel test robot
2024-11-07 17:50 ` Eduard Zingerman [this message]
2024-11-07 17:50 ` [RFC bpf-next 06/11] bpf: KERNEL_VALUE register type Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 07/11] bpf: instantiate inlinable kfuncs before verification Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 08/11] bpf: special rules for kernel function calls inside inlinable kfuncs Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 09/11] bpf: move selected dynptr kfuncs to inlinable_kfuncs.c Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 10/11] selftests/bpf: tests to verify handling of inlined kfuncs Eduard Zingerman
2024-11-07 22:04   ` Jeff Johnson
2024-11-07 22:08     ` Eduard Zingerman
2024-11-07 22:19       ` Jeff Johnson
2024-11-07 23:00         ` Eduard Zingerman
2024-11-07 17:50 ` [RFC bpf-next 11/11] selftests/bpf: dynptr_slice benchmark Eduard Zingerman
2024-11-08 20:41 ` [RFC bpf-next 00/11] bpf: inlinable kfuncs for BPF Toke Høiland-Jørgensen
2024-11-08 23:01   ` Eduard Zingerman
2024-11-11 18:42     ` Toke Høiland-Jørgensen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241107175040.1659341-6-eddyz87@gmail.com \
    --to=eddyz87@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=kernel-team@fb.com \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=yonghong.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.