All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Martin KaFai Lau <martin.lau@kernel.org>,
	David Vernet <void@manifault.com>, Tejun Heo <tj@kernel.org>,
	Raj Sahu <rjsu26@vt.edu>, Dan Williams <djwillia@vt.edu>,
	Rishabh Iyer <rishabh.iyer@epfl.ch>,
	Sanidhya Kashyap <sanidhya.kashyap@epfl.ch>
Subject: [RFC PATCH v1 09/14] bpf, x86: Fix up pc offsets for frame descriptor entries
Date: Thu,  1 Feb 2024 04:21:04 +0000	[thread overview]
Message-ID: <20240201042109.1150490-10-memxor@gmail.com> (raw)
In-Reply-To: <20240201042109.1150490-1-memxor@gmail.com>

Until now, the program counter value stored in frame descriptor entries
was the instruction index of the BPF program's insn and callsites when
going down the frames in a call chain. However, at runtime, the program
counter will be the pointer to the next instruction, and thus needs to
be computed in a position independent way to tally it at runtime to find
the frame descriptor when unwinding.

To do this, we first convert the global instruction index into an
instruction index relative to the start of a subprog, and add 1 to it
(to reflect that at runtime, the program counter points to the next
instruction). Then, we modify the JIT (for now, x86) to convert them
to instruction offsets relative to the start of the JIT image, which is
the prog->bpf_func of the subprog in question at runtime.

Later, subtracting the prog->bpf_func pointer from runtime program
counter will yield the same offset, and allow us to figure out the
corresponding frame descriptor entry.

Note that we have to mark a frame descriptor entry as 'final' because
bpf_int_jit_compile can be called multiple times, and we would try to
convert our already converted pc values again, therefore once we do the
conversion remember it and do not repeat it.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
---
 arch/x86/net/bpf_jit_comp.c | 11 +++++++++++
 include/linux/bpf.h         |  2 ++
 kernel/bpf/verifier.c       | 15 +++++++++++++++
 3 files changed, 28 insertions(+)

diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 87692d983ffd..0dd0791c6ee0 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -3112,6 +3112,17 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 		prog = orig_prog;
 	}
 
