Skip to content

Commit

Permalink
selftests/bpf: Fix trace_virtqueue_add_sgs test issue with LLVM 17.
Browse files Browse the repository at this point in the history
LLVM commit https://reviews.llvm.org/D143726 introduced hoistMinMax optimization
that transformed
  (i < VIRTIO_MAX_SGS) && (i < out_sgs)
into
  i < MIN(VIRTIO_MAX_SGS, out_sgs)

and caused the verifier to stop recognizing such loop as bounded.

Which resulted in the following test failure:

libbpf: prog 'trace_virtqueue_add_sgs': BPF program load failed: Bad address
libbpf: prog 'trace_virtqueue_add_sgs': -- BEGIN PROG LOAD LOG --
The sequence of 8193 jumps is too complex.
verification time 789206 usec
stack depth 56
processed 156446 insns (limit 1000000) max_states_per_insn 7 total_states 1746 peak_states 1701 mark_read 12
-- END PROG LOAD LOG --
libbpf: prog 'trace_virtqueue_add_sgs': failed to load: -14
libbpf: failed to load object 'loop6.bpf.o'

Workaround the verifier limitation for now with inline asm that
prevents this particular optimization.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
  • Loading branch information
Alexei Starovoitov committed Mar 14, 2023
1 parent 5584d9e commit 3c2611b
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions tools/testing/selftests/bpf/progs/loop6.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include "bpf_misc.h"

char _license[] SEC("license") = "GPL";

Expand Down Expand Up @@ -76,6 +77,7 @@ int BPF_KPROBE(trace_virtqueue_add_sgs, void *unused, struct scatterlist **sgs,
return 0;

for (i = 0; (i < VIRTIO_MAX_SGS) && (i < out_sgs); i++) {
__sink(out_sgs);
for (n = 0, sgp = get_sgp(sgs, i); sgp && (n < SG_MAX);
sgp = __sg_next(sgp)) {
bpf_probe_read_kernel(&len, sizeof(len), &sgp->length);
Expand All @@ -85,6 +87,7 @@ int BPF_KPROBE(trace_virtqueue_add_sgs, void *unused, struct scatterlist **sgs,
}

for (i = 0; (i < VIRTIO_MAX_SGS) && (i < in_sgs); i++) {
__sink(in_sgs);
for (n = 0, sgp = get_sgp(sgs, i); sgp && (n < SG_MAX);
sgp = __sg_next(sgp)) {
bpf_probe_read_kernel(&len, sizeof(len), &sgp->length);
Expand Down

0 comments on commit 3c2611b

Please sign in to comment.