Re: [PATCH bpf-next v3 4/5] bpf, x86: Add jit support for private stack

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 30 Sept 2024 at 17:03, Alexei Starovoitov
<alexei.starovoitov@xxxxxxxxx> wrote:
>
> On Thu, Sep 26, 2024 at 4:45 PM Yonghong Song <yonghong.song@xxxxxxxxx> wrote:
> >
> > Add jit support for private stack. For a particular subtree, e.g.,
> >   subtree_root <== stack depth 120
> >    subprog1    <== stack depth 80
> >     subprog2   <== stack depth 40
> >    subprog3    <== stack depth 160
> >
> > Let us say that private_stack_ptr is the memory address allocated for
> > private stack. The frame pointer for each above is calculated like below:
> >   subtree_root  <== subtree_root_fp = private_stack_ptr + 120
> >    subprog1     <== subtree_subprog1_fp = subtree_root_fp + 80
> >     subprog2    <== subtree_subprog2_fp = subtree_subprog1_fp + 40
> >    subprog3     <== subtree_subprog1_fp = subtree_root_fp + 160
> >
> > For any function call to helper/kfunc, push/pop prog frame pointer
> > is needed in order to preserve frame pointer value.
> >
> > To deal with exception handling, push/pop frame pointer is also used
> > surrounding call to subsequent subprog. For example,
> >   subtree_root
> >    subprog1
> >      ...
> >      insn: call bpf_throw
> >      ...
> >
> > After jit, we will have
> >   subtree_root
> >    insn: push r9
> >    subprog1
> >      ...
> >      insn: push r9
> >      insn: call bpf_throw
> >      insn: pop r9
> >      ...
> >    insn: pop r9
> >
> >   exception_handler
> >      pop r9
> >      ...
> > where r9 represents the fp for each subprog.
>
> Kumar,
> please review the interaction of priv_stack with exceptions.
>

Hm, I think it works fine (because of push_r9 around subprog calls),
but I think it's not needed (unless I missed something).

The kernel won't care about r9's value, so the only reason pop_r9 is
being done in ex_handler is to restore the private stack value?
In that case you can just push_r9 once for
prog->aux->exception_boundary after emit_private_frame_ptr, since only
this main subprog's stack will be reused to run the exception
callback. Then keep the pop_r9 as is. And then you don't need to
push_r9 and pop_r9 around subprog calls.

But do you need to do it? It seems later on it will just be overwritten.
Since exception_cb is a PSTACK_TREE_ROOT, you will set its r9 using mov.

So it seems all of this may be unnecessary.

Let me know if I misunderstood something.

...

Another issue that I came across when reading through patches is how
this interacts with extension progs.
Say right now I have this call chain:

main_subprog
  global_subprog (overriden by ext prog)
    subprog1
      call helper
  subprog2

global_subprog (which is a separate ext prog attached there using
freplace) is not using private stack, but main prog is.
So when main_subprog calls into it, it is possible r9 gets overwritten
since JIT didn't preserve it for helper calls from the ext prog.

When subprog2 is called, this will mean r9 equals garbage?

There was a vaguely similar decision to make for exceptions: if we
keep unwinding beyond an extension prog frame, we might end up in the
main subprog frame that did not push the necessary registers to
restore kernel state from exception_cb (because it did not have
bpf_throw during verification). So I ended up making the ext prog
itself an exception boundary, so unwinding stops there and it would
return a result to its caller prog which may or may not use
exceptions.

In my case, I cannot go and re-JIT old progs to make them exception
aware (short of always pushing r12 and all callee regs).
But in your case the changes would be contained to ext_prog, so you
could just figure that out from the tgt_prog seen in
bpf_check_attach_target (i.e. whether it is using priv_stack or not,
and if so, extra JIT instrumentation to reuse and push/pop r9 around
helper calls is necessary for this ext_prog).

> >
> > [...]





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux