All of lore.kernel.org
 help / color / mirror / Atom feed
From: Grant Seltzer <grantseltzer@gmail.com>
To: bpf@vger.kernel.org
Cc: andrii@kernel.org, kpsingh@kernel.org,
	Grant Seltzer <grantseltzer@gmail.com>
Subject: [PATCH v2 bpf-next] Add support for tracing programs in BPF_PROG_RUN
Date: Fri,  3 Feb 2023 13:28:12 -0500	[thread overview]
Message-ID: <20230203182812.20657-1-grantseltzer@gmail.com> (raw)

This patch changes the behavior of how BPF_PROG_RUN treats tracing
(fentry/fexit) programs. Previously only a return value is injected
but the actual program was not run. New behavior mirrors that of
running raw tracepoint BPF programs which actually runs the
instructions of the program via `bpf_prog_run()`

Tracing programs only needs to support an input context so we validate
that non-relevant attributes are not set.

Changes v1 -> v2:
- Fixed unused variable and logic for how the fmod_ret test is handled

Signed-off-by: Grant Seltzer <grantseltzer@gmail.com>
---
 net/bpf/test_run.c | 77 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 70 insertions(+), 7 deletions(-)

diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
index 8da0d73b368e..0c36ed7dd88e 100644
--- a/net/bpf/test_run.c
+++ b/net/bpf/test_run.c
@@ -794,14 +794,34 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size,
 	return data;
 }
 
+struct bpf_tracing_test_run_info {
+	struct bpf_prog *prog;
+	void *ctx;
+	u32 retval;
+};
+
+static void
+__bpf_prog_test_run_tracing(void *data)
+{
+	struct bpf_tracing_test_run_info *info = data;
+
+	rcu_read_lock();
+	info->retval = bpf_prog_run(info->prog, info->ctx);
+	rcu_read_unlock();
+}
+
 int bpf_prog_test_run_tracing(struct bpf_prog *prog,
 			      const union bpf_attr *kattr,
 			      union bpf_attr __user *uattr)
 {
 	struct bpf_fentry_test_t arg = {};
-	u16 side_effect = 0, ret = 0;
-	int b = 2, err = -EFAULT;
-	u32 retval = 0;
+	int b = 2, err = -EFAULT, current_cpu;
+
+	void __user *ctx_in = u64_to_user_ptr(kattr->test.ctx_in);
+	__u32 ctx_size_in = kattr->test.ctx_size_in;
+	struct bpf_tracing_test_run_info info;
+	int cpu = kattr->test.cpu;
+	u16 side_effect = 0;
 
 	if (kattr->test.flags || kattr->test.cpu || kattr->test.batch_size)
 		return -EINVAL;
@@ -820,7 +840,7 @@ int bpf_prog_test_run_tracing(struct bpf_prog *prog,
 			goto out;
 		break;
 	case BPF_MODIFY_RETURN:
-		ret = bpf_modify_return_test(1, &b);
+		bpf_modify_return_test(1, &b);
 		if (b != 2)
 			side_effect = 1;
 		break;
@@ -828,11 +848,54 @@ int bpf_prog_test_run_tracing(struct bpf_prog *prog,
 		goto out;
 	}
 
-	retval = ((u32)side_effect << 16) | ret;
-	if (copy_to_user(&uattr->test.retval, &retval, sizeof(retval)))
-		goto out;
+	/* doesn't support data_in/out, ctx_out, duration, or repeat */
+	if (kattr->test.data_in || kattr->test.data_out ||
+	    kattr->test.ctx_out || kattr->test.duration ||
+	    kattr->test.repeat || kattr->test.batch_size)
+		return -EINVAL;
+
+	if (ctx_size_in < prog->aux->max_ctx_offset ||
+	    ctx_size_in > MAX_BPF_FUNC_ARGS * sizeof(u64))
+		return -EINVAL;
+
+	if ((kattr->test.flags & BPF_F_TEST_RUN_ON_CPU) == 0 && cpu != 0)
+		return -EINVAL;
+
+	if (ctx_size_in) {
+		info.ctx = memdup_user(ctx_in, ctx_size_in);
+		if (IS_ERR(info.ctx))
+			return PTR_ERR(info.ctx);
+	} else {
+		info.ctx = NULL;
+	}
 
 	err = 0;
+	info.prog = prog;
+
+	current_cpu = get_cpu();
+	if ((kattr->test.flags & BPF_F_TEST_RUN_ON_CPU) == 0 ||
+	    cpu == current_cpu) {
+		__bpf_prog_test_run_tracing(&info);
+	} else if (cpu >= nr_cpu_ids || !cpu_online(cpu)) {
+		/* smp_call_function_single() also checks cpu_online()
+		 * after csd_lock(). However, since cpu is from user
+		 * space, let's do an extra quick check to filter out
+		 * invalid value before smp_call_function_single().
+		 */
+		err = -ENXIO;
+	} else {
+		err = smp_call_function_single(cpu, __bpf_prog_test_run_tracing,
+					       &info, 1);
+	}
+	put_cpu();
+
+	info.retval = ((u32)side_effect << 16) | info.retval;
+	if (!err &&
+	    copy_to_user(&uattr->test.retval, &info.retval, sizeof(u32)))
+		err = -EFAULT;
+
+	kfree(info.ctx);
+
 out:
 	trace_bpf_test_finish(&err);
 	return err;
-- 
2.39.1


             reply	other threads:[~2023-02-03 18:28 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-03 18:28 Grant Seltzer [this message]
2023-02-04  6:58 ` [PATCH v2 bpf-next] Add support for tracing programs in BPF_PROG_RUN Martin KaFai Lau
2023-02-05 17:29   ` Grant Seltzer Richman
2023-02-06 20:37     ` Martin KaFai Lau
2023-02-07 15:46       ` Grant Seltzer Richman
2023-02-08  1:05         ` Martin KaFai Lau
2023-02-08 15:40           ` Grant Seltzer Richman

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=20230203182812.20657-1-grantseltzer@gmail.com \
    --to=grantseltzer@gmail.com \
    --cc=andrii@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=kpsingh@kernel.org \
    /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.