All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Olsa <olsajiri@gmail.com>
To: thinker.li@gmail.com
Cc: bpf@vger.kernel.org, ast@kernel.org, martin.lau@linux.dev,
	song@kernel.org, kernel-team@meta.com, andrii@kernel.org,
	davemarchevsky@meta.com, dvernet@meta.com, sinquersw@gmail.com,
	kuifeng@meta.com
Subject: Re: [PATCH bpf-next v8 3/4] bpf: Create argument information for nullable arguments.
Date: Mon, 12 Feb 2024 12:45:19 +0100	[thread overview]
Message-ID: <ZcoEzyRzxLUWWhw4@krava> (raw)
In-Reply-To: <20240209023750.1153905-4-thinker.li@gmail.com>

On Thu, Feb 08, 2024 at 06:37:49PM -0800, thinker.li@gmail.com wrote:

SNIP

>  enum bpf_struct_ops_state {
> @@ -1790,6 +1806,7 @@ int bpf_struct_ops_desc_init(struct bpf_struct_ops_desc *st_ops_desc,
>  			     struct btf *btf,
>  			     struct bpf_verifier_log *log);
>  void bpf_map_struct_ops_info_fill(struct bpf_map_info *info, struct bpf_map *map);
> +void bpf_struct_ops_desc_release(struct bpf_struct_ops_desc *st_ops_desc);
>  #else
>  #define register_bpf_struct_ops(st_ops, type) ({ (void *)(st_ops); 0; })
>  static inline bool bpf_try_module_get(const void *data, struct module *owner)
> @@ -1814,6 +1831,10 @@ static inline void bpf_map_struct_ops_info_fill(struct bpf_map_info *info, struc
>  {
>  }
>  
> +static inline void bpf_struct_ops_desc_release(struct bpf_struct_ops_desc *st_ops_desc, int len)
> +{
> +}

extra len argument?

jirka


SNIP

> +/* Clean up the arg_info in a struct bpf_struct_ops_desc. */
> +void bpf_struct_ops_desc_release(struct bpf_struct_ops_desc *st_ops_desc)
> +{
> +	struct bpf_struct_ops_arg_info *arg_info;
> +	int i;
> +
> +	arg_info = st_ops_desc->arg_info;
> +	if (!arg_info)
> +		return;
> +
> +	for (i = 0; i < btf_type_vlen(st_ops_desc->type); i++)
> +		kfree(arg_info[i].info);
> +
> +	kfree(arg_info);
> +}
> +
>  int bpf_struct_ops_desc_init(struct bpf_struct_ops_desc *st_ops_desc,
>  			     struct btf *btf,
>  			     struct bpf_verifier_log *log)
>  {
>  	struct bpf_struct_ops *st_ops = st_ops_desc->st_ops;
> +	struct bpf_struct_ops_arg_info *arg_info;
>  	const struct btf_member *member;
>  	const struct btf_type *t;
>  	s32 type_id, value_id;
>  	char value_name[128];
>  	const char *mname;
> -	int i;
> +	int i, err;
>  
>  	if (strlen(st_ops->name) + VALUE_PREFIX_LEN >=
>  	    sizeof(value_name)) {
> @@ -160,6 +320,17 @@ int bpf_struct_ops_desc_init(struct bpf_struct_ops_desc *st_ops_desc,
>  	if (!is_valid_value_type(btf, value_id, t, value_name))
>  		return -EINVAL;
>  
> +	arg_info = kcalloc(btf_type_vlen(t), sizeof(*arg_info),
> +			   GFP_KERNEL);
> +	if (!arg_info)
> +		return -ENOMEM;
> +
> +	st_ops_desc->arg_info = arg_info;
> +	st_ops_desc->type = t;
> +	st_ops_desc->type_id = type_id;
> +	st_ops_desc->value_id = value_id;
> +	st_ops_desc->value_type = btf_type_by_id(btf, value_id);
> +
>  	for_each_member(i, t, member) {
>  		const struct btf_type *func_proto;
>  
> @@ -167,40 +338,52 @@ int bpf_struct_ops_desc_init(struct bpf_struct_ops_desc *st_ops_desc,
>  		if (!*mname) {
>  			pr_warn("anon member in struct %s is not supported\n",
>  				st_ops->name);
> -			return -EOPNOTSUPP;
> +			err = -EOPNOTSUPP;
> +			goto errout;
>  		}
>  
>  		if (__btf_member_bitfield_size(t, member)) {
>  			pr_warn("bit field member %s in struct %s is not supported\n",
>  				mname, st_ops->name);
> -			return -EOPNOTSUPP;
> +			err = -EOPNOTSUPP;
> +			goto errout;
>  		}
>  
>  		func_proto = btf_type_resolve_func_ptr(btf,
>  						       member->type,
>  						       NULL);
> -		if (func_proto &&
> -		    btf_distill_func_proto(log, btf,
> +		if (!func_proto)
> +			continue;
> +
> +		if (btf_distill_func_proto(log, btf,
>  					   func_proto, mname,
>  					   &st_ops->func_models[i])) {
>  			pr_warn("Error in parsing func ptr %s in struct %s\n",
>  				mname, st_ops->name);
> -			return -EINVAL;
> +			err = -EINVAL;
> +			goto errout;
>  		}
> +
> +		err = prepare_arg_info(btf, st_ops->name, mname,
> +				       func_proto,
> +				       arg_info + i);
> +		if (err)
> +			goto errout;
>  	}
>  
>  	if (st_ops->init(btf)) {
>  		pr_warn("Error in init bpf_struct_ops %s\n",
>  			st_ops->name);
> -		return -EINVAL;
> +		err = -EINVAL;
> +		goto errout;
>  	}
>  
> -	st_ops_desc->type_id = type_id;
> -	st_ops_desc->type = t;
> -	st_ops_desc->value_id = value_id;
> -	st_ops_desc->value_type = btf_type_by_id(btf, value_id);
> -
>  	return 0;
> +
> +errout:
> +	bpf_struct_ops_desc_release(st_ops_desc);
> +
> +	return err;
>  }
>  
>  static int bpf_struct_ops_map_get_next_key(struct bpf_map *map, void *key,
> diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
> index db53bb76387e..533f02b92c94 100644
> --- a/kernel/bpf/btf.c
> +++ b/kernel/bpf/btf.c
> @@ -1699,6 +1699,13 @@ static void btf_free_struct_meta_tab(struct btf *btf)
>  static void btf_free_struct_ops_tab(struct btf *btf)
>  {
>  	struct btf_struct_ops_tab *tab = btf->struct_ops_tab;
> +	int i;
> +
> +	if (!tab)
> +		return;
> +
> +	for (i = 0; i < tab->cnt; i++)
> +		bpf_struct_ops_desc_release(&tab->ops[i]);
>  
>  	kfree(tab);
>  	btf->struct_ops_tab = NULL;
> @@ -6130,6 +6137,26 @@ static bool prog_args_trusted(const struct bpf_prog *prog)
>  	}
>  }
>  
> +int btf_ctx_arg_offset(struct btf *btf, const struct btf_type *func_proto,
> +		       u32 arg_no)
> +{
> +	const struct btf_param *args;
> +	const struct btf_type *t;
> +	int off = 0, i;
> +	u32 sz;
> +
> +	args = btf_params(func_proto);
> +	for (i = 0; i < arg_no; i++) {
> +		t = btf_type_by_id(btf, args[i].type);
> +		t = btf_resolve_size(btf, t, &sz);
> +		if (IS_ERR(t))
> +			return PTR_ERR(t);
> +		off += roundup(sz, 8);
> +	}
> +
> +	return off;
> +}
> +
>  bool btf_ctx_access(int off, int size, enum bpf_access_type type,
>  		    const struct bpf_prog *prog,
>  		    struct bpf_insn_access_aux *info)
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index c92d6af7d975..72ca27f49616 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -20419,6 +20419,12 @@ static int check_struct_ops_btf_id(struct bpf_verifier_env *env)
>  		}
>  	}
>  
> +	/* btf_ctx_access() used this to provide argument type info */
> +	prog->aux->ctx_arg_info =
> +		st_ops_desc->arg_info[member_idx].info;
> +	prog->aux->ctx_arg_info_size =
> +		st_ops_desc->arg_info[member_idx].cnt;
> +
>  	prog->aux->attach_func_proto = func_proto;
>  	prog->aux->attach_func_name = mname;
>  	env->ops = st_ops->verifier_ops;
> -- 
> 2.34.1
> 
> 

  parent reply	other threads:[~2024-02-12 11:45 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-09  2:37 [PATCH bpf-next v8 0/4] Support PTR_MAYBE_NULL for struct_ops arguments thinker.li
2024-02-09  2:37 ` [PATCH bpf-next v8 1/4] bpf: add btf pointer to struct bpf_ctx_arg_aux thinker.li
2024-02-11 18:59   ` Martin KaFai Lau
2024-02-09  2:37 ` [PATCH bpf-next v8 2/4] bpf: Move __kfunc_param_match_suffix() to btf.c thinker.li
2024-02-09  2:37 ` [PATCH bpf-next v8 3/4] bpf: Create argument information for nullable arguments thinker.li
2024-02-11 19:49   ` Martin KaFai Lau
2024-02-12 17:09     ` Kui-Feng Lee
2024-02-12 11:45   ` Jiri Olsa [this message]
2024-02-12 17:50     ` Kui-Feng Lee
2024-02-13 23:27     ` Martin KaFai Lau
2024-02-09  2:37 ` [PATCH bpf-next v8 4/4] selftests/bpf: Test PTR_MAYBE_NULL arguments of struct_ops operators thinker.li
2024-02-13 23:30 ` [PATCH bpf-next v8 0/4] Support PTR_MAYBE_NULL for struct_ops arguments 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=ZcoEzyRzxLUWWhw4@krava \
    --to=olsajiri@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=davemarchevsky@meta.com \
    --cc=dvernet@meta.com \
    --cc=kernel-team@meta.com \
    --cc=kuifeng@meta.com \
    --cc=martin.lau@linux.dev \
    --cc=sinquersw@gmail.com \
    --cc=song@kernel.org \
    --cc=thinker.li@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.