From: Leon Hwang <leon.hwang@linux.dev>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net,
menglong8.dong@gmail.com, Leon Hwang <leon.hwang@linux.dev>
Subject: [RFC PATCH bpf-next v2 3/6] bpf: Add common attr support for prog_load and btf_load
Date: Fri, 12 Sep 2025 00:33:25 +0800 [thread overview]
Message-ID: <20250911163328.93490-4-leon.hwang@linux.dev> (raw)
In-Reply-To: <20250911163328.93490-1-leon.hwang@linux.dev>
The log buffer of common attributes would be confusing with the one in
'union bpf_attr' for BPF_PROG_LOAD and BPF_BTF_LOAD.
In order to clarify the usage of these two 'log_buf's, they both can be
used for logging if:
* They are same, including 'log_buf', 'log_level' and 'log_size'.
* One of them is missing, then another one will be used for logging.
If they both have 'log_buf' but they are not same, a log message will be
written to the log buffer of 'union bpf_attr'.
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
---
include/linux/bpf.h | 3 ++-
include/linux/bpf_verifier.h | 2 +-
include/linux/btf.h | 3 ++-
kernel/bpf/btf.c | 12 +++++++-----
kernel/bpf/log.c | 23 ++++++++++++++++++++++-
kernel/bpf/syscall.c | 14 ++++++++------
kernel/bpf/verifier.c | 8 ++++----
7 files changed, 46 insertions(+), 19 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 8f6e87f0f3a89..adc0e68cb4e50 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -2717,7 +2717,8 @@ int bpf_check_uarg_tail_zero(bpfptr_t uaddr, size_t expected_size,
size_t actual_size);
/* verify correctness of eBPF program */
-int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size);
+int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size,
+ struct bpf_common_attr *common_attrs);
#ifndef CONFIG_BPF_JIT_ALWAYS_ON
void bpf_patch_call_args(struct bpf_insn *insn, u32 stack_depth);
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 020de62bd09cd..2d61afec91c92 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -864,7 +864,7 @@ __printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_env *env,
__printf(2, 3) void bpf_log(struct bpf_verifier_log *log,
const char *fmt, ...);
int bpf_vlog_init(struct bpf_verifier_log *log, u32 log_level,
- char __user *log_buf, u32 log_size);
+ char __user *log_buf, u32 log_size, const struct bpf_common_attr *common_attrs);
void bpf_vlog_reset(struct bpf_verifier_log *log, u64 new_pos);
int bpf_vlog_finalize(struct bpf_verifier_log *log, u32 *log_size_actual);
diff --git a/include/linux/btf.h b/include/linux/btf.h
index 9eda6b113f9b4..c0acb46930bde 100644
--- a/include/linux/btf.h
+++ b/include/linux/btf.h
@@ -145,7 +145,8 @@ const char *btf_get_name(const struct btf *btf);
void btf_get(struct btf *btf);
void btf_put(struct btf *btf);
const struct btf_header *btf_header(const struct btf *btf);
-int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_sz);
+int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_sz,
+ const struct bpf_common_attr *common_attrs);
struct btf *btf_get_by_fd(int fd);
int btf_get_info_by_fd(const struct btf *btf,
const union bpf_attr *attr,
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 64739308902f7..4a17ae4842210 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -5771,7 +5771,8 @@ static int finalize_log(struct bpf_verifier_log *log, bpfptr_t uattr, u32 uattr_
return err;
}
-static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
+static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size,
+ const struct bpf_common_attr *common_attrs)
{
bpfptr_t btf_data = make_bpfptr(attr->btf, uattr.is_kernel);
char __user *log_ubuf = u64_to_user_ptr(attr->btf_log_buf);
@@ -5791,8 +5792,8 @@ static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u32 uat
/* user could have requested verbose verifier output
* and supplied buffer to store the verification trace
*/
- err = bpf_vlog_init(&env->log, attr->btf_log_level,
- log_ubuf, attr->btf_log_size);
+ err = bpf_vlog_init(&env->log, attr->btf_log_level, log_ubuf, attr->btf_log_size,
+ common_attrs);
if (err)
goto errout_free;
@@ -8028,12 +8029,13 @@ static int __btf_new_fd(struct btf *btf)
return anon_inode_getfd("btf", &btf_fops, btf, O_RDONLY | O_CLOEXEC);
}
-int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
+int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size,
+ const struct bpf_common_attr *common_attrs)
{
struct btf *btf;
int ret;
- btf = btf_parse(attr, uattr, uattr_size);
+ btf = btf_parse(attr, uattr, uattr_size, common_attrs);
if (IS_ERR(btf))
return PTR_ERR(btf);
diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c
index e4983c1303e76..a9a0834884eb9 100644
--- a/kernel/bpf/log.c
+++ b/kernel/bpf/log.c
@@ -29,12 +29,33 @@ static bool bpf_verifier_log_attr_valid(const struct bpf_verifier_log *log)
}
int bpf_vlog_init(struct bpf_verifier_log *log, u32 log_level,
- char __user *log_buf, u32 log_size)
+ char __user *log_buf, u32 log_size, const struct bpf_common_attr *common_attrs)
{
+ u32 log_true_size;
+ int err;
+
log->level = log_level;
log->ubuf = log_buf;
log->len_total = log_size;
+ if (log_buf && common_attrs && common_attrs->log_buf &&
+ ((u64) log_buf != common_attrs->log_buf || log_level != common_attrs->log_level ||
+ log_size != common_attrs->log_size)) {
+ if (!bpf_verifier_log_attr_valid(log))
+ return -EINVAL;
+ bpf_log(log, "Conflict log configs between bpf_attr and common_attr.\n");
+ err = bpf_vlog_finalize(log, &log_true_size);
+ if (err)
+ return err;
+ return -EINVAL;
+ }
+
+ if (!log_buf && common_attrs && common_attrs->log_buf) {
+ log->level = common_attrs->log_level;
+ log->ubuf = u64_to_user_ptr(common_attrs->log_buf);
+ log->len_total = common_attrs->log_size;
+ }
+
/* log attributes have to be sane */
if (!bpf_verifier_log_attr_valid(log))
return -EINVAL;
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index d49f822ceea12..5e5cf0262a14e 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -2764,7 +2764,8 @@ static bool is_perfmon_prog_type(enum bpf_prog_type prog_type)
/* last field in 'union bpf_attr' used by this command */
#define BPF_PROG_LOAD_LAST_FIELD fd_array_cnt
-static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
+static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size,
+ struct bpf_common_attr *common_attrs)
{
enum bpf_prog_type type = attr->prog_type;
struct bpf_prog *prog, *dst_prog = NULL;
@@ -2976,7 +2977,7 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size)
goto free_prog_sec;
/* run eBPF verifier */
- err = bpf_check(&prog, attr, uattr, uattr_size);
+ err = bpf_check(&prog, attr, uattr, uattr_size, common_attrs);
if (err < 0)
goto free_used_maps;
@@ -5292,7 +5293,8 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
#define BPF_BTF_LOAD_LAST_FIELD btf_token_fd
-static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size)
+static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size,
+ struct bpf_common_attr *common_attrs)
{
struct bpf_token *token = NULL;
@@ -5319,7 +5321,7 @@ static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_
bpf_token_put(token);
- return btf_new_fd(attr, uattr, uattr_size);
+ return btf_new_fd(attr, uattr, uattr_size, common_attrs);
}
#define BPF_BTF_GET_FD_BY_ID_LAST_FIELD fd_by_id_token_fd
@@ -6036,7 +6038,7 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
err = map_freeze(&attr);
break;
case BPF_PROG_LOAD:
- err = bpf_prog_load(&attr, uattr, size);
+ err = bpf_prog_load(&attr, uattr, size, &common_attrs);
break;
case BPF_OBJ_PIN:
err = bpf_obj_pin(&attr);
@@ -6081,7 +6083,7 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size,
err = bpf_raw_tracepoint_open(&attr);
break;
case BPF_BTF_LOAD:
- err = bpf_btf_load(&attr, uattr, size);
+ err = bpf_btf_load(&attr, uattr, size, &common_attrs);
break;
case BPF_BTF_GET_FD_BY_ID:
err = bpf_btf_get_fd_by_id(&attr);
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index b9394f8fac0ed..77b57289ec097 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -24584,7 +24584,8 @@ static int compute_scc(struct bpf_verifier_env *env)
return err;
}
-int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size)
+int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size,
+ struct bpf_common_attr *common_attrs)
{
u64 start_time = ktime_get_ns();
struct bpf_verifier_env *env;
@@ -24633,9 +24634,8 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
/* user could have requested verbose verifier output
* and supplied buffer to store the verification trace
*/
- ret = bpf_vlog_init(&env->log, attr->log_level,
- (char __user *) (unsigned long) attr->log_buf,
- attr->log_size);
+ ret = bpf_vlog_init(&env->log, attr->log_level, u64_to_user_ptr(attr->log_buf),
+ attr->log_size, common_attrs);
if (ret)
goto err_unlock;
--
2.50.1
next prev parent reply other threads:[~2025-09-11 16:33 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-11 16:33 [RFC PATCH bpf-next v2 0/6] bpf: Extend bpf syscall with common attributes support Leon Hwang
2025-09-11 16:33 ` [RFC PATCH bpf-next v2 1/6] " Leon Hwang
2025-09-17 0:06 ` Andrii Nakryiko
2025-09-23 15:23 ` Leon Hwang
2025-09-11 16:33 ` [RFC PATCH bpf-next v2 2/6] libbpf: Add support for extended bpf syscall Leon Hwang
2025-09-17 0:06 ` Andrii Nakryiko
2025-09-23 15:36 ` Leon Hwang
2025-09-24 23:57 ` Andrii Nakryiko
2025-09-11 16:33 ` Leon Hwang [this message]
2025-09-17 21:12 ` [RFC PATCH bpf-next v2 3/6] bpf: Add common attr support for prog_load and btf_load Andrii Nakryiko
2025-09-23 15:50 ` Leon Hwang
2025-09-25 0:00 ` Andrii Nakryiko
2025-09-11 16:33 ` [RFC PATCH bpf-next v2 4/6] bpf: Add common attr support for map_create Leon Hwang
2025-09-17 21:39 ` Andrii Nakryiko
2025-09-17 21:49 ` Alexei Starovoitov
2025-09-23 15:52 ` Leon Hwang
2025-09-23 16:27 ` Leon Hwang
2025-09-18 23:29 ` Eduard Zingerman
2025-09-23 16:31 ` Leon Hwang
2025-09-11 16:33 ` [RFC PATCH bpf-next v2 5/6] libbpf: " Leon Hwang
2025-09-17 21:45 ` Andrii Nakryiko
2025-09-17 21:46 ` Andrii Nakryiko
2025-09-23 16:40 ` Leon Hwang
2025-09-25 0:02 ` Andrii Nakryiko
2025-09-11 16:33 ` [RFC PATCH bpf-next v2 6/6] selftests/bpf: Add cases to test map create failure log Leon Hwang
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=20250911163328.93490-4-leon.hwang@linux.dev \
--to=leon.hwang@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=menglong8.dong@gmail.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.