+	if (prog->aux->fdtab && !prog->aux->fdtab->final && image) {
+		struct bpf_exception_frame_desc_tab *fdtab = prog->aux->fdtab;
+
+		for (int i = 0; i < fdtab->cnt; i++) {
+			struct bpf_exception_frame_desc *desc = fdtab->desc[i];
+
+			desc->pc = addrs[desc->pc];
+		}
+		prog->aux->fdtab->final = true;
+	}
+
 	if (!image || !prog->is_func || extra_pass) {
 		if (image)
 			bpf_prog_fill_jited_linfo(prog, addrs + 1);
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 4ac6add0cec8..e310d3ceb14e 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1460,6 +1460,7 @@ struct bpf_prog_aux {
 	bool xdp_has_frags;
 	bool exception_cb;
 	bool exception_boundary;
+	bool bpf_throw_tramp;
 	bool callee_regs_used[4];
 	/* BTF_KIND_FUNC_PROTO for valid attach_btf_id */
 	const struct btf_type *attach_func_proto;
@@ -3395,6 +3396,7 @@ struct bpf_exception_frame_desc {
 
 struct bpf_exception_frame_desc_tab {
 	u32 cnt;
+	bool final;
 	struct bpf_exception_frame_desc **desc;
 };
 
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index aeaf97b0a749..ec9acadc9ea8 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -19514,6 +19514,20 @@ static int jit_subprogs(struct bpf_verifier_env *env)
 		func[i]->aux->exception_cb = env->subprog_info[i].is_exception_cb;
 		if (!i)
 			func[i]->aux->exception_boundary = env->seen_exception;
+		if (i == env->bpf_throw_tramp_subprog)
+			func[i]->aux->bpf_throw_tramp = true;
+		/* Fix up pc of fdtab entries to be relative to subprog start before JIT. */
+		if (env->subprog_info[i].fdtab) {
+			for (int k = 0; k < env->subprog_info[i].fdtab->cnt; k++) {
+				struct bpf_exception_frame_desc *desc = env->subprog_info[i].fdtab->desc[k];
+				/* Add 1 to point to the next instruction, which will be the PC at runtime. */
+				desc->pc = desc->pc - subprog_start + 1;
+			}
+		}
+		/* Transfer fdtab to subprog->aux */
+		func[i]->aux->fdtab = env->subprog_info[i].fdtab;
+		env->subprog_info[i].fdtab = NULL;
+
 		func[i] = bpf_int_jit_compile(func[i]);
 		if (!func[i]->jited) {
 			err = -ENOTSUPP;
@@ -19604,6 +19618,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
 	prog->aux->real_func_cnt = env->subprog_cnt;
 	prog->aux->bpf_exception_cb = (void *)func[env->exception_callback_subprog]->bpf_func;
 	prog->aux->exception_boundary = func[0]->aux->exception_boundary;
+	prog->aux->fdtab = func[0]->aux->fdtab;
 	bpf_prog_jit_attempt_done(prog);
 	return 0;
 out_free:
-- 
2.40.1


  parent reply	other threads:[~2024-02-01  4:21 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-01  4:20 [RFC PATCH v1 00/14] Exceptions - Resource Cleanup Kumar Kartikeya Dwivedi
2024-02-01  4:20 ` [RFC PATCH v1 01/14] bpf: Mark subprogs as throw reachable before do_check pass Kumar Kartikeya Dwivedi
2024-02-12 19:35   ` David Vernet
2024-02-12 22:28     ` Kumar Kartikeya Dwivedi
2024-02-15  1:01   ` Eduard Zingerman
2024-02-16 21:34     ` Kumar Kartikeya Dwivedi
2024-02-01  4:20 ` [RFC PATCH v1 02/14] bpf: Process global subprog's exception propagation Kumar Kartikeya Dwivedi
2024-02-15  1:10   ` Eduard Zingerman
2024-02-16 21:50     ` Kumar Kartikeya Dwivedi
2024-02-17 14:04       ` Eduard Zingerman
2024-02-01  4:20 ` [RFC PATCH v1 03/14] selftests/bpf: Add test for throwing global subprog with acquired refs Kumar Kartikeya Dwivedi
2024-02-15  1:10   ` Eduard Zingerman
2024-02-01  4:20 ` [RFC PATCH v1 04/14] bpf: Refactor check_pseudo_btf_id's BTF reference bump Kumar Kartikeya Dwivedi
2024-02-15  1:11   ` Eduard Zingerman
2024-02-16 21:50     ` Kumar Kartikeya Dwivedi
2024-02-01  4:21 ` [RFC PATCH v1 05/14] bpf: Implement BPF exception frame descriptor generation Kumar Kartikeya Dwivedi
2024-02-15 18:24   ` Eduard Zingerman
2024-02-16 11:23     ` Eduard Zingerman
2024-02-16 22:06       ` Kumar Kartikeya Dwivedi
2024-02-17 17:14         ` Eduard Zingerman
2024-02-20 21:58           ` Kumar Kartikeya Dwivedi
2024-02-16 22:24     ` Kumar Kartikeya Dwivedi
2024-02-01  4:21 ` [RFC PATCH v1 06/14] bpf: Adjust frame descriptor pc on instruction patching Kumar Kartikeya Dwivedi
2024-02-15 16:31   ` Eduard Zingerman
2024-02-16 21:52     ` Kumar Kartikeya Dwivedi
2024-02-17 14:08       ` Eduard Zingerman
2024-02-01  4:21 ` [RFC PATCH v1 07/14] bpf: Use hidden subprog trampoline for bpf_throw Kumar Kartikeya Dwivedi
2024-02-15 22:11   ` Eduard Zingerman
2024-02-16 21:59     ` Kumar Kartikeya Dwivedi
2024-02-17 14:22       ` Eduard Zingerman
2024-02-01  4:21 ` [RFC PATCH v1 08/14] bpf: Compute used callee saved registers for subprogs Kumar Kartikeya Dwivedi
2024-02-15 22:12   ` Eduard Zingerman
2024-02-16 22:02     ` Kumar Kartikeya Dwivedi
2024-02-17 14:26       ` Eduard Zingerman
2024-02-01  4:21 ` Kumar Kartikeya Dwivedi [this message]
2024-02-15 22:12   ` [RFC PATCH v1 09/14] bpf, x86: Fix up pc offsets for frame descriptor entries Eduard Zingerman
2024-02-16 13:33     ` Eduard Zingerman
2024-02-01  4:21 ` [RFC PATCH v1 10/14] bpf, x86: Implement runtime resource cleanup for exceptions Kumar Kartikeya Dwivedi
2024-02-03  9:02   ` kernel test robot
2024-02-16 12:02   ` Eduard Zingerman
2024-02-16 22:28     ` Kumar Kartikeya Dwivedi
2024-02-19 12:01       ` Eduard Zingerman
2024-02-01  4:21 ` [RFC PATCH v1 11/14] bpf: Release references in verifier state when throwing exceptions Kumar Kartikeya Dwivedi
2024-02-16 12:21   ` Eduard Zingerman
2024-02-01  4:21 ` [RFC PATCH v1 12/14] bpf: Register cleanup dtors for runtime unwinding Kumar Kartikeya Dwivedi
2024-02-01  4:21 ` [RFC PATCH v1 13/14] bpf: Make bpf_throw available to all program types Kumar Kartikeya Dwivedi
2024-02-01  4:21 ` [RFC PATCH v1 14/14] selftests/bpf: Add tests for exceptions runtime cleanup Kumar Kartikeya Dwivedi
2024-02-12 20:53   ` David Vernet
2024-02-12 22:43     ` Kumar Kartikeya Dwivedi
2024-02-13 19:33       ` David Vernet
2024-02-13 20:51         ` Kumar Kartikeya Dwivedi
2024-03-14 11:08 ` [RFC PATCH v1 00/14] Exceptions - Resource Cleanup Eduard Zingerman
2024-03-18  5:40   ` Kumar Kartikeya Dwivedi

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=20240201042109.1150490-10-memxor@gmail.com \
    --to=memxor@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=djwillia@vt.edu \
    --cc=martin.lau@kernel.org \
    --cc=rishabh.iyer@epfl.ch \
    --cc=rjsu26@vt.edu \
    --cc=sanidhya.kashyap@epfl.ch \
    --cc=tj@kernel.org \
    --cc=void@manifault.com \
    /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.