From: Martin KaFai Lau <martin.lau@linux.dev>
To: Eduard Zingerman <eddyz87@gmail.com>, bpf@vger.kernel.org
Cc: Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>,
Yonghong Song <yonghong.song@linux.dev>,
Amery Hung <ameryhung@gmail.com>,
kernel-team@meta.com
Subject: Re: [RFC PATCH bpf-next 1/6] bpf: Add gen_epilogue to bpf_verifier_ops
Date: Thu, 15 Aug 2024 15:14:10 -0700 [thread overview]
Message-ID: <a912370d-0812-48ee-aaf5-8dbeddc8fefa@linux.dev> (raw)
In-Reply-To: <19903da56fbfb99e4ad6fdea646aaff885e9fd4d.camel@gmail.com>
On 8/14/24 1:56 PM, Eduard Zingerman wrote:
> On Tue, 2024-08-13 at 11:49 -0700, Martin KaFai Lau wrote:
>> From: Martin KaFai Lau <martin.lau@kernel.org>
>>
>> This patch adds a .gen_epilogue to the bpf_verifier_ops. It is similar
>> to the existing .gen_prologue. Instead of allowing a subsystem
>> to run code at the beginning of a bpf prog, it allows the subsystem
>> to run code just before the bpf prog exit.
>>
>> One of the use case is to allow the upcoming bpf qdisc to ensure that
>> the skb->dev is the same as the qdisc->dev_queue->dev. The bpf qdisc
>> struct_ops implementation could either fix it up or drop the skb.
>> Another use case could be in bpf_tcp_ca.c to enforce snd_cwnd
>> has sane value (e.g. non zero).
>>
>> The epilogue can do the useful thing (like checking skb->dev) if it
>> can access the bpf prog's ctx. Unlike prologue, r1 may not hold the
>> ctx pointer. This patch saves the r1 in the stack if the .gen_epilogue
>> has returned some instructions in the "epilogue_buf".
>>
>> The existing .gen_prologue is done in convert_ctx_accesses().
>> The new .gen_epilogue is done in the convert_ctx_accesses() also.
>> When it sees the (BPF_JMP | BPF_EXIT) instruction, it will be patched
>> with the earlier generated "epilogue_buf". The epilogue patching is
>> only done for the main prog.
>>
>> Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
>> ---
>
> Apart from the note below I don't see any obvious problems with this code.
>
> Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
>
> [...]
>
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -19610,15 +19610,37 @@ static int opt_subreg_zext_lo32_rnd_hi32(struct bpf_verifier_env *env,
>> */
>> static int convert_ctx_accesses(struct bpf_verifier_env *env)
>> {
>> + struct bpf_subprog_info *subprogs = env->subprog_info;
>> const struct bpf_verifier_ops *ops = env->ops;
>> - int i, cnt, size, ctx_field_size, delta = 0;
>> + int i, cnt, size, ctx_field_size, delta = 0, epilogue_cnt = 0;
>> const int insn_cnt = env->prog->len;
>> - struct bpf_insn insn_buf[16], *insn;
>> + struct bpf_insn insn_buf[16], epilogue_buf[16], *insn;
>> u32 target_size, size_default, off;
>> struct bpf_prog *new_prog;
>> enum bpf_access_type type;
>> bool is_narrower_load;
>>
>> + if (ops->gen_epilogue) {
>> + epilogue_cnt = ops->gen_epilogue(epilogue_buf, env->prog,
>> + -(subprogs[0].stack_depth + 8));
>> + if (epilogue_cnt >= ARRAY_SIZE(epilogue_buf)) {
>> + verbose(env, "bpf verifier is misconfigured\n");
>> + return -EINVAL;
>> + } else if (epilogue_cnt) {
>> + /* Save the ARG_PTR_TO_CTX for the epilogue to use */
>> + cnt = 0;
>> + subprogs[0].stack_depth += 8;
>
> Note: two other places that allocate additional stack
> (optimize_bpf_loop(), do_misc_fixups())
> also bump 'env->prog->aux->stack_depth'.
Thanks for pointing it out.
In this case, I will stay with calling .gen_epilogue in convert_ctx_accesses().
>
>> + insn_buf[cnt++] = BPF_STX_MEM(BPF_DW, BPF_REG_FP, BPF_REG_1,
>> + -subprogs[0].stack_depth);
>> + insn_buf[cnt++] = env->prog->insnsi[0];
>> + new_prog = bpf_patch_insn_data(env, 0, insn_buf, cnt);
>> + if (!new_prog)
>> + return -ENOMEM;
>> + env->prog = new_prog;
>> + delta += cnt - 1;
>> + }
>> + }
>> +
>
> [...]
>
next prev parent reply other threads:[~2024-08-15 22:14 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-13 18:49 [RFC PATCH bpf-next 0/6] bpf: Add gen_epilogue and allow kfunc call in pro/epilogue Martin KaFai Lau
2024-08-13 18:49 ` [RFC PATCH bpf-next 1/6] bpf: Add gen_epilogue to bpf_verifier_ops Martin KaFai Lau
2024-08-14 20:56 ` Eduard Zingerman
2024-08-15 22:14 ` Martin KaFai Lau [this message]
2024-08-17 22:25 ` Amery Hung
2024-08-13 18:49 ` [RFC PATCH bpf-next 2/6] bpf: Export bpf_base_func_proto Martin KaFai Lau
2024-08-13 18:49 ` [RFC PATCH bpf-next 3/6] selftests/test: test gen_prologue and gen_epilogue Martin KaFai Lau
2024-08-14 20:48 ` Eduard Zingerman
2024-08-15 23:41 ` Martin KaFai Lau
2024-08-16 0:23 ` Eduard Zingerman
2024-08-16 1:50 ` Eduard Zingerman
2024-08-16 17:27 ` Martin KaFai Lau
2024-08-16 20:27 ` Eduard Zingerman
2024-08-19 22:30 ` Martin KaFai Lau
2024-08-13 18:49 ` [RFC PATCH bpf-next 4/6] bpf: Add module parameter to " Martin KaFai Lau
2024-08-13 18:49 ` [RFC PATCH bpf-next 5/6] bpf: Allow pro/epilogue to call kfunc Martin KaFai Lau
2024-08-14 22:17 ` Eduard Zingerman
2024-08-15 23:47 ` Martin KaFai Lau
2024-08-13 18:49 ` [RFC PATCH bpf-next 6/6] selftests/bpf: Add kfunc call test in gen_prologue and gen_epilogue Martin KaFai Lau
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=a912370d-0812-48ee-aaf5-8dbeddc8fefa@linux.dev \
--to=martin.lau@linux.dev \
--cc=ameryhung@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=kernel-team@meta.com \
--cc=yonghong.song@linux.dev \
/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.