From: Alexei Starovoitov The loop keeps its counter in fp-8. In each iteration it calls bpf_probe_read_kernel() to read from the address of fp-16. This argument is ARG_ANYTHING. The verifier assumed that the helper can write through it, and thus can change the counter. The test expects that scalar evolution calculates the number of iterations: loop header at 2, header_count is 10 Signed-off-by: Alexei Starovoitov --- .../selftests/bpf/progs/verifier_scev.c | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/verifier_scev.c b/tools/testing/selftests/bpf/progs/verifier_scev.c index c242724686fc..bd632951492a 100644 --- a/tools/testing/selftests/bpf/progs/verifier_scev.c +++ b/tools/testing/selftests/bpf/progs/verifier_scev.c @@ -1434,6 +1434,37 @@ __naked void bound_from_rodata(void) : __clobber_all); } +/* + * The address of a stack slot is passed as a number. The helper may read what is + * there. It doesn't write, so the counter in the slot next to it is intact. + */ +SEC("tracepoint") +__success +__log_level(2) +__msg("loop header at 2, header_count is 10") +__naked void stack_address_as_a_number(void) +{ + asm volatile ( + "*(u64 *)(r10 - 8) = 0;" + "*(u64 *)(r10 - 16) = 0;" +"1:" + "r1 = r10;" + "r1 += -24;" + "r2 = 8;" + "r3 = r10;" + "r3 += -16;" + "call %[bpf_probe_read_kernel];" + "r1 = *(u64 *)(r10 - 8);" + "r1 += 1;" + "*(u64 *)(r10 - 8) = r1;" + "if r1 < 10 goto 1b;" + "r0 = 0;" + "exit;" + : + : __imm(bpf_probe_read_kernel) + : __clobber_all); +} + /* The unknown SCEV of an unbound STACK_MISC slot must not prevent widening. */ SEC("tracepoint") __success -- 2.55.0