netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] bpf, x64: bump the number of passes to 64
@ 2020-12-03  9:12 Gary Lin
  2020-12-03 11:20 ` Eric Dumazet
  0 siblings, 1 reply; 5+ messages in thread
From: Gary Lin @ 2020-12-03  9:12 UTC (permalink / raw)
  To: netdev, bpf; +Cc: Alexei Starovoitov, Daniel Borkmann, andreas.taschner

The x64 bpf jit expects bpf images converge within the given passes, but
it could fail to do so with some corner cases. For example:

      l0:     ldh [4]
      l1:     jeq #0x537d, l2, l40
      l2:     ld [0]
      l3:     jeq #0xfa163e0d, l4, l40
      l4:     ldh [12]
      l5:     ldx #0xe
      l6:     jeq #0x86dd, l41, l7
      l8:     ld [x+16]
      l9:     ja 41

        [... repeated ja 41 ]

      l40:    ja 41
      l41:    ret #0
      l42:    ld #len
      l43:    ret a

This bpf program contains 32 "ja 41" instructions which are effectively
NOPs and designed to be replaced with valid code dynamically. Ideally,
bpf jit should optimize those "ja 41" instructions out when translating
the bpf instructions into x86_64 machine code. However, do_jit() can
only remove one "ja 41" for offset==0 on each pass, so it requires at
least 32 runs to eliminate those JMPs and exceeds the current limit of
passes (20). In the end, the program got rejected when BPF_JIT_ALWAYS_ON
is set even though it's legit as a classic socket filter.

Since this kind of programs are usually handcrafted rather than
generated by LLVM, those programs tend to be small. To avoid increasing
the complexity of BPF JIT, this commit just bumps the number of passes
to 64 as suggested by Daniel to make it less likely to fail on such cases.

Signed-off-by: Gary Lin <glin@suse.com>
---
 arch/x86/net/bpf_jit_comp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 796506dcfc42..43cc80387548 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -2042,7 +2042,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
 	 * may converge on the last pass. In such case do one more
 	 * pass to emit the final image.
 	 */
-	for (pass = 0; pass < 20 || image; pass++) {
+	for (pass = 0; pass < 64 || image; pass++) {
 		proglen = do_jit(prog, addrs, image, oldproglen, &ctx);
 		if (proglen <= 0) {
 out_image:
-- 
2.28.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-12-04 10:16 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-12-03  9:12 [PATCH] bpf, x64: bump the number of passes to 64 Gary Lin
2020-12-03 11:20 ` Eric Dumazet
2020-12-03 18:14   ` Alexei Starovoitov
2020-12-04  3:42     ` Gary Lin
2020-12-04 10:15       ` Gary Lin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).