diff --git a/ci/diffs/0001-selftests-bpf-test-case-for-callback_depth-states-pr.patch b/ci/diffs/0001-selftests-bpf-test-case-for-callback_depth-states-pr.patch new file mode 100644 index 000000000..f9fa87927 --- /dev/null +++ b/ci/diffs/0001-selftests-bpf-test-case-for-callback_depth-states-pr.patch @@ -0,0 +1,129 @@ +From 5c2bc5e2f81d3344095ae241032dde20a4ea2b48 Mon Sep 17 00:00:00 2001 +From: Eduard Zingerman +Date: Thu, 22 Feb 2024 17:41:21 +0200 +Subject: [PATCH 1/2] selftests/bpf: test case for callback_depth states + pruning logic + +The test case was minimized from mailing list discussion [0]. +It is equivalent to the following C program: + + struct iter_limit_bug_ctx { __u64 a; __u64 b; __u64 c; }; + + static __naked void iter_limit_bug_cb(void) + { + switch (bpf_get_prandom_u32()) { + case 1: ctx->a = 42; break; + case 2: ctx->b = 42; break; + default: ctx->c = 42; break; + } + } + + int iter_limit_bug(struct __sk_buff *skb) + { + struct iter_limit_bug_ctx ctx = { 7, 7, 7 }; + + bpf_loop(2, iter_limit_bug_cb, &ctx, 0); + if (ctx.a == 42 && ctx.b == 42 && ctx.c == 7) + asm volatile("r1 /= 0;":::"r1"); + return 0; + } + +The main idea is that each loop iteration changes one of the state +variables in a non-deterministic manner. Hence it is premature to +prune the states that have two iterations left comparing them to +states with one iteration left. +E.g. {{7,7,7}, callback_depth=0} can reach state {42,42,7}, +while {{7,7,7}, callback_depth=1} can't. + +[0] https://lore.kernel.org/bpf/9b251840-7cb8-4d17-bd23-1fc8071d8eef@linux.dev/ + +Acked-by: Yonghong Song +Signed-off-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20240222154121.6991-3-eddyz87@gmail.com +Signed-off-by: Alexei Starovoitov +--- + .../bpf/progs/verifier_iterating_callbacks.c | 70 +++++++++++++++++++ + 1 file changed, 70 insertions(+) + +diff --git a/tools/testing/selftests/bpf/progs/verifier_iterating_callbacks.c b/tools/testing/selftests/bpf/progs/verifier_iterating_callbacks.c +index 5905e036e0ea..a955a6358206 100644 +--- a/tools/testing/selftests/bpf/progs/verifier_iterating_callbacks.c ++++ b/tools/testing/selftests/bpf/progs/verifier_iterating_callbacks.c +@@ -239,4 +239,74 @@ int bpf_loop_iter_limit_nested(void *unused) + return 1000 * a + b + c; + } + ++struct iter_limit_bug_ctx { ++ __u64 a; ++ __u64 b; ++ __u64 c; ++}; ++ ++static __naked void iter_limit_bug_cb(void) ++{ ++ /* This is the same as C code below, but written ++ * in assembly to control which branches are fall-through. ++ * ++ * switch (bpf_get_prandom_u32()) { ++ * case 1: ctx->a = 42; break; ++ * case 2: ctx->b = 42; break; ++ * default: ctx->c = 42; break; ++ * } ++ */ ++ asm volatile ( ++ "r9 = r2;" ++ "call %[bpf_get_prandom_u32];" ++ "r1 = r0;" ++ "r2 = 42;" ++ "r0 = 0;" ++ "if r1 == 0x1 goto 1f;" ++ "if r1 == 0x2 goto 2f;" ++ "*(u64 *)(r9 + 16) = r2;" ++ "exit;" ++ "1: *(u64 *)(r9 + 0) = r2;" ++ "exit;" ++ "2: *(u64 *)(r9 + 8) = r2;" ++ "exit;" ++ : ++ : __imm(bpf_get_prandom_u32) ++ : __clobber_all ++ ); ++} ++ ++SEC("tc") ++__failure ++__flag(BPF_F_TEST_STATE_FREQ) ++int iter_limit_bug(struct __sk_buff *skb) ++{ ++ struct iter_limit_bug_ctx ctx = { 7, 7, 7 }; ++ ++ bpf_loop(2, iter_limit_bug_cb, &ctx, 0); ++ ++ /* This is the same as C code below, ++ * written in assembly to guarantee checks order. ++ * ++ * if (ctx.a == 42 && ctx.b == 42 && ctx.c == 7) ++ * asm volatile("r1 /= 0;":::"r1"); ++ */ ++ asm volatile ( ++ "r1 = *(u64 *)%[ctx_a];" ++ "if r1 != 42 goto 1f;" ++ "r1 = *(u64 *)%[ctx_b];" ++ "if r1 != 42 goto 1f;" ++ "r1 = *(u64 *)%[ctx_c];" ++ "if r1 != 7 goto 1f;" ++ "r1 /= 0;" ++ "1:" ++ : ++ : [ctx_a]"m"(ctx.a), ++ [ctx_b]"m"(ctx.b), ++ [ctx_c]"m"(ctx.c) ++ : "r1" ++ ); ++ return 0; ++} ++ + char _license[] SEC("license") = "GPL"; +-- +2.43.0 + diff --git a/ci/diffs/0002-xdp-bonding-Fix-feature-flags-when-there-are-no-slav.patch b/ci/diffs/0002-xdp-bonding-Fix-feature-flags-when-there-are-no-slav.patch new file mode 100644 index 000000000..672eca711 --- /dev/null +++ b/ci/diffs/0002-xdp-bonding-Fix-feature-flags-when-there-are-no-slav.patch @@ -0,0 +1,56 @@ +From f267f262815033452195f46c43b572159262f533 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Tue, 5 Mar 2024 10:08:28 +0100 +Subject: [PATCH 2/2] xdp, bonding: Fix feature flags when there are no slave + devs anymore +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 9b0ed890ac2a ("bonding: do not report NETDEV_XDP_ACT_XSK_ZEROCOPY") +changed the driver from reporting everything as supported before a device +was bonded into having the driver report that no XDP feature is supported +until a real device is bonded as it seems to be more truthful given +eventually real underlying devices decide what XDP features are supported. + +The change however did not take into account when all slave devices get +removed from the bond device. In this case after 9b0ed890ac2a, the driver +keeps reporting a feature mask of 0x77, that is, NETDEV_XDP_ACT_MASK & +~NETDEV_XDP_ACT_XSK_ZEROCOPY whereas it should have reported a feature +mask of 0. + +Fix it by resetting XDP feature flags in the same way as if no XDP program +is attached to the bond device. This was uncovered by the XDP bond selftest +which let BPF CI fail. After adjusting the starting masks on the latter +to 0 instead of NETDEV_XDP_ACT_MASK the test passes again together with +this fix. + +Fixes: 9b0ed890ac2a ("bonding: do not report NETDEV_XDP_ACT_XSK_ZEROCOPY") +Signed-off-by: Daniel Borkmann +Cc: Magnus Karlsson +Cc: Prashant Batra +Cc: Toke Høiland-Jørgensen +Cc: Jakub Kicinski +Reviewed-by: Toke Høiland-Jørgensen +Message-ID: <20240305090829.17131-1-daniel@iogearbox.net> +Signed-off-by: Alexei Starovoitov +--- + drivers/net/bonding/bond_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c +index a11748b8d69b..cd0683bcca03 100644 +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1811,7 +1811,7 @@ void bond_xdp_set_features(struct net_device *bond_dev) + + ASSERT_RTNL(); + +- if (!bond_xdp_check(bond)) { ++ if (!bond_xdp_check(bond) || !bond_has_slaves(bond)) { + xdp_clear_features_flag(bond_dev); + return; + } +-- +2.43.0 +