From 6c89cc4719eebf0ee5fde89113a8d3159e0f31f6 Mon Sep 17 00:00:00 2001 From: Francisco Javier Honduvilla Coto Date: Sun, 21 Apr 2024 15:22:52 +0100 Subject: [PATCH] Fix for verifier error on arm64 See comments for more details. Not sure what commits changed the behaviour but this hack works around this issue. --- src/bpf/profiler.bpf.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/bpf/profiler.bpf.c b/src/bpf/profiler.bpf.c index a7be1e3..f418fc1 100644 --- a/src/bpf/profiler.bpf.c +++ b/src/bpf/profiler.bpf.c @@ -71,6 +71,23 @@ struct { } rate_limits SEC(".maps"); +// On arm64 running 6.8.4-200.fc39.aarch64 the verifier fails with argument list too long. This +// did not use to happen before and it's probably due to a regression in the way the verifier +// accounts for the explored paths. I have tried many other things, such as two mid variables +// but that did not do it. The theory of why this works is that perhaps it's making the verifier +// reset the state it had about the program exploration so the branches its exploring per iteration +// do not grow as much. +#ifdef __TARGET_ARCH_arm64 +static u32 __attribute__((optnone)) verifier_workaround(u32 value) { + return value; +} +#endif +#ifdef __TARGET_ARCH_x86 +static __always_inline u32 verifier_workaround(u32 value) { + return value; +} +#endif + // Binary search the unwind table to find the row index containing the unwind // information for a given program counter (pc) relative to the object file. static __always_inline u64 find_offset_for_pc(stack_unwind_table_t *table, u64 pc, u64 left, @@ -85,8 +102,7 @@ static __always_inline u64 find_offset_for_pc(stack_unwind_table_t *table, u64 p return found; } - u32 mid = (left + right) / 2; - + u32 mid = verifier_workaround((left + right) / 2); // Appease the verifier. if (mid < 0 || mid >= MAX_UNWIND_TABLE_SIZE) { LOG("\t.should never happen, mid: %lu, max: %lu", mid,