From nobody Thu Apr 2 17:43:09 2026 Received: from out-187.mta1.migadu.com (out-187.mta1.migadu.com [95.215.58.187]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4A65B2C0323 for ; Wed, 11 Feb 2026 15:12:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.187 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822735; cv=none; b=LKKFUNCGcDhlpplvyoLK7GplPhFN8Mh9zpQZDDFsQ58zIYITdcS+htbaEyd/FE5LsXr9mmiPAc13OBuBXGJ2n6UFOk/txnwg4CO8u5YKGVotijhn8iJ0/nQhXH8Lo10n1NWYqP2X2FaCxE8eD8OHfFuK+Cg8SuCScXz8WppfEXE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822735; c=relaxed/simple; bh=oCkChfKXe7hI4ezdJMdLkv3tPcmHPMjqXTSQJkHeOeY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hWTaRU2TPKGN7gMmc1cbCFr+J15BKNhmo31VWgQgHAhbR9O3omEAfPWbLvouR5Xpi5Ub6zgO6s+aiheI35Tf6HhbWp4alvMDfKPUldOVNViJ27/hv2hDfD5HJ1Oo5tE0rncWbr372JZghZePEmabVzOpaOfgIXyoZtDwEdAVHcI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=PB9BtwgP; arc=none smtp.client-ip=95.215.58.187 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="PB9BtwgP" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770822732; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hF9a9C1QX6dcE1k6wtpNjT6ojx7h9SxTUcMEP4aCm4Q=; b=PB9BtwgPuWY19jeO6gdI+WYKopTSy5Xb982uWEGWHOFwsJyqPd7t88YX6wEnQcajVeSxws WxhoqBaLV8eY8qopdnmzVqZ0mSDnfSATgZZPK3B/Azyql8f2VT1xu0QgU1nIGJ8il1dLeh +tCZmbHs/PhziVmmFWHOwc15sYj01PY= From: Leon Hwang To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Christian Brauner , Seth Forshee , Yuichiro Tsuji , Andrey Albershteyn , Leon Hwang , Willem de Bruijn , Jason Xing , Tao Chen , Mykyta Yatsenko , Kumar Kartikeya Dwivedi , Anton Protopopov , Amery Hung , Rong Tao , linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-kselftest@vger.kernel.org, kernel-patches-bot@fb.com Subject: [PATCH bpf-next v10 1/8] bpf: Extend BPF syscall with common attributes support Date: Wed, 11 Feb 2026 23:11:08 +0800 Message-ID: <20260211151115.78013-2-leon.hwang@linux.dev> In-Reply-To: <20260211151115.78013-1-leon.hwang@linux.dev> References: <20260211151115.78013-1-leon.hwang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Add generic BPF syscall support for passing common attributes. The initial set of common attributes includes: 1. 'log_buf': User-provided buffer for storing logs. 2. 'log_size': Size of the log buffer. 3. 'log_level': Log verbosity level. 4. 'log_true_size': Actual log size reported by kernel. The common-attribute pointer and its size are passed as the 4th and 5th syscall arguments. A new command bit, 'BPF_COMMON_ATTRS' ('1 << 16'), indicates that common attributes are supplied. This commit adds syscall and uapi plumbing. Command-specific handling is added in follow-up patches. Signed-off-by: Leon Hwang --- include/linux/syscalls.h | 3 ++- include/uapi/linux/bpf.h | 8 ++++++++ kernel/bpf/syscall.c | 25 +++++++++++++++++++++---- tools/include/uapi/linux/bpf.h | 8 ++++++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 6c8a570cf44a..aadbb7164ea5 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -937,7 +937,8 @@ asmlinkage long sys_seccomp(unsigned int op, unsigned i= nt flags, asmlinkage long sys_getrandom(char __user *buf, size_t count, unsigned int flags); asmlinkage long sys_memfd_create(const char __user *uname_ptr, unsigned in= t flags); -asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int= size); +asmlinkage long sys_bpf(int cmd, union bpf_attr __user *attr, unsigned int= size, + struct bpf_common_attr __user *attr_common, unsigned int size_common); asmlinkage long sys_execveat(int dfd, const char __user *filename, const char __user *const __user *argv, const char __user *const __user *envp, int flags); diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index c8d400b7680a..b2126c9641ec 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -994,6 +994,7 @@ enum bpf_cmd { BPF_PROG_STREAM_READ_BY_FD, BPF_PROG_ASSOC_STRUCT_OPS, __MAX_BPF_CMD, + BPF_COMMON_ATTRS =3D 1 << 16, /* Indicate carrying syscall common attrs. = */ }; =20 enum bpf_map_type { @@ -1500,6 +1501,13 @@ struct bpf_stack_build_id { }; }; =20 +struct bpf_common_attr { + __u64 log_buf; + __u32 log_size; + __u32 log_level; + __u32 log_true_size; +}; + #define BPF_OBJ_NAME_LEN 16U =20 enum { diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 683c332dbafb..0e231c0b1d04 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -6186,8 +6186,10 @@ static int prog_assoc_struct_ops(union bpf_attr *att= r) return ret; } =20 -static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size) +static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size, + bpfptr_t uattr_common, unsigned int size_common) { + struct bpf_common_attr attr_common; union bpf_attr attr; int err; =20 @@ -6201,6 +6203,20 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uatt= r, unsigned int size) if (copy_from_bpfptr(&attr, uattr, size) !=3D 0) return -EFAULT; =20 + memset(&attr_common, 0, sizeof(attr_common)); + if (cmd & BPF_COMMON_ATTRS) { + err =3D bpf_check_uarg_tail_zero(uattr_common, sizeof(attr_common), size= _common); + if (err) + return err; + + cmd &=3D ~BPF_COMMON_ATTRS; + size_common =3D min_t(u32, size_common, sizeof(attr_common)); + if (copy_from_bpfptr(&attr_common, uattr_common, size_common) !=3D 0) + return -EFAULT; + } else { + size_common =3D 0; + } + err =3D security_bpf(cmd, &attr, size, uattr.is_kernel); if (err < 0) return err; @@ -6336,9 +6352,10 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uatt= r, unsigned int size) return err; } =20 -SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned in= t, size) +SYSCALL_DEFINE5(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned in= t, size, + struct bpf_common_attr __user *, uattr_common, unsigned int, size_common) { - return __sys_bpf(cmd, USER_BPFPTR(uattr), size); + return __sys_bpf(cmd, USER_BPFPTR(uattr), size, USER_BPFPTR(uattr_common)= , size_common); } =20 static bool syscall_prog_is_valid_access(int off, int size, @@ -6369,7 +6386,7 @@ BPF_CALL_3(bpf_sys_bpf, int, cmd, union bpf_attr *, a= ttr, u32, attr_size) default: return -EINVAL; } - return __sys_bpf(cmd, KERNEL_BPFPTR(attr), attr_size); + return __sys_bpf(cmd, KERNEL_BPFPTR(attr), attr_size, KERNEL_BPFPTR(NULL)= , 0); } =20 =20 diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 5e38b4887de6..c4934c2370fd 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -994,6 +994,7 @@ enum bpf_cmd { BPF_PROG_STREAM_READ_BY_FD, BPF_PROG_ASSOC_STRUCT_OPS, __MAX_BPF_CMD, + BPF_COMMON_ATTRS =3D 1 << 16, /* Indicate carrying syscall common attrs. = */ }; =20 enum bpf_map_type { @@ -1500,6 +1501,13 @@ struct bpf_stack_build_id { }; }; =20 +struct bpf_common_attr { + __u64 log_buf; + __u32 log_size; + __u32 log_level; + __u32 log_true_size; +}; + #define BPF_OBJ_NAME_LEN 16U =20 enum { --=20 2.52.0 From nobody Thu Apr 2 17:43:09 2026 Received: from out-180.mta1.migadu.com (out-180.mta1.migadu.com [95.215.58.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F2B4E153598 for ; Wed, 11 Feb 2026 15:12:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822748; cv=none; b=H2fPIwYC2CLf6o6sceANOsPp6yqyaskOHsSSSi+CtjdG4uARvuU6KPreAme183sH5UgdpTm7qGN/H87J1YNCER4zVXdqIPmf16xcR1sUrfcWQBSUHIbD6N6lc7JK7E6PlJVdlZw/2t7ghIw/rVib6/0VtRBM57AgXGoKyHtW9e4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822748; c=relaxed/simple; bh=+rpFprJBjV+nkGhaF+kJyg6eUDCUKexcnfBuSKsRM0U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=m3iHCSeqHMzrCwSlBJTlsEKltFnfBJiTAjD/B/Kj6oYcrX5diDpXvC73NO+GIyANoyQaA/QdcFuSDLoNgT7H7c21oU4Kf1xEkifjYIjyf8aiUfcfIMpXP0vglqGHPFTRj0fGYKgsyKn82tT2FTg0NCydydtimuPHblXbL8AN5d4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=iHdioILK; arc=none smtp.client-ip=95.215.58.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="iHdioILK" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770822745; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=z226B2XpSmq8CSurWwANapKEljmLoPyyQ4nyb6ASTzE=; b=iHdioILK1HvA9Fot4URphSKWZhlO9EF/LAxEVnhmYlBq0Y4oaNWyzfT6rbvLshwwevd0SW 0bk4DVdNx0HoQU00FkkPYgHz4jJJ4rjBohscXxhFKzfYsJHWCS+HOnjeoieo89ryZKLVom k2hP7BUaBAmILIhEikcfUDI5BOqqyWs= From: Leon Hwang To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Christian Brauner , Seth Forshee , Yuichiro Tsuji , Andrey Albershteyn , Leon Hwang , Willem de Bruijn , Jason Xing , Tao Chen , Mykyta Yatsenko , Kumar Kartikeya Dwivedi , Anton Protopopov , Amery Hung , Rong Tao , linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-kselftest@vger.kernel.org, kernel-patches-bot@fb.com Subject: [PATCH bpf-next v10 2/8] libbpf: Add support for extended bpf syscall Date: Wed, 11 Feb 2026 23:11:09 +0800 Message-ID: <20260211151115.78013-3-leon.hwang@linux.dev> In-Reply-To: <20260211151115.78013-1-leon.hwang@linux.dev> References: <20260211151115.78013-1-leon.hwang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" To support the extended BPF syscall introduced in the previous commit, introduce the following internal APIs: * 'sys_bpf_ext()' * 'sys_bpf_ext_fd()' They wrap the raw 'syscall()' interface to support passing extended attributes. * 'probe_sys_bpf_ext()' Check whether current kernel supports the BPF syscall common attributes. Acked-by: Andrii Nakryiko Signed-off-by: Leon Hwang --- tools/lib/bpf/bpf.c | 36 +++++++++++++++++++++++++++++++++ tools/lib/bpf/features.c | 8 ++++++++ tools/lib/bpf/libbpf_internal.h | 3 +++ 3 files changed, 47 insertions(+) diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 5846de364209..9d8740761b7a 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -69,6 +69,42 @@ static inline __u64 ptr_to_u64(const void *ptr) return (__u64) (unsigned long) ptr; } =20 +static inline int sys_bpf_ext(enum bpf_cmd cmd, union bpf_attr *attr, + unsigned int size, + struct bpf_common_attr *attr_common, + unsigned int size_common) +{ + cmd =3D attr_common ? (cmd | BPF_COMMON_ATTRS) : (cmd & ~BPF_COMMON_ATTRS= ); + return syscall(__NR_bpf, cmd, attr, size, attr_common, size_common); +} + +static inline int sys_bpf_ext_fd(enum bpf_cmd cmd, union bpf_attr *attr, + unsigned int size, + struct bpf_common_attr *attr_common, + unsigned int size_common) +{ + int fd; + + fd =3D sys_bpf_ext(cmd, attr, size, attr_common, size_common); + return ensure_good_fd(fd); +} + +int probe_sys_bpf_ext(void) +{ + const size_t attr_sz =3D offsetofend(union bpf_attr, prog_token_fd); + union bpf_attr attr; + int fd; + + memset(&attr, 0, attr_sz); + fd =3D syscall(__NR_bpf, BPF_PROG_LOAD | BPF_COMMON_ATTRS, &attr, attr_sz= , NULL, + sizeof(struct bpf_common_attr)); + if (fd >=3D 0) { + close(fd); + return -EINVAL; + } + return errno =3D=3D EFAULT ? 1 : 0; +} + static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr, unsigned int size) { diff --git a/tools/lib/bpf/features.c b/tools/lib/bpf/features.c index b842b83e2480..e0d646a9e233 100644 --- a/tools/lib/bpf/features.c +++ b/tools/lib/bpf/features.c @@ -506,6 +506,11 @@ static int probe_kern_arg_ctx_tag(int token_fd) return probe_fd(prog_fd); } =20 +static int probe_bpf_syscall_common_attrs(int token_fd) +{ + return probe_sys_bpf_ext(); +} + typedef int (*feature_probe_fn)(int /* token_fd */); =20 static struct kern_feature_cache feature_cache; @@ -581,6 +586,9 @@ static struct kern_feature_desc { [FEAT_BTF_QMARK_DATASEC] =3D { "BTF DATASEC names starting from '?'", probe_kern_btf_qmark_datasec, }, + [FEAT_BPF_SYSCALL_COMMON_ATTRS] =3D { + "BPF syscall common attributes support", probe_bpf_syscall_common_attrs, + }, }; =20 bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id= feat_id) diff --git a/tools/lib/bpf/libbpf_internal.h b/tools/lib/bpf/libbpf_interna= l.h index fc59b21b51b5..aa16be869c4f 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 BPF syscall common attributes */ + FEAT_BPF_SYSCALL_COMMON_ATTRS, __FEAT_CNT, }; =20 @@ -757,4 +759,5 @@ int probe_fd(int fd); #define SHA256_DWORD_SIZE SHA256_DIGEST_LENGTH / sizeof(__u64) =20 void libbpf_sha256(const void *data, size_t len, __u8 out[SHA256_DIGEST_LE= NGTH]); +int probe_sys_bpf_ext(void); #endif /* __LIBBPF_LIBBPF_INTERNAL_H */ --=20 2.52.0 From nobody Thu Apr 2 17:43:09 2026 Received: from out-184.mta0.migadu.com (out-184.mta0.migadu.com [91.218.175.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 978762857FC; Wed, 11 Feb 2026 15:13:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822788; cv=none; b=uQCpVYOB4cW8LelaT8O8mx7/HzQpxFohpu16iJogr6SISeqhqzE7rvzhGUuLfFFPuTCYz6QeSKq+gp1lHQMLFIMQgqIe5gv7KXVQEgMW4MPrcxp6XD3AcSRrjS8MTZVzKvphG2tpdQqJM51xwe37hj0ZAFCVvw4qIUpZHyRyA/M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822788; c=relaxed/simple; bh=4q69c1QODaiGNIKBTKpOsT0bunegxacYWzADmmMlE4I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CVCvaMI68NMxHRS2uP7nR6j2ddYCub09AAVBsgUa+o81jMSVhAeYqYKcL802uXBHSNL5GJ3cIjget3JDMcGTzSZ0da0R1PYg+kKWD1JN9Zneq7qr785uTaU81GvhCu+SCRk52eMoV7hXl90iooUSaQ5UEc7X8xfcxzPuehtaZus= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=MpX+4uPN; arc=none smtp.client-ip=91.218.175.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="MpX+4uPN" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770822772; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jF9AjMmQRvmg5AzqdDMlHG4wUpC0zw/dT5UcgyQ97JE=; b=MpX+4uPN9/82M272Q7uYWbu90IrJ0DfzHSiNux9HPl5FRrGInIzWafI8YVMasqCIa1EuKC RYwLASpFHUyhNsCMCbVWC66kSyhkFSa0CGMzZTgr7zXQA04Ia5ZlOCKaJ2H/RwVVhpmxbT rwfW9ahjvXJBemd/WW3IcCni9K4vH/g= From: Leon Hwang To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Christian Brauner , Seth Forshee , Yuichiro Tsuji , Andrey Albershteyn , Leon Hwang , Willem de Bruijn , Jason Xing , Tao Chen , Mykyta Yatsenko , Kumar Kartikeya Dwivedi , Anton Protopopov , Amery Hung , Rong Tao , linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-kselftest@vger.kernel.org, kernel-patches-bot@fb.com Subject: [PATCH bpf-next v10 3/8] bpf: Refactor reporting log_true_size for prog_load Date: Wed, 11 Feb 2026 23:11:10 +0800 Message-ID: <20260211151115.78013-4-leon.hwang@linux.dev> In-Reply-To: <20260211151115.78013-1-leon.hwang@linux.dev> References: <20260211151115.78013-1-leon.hwang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" The next commit will add support for reporting logs via extended common attributes, including 'log_true_size'. To prepare for that, refactor the 'log_true_size' reporting logic by introducing a new struct bpf_log_attr to encapsulate log-related behavior: * bpf_log_attr_init(): initialize log fields, which will support extended common attributes in the next commit. * bpf_log_attr_finalize(): handle log finalization and write back 'log_true_size' to userspace. Signed-off-by: Leon Hwang Acked-by: Andrii Nakryiko --- include/linux/bpf.h | 4 +++- include/linux/bpf_verifier.h | 11 +++++++++++ kernel/bpf/log.c | 25 +++++++++++++++++++++++++ kernel/bpf/syscall.c | 13 ++++++++++--- kernel/bpf/verifier.c | 17 ++++------------- 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index cd9b96434904..d4dbcc7ad156 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -2913,7 +2913,9 @@ int bpf_check_uarg_tail_zero(bpfptr_t uaddr, size_t e= xpected_size, size_t actual_size); =20 /* verify correctness of eBPF program */ -int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr, = u32 uattr_size); +struct bpf_log_attr; +int bpf_check(struct bpf_prog **fp, union bpf_attr *attr, bpfptr_t uattr, + struct bpf_log_attr *attr_log); =20 #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 ef8e45a362d9..dbd9bdb955b3 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -635,6 +635,17 @@ static inline bool bpf_verifier_log_needed(const struc= t bpf_verifier_log *log) return log && log->level; } =20 +struct bpf_log_attr { + char __user *log_buf; + u32 log_size; + u32 log_level; + u32 __user *log_true_size; +}; + +int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size,= u32 log_level, + u32 __user *log_true_size); +int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_l= og *log); + #define BPF_MAX_SUBPROGS 256 =20 struct bpf_subprog_arg_info { diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c index a0c3b35de2ce..e31747b84fe2 100644 --- a/kernel/bpf/log.c +++ b/kernel/bpf/log.c @@ -863,3 +863,28 @@ void print_insn_state(struct bpf_verifier_env *env, co= nst struct bpf_verifier_st } print_verifier_state(env, vstate, frameno, false); } + +int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size,= u32 log_level, + u32 __user *log_true_size) +{ + memset(log, 0, sizeof(*log)); + log->log_buf =3D u64_to_user_ptr(log_buf); + log->log_size =3D log_size; + log->log_level =3D log_level; + log->log_true_size =3D log_true_size; + return 0; +} + +int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_l= og *log) +{ + u32 log_true_size; + int err; + + err =3D bpf_vlog_finalize(log, &log_true_size); + + if (attr->log_true_size && copy_to_user(attr->log_true_size, &log_true_si= ze, + sizeof(log_true_size))) + return -EFAULT; + + return err; +} diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 0e231c0b1d04..e86674811996 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -2867,7 +2867,7 @@ static int bpf_prog_mark_insn_arrays_ready(struct bpf= _prog *prog) /* last field in 'union bpf_attr' used by this command */ #define BPF_PROG_LOAD_LAST_FIELD keyring_id =20 -static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_s= ize) +static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, struct bpf_= log_attr *attr_log) { enum bpf_prog_type type =3D attr->prog_type; struct bpf_prog *prog, *dst_prog =3D NULL; @@ -3085,7 +3085,7 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr= _t uattr, u32 uattr_size) goto free_prog_sec; =20 /* run eBPF verifier */ - err =3D bpf_check(&prog, attr, uattr, uattr_size); + err =3D bpf_check(&prog, attr, uattr, attr_log); if (err < 0) goto free_used_maps; =20 @@ -6189,7 +6189,10 @@ static int prog_assoc_struct_ops(union bpf_attr *att= r) static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr, unsigned int size, bpfptr_t uattr_common, unsigned int size_common) { + bool from_user =3D !bpfptr_is_kernel(uattr); struct bpf_common_attr attr_common; + u32 __user *log_true_size =3D NULL; + struct bpf_log_attr attr_log; union bpf_attr attr; int err; =20 @@ -6241,7 +6244,11 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uatt= r, unsigned int size, err =3D map_freeze(&attr); break; case BPF_PROG_LOAD: - err =3D bpf_prog_load(&attr, uattr, size); + if (from_user && size >=3D offsetofend(union bpf_attr, log_true_size)) + log_true_size =3D uattr.user + offsetof(union bpf_attr, log_true_size); + err =3D bpf_log_attr_init(&attr_log, attr.log_buf, attr.log_size, attr.l= og_level, + log_true_size); + err =3D err ?: bpf_prog_load(&attr, uattr, &attr_log); break; case BPF_OBJ_PIN: err =3D bpf_obj_pin(&attr); diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index edf5342b982f..f1447b1878fd 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -25840,12 +25840,12 @@ static int compute_scc(struct bpf_verifier_env *e= nv) return err; } =20 -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, + struct bpf_log_attr *attr_log) { u64 start_time =3D ktime_get_ns(); struct bpf_verifier_env *env; int i, len, ret =3D -EINVAL, err; - u32 log_true_size; bool is_priv; =20 BTF_TYPE_EMIT(enum bpf_features); @@ -25892,9 +25892,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_att= r *attr, bpfptr_t uattr, __u3 /* user could have requested verbose verifier output * and supplied buffer to store the verification trace */ - ret =3D bpf_vlog_init(&env->log, attr->log_level, - (char __user *) (unsigned long) attr->log_buf, - attr->log_size); + ret =3D bpf_vlog_init(&env->log, attr_log->log_level, attr_log->log_buf, = attr_log->log_size); if (ret) goto err_unlock; =20 @@ -26044,17 +26042,10 @@ int bpf_check(struct bpf_prog **prog, union bpf_a= ttr *attr, bpfptr_t uattr, __u3 env->prog->aux->verified_insns =3D env->insn_processed; =20 /* preserve original error even if log finalization is successful */ - err =3D bpf_vlog_finalize(&env->log, &log_true_size); + err =3D bpf_log_attr_finalize(attr_log, &env->log); if (err) ret =3D err; =20 - if (uattr_size >=3D offsetofend(union bpf_attr, log_true_size) && - copy_to_bpfptr_offset(uattr, offsetof(union bpf_attr, log_true_size), - &log_true_size, sizeof(log_true_size))) { - ret =3D -EFAULT; - goto err_release_maps; - } - if (ret) goto err_release_maps; =20 --=20 2.52.0 From nobody Thu Apr 2 17:43:09 2026 Received: from out-174.mta0.migadu.com (out-174.mta0.migadu.com [91.218.175.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 307322C1786; Wed, 11 Feb 2026 15:13:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822790; cv=none; b=rNlZ8r0a23ruLCALNZ9UYxieT1MMYrIWnXNVO46BtI/y/pSSp6BM43zU4NPufNEnRhtwL0QCdPh5XnCq0hWDlMyGCoeIJcT66VRLrgWSMRYiKYlQYbtX0h2KKwAdW0Sj4VzMctVVsDrH327Y2MXIEjDHwYncFR0JDzgK83QMsw4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822790; c=relaxed/simple; bh=lthvPF/ml1r5EnR/35ExbPQFTtQQwu4vZfopkXTIPh4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BzwZ+qW85Co8OGhbFF6a6VbOJP6MJGN0A8Y9nLjznAtNz3ZhW1KWb6h5/VoFeMUt7GqetvDD38WSFD26gnSyT4qAiWABYtZWw9TxDjsi0ERnA1ZwxZMaiJIGUdp1QKrzC8Gc0Pvhh4QT30MHsrsj7pCGg/6Jfebndg2PxeLv/qM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=lZdEwBuA; arc=none smtp.client-ip=91.218.175.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="lZdEwBuA" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770822785; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TBLB0j6NUT8VMW7VzB6bsjT1W7Y7IEGuaG2IDwLBHbk=; b=lZdEwBuAPEFhjY7hYEYui7erBbRIJSOcg2rRkbw/hHOQ2NAiRmHOVPeJy+nuGW7R1tBuVd spADLNm9GIRNPpCit6aTs1MBIOF9VBKe8I2QkcFPJGhlHlLB0BMLikT4PE3M8WCYTz5qNL 0PppPaIz5v1jsvTQVgKWwxiO95+uf7c= From: Leon Hwang To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Christian Brauner , Seth Forshee , Yuichiro Tsuji , Andrey Albershteyn , Leon Hwang , Willem de Bruijn , Jason Xing , Tao Chen , Mykyta Yatsenko , Kumar Kartikeya Dwivedi , Anton Protopopov , Amery Hung , Rong Tao , linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-kselftest@vger.kernel.org, kernel-patches-bot@fb.com Subject: [PATCH bpf-next v10 4/8] bpf: Add syscall common attributes support for prog_load Date: Wed, 11 Feb 2026 23:11:11 +0800 Message-ID: <20260211151115.78013-5-leon.hwang@linux.dev> In-Reply-To: <20260211151115.78013-1-leon.hwang@linux.dev> References: <20260211151115.78013-1-leon.hwang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" BPF_PROG_LOAD can now take log parameters from both union bpf_attr and struct bpf_common_attr. The merge rules are: - if both sides provide a complete log tuple (buf/size/level) and they match, use it; - if only one side provides log parameters, use that one; - if both sides provide complete tuples but they differ, return -EINVAL. Signed-off-by: Leon Hwang --- include/linux/bpf_verifier.h | 3 ++- kernel/bpf/log.c | 31 ++++++++++++++++++++++++++++++- kernel/bpf/syscall.c | 2 +- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index dbd9bdb955b3..34f28d40022a 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -643,7 +643,8 @@ struct bpf_log_attr { }; =20 int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size,= u32 log_level, - u32 __user *log_true_size); + u32 __user *log_true_size, struct bpf_common_attr *common, bpfptr_= t uattr, + u32 size); int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_l= og *log); =20 #define BPF_MAX_SUBPROGS 256 diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c index e31747b84fe2..a2b41bf5e9cb 100644 --- a/kernel/bpf/log.c +++ b/kernel/bpf/log.c @@ -864,14 +864,43 @@ void print_insn_state(struct bpf_verifier_env *env, c= onst struct bpf_verifier_st print_verifier_state(env, vstate, frameno, false); } =20 +static bool bpf_log_attrs_set(u64 log_buf, u32 log_size, u32 log_level) +{ + return log_buf && log_size && log_level; +} + +static bool bpf_log_attrs_diff(struct bpf_common_attr *common, u64 log_buf= , u32 log_size, + u32 log_level) +{ + return bpf_log_attrs_set(log_buf, log_size, log_level) && + bpf_log_attrs_set(common->log_buf, common->log_size, common->log_level) = && + (log_buf !=3D common->log_buf || log_size !=3D common->log_size || + log_level !=3D common->log_level); +} + int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size,= u32 log_level, - u32 __user *log_true_size) + u32 __user *log_true_size, struct bpf_common_attr *common, bpfptr_= t uattr, + u32 size) { + if (bpf_log_attrs_diff(common, log_buf, log_size, log_level)) + return -EINVAL; + memset(log, 0, sizeof(*log)); log->log_buf =3D u64_to_user_ptr(log_buf); log->log_size =3D log_size; log->log_level =3D log_level; log->log_true_size =3D log_true_size; + + if (!log_buf && common->log_buf) { + log->log_buf =3D u64_to_user_ptr(common->log_buf); + log->log_size =3D common->log_size; + log->log_level =3D common->log_level; + if (size >=3D offsetofend(struct bpf_common_attr, log_true_size)) + log->log_true_size =3D uattr.user + + offsetof(struct bpf_common_attr, log_true_size); + else + log->log_true_size =3D NULL; + } return 0; } =20 diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index e86674811996..17116603ff51 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -6247,7 +6247,7 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr= , unsigned int size, if (from_user && size >=3D offsetofend(union bpf_attr, log_true_size)) log_true_size =3D uattr.user + offsetof(union bpf_attr, log_true_size); err =3D bpf_log_attr_init(&attr_log, attr.log_buf, attr.log_size, attr.l= og_level, - log_true_size); + log_true_size, &attr_common, uattr_common, size_common); err =3D err ?: bpf_prog_load(&attr, uattr, &attr_log); break; case BPF_OBJ_PIN: --=20 2.52.0 From nobody Thu Apr 2 17:43:09 2026 Received: from out-172.mta0.migadu.com (out-172.mta0.migadu.com [91.218.175.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 60B802BD5A2 for ; Wed, 11 Feb 2026 15:13:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822804; cv=none; b=aTRmgf7Q3sfCBHr4hj//jl30+j/P/BzpEYUWPRDGsDkohY8ug3vWeIQ1PBP0u1kuChLpxTsFXR4y0HtlhiDuoyJPMn8yDjhprr4zVsh1DLqnfHmKVP+B8VdiLsCjmr2vnNrl5IphdY+XhqAj9uQlRDTTXEN+BVP9O3kfaKuuG5M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822804; c=relaxed/simple; bh=xGrjr3R26cChQa8oIfDI45hhfkDbQaXebwPvgJtwy7M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=EB479nyUSOg8uevImVvblxWNL/AEqxPYNrKVhcCIBKwejc1NSzKxhHffRZnzb0lkgZsRlacip6yh94X3wOwfM82VinEIFMb0NS9eh1eSX545TrC4B0wcryHv4lxPzO3sxDXI05IdjkeG9yYsk3J+oEUSxKLbU/dDL59X4HUnBhY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=NDE5SBxh; arc=none smtp.client-ip=91.218.175.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="NDE5SBxh" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770822800; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=PVUmNNYrKZTMQSU8roklyUGMEweqe6NZoOaXUuUpkiE=; b=NDE5SBxh3t9nliHgAZuh19mPwWVuj03geI3N6I5XUxqQyCrliVuiWmFPfzJ+LHBybsFrO3 W+r31jyqw6lBm+mLn/GO6ppg5kCK/BstAccV5tHqM/wvhXcaxhHnh8ECC4+0BwByCewIX3 xPOogx83i9jPS3FG3iYk5CP8iC9CrpM= From: Leon Hwang To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Christian Brauner , Seth Forshee , Yuichiro Tsuji , Andrey Albershteyn , Leon Hwang , Willem de Bruijn , Jason Xing , Tao Chen , Mykyta Yatsenko , Kumar Kartikeya Dwivedi , Anton Protopopov , Amery Hung , Rong Tao , linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-kselftest@vger.kernel.org, kernel-patches-bot@fb.com Subject: [PATCH bpf-next v10 5/8] bpf: Add syscall common attributes support for btf_load Date: Wed, 11 Feb 2026 23:11:12 +0800 Message-ID: <20260211151115.78013-6-leon.hwang@linux.dev> In-Reply-To: <20260211151115.78013-1-leon.hwang@linux.dev> References: <20260211151115.78013-1-leon.hwang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" BPF_BTF_LOAD can now take log parameters from both union bpf_attr and struct bpf_common_attr, with the same merge rules as BPF_PROG_LOAD: - if both sides provide a complete log tuple (buf/size/level) and they match, use it; - if only one side provides log parameters, use that one; - if both sides provide complete tuples but they differ, return -EINVAL. Signed-off-by: Leon Hwang Acked-by: Andrii Nakryiko --- include/linux/btf.h | 3 ++- kernel/bpf/btf.c | 30 +++++++----------------------- kernel/bpf/syscall.c | 11 ++++++++--- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/include/linux/btf.h b/include/linux/btf.h index 48108471c5b1..f64d87315c5f 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); +struct bpf_log_attr; +int btf_new_fd(const union bpf_attr *attr, bpfptr_t uattr, struct bpf_log_= attr *attr_log); 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 7708958e3fb8..810007028b72 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c @@ -5857,25 +5857,10 @@ static int btf_check_type_tags(struct btf_verifier_= env *env, return 0; } =20 -static int finalize_log(struct bpf_verifier_log *log, bpfptr_t uattr, u32 = uattr_size) -{ - u32 log_true_size; - int err; - - err =3D bpf_vlog_finalize(log, &log_true_size); - - if (uattr_size >=3D offsetofend(union bpf_attr, btf_log_true_size) && - copy_to_bpfptr_offset(uattr, offsetof(union bpf_attr, btf_log_true_si= ze), - &log_true_size, sizeof(log_true_size))) - err =3D -EFAULT; - - return err; -} - -static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, u= 32 uattr_size) +static struct btf *btf_parse(const union bpf_attr *attr, bpfptr_t uattr, + struct bpf_log_attr *attr_log) { bpfptr_t btf_data =3D make_bpfptr(attr->btf, uattr.is_kernel); - char __user *log_ubuf =3D u64_to_user_ptr(attr->btf_log_buf); struct btf_struct_metas *struct_meta_tab; struct btf_verifier_env *env =3D NULL; struct btf *btf =3D NULL; @@ -5892,8 +5877,7 @@ static struct btf *btf_parse(const union bpf_attr *at= tr, bpfptr_t uattr, u32 uat /* user could have requested verbose verifier output * and supplied buffer to store the verification trace */ - err =3D bpf_vlog_init(&env->log, attr->btf_log_level, - log_ubuf, attr->btf_log_size); + err =3D bpf_vlog_init(&env->log, attr_log->log_level, attr_log->log_buf, = attr_log->log_size); if (err) goto errout_free; =20 @@ -5954,7 +5938,7 @@ static struct btf *btf_parse(const union bpf_attr *at= tr, bpfptr_t uattr, u32 uat } } =20 - err =3D finalize_log(&env->log, uattr, uattr_size); + err =3D bpf_log_attr_finalize(attr_log, &env->log); if (err) goto errout_free; =20 @@ -5966,7 +5950,7 @@ static struct btf *btf_parse(const union bpf_attr *at= tr, bpfptr_t uattr, u32 uat btf_free_struct_meta_tab(btf); errout: /* overwrite err with -ENOSPC or -EFAULT */ - ret =3D finalize_log(&env->log, uattr, uattr_size); + ret =3D bpf_log_attr_finalize(attr_log, &env->log); if (ret) err =3D ret; errout_free: @@ -8137,12 +8121,12 @@ static int __btf_new_fd(struct btf *btf) return anon_inode_getfd("btf", &btf_fops, btf, O_RDONLY | O_CLOEXEC); } =20 -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, struct bpf_log_= attr *attr_log) { struct btf *btf; int ret; =20 - btf =3D btf_parse(attr, uattr, uattr_size); + btf =3D btf_parse(attr, uattr, attr_log); if (IS_ERR(btf)) return PTR_ERR(btf); =20 diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 17116603ff51..6d727a4b5121 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -5448,7 +5448,7 @@ static int bpf_obj_get_info_by_fd(const union bpf_att= r *attr, =20 #define BPF_BTF_LOAD_LAST_FIELD btf_token_fd =20 -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, struct= bpf_log_attr *attr_log) { struct bpf_token *token =3D NULL; =20 @@ -5475,7 +5475,7 @@ static int bpf_btf_load(const union bpf_attr *attr, b= pfptr_t uattr, __u32 uattr_ =20 bpf_token_put(token); =20 - return btf_new_fd(attr, uattr, uattr_size); + return btf_new_fd(attr, uattr, attr_log); } =20 #define BPF_BTF_GET_FD_BY_ID_LAST_FIELD fd_by_id_token_fd @@ -6293,7 +6293,12 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uatt= r, unsigned int size, err =3D bpf_raw_tracepoint_open(&attr); break; case BPF_BTF_LOAD: - err =3D bpf_btf_load(&attr, uattr, size); + if (from_user && size >=3D offsetofend(union bpf_attr, btf_log_true_size= )) + log_true_size =3D uattr.user + offsetof(union bpf_attr, btf_log_true_si= ze); + err =3D bpf_log_attr_init(&attr_log, attr.btf_log_buf, attr.btf_log_size, + attr.btf_log_level, log_true_size, &attr_common, + uattr_common, size_common); + err =3D err ?: bpf_btf_load(&attr, uattr, &attr_log); break; case BPF_BTF_GET_FD_BY_ID: err =3D bpf_btf_get_fd_by_id(&attr); --=20 2.52.0 From nobody Thu Apr 2 17:43:09 2026 Received: from out-181.mta0.migadu.com (out-181.mta0.migadu.com [91.218.175.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 77C7F2C1788 for ; Wed, 11 Feb 2026 15:13:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822833; cv=none; b=RjnR8i69Bn5b6i0eoWwcJU1CFzlMK3UaNHF7sB+4zmSqL0ulimEzLXiM50QzweP/xKODk8bvCsXjH9o9ZuSkbjTIC6wHkTEjTHszT+cpQGiXlHVYPoDZClMruKTkaAYqtss1NeMqxOJKp5z78CgW8pSQ0RUO66iaiHYOZV4M4jo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822833; c=relaxed/simple; bh=wsNbnNrX/E0oUOQ/abuMeAPFytvjjexeGaGlGVLL/X0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=jneccnTDC9enVvF3kV1xpLYZkjAfAB/U9X/Rd4l0wJ4eEnl9X0P1XEP+kktIH+wKnEBc5vSft4v90fgz1B/eq5T5mzPgDLrISH8O2id5oDG7h5ORAvD21OEARvtDjhLFQe9Y7lK2HYFlw6jDOeeEuEj7gwohoCGQeE+RV58iAdM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=iYsP1oy3; arc=none smtp.client-ip=91.218.175.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="iYsP1oy3" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770822828; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=daYcGmxvC1QIWnmveG7GEdqpmzD/le9h83f5BmM71Tk=; b=iYsP1oy3bjjK1xRAtleWVqSclVdnjMPk595F9m0jHXUWdoTu6DFag+6ymycL8kwssGW8cP tnAn1WDcI09KGYEYCckQqnrGDWGLAZxIJ4TPbusvq+/5JtGGWGJh3gCkfMOOZKOr3q8+Uc dAT4mEyq/r9jCSqakItB/xR5UaSDux4= From: Leon Hwang To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Christian Brauner , Seth Forshee , Yuichiro Tsuji , Andrey Albershteyn , Leon Hwang , Willem de Bruijn , Jason Xing , Tao Chen , Mykyta Yatsenko , Kumar Kartikeya Dwivedi , Anton Protopopov , Amery Hung , Rong Tao , linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-kselftest@vger.kernel.org, kernel-patches-bot@fb.com Subject: [PATCH bpf-next v10 6/8] bpf: Add syscall common attributes support for map_create Date: Wed, 11 Feb 2026 23:11:13 +0800 Message-ID: <20260211151115.78013-7-leon.hwang@linux.dev> In-Reply-To: <20260211151115.78013-1-leon.hwang@linux.dev> References: <20260211151115.78013-1-leon.hwang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Many BPF_MAP_CREATE validation failures currently return -EINVAL without any explanation to userspace. Plumb common syscall log attributes into map_create(), create a verifier log from bpf_common_attr::log_buf/log_size/log_level, and report map-creation failure reasons through that buffer. This improves debuggability by allowing userspace to inspect why map creation failed and read back log_true_size from common attributes. Signed-off-by: Leon Hwang --- include/linux/bpf_verifier.h | 3 ++ kernel/bpf/log.c | 30 +++++++++++++++++ kernel/bpf/syscall.c | 65 ++++++++++++++++++++++++++++++------ 3 files changed, 88 insertions(+), 10 deletions(-) diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 34f28d40022a..52627a93338f 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h @@ -645,6 +645,9 @@ struct bpf_log_attr { int bpf_log_attr_init(struct bpf_log_attr *log, u64 log_buf, u32 log_size,= u32 log_level, u32 __user *log_true_size, struct bpf_common_attr *common, bpfptr_= t uattr, u32 size); +struct bpf_verifier_log *bpf_log_attr_create_vlog(struct bpf_log_attr *att= r_log, + struct bpf_common_attr *common, bpfptr_t uattr, + u32 size); int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_l= og *log); =20 #define BPF_MAX_SUBPROGS 256 diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c index a2b41bf5e9cb..f7251217452e 100644 --- a/kernel/bpf/log.c +++ b/kernel/bpf/log.c @@ -904,6 +904,36 @@ int bpf_log_attr_init(struct bpf_log_attr *log, u64 lo= g_buf, u32 log_size, u32 l return 0; } =20 + +struct bpf_verifier_log *bpf_log_attr_create_vlog(struct bpf_log_attr *att= r_log, + struct bpf_common_attr *common, bpfptr_t uattr, + u32 size) +{ + struct bpf_verifier_log *log; + int err; + + memset(attr_log, 0, sizeof(*attr_log)); + if (size >=3D offsetofend(struct bpf_common_attr, log_true_size)) + attr_log->log_true_size =3D uattr.user + offsetof(struct bpf_common_attr, + log_true_size); + + if (!common->log_buf) + return NULL; + + log =3D kzalloc_obj(*log, GFP_KERNEL); + if (!log) + return ERR_PTR(-ENOMEM); + + err =3D bpf_vlog_init(log, common->log_level, u64_to_user_ptr(common->log= _buf), + common->log_size); + if (err) { + kfree(log); + return ERR_PTR(err); + } + + return log; +} + int bpf_log_attr_finalize(struct bpf_log_attr *attr, struct bpf_verifier_l= og *log) { u32 log_true_size; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 6d727a4b5121..04bb4a905559 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1365,7 +1365,7 @@ static int map_check_btf(struct bpf_map *map, struct = bpf_token *token, =20 #define BPF_MAP_CREATE_LAST_FIELD excl_prog_hash_size /* called via syscall */ -static int map_create(union bpf_attr *attr, bpfptr_t uattr) +static int __map_create(union bpf_attr *attr, bpfptr_t uattr, struct bpf_v= erifier_log *log) { const struct bpf_map_ops *ops; struct bpf_token *token =3D NULL; @@ -1377,8 +1377,10 @@ static int map_create(union bpf_attr *attr, bpfptr_t= uattr) int err; =20 err =3D CHECK_ATTR(BPF_MAP_CREATE); - if (err) + if (err) { + bpf_log(log, "Invalid attr.\n"); return -EINVAL; + } =20 /* check BPF_F_TOKEN_FD flag, remember if it's set, and then clear it * to avoid per-map type checks tripping on unknown flag @@ -1387,17 +1389,25 @@ static int map_create(union bpf_attr *attr, bpfptr_= t uattr) attr->map_flags &=3D ~BPF_F_TOKEN_FD; =20 if (attr->btf_vmlinux_value_type_id) { - if (attr->map_type !=3D BPF_MAP_TYPE_STRUCT_OPS || - attr->btf_key_type_id || attr->btf_value_type_id) + if (attr->map_type !=3D BPF_MAP_TYPE_STRUCT_OPS) { + bpf_log(log, "btf_vmlinux_value_type_id can only be used with struct_op= s maps.\n"); return -EINVAL; + } + if (attr->btf_key_type_id || attr->btf_value_type_id) { + bpf_log(log, "btf_vmlinux_value_type_id is mutually exclusive with btf_= key_type_id and btf_value_type_id.\n"); + return -EINVAL; + } } else if (attr->btf_key_type_id && !attr->btf_value_type_id) { + bpf_log(log, "Invalid btf_value_type_id.\n"); return -EINVAL; } =20 if (attr->map_type !=3D BPF_MAP_TYPE_BLOOM_FILTER && attr->map_type !=3D BPF_MAP_TYPE_ARENA && - attr->map_extra !=3D 0) + attr->map_extra !=3D 0) { + bpf_log(log, "Invalid map_extra.\n"); return -EINVAL; + } =20 f_flags =3D bpf_get_file_flag(attr->map_flags); if (f_flags < 0) @@ -1405,13 +1415,17 @@ static int map_create(union bpf_attr *attr, bpfptr_= t uattr) =20 if (numa_node !=3D NUMA_NO_NODE && ((unsigned int)numa_node >=3D nr_node_ids || - !node_online(numa_node))) + !node_online(numa_node))) { + bpf_log(log, "Invalid numa_node.\n"); return -EINVAL; + } =20 /* find map type and init map: hashtable vs rbtree vs bloom vs ... */ map_type =3D attr->map_type; - if (map_type >=3D ARRAY_SIZE(bpf_map_types)) + if (map_type >=3D ARRAY_SIZE(bpf_map_types)) { + bpf_log(log, "Invalid map_type.\n"); return -EINVAL; + } map_type =3D array_index_nospec(map_type, ARRAY_SIZE(bpf_map_types)); ops =3D bpf_map_types[map_type]; if (!ops) @@ -1429,8 +1443,10 @@ static int map_create(union bpf_attr *attr, bpfptr_t= uattr) =20 if (token_flag) { token =3D bpf_token_get_from_fd(attr->map_token_fd); - if (IS_ERR(token)) + if (IS_ERR(token)) { + bpf_log(log, "Invalid map_token_fd.\n"); return PTR_ERR(token); + } =20 /* if current token doesn't grant map creation permissions, * then we can't use this token, so ignore it and rely on @@ -1513,8 +1529,10 @@ static int map_create(union bpf_attr *attr, bpfptr_t= uattr) =20 err =3D bpf_obj_name_cpy(map->name, attr->map_name, sizeof(attr->map_name)); - if (err < 0) + if (err < 0) { + bpf_log(log, "Invalid map_name.\n"); goto free_map; + } =20 preempt_disable(); map->cookie =3D gen_cookie_next(&bpf_map_cookie); @@ -1537,6 +1555,7 @@ static int map_create(union bpf_attr *attr, bpfptr_t = uattr) =20 btf =3D btf_get_by_fd(attr->btf_fd); if (IS_ERR(btf)) { + bpf_log(log, "Invalid btf_fd.\n"); err =3D PTR_ERR(btf); goto free_map; } @@ -1564,6 +1583,7 @@ static int map_create(union bpf_attr *attr, bpfptr_t = uattr) bpfptr_t uprog_hash =3D make_bpfptr(attr->excl_prog_hash, uattr.is_kerne= l); =20 if (attr->excl_prog_hash_size !=3D SHA256_DIGEST_SIZE) { + bpf_log(log, "Invalid excl_prog_hash_size.\n"); err =3D -EINVAL; goto free_map; } @@ -1579,6 +1599,7 @@ static int map_create(union bpf_attr *attr, bpfptr_t = uattr) goto free_map; } } else if (attr->excl_prog_hash_size) { + bpf_log(log, "Invalid excl_prog_hash_size.\n"); err =3D -EINVAL; goto free_map; } @@ -1617,6 +1638,30 @@ static int map_create(union bpf_attr *attr, bpfptr_t= uattr) return err; } =20 +static int map_create(union bpf_attr *attr, bpfptr_t uattr, struct bpf_com= mon_attr *attr_common, + bpfptr_t uattr_common, u32 size_common) +{ + struct bpf_verifier_log *log; + struct bpf_log_attr attr_log; + int err, ret; + + log =3D bpf_log_attr_create_vlog(&attr_log, attr_common, uattr_common, si= ze_common); + if (IS_ERR(log)) + return PTR_ERR(log); + + err =3D __map_create(attr, uattr, log); + if (err >=3D 0) + goto free; + + ret =3D bpf_log_attr_finalize(&attr_log, log); + if (ret) + err =3D ret; + +free: + kfree(log); + return err; +} + void bpf_map_inc(struct bpf_map *map) { atomic64_inc(&map->refcnt); @@ -6226,7 +6271,7 @@ static int __sys_bpf(enum bpf_cmd cmd, bpfptr_t uattr= , unsigned int size, =20 switch (cmd) { case BPF_MAP_CREATE: - err =3D map_create(&attr, uattr); + err =3D map_create(&attr, uattr, &attr_common, uattr_common, size_common= ); break; case BPF_MAP_LOOKUP_ELEM: err =3D map_lookup_elem(&attr); --=20 2.52.0 From nobody Thu Apr 2 17:43:09 2026 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C19D52C11E4 for ; Wed, 11 Feb 2026 15:14:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822847; cv=none; b=TWDLHMKkuAE/6blMRY8ON4+f2GOR33DoUZXZmNBUdzthQvOa8fkh1pXyjk5spk8+DdUDOhrJCn0Elvx4v1LMx7dgyGWA2ytN4zbkrvD1rMtnYdIaNB+n06rTSRso4ZkQmS0oBRgsiMQANggR0ZQMYxGEimO7GQsi1amZRPLVoR4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822847; c=relaxed/simple; bh=gnEMOtd8FWF1Mm8F80lXlNVgFhdShhiT2kKRS5dMM8c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Zn7v83O3GsM+Cjbn+RbO7Mo10Tg6Zd2kVsHoxFgUheszFC8e7d6IK88+HaUwuFPxdAirqsI0QfnP2Vz6Z+Ban94beJp7BIO2QNKNLF/dvjfGFYPgNidOZwayG3jerLe5dQTVISZQpSx4KvEpmsmW0z6KSznGrLynnXh3WqUg3/k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=RvszaWut; arc=none smtp.client-ip=91.218.175.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="RvszaWut" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770822842; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WEd1Tu6pzCQjp2hnQoKiK4JRxMafdGLudagS7tdkGr4=; b=RvszaWutwelRYGbPptNYWBQBsi2lb/jXpd8yhcWvs/LnCsb2gFvMisGfWlpsm2Pn1WN3oG akbPSzsaecHgEPsMHJtn2jlO8HBy1hqIyF0YCuAE+HoXSESLsG5zp3n1GlTg07toBFueUI fVJgykLXo11u5Rr8gYGF1R5CkMc4Vp8= From: Leon Hwang To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Christian Brauner , Seth Forshee , Yuichiro Tsuji , Andrey Albershteyn , Leon Hwang , Willem de Bruijn , Jason Xing , Tao Chen , Mykyta Yatsenko , Kumar Kartikeya Dwivedi , Anton Protopopov , Amery Hung , Rong Tao , linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-kselftest@vger.kernel.org, kernel-patches-bot@fb.com Subject: [PATCH bpf-next v10 7/8] libbpf: Add syscall common attributes support for map_create Date: Wed, 11 Feb 2026 23:11:14 +0800 Message-ID: <20260211151115.78013-8-leon.hwang@linux.dev> In-Reply-To: <20260211151115.78013-1-leon.hwang@linux.dev> References: <20260211151115.78013-1-leon.hwang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" With the previous commit adding common attribute support for BPF_MAP_CREATE, users can now retrieve detailed error messages when map creation fails via the log_buf field. Introduce struct bpf_log_opts with the following fields: log_buf, log_size, log_level, and log_true_size. Extend bpf_map_create_opts with a new field log_opts, allowing users to capture and inspect log messages on map creation failures. Acked-by: Andrii Nakryiko Signed-off-by: Leon Hwang --- tools/lib/bpf/bpf.c | 16 +++++++++++++++- tools/lib/bpf/bpf.h | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 9d8740761b7a..0c3e40844d80 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -209,6 +209,9 @@ int bpf_map_create(enum bpf_map_type map_type, const struct bpf_map_create_opts *opts) { const size_t attr_sz =3D offsetofend(union bpf_attr, excl_prog_hash_size); + const size_t attr_common_sz =3D sizeof(struct bpf_common_attr); + struct bpf_common_attr attr_common; + struct bpf_log_opts *log_opts; union bpf_attr attr; int fd; =20 @@ -242,7 +245,18 @@ int bpf_map_create(enum bpf_map_type map_type, attr.excl_prog_hash =3D ptr_to_u64(OPTS_GET(opts, excl_prog_hash, NULL)); attr.excl_prog_hash_size =3D OPTS_GET(opts, excl_prog_hash_size, 0); =20 - fd =3D sys_bpf_fd(BPF_MAP_CREATE, &attr, attr_sz); + log_opts =3D OPTS_GET(opts, log_opts, NULL); + if (log_opts && feat_supported(NULL, FEAT_BPF_SYSCALL_COMMON_ATTRS)) { + memset(&attr_common, 0, attr_common_sz); + attr_common.log_buf =3D ptr_to_u64(OPTS_GET(log_opts, log_buf, NULL)); + attr_common.log_size =3D OPTS_GET(log_opts, log_size, 0); + attr_common.log_level =3D OPTS_GET(log_opts, log_level, 0); + fd =3D sys_bpf_ext_fd(BPF_MAP_CREATE, &attr, attr_sz, &attr_common, attr= _common_sz); + OPTS_SET(log_opts, log_true_size, attr_common.log_true_size); + } else { + fd =3D sys_bpf_fd(BPF_MAP_CREATE, &attr, attr_sz); + OPTS_SET(log_opts, log_true_size, 0); + } return libbpf_err_errno(fd); } =20 diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 2c8e88ddb674..db834f09799e 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h @@ -37,6 +37,18 @@ extern "C" { =20 LIBBPF_API int libbpf_set_memlock_rlim(size_t memlock_bytes); =20 +struct bpf_log_opts { + size_t sz; /* size of this struct for forward/backward compatibility */ + + char *log_buf; + __u32 log_size; + __u32 log_level; + __u32 log_true_size; /* out parameter set by kernel */ + + size_t :0; +}; +#define bpf_log_opts__last_field log_true_size + struct bpf_map_create_opts { size_t sz; /* size of this struct for forward/backward compatibility */ =20 @@ -57,9 +69,12 @@ struct bpf_map_create_opts { =20 const void *excl_prog_hash; __u32 excl_prog_hash_size; + + struct bpf_log_opts *log_opts; + size_t :0; }; -#define bpf_map_create_opts__last_field excl_prog_hash_size +#define bpf_map_create_opts__last_field log_opts =20 LIBBPF_API int bpf_map_create(enum bpf_map_type map_type, const char *map_name, --=20 2.52.0 From nobody Thu Apr 2 17:43:09 2026 Received: from out-186.mta0.migadu.com (out-186.mta0.migadu.com [91.218.175.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 250352C11F7; Wed, 11 Feb 2026 15:14:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.186 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822859; cv=none; b=DMghp6U11DIoNvkpwyg8KhUyLH2k13Jxhj+QHsWkfU8t25kZG7reZ03oE1mhYminp3MVNIDFLiBfAoZCOyuTVy2CL7u4rduzIWD/bhNynep5X+vxQZqvq0nog25urEDk2jK60P/tLevF46SOoFM1s95yS9vkMwPbjGa9m9cTrIQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770822859; c=relaxed/simple; bh=Xbuo0FEpNgg2KvKrlkPAzBRG1hOjRZTYZrlBKdxpLfg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CRbxRzlsKSvbd9F8JEjfTO9BWQjylra8BIO58FXhcATohvBDDKIRQSMVHF1sMjQQnhW6DTBX2jjTPmfKp3UE3N/jJkOl0veDoL/Qa+xBzV3soHyqZqxIwbz4JS9dNq+LoC+WISQu8W98qSPPOMbdXMO7HTjyANXMt9JwYHgi9lQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=wpdZeo8d; arc=none smtp.client-ip=91.218.175.186 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="wpdZeo8d" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1770822855; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=a5In126ErDNUVM/dknzqOxFVFJMm2FSnEOt8BQhQYkg=; b=wpdZeo8do+KS5ANCddRxS7Ag4bCm2/yv/POl8agOb6SzqiHbgUyHDmATFj9DH3BQjsArlt CtYUWTo8PnNoug6sys0CTEjbGQCCjjFgzc7wrP/zDB5BBMuWcxhi7C4jMlrvxdWPs1H5WF rgR98psbfFwGUo14xK1u72IK9yiB/xg= From: Leon Hwang To: bpf@vger.kernel.org Cc: Alexei Starovoitov , Daniel Borkmann , John Fastabend , Andrii Nakryiko , Martin KaFai Lau , Eduard Zingerman , Song Liu , Yonghong Song , KP Singh , Stanislav Fomichev , Hao Luo , Jiri Olsa , Shuah Khan , Christian Brauner , Seth Forshee , Yuichiro Tsuji , Andrey Albershteyn , Leon Hwang , Willem de Bruijn , Jason Xing , Tao Chen , Mykyta Yatsenko , Kumar Kartikeya Dwivedi , Anton Protopopov , Amery Hung , Rong Tao , linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, linux-kselftest@vger.kernel.org, kernel-patches-bot@fb.com Subject: [PATCH bpf-next v10 8/8] selftests/bpf: Add tests to verify map create failure log Date: Wed, 11 Feb 2026 23:11:15 +0800 Message-ID: <20260211151115.78013-9-leon.hwang@linux.dev> In-Reply-To: <20260211151115.78013-1-leon.hwang@linux.dev> References: <20260211151115.78013-1-leon.hwang@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" Add tests to verify that the kernel reports the expected error messages when map creation fails. Signed-off-by: Leon Hwang --- .../selftests/bpf/prog_tests/map_init.c | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/tools/testing/selftests/bpf/prog_tests/map_init.c b/tools/test= ing/selftests/bpf/prog_tests/map_init.c index 14a31109dd0e..b8b727e24b5e 100644 --- a/tools/testing/selftests/bpf/prog_tests/map_init.c +++ b/tools/testing/selftests/bpf/prog_tests/map_init.c @@ -212,3 +212,169 @@ void test_map_init(void) if (test__start_subtest("pcpu_lru_map_init")) test_pcpu_lru_map_init(); } + +static void test_map_create(enum bpf_map_type map_type, const char *map_na= me, + struct bpf_map_create_opts *opts, const char *exp_msg) +{ + const int key_size =3D 4, value_size =3D 4, max_entries =3D 1; + char log_buf[128]; + int fd; + LIBBPF_OPTS(bpf_log_opts, log_opts); + + log_buf[0] =3D '\0'; + log_opts.log_buf =3D log_buf; + log_opts.log_size =3D sizeof(log_buf); + log_opts.log_level =3D 1; + opts->log_opts =3D &log_opts; + fd =3D bpf_map_create(map_type, map_name, key_size, value_size, max_entri= es, opts); + if (!ASSERT_LT(fd, 0, "bpf_map_create")) { + close(fd); + return; + } + + ASSERT_STREQ(log_buf, exp_msg, "log_buf"); + ASSERT_EQ(log_opts.log_true_size, strlen(exp_msg) + 1, "log_true_size"); +} + +static void test_map_create_array(struct bpf_map_create_opts *opts, const = char *exp_msg) +{ + test_map_create(BPF_MAP_TYPE_ARRAY, "test_map_create", opts, exp_msg); +} + +static void test_invalid_vmlinux_value_type_id_struct_ops(void) +{ + const char *msg =3D "btf_vmlinux_value_type_id can only be used with stru= ct_ops maps.\n"; + LIBBPF_OPTS(bpf_map_create_opts, opts, + .btf_vmlinux_value_type_id =3D 1, + ); + + test_map_create_array(&opts, msg); +} + +static void test_invalid_vmlinux_value_type_id_kv_type_id(void) +{ + const char *msg =3D "btf_vmlinux_value_type_id is mutually exclusive with= btf_key_type_id and btf_value_type_id.\n"; + LIBBPF_OPTS(bpf_map_create_opts, opts, + .btf_vmlinux_value_type_id =3D 1, + .btf_key_type_id =3D 1, + ); + + test_map_create(BPF_MAP_TYPE_STRUCT_OPS, "test_map_create", &opts, msg); +} + +static void test_invalid_value_type_id(void) +{ + const char *msg =3D "Invalid btf_value_type_id.\n"; + LIBBPF_OPTS(bpf_map_create_opts, opts, + .btf_key_type_id =3D 1, + ); + + test_map_create_array(&opts, msg); +} + +static void test_invalid_map_extra(void) +{ + const char *msg =3D "Invalid map_extra.\n"; + LIBBPF_OPTS(bpf_map_create_opts, opts, + .map_extra =3D 1, + ); + + test_map_create_array(&opts, msg); +} + +static void test_invalid_numa_node(void) +{ + const char *msg =3D "Invalid numa_node.\n"; + LIBBPF_OPTS(bpf_map_create_opts, opts, + .map_flags =3D BPF_F_NUMA_NODE, + .numa_node =3D 0xFF, + ); + + test_map_create_array(&opts, msg); +} + +static void test_invalid_map_type(void) +{ + const char *msg =3D "Invalid map_type.\n"; + LIBBPF_OPTS(bpf_map_create_opts, opts); + + test_map_create(__MAX_BPF_MAP_TYPE, "test_map_create", &opts, msg); +} + +static void test_invalid_token_fd(void) +{ + const char *msg =3D "Invalid map_token_fd.\n"; + LIBBPF_OPTS(bpf_map_create_opts, opts, + .map_flags =3D BPF_F_TOKEN_FD, + .token_fd =3D 0xFF, + ); + + test_map_create_array(&opts, msg); +} + +static void test_invalid_map_name(void) +{ + const char *msg =3D "Invalid map_name.\n"; + LIBBPF_OPTS(bpf_map_create_opts, opts); + + test_map_create(BPF_MAP_TYPE_ARRAY, "test-!@#", &opts, msg); +} + +static void test_invalid_btf_fd(void) +{ + const char *msg =3D "Invalid btf_fd.\n"; + LIBBPF_OPTS(bpf_map_create_opts, opts, + .btf_fd =3D -1, + .btf_key_type_id =3D 1, + .btf_value_type_id =3D 1, + ); + + test_map_create_array(&opts, msg); +} + +static void test_excl_prog_hash_size_1(void) +{ + const char *msg =3D "Invalid excl_prog_hash_size.\n"; + const char *hash =3D "DEADCODE"; + LIBBPF_OPTS(bpf_map_create_opts, opts, + .excl_prog_hash =3D hash, + ); + + test_map_create_array(&opts, msg); +} + +static void test_excl_prog_hash_size_2(void) +{ + const char *msg =3D "Invalid excl_prog_hash_size.\n"; + LIBBPF_OPTS(bpf_map_create_opts, opts, + .excl_prog_hash_size =3D 1, + ); + + test_map_create_array(&opts, msg); +} + +void test_map_create_failure(void) +{ + if (test__start_subtest("invalid_vmlinux_value_type_id_struct_ops")) + test_invalid_vmlinux_value_type_id_struct_ops(); + if (test__start_subtest("invalid_vmlinux_value_type_id_kv_type_id")) + test_invalid_vmlinux_value_type_id_kv_type_id(); + if (test__start_subtest("invalid_value_type_id")) + test_invalid_value_type_id(); + if (test__start_subtest("invalid_map_extra")) + test_invalid_map_extra(); + if (test__start_subtest("invalid_numa_node")) + test_invalid_numa_node(); + if (test__start_subtest("invalid_map_type")) + test_invalid_map_type(); + if (test__start_subtest("invalid_token_fd")) + test_invalid_token_fd(); + if (test__start_subtest("invalid_map_name")) + test_invalid_map_name(); + if (test__start_subtest("invalid_btf_fd")) + test_invalid_btf_fd(); + if (test__start_subtest("invalid_excl_prog_hash_size_1")) + test_excl_prog_hash_size_1(); + if (test__start_subtest("invalid_excl_prog_hash_size_2")) + test_excl_prog_hash_size_2(); +} --=20 2.52.0