From: Anton Protopopov <a.s.protopopov@gmail.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: bpf <bpf@vger.kernel.org>, Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Anton Protopopov <aspsk@isovalent.com>,
Daniel Borkmann <daniel@iogearbox.net>,
Eduard Zingerman <eddyz87@gmail.com>,
Quentin Monnet <qmo@kernel.org>,
Yonghong Song <yonghong.song@linux.dev>
Subject: Re: [RFC bpf-next 8/9] libbpf: support llvm-generated indirect jumps
Date: Wed, 18 Jun 2025 15:08:24 +0000 [thread overview]
Message-ID: <aFLWaNSsV7M2gV98@mail.gmail.com> (raw)
In-Reply-To: <CAADnVQKhVyh4WqjUgxYLZwn5VMY6hSMWyLoQPxt4TJG1812DcA@mail.gmail.com>
On 25/06/17 08:22PM, Alexei Starovoitov wrote:
> On Sun, Jun 15, 2025 at 1:55 AM Anton Protopopov
> <a.s.protopopov@gmail.com> wrote:
> >
> > The final line generates an indirect jump. The
> > format of the indirect jump instruction supported by BPF is
> >
> > BPF_JMP|BPF_X|BPF_JA, SRC=0, DST=Rx, off=0, imm=fd(M)
> >
> > and, obviously, the map M must be the same map which was used to
> > init the register rX. This patch implements this in the following,
> > hacky, but so far suitable for all existing use-cases, way. On
> > encountering a `gotox` instruction libbpf tracks back to the
> > previous direct load from map and stores this map file descriptor
> > in the gotox instruction.
>
> ...
>
> > +/*
> > + * This one is too dumb, of course. TBD to make it smarter.
> > + */
> > +static int find_jt_map_fd(struct bpf_program *prog, int insn_idx)
> > +{
> > + struct bpf_insn *insn = &prog->insns[insn_idx];
> > + __u8 dst_reg = insn->dst_reg;
> > +
> > + /* TBD: this function is such smart for now that it even ignores this
> > + * register. Instead, it should backtrack the load more carefully.
> > + * (So far even this dumb version works with all selftests.)
> > + */
> > + pr_debug("searching for a load instruction which populated dst_reg=r%u\n", dst_reg);
> > +
> > + while (--insn >= prog->insns) {
> > + if (insn->code == (BPF_LD|BPF_DW|BPF_IMM))
> > + return insn[0].imm;
> > + }
> > +
> > + return -ENOENT;
> > +}
> > +
> > +static int bpf_object__patch_gotox(struct bpf_object *obj, struct bpf_program *prog)
> > +{
> > + struct bpf_insn *insn = prog->insns;
> > + int map_fd;
> > + int i;
> > +
> > + for (i = 0; i < prog->insns_cnt; i++, insn++) {
> > + if (!insn_is_gotox(insn))
> > + continue;
> > +
> > + if (obj->gen_loader)
> > + return -EFAULT;
> > +
> > + map_fd = find_jt_map_fd(prog, i);
> > + if (map_fd < 0)
> > + return map_fd;
> > +
> > + insn->imm = map_fd;
> > + }
>
> This is obviously broken and cannot be made smarter in libbpf.
> It won't be doing data flow analysis.
>
> The only option I see is to teach llvm to tag jmp_table in gotox.
> Probably the simplest way is to add the same relo to gotox insn
> as for ld_imm64. Then libbpf has a direct way to assign
> the same map_fd into both ld_imm64 and gotox.
This would be nice.
> Uglier alternatives is to redesign the gotox encoding and
> drop ld_imm64 and *=8 altogether.
> Then gotox jmp_table[R5] will be like jumbo insn that
> does *=8 and load inside and JIT emits all that.
> But it's ugly and likely has other downsides.
I did this in my initial draft for LLVM (and supporting different
kind of instructions was done using bits in SRC). But the "native"
approach looks better for me now, especially if compiles can be
taught to link load&gotox.
next prev parent reply other threads:[~2025-06-18 15:02 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-15 8:59 [RFC bpf-next 0/9] BPF indirect jumps Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 1/9] bpf: save the start of functions in bpf_prog_aux Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 2/9] bpf, x86: add new map type: instructions set Anton Protopopov
2025-06-18 0:57 ` Eduard Zingerman
2025-06-18 2:16 ` Alexei Starovoitov
2025-06-19 18:57 ` Anton Protopopov
2025-06-19 18:55 ` Anton Protopopov
2025-06-19 18:55 ` Eduard Zingerman
2025-06-15 8:59 ` [RFC bpf-next 3/9] selftests/bpf: add selftests for new insn_set map Anton Protopopov
2025-06-18 11:04 ` Eduard Zingerman
2025-06-18 15:16 ` Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 4/9] bpf, x86: allow indirect jumps to r8...r15 Anton Protopopov
2025-06-17 19:41 ` Alexei Starovoitov
2025-06-18 14:28 ` Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 5/9] bpf, x86: add support for indirect jumps Anton Protopopov
2025-06-18 3:06 ` Alexei Starovoitov
2025-06-19 19:57 ` Anton Protopopov
2025-06-19 19:58 ` Anton Protopopov
2025-06-18 11:03 ` Eduard Zingerman
2025-06-19 20:13 ` Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 6/9] bpf: workaround llvm behaviour with " Anton Protopopov
2025-06-18 11:04 ` Eduard Zingerman
2025-06-18 13:59 ` Alexei Starovoitov
2025-06-15 8:59 ` [RFC bpf-next 7/9] bpf: disasm: add support for BPF_JMP|BPF_JA|BPF_X Anton Protopopov
2025-06-15 8:59 ` [RFC bpf-next 8/9] libbpf: support llvm-generated indirect jumps Anton Protopopov
2025-06-18 3:22 ` Alexei Starovoitov
2025-06-18 15:08 ` Anton Protopopov [this message]
2025-07-07 23:45 ` Eduard Zingerman
2025-07-07 23:49 ` Alexei Starovoitov
2025-07-08 0:01 ` Eduard Zingerman
2025-07-08 0:12 ` Alexei Starovoitov
2025-07-08 0:18 ` Eduard Zingerman
2025-07-08 0:49 ` Alexei Starovoitov
2025-07-08 0:51 ` Eduard Zingerman
2025-07-08 20:59 ` Eduard Zingerman
2025-07-08 21:25 ` Alexei Starovoitov
2025-07-08 21:29 ` Eduard Zingerman
2025-07-09 5:33 ` Anton Protopopov
2025-07-09 5:58 ` Eduard Zingerman
2025-07-09 8:38 ` Eduard Zingerman
2025-07-10 5:11 ` Eduard Zingerman
2025-07-10 6:10 ` Anton Protopopov
2025-07-10 6:13 ` Eduard Zingerman
2025-06-18 19:49 ` Eduard Zingerman
2025-06-27 2:28 ` Eduard Zingerman
2025-06-27 10:18 ` Anton Protopopov
2025-07-03 18:21 ` Eduard Zingerman
2025-07-03 19:03 ` Anton Protopopov
2025-07-07 19:07 ` Eduard Zingerman
2025-07-07 19:34 ` Anton Protopopov
2025-07-07 21:44 ` Yonghong Song
2025-07-08 5:58 ` Yonghong Song
2025-07-08 8:30 ` Eduard Zingerman
2025-07-08 10:42 ` Eduard Zingerman
2025-06-15 8:59 ` [RFC bpf-next 9/9] selftests/bpf: add selftests for " Anton Protopopov
2025-06-18 3:24 ` Alexei Starovoitov
2025-06-18 14:49 ` Anton Protopopov
2025-06-18 16:01 ` Alexei Starovoitov
2025-06-18 16:36 ` Anton Protopopov
2025-06-18 16:43 ` Alexei Starovoitov
2025-06-18 20:25 ` Anton Protopopov
2025-06-18 21:59 ` Alexei Starovoitov
2025-06-19 5:05 ` Anton Protopopov
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=aFLWaNSsV7M2gV98@mail.gmail.com \
--to=a.s.protopopov@gmail.com \
--cc=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=aspsk@isovalent.com \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=qmo@kernel.org \
--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.