Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH RFC bpf-next 1/8] kasan: expose generic kasan helpers
From: Andrey Konovalov @ 2026-04-13 22:19 UTC (permalink / raw)
  To: Alexis Lothoré (eBPF Foundation)
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, Jiri Olsa, John Fastabend,
	David S. Miller, David Ahern, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Shuah Khan,
	Maxime Coquelin, Alexandre Torgue, Andrey Ryabinin,
	Alexander Potapenko, Dmitry Vyukov, Vincenzo Frascino,
	Andrew Morton, ebpf, Bastien Curutchet, Thomas Petazzoni,
	Xu Kuohai, bpf, linux-kernel, netdev, linux-kselftest,
	linux-stm32, linux-arm-kernel, kasan-dev, linux-mm
In-Reply-To: <20260413-kasan-v1-1-1a5831230821@bootlin.com>

On Mon, Apr 13, 2026 at 8:29 PM Alexis Lothoré (eBPF Foundation)
<alexis.lothore@bootlin.com> wrote:
>
> In order to prepare KASAN helpers to be called from the eBPF subsystem
> (to add KASAN instrumentation at runtime when JITing eBPF programs),
> expose the __asan_{load,store}X functions in linux/kasan.h
>
> Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
> ---
>  include/linux/kasan.h | 13 +++++++++++++
>  mm/kasan/kasan.h      | 10 ----------
>  2 files changed, 13 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/kasan.h b/include/linux/kasan.h
> index 338a1921a50a..6f580d4a39e4 100644
> --- a/include/linux/kasan.h
> +++ b/include/linux/kasan.h
> @@ -710,4 +710,17 @@ void kasan_non_canonical_hook(unsigned long addr);
>  static inline void kasan_non_canonical_hook(unsigned long addr) { }
>  #endif /* CONFIG_KASAN_GENERIC || CONFIG_KASAN_SW_TAGS */
>
> +#ifdef CONFIG_KASAN_GENERIC
> +void __asan_load1(void *p);
> +void __asan_store1(void *p);
> +void __asan_load2(void *p);
> +void __asan_store2(void *p);
> +void __asan_load4(void *p);
> +void __asan_store4(void *p);
> +void __asan_load8(void *p);
> +void __asan_store8(void *p);
> +void __asan_load16(void *p);
> +void __asan_store16(void *p);
> +#endif /* CONFIG_KASAN_GENERIC */

This looks ugly, let's not do this unless it's really required.

You can just use kasan_check_read/write() instead - these are public
wrappers around the same shadow memory checking functions. And they
also work with the SW_TAGS mode, in case the BPF would want to use
that mode at some point. (For HW_TAGS, we only have kasan_check_byte()
that checks a single byte, but it can be extended in the future if
required to be used by BPF.)



> +
>  #endif /* LINUX_KASAN_H */
> diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
> index fc9169a54766..3bfce8eb3135 100644
> --- a/mm/kasan/kasan.h
> +++ b/mm/kasan/kasan.h
> @@ -594,16 +594,6 @@ void __asan_handle_no_return(void);
>  void __asan_alloca_poison(void *, ssize_t size);
>  void __asan_allocas_unpoison(void *stack_top, ssize_t stack_bottom);
>
> -void __asan_load1(void *);
> -void __asan_store1(void *);
> -void __asan_load2(void *);
> -void __asan_store2(void *);
> -void __asan_load4(void *);
> -void __asan_store4(void *);
> -void __asan_load8(void *);
> -void __asan_store8(void *);
> -void __asan_load16(void *);
> -void __asan_store16(void *);
>  void __asan_loadN(void *, ssize_t size);
>  void __asan_storeN(void *, ssize_t size);
>
>
> --
> 2.53.0
>

^ permalink raw reply

* Re: [PATCH RFC bpf-next 3/8] bpf: add BPF_JIT_KASAN for KASAN instrumentation of JITed programs
From: Andrey Konovalov @ 2026-04-13 22:20 UTC (permalink / raw)
  To: Alexis Lothoré (eBPF Foundation)
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, Jiri Olsa, John Fastabend,
	David S. Miller, David Ahern, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Shuah Khan,
	Maxime Coquelin, Alexandre Torgue, Andrey Ryabinin,
	Alexander Potapenko, Dmitry Vyukov, Vincenzo Frascino,
	Andrew Morton, ebpf, Bastien Curutchet, Thomas Petazzoni,
	Xu Kuohai, bpf, linux-kernel, netdev, linux-kselftest,
	linux-stm32, linux-arm-kernel, kasan-dev, linux-mm
In-Reply-To: <20260413-kasan-v1-3-1a5831230821@bootlin.com>

On Mon, Apr 13, 2026 at 8:29 PM Alexis Lothoré (eBPF Foundation)
<alexis.lothore@bootlin.com> wrote:
>
> Add a new Kconfig option CONFIG_BPF_JIT_KASAN that automatically enables
> KASAN (Kernel Address Sanitizer) memory access checks for JIT-compiled
> BPF programs, when both KASAN and JIT compiler are enabled. When
> enabled, the JIT compiler will emit shadow memory checks before memory
> loads and stores to detect use-after-free, out-of-bounds, and other
> memory safety bugs at runtime. The option is gated behind
> HAVE_EBPF_JIT_KASAN, as it needs proper arch-specific implementation.
>
> Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
> ---
>  kernel/bpf/Kconfig | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/kernel/bpf/Kconfig b/kernel/bpf/Kconfig
> index eb3de35734f0..28392adb3d7e 100644
> --- a/kernel/bpf/Kconfig
> +++ b/kernel/bpf/Kconfig
> @@ -17,6 +17,10 @@ config HAVE_CBPF_JIT
>  config HAVE_EBPF_JIT
>         bool
>
> +# KASAN support for JIT compiler
> +config HAVE_EBPF_JIT_KASAN
> +       bool
> +
>  # Used by archs to tell that they want the BPF JIT compiler enabled by
>  # default for kernels that were compiled with BPF JIT support.
>  config ARCH_WANT_DEFAULT_BPF_JIT
> @@ -101,4 +105,9 @@ config BPF_LSM
>
>           If you are unsure how to answer this question, answer N.
>
> +config BPF_JIT_KASAN
> +       bool
> +       depends on HAVE_EBPF_JIT_KASAN
> +       default y if BPF_JIT && KASAN_GENERIC

Should this be "depends on KASAN && KASAN_GENERIC"?


> +
>  endmenu # "BPF subsystem"
>
> --
> 2.53.0
>

^ permalink raw reply

* Re: [PATCH RFC bpf-next 8/8] selftests/bpf: add tests to validate KASAN on JIT programs
From: Andrey Konovalov @ 2026-04-13 22:20 UTC (permalink / raw)
  To: Alexis Lothoré (eBPF Foundation)
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Song Liu, Yonghong Song, Jiri Olsa, John Fastabend,
	David S. Miller, David Ahern, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Shuah Khan,
	Maxime Coquelin, Alexandre Torgue, Andrey Ryabinin,
	Alexander Potapenko, Dmitry Vyukov, Vincenzo Frascino,
	Andrew Morton, ebpf, Bastien Curutchet, Thomas Petazzoni,
	Xu Kuohai, bpf, linux-kernel, netdev, linux-kselftest,
	linux-stm32, linux-arm-kernel, kasan-dev, linux-mm
In-Reply-To: <20260413-kasan-v1-8-1a5831230821@bootlin.com>

On Mon, Apr 13, 2026 at 8:29 PM Alexis Lothoré (eBPF Foundation)
<alexis.lothore@bootlin.com> wrote:
>
> Add a basic KASAN test runner that loads and test-run programs that can
> trigger memory management bugs. The test captures kernel logs and ensure
> that the expected KASAN splat is emitted by searching for the
> corresponding first lines in the report.
>
> This version implements two faulty programs triggering either a
> user-after-free, or an out-of-bounds memory usage. The bugs are
> triggered thanks to some dedicated kfuncs in bpf_testmod.c, but two
> different techniques are used, as some cases can be quite hard to
> trigger in a pure "black box" approach:
> - for reads, we can make the used kfuncs return some faulty pointers
>   that ebpf programs will manipulate, they will generate legitimate
>   kasan reports as a consequence
> - applying the same trick for faulty writes is harder, as ebpf programs
>   can't write kernel data freely. So ebpf programs can call another
>   specific testing kfunc that will alter the shadow memory matching the
>   passed memory (eg: a map). When the program will try to write to the
>   corresponding memory, it will trigger a report as well.
>
> Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
> ---
> The way of bringing kasan_poison into bpf_testmod is definitely not
> ideal.  But I would like to validate the testing approach (triggering
> real faulty accesses, which is hard on some cases, VS manually poisoning
> BPF-manipulated memory) before eventually making clean bridges between
> KASAN APIs and bpf_testmod.c, if the latter approach is the valid one.

Would it make sense to put these tests into KASAN KUnit tests in
mm/kasan/kasan_test_c.c? I assume there is a kernel API to JIT BPF
programs from the kernel itself?

There, you can just call kasan_poison(), some tests already do this.
And you can also extend the KASAN KUnit test framework to find out
whether the bad access is a read or write, if you want to check this.



