From: Amery Hung <ameryhung@gmail.com>
To: bpf@vger.kernel.org
Cc: alexei.starovoitov@gmail.com, andrii@kernel.org,
daniel@iogearbox.net, eddyz87@gmail.com, memxor@gmail.com,
ameryhung@gmail.com, kernel-team@meta.com
Subject: [PATCH bpf-next v1 06/22] bpf: Unify kfunc argument kinds with enum bpf_arg_type
Date: Sat, 5 Sep 2026 15:01:01 -0700 [thread overview]
Message-ID: <20260905220117.922028-7-ameryhung@gmail.com> (raw)
In-Reply-To: <20260905220117.922028-1-ameryhung@gmail.com>
check_kfunc_args() classifies arguments with enum kfunc_ptr_arg_type
while check_func_arg() uses enum bpf_arg_type, yet both classifications
are stored in bpf_func_proto::arg_type. The overlapping namespaces force
the kfunc path to translate argument kinds before calling shared checks.
Fold the kfunc kinds into enum bpf_arg_type. Reuse ARG_SCALAR and
the existing pointer and memory kinds where their semantics match,
map kfunc callbacks to ARG_PTR_TO_FUNC, and add enumerators for the
remaining kfunc-only kinds. check_kfunc_args() can then carry one
classification throughout verification.
Preserving the original argument kind also lets
check_func_arg_reg_off() derive the zero-offset requirement for
ARG_PTR_TO_REFCOUNTED_KPTR directly. Remove its separate
btf_id_fixed_off_ok parameter and wrapper, along with the now-empty
translation switch in check_kfunc_args().
No functional change.
Signed-off-by: Amery Hung <ameryhung@gmail.com>
---
include/linux/bpf.h | 14 +++
kernel/bpf/verifier.c | 221 ++++++++++++++----------------------------
2 files changed, 87 insertions(+), 148 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 1574fe2d8cc0..f620920ea575 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -908,6 +908,20 @@ enum bpf_arg_type {
ARG_PTR_TO_TIMER, /* pointer to bpf_timer */
ARG_KPTR_XCHG_DEST, /* pointer to destination that kptrs are bpf_kptr_xchg'd into */
ARG_PTR_TO_DYNPTR, /* pointer to bpf_dynptr. See bpf_type_flag for dynptr type */
+
+ ARG_CONST_SCALAR, /* scalar known at verification time */
+ ARG_CONST_MEM_SIZE, /* ARG_MEM_SIZE that must be constant */
+ ARG_PTR_TO_ALLOC_BTF_ID, /* pointer to an allocated object */
+ ARG_PTR_TO_REFCOUNTED_KPTR, /* pointer to a refcounted local kptr */
+ ARG_PTR_TO_ITER, /* pointer to an iterator */
+ ARG_PTR_TO_LIST_HEAD, /* pointer to bpf_list_head */
+ ARG_PTR_TO_LIST_NODE, /* pointer to bpf_list_node */
+ ARG_PTR_TO_RB_ROOT, /* pointer to bpf_rb_root */
+ ARG_PTR_TO_RB_NODE, /* pointer to bpf_rb_node */
+ ARG_PTR_TO_WORKQUEUE, /* pointer to bpf_wq */
+ ARG_PTR_TO_TASK_WORK, /* pointer to bpf_task_work */
+ ARG_PTR_TO_IRQ_FLAG, /* pointer to saved IRQ flags on the stack */
+ ARG_PTR_TO_RES_SPIN_LOCK, /* pointer to bpf_res_spin_lock */
__BPF_ARG_TYPE_MAX,
/* Extended arg_types. */
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index d444e72fdd97..a0a74a5e23be 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -8533,10 +8533,9 @@ reg_find_field_offset(const struct bpf_reg_state *reg, s32 off, u32 fields)
return field;
}
-static int __check_func_arg_reg_off(struct bpf_verifier_env *env,
- const struct bpf_reg_state *reg, argno_t argno,
- enum bpf_arg_type arg_type,
- bool btf_id_fixed_off_ok)
+static int check_func_arg_reg_off(struct bpf_verifier_env *env,
+ const struct bpf_reg_state *reg, argno_t argno,
+ enum bpf_arg_type arg_type)
{
u32 type = reg->type;
@@ -8592,12 +8591,15 @@ static int __check_func_arg_reg_off(struct bpf_verifier_env *env,
case PTR_TO_BTF_ID | MEM_ALLOC | NON_OWN_REF:
case PTR_TO_BTF_ID | MEM_ALLOC | NON_OWN_REF | MEM_RCU:
/* When referenced PTR_TO_BTF_ID is passed to release function,
- * its fixed offset must be 0. In the other cases, fixed offset
- * can be non-zero unless the caller requires otherwise.
- * var_off always must be 0 for PTR_TO_BTF_ID, hence we still
- * need to do checks instead of returning.
+ * its fixed offset must be 0. bpf_refcount_acquire() returns the
+ * pointer it was given while incrementing the refcount at the
+ * refcount field offset, so it needs a zero offset too. In the
+ * other cases, fixed offset can be non-zero. var_off always must
+ * be 0 for PTR_TO_BTF_ID, hence we still need to do checks
+ * instead of returning.
*/
- return __check_ptr_off_reg(env, reg, argno, btf_id_fixed_off_ok);
+ return __check_ptr_off_reg(env, reg, argno,
+ base_type(arg_type) != ARG_PTR_TO_REFCOUNTED_KPTR);
case PTR_TO_CTX:
/*
* Allow fixed and variable offsets for syscall context, but
@@ -8613,13 +8615,6 @@ static int __check_func_arg_reg_off(struct bpf_verifier_env *env,
}
}
-static int check_func_arg_reg_off(struct bpf_verifier_env *env,
- const struct bpf_reg_state *reg, argno_t argno,
- enum bpf_arg_type arg_type)
-{
- return __check_func_arg_reg_off(env, reg, argno, arg_type, true);
-}
-
static int check_arg_const_str(struct bpf_verifier_env *env,
struct bpf_reg_state *reg, argno_t argno)
{
@@ -11793,34 +11788,6 @@ static void btf_member_path_str(const struct btf *btf, const struct btf_member_p
}
}
-enum kfunc_ptr_arg_type {
- KF_ARG_CONST_MEM_SIZE,
- KF_ARG_MEM_SIZE,
- KF_ARG_CONST,
- KF_ARG_CONST_ALLOC_SIZE_OR_ZERO,
- KF_ARG_ANYTHING,
- KF_ARG_PTR_TO_CTX,
- KF_ARG_PTR_TO_ALLOC_BTF_ID, /* Allocated object */
- KF_ARG_PTR_TO_REFCOUNTED_KPTR, /* Refcounted local kptr */
- KF_ARG_PTR_TO_DYNPTR,
- KF_ARG_PTR_TO_ITER,
- KF_ARG_PTR_TO_LIST_HEAD,
- KF_ARG_PTR_TO_LIST_NODE,
- KF_ARG_PTR_TO_BTF_ID, /* Also covers reg2btf_ids conversions */
- KF_ARG_PTR_TO_MEM,
- KF_ARG_PTR_TO_CALLBACK,
- KF_ARG_PTR_TO_RB_ROOT,
- KF_ARG_PTR_TO_RB_NODE,
- KF_ARG_PTR_TO_CONST_STR,
- KF_ARG_CONST_MAP_PTR,
- KF_ARG_PTR_TO_TIMER,
- KF_ARG_PTR_TO_WORKQUEUE,
- KF_ARG_PTR_TO_IRQ_FLAG,
- KF_ARG_PTR_TO_RES_SPIN_LOCK,
- KF_ARG_PTR_TO_TASK_WORK,
- KF_ARG_PTR_TO_ARENA,
-};
-
enum special_kfunc_type {
KF_bpf_obj_new_impl,
KF_bpf_obj_new,
@@ -12082,15 +12049,15 @@ get_kfunc_arg_type(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
/* Scalar arguments are classified from their BTF suffix/name alone. */
if (btf_type_is_scalar(t)) {
if (is_kfunc_arg_constant(meta->btf, &args[arg]))
- return KF_ARG_CONST;
+ return ARG_CONST_SCALAR;
if (is_kfunc_arg_const_mem_size(meta->btf, &args[arg]))
- return KF_ARG_CONST_MEM_SIZE;
+ return ARG_CONST_MEM_SIZE;
if (is_kfunc_arg_mem_size(meta->btf, &args[arg]))
- return KF_ARG_MEM_SIZE;
+ return ARG_MEM_SIZE;
if (is_kfunc_arg_scalar_with_name(meta->btf, &args[arg], "rdonly_buf_size") ||
is_kfunc_arg_scalar_with_name(meta->btf, &args[arg], "rdwr_buf_size"))
- return KF_ARG_CONST_ALLOC_SIZE_OR_ZERO;
- return KF_ARG_ANYTHING;
+ return ARG_CONST_ALLOC_SIZE_OR_ZERO;
+ return ARG_SCALAR;
}
if (!btf_type_is_ptr(t)) {
@@ -12104,48 +12071,48 @@ get_kfunc_arg_type(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
/* In this function, we verify the kfunc's BTF as per the argument type,
* leaving the rest of the verification with respect to the register
* type to our caller. When a set of conditions hold in the BTF type of
- * arguments, we resolve it to a known kfunc_ptr_arg_type.
+ * arguments, we resolve it to a known bpf_arg_type.
*/
if (is_kfunc_call(meta, special_kfunc_list[KF_bpf_cast_to_kern_ctx]) ||
is_kfunc_call(meta, special_kfunc_list[KF_bpf_session_is_return]) ||
is_kfunc_call(meta, special_kfunc_list[KF_bpf_session_cookie]))
- arg_type = KF_ARG_PTR_TO_CTX;
+ arg_type = ARG_PTR_TO_CTX;
else if (btf_is_prog_ctx_type(&env->log, meta->btf, t, resolve_prog_type(env->prog), arg))
- arg_type = KF_ARG_PTR_TO_CTX;
+ arg_type = ARG_PTR_TO_CTX;
else if (is_kfunc_arg_alloc_obj(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_ALLOC_BTF_ID;
+ arg_type = ARG_PTR_TO_ALLOC_BTF_ID;
else if (is_kfunc_arg_refcounted_kptr(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_REFCOUNTED_KPTR;
+ arg_type = ARG_PTR_TO_REFCOUNTED_KPTR;
else if (is_kfunc_arg_dynptr(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_DYNPTR;
+ arg_type = ARG_PTR_TO_DYNPTR;
else if (is_kfunc_arg_iter(meta, arg, &args[arg]))
- arg_type = KF_ARG_PTR_TO_ITER;
+ arg_type = ARG_PTR_TO_ITER;
else if (is_kfunc_arg_list_head(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_LIST_HEAD;
+ arg_type = ARG_PTR_TO_LIST_HEAD;
else if (is_kfunc_arg_list_node(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_LIST_NODE;
+ arg_type = ARG_PTR_TO_LIST_NODE;
else if (is_kfunc_arg_rbtree_root(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_RB_ROOT;
+ arg_type = ARG_PTR_TO_RB_ROOT;
else if (is_kfunc_arg_rbtree_node(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_RB_NODE;
+ arg_type = ARG_PTR_TO_RB_NODE;
else if (is_kfunc_arg_const_str(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_CONST_STR;
+ arg_type = ARG_PTR_TO_CONST_STR;
else if (is_kfunc_arg_const_map(meta->btf, &args[arg]))
- arg_type = KF_ARG_CONST_MAP_PTR;
+ arg_type = ARG_CONST_MAP_PTR;
else if (is_kfunc_arg_map(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_BTF_ID;
+ arg_type = ARG_PTR_TO_BTF_ID;
else if (is_kfunc_arg_wq(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_WORKQUEUE;
+ arg_type = ARG_PTR_TO_WORKQUEUE;
else if (is_kfunc_arg_timer(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_TIMER;
+ arg_type = ARG_PTR_TO_TIMER;
else if (is_kfunc_arg_task_work(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_TASK_WORK;
+ arg_type = ARG_PTR_TO_TASK_WORK;
else if (is_kfunc_arg_irq_flag(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_IRQ_FLAG;
+ arg_type = ARG_PTR_TO_IRQ_FLAG;
else if (is_kfunc_arg_res_spin_lock(meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_RES_SPIN_LOCK;
+ arg_type = ARG_PTR_TO_RES_SPIN_LOCK;
else if (is_kfunc_arg_callback(env, meta->btf, &args[arg]))
- arg_type = KF_ARG_PTR_TO_CALLBACK;
+ arg_type = ARG_PTR_TO_FUNC;
else if (is_kfunc_arg_arena(meta->btf, &args[arg])) {
if (!bpf_jit_supports_arena_args()) {
verbose(env, "JIT does not support kfunc %s() with arena pointer arguments\n",
@@ -12168,7 +12135,7 @@ get_kfunc_arg_type(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
* whether the JIT rebases it to the arena base or preserves NULL.
* The common nullable path below records that verifier property.
*/
- arg_type = KF_ARG_PTR_TO_ARENA;
+ arg_type = ARG_PTR_TO_ARENA;
} else if (arg + 1 < nargs &&
(is_kfunc_arg_mem_size(meta->btf, &args[arg + 1]) ||
is_kfunc_arg_const_mem_size(meta->btf, &args[arg + 1]))) {
@@ -12178,10 +12145,10 @@ get_kfunc_arg_type(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
reg_arg_name(env, argno), btf_type_str(ref_t), ref_tname);
return -EINVAL;
}
- arg_type = KF_ARG_PTR_TO_MEM;
+ arg_type = ARG_PTR_TO_MEM;
} else if (btf_type_is_struct(ref_t))
- /* A pointer to a struct without a size argument is classified as KF_ARG_PTR_TO_BTF_ID */
- arg_type = KF_ARG_PTR_TO_BTF_ID;
+ /* A pointer to a struct without a size argument is classified as ARG_PTR_TO_BTF_ID */
+ arg_type = ARG_PTR_TO_BTF_ID;
else {
/*
* Otherwise this is a fixed-size memory buffer supported by
@@ -12194,7 +12161,7 @@ get_kfunc_arg_type(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
reg_arg_name(env, argno), btf_type_str(ref_t), ref_tname);
return -EINVAL;
}
- arg_type = KF_ARG_PTR_TO_MEM | MEM_FIXED_SIZE;
+ arg_type = ARG_PTR_TO_MEM | MEM_FIXED_SIZE;
}
if (is_kfunc_arg_nullable(meta->btf, &args[arg]))
@@ -12826,13 +12793,11 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
*/
for (i = 0; i < nargs; i++) {
struct bpf_reg_state *reg = get_func_arg_reg(caller, regs, i);
+ enum bpf_arg_type arg_type = meta->fn->arg_type[i];
const struct btf_type *t, *ref_t, *resolve_ret;
- enum bpf_arg_type arg_type = ARG_UNUSED;
argno_t argno = argno_from_arg(i + 1);
int regno = reg_from_argno(argno);
- bool btf_id_fixed_off_ok = true;
u32 ref_id = args[i].type, type_size;
- int kf_arg_type = meta->fn->arg_type[i];
if (is_kfunc_arg_prog_aux(btf, &args[i])) {
/* Reject repeated use bpf_prog_aux */
@@ -12862,7 +12827,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (btf_type_is_ptr(t) &&
(bpf_register_is_null(reg) || type_may_be_null(reg->type)) &&
- !type_may_be_null(kf_arg_type)) {
+ !type_may_be_null(arg_type)) {
const char *expected_type;
expected_type = bpf_diag_fmt_btf_type(env, btf, args[i].type);
@@ -12892,7 +12857,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (reg_is_referenced(env, reg))
update_ref_obj(&meta->ref_obj, reg);
- if (bpf_register_is_null(reg) && type_may_be_null(kf_arg_type))
+ if (bpf_register_is_null(reg) && type_may_be_null(arg_type))
continue;
if (is_kfunc_arg_map(btf, &args[i])) {
@@ -12901,54 +12866,14 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
ref_tname = btf_name_by_offset(btf, ref_t->name_off);
}
- switch (base_type(kf_arg_type)) {
- case KF_ARG_CONST:
- case KF_ARG_CONST_MEM_SIZE:
- case KF_ARG_MEM_SIZE:
- case KF_ARG_ANYTHING:
- case KF_ARG_CONST_ALLOC_SIZE_OR_ZERO:
- case KF_ARG_PTR_TO_ALLOC_BTF_ID:
- case KF_ARG_PTR_TO_BTF_ID:
- case KF_ARG_CONST_MAP_PTR:
- case KF_ARG_PTR_TO_ITER:
- case KF_ARG_PTR_TO_LIST_HEAD:
- case KF_ARG_PTR_TO_LIST_NODE:
- case KF_ARG_PTR_TO_RB_ROOT:
- case KF_ARG_PTR_TO_RB_NODE:
- case KF_ARG_PTR_TO_MEM:
- case KF_ARG_PTR_TO_CALLBACK:
- case KF_ARG_PTR_TO_CONST_STR:
- case KF_ARG_PTR_TO_WORKQUEUE:
- case KF_ARG_PTR_TO_TIMER:
- case KF_ARG_PTR_TO_TASK_WORK:
- case KF_ARG_PTR_TO_IRQ_FLAG:
- case KF_ARG_PTR_TO_RES_SPIN_LOCK:
- case KF_ARG_PTR_TO_ARENA:
- break;
- case KF_ARG_PTR_TO_DYNPTR:
- arg_type = ARG_PTR_TO_DYNPTR;
- break;
- case KF_ARG_PTR_TO_CTX:
- arg_type = ARG_PTR_TO_CTX;
- break;
- case KF_ARG_PTR_TO_REFCOUNTED_KPTR:
- arg_type = ARG_PTR_TO_BTF_ID;
- btf_id_fixed_off_ok = false;
- break;
- default:
- verifier_bug(env, "unknown kfunc arg type %d", kf_arg_type);
- return -EFAULT;
- }
-
if (regno == meta->release_regno)
arg_type |= OBJ_RELEASE;
- ret = __check_func_arg_reg_off(env, reg, argno, arg_type,
- btf_id_fixed_off_ok);
+ ret = check_func_arg_reg_off(env, reg, argno, arg_type);
if (ret < 0)
return ret;
- switch (base_type(kf_arg_type)) {
- case KF_ARG_CONST:
+ switch (base_type(arg_type)) {
+ case ARG_CONST_SCALAR:
if (reg->type != SCALAR_VALUE) {
verbose(env, "%s is not a scalar\n", reg_arg_name(env, argno));
bpf_diag_call_arg_fmt(env, insn_idx, argno, func_name,
@@ -12969,7 +12894,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
return ret;
}
break;
- case KF_ARG_ANYTHING:
+ case ARG_SCALAR:
if (reg->type != SCALAR_VALUE) {
verbose(env, "%s is not a scalar\n", reg_arg_name(env, argno));
bpf_diag_call_arg_fmt(env, insn_idx, argno, func_name,
@@ -12980,7 +12905,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
return -EINVAL;
}
break;
- case KF_ARG_CONST_ALLOC_SIZE_OR_ZERO:
+ case ARG_CONST_ALLOC_SIZE_OR_ZERO:
if (reg->type != SCALAR_VALUE) {
verbose(env, "%s is not a scalar\n", reg_arg_name(env, argno));
bpf_diag_call_arg_fmt(env, insn_idx, argno, func_name,
@@ -13003,7 +12928,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
return ret;
}
break;
- case KF_ARG_PTR_TO_CTX:
+ case ARG_PTR_TO_CTX:
if (reg->type != PTR_TO_CTX) {
verbose(env, "%s expected pointer to ctx, but got %s\n",
reg_arg_name(env, argno), reg_type_str(env, reg->type));
@@ -13022,14 +12947,14 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
meta->ret_btf_id = ret;
}
break;
- case KF_ARG_PTR_TO_ARENA:
+ case ARG_PTR_TO_ARENA:
if (reg->type != PTR_TO_ARENA && reg->type != SCALAR_VALUE) {
verbose(env, "%s is not a pointer to arena or scalar\n",
reg_arg_name(env, argno));
return -EINVAL;
}
break;
- case KF_ARG_PTR_TO_ALLOC_BTF_ID:
+ case ARG_PTR_TO_ALLOC_BTF_ID:
if (reg->type == (PTR_TO_BTF_ID | MEM_ALLOC)) {
if (!is_bpf_obj_drop_kfunc(meta->func_id)) {
verbose(env, "%s expected for bpf_obj_drop()\n",
@@ -13065,7 +12990,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
meta->arg_btf_id = reg->btf_id;
}
break;
- case KF_ARG_PTR_TO_DYNPTR:
+ case ARG_PTR_TO_DYNPTR:
{
enum bpf_arg_type dynptr_arg_type = ARG_PTR_TO_DYNPTR;
@@ -13100,7 +13025,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
return ret;
break;
}
- case KF_ARG_PTR_TO_ITER:
+ case ARG_PTR_TO_ITER:
if (is_kfunc_call(meta, special_kfunc_list[KF_bpf_iter_css_task_new])) {
if (!check_css_task_iter_allowlist(env)) {
verbose(env, "css_task_iter is only allowed in bpf_lsm, bpf_iter and sleepable progs\n");
@@ -13111,7 +13036,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (ret < 0)
return ret;
break;
- case KF_ARG_PTR_TO_LIST_HEAD:
+ case ARG_PTR_TO_LIST_HEAD:
if (reg->type != PTR_TO_MAP_VALUE &&
reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
verbose(env, "%s expected pointer to map value or allocated object\n",
@@ -13127,7 +13052,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (ret < 0)
return ret;
break;
- case KF_ARG_PTR_TO_RB_ROOT:
+ case ARG_PTR_TO_RB_ROOT:
if (reg->type != PTR_TO_MAP_VALUE &&
reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
verbose(env, "%s expected pointer to map value or allocated object\n",
@@ -13143,7 +13068,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (ret < 0)
return ret;
break;
- case KF_ARG_PTR_TO_LIST_NODE:
+ case ARG_PTR_TO_LIST_NODE:
if (is_kfunc_arg_nonown_allowed(btf, &args[i]) &&
type_is_non_owning_ref(reg->type) && !reg_is_referenced(env, reg)) {
/* Allow bpf_list_front/back return value for
@@ -13165,7 +13090,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (ret < 0)
return ret;
break;
- case KF_ARG_PTR_TO_RB_NODE:
+ case ARG_PTR_TO_RB_NODE:
if (is_bpf_rbtree_add_kfunc(meta->func_id)) {
if (reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
verbose(env, "%s expected pointer to allocated object\n",
@@ -13192,7 +13117,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (ret < 0)
return ret;
break;
- case KF_ARG_CONST_MAP_PTR:
+ case ARG_CONST_MAP_PTR:
if (base_type(reg->type) != CONST_PTR_TO_MAP ||
type_may_be_null(reg->type)) {
verbose(env, "pointer in %s isn't map pointer\n",
@@ -13203,7 +13128,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (ret < 0)
return ret;
break;
- case KF_ARG_PTR_TO_BTF_ID:
+ case ARG_PTR_TO_BTF_ID:
/* Only base_type is checked, further checks are done here */
if (base_type(reg->type) == PTR_TO_BTF_ID ||
reg2btf_ids[base_type(reg->type)]) {
@@ -13268,10 +13193,10 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
* If the register does not contain btf id but the argument type is a pointer to
* scalar-only struct, allow verifying it as a fixed size memory.
*/
- kf_arg_type = KF_ARG_PTR_TO_MEM | MEM_FIXED_SIZE;
+ arg_type = ARG_PTR_TO_MEM | MEM_FIXED_SIZE;
fallthrough;
- case KF_ARG_PTR_TO_MEM:
- if (kf_arg_type & MEM_FIXED_SIZE) {
+ case ARG_PTR_TO_MEM:
+ if (arg_type & MEM_FIXED_SIZE) {
bool known_memory;
resolve_ret = btf_resolve_size(btf, ref_t, &type_size);
@@ -13305,7 +13230,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
}
}
break;
- case KF_ARG_CONST_MEM_SIZE:
+ case ARG_CONST_MEM_SIZE:
ret = process_const_arg(env, reg, argno, meta);
if (ret < 0) {
if (ret == -EINVAL)
@@ -13316,7 +13241,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
return ret;
}
fallthrough;
- case KF_ARG_MEM_SIZE:
+ case ARG_MEM_SIZE:
{
struct bpf_reg_state *buff_reg = get_func_arg_reg(caller, regs, i - 1);
struct bpf_reg_state *size_reg = reg;
@@ -13369,14 +13294,14 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
}
break;
}
- case KF_ARG_PTR_TO_CALLBACK:
+ case ARG_PTR_TO_FUNC:
if (reg->type != PTR_TO_FUNC) {
verbose(env, "%s expected pointer to func\n", reg_arg_name(env, argno));
return -EINVAL;
}
meta->subprogno = reg->subprogno;
break;
- case KF_ARG_PTR_TO_REFCOUNTED_KPTR:
+ case ARG_PTR_TO_REFCOUNTED_KPTR:
if (!type_is_ptr_alloc_obj(reg->type)) {
verbose(env, "%s is neither owning or non-owning ref\n",
reg_arg_name(env, argno));
@@ -13405,7 +13330,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
meta->arg_btf = reg->btf;
meta->arg_btf_id = reg->btf_id;
break;
- case KF_ARG_PTR_TO_CONST_STR:
+ case ARG_PTR_TO_CONST_STR:
if (reg->type != PTR_TO_MAP_VALUE) {
verbose(env, "%s doesn't point to a const string\n",
reg_arg_name(env, argno));
@@ -13420,7 +13345,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (ret)
return ret;
break;
- case KF_ARG_PTR_TO_WORKQUEUE:
+ case ARG_PTR_TO_WORKQUEUE:
if (reg->type != PTR_TO_MAP_VALUE) {
verbose(env, "%s doesn't point to a map value\n",
reg_arg_name(env, argno));
@@ -13430,7 +13355,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (ret < 0)
return ret;
break;
- case KF_ARG_PTR_TO_TIMER:
+ case ARG_PTR_TO_TIMER:
if (reg->type != PTR_TO_MAP_VALUE) {
verbose(env, "%s doesn't point to a map value\n",
reg_arg_name(env, argno));
@@ -13440,7 +13365,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (ret < 0)
return ret;
break;
- case KF_ARG_PTR_TO_TASK_WORK:
+ case ARG_PTR_TO_TASK_WORK:
if (reg->type != PTR_TO_MAP_VALUE) {
verbose(env, "%s doesn't point to a map value\n",
reg_arg_name(env, argno));
@@ -13450,7 +13375,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (ret < 0)
return ret;
break;
- case KF_ARG_PTR_TO_IRQ_FLAG:
+ case ARG_PTR_TO_IRQ_FLAG:
if (reg->type != PTR_TO_STACK) {
verbose(env, "%s doesn't point to an irq flag on stack\n",
reg_arg_name(env, argno));
@@ -13465,7 +13390,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
if (ret < 0)
return ret;
break;
- case KF_ARG_PTR_TO_RES_SPIN_LOCK:
+ case ARG_PTR_TO_RES_SPIN_LOCK:
{
int flags = PROCESS_RES_LOCK;
--
2.52.0
next prev parent reply other threads:[~2026-09-05 22:01 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-05 22:00 [PATCH bpf-next v1 00/22] bpf: Unify helper and kfunc argument checks Amery Hung
2026-09-05 22:00 ` [PATCH bpf-next v1 01/22] bpf: Pass call metadata through shared " Amery Hung
2026-09-05 22:00 ` [PATCH bpf-next v1 02/22] bpf: Address check_func_arg() arguments by argno Amery Hung
2026-09-05 22:44 ` bot+bpf-ci
2026-09-09 17:37 ` Amery Hung
2026-09-05 22:00 ` [PATCH bpf-next v1 03/22] bpf: Only compare func_id against BPF_FUNC_* for helper calls Amery Hung
2026-09-05 22:00 ` [PATCH bpf-next v1 04/22] bpf: Only compare func_id against kfunc BTF IDs for kfunc calls Amery Hung
2026-09-05 22:44 ` bot+bpf-ci
2026-09-09 17:47 ` Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 05/22] bpf: Rename ambiguous function argument types Amery Hung
2026-09-05 23:08 ` bot+bpf-ci
2026-09-09 17:54 ` Amery Hung
2026-09-05 22:01 ` Amery Hung [this message]
2026-09-05 23:08 ` [PATCH bpf-next v1 06/22] bpf: Unify kfunc argument kinds with enum bpf_arg_type bot+bpf-ci
2026-09-09 18:04 ` Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 07/22] bpf: Align helper and kfunc ARG_PTR_TO_PROG_AUX handling Amery Hung
2026-09-05 23:08 ` bot+bpf-ci
2026-09-09 18:23 ` Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 08/22] bpf: Classify kfunc arguments the verifier ignores Amery Hung
2026-09-05 22:44 ` bot+bpf-ci
2026-09-09 18:27 ` Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 09/22] bpf: Set OBJ_RELEASE when generating kfunc argument types Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 10/22] bpf: Set MEM_UNINIT and dynptr subtypes when generating kfunc arg types Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 11/22] bpf: Set MEM_RCU when generating kfunc argument types Amery Hung
2026-09-05 22:44 ` bot+bpf-ci
2026-09-09 18:41 ` Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 12/22] bpf: Resolve BTF ID of ARG_PTR_TO_BTF_ID in kfunc bpf_func_proto Amery Hung
2026-09-05 23:08 ` bot+bpf-ci
2026-09-09 20:42 ` Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 13/22] bpf: Resolve ARG_PTR_TO_MEM | MEM_FIXED_SIZE size " Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 14/22] bpf: Consolidate runtime argument type resolution Amery Hung
2026-09-10 21:52 ` Alexei Starovoitov
2026-09-11 21:01 ` Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 15/22] bpf: Consolidate nullable argument validation Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 16/22] bpf: Drop redundant BTF pointer helper write rejection Amery Hung
2026-09-05 23:08 ` bot+bpf-ci
2026-09-09 20:48 ` Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 17/22] bpf: Consolidate helper and kfunc PTR_TO_BTF_ID argument matching Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 18/22] bpf: Admit kfunc argument registers through check_reg_type() Amery Hung
2026-09-05 23:23 ` bot+bpf-ci
2026-09-10 16:18 ` Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 19/22] selftests/bpf: Test kfunc packet memory direct writes Amery Hung
2026-09-05 22:44 ` bot+bpf-ci
2026-09-11 20:46 ` Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 20/22] bpf: Consolidate function call pkt_access validation Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 21/22] bpf: Consolidate release argument validation Amery Hung
2026-09-05 23:08 ` bot+bpf-ci
2026-09-11 20:47 ` Amery Hung
2026-09-05 22:01 ` [PATCH bpf-next v1 22/22] bpf: Check helper and kfunc arguments in one path Amery Hung
2026-09-05 22:33 ` sashiko-bot
2026-09-11 20:59 ` Amery Hung
2026-09-10 21:53 ` Alexei Starovoitov
2026-09-11 20:55 ` Amery Hung
2026-09-12 3:20 ` [PATCH bpf-next v1 00/22] bpf: Unify helper and kfunc argument checks patchwork-bot+netdevbpf
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=20260905220117.922028-7-ameryhung@gmail.com \
--to=ameryhung@gmail.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=kernel-team@meta.com \
--cc=memxor@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox