bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: John Fastabend <john.fastabend@gmail.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>, davem@davemloft.net
Cc: daniel@iogearbox.net, john.fastabend@gmail.com,
	netdev@vger.kernel.org, bpf@vger.kernel.org, kernel-team@fb.com
Subject: RE: [PATCH v2 bpf-next 1/4] bpf: Propagate scalar ranges through register assignments.
Date: Fri, 09 Oct 2020 12:42:00 -0700	[thread overview]
Message-ID: <5f80bd081008f_ed742083e@john-XPS-13-9370.notmuch> (raw)
In-Reply-To: <20201009011240.48506-2-alexei.starovoitov@gmail.com>

Alexei Starovoitov wrote:
> From: Alexei Starovoitov <ast@kernel.org>
> 
> The llvm register allocator may use two different registers representing the
> same virtual register. In such case the following pattern can be observed:
> 1047: (bf) r9 = r6
> 1048: (a5) if r6 < 0x1000 goto pc+1
> 1050: ...
> 1051: (a5) if r9 < 0x2 goto pc+66
> 1052: ...
> 1053: (bf) r2 = r9 /* r2 needs to have upper and lower bounds */
> 
> This is normal behavior of greedy register allocator.
> The slides 137+ explain why regalloc introduces such register copy:
> http://llvm.org/devmtg/2018-04/slides/Yatsina-LLVM%20Greedy%20Register%20Allocator.pdf
> There is no way to tell llvm 'not to do this'.
> Hence the verifier has to recognize such patterns.
> 
> In order to track this information without backtracking allocate ID
> for scalars in a similar way as it's done for find_good_pkt_pointers().
> 
> When the verifier encounters r9 = r6 assignment it will assign the same ID
> to both registers. Later if either register range is narrowed via conditional
> jump propagate the register state into the other register.
> 
> Clear register ID in adjust_reg_min_max_vals() for any alu instruction. The
> register ID is ignored for scalars in regsafe() and doesn't affect state
> pruning. mark_reg_unknown() clears the ID. It's used to process call, endian
> and other instructions. Hence ID is explicitly cleared only in
> adjust_reg_min_max_vals() and in 32-bit mov.
> 
> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
> Acked-by: Andrii Nakryiko <andrii@kernel.org>
> ---
>  kernel/bpf/verifier.c                         | 50 +++++++++++++++++++
>  .../testing/selftests/bpf/prog_tests/align.c  | 16 +++---
>  .../bpf/verifier/direct_packet_access.c       |  2 +-
>  3 files changed, 59 insertions(+), 9 deletions(-)
> 

I also walked through the stack read case and I don't see any issues
there either. We will run check_mem_access on the ld with src_reg->type set
to PTR_TO_STACK. So we run through check_stack_read() with a value_regno
set to the dst_reg (>=0). The case I was thinking of was if we had a
size != BPF_REG_SIZE. But, this case is handled by marking the dst reg
unknown and never copying over the stack[spi]. If size == BPF_REG_SIZE
its a full read and we also ensure all stype[] are STACK_SPILL. Then
everything looks safe to do state->regs[value_reno] = *reg e.g. assign
register state from stack complete with reg.id. 

Looking the other way at stack writes. We only allow SCALAR type bounds to
be saved on the stack if they are constant and size = BPF_REG_SIZE so no
problems there.

LGTM!

Acked-by: John Fastabend <john.fastabend@gmail.com>

  reply	other threads:[~2020-10-09 19:42 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-09  1:12 [PATCH v2 bpf-next 0/4] bpf: Make the verifier recognize llvm register allocation patterns Alexei Starovoitov
2020-10-09  1:12 ` [PATCH v2 bpf-next 1/4] bpf: Propagate scalar ranges through register assignments Alexei Starovoitov
2020-10-09 19:42   ` John Fastabend [this message]
2020-10-09  1:12 ` [PATCH v2 bpf-next 2/4] bpf: Track spill/fill of bounded scalars Alexei Starovoitov
2020-10-09 19:49   ` John Fastabend
2020-10-09  1:12 ` [PATCH v2 bpf-next 3/4] selftests/bpf: Add profiler test Alexei Starovoitov
2020-10-09  6:49   ` Yonghong Song
2020-10-09 15:08     ` Alexei Starovoitov
2020-10-09 15:13       ` Yonghong Song
2020-10-13 19:56   ` Jiri Olsa
2020-10-13 21:03     ` Alexei Starovoitov
2020-10-13 21:56       ` Andrii Nakryiko
2020-10-15  6:09         ` Song Liu
2020-11-04 16:45           ` Jiri Olsa
2020-11-04 20:50             ` Andrii Nakryiko
2020-11-04 21:57               ` Jiri Olsa
2020-10-13 21:59       ` Jiri Olsa
2020-10-14  0:21     ` Song Liu
2020-10-09  1:12 ` [PATCH v2 bpf-next 4/4] selftests/bpf: Asm tests for the verifier regalloc tracking Alexei Starovoitov
2020-10-09 20:06   ` John Fastabend
2020-10-09 20:10 ` [PATCH v2 bpf-next 0/4] bpf: Make the verifier recognize llvm register allocation patterns 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=5f80bd081008f_ed742083e@john-XPS-13-9370.notmuch \
    --to=john.fastabend@gmail.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=kernel-team@fb.com \
    --cc=netdev@vger.kernel.org \
    /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 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).