> ---
>  tools/testing/selftests/bpf/prog_tests/kasan.c     | 165 +++++++++++++++++++++
>  tools/testing/selftests/bpf/progs/kasan.c          | 146 ++++++++++++++++++
>  .../testing/selftests/bpf/test_kmods/bpf_testmod.c |  79 ++++++++++
>  3 files changed, 390 insertions(+)
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/kasan.c b/tools/testing/selftests/bpf/prog_tests/kasan.c
> new file mode 100644
> index 000000000000..fd628aaa8005
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/kasan.c
> @@ -0,0 +1,165 @@
> +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
> +#include <bpf/bpf.h>
> +#include <fcntl.h>
> +#include <linux/if_ether.h>
> +#include <sys/klog.h>
> +#include <test_progs.h>
> +#include <unpriv_helpers.h>
> +#include "kasan.skel.h"
> +
> +#define SUBTEST_NAME_MAX_LEN   64
> +#define SYSLOG_ACTION_READ_ALL 3
> +#define SYSLOG_ACTION_CLEAR    5
> +
> +#define MAX_LOG_SIZE           (8*1024)
> +#define READ_CHUNK_SIZE                128
> +
> +#define KASAN_PATTERN_SLAB_UAF "BUG: KASAN: slab-use-after-free in bpf_prog_"
> +#define KASAN_PATTERN_GLOBAL_OOB "BUG: KASAN: global-out-of-bounds in bpf_prog_"
> +
> +static char klog_buffer[MAX_LOG_SIZE];
> +
> +static int read_kernel_logs(char *buf, size_t max_len)
> +{
> +       return klogctl(SYSLOG_ACTION_READ_ALL, buf, max_len);
> +}
> +
> +static int clear_kernel_logs(void)
> +{
> +       return klogctl(SYSLOG_ACTION_CLEAR, NULL, 0);
> +}
> +
> +static int kernel_logs_have_matching_kasan_report(char *buf, char *pattern,
> +                                                 bool is_write, int size)
> +{
> +       char *access_desc_start, *access_desc_end, *tmp;
> +       char access_log[READ_CHUNK_SIZE];
> +       char *kasan_report_start;
> +       int hsize, nsize;
> +       /* Searched kasan report is valid if
> +        * - it contains the expected kasan pattern
> +        * - the next line is the description of the faulty access
> +        * - faulty access properties match the tested type and size
> +        */
> +       kasan_report_start = strstr(buf, pattern);
> +
> +       if (!kasan_report_start)
> +               return 1;
> +
> +       /* Find next line */
> +       access_desc_start = strchr(kasan_report_start, '\n');
> +       if (!access_desc_start)
> +               return 1;
> +       access_desc_start++;
> +
> +       access_desc_end = strchr(access_desc_start, '\n');
> +       if (!access_desc_end)
> +               return 1;
> +
> +       nsize = snprintf(access_log, READ_CHUNK_SIZE, "%s of size %d at addr",
> +                is_write ? "Write" : "Read", size);
> +
> +       hsize = access_desc_end - access_desc_start;
> +       tmp = memmem(access_desc_start, hsize, access_log, nsize);
> +
> +       if (!tmp)
> +               return 1;
> +
> +       return 0;
> +}
> +
> +struct test_spec {
> +       char *prog_name;
> +       char *expected_report_pattern;
> +};
> +
> +static struct test_spec tests[] = {
> +       {
> +               .prog_name = "bpf_kasan_uaf",
> +               .expected_report_pattern = KASAN_PATTERN_SLAB_UAF
> +       },
> +       {
> +               .prog_name = "bpf_kasan_oob",
> +               .expected_report_pattern = KASAN_PATTERN_GLOBAL_OOB
> +       }
> +};
> +
> +static void run_test_with_type_and_size(struct kasan *skel,
> +                                       struct test_spec *test, bool is_write,
> +                                       int access_size)
> +{
> +       char subtest_name[SUBTEST_NAME_MAX_LEN];
> +       struct bpf_program *prog;
> +       uint8_t buf[ETH_HLEN];
> +       int ret;
> +
> +       prog = bpf_object__find_program_by_name(skel->obj, test->prog_name);
> +       if (!ASSERT_OK_PTR(prog, "find test prog"))
> +               return;
> +
> +       snprintf(subtest_name, SUBTEST_NAME_MAX_LEN, "%s_%s_%d",
> +                test->prog_name, is_write ? "write" : "read", access_size);
> +
> +       if (!test__start_subtest(subtest_name))
> +               return;
> +
> +       ret = clear_kernel_logs();
> +       if (!ASSERT_OK(ret, "reset log buffer"))
> +               return;
> +
> +       LIBBPF_OPTS(bpf_test_run_opts, topts);
> +       topts.sz = sizeof(struct bpf_test_run_opts);
> +       topts.data_size_in = ETH_HLEN;
> +       topts.data_in = buf;
> +       skel->bss->is_write = is_write;
> +       skel->bss->access_size = access_size;
> +       ret = bpf_prog_test_run_opts(bpf_program__fd(prog), &topts);
> +       if (!ASSERT_OK(ret, "run prog"))
> +               return;
> +
> +       ret = read_kernel_logs(klog_buffer, MAX_LOG_SIZE);
> +       if (ASSERT_GE(ret, 0, "read kernel logs"))
> +               ASSERT_OK(kernel_logs_have_matching_kasan_report(
> +                                 klog_buffer, test->expected_report_pattern,
> +                                 is_write, access_size),
> +                         test->prog_name);
> +}
> +
> +static void run_test_with_type(struct kasan *skel, struct test_spec *test,
> +                              bool is_write)
> +{
> +       run_test_with_type_and_size(skel, test, is_write, 1);
> +       run_test_with_type_and_size(skel, test, is_write, 2);
> +       run_test_with_type_and_size(skel, test, is_write, 4);
> +       run_test_with_type_and_size(skel, test, is_write, 8);
> +}
> +
> +static void run_test(struct kasan *skel, struct test_spec *test)
> +{
> +       run_test_with_type(skel, test, false);
> +       run_test_with_type(skel, test, true);
> +}
> +
> +void test_kasan(void)
> +{
> +       struct test_spec *test;
> +       struct kasan *skel;
> +       int i;
> +
> +       if (!is_jit_enabled() || !get_kasan_jit_enabled()) {
> +               test__skip();
> +               return;
> +       }
> +
> +       skel = kasan__open_and_load();
> +       if (!ASSERT_OK_PTR(skel, "open and load prog"))
> +               return;
> +
> +       for (i = 0; i < ARRAY_SIZE(tests); i++) {
> +               test = &tests[i];
> +
> +               run_test(skel, test);
> +       }
> +
> +       kasan__destroy(skel);
> +}
> diff --git a/tools/testing/selftests/bpf/progs/kasan.c b/tools/testing/selftests/bpf/progs/kasan.c
> new file mode 100644
> index 000000000000..f713c9b7c9ce
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/progs/kasan.c
> @@ -0,0 +1,146 @@
> +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
> +
> +#include <linux/bpf.h>
> +#include <bpf/bpf_helpers.h>
> +#include <bpf/bpf_tracing.h>
> +
> +#define KASAN_SLAB_FREE 0xFB
> +#define KASAN_GLOBAL_REDZONE 0xF9
> +
> +extern __u8 *bpf_kfunc_kasan_uaf_1(void) __ksym;
> +extern __u16 *bpf_kfunc_kasan_uaf_2(void) __ksym;
> +extern __u32 *bpf_kfunc_kasan_uaf_4(void) __ksym;
> +extern __u64 *bpf_kfunc_kasan_uaf_8(void) __ksym;
> +extern __u8 *bpf_kfunc_kasan_oob_1(void) __ksym;
> +extern __u16 *bpf_kfunc_kasan_oob_2(void) __ksym;
> +extern __u32 *bpf_kfunc_kasan_oob_4(void) __ksym;
> +extern __u64 *bpf_kfunc_kasan_oob_8(void) __ksym;
> +extern void bpf_kfunc_kasan_poison(void *mem, __u32 mem__sz, __u8 byte) __ksym;
> +
> +int access_size;
> +int is_write;
> +
> +struct kasan_write_val {
> +       __u8 data_1;
> +       __u16 data_2;
> +       __u32 data_4;
> +       __u64 data_8;
> +};
> +
> +struct {
> +       __uint(type, BPF_MAP_TYPE_ARRAY);
> +       __uint(max_entries, 1);
> +       __type(key, __u32);
> +       __type(value, struct kasan_write_val);
> +} test_map SEC(".maps");
> +
> +static void bpf_kasan_faulty_write(int size, __u8 poison_byte)
> +{
> +       struct kasan_write_val *val;
> +       __u32 key = 0;
> +
> +       val = bpf_map_lookup_elem(&test_map, &key);
> +       if (!val)
> +               return;
> +
> +       bpf_kfunc_kasan_poison(val, sizeof(struct kasan_write_val),
> +                              poison_byte);
> +       switch (size) {
> +       case 1:
> +               val->data_1 = 0xAA;
> +               break;
> +       case 2:
> +               val->data_2 = 0xAA;
> +               break;
> +       case 4:
> +               val->data_4 = 0xAA;
> +               break;
> +       case 8:
> +               val->data_8 = 0xAA;
> +               break;
> +       }
> +       bpf_kfunc_kasan_poison(val, sizeof(struct kasan_write_val), 0x00);
> +}
> +
> +
> +static int bpf_kasan_uaf_read(int size)
> +{
> +       __u8 *result_1;
> +       __u16 *result_2;
> +       __u32 *result_4;
> +       __u64 *result_8;
> +       int ret = 0;
> +
> +       switch (size) {
> +       case 1:
> +               result_1 = bpf_kfunc_kasan_uaf_1();
> +               ret = result_1[0] ? 1 : 0;
> +               break;
> +       case 2:
> +               result_2 = bpf_kfunc_kasan_uaf_2();
> +               ret = result_2[0] ? 1 : 0;
> +               break;
> +       case 4:
> +               result_4 = bpf_kfunc_kasan_uaf_4();
> +               ret = result_4[0] ? 1 : 0;
> +               break;
> +       case 8:
> +               result_8 = bpf_kfunc_kasan_uaf_8();
> +               ret = result_8[0] ? 1 : 0;
> +               break;
> +       }
> +       return ret;
> +}
> +
> +SEC("tcx/ingress")
> +int bpf_kasan_uaf(struct __sk_buff *skb)
> +{
> +       if (is_write) {
> +               bpf_kasan_faulty_write(access_size, KASAN_SLAB_FREE);
> +               return 0;
> +       }
> +
> +       return bpf_kasan_uaf_read(access_size);
> +}
> +
> +static int bpf_kasan_oob_read(int size)
> +{
> +       __u8 *result_1;
> +       __u16 *result_2;
> +       __u32 *result_4;
> +       __u64 *result_8;
> +       int ret = 0;
> +
> +       switch (size) {
> +       case 1:
> +               result_1 = bpf_kfunc_kasan_oob_1();
> +               ret = result_1[0] ? 1 : 0;
> +               break;
> +       case 2:
> +               result_2 = bpf_kfunc_kasan_oob_2();
> +               ret = result_2[0] ? 1 : 0;
> +               break;
> +       case 4:
> +               result_4 = bpf_kfunc_kasan_oob_4();
> +               ret = result_4[0] ? 1 : 0;
> +               break;
> +       case 8:
> +               result_8 = bpf_kfunc_kasan_oob_8();
> +               ret = result_8[0] ? 1 : 0;
> +               break;
> +       }
> +       return ret;
> +}
> +
> +SEC("tcx/ingress")
> +int bpf_kasan_oob(struct __sk_buff *skb)
> +{
> +       if (is_write) {
> +               bpf_kasan_faulty_write(access_size, KASAN_GLOBAL_REDZONE);
> +               return 0;
> +       }
> +
> +       return bpf_kasan_oob_read(access_size);
> +}
> +
> +char LICENSE[] SEC("license") = "GPL";
> diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
> index d876314a4d67..01554bcbbbb0 100644
> --- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
> +++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
> @@ -271,6 +271,76 @@ __bpf_kfunc void bpf_kfunc_put_default_trusted_ptr_test(struct prog_test_member
>          */
>  }
>
> +static void *kasan_uaf(void)
> +{
> +       void *p = kmalloc(64, GFP_ATOMIC);
> +
> +       if (!p)
> +               return NULL;
> +       memset(p, 0xAA, 64);
> +       kfree(p);
> +
> +       return p;
> +}
> +
> +#ifdef CONFIG_KASAN_GENERIC
> +extern void kasan_poison(const void *addr, size_t size, u8 value, bool init);
> +
> +__bpf_kfunc void bpf_kfunc_kasan_poison(void *mem, u32 mem__sz, u8 byte)
> +{
> +       kasan_poison(mem, mem__sz, byte, false);
> +}
> +#else
> +__bpf_kfunc void bpf_kfunc_kasan_poison(void *mem, u32 mem__sz, u8 byte) { }
> +#endif
> +
> +__bpf_kfunc u8 *bpf_kfunc_kasan_uaf_1(void)
> +{
> +       return kasan_uaf();
> +}
> +
> +__bpf_kfunc u16 *bpf_kfunc_kasan_uaf_2(void)
> +{
> +       return kasan_uaf();
> +}
> +
> +__bpf_kfunc u32 *bpf_kfunc_kasan_uaf_4(void)
> +{
> +       return kasan_uaf();
> +}
> +
> +__bpf_kfunc u64 *bpf_kfunc_kasan_uaf_8(void)
> +{
> +       return kasan_uaf();
> +}
> +
> +static u8 test_oob_buffer[64];
> +
> +static void *bpf_kfunc_kasan_oob(void)
> +{
> +       return test_oob_buffer+64;
> +}
> +
> +__bpf_kfunc u8 *bpf_kfunc_kasan_oob_1(void)
> +{
> +       return bpf_kfunc_kasan_oob();
> +}
> +
> +__bpf_kfunc u16 *bpf_kfunc_kasan_oob_2(void)
> +{
> +       return bpf_kfunc_kasan_oob();
> +}
> +
> +__bpf_kfunc u32 *bpf_kfunc_kasan_oob_4(void)
> +{
> +       return bpf_kfunc_kasan_oob();
> +}
> +
> +__bpf_kfunc u64 *bpf_kfunc_kasan_oob_8(void)
> +{
> +       return bpf_kfunc_kasan_oob();
> +}
> +
>  __bpf_kfunc struct bpf_testmod_ctx *
>  bpf_testmod_ctx_create(int *err)
>  {
> @@ -740,6 +810,15 @@ BTF_ID_FLAGS(func, bpf_testmod_ops3_call_test_1)
>  BTF_ID_FLAGS(func, bpf_testmod_ops3_call_test_2)
>  BTF_ID_FLAGS(func, bpf_kfunc_get_default_trusted_ptr_test);
>  BTF_ID_FLAGS(func, bpf_kfunc_put_default_trusted_ptr_test);
> +BTF_ID_FLAGS(func, bpf_kfunc_kasan_poison)
> +BTF_ID_FLAGS(func, bpf_kfunc_kasan_uaf_1)
> +BTF_ID_FLAGS(func, bpf_kfunc_kasan_uaf_2)
> +BTF_ID_FLAGS(func, bpf_kfunc_kasan_uaf_4)
> +BTF_ID_FLAGS(func, bpf_kfunc_kasan_uaf_8)
> +BTF_ID_FLAGS(func, bpf_kfunc_kasan_oob_1)
> +BTF_ID_FLAGS(func, bpf_kfunc_kasan_oob_2)
> +BTF_ID_FLAGS(func, bpf_kfunc_kasan_oob_4)
> +BTF_ID_FLAGS(func, bpf_kfunc_kasan_oob_8)
>  BTF_KFUNCS_END(bpf_testmod_common_kfunc_ids)
>
>  BTF_ID_LIST(bpf_testmod_dtor_ids)
>
> --
> 2.53.0
>

^ permalink raw reply

* Re: [PATCH net-next 5/7] net/mlx5: E-Switch, block representors during reconfiguration
From: Jakub Kicinski @ 2026-04-13 22:22 UTC (permalink / raw)
  To: Tariq Toukan
  Cc: Eric Dumazet, Paolo Abeni, Andrew Lunn, David S. Miller,
	Saeed Mahameed, Leon Romanovsky, Mark Bloch, Shay Drory,
	Or Har-Toov, Edward Srouji, Maher Sanalla, Simon Horman,
	Moshe Shemesh, Kees Cook, Patrisious Haddad, Gerd Bayer,
	Parav Pandit, Cosmin Ratiu, Carolina Jubran, netdev, linux-rdma,
	linux-kernel, Gal Pressman, Dragos Tatulea
In-Reply-To: <20260409115550.156419-6-tariqt@nvidia.com>

On Thu, 9 Apr 2026 14:55:48 +0300 Tariq Toukan wrote:
> A spinlock is out because the protected work can sleep (RDMA ops,
> devcom, netdev callbacks). A mutex won't work either: esw_mode_change()
> has to drop the guard mid-flight so mlx5_rescan_drivers_locked() can
> reload mlx5_ib, which calls back into mlx5_eswitch_register_vport_reps()
> on the same thread. Beyond that, any real lock would create an ABBA
> cycle: the LAG side holds the LAG lock when it calls reps_block(), and
> the mlx5_ib side holds RDMA locks when it calls register_vport_reps(),
> and those two subsystems talk to each other. The atomic CAS loop avoids
> all of this - no lock ordering, no sleep restrictions, and the owner
> can drop the guard and let a nested caller win the next transition
> before reclaiming it.

You gotta explain to me how a busy loop waiting for a bit to go 
to "UNBLOCKED" state is anything else than a homegrown lock :S

Also what purpose does the atomic_cond_read_relaxed() serve?
I haven't seen it being used before.

^ permalink raw reply

* Re: [PATCH net-next v3 0/4] net: move .getsockopt away from __user buffers
From: patchwork-bot+netdevbpf @ 2026-04-13 22:30 UTC (permalink / raw)
  To: Breno Leitao
  Cc: davem, edumazet, kuba, pabeni, horms, kuniyu, willemb, metze,
	axboe, sdf, io-uring, bpf, netdev, torvalds, linux-kernel,
	kernel-team
In-Reply-To: <20260408-getsockopt-v3-0-061bb9cb355d@debian.org>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Wed, 08 Apr 2026 03:30:28 -0700 you wrote:
> Currently, the .getsockopt callback requires __user pointers:
> 
>   int (*getsockopt)(struct socket *sock, int level,
>                     int optname, char __user *optval, int __user *optlen);
> 
> This prevents kernel callers (io_uring, BPF) from using getsockopt on
> levels other than SOL_SOCKET, since they pass kernel pointers.
> 
> [...]

Here is the summary with links:
  - [net-next,v3,1/4] net: add getsockopt_iter callback to proto_ops
    https://git.kernel.org/netdev/net-next/c/67fab22a7adc
  - [net-next,v3,2/4] net: call getsockopt_iter if available
    https://git.kernel.org/netdev/net-next/c/5bd0dec150f5
  - [net-next,v3,3/4] af_packet: convert to getsockopt_iter
    https://git.kernel.org/netdev/net-next/c/9c99d6270569
  - [net-next,v3,4/4] can: raw: convert to getsockopt_iter
    https://git.kernel.org/netdev/net-next/c/5b75e7d67695

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH net-next v4 4/4] net: dsa: yt921x: Add port qdisc tbf support
From: Jakub Kicinski @ 2026-04-13 22:32 UTC (permalink / raw)
  To: David Yang
  Cc: netdev, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Paolo Abeni, linux-kernel
In-Reply-To: <20260409171209.2575583-5-mmyangfl@gmail.com>

On Fri, 10 Apr 2026 01:12:04 +0800 David Yang wrote:
> +static int
> +yt921x_tbf_validate(struct yt921x_priv *priv,
> +		    const struct tc_tbf_qopt_offload *qopt, int *queuep)
> +{
> +	struct device *dev = to_device(priv);
> +	int queue = -1;
> +
> +	/* TODO: queue support */
> +	if (qopt->parent != TC_H_ROOT) {
> +		dev_err(dev, "Parent should be \"root\"\n");

Let's add extack to the offload struct like htb does and report this to
the user instead of the logs?

> +		return -EOPNOTSUPP;
> +	}
> +
> +	switch (qopt->command) {
> +	case TC_TBF_REPLACE: {
> +		const struct tc_tbf_qopt_offload_replace_params *p;
> +
> +		p = &qopt->replace_params;
> +
> +		if (!p->rate.mpu) {
> +			dev_info(dev, "Assuming you want mpu = 64\n");

BTW we can use extack for "warnings" like this, too

> +		} else if (p->rate.mpu != 64) {
> +			dev_err(dev, "mpu other than 64 not supported\n");
> +			return -EINVAL;
> +		}
> +		break;
> +	}
> +	default:
> +		break;
> +	}
> +
> +	*queuep = queue;
> +	return 0;
> +}
> +
> +static int
> +yt921x_dsa_port_setup_tc_tbf_port(struct dsa_switch *ds, int port,
> +				  const struct tc_tbf_qopt_offload *qopt)
> +{
> +	struct yt921x_priv *priv = to_yt921x_priv(ds);
> +	u32 ctrls[2];
> +	int res;
> +
> +	switch (qopt->command) {
> +	case TC_TBF_DESTROY:
> +		ctrls[0] = 0;
> +		ctrls[1] = 0;
> +		break;
> +	case TC_TBF_REPLACE: {
> +		const struct tc_tbf_qopt_offload_replace_params *p;
> +		struct yt921x_marker marker;
> +		u64 burst;
> +
> +		p = &qopt->replace_params;
> +
> +		/* where is burst??? */

Why not add it?

> +		burst = div_u64(priv->port_shape_slot_ns * p->rate.rate_bytes_ps,
> +				1000000000) + 10000;
-- 
pw-bot: cr

^ permalink raw reply

* Re: [PATCH bpf-next v2 1/1] bpf: Refactor dynptr mutability tracking
From: Amery Hung @ 2026-04-13 22:35 UTC (permalink / raw)
  To: Mykyta Yatsenko
  Cc: bpf, netdev, alexei.starovoitov, andrii, daniel, memxor, eddyz87,
	yatsenko, martin.lau, kernel-team
In-Reply-To: <123ccf9c-a6ec-496a-872d-965e46d07d51@gmail.com>

On Mon, Apr 13, 2026 at 9:05 AM Mykyta Yatsenko
<mykyta.yatsenko5@gmail.com> wrote:

> > -__bpf_kfunc int bpf_get_fsverity_digest(struct file *file, struct bpf_dynptr *digest_p)
> > +__bpf_kfunc int bpf_get_fsverity_digest(struct file *file, const struct bpf_dynptr *digest_p)
> >   {
> >       struct bpf_dynptr_kern *digest_ptr = (struct bpf_dynptr_kern *)digest_p;
>
> maybe we can make this digest_ptr const as well, otherwise it's a little
> bit strange to introduce const, but cast to non-const kernel struct
> immediately. I think we can apply this in other kfuncs.

Good catch. Will double check other instances.

>
> >       const struct inode *inode = file_inode(file);
> > diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> > index 05b34a6355b0..329b78940b79 100644
> > --- a/include/linux/bpf.h
> > +++ b/include/linux/bpf.h
> > @@ -3621,8 +3621,8 @@ static inline int bpf_fd_reuseport_array_update_elem(struct bpf_map *map,
> >   struct bpf_key *bpf_lookup_user_key(s32 serial, u64 flags);
> >   struct bpf_key *bpf_lookup_system_key(u64 id);
> >   void bpf_key_put(struct bpf_key *bkey);
> > -int bpf_verify_pkcs7_signature(struct bpf_dynptr *data_p,
> > -                            struct bpf_dynptr *sig_p,
> > +int bpf_verify_pkcs7_signature(const struct bpf_dynptr *data_p,
> > +                            const struct bpf_dynptr *sig_p,
> >                              struct bpf_key *trusted_keyring);
> >
> >   #else
>
> ...
>
> >               err = mark_stack_slots_dynptr(env, reg, arg_type, insn_idx, clone_ref_obj_id);
> > -     } else /* MEM_RDONLY and None case from above */ {
> > +     } else /* OBJ_RELEASE and None case from above */ {
> >               /* For the reg->type == PTR_TO_STACK case, bpf_dynptr is never const */
> > -             if (reg->type == CONST_PTR_TO_DYNPTR && !(arg_type & MEM_RDONLY)) {
> > -                     verbose(env, "cannot pass pointer to const bpf_dynptr, the helper mutates it\n");
> > +             if (reg->type == CONST_PTR_TO_DYNPTR && (arg_type & OBJ_RELEASE)) {
> > +                     verbose(env, "CONST_PTR_TO_DYNPTR cannot be released");
>
> \n is missing in the verbose.

Ack.

>
> >                       return -EINVAL;
> >               }
> >
> > @@ -8958,7 +8929,7 @@ static int process_dynptr_func(struct bpf_verifier_env *env, int regno, int insn
> >                       return -EINVAL;
> >               }
> >
> > -             /* Fold modifiers (in this case, MEM_RDONLY) when checking expected type */
> > +             /* Fold modifiers (in this case, OBJ_RELEASE) when checking expected type */
> >               if (!is_dynptr_type_expected(env, reg, arg_type & ~MEM_RDONLY)) {
>
> Do we need to update the `is_dynptr_type_expected(env, reg, arg_type &
> ~MEM_RDONLY)` as MEM_RDONLY is no longer applied to the dynptr?

Ah yes. AI review bot didn't find it but sashiko did.

>
> >                       verbose(env,
> >                               "Expected a dynptr of type %s as arg #%d\n",
> > @@ -10803,7 +10774,7 @@ static int btf_check_func_arg_match(struct bpf_verifier_env *env, int subprog,
> >                               bpf_log(log, "R%d is not a pointer to arena or scalar.\n", regno);
> >                               return -EINVAL;
> >                       }
> > -             } else if (arg->arg_type == (ARG_PTR_TO_DYNPTR | MEM_RDONLY)) {
> > +             } else if (arg->arg_type == ARG_PTR_TO_DYNPTR) {
> >                       ret = check_func_arg_reg_off(env, reg, regno, ARG_PTR_TO_DYNPTR);
> >                       if (ret)
> >                               return ret;
> > @@ -13718,9 +13689,6 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
> >                       enum bpf_arg_type dynptr_arg_type = ARG_PTR_TO_DYNPTR;
> >                       int clone_ref_obj_id = 0;
> >
> > -                     if (reg->type == CONST_PTR_TO_DYNPTR)
> > -                             dynptr_arg_type |= MEM_RDONLY;
> > -
> >                       if (is_kfunc_arg_uninit(btf, &args[i]))
> >                               dynptr_arg_type |= MEM_UNINIT;

^ permalink raw reply

* Re: [PATCH v3 0/5] net: qrtr: ns: A bunch of fixs
From: patchwork-bot+netdevbpf @ 2026-04-13 22:40 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: mani, davem, edumazet, kuba, pabeni, horms, linux-arm-msm, netdev,
	linux-kernel, stable, yimingqian591
In-Reply-To: <20260409-qrtr-fix-v3-0-00a8a5ff2b51@oss.qualcomm.com>

Hello:

This series was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Thu, 09 Apr 2026 23:04:11 +0530 you wrote:
> Hi,
> 
> This series fixes a bunch of possible memory exhaustion issues in the QRTR
> nameserver.
> 
> ---
> Changes in v3:
> - Fixed the issues in remove() callback and other places reported by Sashiko
> - Link to v2: https://patch.msgid.link/20260403-qrtr-fix-v2-0-f88a14859c63@oss.qualcomm.com
> 
> [...]

Here is the summary with links:
  - [v3,1/5] net: qrtr: ns: Limit the maximum server registration per node
    https://git.kernel.org/netdev/net/c/d5ee2ff98322
  - [v3,2/5] net: qrtr: ns: Limit the maximum number of lookups
    https://git.kernel.org/netdev/net/c/5640227d9a21
  - [v3,3/5] net: qrtr: ns: Free the node during ctrl_cmd_bye()
    https://git.kernel.org/netdev/net/c/68efba36446a
  - [v3,4/5] net: qrtr: ns: Limit the total number of nodes
    https://git.kernel.org/netdev/net/c/27d5e84e810b
  - [v3,5/5] net: qrtr: ns: Fix use-after-free in driver remove()
    https://git.kernel.org/netdev/net/c/7809fea20c94

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* RE: [EXTERNAL] [PATCH 1/1] net: mana: fix use-after-free in add_adev() error path
From: Long Li @ 2026-04-13 22:43 UTC (permalink / raw)
  To: Ao Zhou, netdev@vger.kernel.org
  Cc: KY Srinivasan, Haiyang Zhang, wei.liu@kernel.org, Dexuan Cui,
	andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
	kuba@kernel.org, pabeni@redhat.com, ernis@linux.microsoft.com,
	ssengar@linux.microsoft.com, dipayanroy@linux.microsoft.com,
	gargaditya@linux.microsoft.com, Shiraz Saleem, kees@kernel.org,
	leon@kernel.org, Yifan Wu, Juefei Pu, Yuan Tan, Xin Liu,
	ruijieli51@gmail.com
In-Reply-To: <c4ea7d8907cf72b259bf70bd8c2e791e1c4ff70f.1774942606.git.623701471@qq.com>

> From: Ruijie Li <ruijieli51@gmail.com>
> 
> If auxiliary_device_add() fails, add_adev() jumps to add_fail and calls
> auxiliary_device_uninit(adev).
> 
> The auxiliary device has its release callback set to adev_release(), which frees
> the containing struct mana_adev. Since adev is embedded in struct mana_adev,
> the subsequent fall-through to init_fail and access to adev->id may result in a
> use-after-free.
> 
> Fix this by saving the allocated auxiliary device id in a local variable before
> calling auxiliary_device_add(), and use that saved id in the cleanup path after
> auxiliary_device_uninit().
> 
> Fixes: a69839d4327d ("net: mana: Add support for auxiliary device")
> Cc: <stable@kernel.org>
> Reported-by: Yifan Wu <yifanwucs@gmail.com>
> Reported-by: Juefei Pu <tomapufckgml@gmail.com>
> Co-developed-by: Yuan Tan <yuantan098@gmail.com>
> Signed-off-by: Yuan Tan <yuantan098@gmail.com>
> Suggested-by: Xin Liu <bird@lzu.edu.cn>
> Tested-by: Yuqi Xu<xuyuqiabc@gmail.com>
> Signed-off-by: LI Ruijie <ruijieli51@gmail.com>
> Signed-off-by: Ao Zhou <n05ec@lzu.edu.cn>

This has been fixed in this earlier commit:
https://lore.kernel.org/all/20260323165730.945365-1-lgs201920130244@gmail.com/

Thanks for helping

Long

> 
> ---
>  drivers/net/ethernet/microsoft/mana/mana_en.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c
> b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index 9017e806ecda..dca62fb9a3a9 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -3425,6 +3425,7 @@ static int add_adev(struct gdma_dev *gd, const char
> *name)
>         struct auxiliary_device *adev;
>         struct mana_adev *madev;
>         int ret;
> +       int id;
> 
>         madev = kzalloc_obj(*madev);
>         if (!madev)
> @@ -3434,7 +3435,8 @@ static int add_adev(struct gdma_dev *gd, const char
> *name)
>         ret = mana_adev_idx_alloc();
>         if (ret < 0)
>                 goto idx_fail;
> -       adev->id = ret;
> +       id = ret;
> +       adev->id = id;
> 
>         adev->name = name;
>         adev->dev.parent = gd->gdma_context->dev; @@ -3460,7 +3462,7 @@
> static int add_adev(struct gdma_dev *gd, const char *name)
>         auxiliary_device_uninit(adev);
> 
>  init_fail:
> -       mana_adev_idx_free(adev->id);
> +       mana_adev_idx_free(id);
> 
>  idx_fail:
>         kfree(madev);
> --


^ permalink raw reply

* Re: [PATCH net-next v3 0/9] net: dsa: add DSA support for the LAN9645x switch chip family
From: Jakub Kicinski @ 2026-04-13 22:47 UTC (permalink / raw)
  To: Jens Emil Schulz Østergaard
  Cc: UNGLinuxDriver, Andrew Lunn, Vladimir Oltean, David S. Miller,
	Eric Dumazet, Paolo Abeni, Simon Horman, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Woojung Huh, Russell King,
	Steen Hegelund, Daniel Machon, linux-kernel, netdev, devicetree
In-Reply-To: <20260410-dsa_lan9645x_switch_driver_base-v3-0-aadc8595306d@microchip.com>

On Fri, 10 Apr 2026 13:48:36 +0200 Jens Emil Schulz Østergaard wrote:
> This series provides the Microchip LAN9645X Switch driver.
> 
> The LAN9645x is a family of chips with ethernet switch functionality and
> multiple peripheral functions. The switch delivers up to 9 ethernet
> ports and 12 Gbps switching bandwidth.
> 
> The switch chip has 5 integrated copper PHYs, support for 2x RGMII
> interfaces, 2x SGMII and one QSGMII interface.
> 
> The switch chip is from the same design architecture family as ocelot
> and lan966x, and the driver reflects this similarity. However, LAN9645x
> does not have an internal CPU in any package, and must be driven
> externally. For register IO it supports interfaces such as SPI, I2C and
> MDIO.

We're wrapping up the 7.1 PR and doesn't look like Vladimir (or any
other DSA expert) had a chance to review this yet, so let's defer to
the next cycle.
-- 
pw-bot: defer

^ permalink raw reply

* Re: [PATCH net v2 0/2] octeon_ep_vf: fix napi_build_skb() NULL dereference
From: patchwork-bot+netdevbpf @ 2026-04-13 22:50 UTC (permalink / raw)
  To: David CARLIER
  Cc: netdev, vburru, sedara, srasheed, sburla, andrew+netdev, davem,
	edumazet, kuba, pabeni, horms, linux-kernel, stable
In-Reply-To: <20260409184009.930359-1-devnexen@gmail.com>

Hello:

This series was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Thu,  9 Apr 2026 19:40:07 +0100 you wrote:
> napi_build_skb() can return NULL on allocation failure. In
> __octep_vf_oq_process_rx(), the result is used directly without a
> NULL check in both the single-buffer and multi-fragment paths,
> leading to a NULL pointer dereference.
> 
> Patch 1 introduces a helper to deduplicate the ring index advance
> pattern, patch 2 adds the actual NULL checks.
> 
> [...]

Here is the summary with links:
  - [net,v2,1/2] octeon_ep_vf: introduce octep_vf_oq_next_idx() helper
    https://git.kernel.org/netdev/net/c/4e5bc3ff060e
  - [net,v2,2/2] octeon_ep_vf: add NULL check for napi_build_skb()
    https://git.kernel.org/netdev/net/c/dd66b4285470

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH net-next v4 2/2] net: pse-pd: add LED trigger support via notification path
From: Jakub Kicinski @ 2026-04-13 22:51 UTC (permalink / raw)
  To: Carlo Szelinsky
  Cc: Oleksij Rempel, Kory Maincent, Andrew Lunn, David S . Miller,
	Eric Dumazet, Paolo Abeni, Krzysztof Kozlowski,
	Krzysztof Kozlowski, Conor Dooley, Rob Herring, netdev,
	linux-kernel, linux-leds, kernel test robot
In-Reply-To: <20260410124428.809943-3-github@szelinsky.de>

On Fri, 10 Apr 2026 14:44:28 +0200 Carlo Szelinsky wrote:
> @@ -266,6 +267,23 @@ struct pse_pi {
>  	int pw_allocated_mW;
>  };
>  
> +#if IS_ENABLED(CONFIG_LEDS_TRIGGERS)
> +/**
> + * struct pse_pi_led_triggers - LED trigger state for a PSE PI
> + *
> + * @delivering: LED trigger for power delivering state
> + * @enabled: LED trigger for admin enabled state
> + * @last_delivering: cached delivering state for change detection
> + * @last_enabled: cached enabled state for change detection
> + */
> +struct pse_pi_led_triggers {
> +	struct led_trigger delivering;
> +	struct led_trigger enabled;
> +	bool last_delivering;
> +	bool last_enabled;
> +};
> +#endif
> +
>  /**

avoid wrapping type definitions in ifdefs.
This only forces other code to also be wrapped in ifdefs.

^ permalink raw reply

* Re: [PATCH net-next v4 1/2] net: pse-pd: add devm_pse_poll_helper()
From: Jakub Kicinski @ 2026-04-13 22:50 UTC (permalink / raw)
  To: github
  Cc: Jakub Kicinski, o.rempel, kory.maincent, andrew+netdev, davem,
	edumazet, pabeni, krzk, krzk+dt, conor+dt, robh, netdev,
	linux-kernel, linux-leds, lkp
In-Reply-To: <20260410124428.809943-2-github@szelinsky.de>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
net: pse-pd: add devm_pse_poll_helper()

Extract the common event handling loop from pse_isr() into a shared
pse_handle_events() function, and add a generic poll-based alternative
to the IRQ path for PSE controllers that lack interrupt support.

> Work cancellation on teardown is handled via devm_add_action_or_reset()
> to ensure the delayed work is cancelled before poll_notifs is freed
> by devres, avoiding a use-after-free when devm_pse_poll_helper() is
> called after devm_pse_controller_register() (devres LIFO ordering).

Is it safe to rely on this devm registration order to prevent a
use-after-free?

Standard Linux driver initialization typically sets up interrupts and
pollers before device registration to prevent race conditions where an
unready device is exposed to userspace.

If a driver follows this standard ordering by calling the helper before
registration, devres will unregister the controller first. This will
tear down resources in pse_controller_unregister() while the poll work
remains active.

If the worker executes during this race window, could it access the
already-freed pcdev->pi array or push to the destroyed ntf_fifo? Would
it be safer to explicitly cancel asynchronous event sources within
pse_controller_unregister() instead?

> --- a/drivers/net/pse-pd/pse_core.c
> +++ b/drivers/net/pse-pd/pse_core.c
[ ... ]
> +static void pse_handle_events(struct pse_controller_dev *pcdev,
> +			      unsigned long *notifs,
> +			      unsigned long notifs_mask)
>  {
> -	struct pse_controller_dev *pcdev;
> -	unsigned long notifs_mask = 0;
> -	struct pse_irq_desc *desc;
> -	struct pse_irq *h = data;
> -	int ret, i;
> -
> -	desc = &h->desc;
> -	pcdev = h->pcdev;
> -
> -	/* Clear notifs mask */
> -	memset(h->notifs, 0, pcdev->nr_lines * sizeof(*h->notifs));
> -	mutex_lock(&pcdev->lock);
> -	ret = desc->map_event(irq, pcdev, h->notifs, &notifs_mask);
> -	if (ret || !notifs_mask) {
> -		mutex_unlock(&pcdev->lock);
> -		return IRQ_NONE;
> -	}
> +	int i;
>  
>  	for_each_set_bit(i, &notifs_mask, pcdev->nr_lines) {

Can this lead to an out-of-bounds read on the stack if a controller
supports more than BITS_PER_LONG ports?

The notifs_mask variable is passed by value to pse_handle_events(), but
for_each_set_bit() takes its address. If pcdev->nr_lines is greater than
BITS_PER_LONG (e.g., a 48-port switch on a 32-bit architecture), the
macro will read past the function argument on the stack into uninitialized
memory.

[ ... ]
> +static irqreturn_t pse_isr(int irq, void *data)
> +{
> +	struct pse_controller_dev *pcdev;
> +	unsigned long notifs_mask = 0;
> +	struct pse_irq *h = data;
> +	int ret;
> +
> +	pcdev = h->pcdev;
> +
> +	/* Clear notifs mask */
> +	memset(h->notifs, 0, pcdev->nr_lines * sizeof(*h->notifs));
> +	mutex_lock(&pcdev->lock);
> +	ret = h->desc.map_event(irq, pcdev, h->notifs, &notifs_mask);

Could this also result in a stack out-of-bounds write?

If map_event() uses set_bit() to report an event on a port index greater
than or equal to BITS_PER_LONG, it will write past the 4-byte boundary of
the scalar notifs_mask variable, corrupting adjacent stack memory.

[ ... ]
> +static void pse_poll_worker(struct work_struct *work)
> +{
> +	struct pse_controller_dev *pcdev =
> +		container_of(work, struct pse_controller_dev,
> +			     poll_work.work);
> +	unsigned long notifs_mask = 0;
> +	int ret;
> +
> +	memset(pcdev->poll_notifs, 0,
> +	       pcdev->nr_lines * sizeof(*pcdev->poll_notifs));
> +	mutex_lock(&pcdev->lock);
> +	ret = pcdev->poll_desc.map_event(0, pcdev, pcdev->poll_notifs,
> +					 &notifs_mask);

Does this share the same out-of-bounds write risk for notifs_mask as the
IRQ handler above?
-- 
pw-bot: cr

^ permalink raw reply

* Re: [PATCH net-next v4 2/2] net: pse-pd: add LED trigger support via notification path
From: Jakub Kicinski @ 2026-04-13 22:53 UTC (permalink / raw)
  To: github
  Cc: Jakub Kicinski, o.rempel, kory.maincent, andrew+netdev, davem,
	edumazet, pabeni, krzk, krzk+dt, conor+dt, robh, netdev,
	linux-kernel, linux-leds, lkp
In-Reply-To: <20260410124428.809943-3-github@szelinsky.de>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
Date:   Fri Apr 10 12:44:28 2026 +0000

    net: pse-pd: add LED trigger support via notification path
    
    Add per-PI "delivering" and "enabled" LED triggers to the PSE core
    subsystem. LED state is updated from the shared pse_handle_events()
    function whenever the IRQ or poll path detects a state change, as well
    as from the regulator enable/disable paths so that host-initiated
    admin state changes via ethtool are immediately reflected.

    Link: https://lore.kernel.org/oe-kbuild-all/202603251254.o5PqMBRU-lkp@intel.com/
    Link: https://lore.kernel.org/oe-kbuild-all/202603251250.cuMCk5Yv-lkp@intel.com/

> diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
> index f641a6fa087fb..dfc84340afb9d 100644
> --- a/drivers/net/pse-pd/pse_core.c
> +++ b/drivers/net/pse-pd/pse_core.c

[ ... ]

> +static int pse_led_triggers_register(struct pse_controller_dev *pcdev)
> +{
> +	struct device *dev = pcdev->dev;
> +	const char *dev_id;
> +	int i, ret;
> +
> +	dev_id = dev_name(dev);
> +
> +	pcdev->pi_led_trigs = devm_kcalloc(dev, pcdev->nr_lines,
> +					   sizeof(*pcdev->pi_led_trigs),
> +					   GFP_KERNEL);
> +	if (!pcdev->pi_led_trigs)
> +		return -ENOMEM;
> +
> +	for (i = 0; i < pcdev->nr_lines; i++) {
> +		struct pse_pi_led_triggers *trigs = &pcdev->pi_led_trigs[i];
> +
> +		/* Skip PIs not described in device tree */
> +		if (!pcdev->no_of_pse_pi && !pcdev->pi[i].np)
> +			continue;
> +
> +		trigs->delivering.name = devm_kasprintf(dev, GFP_KERNEL,
> +							"pse-%s:port%d:delivering",
> +							dev_id, i);
> +		if (!trigs->delivering.name)
> +			return -ENOMEM;
> +
> +		ret = devm_led_trigger_register(dev, &trigs->delivering);

The commit message states that the initial LED state is queried at
registration time so already-active ports are reflected immediately.

Since no LED is bound to these triggers at registration time, the initial
led_trigger_event() call will be dropped. If an LED is bound later, will
it remain in the default (off) state because there is no .activate callback
configured on the trigger to sync the current state?

Furthermore, since the state is cached in last_delivering and last_enabled,
subsequent updates might not fire new events until the hardware state
actually toggles.

> +		if (ret)
> +			return ret;
> +
> +		trigs->enabled.name = devm_kasprintf(dev, GFP_KERNEL,
> +						     "pse-%s:port%d:enabled",
> +						     dev_id, i);
> +		if (!trigs->enabled.name)
> +			return -ENOMEM;
> +
> +		ret = devm_led_trigger_register(dev, &trigs->enabled);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}

[ ... ]

> @@ -1108,6 +1217,20 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
>  	if (ret)
>  		return ret;
>  
> +	ret = pse_led_triggers_register(pcdev);
> +	if (ret) {
> +		dev_warn(pcdev->dev, "Failed to register LED triggers: %d\n",
> +			 ret);
> +	}

If devm_led_trigger_register() fails inside pse_led_triggers_register(),
the function returns an error but leaves trigs->delivering.name allocated
and non-NULL.

Because we only log a warning here and continue execution, the cleanup
for pcdev->pi_led_trigs does not occur.

Later, pse_led_update() verifies validity using this check:

	if (!trigs->delivering.name)
		return;

Since the name is non-NULL, it proceeds to call led_trigger_event() on the
unregistered trigger. Could this result in a NULL pointer dereference,
as the led_cdevs list head within the zero-initialized led_trigger
structure is uninitialized?

> +
> +	/* Query initial LED state for all PIs so already-active ports
> +	 * are reflected immediately without waiting for a hardware event.
> +	 */
> +	for (i = 0; i < pcdev->nr_lines; i++) {
> +		if (pcdev->no_of_pse_pi || pcdev->pi[i].np)
> +			pse_led_update(pcdev, i);
> +	}

The docstring for pse_led_update() specifies that it "Must be called with
pcdev->lock held."

Since this loop calls pse_led_update(pcdev, i) without acquiring
pcdev->lock, and the PI regulators have already been registered and exposed
to consumers earlier in this function, can this race with a concurrent
regulator_enable()?

A concurrent regulator_enable() can trigger pse_pi_enable(), which acquires
the lock and also calls pse_led_update(). This could result in unprotected
calls to the pi_get_pw_status and pi_get_admin_state hardware callbacks,
and concurrent writes to the last_delivering and last_enabled variables.

> +
>  	mutex_lock(&pse_list_mutex);
>  	list_add(&pcdev->list, &pse_controller_list);
>  	mutex_unlock(&pse_list_mutex);

^ permalink raw reply

* Re: [PATCH net-next v3 00/12] BIG TCP for UDP tunnels
From: Jakub Kicinski @ 2026-04-13 22:55 UTC (permalink / raw)
  To: Alice Mikityanska
  Cc: Daniel Borkmann, David S. Miller, Eric Dumazet, Paolo Abeni,
	Xin Long, Willem de Bruijn, David Ahern, Nikolay Aleksandrov,
	Shuah Khan, Stanislav Fomichev, Andrew Lunn, Simon Horman,
	Florian Westphal, netdev, Alice Mikityanska
In-Reply-To: <20260410150943.993350-1-alice.kernel@fastmail.im>

On Fri, 10 Apr 2026 18:09:31 +0300 Alice Mikityanska wrote:
> This series is a follow-up to "BIG TCP without HBH in IPv6", and it adds
> support for BIG TCP IPv4/IPv6 workloads in vxlan and geneve. Now that
> IPv6 BIG TCP doesn't require stripping the HBH in all various
> combinations in tunneled traffic, adding BIG TCP becomes feasible.

No longer applies, sorry :( 
We'll have to revisit after the merge window.
-- 
pw-bot: cr

^ permalink raw reply

* Re: [PATCH net] net: airoha: Add missing bits in airoha_qdma_cleanup_tx_queue()
From: Jakub Kicinski @ 2026-04-13 22:57 UTC (permalink / raw)
  To: lorenzo
  Cc: Jakub Kicinski, andrew+netdev, davem, edumazet, pabeni,
	linux-arm-kernel, linux-mediatek, netdev
In-Reply-To: <20260410-airoha_qdma_cleanup_tx_queue-fix-net-v1-1-b7171c8f1e78@kernel.org>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
net: airoha: Add missing bits in airoha_qdma_cleanup_tx_queue()

This commit resets DMA TX descriptors in airoha_qdma_cleanup_tx_queue
and synchronizes TX_DMA_IDX to TX_CPU_IDX to notify the hardware that
the ring is empty.

> diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
> index 9285a68f435fe..963ab7b8d166b 100644
> --- a/drivers/net/ethernet/airoha/airoha_eth.c
> +++ b/drivers/net/ethernet/airoha/airoha_eth.c
> @@ -1044,13 +1044,17 @@ static int airoha_qdma_init_tx(struct airoha_qdma *qdma)
[ ... ]
>  	spin_lock_bh(&q->lock);
>  	for (i = 0; i < q->ndesc; i++) {
> -		struct airoha_queue_entry *e = &q->entry[i];
> +		struct airoha_qdma_desc *desc = &q->desc[i];
>  
> +		e = &q->entry[i];

Can this result in a NULL pointer dereference?

If airoha_qdma_init_tx_queue() sets q->ndesc before allocating q->entry and
q->desc, and devm_kzalloc() fails, the error path jumps to
airoha_hw_cleanup().

Because q->ndesc > 0, this cleanup loop would execute and dereference
q->entry[i] and q->desc[i], which may not have been allocated.

[ ... ]
> +		/* Reset DMA descriptor */
> +		WRITE_ONCE(desc->ctrl, 0);
> +		WRITE_ONCE(desc->addr, 0);
> +		WRITE_ONCE(desc->data, 0);
> +		WRITE_ONCE(desc->msg0, 0);
> +		WRITE_ONCE(desc->msg1, 0);
> +		WRITE_ONCE(desc->msg2, 0);

Is it safe to modify these DMA descriptors and reset the ring indices below
without waiting for the hardware DMA engine to become idle?

In airoha_dev_stop(), the driver clears GLOBAL_CFG_TX_DMA_EN_MASK to request
the hardware DMA engine to stop, but it does not appear to poll
GLOBAL_CFG_TX_DMA_BUSY_MASK to ensure it has actually stopped.

Modifying the DMA descriptors and internal ring indices while the hardware
is still actively processing in-flight descriptors could potentially lead
to corrupted DMA fetches or IOMMU faults.

>  		q->queued--;
>  	}
> +
> +	e = list_first_entry(&q->tx_list, struct airoha_queue_entry,
> +			     list);
> +	index = e - q->entry;
> +	/* Set TX_DMA_IDX to TX_CPU_IDX to notify the hw the QDMA TX ring is
> +	 * empty.
> +	 */
> +	airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), TX_RING_CPU_IDX_MASK,
> +			FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
> +	airoha_qdma_rmw(qdma, REG_TX_DMA_IDX(qid), TX_RING_DMA_IDX_MASK,
> +			FIELD_PREP(TX_RING_DMA_IDX_MASK, index));

Could list_first_entry() be called on an empty list here?

If q->tx_list is empty (for example, if allocation failed in
airoha_qdma_init_tx_queue or if no entries had a valid dma_addr), calling
list_first_entry() returns an invalid pointer.

The subsequent pointer arithmetic would produce a garbage index value,
which is then written to the REG_TX_CPU_IDX and REG_TX_DMA_IDX registers.
-- 
pw-bot: cr

^ permalink raw reply

* Re: [PATCH v2] udp: Force compute_score to always inline
From: patchwork-bot+netdevbpf @ 2026-04-13 23:00 UTC (permalink / raw)
  To: Gabriel Krisman Bertazi
  Cc: willemdebruijn.kernel, davem, dsahern, edumazet, kuba, pabeni,
	kuniyu, horms, netdev, willemb
In-Reply-To: <20260410155936.654915-1-krisman@suse.de>

Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Fri, 10 Apr 2026 11:59:36 -0400 you wrote:
> Back in 2024 I reported a 7-12% regression on an iperf3 UDP loopback
> thoughput test that we traced to the extra overhead of calling
> compute_score on two places, introduced by commit f0ea27e7bfe1 ("udp:
> re-score reuseport groups when connected sockets are present").  At the
> time, I pointed out the overhead was caused by the multiple calls,
> associated with cpu-specific mitigations, and merged commit
> 50aee97d1511 ("udp: Avoid call to compute_score on multiple sites") to
> jump back explicitly, to force the rescore call in a single place.
> 
> [...]

Here is the summary with links:
  - [v2] udp: Force compute_score to always inline
    https://git.kernel.org/netdev/net-next/c/b80a95ccf160

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH net] net/sched: taprio: fix use-after-free in advance_sched() on schedule switch
From: Jakub Kicinski @ 2026-04-13 23:01 UTC (permalink / raw)
  To: vinicius.gomes
  Cc: Jakub Kicinski, vladimir.oltean, jhs, jiri, davem, edumazet,
	pabeni, horms, netdev, linux-kernel, qjx1298677004
In-Reply-To: <20260410-taprio-user-after-free-fix-net-v1-1-0931b1579988@intel.com>

This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
net/sched: taprio: fix use-after-free in advance_sched() on schedule switch

This commit updates advance_sched() to select the next entry from the new
oper schedule immediately after switch_schedules() returns. It relies on the
pre-calculated end_time of the new schedule's first entry instead of
overwriting it with the admin schedule's base time.

> diff --git a/net/sched/sch_taprio.c b/net/sched/sch_taprio.c
> index f721c03514f60..0316f2dee06ac 100644
> --- a/net/sched/sch_taprio.c
> +++ b/net/sched/sch_taprio.c

[ ... ]

> @@ -972,11 +972,12 @@ static enum hrtimer_restart advance_sched(struct hrtimer *timer)
>  	}
>  
>  	if (should_change_schedules(admin, oper, end_time)) {
> -		/* Set things so the next time this runs, the new
> -		 * schedule runs.
> -		 */
> -		end_time = sched_base_time(admin);

Does removing this assignment introduce a regression where the new schedule
activates prematurely?

Since the new schedule's first entry has its end_time pre-calculated
as base_time + interval, if we activate it early (before its actual
base_time), does it stretch the entry backwards in time?

Could this cause its gate mask to apply during the time gap, violating the
strictly configured gate durations?

>  		switch_schedules(q, &admin, &oper);

Can this sequence cause a use-after-free regression due to the RCU grace
period starting too early?

Inside switch_schedules(), call_rcu() is invoked on the old oper
schedule. However, q->current_entry is not updated until later in
advance_sched() at the first_run label:

first_run:
	rcu_assign_pointer(q->current_entry, next);

If a concurrent reader calls rcu_dereference(q->current_entry) between
switch_schedules() and this assignment, can it acquire a pointer to the
old schedule after call_rcu() has already started? This would mean the
grace period will not wait for this new reader.

As a separate pre-existing issue, can switch_schedules() be called
concurrently by lockless readers?

If advance_sched() calls it under q->current_entry_lock, but a concurrent
reader like get_packet_txtime() evaluates the switch condition and calls
switch_schedules() without holding locks, can they race?

Could this lead to call_rcu() being called twice on the same old oper
object, potentially corrupting the RCU callback list?

> +		/* After changing schedules, the next entry is the first one
> +		 * in the new schedule, with a pre-calculated end_time.
> +		 */
> +		next = list_first_entry(&oper->entries, struct sched_entry, list);
> +		end_time = next->end_time;
>  	}
>  
>  	next->end_time = end_time;

^ permalink raw reply

* Re: [PATCH net] bnge: return after auxiliary_device_uninit() in error path
From: patchwork-bot+netdevbpf @ 2026-04-13 23:10 UTC (permalink / raw)
  To: Greg KH
  Cc: netdev, linux-kernel, vikas.gupta, andrew+netdev, davem, edumazet,
	kuba, pabeni, stable
In-Reply-To: <2026041124-banshee-molecular-0f70@gregkh>

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Sat, 11 Apr 2026 12:45:25 +0200 you wrote:
> When auxiliary_device_add() fails, the error block calls
> auxiliary_device_uninit() but does not return.  The uninit drops the
> last reference and synchronously runs bnge_aux_dev_release(), which sets
> bd->auxr_dev = NULL and frees the underlying object.  The subsequent
> bd->auxr_dev->net = bd->netdev then dereferences NULL, which is not a
> good thing to have happen when trying to clean up from an error.
> 
> [...]

Here is the summary with links:
  - [net] bnge: return after auxiliary_device_uninit() in error path
    https://git.kernel.org/netdev/net/c/8b0c25528cb6

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH v1 net] tcp: Don't set treq->req_usec_ts in cookie_tcp_reqsk_init().
From: patchwork-bot+netdevbpf @ 2026-04-13 23:10 UTC (permalink / raw)
  To: Kuniyuki Iwashima
  Cc: edumazet, ncardwell, davem, kuba, pabeni, horms, kuni1840, netdev
In-Reply-To: <20260410235328.1773449-1-kuniyu@google.com>

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Fri, 10 Apr 2026 23:53:27 +0000 you wrote:
> Commit de5626b95e13 ("tcp: Factorise cookie-independent fields
> initialisation in cookie_v[46]_check().") miscategorised
> tcp_rsk(req)->req_usec_ts init to cookie_tcp_reqsk_init(),
> which is used by both BPF/non-BPF SYN cookie reqsk.
> 
> Rather, it should have been moved to cookie_tcp_reqsk_alloc() by
> commit 8e7bab6b9652 ("tcp: Factorise cookie-dependent fields
> initialisation in cookie_v[46]_check()") so that only non-BPF SYN
> cookie sets tcp_rsk(req)->req_usec_ts to false.
> 
> [...]

Here is the summary with links:
  - [v1,net] tcp: Don't set treq->req_usec_ts in cookie_tcp_reqsk_init().
    https://git.kernel.org/netdev/net/c/c058bbf05b11

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH iwl-net] ice: fix infinite recursion in ice_cfg_tx_topo via ice_init_dev_hw
From: Jacob Keller @ 2026-04-13 23:43 UTC (permalink / raw)
  To: Petr Oros, netdev
  Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Aleksandr Loktionov,
	Nikolay Aleksandrov, Daniel Zahka, Paul Greenwalt, Dave Ertman,
	Michal Swiatkowski, intel-wired-lan, linux-kernel
In-Reply-To: <20260413191420.3524013-1-poros@redhat.com>

On 4/13/2026 12:14 PM, Petr Oros wrote:
> On certain E810 configurations where firmware supports Tx scheduler
> topology switching (tx_sched_topo_comp_mode_en), ice_cfg_tx_topo()
> may need to apply a new 5-layer or 9-layer topology from the DDP
> package. If the AQ command to set the topology fails (e.g. due to
> invalid DDP data or firmware limitations), the global configuration
> lock must still be cleared via a CORER reset.
> 
> Commit 86aae43f21cf ("ice: don't leave device non-functional if Tx
> scheduler config fails") correctly fixed this by refactoring
> ice_cfg_tx_topo() to always trigger CORER after acquiring the global
> lock and re-initialize hardware via ice_init_hw() afterwards.
> 
> However, commit 8a37f9e2ff40 ("ice: move ice_deinit_dev() to the end
> of deinit paths") later moved ice_init_dev_hw() into ice_init_hw(),
> breaking the reinit path introduced by 86aae43f21cf. This creates an
> infinite recursive call chain:
> 
>   ice_init_hw()
>     ice_init_dev_hw()
>       ice_cfg_tx_topo()         # topology change needed
>         ice_deinit_hw()
>         ice_init_hw()           # reinit after CORER
>           ice_init_dev_hw()     # recurse
>             ice_cfg_tx_topo()
>               ...               # stack overflow
> 

Oof, ya thats not good. I guess this only happens if the topology needs
to change, so it wouldn't affect many systems where we had already
changed the topology before hand on the old driver.

> Fix by moving ice_init_dev_hw() back out of ice_init_hw() and calling
> it explicitly from ice_probe() and ice_devlink_reinit_up(). The third
> caller, ice_cfg_tx_topo(), intentionally does not need ice_init_dev_hw()
> during its reinit, it only needs the core HW reinitialization. This
> breaks the recursion cleanly without adding flags or guards.
> 
> The deinit ordering changes from commit 8a37f9e2ff40 ("ice: move
> ice_deinit_dev() to the end of deinit paths") which fixed slow rmmod
> are preserved, only the init-side placement of ice_init_dev_hw() is
> reverted.
> 
> Fixes: 8a37f9e2ff40 ("ice: move ice_deinit_dev() to the end of deinit paths")
> Signed-off-by: Petr Oros <poros@redhat.com>

The fix looks correct to me, and definitely the most elegant.

Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>

^ permalink raw reply

* Re: [PATCH] net: phy: realtek: use LEDCR page number define on RTL8211F
From: patchwork-bot+netdevbpf @ 2026-04-13 23:50 UTC (permalink / raw)
  To: Aleksander Jan Bajkowski
  Cc: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, daniel,
	vladimir.oltean, michael, daniel.braunwarth, ih, rmk+kernel,
	netdev, linux-kernel
In-Reply-To: <20260411105150.184577-1-olek2@wp.pl>

Hello:

This patch was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Sat, 11 Apr 2026 12:51:45 +0200 you wrote:
> Replace the magic number with an existing define for the LEDCR
> register page number on the RTL8211F.
> 
> Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
> ---
>  drivers/net/phy/realtek/realtek_main.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)

Here is the summary with links:
  - net: phy: realtek: use LEDCR page number define on RTL8211F
    https://git.kernel.org/netdev/net-next/c/43a2deae3661

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH net-next v2 0/2] net: dsa: mxl862xx: add statistics support
From: patchwork-bot+netdevbpf @ 2026-04-13 23:50 UTC (permalink / raw)
  To: Daniel Golle
  Cc: andrew, olteanv, davem, edumazet, kuba, pabeni, linux, netdev,
	linux-kernel, frankwu, chad, cezary.wilmanski, lxu, yweng, jverdu,
	ajayaraman, john
In-Reply-To: <cover.1775951347.git.daniel@makrotopia.org>

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Sun, 12 Apr 2026 01:01:48 +0100 you wrote:
> Add per-port RMON statistics support for the MxL862xx DSA driver,
> covering hardware-specific ethtool -S counters, standard IEEE 802.3
> MAC/ctrl/pause statistics, and rtnl_link_stats64 via polled 64-bit
> accumulation.
> 
> Changes since v1:
>  * trim mxl862xx_mib[] to counters not covered elsewhere only
>  * remove histogram counters (moved to .get_rmon_stats)
>  * remove RMON error counters (moved to .get_rmon_stats)
>  * remove counters already in .get_eth_mac_stats
>  * remove counters already in .get_stats64
>  * add mxl862xx_rmon_ranges[] and mxl862xx_get_rmon_stats()
> 
> [...]

Here is the summary with links:
  - [net-next,v2,1/2] net: dsa: mxl862xx: add ethtool statistics support
    https://git.kernel.org/netdev/net-next/c/e6295d124644
  - [net-next,v2,2/2] net: dsa: mxl862xx: implement .get_stats64
    https://git.kernel.org/netdev/net-next/c/a21d33a5265f

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply

* Re: [PATCH net-next v18 00/15] Begin upstreaming Homa transport protocol
From: John Ousterhout @ 2026-04-13 23:54 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: netdev, pabeni, edumazet, horms
In-Reply-To: <20260412134531.21341692@kernel.org>

On Sun, Apr 12, 2026 at 1:45 PM Jakub Kicinski <kuba@kernel.org> wrote:
>
> On Fri, 10 Apr 2026 13:02:54 -0700 John Ousterhout wrote:
> > This patch series begins the process of upstreaming the Homa transport
> > protocol. Homa is an alternative to TCP for use in datacenter
> > environments. It provides 10-100x reductions in tail latency for short
> > messages relative to TCP. Its benefits are greatest for mixed workloads
> > containing both short and long messages running under high network loads.
> > Homa is not API-compatible with TCP: it is connectionless and message-
> > oriented (but still reliable and flow-controlled). Homa's new API not
> > only contributes to its performance gains, but it also eliminates the
> > massive amount of connection state required by TCP for highly connected
> > datacenter workloads (Homa uses ~ 1 socket per application, whereas
> > TCP requires a separate socket for each peer).
>
> make coccicheck says:
>
> net/homa/homa_peer.c:213:21-22: WARNING opportunity for swap()

Fixed.

^ permalink raw reply

* Re: [PATCH net-next 5/5] selftests: ovpn: align command flow with TAP
From: Jakub Kicinski @ 2026-04-13 23:56 UTC (permalink / raw)
  To: antonio
  Cc: Jakub Kicinski, netdev, ralf, sd, pabeni, andrew+netdev, davem,
	edumazet
In-Reply-To: <20260412221121.410365-6-antonio@openvpn.net>

This is an AI-generated review of your patch. The human sending this
email says: "The second one looks legit, would you prefer to follow
up or respin?"
---
selftests: ovpn: align command flow with TAP

This commit restructures the ovpn selftests to use the TAP infrastructure,
splitting each test into stages with KTAP output, adding command wrappers,
and centralizing behavior control in common.sh.

> diff --git a/tools/testing/selftests/net/ovpn/common.sh b/tools/testing/selftests/net/ovpn/common.sh
> index 2b3f2e5c8cc9d..ec6fea37ceb39 100644
> --- a/tools/testing/selftests/net/ovpn/common.sh
> +++ b/tools/testing/selftests/net/ovpn/common.sh

[ ... ]

> @@ -152,8 +263,8 @@ ovpn_compare_ntfs() {
>  		received="${OVPN_TMP_JSONS[$1]}"
>  		diff_file=$(mktemp)
>  
> -		kill -TERM ${OVPN_LISTENER_PIDS[$1]} || true
> -		wait ${OVPN_LISTENER_PIDS[$1]} || true
> +		kill -TERM ${OVPN_LISTENER_PIDS[$1]} 2>/dev/null || true
> +		wait ${OVPN_LISTENER_PIDS[$1]} 2>/dev/null || true
>  		printf "Checking notifications for peer ${1}... "

Does this leave the reaped PID in OVPN_LISTENER_PIDS?

Later, ovpn_cleanup() calls ovpn_stop_listener() which iterates over the
array and issues another kill -TERM on the same PID. Since the process was
already reaped by the wait here, could the OS recycle the PID, potentially
causing the second kill to terminate an unrelated system process?

[ ... ]

> +ovpn_cleanup_peer_ns() {
> +	local peer="$1"
> +
> +	if ! ip netns list | grep -qx "${peer}"; then
> +		return 0
> +	fi

Can this fail to match and permanently leak network namespaces?

When virtual interfaces are moved into namespaces during setup, ip netns list
often includes an internal ID in its output, such as:
peer0 (id: 0)

Because grep is using the -x flag to enforce an exact whole-line match,
it appears this will fail to match peer0 and return early, skipping the
subsequent namespace deletion.

[ ... ]

> diff --git a/tools/testing/selftests/net/ovpn/test-close-socket.sh b/tools/testing/selftests/net/ovpn/test-close-socket.sh
> index 4f0367c60fdaf..e97affe727383 100755
> --- a/tools/testing/selftests/net/ovpn/test-close-socket.sh
> +++ b/tools/testing/selftests/net/ovpn/test-close-socket.sh
> @@ -9,37 +9,72 @@ set -e
>  
>  source ./common.sh

Is test-close-socket.sh missing the set -eE flag and the ovpn_stage_err
ERR trap?

The other test scripts were updated to use set -eE and register the trap,
which handles emitting the KTAP failure directive. If a command fails here,
will set -e cause the script to exit immediately and bypass the KTAP
failure reporting entirely?

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox