From: Sasha Levin Date: Sat, 18 Jan 2025 17:23:26 +0000 (-0500) Subject: Fixes for 6.12 X-Git-Tag: v6.1.126~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c1644bf8e8c2fdc1e5c24121d9f293865c9e53d2;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.12 Signed-off-by: Sasha Levin --- diff --git a/queue-6.12/bpf-fix-bpf_sk_select_reuseport-memory-leak.patch b/queue-6.12/bpf-fix-bpf_sk_select_reuseport-memory-leak.patch new file mode 100644 index 0000000000..4667f1e4ea --- /dev/null +++ b/queue-6.12/bpf-fix-bpf_sk_select_reuseport-memory-leak.patch @@ -0,0 +1,112 @@ +From bf86ba00e5c71f0b2bbce7c3a95b15b71c46334f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Jan 2025 14:21:55 +0100 +Subject: bpf: Fix bpf_sk_select_reuseport() memory leak + +From: Michal Luczaj + +[ Upstream commit b3af60928ab9129befa65e6df0310d27300942bf ] + +As pointed out in the original comment, lookup in sockmap can return a TCP +ESTABLISHED socket. Such TCP socket may have had SO_ATTACH_REUSEPORT_EBPF +set before it was ESTABLISHED. In other words, a non-NULL sk_reuseport_cb +does not imply a non-refcounted socket. + +Drop sk's reference in both error paths. + +unreferenced object 0xffff888101911800 (size 2048): + comm "test_progs", pid 44109, jiffies 4297131437 + hex dump (first 32 bytes): + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 80 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace (crc 9336483b): + __kmalloc_noprof+0x3bf/0x560 + __reuseport_alloc+0x1d/0x40 + reuseport_alloc+0xca/0x150 + reuseport_attach_prog+0x87/0x140 + sk_reuseport_attach_bpf+0xc8/0x100 + sk_setsockopt+0x1181/0x1990 + do_sock_setsockopt+0x12b/0x160 + __sys_setsockopt+0x7b/0xc0 + __x64_sys_setsockopt+0x1b/0x30 + do_syscall_64+0x93/0x180 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 64d85290d79c ("bpf: Allow bpf_map_lookup_elem for SOCKMAP and SOCKHASH") +Signed-off-by: Michal Luczaj +Reviewed-by: Martin KaFai Lau +Link: https://patch.msgid.link/20250110-reuseport-memleak-v1-1-fa1ddab0adfe@rbox.co +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 30 ++++++++++++++++++------------ + 1 file changed, 18 insertions(+), 12 deletions(-) + +diff --git a/net/core/filter.c b/net/core/filter.c +index 54a53fae9e98f..46da488ff0703 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -11263,6 +11263,7 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern, + bool is_sockarray = map->map_type == BPF_MAP_TYPE_REUSEPORT_SOCKARRAY; + struct sock_reuseport *reuse; + struct sock *selected_sk; ++ int err; + + selected_sk = map->ops->map_lookup_elem(map, key); + if (!selected_sk) +@@ -11270,10 +11271,6 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern, + + reuse = rcu_dereference(selected_sk->sk_reuseport_cb); + if (!reuse) { +- /* Lookup in sock_map can return TCP ESTABLISHED sockets. */ +- if (sk_is_refcounted(selected_sk)) +- sock_put(selected_sk); +- + /* reuseport_array has only sk with non NULL sk_reuseport_cb. + * The only (!reuse) case here is - the sk has already been + * unhashed (e.g. by close()), so treat it as -ENOENT. +@@ -11281,24 +11278,33 @@ BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern, + * Other maps (e.g. sock_map) do not provide this guarantee and + * the sk may never be in the reuseport group to begin with. + */ +- return is_sockarray ? -ENOENT : -EINVAL; ++ err = is_sockarray ? -ENOENT : -EINVAL; ++ goto error; + } + + if (unlikely(reuse->reuseport_id != reuse_kern->reuseport_id)) { + struct sock *sk = reuse_kern->sk; + +- if (sk->sk_protocol != selected_sk->sk_protocol) +- return -EPROTOTYPE; +- else if (sk->sk_family != selected_sk->sk_family) +- return -EAFNOSUPPORT; +- +- /* Catch all. Likely bound to a different sockaddr. */ +- return -EBADFD; ++ if (sk->sk_protocol != selected_sk->sk_protocol) { ++ err = -EPROTOTYPE; ++ } else if (sk->sk_family != selected_sk->sk_family) { ++ err = -EAFNOSUPPORT; ++ } else { ++ /* Catch all. Likely bound to a different sockaddr. */ ++ err = -EBADFD; ++ } ++ goto error; + } + + reuse_kern->selected_sk = selected_sk; + + return 0; ++error: ++ /* Lookup in sock_map can return TCP ESTABLISHED sockets. */ ++ if (sk_is_refcounted(selected_sk)) ++ sock_put(selected_sk); ++ ++ return err; + } + + static const struct bpf_func_proto sk_select_reuseport_proto = { +-- +2.39.5 + diff --git a/queue-6.12/btrfs-add-the-missing-error-handling-inside-get_cano.patch b/queue-6.12/btrfs-add-the-missing-error-handling-inside-get_cano.patch new file mode 100644 index 0000000000..1b826bee58 --- /dev/null +++ b/queue-6.12/btrfs-add-the-missing-error-handling-inside-get_cano.patch @@ -0,0 +1,44 @@ +From e3209b40abc256afb1bf6d333855af2f3a448e8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2025 14:14:04 +1030 +Subject: btrfs: add the missing error handling inside get_canonical_dev_path + +From: Qu Wenruo + +[ Upstream commit fe4de594f7a2e9bc49407de60fbd20809fad4192 ] + +Inside function get_canonical_dev_path(), we call d_path() to get the +final device path. + +But d_path() can return error, and in that case the next strscpy() call +will trigger an invalid memory access. + +Add back the missing error handling for d_path(). + +Reported-by: Boris Burkov +Fixes: 7e06de7c83a7 ("btrfs: canonicalize the device path before adding it") +Signed-off-by: Qu Wenruo +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/volumes.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c +index 0c4d14c59ebec..395b8b880ce78 100644 +--- a/fs/btrfs/volumes.c ++++ b/fs/btrfs/volumes.c +@@ -797,6 +797,10 @@ static int get_canonical_dev_path(const char *dev_path, char *canonical) + if (ret) + goto out; + resolved_path = d_path(&path, path_buf, PATH_MAX); ++ if (IS_ERR(resolved_path)) { ++ ret = PTR_ERR(resolved_path); ++ goto out; ++ } + ret = strscpy(canonical, resolved_path, PATH_MAX); + out: + kfree(path_buf); +-- +2.39.5 + diff --git a/queue-6.12/cpufreq-move-endif-to-the-end-of-kconfig-file.patch b/queue-6.12/cpufreq-move-endif-to-the-end-of-kconfig-file.patch new file mode 100644 index 0000000000..5ee96e453e --- /dev/null +++ b/queue-6.12/cpufreq-move-endif-to-the-end-of-kconfig-file.patch @@ -0,0 +1,48 @@ +From 81762656f37ef8ad57ec798405377b45a893ec61 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Jan 2025 11:23:10 +0530 +Subject: cpufreq: Move endif to the end of Kconfig file + +From: Viresh Kumar + +[ Upstream commit 7e265fc04690d449a40b413b0348b15c748cea6f ] + +It is possible to enable few cpufreq drivers, without the framework +being enabled. This happened due to a bug while moving the entries +earlier. Fix it. + +Fixes: 7ee1378736f0 ("cpufreq: Move CPPC configs to common Kconfig and add RISC-V") +Signed-off-by: Viresh Kumar +Reviewed-by: Pierre Gondois +Reviewed-by: Sunil V L +Reviewed-by: Sudeep Holla +Link: https://patch.msgid.link/84ac7a8fa72a8fe20487bb0a350a758bce060965.1736488384.git.viresh.kumar@linaro.org +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/Kconfig | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig +index 2561b215432a8..588ab1cc6d557 100644 +--- a/drivers/cpufreq/Kconfig ++++ b/drivers/cpufreq/Kconfig +@@ -311,8 +311,6 @@ config QORIQ_CPUFREQ + This adds the CPUFreq driver support for Freescale QorIQ SoCs + which are capable of changing the CPU's frequency dynamically. + +-endif +- + config ACPI_CPPC_CPUFREQ + tristate "CPUFreq driver based on the ACPI CPPC spec" + depends on ACPI_PROCESSOR +@@ -341,4 +339,6 @@ config ACPI_CPPC_CPUFREQ_FIE + + If in doubt, say N. + ++endif ++ + endmenu +-- +2.39.5 + diff --git a/queue-6.12/cpuidle-teo-update-documentation-after-previous-chan.patch b/queue-6.12/cpuidle-teo-update-documentation-after-previous-chan.patch new file mode 100644 index 0000000000..db8d8bf648 --- /dev/null +++ b/queue-6.12/cpuidle-teo-update-documentation-after-previous-chan.patch @@ -0,0 +1,163 @@ +From c81ea42a9926a06754cae3a300b94a34b8c15fd7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Jan 2025 13:48:10 +0100 +Subject: cpuidle: teo: Update documentation after previous changes + +From: Rafael J. Wysocki + +[ Upstream commit 5a597a19a2148d1c5cd987907a60c042ab0f62d5 ] + +After previous changes, the description of the teo governor in the +documentation comment does not match the code any more, so update it +as appropriate. + +Fixes: 449914398083 ("cpuidle: teo: Remove recent intercepts metric") +Fixes: 2662342079f5 ("cpuidle: teo: Gather statistics regarding whether or not to stop the tick") +Fixes: 6da8f9ba5a87 ("cpuidle: teo: Skip tick_nohz_get_sleep_length() call in some cases") +Signed-off-by: Rafael J. Wysocki +Reviewed-by: Christian Loehle +Link: https://patch.msgid.link/6120335.lOV4Wx5bFT@rjwysocki.net +[ rjw: Corrected 3 typos found by Christian ] +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/cpuidle/governors/teo.c | 91 +++++++++++++++++---------------- + 1 file changed, 48 insertions(+), 43 deletions(-) + +diff --git a/drivers/cpuidle/governors/teo.c b/drivers/cpuidle/governors/teo.c +index f2992f92d8db8..173ddcac540ad 100644 +--- a/drivers/cpuidle/governors/teo.c ++++ b/drivers/cpuidle/governors/teo.c +@@ -10,25 +10,27 @@ + * DOC: teo-description + * + * The idea of this governor is based on the observation that on many systems +- * timer events are two or more orders of magnitude more frequent than any +- * other interrupts, so they are likely to be the most significant cause of CPU +- * wakeups from idle states. Moreover, information about what happened in the +- * (relatively recent) past can be used to estimate whether or not the deepest +- * idle state with target residency within the (known) time till the closest +- * timer event, referred to as the sleep length, is likely to be suitable for +- * the upcoming CPU idle period and, if not, then which of the shallower idle +- * states to choose instead of it. ++ * timer interrupts are two or more orders of magnitude more frequent than any ++ * other interrupt types, so they are likely to dominate CPU wakeup patterns. ++ * Moreover, in principle, the time when the next timer event is going to occur ++ * can be determined at the idle state selection time, although doing that may ++ * be costly, so it can be regarded as the most reliable source of information ++ * for idle state selection. + * +- * Of course, non-timer wakeup sources are more important in some use cases +- * which can be covered by taking a few most recent idle time intervals of the +- * CPU into account. However, even in that context it is not necessary to +- * consider idle duration values greater than the sleep length, because the +- * closest timer will ultimately wake up the CPU anyway unless it is woken up +- * earlier. ++ * Of course, non-timer wakeup sources are more important in some use cases, ++ * but even then it is generally unnecessary to consider idle duration values ++ * greater than the time time till the next timer event, referred as the sleep ++ * length in what follows, because the closest timer will ultimately wake up the ++ * CPU anyway unless it is woken up earlier. + * +- * Thus this governor estimates whether or not the prospective idle duration of +- * a CPU is likely to be significantly shorter than the sleep length and selects +- * an idle state for it accordingly. ++ * However, since obtaining the sleep length may be costly, the governor first ++ * checks if it can select a shallow idle state using wakeup pattern information ++ * from recent times, in which case it can do without knowing the sleep length ++ * at all. For this purpose, it counts CPU wakeup events and looks for an idle ++ * state whose target residency has not exceeded the idle duration (measured ++ * after wakeup) in the majority of relevant recent cases. If the target ++ * residency of that state is small enough, it may be used right away and the ++ * sleep length need not be determined. + * + * The computations carried out by this governor are based on using bins whose + * boundaries are aligned with the target residency parameter values of the CPU +@@ -39,7 +41,11 @@ + * idle state 2, the third bin spans from the target residency of idle state 2 + * up to, but not including, the target residency of idle state 3 and so on. + * The last bin spans from the target residency of the deepest idle state +- * supplied by the driver to infinity. ++ * supplied by the driver to the scheduler tick period length or to infinity if ++ * the tick period length is less than the target residency of that state. In ++ * the latter case, the governor also counts events with the measured idle ++ * duration between the tick period length and the target residency of the ++ * deepest idle state. + * + * Two metrics called "hits" and "intercepts" are associated with each bin. + * They are updated every time before selecting an idle state for the given CPU +@@ -49,47 +55,46 @@ + * sleep length and the idle duration measured after CPU wakeup fall into the + * same bin (that is, the CPU appears to wake up "on time" relative to the sleep + * length). In turn, the "intercepts" metric reflects the relative frequency of +- * situations in which the measured idle duration is so much shorter than the +- * sleep length that the bin it falls into corresponds to an idle state +- * shallower than the one whose bin is fallen into by the sleep length (these +- * situations are referred to as "intercepts" below). ++ * non-timer wakeup events for which the measured idle duration falls into a bin ++ * that corresponds to an idle state shallower than the one whose bin is fallen ++ * into by the sleep length (these events are also referred to as "intercepts" ++ * below). + * + * In order to select an idle state for a CPU, the governor takes the following + * steps (modulo the possible latency constraint that must be taken into account + * too): + * +- * 1. Find the deepest CPU idle state whose target residency does not exceed +- * the current sleep length (the candidate idle state) and compute 2 sums as +- * follows: ++ * 1. Find the deepest enabled CPU idle state (the candidate idle state) and ++ * compute 2 sums as follows: + * +- * - The sum of the "hits" and "intercepts" metrics for the candidate state +- * and all of the deeper idle states (it represents the cases in which the +- * CPU was idle long enough to avoid being intercepted if the sleep length +- * had been equal to the current one). ++ * - The sum of the "hits" metric for all of the idle states shallower than ++ * the candidate one (it represents the cases in which the CPU was likely ++ * woken up by a timer). + * +- * - The sum of the "intercepts" metrics for all of the idle states shallower +- * than the candidate one (it represents the cases in which the CPU was not +- * idle long enough to avoid being intercepted if the sleep length had been +- * equal to the current one). ++ * - The sum of the "intercepts" metric for all of the idle states shallower ++ * than the candidate one (it represents the cases in which the CPU was ++ * likely woken up by a non-timer wakeup source). + * +- * 2. If the second sum is greater than the first one the CPU is likely to wake +- * up early, so look for an alternative idle state to select. ++ * 2. If the second sum computed in step 1 is greater than a half of the sum of ++ * both metrics for the candidate state bin and all subsequent bins(if any), ++ * a shallower idle state is likely to be more suitable, so look for it. + * +- * - Traverse the idle states shallower than the candidate one in the ++ * - Traverse the enabled idle states shallower than the candidate one in the + * descending order. + * + * - For each of them compute the sum of the "intercepts" metrics over all + * of the idle states between it and the candidate one (including the + * former and excluding the latter). + * +- * - If each of these sums that needs to be taken into account (because the +- * check related to it has indicated that the CPU is likely to wake up +- * early) is greater than a half of the corresponding sum computed in step +- * 1 (which means that the target residency of the state in question had +- * not exceeded the idle duration in over a half of the relevant cases), +- * select the given idle state instead of the candidate one. ++ * - If this sum is greater than a half of the second sum computed in step 1, ++ * use the given idle state as the new candidate one. + * +- * 3. By default, select the candidate state. ++ * 3. If the current candidate state is state 0 or its target residency is short ++ * enough, return it and prevent the scheduler tick from being stopped. ++ * ++ * 4. Obtain the sleep length value and check if it is below the target ++ * residency of the current candidate state, in which case a new shallower ++ * candidate state needs to be found, so look for it. + */ + + #include +-- +2.39.5 + diff --git a/queue-6.12/drm-tests-helpers-fix-compiler-warning.patch b/queue-6.12/drm-tests-helpers-fix-compiler-warning.patch new file mode 100644 index 0000000000..5294750200 --- /dev/null +++ b/queue-6.12/drm-tests-helpers-fix-compiler-warning.patch @@ -0,0 +1,45 @@ +From e118e0787c354ebc3af802df44471ad75c49840c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Jan 2025 00:51:33 +0800 +Subject: drm/tests: helpers: Fix compiler warning + +From: Yu-Chun Lin + +[ Upstream commit b9097e4c8bf3934e4e07e6f9b88741957fef351e ] + +Delete one line break to make the format correct, resolving the +following warning during a W=1 build: + +>> drivers/gpu/drm/tests/drm_kunit_helpers.c:324: warning: bad line: for a KUnit test + +Fixes: caa714f86699 ("drm/tests: helpers: Add helper for drm_display_mode_from_cea_vic()") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202501032001.O6WY1VCW-lkp@intel.com/ +Reviewed-by: Kuan-Wei Chiu +Tested-by: Kuan-Wei Chiu +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Yu-Chun Lin +Link: https://patchwork.freedesktop.org/patch/msgid/20250104165134.1695864-1-eleanor15x@gmail.com +Signed-off-by: Maxime Ripard +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/tests/drm_kunit_helpers.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c +index 04a6b8cc62ac6..3c0b7824c0be3 100644 +--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c ++++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c +@@ -320,8 +320,7 @@ static void kunit_action_drm_mode_destroy(void *ptr) + } + + /** +- * drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC +- for a KUnit test ++ * drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC for a KUnit test + * @test: The test context object + * @dev: DRM device + * @video_code: CEA VIC of the mode +-- +2.39.5 + diff --git a/queue-6.12/drm-v3d-ensure-job-pointer-is-set-to-null-after-job-.patch b/queue-6.12/drm-v3d-ensure-job-pointer-is-set-to-null-after-job-.patch new file mode 100644 index 0000000000..339994ee1e --- /dev/null +++ b/queue-6.12/drm-v3d-ensure-job-pointer-is-set-to-null-after-job-.patch @@ -0,0 +1,66 @@ +From ab48977d8c5709ea1f62a31443c1d4dab2ea87b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jan 2025 12:47:40 -0300 +Subject: drm/v3d: Ensure job pointer is set to NULL after job completion +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Maíra Canal + +[ Upstream commit e4b5ccd392b92300a2b341705cc4805681094e49 ] + +After a job completes, the corresponding pointer in the device must +be set to NULL. Failing to do so triggers a warning when unloading +the driver, as it appears the job is still active. To prevent this, +assign the job pointer to NULL after completing the job, indicating +the job has finished. + +Fixes: 14d1d1908696 ("drm/v3d: Remove the bad signaled() implementation.") +Signed-off-by: Maíra Canal +Reviewed-by: Jose Maria Casanova Crespo +Link: https://patchwork.freedesktop.org/patch/msgid/20250113154741.67520-1-mcanal@igalia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/v3d/v3d_irq.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/v3d/v3d_irq.c b/drivers/gpu/drm/v3d/v3d_irq.c +index 20bf33702c3c4..da203045df9be 100644 +--- a/drivers/gpu/drm/v3d/v3d_irq.c ++++ b/drivers/gpu/drm/v3d/v3d_irq.c +@@ -108,6 +108,7 @@ v3d_irq(int irq, void *arg) + v3d_job_update_stats(&v3d->bin_job->base, V3D_BIN); + trace_v3d_bcl_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); ++ v3d->bin_job = NULL; + status = IRQ_HANDLED; + } + +@@ -118,6 +119,7 @@ v3d_irq(int irq, void *arg) + v3d_job_update_stats(&v3d->render_job->base, V3D_RENDER); + trace_v3d_rcl_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); ++ v3d->render_job = NULL; + status = IRQ_HANDLED; + } + +@@ -128,6 +130,7 @@ v3d_irq(int irq, void *arg) + v3d_job_update_stats(&v3d->csd_job->base, V3D_CSD); + trace_v3d_csd_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); ++ v3d->csd_job = NULL; + status = IRQ_HANDLED; + } + +@@ -165,6 +168,7 @@ v3d_hub_irq(int irq, void *arg) + v3d_job_update_stats(&v3d->tfu_job->base, V3D_TFU); + trace_v3d_tfu_irq(&v3d->drm, fence->seqno); + dma_fence_signal(&fence->base); ++ v3d->tfu_job = NULL; + status = IRQ_HANDLED; + } + +-- +2.39.5 + diff --git a/queue-6.12/drm-vmwgfx-add-new-keep_resv-bo-param.patch b/queue-6.12/drm-vmwgfx-add-new-keep_resv-bo-param.patch new file mode 100644 index 0000000000..3c3717ecf8 --- /dev/null +++ b/queue-6.12/drm-vmwgfx-add-new-keep_resv-bo-param.patch @@ -0,0 +1,147 @@ +From b1e88bd6bb9183213adf646a54c792be356c04ee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Jan 2025 12:53:35 -0600 +Subject: drm/vmwgfx: Add new keep_resv BO param + +From: Ian Forbes + +[ Upstream commit b7d40627813799870e72729c6fc979a8a40d9ba6 ] + +Adds a new BO param that keeps the reservation locked after creation. +This removes the need to re-reserve the BO after creation which is a +waste of cycles. + +This also fixes a bug in vmw_prime_import_sg_table where the imported +reservation is unlocked twice. + +Signed-off-by: Ian Forbes +Fixes: b32233acceff ("drm/vmwgfx: Fix prime import/export") +Reviewed-by: Zack Rusin +Signed-off-by: Zack Rusin +Link: https://patchwork.freedesktop.org/patch/msgid/20250110185335.15301-1-ian.forbes@broadcom.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vmwgfx/vmwgfx_bo.c | 3 ++- + drivers/gpu/drm/vmwgfx/vmwgfx_bo.h | 3 ++- + drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 7 ++----- + drivers/gpu/drm/vmwgfx/vmwgfx_gem.c | 1 + + drivers/gpu/drm/vmwgfx/vmwgfx_shader.c | 7 ++----- + drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c | 5 ++--- + 6 files changed, 11 insertions(+), 15 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +index a0e433fbcba67..183cda50094cb 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +@@ -443,7 +443,8 @@ static int vmw_bo_init(struct vmw_private *dev_priv, + + if (params->pin) + ttm_bo_pin(&vmw_bo->tbo); +- ttm_bo_unreserve(&vmw_bo->tbo); ++ if (!params->keep_resv) ++ ttm_bo_unreserve(&vmw_bo->tbo); + + return 0; + } +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h +index 43b5439ec9f76..c21ba7ff77368 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_bo.h +@@ -56,8 +56,9 @@ struct vmw_bo_params { + u32 domain; + u32 busy_domain; + enum ttm_bo_type bo_type; +- size_t size; + bool pin; ++ bool keep_resv; ++ size_t size; + struct dma_resv *resv; + struct sg_table *sg; + }; +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +index 2825dd3149ed5..2e84e1029732d 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +@@ -401,7 +401,8 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) + .busy_domain = VMW_BO_DOMAIN_SYS, + .bo_type = ttm_bo_type_kernel, + .size = PAGE_SIZE, +- .pin = true ++ .pin = true, ++ .keep_resv = true, + }; + + /* +@@ -413,10 +414,6 @@ static int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) + if (unlikely(ret != 0)) + return ret; + +- ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL); +- BUG_ON(ret != 0); +- vmw_bo_pin_reserved(vbo, true); +- + ret = ttm_bo_kmap(&vbo->tbo, 0, 1, &map); + if (likely(ret == 0)) { + result = ttm_kmap_obj_virtual(&map, &dummy); +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c +index b9857f37ca1ac..ed5015ced3920 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gem.c +@@ -206,6 +206,7 @@ struct drm_gem_object *vmw_prime_import_sg_table(struct drm_device *dev, + .bo_type = ttm_bo_type_sg, + .size = attach->dmabuf->size, + .pin = false, ++ .keep_resv = true, + .resv = attach->dmabuf->resv, + .sg = table, + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +index a01ca3226d0af..7fb1c88bcc475 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +@@ -896,7 +896,8 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, + .busy_domain = VMW_BO_DOMAIN_SYS, + .bo_type = ttm_bo_type_device, + .size = size, +- .pin = true ++ .pin = true, ++ .keep_resv = true, + }; + + if (!vmw_shader_id_ok(user_key, shader_type)) +@@ -906,10 +907,6 @@ int vmw_compat_shader_add(struct vmw_private *dev_priv, + if (unlikely(ret != 0)) + goto out; + +- ret = ttm_bo_reserve(&buf->tbo, false, true, NULL); +- if (unlikely(ret != 0)) +- goto no_reserve; +- + /* Map and copy shader bytecode. */ + ret = ttm_bo_kmap(&buf->tbo, 0, PFN_UP(size), &map); + if (unlikely(ret != 0)) { +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +index 621d98b376bbb..5553892d7c3e0 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +@@ -572,15 +572,14 @@ int vmw_bo_create_and_populate(struct vmw_private *dev_priv, + .busy_domain = domain, + .bo_type = ttm_bo_type_kernel, + .size = bo_size, +- .pin = true ++ .pin = true, ++ .keep_resv = true, + }; + + ret = vmw_bo_create(dev_priv, &bo_params, &vbo); + if (unlikely(ret != 0)) + return ret; + +- ret = ttm_bo_reserve(&vbo->tbo, false, true, NULL); +- BUG_ON(ret != 0); + ret = vmw_ttm_populate(vbo->tbo.bdev, vbo->tbo.ttm, &ctx); + if (likely(ret == 0)) { + struct vmw_ttm_tt *vmw_tt = +-- +2.39.5 + diff --git a/queue-6.12/drm-vmwgfx-unreserve-bo-on-error.patch b/queue-6.12/drm-vmwgfx-unreserve-bo-on-error.patch new file mode 100644 index 0000000000..486ad6d061 --- /dev/null +++ b/queue-6.12/drm-vmwgfx-unreserve-bo-on-error.patch @@ -0,0 +1,81 @@ +From f1c0d4f64ee64a22cf5f861c2714457f2ed0948e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Dec 2024 13:55:35 -0600 +Subject: drm/vmwgfx: Unreserve BO on error + +From: Ian Forbes + +[ Upstream commit cb343ded122e0bf41e4b2a9f89386296451be109 ] + +Unlock BOs in reverse order. +Add an acquire context so that lockdep doesn't complain. + +Fixes: d6667f0ddf46 ("drm/vmwgfx: Fix handling of dumb buffers") +Signed-off-by: Ian Forbes +Signed-off-by: Zack Rusin +Link: https://patchwork.freedesktop.org/patch/msgid/20241210195535.2074918-1-ian.forbes@broadcom.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +index 10d596cb4b402..5f99f7437ae61 100644 +--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c ++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +@@ -750,6 +750,7 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane, + struct vmw_plane_state *old_vps = vmw_plane_state_to_vps(old_state); + struct vmw_bo *old_bo = NULL; + struct vmw_bo *new_bo = NULL; ++ struct ww_acquire_ctx ctx; + s32 hotspot_x, hotspot_y; + int ret; + +@@ -769,9 +770,11 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane, + if (du->cursor_surface) + du->cursor_age = du->cursor_surface->snooper.age; + ++ ww_acquire_init(&ctx, &reservation_ww_class); ++ + if (!vmw_user_object_is_null(&old_vps->uo)) { + old_bo = vmw_user_object_buffer(&old_vps->uo); +- ret = ttm_bo_reserve(&old_bo->tbo, false, false, NULL); ++ ret = ttm_bo_reserve(&old_bo->tbo, false, false, &ctx); + if (ret != 0) + return; + } +@@ -779,9 +782,14 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane, + if (!vmw_user_object_is_null(&vps->uo)) { + new_bo = vmw_user_object_buffer(&vps->uo); + if (old_bo != new_bo) { +- ret = ttm_bo_reserve(&new_bo->tbo, false, false, NULL); +- if (ret != 0) ++ ret = ttm_bo_reserve(&new_bo->tbo, false, false, &ctx); ++ if (ret != 0) { ++ if (old_bo) { ++ ttm_bo_unreserve(&old_bo->tbo); ++ ww_acquire_fini(&ctx); ++ } + return; ++ } + } else { + new_bo = NULL; + } +@@ -803,10 +811,12 @@ vmw_du_cursor_plane_atomic_update(struct drm_plane *plane, + hotspot_x, hotspot_y); + } + +- if (old_bo) +- ttm_bo_unreserve(&old_bo->tbo); + if (new_bo) + ttm_bo_unreserve(&new_bo->tbo); ++ if (old_bo) ++ ttm_bo_unreserve(&old_bo->tbo); ++ ++ ww_acquire_fini(&ctx); + + du->cursor_x = new_state->crtc_x + du->set_gui_x; + du->cursor_y = new_state->crtc_y + du->set_gui_y; +-- +2.39.5 + diff --git a/queue-6.12/eth-bnxt-always-recalculate-features-after-xdp-clear.patch b/queue-6.12/eth-bnxt-always-recalculate-features-after-xdp-clear.patch new file mode 100644 index 0000000000..a1202d96d0 --- /dev/null +++ b/queue-6.12/eth-bnxt-always-recalculate-features-after-xdp-clear.patch @@ -0,0 +1,164 @@ +From 00b3a2aaa45fc436fe1712cb62b516374720ef85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2025 20:30:57 -0800 +Subject: eth: bnxt: always recalculate features after XDP clearing, fix + null-deref + +From: Jakub Kicinski + +[ Upstream commit f0aa6a37a3dbb40b272df5fc6db93c114688adcd ] + +Recalculate features when XDP is detached. + +Before: + # ip li set dev eth0 xdp obj xdp_dummy.bpf.o sec xdp + # ip li set dev eth0 xdp off + # ethtool -k eth0 | grep gro + rx-gro-hw: off [requested on] + +After: + # ip li set dev eth0 xdp obj xdp_dummy.bpf.o sec xdp + # ip li set dev eth0 xdp off + # ethtool -k eth0 | grep gro + rx-gro-hw: on + +The fact that HW-GRO doesn't get re-enabled automatically is just +a minor annoyance. The real issue is that the features will randomly +come back during another reconfiguration which just happens to invoke +netdev_update_features(). The driver doesn't handle reconfiguring +two things at a time very robustly. + +Starting with commit 98ba1d931f61 ("bnxt_en: Fix RSS logic in +__bnxt_reserve_rings()") we only reconfigure the RSS hash table +if the "effective" number of Rx rings has changed. If HW-GRO is +enabled "effective" number of rings is 2x what user sees. +So if we are in the bad state, with HW-GRO re-enablement "pending" +after XDP off, and we lower the rings by / 2 - the HW-GRO rings +doing 2x and the ethtool -L doing / 2 may cancel each other out, +and the: + + if (old_rx_rings != bp->hw_resc.resv_rx_rings && + +condition in __bnxt_reserve_rings() will be false. +The RSS map won't get updated, and we'll crash with: + + BUG: kernel NULL pointer dereference, address: 0000000000000168 + RIP: 0010:__bnxt_hwrm_vnic_set_rss+0x13a/0x1a0 + bnxt_hwrm_vnic_rss_cfg_p5+0x47/0x180 + __bnxt_setup_vnic_p5+0x58/0x110 + bnxt_init_nic+0xb72/0xf50 + __bnxt_open_nic+0x40d/0xab0 + bnxt_open_nic+0x2b/0x60 + ethtool_set_channels+0x18c/0x1d0 + +As we try to access a freed ring. + +The issue is present since XDP support was added, really, but +prior to commit 98ba1d931f61 ("bnxt_en: Fix RSS logic in +__bnxt_reserve_rings()") it wasn't causing major issues. + +Fixes: 1054aee82321 ("bnxt_en: Use NETIF_F_GRO_HW.") +Fixes: 98ba1d931f61 ("bnxt_en: Fix RSS logic in __bnxt_reserve_rings()") +Reviewed-by: Michael Chan +Reviewed-by: Somnath Kotur +Link: https://patch.msgid.link/20250109043057.2888953-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 25 +++++++++++++++---- + drivers/net/ethernet/broadcom/bnxt/bnxt.h | 2 +- + drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 7 ------ + 3 files changed, 21 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index c255445e97f3c..603e9c968c44b 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -4558,7 +4558,7 @@ void bnxt_set_ring_params(struct bnxt *bp) + /* Changing allocation mode of RX rings. + * TODO: Update when extending xdp_rxq_info to support allocation modes. + */ +-int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode) ++static void __bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode) + { + struct net_device *dev = bp->dev; + +@@ -4579,15 +4579,30 @@ int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode) + bp->rx_skb_func = bnxt_rx_page_skb; + } + bp->rx_dir = DMA_BIDIRECTIONAL; +- /* Disable LRO or GRO_HW */ +- netdev_update_features(dev); + } else { + dev->max_mtu = bp->max_mtu; + bp->flags &= ~BNXT_FLAG_RX_PAGE_MODE; + bp->rx_dir = DMA_FROM_DEVICE; + bp->rx_skb_func = bnxt_rx_skb; + } +- return 0; ++} ++ ++void bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode) ++{ ++ __bnxt_set_rx_skb_mode(bp, page_mode); ++ ++ if (!page_mode) { ++ int rx, tx; ++ ++ bnxt_get_max_rings(bp, &rx, &tx, true); ++ if (rx > 1) { ++ bp->flags &= ~BNXT_FLAG_NO_AGG_RINGS; ++ bp->dev->hw_features |= NETIF_F_LRO; ++ } ++ } ++ ++ /* Update LRO and GRO_HW availability */ ++ netdev_update_features(bp->dev); + } + + static void bnxt_free_vnic_attributes(struct bnxt *bp) +@@ -15909,7 +15924,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) + if (bp->max_fltr < BNXT_MAX_FLTR) + bp->max_fltr = BNXT_MAX_FLTR; + bnxt_init_l2_fltr_tbl(bp); +- bnxt_set_rx_skb_mode(bp, false); ++ __bnxt_set_rx_skb_mode(bp, false); + bnxt_set_tpa_flags(bp); + bnxt_set_ring_params(bp); + bnxt_rdma_aux_device_init(bp); +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h +index 9e05704d94450..bee645f58d0bd 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h +@@ -2796,7 +2796,7 @@ void bnxt_reuse_rx_data(struct bnxt_rx_ring_info *rxr, u16 cons, void *data); + u32 bnxt_fw_health_readl(struct bnxt *bp, int reg_idx); + void bnxt_set_tpa_flags(struct bnxt *bp); + void bnxt_set_ring_params(struct bnxt *); +-int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode); ++void bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode); + void bnxt_insert_usr_fltr(struct bnxt *bp, struct bnxt_filter_base *fltr); + void bnxt_del_one_usr_fltr(struct bnxt *bp, struct bnxt_filter_base *fltr); + int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap, +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +index f88b641533fcc..dc51dce209d5f 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c +@@ -422,15 +422,8 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog) + bnxt_set_rx_skb_mode(bp, true); + xdp_features_set_redirect_target(dev, true); + } else { +- int rx, tx; +- + xdp_features_clear_redirect_target(dev); + bnxt_set_rx_skb_mode(bp, false); +- bnxt_get_max_rings(bp, &rx, &tx, true); +- if (rx > 1) { +- bp->flags &= ~BNXT_FLAG_NO_AGG_RINGS; +- bp->dev->hw_features |= NETIF_F_LRO; +- } + } + bp->tx_nr_rings_xdp = tx_xdp; + bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp; +-- +2.39.5 + diff --git a/queue-6.12/gtp-destroy-device-along-with-udp-socket-s-netns-dis.patch b/queue-6.12/gtp-destroy-device-along-with-udp-socket-s-netns-dis.patch new file mode 100644 index 0000000000..1fc782c482 --- /dev/null +++ b/queue-6.12/gtp-destroy-device-along-with-udp-socket-s-netns-dis.patch @@ -0,0 +1,125 @@ +From 1dbe8acb4d039ee01ea2d4e95fef75cd569fbb4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Jan 2025 10:47:53 +0900 +Subject: gtp: Destroy device along with udp socket's netns dismantle. + +From: Kuniyuki Iwashima + +[ Upstream commit eb28fd76c0a08a47b470677c6cef9dd1c60e92d1 ] + +gtp_newlink() links the device to a list in dev_net(dev) instead of +src_net, where a udp tunnel socket is created. + +Even when src_net is removed, the device stays alive on dev_net(dev). +Then, removing src_net triggers the splat below. [0] + +In this example, gtp0 is created in ns2, and the udp socket is created +in ns1. + + ip netns add ns1 + ip netns add ns2 + ip -n ns1 link add netns ns2 name gtp0 type gtp role sgsn + ip netns del ns1 + +Let's link the device to the socket's netns instead. + +Now, gtp_net_exit_batch_rtnl() needs another netdev iteration to remove +all gtp devices in the netns. + +[0]: +ref_tracker: net notrefcnt@000000003d6e7d05 has 1/2 users at + sk_alloc (./include/net/net_namespace.h:345 net/core/sock.c:2236) + inet_create (net/ipv4/af_inet.c:326 net/ipv4/af_inet.c:252) + __sock_create (net/socket.c:1558) + udp_sock_create4 (net/ipv4/udp_tunnel_core.c:18) + gtp_create_sock (./include/net/udp_tunnel.h:59 drivers/net/gtp.c:1423) + gtp_create_sockets (drivers/net/gtp.c:1447) + gtp_newlink (drivers/net/gtp.c:1507) + rtnl_newlink (net/core/rtnetlink.c:3786 net/core/rtnetlink.c:3897 net/core/rtnetlink.c:4012) + rtnetlink_rcv_msg (net/core/rtnetlink.c:6922) + netlink_rcv_skb (net/netlink/af_netlink.c:2542) + netlink_unicast (net/netlink/af_netlink.c:1321 net/netlink/af_netlink.c:1347) + netlink_sendmsg (net/netlink/af_netlink.c:1891) + ____sys_sendmsg (net/socket.c:711 net/socket.c:726 net/socket.c:2583) + ___sys_sendmsg (net/socket.c:2639) + __sys_sendmsg (net/socket.c:2669) + do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83) + +WARNING: CPU: 1 PID: 60 at lib/ref_tracker.c:179 ref_tracker_dir_exit (lib/ref_tracker.c:179) +Modules linked in: +CPU: 1 UID: 0 PID: 60 Comm: kworker/u16:2 Not tainted 6.13.0-rc5-00147-g4c1224501e9d #5 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 +Workqueue: netns cleanup_net +RIP: 0010:ref_tracker_dir_exit (lib/ref_tracker.c:179) +Code: 00 00 00 fc ff df 4d 8b 26 49 bd 00 01 00 00 00 00 ad de 4c 39 f5 0f 85 df 00 00 00 48 8b 74 24 08 48 89 df e8 a5 cc 12 02 90 <0f> 0b 90 48 8d 6b 44 be 04 00 00 00 48 89 ef e8 80 de 67 ff 48 89 +RSP: 0018:ff11000009a07b60 EFLAGS: 00010286 +RAX: 0000000000002bd3 RBX: ff1100000f4e1aa0 RCX: 1ffffffff0e40ac6 +RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff8423ee3c +RBP: ff1100000f4e1af0 R08: 0000000000000001 R09: fffffbfff0e395ae +R10: 0000000000000001 R11: 0000000000036001 R12: ff1100000f4e1af0 +R13: dead000000000100 R14: ff1100000f4e1af0 R15: dffffc0000000000 +FS: 0000000000000000(0000) GS:ff1100006ce80000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00007f9b2464bd98 CR3: 0000000005286005 CR4: 0000000000771ef0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 +PKRU: 55555554 +Call Trace: + + ? __warn (kernel/panic.c:748) + ? ref_tracker_dir_exit (lib/ref_tracker.c:179) + ? report_bug (lib/bug.c:201 lib/bug.c:219) + ? handle_bug (arch/x86/kernel/traps.c:285) + ? exc_invalid_op (arch/x86/kernel/traps.c:309 (discriminator 1)) + ? asm_exc_invalid_op (./arch/x86/include/asm/idtentry.h:621) + ? _raw_spin_unlock_irqrestore (./arch/x86/include/asm/irqflags.h:42 ./arch/x86/include/asm/irqflags.h:97 ./arch/x86/include/asm/irqflags.h:155 ./include/linux/spinlock_api_smp.h:151 kernel/locking/spinlock.c:194) + ? ref_tracker_dir_exit (lib/ref_tracker.c:179) + ? __pfx_ref_tracker_dir_exit (lib/ref_tracker.c:158) + ? kfree (mm/slub.c:4613 mm/slub.c:4761) + net_free (net/core/net_namespace.c:476 net/core/net_namespace.c:467) + cleanup_net (net/core/net_namespace.c:664 (discriminator 3)) + process_one_work (kernel/workqueue.c:3229) + worker_thread (kernel/workqueue.c:3304 kernel/workqueue.c:3391) + kthread (kernel/kthread.c:389) + ret_from_fork (arch/x86/kernel/process.c:147) + ret_from_fork_asm (arch/x86/entry/entry_64.S:257) + + +Fixes: 459aa660eb1d ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)") +Reported-by: Xiao Liang +Closes: https://lore.kernel.org/netdev/20250104125732.17335-1-shaw.leon@gmail.com/ +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/gtp.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c +index 819ce4b756d23..47406ce990161 100644 +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -1526,7 +1526,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev, + goto out_encap; + } + +- gn = net_generic(dev_net(dev), gtp_net_id); ++ gn = net_generic(src_net, gtp_net_id); + list_add(>p->list, &gn->gtp_dev_list); + dev->priv_destructor = gtp_destructor; + +@@ -2487,6 +2487,11 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, + list_for_each_entry(net, net_list, exit_list) { + struct gtp_net *gn = net_generic(net, gtp_net_id); + struct gtp_dev *gtp, *gtp_next; ++ struct net_device *dev; ++ ++ for_each_netdev(net, dev) ++ if (dev->rtnl_link_ops == >p_link_ops) ++ gtp_dellink(dev, dev_to_kill); + + list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list) + gtp_dellink(gtp->dev, dev_to_kill); +-- +2.39.5 + diff --git a/queue-6.12/gtp-use-for_each_netdev_rcu-in-gtp_genl_dump_pdp.patch b/queue-6.12/gtp-use-for_each_netdev_rcu-in-gtp_genl_dump_pdp.patch new file mode 100644 index 0000000000..4a0f7cc87b --- /dev/null +++ b/queue-6.12/gtp-use-for_each_netdev_rcu-in-gtp_genl_dump_pdp.patch @@ -0,0 +1,91 @@ +From 204c25494333cbe7d49f426e6860dc021be4a7d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Jan 2025 10:47:52 +0900 +Subject: gtp: Use for_each_netdev_rcu() in gtp_genl_dump_pdp(). + +From: Kuniyuki Iwashima + +[ Upstream commit 46841c7053e6d25fb33e0534ef023833bf03e382 ] + +gtp_newlink() links the gtp device to a list in dev_net(dev). + +However, even after the gtp device is moved to another netns, +it stays on the list but should be invisible. + +Let's use for_each_netdev_rcu() for netdev traversal in +gtp_genl_dump_pdp(). + +Note that gtp_dev_list is no longer used under RCU, so list +helpers are converted to the non-RCU variant. + +Fixes: 459aa660eb1d ("gtp: add initial driver for datapath of GPRS Tunneling Protocol (GTP-U)") +Reported-by: Xiao Liang +Closes: https://lore.kernel.org/netdev/CABAhCOQdBL6h9M2C+kd+bGivRJ9Q72JUxW+-gur0nub_=PmFPA@mail.gmail.com/ +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/gtp.c | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c +index 70f981887518a..819ce4b756d23 100644 +--- a/drivers/net/gtp.c ++++ b/drivers/net/gtp.c +@@ -1527,7 +1527,7 @@ static int gtp_newlink(struct net *src_net, struct net_device *dev, + } + + gn = net_generic(dev_net(dev), gtp_net_id); +- list_add_rcu(>p->list, &gn->gtp_dev_list); ++ list_add(>p->list, &gn->gtp_dev_list); + dev->priv_destructor = gtp_destructor; + + netdev_dbg(dev, "registered new GTP interface\n"); +@@ -1553,7 +1553,7 @@ static void gtp_dellink(struct net_device *dev, struct list_head *head) + hlist_for_each_entry_safe(pctx, next, >p->tid_hash[i], hlist_tid) + pdp_context_delete(pctx); + +- list_del_rcu(>p->list); ++ list_del(>p->list); + unregister_netdevice_queue(dev, head); + } + +@@ -2279,16 +2279,19 @@ static int gtp_genl_dump_pdp(struct sk_buff *skb, + struct gtp_dev *last_gtp = (struct gtp_dev *)cb->args[2], *gtp; + int i, j, bucket = cb->args[0], skip = cb->args[1]; + struct net *net = sock_net(skb->sk); ++ struct net_device *dev; + struct pdp_ctx *pctx; +- struct gtp_net *gn; +- +- gn = net_generic(net, gtp_net_id); + + if (cb->args[4]) + return 0; + + rcu_read_lock(); +- list_for_each_entry_rcu(gtp, &gn->gtp_dev_list, list) { ++ for_each_netdev_rcu(net, dev) { ++ if (dev->rtnl_link_ops != >p_link_ops) ++ continue; ++ ++ gtp = netdev_priv(dev); ++ + if (last_gtp && last_gtp != gtp) + continue; + else +@@ -2483,9 +2486,9 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list, + + list_for_each_entry(net, net_list, exit_list) { + struct gtp_net *gn = net_generic(net, gtp_net_id); +- struct gtp_dev *gtp; ++ struct gtp_dev *gtp, *gtp_next; + +- list_for_each_entry(gtp, &gn->gtp_dev_list, list) ++ list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list) + gtp_dellink(gtp->dev, dev_to_kill); + } + } +-- +2.39.5 + diff --git a/queue-6.12/ice-add-correct-phy-lane-assignment.patch b/queue-6.12/ice-add-correct-phy-lane-assignment.patch new file mode 100644 index 0000000000..601c4227c2 --- /dev/null +++ b/queue-6.12/ice-add-correct-phy-lane-assignment.patch @@ -0,0 +1,303 @@ +From ff7d5ac3e7743791f9d8444534229248faf20446 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2024 13:29:16 +0100 +Subject: ice: Add correct PHY lane assignment + +From: Karol Kolacinski + +[ Upstream commit 258f5f905815979f15d5151d2ea4f20d8e057fe1 ] + +Driver always naively assumes, that for PTP purposes, PHY lane to +configure is corresponding to PF ID. + +This is not true for some port configurations, e.g.: +- 2x50G per quad, where lanes used are 0 and 2 on each quad, but PF IDs + are 0 and 1 +- 100G per quad on 2 quads, where lanes used are 0 and 4, but PF IDs are + 0 and 1 + +Use correct PHY lane assignment by getting and parsing port options. +This is read from the NVM by the FW and provided to the driver with +the indication of active port split. + +Remove ice_is_muxed_topo(), which is no longer needed. + +Fixes: 4409ea1726cb ("ice: Adjust PTP init for 2x50G E825C devices") +Reviewed-by: Przemek Kitszel +Reviewed-by: Arkadiusz Kubalewski +Signed-off-by: Karol Kolacinski +Signed-off-by: Grzegorz Nitka +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + .../net/ethernet/intel/ice/ice_adminq_cmd.h | 1 + + drivers/net/ethernet/intel/ice/ice_common.c | 51 +++++++++++++++++++ + drivers/net/ethernet/intel/ice/ice_common.h | 1 + + drivers/net/ethernet/intel/ice/ice_main.c | 6 +-- + drivers/net/ethernet/intel/ice/ice_ptp.c | 23 ++++----- + drivers/net/ethernet/intel/ice/ice_ptp.h | 4 +- + drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 26 +--------- + drivers/net/ethernet/intel/ice/ice_type.h | 1 - + 8 files changed, 68 insertions(+), 45 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h +index 79a6edd0be0ec..80f3dfd271243 100644 +--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h ++++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h +@@ -1648,6 +1648,7 @@ struct ice_aqc_get_port_options_elem { + #define ICE_AQC_PORT_OPT_MAX_LANE_25G 5 + #define ICE_AQC_PORT_OPT_MAX_LANE_50G 6 + #define ICE_AQC_PORT_OPT_MAX_LANE_100G 7 ++#define ICE_AQC_PORT_OPT_MAX_LANE_200G 8 + + u8 global_scid[2]; + u8 phy_scid[2]; +diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c +index f1324e25b2af1..068a467de1d56 100644 +--- a/drivers/net/ethernet/intel/ice/ice_common.c ++++ b/drivers/net/ethernet/intel/ice/ice_common.c +@@ -4074,6 +4074,57 @@ ice_aq_set_port_option(struct ice_hw *hw, u8 lport, u8 lport_valid, + return ice_aq_send_cmd(hw, &desc, NULL, 0, NULL); + } + ++/** ++ * ice_get_phy_lane_number - Get PHY lane number for current adapter ++ * @hw: pointer to the hw struct ++ * ++ * Return: PHY lane number on success, negative error code otherwise. ++ */ ++int ice_get_phy_lane_number(struct ice_hw *hw) ++{ ++ struct ice_aqc_get_port_options_elem *options; ++ unsigned int lport = 0; ++ unsigned int lane; ++ int err; ++ ++ options = kcalloc(ICE_AQC_PORT_OPT_MAX, sizeof(*options), GFP_KERNEL); ++ if (!options) ++ return -ENOMEM; ++ ++ for (lane = 0; lane < ICE_MAX_PORT_PER_PCI_DEV; lane++) { ++ u8 options_count = ICE_AQC_PORT_OPT_MAX; ++ u8 speed, active_idx, pending_idx; ++ bool active_valid, pending_valid; ++ ++ err = ice_aq_get_port_options(hw, options, &options_count, lane, ++ true, &active_idx, &active_valid, ++ &pending_idx, &pending_valid); ++ if (err) ++ goto err; ++ ++ if (!active_valid) ++ continue; ++ ++ speed = options[active_idx].max_lane_speed; ++ /* If we don't get speed for this lane, it's unoccupied */ ++ if (speed > ICE_AQC_PORT_OPT_MAX_LANE_200G) ++ continue; ++ ++ if (hw->pf_id == lport) { ++ kfree(options); ++ return lane; ++ } ++ ++ lport++; ++ } ++ ++ /* PHY lane not found */ ++ err = -ENXIO; ++err: ++ kfree(options); ++ return err; ++} ++ + /** + * ice_aq_sff_eeprom + * @hw: pointer to the HW struct +diff --git a/drivers/net/ethernet/intel/ice/ice_common.h b/drivers/net/ethernet/intel/ice/ice_common.h +index 27208a60cece5..fe6f88cfd9486 100644 +--- a/drivers/net/ethernet/intel/ice/ice_common.h ++++ b/drivers/net/ethernet/intel/ice/ice_common.h +@@ -193,6 +193,7 @@ ice_aq_get_port_options(struct ice_hw *hw, + int + ice_aq_set_port_option(struct ice_hw *hw, u8 lport, u8 lport_valid, + u8 new_option); ++int ice_get_phy_lane_number(struct ice_hw *hw); + int + ice_aq_sff_eeprom(struct ice_hw *hw, u16 lport, u8 bus_addr, + u16 mem_addr, u8 page, u8 set_page, u8 *data, u8 length, +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 8f2e758c39427..45eefe22fb5b7 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -1144,7 +1144,7 @@ ice_link_event(struct ice_pf *pf, struct ice_port_info *pi, bool link_up, + if (link_up == old_link && link_speed == old_link_speed) + return 0; + +- ice_ptp_link_change(pf, pf->hw.pf_id, link_up); ++ ice_ptp_link_change(pf, link_up); + + if (ice_is_dcb_active(pf)) { + if (test_bit(ICE_FLAG_DCB_ENA, pf->flags)) +@@ -6744,7 +6744,7 @@ static int ice_up_complete(struct ice_vsi *vsi) + ice_print_link_msg(vsi, true); + netif_tx_start_all_queues(vsi->netdev); + netif_carrier_on(vsi->netdev); +- ice_ptp_link_change(pf, pf->hw.pf_id, true); ++ ice_ptp_link_change(pf, true); + } + + /* Perform an initial read of the statistics registers now to +@@ -7214,7 +7214,7 @@ int ice_down(struct ice_vsi *vsi) + + if (vsi->netdev) { + vlan_err = ice_vsi_del_vlan_zero(vsi); +- ice_ptp_link_change(vsi->back, vsi->back->hw.pf_id, false); ++ ice_ptp_link_change(vsi->back, false); + netif_carrier_off(vsi->netdev); + netif_tx_disable(vsi->netdev); + } +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c +index 0b3dd87a331c7..7c6f81beaee46 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c +@@ -1466,10 +1466,9 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port) + /** + * ice_ptp_link_change - Reconfigure PTP after link status change + * @pf: Board private structure +- * @port: Port for which the PHY start is set + * @linkup: Link is up or down + */ +-void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup) ++void ice_ptp_link_change(struct ice_pf *pf, bool linkup) + { + struct ice_ptp_port *ptp_port; + struct ice_hw *hw = &pf->hw; +@@ -1477,14 +1476,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup) + if (pf->ptp.state != ICE_PTP_READY) + return; + +- if (WARN_ON_ONCE(port >= hw->ptp.num_lports)) +- return; +- + ptp_port = &pf->ptp.port; +- if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo) +- port *= 2; +- if (WARN_ON_ONCE(ptp_port->port_num != port)) +- return; + + /* Update cached link status for this port immediately */ + ptp_port->link_up = linkup; +@@ -3383,10 +3375,17 @@ void ice_ptp_init(struct ice_pf *pf) + { + struct ice_ptp *ptp = &pf->ptp; + struct ice_hw *hw = &pf->hw; +- int err; ++ int lane_num, err; + + ptp->state = ICE_PTP_INITIALIZING; + ++ lane_num = ice_get_phy_lane_number(hw); ++ if (lane_num < 0) { ++ err = lane_num; ++ goto err_exit; ++ } ++ ++ ptp->port.port_num = (u8)lane_num; + ice_ptp_init_hw(hw); + + ice_ptp_init_tx_interrupt_mode(pf); +@@ -3407,10 +3406,6 @@ void ice_ptp_init(struct ice_pf *pf) + if (err) + goto err_exit; + +- ptp->port.port_num = hw->pf_id; +- if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo) +- ptp->port.port_num = hw->pf_id * 2; +- + err = ice_ptp_init_port(pf, &ptp->port); + if (err) + goto err_exit; +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h +index 5615efc42c624..f1cfa6aa4e76b 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp.h ++++ b/drivers/net/ethernet/intel/ice/ice_ptp.h +@@ -332,7 +332,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf, + enum ice_reset_req reset_type); + void ice_ptp_init(struct ice_pf *pf); + void ice_ptp_release(struct ice_pf *pf); +-void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup); ++void ice_ptp_link_change(struct ice_pf *pf, bool linkup); + #else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */ + static inline int ice_ptp_set_ts_config(struct ice_pf *pf, struct ifreq *ifr) + { +@@ -380,7 +380,7 @@ static inline void ice_ptp_prepare_for_reset(struct ice_pf *pf, + } + static inline void ice_ptp_init(struct ice_pf *pf) { } + static inline void ice_ptp_release(struct ice_pf *pf) { } +-static inline void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup) ++static inline void ice_ptp_link_change(struct ice_pf *pf, bool linkup) + { + } + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +index 28bd4815ebcf3..7190fde16c868 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +@@ -2698,26 +2698,6 @@ static int ice_get_phy_tx_tstamp_ready_eth56g(struct ice_hw *hw, u8 port, + return 0; + } + +-/** +- * ice_is_muxed_topo - detect breakout 2x50G topology for E825C +- * @hw: pointer to the HW struct +- * +- * Return: true if it's 2x50 breakout topology, false otherwise +- */ +-static bool ice_is_muxed_topo(struct ice_hw *hw) +-{ +- u8 link_topo; +- bool mux; +- u32 val; +- +- val = rd32(hw, GLGEN_SWITCH_MODE_CONFIG); +- mux = FIELD_GET(GLGEN_SWITCH_MODE_CONFIG_25X4_QUAD_M, val); +- val = rd32(hw, GLGEN_MAC_LINK_TOPO); +- link_topo = FIELD_GET(GLGEN_MAC_LINK_TOPO_LINK_TOPO_M, val); +- +- return (mux && link_topo == ICE_LINK_TOPO_UP_TO_2_LINKS); +-} +- + /** + * ice_ptp_init_phy_e825 - initialize PHY parameters + * @hw: pointer to the HW struct +@@ -2740,12 +2720,8 @@ static void ice_ptp_init_phy_e825(struct ice_hw *hw) + + ice_sb_access_ena_eth56g(hw, true); + err = ice_read_phy_eth56g(hw, hw->pf_id, PHY_REG_REVISION, &phy_rev); +- if (err || phy_rev != PHY_REVISION_ETH56G) { ++ if (err || phy_rev != PHY_REVISION_ETH56G) + ptp->phy_model = ICE_PHY_UNSUP; +- return; +- } +- +- ptp->is_2x50g_muxed_topo = ice_is_muxed_topo(hw); + } + + /* E822 family functions +diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h +index 479227bdff75e..609f31e0dfded 100644 +--- a/drivers/net/ethernet/intel/ice/ice_type.h ++++ b/drivers/net/ethernet/intel/ice/ice_type.h +@@ -880,7 +880,6 @@ struct ice_ptp_hw { + union ice_phy_params phy; + u8 num_lports; + u8 ports_per_phy; +- bool is_2x50g_muxed_topo; + }; + + /* Port hardware description */ +-- +2.39.5 + diff --git a/queue-6.12/ice-add-ice_get_ctrl_ptp-wrapper-to-simplify-the-cod.patch b/queue-6.12/ice-add-ice_get_ctrl_ptp-wrapper-to-simplify-the-cod.patch new file mode 100644 index 0000000000..d9ea3e6910 --- /dev/null +++ b/queue-6.12/ice-add-ice_get_ctrl_ptp-wrapper-to-simplify-the-cod.patch @@ -0,0 +1,79 @@ +From e100d854a338dbf390b9076ddd54556f4b0da4a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 15:09:54 +0200 +Subject: ice: Add ice_get_ctrl_ptp() wrapper to simplify the code + +From: Sergey Temerkhanov + +[ Upstream commit 97ed20a01f5b96e8738b53f56ae84b06953a2853 ] + +Add ice_get_ctrl_ptp() wrapper to simplify the PTP support code +in the functions that do not use ctrl_pf directly. +Add the control PF pointer to struct ice_adapter +Rearrange fields in struct ice_adapter + +Signed-off-by: Sergey Temerkhanov +Reviewed-by: Przemek Kitszel +Reviewed-by: Simon Horman +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 258f5f905815 ("ice: Add correct PHY lane assignment") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_adapter.h | 5 ++++- + drivers/net/ethernet/intel/ice/ice_ptp.c | 12 ++++++++++++ + 2 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.h b/drivers/net/ethernet/intel/ice/ice_adapter.h +index 9d11014ec02ff..eb7cac01c2427 100644 +--- a/drivers/net/ethernet/intel/ice/ice_adapter.h ++++ b/drivers/net/ethernet/intel/ice/ice_adapter.h +@@ -8,18 +8,21 @@ + #include + + struct pci_dev; ++struct ice_pf; + + /** + * struct ice_adapter - PCI adapter resources shared across PFs + * @ptp_gltsyn_time_lock: Spinlock protecting access to the GLTSYN_TIME + * register of the PTP clock. + * @refcount: Reference count. struct ice_pf objects hold the references. ++ * @ctrl_pf: Control PF of the adapter + */ + struct ice_adapter { ++ refcount_t refcount; + /* For access to the GLTSYN_TIME register */ + spinlock_t ptp_gltsyn_time_lock; + +- refcount_t refcount; ++ struct ice_pf *ctrl_pf; + }; + + struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev); +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c +index d534c8e571cee..2fb73ab41bc20 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c +@@ -16,6 +16,18 @@ static const struct ptp_pin_desc ice_pin_desc_e810t[] = { + { "U.FL2", UFL2, PTP_PF_NONE, 2, { 0, } }, + }; + ++static struct ice_pf *ice_get_ctrl_pf(struct ice_pf *pf) ++{ ++ return !pf->adapter ? NULL : pf->adapter->ctrl_pf; ++} ++ ++static __maybe_unused struct ice_ptp *ice_get_ctrl_ptp(struct ice_pf *pf) ++{ ++ struct ice_pf *ctrl_pf = ice_get_ctrl_pf(pf); ++ ++ return !ctrl_pf ? NULL : &ctrl_pf->ptp; ++} ++ + /** + * ice_get_sma_config_e810t + * @hw: pointer to the hw struct +-- +2.39.5 + diff --git a/queue-6.12/ice-fix-e825-initialization.patch b/queue-6.12/ice-fix-e825-initialization.patch new file mode 100644 index 0000000000..6fce61676e --- /dev/null +++ b/queue-6.12/ice-fix-e825-initialization.patch @@ -0,0 +1,79 @@ +From f3367479563eb8ed8303f527e3bb82d45926221a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2024 13:29:13 +0100 +Subject: ice: Fix E825 initialization + +From: Karol Kolacinski + +[ Upstream commit d79c304c76e9b30ff5527afc176b5c4f9f0374b6 ] + +Current implementation checks revision of all PHYs on all PFs, which is +incorrect and may result in initialization failure. Check only the +revision of the current PHY. + +Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products") +Reviewed-by: Arkadiusz Kubalewski +Signed-off-by: Karol Kolacinski +Signed-off-by: Grzegorz Nitka +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 22 +++++++++------------ + 1 file changed, 9 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +index 3816e45b6ab44..f6816c2f71438 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +@@ -2664,14 +2664,15 @@ static bool ice_is_muxed_topo(struct ice_hw *hw) + } + + /** +- * ice_ptp_init_phy_e825c - initialize PHY parameters ++ * ice_ptp_init_phy_e825 - initialize PHY parameters + * @hw: pointer to the HW struct + */ +-static void ice_ptp_init_phy_e825c(struct ice_hw *hw) ++static void ice_ptp_init_phy_e825(struct ice_hw *hw) + { + struct ice_ptp_hw *ptp = &hw->ptp; + struct ice_eth56g_params *params; +- u8 phy; ++ u32 phy_rev; ++ int err; + + ptp->phy_model = ICE_PHY_ETH56G; + params = &ptp->phy.eth56g; +@@ -2685,15 +2686,10 @@ static void ice_ptp_init_phy_e825c(struct ice_hw *hw) + ptp->num_lports = params->num_phys * ptp->ports_per_phy; + + ice_sb_access_ena_eth56g(hw, true); +- for (phy = 0; phy < params->num_phys; phy++) { +- u32 phy_rev; +- int err; +- +- err = ice_read_phy_eth56g(hw, phy, PHY_REG_REVISION, &phy_rev); +- if (err || phy_rev != PHY_REVISION_ETH56G) { +- ptp->phy_model = ICE_PHY_UNSUP; +- return; +- } ++ err = ice_read_phy_eth56g(hw, hw->pf_id, PHY_REG_REVISION, &phy_rev); ++ if (err || phy_rev != PHY_REVISION_ETH56G) { ++ ptp->phy_model = ICE_PHY_UNSUP; ++ return; + } + + ptp->is_2x50g_muxed_topo = ice_is_muxed_topo(hw); +@@ -5395,7 +5391,7 @@ void ice_ptp_init_hw(struct ice_hw *hw) + else if (ice_is_e810(hw)) + ice_ptp_init_phy_e810(ptp); + else if (ice_is_e825c(hw)) +- ice_ptp_init_phy_e825c(hw); ++ ice_ptp_init_phy_e825(hw); + else + ptp->phy_model = ICE_PHY_UNSUP; + } +-- +2.39.5 + diff --git a/queue-6.12/ice-fix-eth56g-fc-fec-rx-offset-value.patch b/queue-6.12/ice-fix-eth56g-fc-fec-rx-offset-value.patch new file mode 100644 index 0000000000..ea57df5722 --- /dev/null +++ b/queue-6.12/ice-fix-eth56g-fc-fec-rx-offset-value.patch @@ -0,0 +1,41 @@ +From 3b4066672e0b53c25af72680e200f8f4964ce868 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2024 13:29:15 +0100 +Subject: ice: Fix ETH56G FC-FEC Rx offset value + +From: Karol Kolacinski + +[ Upstream commit 2e60560f1ec9b722f9c6699ec5d966f1732d14dd ] + +Fix ETH56G FC-FEC incorrect Rx offset value by changing it from -255.96 +to -469.26 ns. + +Those values are derived from HW spec and reflect internal delays. +Hex value is a fixed point representation in Q23.9 format. + +Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products") +Reviewed-by: Arkadiusz Kubalewski +Signed-off-by: Karol Kolacinski +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_ptp_consts.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_consts.h b/drivers/net/ethernet/intel/ice/ice_ptp_consts.h +index 3005dd252a102..bdb1020147d1c 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_consts.h ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_consts.h +@@ -131,7 +131,7 @@ struct ice_eth56g_mac_reg_cfg eth56g_mac_cfg[NUM_ICE_ETH56G_LNK_SPD] = { + .rx_offset = { + .serdes = 0xffffeb27, /* -10.42424 */ + .no_fec = 0xffffcccd, /* -25.6 */ +- .fc = 0xfffe0014, /* -255.96 */ ++ .fc = 0xfffc557b, /* -469.26 */ + .sfd = 0x4a4, /* 2.32 */ + .bs_ds = 0x32 /* 0.0969697 */ + } +-- +2.39.5 + diff --git a/queue-6.12/ice-fix-quad-registers-read-on-e825.patch b/queue-6.12/ice-fix-quad-registers-read-on-e825.patch new file mode 100644 index 0000000000..936111fd6f --- /dev/null +++ b/queue-6.12/ice-fix-quad-registers-read-on-e825.patch @@ -0,0 +1,459 @@ +From 63a45c1b0d95af055c17c2fc2eb6f2c3d747fd31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Nov 2024 13:29:14 +0100 +Subject: ice: Fix quad registers read on E825 + +From: Karol Kolacinski + +[ Upstream commit dc26548d729e5f732197d2b210fb77c745b01495 ] + +Quad registers are read/written incorrectly. E825 devices always use +quad 0 address and differentiate between the PHYs by changing SBQ +destination device (phy_0 or phy_0_peer). + +Add helpers for reading/writing PTP registers shared per quad and use +correct quad address and SBQ destination device based on port. + +Fixes: 7cab44f1c35f ("ice: Introduce ETH56G PHY model for E825C products") +Reviewed-by: Arkadiusz Kubalewski +Signed-off-by: Karol Kolacinski +Signed-off-by: Grzegorz Nitka +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 219 ++++++++++++-------- + drivers/net/ethernet/intel/ice/ice_type.h | 1 - + 2 files changed, 133 insertions(+), 87 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +index f6816c2f71438..64c36620a02f3 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +@@ -877,31 +877,46 @@ static void ice_ptp_exec_tmr_cmd(struct ice_hw *hw) + * The following functions operate on devices with the ETH 56G PHY. + */ + ++/** ++ * ice_ptp_get_dest_dev_e825 - get destination PHY for given port number ++ * @hw: pointer to the HW struct ++ * @port: destination port ++ * ++ * Return: destination sideband queue PHY device. ++ */ ++static enum ice_sbq_msg_dev ice_ptp_get_dest_dev_e825(struct ice_hw *hw, ++ u8 port) ++{ ++ /* On a single complex E825, PHY 0 is always destination device phy_0 ++ * and PHY 1 is phy_0_peer. ++ */ ++ if (port >= hw->ptp.ports_per_phy) ++ return eth56g_phy_1; ++ else ++ return eth56g_phy_0; ++} ++ + /** + * ice_write_phy_eth56g - Write a PHY port register + * @hw: pointer to the HW struct +- * @phy_idx: PHY index ++ * @port: destination port + * @addr: PHY register address + * @val: Value to write + * + * Return: 0 on success, other error codes when failed to write to PHY + */ +-static int ice_write_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr, +- u32 val) ++static int ice_write_phy_eth56g(struct ice_hw *hw, u8 port, u32 addr, u32 val) + { +- struct ice_sbq_msg_input phy_msg; ++ struct ice_sbq_msg_input msg = { ++ .dest_dev = ice_ptp_get_dest_dev_e825(hw, port), ++ .opcode = ice_sbq_msg_wr, ++ .msg_addr_low = lower_16_bits(addr), ++ .msg_addr_high = upper_16_bits(addr), ++ .data = val ++ }; + int err; + +- phy_msg.opcode = ice_sbq_msg_wr; +- +- phy_msg.msg_addr_low = lower_16_bits(addr); +- phy_msg.msg_addr_high = upper_16_bits(addr); +- +- phy_msg.data = val; +- phy_msg.dest_dev = hw->ptp.phy.eth56g.phy_addr[phy_idx]; +- +- err = ice_sbq_rw_reg(hw, &phy_msg, ICE_AQ_FLAG_RD); +- ++ err = ice_sbq_rw_reg(hw, &msg, ICE_AQ_FLAG_RD); + if (err) + ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n", + err); +@@ -912,41 +927,36 @@ static int ice_write_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr, + /** + * ice_read_phy_eth56g - Read a PHY port register + * @hw: pointer to the HW struct +- * @phy_idx: PHY index ++ * @port: destination port + * @addr: PHY register address + * @val: Value to write + * + * Return: 0 on success, other error codes when failed to read from PHY + */ +-static int ice_read_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr, +- u32 *val) ++static int ice_read_phy_eth56g(struct ice_hw *hw, u8 port, u32 addr, u32 *val) + { +- struct ice_sbq_msg_input phy_msg; ++ struct ice_sbq_msg_input msg = { ++ .dest_dev = ice_ptp_get_dest_dev_e825(hw, port), ++ .opcode = ice_sbq_msg_rd, ++ .msg_addr_low = lower_16_bits(addr), ++ .msg_addr_high = upper_16_bits(addr) ++ }; + int err; + +- phy_msg.opcode = ice_sbq_msg_rd; +- +- phy_msg.msg_addr_low = lower_16_bits(addr); +- phy_msg.msg_addr_high = upper_16_bits(addr); +- +- phy_msg.data = 0; +- phy_msg.dest_dev = hw->ptp.phy.eth56g.phy_addr[phy_idx]; +- +- err = ice_sbq_rw_reg(hw, &phy_msg, ICE_AQ_FLAG_RD); +- if (err) { ++ err = ice_sbq_rw_reg(hw, &msg, ICE_AQ_FLAG_RD); ++ if (err) + ice_debug(hw, ICE_DBG_PTP, "PTP failed to send msg to phy %d\n", + err); +- return err; +- } +- +- *val = phy_msg.data; ++ else ++ *val = msg.data; + +- return 0; ++ return err; + } + + /** + * ice_phy_res_address_eth56g - Calculate a PHY port register address +- * @port: Port number to be written ++ * @hw: pointer to the HW struct ++ * @lane: Lane number to be written + * @res_type: resource type (register/memory) + * @offset: Offset from PHY port register base + * @addr: The result address +@@ -955,17 +965,19 @@ static int ice_read_phy_eth56g(struct ice_hw *hw, u8 phy_idx, u32 addr, + * * %0 - success + * * %EINVAL - invalid port number or resource type + */ +-static int ice_phy_res_address_eth56g(u8 port, enum eth56g_res_type res_type, +- u32 offset, u32 *addr) ++static int ice_phy_res_address_eth56g(struct ice_hw *hw, u8 lane, ++ enum eth56g_res_type res_type, ++ u32 offset, ++ u32 *addr) + { +- u8 lane = port % ICE_PORTS_PER_QUAD; +- u8 phy = ICE_GET_QUAD_NUM(port); +- + if (res_type >= NUM_ETH56G_PHY_RES) + return -EINVAL; + +- *addr = eth56g_phy_res[res_type].base[phy] + ++ /* Lanes 4..7 are in fact 0..3 on a second PHY */ ++ lane %= hw->ptp.ports_per_phy; ++ *addr = eth56g_phy_res[res_type].base[0] + + lane * eth56g_phy_res[res_type].step + offset; ++ + return 0; + } + +@@ -985,19 +997,17 @@ static int ice_phy_res_address_eth56g(u8 port, enum eth56g_res_type res_type, + static int ice_write_port_eth56g(struct ice_hw *hw, u8 port, u32 offset, + u32 val, enum eth56g_res_type res_type) + { +- u8 phy_port = port % hw->ptp.ports_per_phy; +- u8 phy_idx = port / hw->ptp.ports_per_phy; + u32 addr; + int err; + + if (port >= hw->ptp.num_lports) + return -EINVAL; + +- err = ice_phy_res_address_eth56g(phy_port, res_type, offset, &addr); ++ err = ice_phy_res_address_eth56g(hw, port, res_type, offset, &addr); + if (err) + return err; + +- return ice_write_phy_eth56g(hw, phy_idx, addr, val); ++ return ice_write_phy_eth56g(hw, port, addr, val); + } + + /** +@@ -1016,19 +1026,17 @@ static int ice_write_port_eth56g(struct ice_hw *hw, u8 port, u32 offset, + static int ice_read_port_eth56g(struct ice_hw *hw, u8 port, u32 offset, + u32 *val, enum eth56g_res_type res_type) + { +- u8 phy_port = port % hw->ptp.ports_per_phy; +- u8 phy_idx = port / hw->ptp.ports_per_phy; + u32 addr; + int err; + + if (port >= hw->ptp.num_lports) + return -EINVAL; + +- err = ice_phy_res_address_eth56g(phy_port, res_type, offset, &addr); ++ err = ice_phy_res_address_eth56g(hw, port, res_type, offset, &addr); + if (err) + return err; + +- return ice_read_phy_eth56g(hw, phy_idx, addr, val); ++ return ice_read_phy_eth56g(hw, port, addr, val); + } + + /** +@@ -1177,6 +1185,56 @@ static int ice_write_port_mem_eth56g(struct ice_hw *hw, u8 port, u16 offset, + return ice_write_port_eth56g(hw, port, offset, val, ETH56G_PHY_MEM_PTP); + } + ++/** ++ * ice_write_quad_ptp_reg_eth56g - Write a PHY quad register ++ * @hw: pointer to the HW struct ++ * @offset: PHY register offset ++ * @port: Port number ++ * @val: Value to write ++ * ++ * Return: ++ * * %0 - success ++ * * %EIO - invalid port number or resource type ++ * * %other - failed to write to PHY ++ */ ++static int ice_write_quad_ptp_reg_eth56g(struct ice_hw *hw, u8 port, ++ u32 offset, u32 val) ++{ ++ u32 addr; ++ ++ if (port >= hw->ptp.num_lports) ++ return -EIO; ++ ++ addr = eth56g_phy_res[ETH56G_PHY_REG_PTP].base[0] + offset; ++ ++ return ice_write_phy_eth56g(hw, port, addr, val); ++} ++ ++/** ++ * ice_read_quad_ptp_reg_eth56g - Read a PHY quad register ++ * @hw: pointer to the HW struct ++ * @offset: PHY register offset ++ * @port: Port number ++ * @val: Value to read ++ * ++ * Return: ++ * * %0 - success ++ * * %EIO - invalid port number or resource type ++ * * %other - failed to read from PHY ++ */ ++static int ice_read_quad_ptp_reg_eth56g(struct ice_hw *hw, u8 port, ++ u32 offset, u32 *val) ++{ ++ u32 addr; ++ ++ if (port >= hw->ptp.num_lports) ++ return -EIO; ++ ++ addr = eth56g_phy_res[ETH56G_PHY_REG_PTP].base[0] + offset; ++ ++ return ice_read_phy_eth56g(hw, port, addr, val); ++} ++ + /** + * ice_is_64b_phy_reg_eth56g - Check if this is a 64bit PHY register + * @low_addr: the low address to check +@@ -1896,7 +1954,6 @@ ice_phy_get_speed_eth56g(struct ice_link_status *li) + */ + static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port) + { +- u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1); + u32 val; + int err; + +@@ -1911,8 +1968,8 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port) + switch (ice_phy_get_speed_eth56g(&hw->port_info->phy.link_info)) { + case ICE_ETH56G_LNK_SPD_1G: + case ICE_ETH56G_LNK_SPD_2_5G: +- err = ice_read_ptp_reg_eth56g(hw, port_blk, +- PHY_GPCS_CONFIG_REG0, &val); ++ err = ice_read_quad_ptp_reg_eth56g(hw, port, ++ PHY_GPCS_CONFIG_REG0, &val); + if (err) { + ice_debug(hw, ICE_DBG_PTP, "Failed to read PHY_GPCS_CONFIG_REG0, status: %d", + err); +@@ -1923,8 +1980,8 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port) + val |= FIELD_PREP(PHY_GPCS_CONFIG_REG0_TX_THR_M, + ICE_ETH56G_NOMINAL_TX_THRESH); + +- err = ice_write_ptp_reg_eth56g(hw, port_blk, +- PHY_GPCS_CONFIG_REG0, val); ++ err = ice_write_quad_ptp_reg_eth56g(hw, port, ++ PHY_GPCS_CONFIG_REG0, val); + if (err) { + ice_debug(hw, ICE_DBG_PTP, "Failed to write PHY_GPCS_CONFIG_REG0, status: %d", + err); +@@ -1965,50 +2022,47 @@ static int ice_phy_cfg_parpcs_eth56g(struct ice_hw *hw, u8 port) + */ + int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port) + { +- u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1); +- u8 blk_port = port & (ICE_PORTS_PER_QUAD - 1); ++ u8 quad_lane = port % ICE_PORTS_PER_QUAD; ++ u32 addr, val, peer_delay; + bool enable, sfd_ena; +- u32 val, peer_delay; + int err; + + enable = hw->ptp.phy.eth56g.onestep_ena; + peer_delay = hw->ptp.phy.eth56g.peer_delay; + sfd_ena = hw->ptp.phy.eth56g.sfd_ena; + +- /* PHY_PTP_1STEP_CONFIG */ +- err = ice_read_ptp_reg_eth56g(hw, port_blk, PHY_PTP_1STEP_CONFIG, &val); ++ addr = PHY_PTP_1STEP_CONFIG; ++ err = ice_read_quad_ptp_reg_eth56g(hw, port, addr, &val); + if (err) + return err; + + if (enable) +- val |= blk_port; ++ val |= BIT(quad_lane); + else +- val &= ~blk_port; ++ val &= ~BIT(quad_lane); + + val &= ~(PHY_PTP_1STEP_T1S_UP64_M | PHY_PTP_1STEP_T1S_DELTA_M); + +- err = ice_write_ptp_reg_eth56g(hw, port_blk, PHY_PTP_1STEP_CONFIG, val); ++ err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val); + if (err) + return err; + +- /* PHY_PTP_1STEP_PEER_DELAY */ ++ addr = PHY_PTP_1STEP_PEER_DELAY(quad_lane); + val = FIELD_PREP(PHY_PTP_1STEP_PD_DELAY_M, peer_delay); + if (peer_delay) + val |= PHY_PTP_1STEP_PD_ADD_PD_M; + val |= PHY_PTP_1STEP_PD_DLY_V_M; +- err = ice_write_ptp_reg_eth56g(hw, port_blk, +- PHY_PTP_1STEP_PEER_DELAY(blk_port), val); ++ err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val); + if (err) + return err; + + val &= ~PHY_PTP_1STEP_PD_DLY_V_M; +- err = ice_write_ptp_reg_eth56g(hw, port_blk, +- PHY_PTP_1STEP_PEER_DELAY(blk_port), val); ++ err = ice_write_quad_ptp_reg_eth56g(hw, port, addr, val); + if (err) + return err; + +- /* PHY_MAC_XIF_MODE */ +- err = ice_read_mac_reg_eth56g(hw, port, PHY_MAC_XIF_MODE, &val); ++ addr = PHY_MAC_XIF_MODE; ++ err = ice_read_mac_reg_eth56g(hw, port, addr, &val); + if (err) + return err; + +@@ -2028,7 +2082,7 @@ int ice_phy_cfg_ptp_1step_eth56g(struct ice_hw *hw, u8 port) + FIELD_PREP(PHY_MAC_XIF_TS_BIN_MODE_M, enable) | + FIELD_PREP(PHY_MAC_XIF_TS_SFD_ENA_M, sfd_ena); + +- return ice_write_mac_reg_eth56g(hw, port, PHY_MAC_XIF_MODE, val); ++ return ice_write_mac_reg_eth56g(hw, port, addr, val); + } + + /** +@@ -2070,21 +2124,22 @@ static u32 ice_ptp_calc_bitslip_eth56g(struct ice_hw *hw, u8 port, u32 bs, + bool fc, bool rs, + enum ice_eth56g_link_spd spd) + { +- u8 port_offset = port & (ICE_PORTS_PER_QUAD - 1); +- u8 port_blk = port & ~(ICE_PORTS_PER_QUAD - 1); + u32 bitslip; + int err; + + if (!bs || rs) + return 0; + +- if (spd == ICE_ETH56G_LNK_SPD_1G || spd == ICE_ETH56G_LNK_SPD_2_5G) ++ if (spd == ICE_ETH56G_LNK_SPD_1G || spd == ICE_ETH56G_LNK_SPD_2_5G) { + err = ice_read_gpcs_reg_eth56g(hw, port, PHY_GPCS_BITSLIP, + &bitslip); +- else +- err = ice_read_ptp_reg_eth56g(hw, port_blk, +- PHY_REG_SD_BIT_SLIP(port_offset), +- &bitslip); ++ } else { ++ u8 quad_lane = port % ICE_PORTS_PER_QUAD; ++ u32 addr; ++ ++ addr = PHY_REG_SD_BIT_SLIP(quad_lane); ++ err = ice_read_quad_ptp_reg_eth56g(hw, port, addr, &bitslip); ++ } + if (err) + return 0; + +@@ -2679,8 +2734,6 @@ static void ice_ptp_init_phy_e825(struct ice_hw *hw) + params->onestep_ena = false; + params->peer_delay = 0; + params->sfd_ena = false; +- params->phy_addr[0] = eth56g_phy_0; +- params->phy_addr[1] = eth56g_phy_1; + params->num_phys = 2; + ptp->ports_per_phy = 4; + ptp->num_lports = params->num_phys * ptp->ports_per_phy; +@@ -2711,10 +2764,9 @@ static void ice_fill_phy_msg_e82x(struct ice_hw *hw, + struct ice_sbq_msg_input *msg, u8 port, + u16 offset) + { +- int phy_port, phy, quadtype; ++ int phy_port, quadtype; + + phy_port = port % hw->ptp.ports_per_phy; +- phy = port / hw->ptp.ports_per_phy; + quadtype = ICE_GET_QUAD_NUM(port) % + ICE_GET_QUAD_NUM(hw->ptp.ports_per_phy); + +@@ -2726,12 +2778,7 @@ static void ice_fill_phy_msg_e82x(struct ice_hw *hw, + msg->msg_addr_high = P_Q1_H(P_4_BASE + offset, phy_port); + } + +- if (phy == 0) +- msg->dest_dev = rmn_0; +- else if (phy == 1) +- msg->dest_dev = rmn_1; +- else +- msg->dest_dev = rmn_2; ++ msg->dest_dev = rmn_0; + } + + /** +diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h +index 45768796691fe..479227bdff75e 100644 +--- a/drivers/net/ethernet/intel/ice/ice_type.h ++++ b/drivers/net/ethernet/intel/ice/ice_type.h +@@ -850,7 +850,6 @@ struct ice_mbx_data { + + struct ice_eth56g_params { + u8 num_phys; +- u8 phy_addr[2]; + bool onestep_ena; + bool sfd_ena; + u32 peer_delay; +-- +2.39.5 + diff --git a/queue-6.12/ice-introduce-ice_get_phy_model-wrapper.patch b/queue-6.12/ice-introduce-ice_get_phy_model-wrapper.patch new file mode 100644 index 0000000000..76cbd0daa6 --- /dev/null +++ b/queue-6.12/ice-introduce-ice_get_phy_model-wrapper.patch @@ -0,0 +1,231 @@ +From f893b9f439504421f64e661cc1707c39aa9cde4c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 15:09:53 +0200 +Subject: ice: Introduce ice_get_phy_model() wrapper + +From: Sergey Temerkhanov + +[ Upstream commit 5e0776451d89eefe66b19e010e48ece1cca07e58 ] + +Introduce ice_get_phy_model() to improve code readability + +Signed-off-by: Sergey Temerkhanov +Reviewed-by: Przemek Kitszel +Reviewed-by: Simon Horman +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 258f5f905815 ("ice: Add correct PHY lane assignment") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice.h | 5 +++++ + drivers/net/ethernet/intel/ice/ice_ptp.c | 19 +++++++++--------- + drivers/net/ethernet/intel/ice/ice_ptp_hw.c | 22 ++++++++++----------- + 3 files changed, 25 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h +index d6f80da30decf..558cda577191d 100644 +--- a/drivers/net/ethernet/intel/ice/ice.h ++++ b/drivers/net/ethernet/intel/ice/ice.h +@@ -1047,5 +1047,10 @@ static inline void ice_clear_rdma_cap(struct ice_pf *pf) + clear_bit(ICE_FLAG_RDMA_ENA, pf->flags); + } + ++static inline enum ice_phy_model ice_get_phy_model(const struct ice_hw *hw) ++{ ++ return hw->ptp.phy_model; ++} ++ + extern const struct xdp_metadata_ops ice_xdp_md_ops; + #endif /* _ICE_H_ */ +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c +index ef2e858f49bb0..d534c8e571cee 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c +@@ -1363,7 +1363,7 @@ ice_ptp_port_phy_stop(struct ice_ptp_port *ptp_port) + + mutex_lock(&ptp_port->ps_lock); + +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + err = ice_stop_phy_timer_eth56g(hw, port, true); + break; +@@ -1409,7 +1409,7 @@ ice_ptp_port_phy_restart(struct ice_ptp_port *ptp_port) + + mutex_lock(&ptp_port->ps_lock); + +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + err = ice_start_phy_timer_eth56g(hw, port); + break; +@@ -1480,8 +1480,7 @@ void ice_ptp_link_change(struct ice_pf *pf, u8 port, bool linkup) + /* Skip HW writes if reset is in progress */ + if (pf->hw.reset_ongoing) + return; +- +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_E810: + /* Do not reconfigure E810 PHY */ + return; +@@ -1514,7 +1513,7 @@ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold) + + ice_ptp_reset_ts_memory(hw); + +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: { + int port; + +@@ -1553,7 +1552,7 @@ static int ice_ptp_cfg_phy_interrupt(struct ice_pf *pf, bool ena, u32 threshold) + case ICE_PHY_UNSUP: + default: + dev_warn(dev, "%s: Unexpected PHY model %d\n", __func__, +- hw->ptp.phy_model); ++ ice_get_phy_model(hw)); + return -EOPNOTSUPP; + } + } +@@ -2059,7 +2058,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts) + /* For Vernier mode on E82X, we need to recalibrate after new settime. + * Start with marking timestamps as invalid. + */ +- if (hw->ptp.phy_model == ICE_PHY_E82X) { ++ if (ice_get_phy_model(hw) == ICE_PHY_E82X) { + err = ice_ptp_clear_phy_offset_ready_e82x(hw); + if (err) + dev_warn(ice_pf_to_dev(pf), "Failed to mark timestamps as invalid before settime\n"); +@@ -2083,7 +2082,7 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts) + ice_ptp_enable_all_clkout(pf); + + /* Recalibrate and re-enable timestamp blocks for E822/E823 */ +- if (hw->ptp.phy_model == ICE_PHY_E82X) ++ if (ice_get_phy_model(hw) == ICE_PHY_E82X) + ice_ptp_restart_all_phy(pf); + exit: + if (err) { +@@ -3209,7 +3208,7 @@ static int ice_ptp_init_port(struct ice_pf *pf, struct ice_ptp_port *ptp_port) + + mutex_init(&ptp_port->ps_lock); + +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + return ice_ptp_init_tx_eth56g(pf, &ptp_port->tx, + ptp_port->port_num); +@@ -3307,7 +3306,7 @@ static void ice_ptp_remove_auxbus_device(struct ice_pf *pf) + */ + static void ice_ptp_init_tx_interrupt_mode(struct ice_pf *pf) + { +- switch (pf->hw.ptp.phy_model) { ++ switch (ice_get_phy_model(&pf->hw)) { + case ICE_PHY_E82X: + /* E822 based PHY has the clock owner process the interrupt + * for all ports. +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +index 64c36620a02f3..28bd4815ebcf3 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.c +@@ -804,7 +804,7 @@ static u32 ice_ptp_tmr_cmd_to_port_reg(struct ice_hw *hw, + /* Certain hardware families share the same register values for the + * port register and source timer register. + */ +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_E810: + return ice_ptp_tmr_cmd_to_src_reg(hw, cmd) & TS_CMD_MASK_E810; + default: +@@ -5461,7 +5461,7 @@ void ice_ptp_init_hw(struct ice_hw *hw) + static int ice_ptp_write_port_cmd(struct ice_hw *hw, u8 port, + enum ice_ptp_tmr_cmd cmd) + { +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + return ice_ptp_write_port_cmd_eth56g(hw, port, cmd); + case ICE_PHY_E82X: +@@ -5526,7 +5526,7 @@ static int ice_ptp_port_cmd(struct ice_hw *hw, enum ice_ptp_tmr_cmd cmd) + u32 port; + + /* PHY models which can program all ports simultaneously */ +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_E810: + return ice_ptp_port_cmd_e810(hw, cmd); + default: +@@ -5605,7 +5605,7 @@ int ice_ptp_init_time(struct ice_hw *hw, u64 time) + + /* PHY timers */ + /* Fill Rx and Tx ports and send msg to PHY */ +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + err = ice_ptp_prep_phy_time_eth56g(hw, + (u32)(time & 0xFFFFFFFF)); +@@ -5651,7 +5651,7 @@ int ice_ptp_write_incval(struct ice_hw *hw, u64 incval) + wr32(hw, GLTSYN_SHADJ_L(tmr_idx), lower_32_bits(incval)); + wr32(hw, GLTSYN_SHADJ_H(tmr_idx), upper_32_bits(incval)); + +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + err = ice_ptp_prep_phy_incval_eth56g(hw, incval); + break; +@@ -5720,7 +5720,7 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj) + wr32(hw, GLTSYN_SHADJ_L(tmr_idx), 0); + wr32(hw, GLTSYN_SHADJ_H(tmr_idx), adj); + +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + err = ice_ptp_prep_phy_adj_eth56g(hw, adj); + break; +@@ -5753,7 +5753,7 @@ int ice_ptp_adj_clock(struct ice_hw *hw, s32 adj) + */ + int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp) + { +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + return ice_read_ptp_tstamp_eth56g(hw, block, idx, tstamp); + case ICE_PHY_E810: +@@ -5783,7 +5783,7 @@ int ice_read_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx, u64 *tstamp) + */ + int ice_clear_phy_tstamp(struct ice_hw *hw, u8 block, u8 idx) + { +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + return ice_clear_ptp_tstamp_eth56g(hw, block, idx); + case ICE_PHY_E810: +@@ -5846,7 +5846,7 @@ static int ice_get_pf_c827_idx(struct ice_hw *hw, u8 *idx) + */ + void ice_ptp_reset_ts_memory(struct ice_hw *hw) + { +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + ice_ptp_reset_ts_memory_eth56g(hw); + break; +@@ -5875,7 +5875,7 @@ int ice_ptp_init_phc(struct ice_hw *hw) + /* Clear event err indications for auxiliary pins */ + (void)rd32(hw, GLTSYN_STAT(src_idx)); + +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + return ice_ptp_init_phc_eth56g(hw); + case ICE_PHY_E810: +@@ -5900,7 +5900,7 @@ int ice_ptp_init_phc(struct ice_hw *hw) + */ + int ice_get_phy_tx_tstamp_ready(struct ice_hw *hw, u8 block, u64 *tstamp_ready) + { +- switch (hw->ptp.phy_model) { ++ switch (ice_get_phy_model(hw)) { + case ICE_PHY_ETH56G: + return ice_get_phy_tx_tstamp_ready_eth56g(hw, block, + tstamp_ready); +-- +2.39.5 + diff --git a/queue-6.12/ice-use-ice_adapter-for-ptp-shared-data-instead-of-a.patch b/queue-6.12/ice-use-ice_adapter-for-ptp-shared-data-instead-of-a.patch new file mode 100644 index 0000000000..87e657bb84 --- /dev/null +++ b/queue-6.12/ice-use-ice_adapter-for-ptp-shared-data-instead-of-a.patch @@ -0,0 +1,423 @@ +From 13950ae904c8b1b0bb82b6f65485d3a701716110 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 21 Aug 2024 15:09:56 +0200 +Subject: ice: Use ice_adapter for PTP shared data instead of auxdev + +From: Sergey Temerkhanov + +[ Upstream commit e800654e85b5b27966fc6493201f5f8cf658beb6 ] + +Use struct ice_adapter to hold shared PTP data and control PTP +related actions instead of auxbus. This allows significant code +simplification and faster access to the container fields used in +the PTP support code. + +Move the PTP port list to the ice_adapter container to simplify +the code and avoid race conditions which could occur due to the +synchronous nature of the initialization/access and +certain memory saving can be achieved by moving PTP data into +the ice_adapter itself. + +Signed-off-by: Sergey Temerkhanov +Reviewed-by: Przemek Kitszel +Reviewed-by: Simon Horman +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 258f5f905815 ("ice: Add correct PHY lane assignment") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_adapter.c | 6 + + drivers/net/ethernet/intel/ice/ice_adapter.h | 17 +++ + drivers/net/ethernet/intel/ice/ice_ptp.c | 115 ++++++++++++------- + drivers/net/ethernet/intel/ice/ice_ptp.h | 5 +- + drivers/net/ethernet/intel/ice/ice_ptp_hw.h | 5 + + 5 files changed, 105 insertions(+), 43 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.c b/drivers/net/ethernet/intel/ice/ice_adapter.c +index ad84d8ad49a63..f3e195974a8ef 100644 +--- a/drivers/net/ethernet/intel/ice/ice_adapter.c ++++ b/drivers/net/ethernet/intel/ice/ice_adapter.c +@@ -40,11 +40,17 @@ static struct ice_adapter *ice_adapter_new(void) + spin_lock_init(&adapter->ptp_gltsyn_time_lock); + refcount_set(&adapter->refcount, 1); + ++ mutex_init(&adapter->ports.lock); ++ INIT_LIST_HEAD(&adapter->ports.ports); ++ + return adapter; + } + + static void ice_adapter_free(struct ice_adapter *adapter) + { ++ WARN_ON(!list_empty(&adapter->ports.ports)); ++ mutex_destroy(&adapter->ports.lock); ++ + kfree(adapter); + } + +diff --git a/drivers/net/ethernet/intel/ice/ice_adapter.h b/drivers/net/ethernet/intel/ice/ice_adapter.h +index eb7cac01c2427..e233225848b38 100644 +--- a/drivers/net/ethernet/intel/ice/ice_adapter.h ++++ b/drivers/net/ethernet/intel/ice/ice_adapter.h +@@ -4,18 +4,34 @@ + #ifndef _ICE_ADAPTER_H_ + #define _ICE_ADAPTER_H_ + ++#include + #include + #include + + struct pci_dev; + struct ice_pf; + ++/** ++ * struct ice_port_list - data used to store the list of adapter ports ++ * ++ * This structure contains data used to maintain a list of adapter ports ++ * ++ * @ports: list of ports ++ * @lock: protect access to the ports list ++ */ ++struct ice_port_list { ++ struct list_head ports; ++ /* To synchronize the ports list operations */ ++ struct mutex lock; ++}; ++ + /** + * struct ice_adapter - PCI adapter resources shared across PFs + * @ptp_gltsyn_time_lock: Spinlock protecting access to the GLTSYN_TIME + * register of the PTP clock. + * @refcount: Reference count. struct ice_pf objects hold the references. + * @ctrl_pf: Control PF of the adapter ++ * @ports: Ports list + */ + struct ice_adapter { + refcount_t refcount; +@@ -23,6 +39,7 @@ struct ice_adapter { + spinlock_t ptp_gltsyn_time_lock; + + struct ice_pf *ctrl_pf; ++ struct ice_port_list ports; + }; + + struct ice_adapter *ice_adapter_get(const struct pci_dev *pdev); +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c +index 2fb73ab41bc20..0b3dd87a331c7 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp.c ++++ b/drivers/net/ethernet/intel/ice/ice_ptp.c +@@ -21,7 +21,7 @@ static struct ice_pf *ice_get_ctrl_pf(struct ice_pf *pf) + return !pf->adapter ? NULL : pf->adapter->ctrl_pf; + } + +-static __maybe_unused struct ice_ptp *ice_get_ctrl_ptp(struct ice_pf *pf) ++static struct ice_ptp *ice_get_ctrl_ptp(struct ice_pf *pf) + { + struct ice_pf *ctrl_pf = ice_get_ctrl_pf(pf); + +@@ -812,8 +812,8 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf) + struct ice_ptp_port *port; + unsigned int i; + +- mutex_lock(&pf->ptp.ports_owner.lock); +- list_for_each_entry(port, &pf->ptp.ports_owner.ports, list_member) { ++ mutex_lock(&pf->adapter->ports.lock); ++ list_for_each_entry(port, &pf->adapter->ports.ports, list_node) { + struct ice_ptp_tx *tx = &port->tx; + + if (!tx || !tx->init) +@@ -821,7 +821,7 @@ static enum ice_tx_tstamp_work ice_ptp_tx_tstamp_owner(struct ice_pf *pf) + + ice_ptp_process_tx_tstamp(tx); + } +- mutex_unlock(&pf->ptp.ports_owner.lock); ++ mutex_unlock(&pf->adapter->ports.lock); + + for (i = 0; i < ICE_GET_QUAD_NUM(pf->hw.ptp.num_lports); i++) { + u64 tstamp_ready; +@@ -986,7 +986,7 @@ ice_ptp_flush_all_tx_tracker(struct ice_pf *pf) + { + struct ice_ptp_port *port; + +- list_for_each_entry(port, &pf->ptp.ports_owner.ports, list_member) ++ list_for_each_entry(port, &pf->adapter->ports.ports, list_node) + ice_ptp_flush_tx_tracker(ptp_port_to_pf(port), &port->tx); + } + +@@ -1586,10 +1586,10 @@ static void ice_ptp_restart_all_phy(struct ice_pf *pf) + { + struct list_head *entry; + +- list_for_each(entry, &pf->ptp.ports_owner.ports) { ++ list_for_each(entry, &pf->adapter->ports.ports) { + struct ice_ptp_port *port = list_entry(entry, + struct ice_ptp_port, +- list_member); ++ list_node); + + if (port->link_up) + ice_ptp_port_phy_restart(port); +@@ -2906,6 +2906,50 @@ void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type) + dev_err(ice_pf_to_dev(pf), "PTP reset failed %d\n", err); + } + ++static bool ice_is_primary(struct ice_hw *hw) ++{ ++ return ice_is_e825c(hw) && ice_is_dual(hw) ? ++ !!(hw->dev_caps.nac_topo.mode & ICE_NAC_TOPO_PRIMARY_M) : true; ++} ++ ++static int ice_ptp_setup_adapter(struct ice_pf *pf) ++{ ++ if (!ice_pf_src_tmr_owned(pf) || !ice_is_primary(&pf->hw)) ++ return -EPERM; ++ ++ pf->adapter->ctrl_pf = pf; ++ ++ return 0; ++} ++ ++static int ice_ptp_setup_pf(struct ice_pf *pf) ++{ ++ struct ice_ptp *ctrl_ptp = ice_get_ctrl_ptp(pf); ++ struct ice_ptp *ptp = &pf->ptp; ++ ++ if (WARN_ON(!ctrl_ptp) || ice_get_phy_model(&pf->hw) == ICE_PHY_UNSUP) ++ return -ENODEV; ++ ++ INIT_LIST_HEAD(&ptp->port.list_node); ++ mutex_lock(&pf->adapter->ports.lock); ++ ++ list_add(&ptp->port.list_node, ++ &pf->adapter->ports.ports); ++ mutex_unlock(&pf->adapter->ports.lock); ++ ++ return 0; ++} ++ ++static void ice_ptp_cleanup_pf(struct ice_pf *pf) ++{ ++ struct ice_ptp *ptp = &pf->ptp; ++ ++ if (ice_get_phy_model(&pf->hw) != ICE_PHY_UNSUP) { ++ mutex_lock(&pf->adapter->ports.lock); ++ list_del(&ptp->port.list_node); ++ mutex_unlock(&pf->adapter->ports.lock); ++ } ++} + /** + * ice_ptp_aux_dev_to_aux_pf - Get auxiliary PF handle for the auxiliary device + * @aux_dev: auxiliary device to get the auxiliary PF for +@@ -2957,9 +3001,9 @@ static int ice_ptp_auxbus_probe(struct auxiliary_device *aux_dev, + if (WARN_ON(!owner_pf)) + return -ENODEV; + +- INIT_LIST_HEAD(&aux_pf->ptp.port.list_member); ++ INIT_LIST_HEAD(&aux_pf->ptp.port.list_node); + mutex_lock(&owner_pf->ptp.ports_owner.lock); +- list_add(&aux_pf->ptp.port.list_member, ++ list_add(&aux_pf->ptp.port.list_node, + &owner_pf->ptp.ports_owner.ports); + mutex_unlock(&owner_pf->ptp.ports_owner.lock); + +@@ -2976,7 +3020,7 @@ static void ice_ptp_auxbus_remove(struct auxiliary_device *aux_dev) + struct ice_pf *aux_pf = ice_ptp_aux_dev_to_aux_pf(aux_dev); + + mutex_lock(&owner_pf->ptp.ports_owner.lock); +- list_del(&aux_pf->ptp.port.list_member); ++ list_del(&aux_pf->ptp.port.list_node); + mutex_unlock(&owner_pf->ptp.ports_owner.lock); + } + +@@ -3036,7 +3080,7 @@ ice_ptp_auxbus_create_id_table(struct ice_pf *pf, const char *name) + * ice_ptp_register_auxbus_driver - Register PTP auxiliary bus driver + * @pf: Board private structure + */ +-static int ice_ptp_register_auxbus_driver(struct ice_pf *pf) ++static int __always_unused ice_ptp_register_auxbus_driver(struct ice_pf *pf) + { + struct auxiliary_driver *aux_driver; + struct ice_ptp *ptp; +@@ -3079,7 +3123,7 @@ static int ice_ptp_register_auxbus_driver(struct ice_pf *pf) + * ice_ptp_unregister_auxbus_driver - Unregister PTP auxiliary bus driver + * @pf: Board private structure + */ +-static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf) ++static void __always_unused ice_ptp_unregister_auxbus_driver(struct ice_pf *pf) + { + struct auxiliary_driver *aux_driver = &pf->ptp.ports_owner.aux_driver; + +@@ -3098,15 +3142,12 @@ static void ice_ptp_unregister_auxbus_driver(struct ice_pf *pf) + */ + int ice_ptp_clock_index(struct ice_pf *pf) + { +- struct auxiliary_device *aux_dev; +- struct ice_pf *owner_pf; ++ struct ice_ptp *ctrl_ptp = ice_get_ctrl_ptp(pf); + struct ptp_clock *clock; + +- aux_dev = &pf->ptp.port.aux_dev; +- owner_pf = ice_ptp_aux_dev_to_owner_pf(aux_dev); +- if (!owner_pf) ++ if (!ctrl_ptp) + return -1; +- clock = owner_pf->ptp.clock; ++ clock = ctrl_ptp->clock; + + return clock ? ptp_clock_index(clock) : -1; + } +@@ -3166,15 +3207,7 @@ static int ice_ptp_init_owner(struct ice_pf *pf) + if (err) + goto err_clk; + +- err = ice_ptp_register_auxbus_driver(pf); +- if (err) { +- dev_err(ice_pf_to_dev(pf), "Failed to register PTP auxbus driver"); +- goto err_aux; +- } +- + return 0; +-err_aux: +- ptp_clock_unregister(pf->ptp.clock); + err_clk: + pf->ptp.clock = NULL; + err_exit: +@@ -3250,7 +3283,7 @@ static void ice_ptp_release_auxbus_device(struct device *dev) + * ice_ptp_create_auxbus_device - Create PTP auxiliary bus device + * @pf: Board private structure + */ +-static int ice_ptp_create_auxbus_device(struct ice_pf *pf) ++static __always_unused int ice_ptp_create_auxbus_device(struct ice_pf *pf) + { + struct auxiliary_device *aux_dev; + struct ice_ptp *ptp; +@@ -3297,7 +3330,7 @@ static int ice_ptp_create_auxbus_device(struct ice_pf *pf) + * ice_ptp_remove_auxbus_device - Remove PTP auxiliary bus device + * @pf: Board private structure + */ +-static void ice_ptp_remove_auxbus_device(struct ice_pf *pf) ++static __always_unused void ice_ptp_remove_auxbus_device(struct ice_pf *pf) + { + struct auxiliary_device *aux_dev = &pf->ptp.port.aux_dev; + +@@ -3361,19 +3394,26 @@ void ice_ptp_init(struct ice_pf *pf) + /* If this function owns the clock hardware, it must allocate and + * configure the PTP clock device to represent it. + */ +- if (ice_pf_src_tmr_owned(pf)) { ++ if (ice_pf_src_tmr_owned(pf) && ice_is_primary(hw)) { ++ err = ice_ptp_setup_adapter(pf); ++ if (err) ++ goto err_exit; + err = ice_ptp_init_owner(pf); + if (err) +- goto err; ++ goto err_exit; + } + ++ err = ice_ptp_setup_pf(pf); ++ if (err) ++ goto err_exit; ++ + ptp->port.port_num = hw->pf_id; + if (ice_is_e825c(hw) && hw->ptp.is_2x50g_muxed_topo) + ptp->port.port_num = hw->pf_id * 2; + + err = ice_ptp_init_port(pf, &ptp->port); + if (err) +- goto err; ++ goto err_exit; + + /* Start the PHY timestamping block */ + ice_ptp_reset_phy_timestamping(pf); +@@ -3381,20 +3421,16 @@ void ice_ptp_init(struct ice_pf *pf) + /* Configure initial Tx interrupt settings */ + ice_ptp_cfg_tx_interrupt(pf); + +- err = ice_ptp_create_auxbus_device(pf); +- if (err) +- goto err; +- + ptp->state = ICE_PTP_READY; + + err = ice_ptp_init_work(pf, ptp); + if (err) +- goto err; ++ goto err_exit; + + dev_info(ice_pf_to_dev(pf), "PTP init successful\n"); + return; + +-err: ++err_exit: + /* If we registered a PTP clock, release it */ + if (pf->ptp.clock) { + ptp_clock_unregister(ptp->clock); +@@ -3421,7 +3457,7 @@ void ice_ptp_release(struct ice_pf *pf) + /* Disable timestamping for both Tx and Rx */ + ice_ptp_disable_timestamp_mode(pf); + +- ice_ptp_remove_auxbus_device(pf); ++ ice_ptp_cleanup_pf(pf); + + ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx); + +@@ -3436,9 +3472,6 @@ void ice_ptp_release(struct ice_pf *pf) + pf->ptp.kworker = NULL; + } + +- if (ice_pf_src_tmr_owned(pf)) +- ice_ptp_unregister_auxbus_driver(pf); +- + if (!pf->ptp.clock) + return; + +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.h b/drivers/net/ethernet/intel/ice/ice_ptp.h +index 2db2257a0fb2f..5615efc42c624 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp.h ++++ b/drivers/net/ethernet/intel/ice/ice_ptp.h +@@ -169,7 +169,7 @@ struct ice_ptp_tx { + * ready for PTP functionality. It is used to track the port initialization + * and determine when the port's PHY offset is valid. + * +- * @list_member: list member structure of auxiliary device ++ * @list_node: list member structure + * @tx: Tx timestamp tracking for this port + * @aux_dev: auxiliary device associated with this port + * @ov_work: delayed work task for tracking when PHY offset is valid +@@ -179,7 +179,7 @@ struct ice_ptp_tx { + * @port_num: the port number this structure represents + */ + struct ice_ptp_port { +- struct list_head list_member; ++ struct list_head list_node; + struct ice_ptp_tx tx; + struct auxiliary_device aux_dev; + struct kthread_delayed_work ov_work; +@@ -205,6 +205,7 @@ enum ice_ptp_tx_interrupt { + * @ports: list of porst handled by this port owner + * @lock: protect access to ports list + */ ++ + struct ice_ptp_port_owner { + struct auxiliary_driver aux_driver; + struct list_head ports; +diff --git a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +index 4c8b845713442..3499062218b59 100644 +--- a/drivers/net/ethernet/intel/ice/ice_ptp_hw.h ++++ b/drivers/net/ethernet/intel/ice/ice_ptp_hw.h +@@ -452,6 +452,11 @@ static inline u64 ice_get_base_incval(struct ice_hw *hw) + } + } + ++static inline bool ice_is_dual(struct ice_hw *hw) ++{ ++ return !!(hw->dev_caps.nac_topo.mode & ICE_NAC_TOPO_DUAL_M); ++} ++ + #define PFTSYN_SEM_BYTES 4 + + #define ICE_PTP_CLOCK_INDEX_0 0x00 +-- +2.39.5 + diff --git a/queue-6.12/net-ethernet-ti-cpsw_ale-fix-cpsw_ale_get_field.patch b/queue-6.12/net-ethernet-ti-cpsw_ale-fix-cpsw_ale_get_field.patch new file mode 100644 index 0000000000..a049f6cc5b --- /dev/null +++ b/queue-6.12/net-ethernet-ti-cpsw_ale-fix-cpsw_ale_get_field.patch @@ -0,0 +1,86 @@ +From 08066a194d4b435268fe89c571c760b35b657dc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2025 22:54:33 +0530 +Subject: net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field() + +From: Sudheer Kumar Doredla + +[ Upstream commit 03d120f27d050336f7e7d21879891542c4741f81 ] + +CPSW ALE has 75-bit ALE entries stored across three 32-bit words. +The cpsw_ale_get_field() and cpsw_ale_set_field() functions support +ALE field entries spanning up to two words at the most. + +The cpsw_ale_get_field() and cpsw_ale_set_field() functions work as +expected when ALE field spanned across word1 and word2, but fails when +ALE field spanned across word2 and word3. + +For example, while reading the ALE field spanned across word2 and word3 +(i.e. bits 62 to 64), the word3 data shifted to an incorrect position +due to the index becoming zero while flipping. +The same issue occurred when setting an ALE entry. + +This issue has not been seen in practice but will be an issue in the future +if the driver supports accessing ALE fields spanning word2 and word3 + +Fix the methods to handle getting/setting fields spanning up to two words. + +Fixes: b685f1a58956 ("net: ethernet: ti: cpsw_ale: Fix cpsw_ale_get_field()/cpsw_ale_set_field()") +Signed-off-by: Sudheer Kumar Doredla +Reviewed-by: Simon Horman +Reviewed-by: Roger Quadros +Reviewed-by: Siddharth Vadapalli +Link: https://patch.msgid.link/20250108172433.311694-1-s-doredla@ti.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/ti/cpsw_ale.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/ti/cpsw_ale.c b/drivers/net/ethernet/ti/cpsw_ale.c +index 8d02d2b214293..dc5e247ca5d1a 100644 +--- a/drivers/net/ethernet/ti/cpsw_ale.c ++++ b/drivers/net/ethernet/ti/cpsw_ale.c +@@ -127,15 +127,15 @@ struct cpsw_ale_dev_id { + + static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) + { +- int idx, idx2; ++ int idx, idx2, index; + u32 hi_val = 0; + + idx = start / 32; + idx2 = (start + bits - 1) / 32; + /* Check if bits to be fetched exceed a word */ + if (idx != idx2) { +- idx2 = 2 - idx2; /* flip */ +- hi_val = ale_entry[idx2] << ((idx2 * 32) - start); ++ index = 2 - idx2; /* flip */ ++ hi_val = ale_entry[index] << ((idx2 * 32) - start); + } + start -= idx * 32; + idx = 2 - idx; /* flip */ +@@ -145,16 +145,16 @@ static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits) + static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, + u32 value) + { +- int idx, idx2; ++ int idx, idx2, index; + + value &= BITMASK(bits); + idx = start / 32; + idx2 = (start + bits - 1) / 32; + /* Check if bits to be set exceed a word */ + if (idx != idx2) { +- idx2 = 2 - idx2; /* flip */ +- ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32))); +- ale_entry[idx2] |= (value >> ((idx2 * 32) - start)); ++ index = 2 - idx2; /* flip */ ++ ale_entry[index] &= ~(BITMASK(bits + start - (idx2 * 32))); ++ ale_entry[index] |= (value >> ((idx2 * 32) - start)); + } + start -= idx * 32; + idx = 2 - idx; /* flip */ +-- +2.39.5 + diff --git a/queue-6.12/net-fec-handle-page_pool_dev_alloc_pages-error.patch b/queue-6.12/net-fec-handle-page_pool_dev_alloc_pages-error.patch new file mode 100644 index 0000000000..7f90f5aa94 --- /dev/null +++ b/queue-6.12/net-fec-handle-page_pool_dev_alloc_pages-error.patch @@ -0,0 +1,96 @@ +From 7c38868fc6519ce1066b30e5a4bda7acdb32b298 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jan 2025 10:48:45 -0500 +Subject: net: fec: handle page_pool_dev_alloc_pages error + +From: Kevin Groeneveld + +[ Upstream commit 001ba0902046cb6c352494df610718c0763e77a5 ] + +The fec_enet_update_cbd function calls page_pool_dev_alloc_pages but did +not handle the case when it returned NULL. There was a WARN_ON(!new_page) +but it would still proceed to use the NULL pointer and then crash. + +This case does seem somewhat rare but when the system is under memory +pressure it can happen. One case where I can duplicate this with some +frequency is when writing over a smbd share to a SATA HDD attached to an +imx6q. + +Setting /proc/sys/vm/min_free_kbytes to higher values also seems to solve +the problem for my test case. But it still seems wrong that the fec driver +ignores the memory allocation error and can crash. + +This commit handles the allocation error by dropping the current packet. + +Fixes: 95698ff6177b5 ("net: fec: using page pool to manage RX buffers") +Signed-off-by: Kevin Groeneveld +Reviewed-by: Jacob Keller +Reviewed-by: Wei Fang +Link: https://patch.msgid.link/20250113154846.1765414-1-kgroeneveld@lenbrook.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/freescale/fec_main.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c +index 9d9fcec41488e..49d1748e0c043 100644 +--- a/drivers/net/ethernet/freescale/fec_main.c ++++ b/drivers/net/ethernet/freescale/fec_main.c +@@ -1591,19 +1591,22 @@ static void fec_enet_tx(struct net_device *ndev, int budget) + fec_enet_tx_queue(ndev, i, budget); + } + +-static void fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq, ++static int fec_enet_update_cbd(struct fec_enet_priv_rx_q *rxq, + struct bufdesc *bdp, int index) + { + struct page *new_page; + dma_addr_t phys_addr; + + new_page = page_pool_dev_alloc_pages(rxq->page_pool); +- WARN_ON(!new_page); +- rxq->rx_skb_info[index].page = new_page; ++ if (unlikely(!new_page)) ++ return -ENOMEM; + ++ rxq->rx_skb_info[index].page = new_page; + rxq->rx_skb_info[index].offset = FEC_ENET_XDP_HEADROOM; + phys_addr = page_pool_get_dma_addr(new_page) + FEC_ENET_XDP_HEADROOM; + bdp->cbd_bufaddr = cpu_to_fec32(phys_addr); ++ ++ return 0; + } + + static u32 +@@ -1698,6 +1701,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) + int cpu = smp_processor_id(); + struct xdp_buff xdp; + struct page *page; ++ __fec32 cbd_bufaddr; + u32 sub_len = 4; + + #if !defined(CONFIG_M5272) +@@ -1766,12 +1770,17 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id) + + index = fec_enet_get_bd_index(bdp, &rxq->bd); + page = rxq->rx_skb_info[index].page; ++ cbd_bufaddr = bdp->cbd_bufaddr; ++ if (fec_enet_update_cbd(rxq, bdp, index)) { ++ ndev->stats.rx_dropped++; ++ goto rx_processing_done; ++ } ++ + dma_sync_single_for_cpu(&fep->pdev->dev, +- fec32_to_cpu(bdp->cbd_bufaddr), ++ fec32_to_cpu(cbd_bufaddr), + pkt_len, + DMA_FROM_DEVICE); + prefetch(page_address(page)); +- fec_enet_update_cbd(rxq, bdp, index); + + if (xdp_prog) { + xdp_buff_clear_frags_flag(&xdp); +-- +2.39.5 + diff --git a/queue-6.12/net-make-page_pool_ref_netmem-work-with-net-iovs.patch b/queue-6.12/net-make-page_pool_ref_netmem-work-with-net-iovs.patch new file mode 100644 index 0000000000..f84270d264 --- /dev/null +++ b/queue-6.12/net-make-page_pool_ref_netmem-work-with-net-iovs.patch @@ -0,0 +1,39 @@ +From 1cfae25c3112fee653b469824140de68e4fb7d26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2025 14:06:22 -0800 +Subject: net: make page_pool_ref_netmem work with net iovs + +From: Pavel Begunkov + +[ Upstream commit cbc16bceea784210d585a42ac9f8f10ce62b300e ] + +page_pool_ref_netmem() should work with either netmem representation, but +currently it casts to a page with netmem_to_page(), which will fail with +net iovs. Use netmem_get_pp_ref_count_ref() instead. + +Fixes: 8ab79ed50cf1 ("page_pool: devmem support") +Signed-off-by: Pavel Begunkov +Signed-off-by: David Wei +Link: https://lore.kernel.org/20250108220644.3528845-2-dw@davidwei.uk +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/page_pool/helpers.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h +index 793e6fd78bc5c..60a5347922bec 100644 +--- a/include/net/page_pool/helpers.h ++++ b/include/net/page_pool/helpers.h +@@ -294,7 +294,7 @@ static inline long page_pool_unref_page(struct page *page, long nr) + + static inline void page_pool_ref_netmem(netmem_ref netmem) + { +- atomic_long_inc(&netmem_to_page(netmem)->pp_ref_count); ++ atomic_long_inc(netmem_get_pp_ref_count_ref(netmem)); + } + + static inline void page_pool_ref_page(struct page *page) +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5-clear-port-select-structure-when-fail-to-cr.patch b/queue-6.12/net-mlx5-clear-port-select-structure-when-fail-to-cr.patch new file mode 100644 index 0000000000..06666db39d --- /dev/null +++ b/queue-6.12/net-mlx5-clear-port-select-structure-when-fail-to-cr.patch @@ -0,0 +1,107 @@ +From c1cb7d99d032c187b2fea5a32b3c8f09741c9c58 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Jan 2025 13:39:07 +0200 +Subject: net/mlx5: Clear port select structure when fail to create + +From: Mark Zhang + +[ Upstream commit 5641e82cb55b4ecbc6366a499300917d2f3e6790 ] + +Clear the port select structure on error so no stale values left after +definers are destroyed. That's because the mlx5_lag_destroy_definers() +always try to destroy all lag definers in the tt_map, so in the flow +below lag definers get double-destroyed and cause kernel crash: + + mlx5_lag_port_sel_create() + mlx5_lag_create_definers() + mlx5_lag_create_definer() <- Failed on tt 1 + mlx5_lag_destroy_definers() <- definers[tt=0] gets destroyed + mlx5_lag_port_sel_create() + mlx5_lag_create_definers() + mlx5_lag_create_definer() <- Failed on tt 0 + mlx5_lag_destroy_definers() <- definers[tt=0] gets double-destroyed + + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008 + Mem abort info: + ESR = 0x0000000096000005 + EC = 0x25: DABT (current EL), IL = 32 bits + SET = 0, FnV = 0 + EA = 0, S1PTW = 0 + FSC = 0x05: level 1 translation fault + Data abort info: + ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 + CM = 0, WnR = 0, TnD = 0, TagAccess = 0 + GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 + user pgtable: 64k pages, 48-bit VAs, pgdp=0000000112ce2e00 + [0000000000000008] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 + Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP + Modules linked in: iptable_raw bonding ip_gre ip6_gre gre ip6_tunnel tunnel6 geneve ip6_udp_tunnel udp_tunnel ipip tunnel4 ip_tunnel rdma_ucm(OE) rdma_cm(OE) iw_cm(OE) ib_ipoib(OE) ib_cm(OE) ib_umad(OE) mlx5_ib(OE) ib_uverbs(OE) mlx5_fwctl(OE) fwctl(OE) mlx5_core(OE) mlxdevm(OE) ib_core(OE) mlxfw(OE) memtrack(OE) mlx_compat(OE) openvswitch nsh nf_conncount psample xt_conntrack xt_MASQUERADE nf_conntrack_netlink nfnetlink xfrm_user xfrm_algo xt_addrtype iptable_filter iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 br_netfilter bridge stp llc netconsole overlay efi_pstore sch_fq_codel zram ip_tables crct10dif_ce qemu_fw_cfg fuse ipv6 crc_ccitt [last unloaded: mlx_compat(OE)] + CPU: 3 UID: 0 PID: 217 Comm: kworker/u53:2 Tainted: G OE 6.11.0+ #2 + Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE + Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015 + Workqueue: mlx5_lag mlx5_do_bond_work [mlx5_core] + pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + pc : mlx5_del_flow_rules+0x24/0x2c0 [mlx5_core] + lr : mlx5_lag_destroy_definer+0x54/0x100 [mlx5_core] + sp : ffff800085fafb00 + x29: ffff800085fafb00 x28: ffff0000da0c8000 x27: 0000000000000000 + x26: ffff0000da0c8000 x25: ffff0000da0c8000 x24: ffff0000da0c8000 + x23: ffff0000c31f81a0 x22: 0400000000000000 x21: ffff0000da0c8000 + x20: 0000000000000000 x19: 0000000000000001 x18: 0000000000000000 + x17: 0000000000000000 x16: 0000000000000000 x15: 0000ffff8b0c9350 + x14: 0000000000000000 x13: ffff800081390d18 x12: ffff800081dc3cc0 + x11: 0000000000000001 x10: 0000000000000b10 x9 : ffff80007ab7304c + x8 : ffff0000d00711f0 x7 : 0000000000000004 x6 : 0000000000000190 + x5 : ffff00027edb3010 x4 : 0000000000000000 x3 : 0000000000000000 + x2 : ffff0000d39b8000 x1 : ffff0000d39b8000 x0 : 0400000000000000 + Call trace: + mlx5_del_flow_rules+0x24/0x2c0 [mlx5_core] + mlx5_lag_destroy_definer+0x54/0x100 [mlx5_core] + mlx5_lag_destroy_definers+0xa0/0x108 [mlx5_core] + mlx5_lag_port_sel_create+0x2d4/0x6f8 [mlx5_core] + mlx5_activate_lag+0x60c/0x6f8 [mlx5_core] + mlx5_do_bond_work+0x284/0x5c8 [mlx5_core] + process_one_work+0x170/0x3e0 + worker_thread+0x2d8/0x3e0 + kthread+0x11c/0x128 + ret_from_fork+0x10/0x20 + Code: a9025bf5 aa0003f6 a90363f7 f90023f9 (f9400400) + ---[ end trace 0000000000000000 ]--- + +Fixes: dc48516ec7d3 ("net/mlx5: Lag, add support to create definers for LAG") +Signed-off-by: Mark Zhang +Reviewed-by: Leon Romanovsky +Reviewed-by: Mark Bloch +Reviewed-by: Jacob Keller +Signed-off-by: Tariq Toukan +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c +index ab2717012b79b..39e80704b1c42 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/port_sel.c +@@ -530,7 +530,7 @@ int mlx5_lag_port_sel_create(struct mlx5_lag *ldev, + set_tt_map(port_sel, hash_type); + err = mlx5_lag_create_definers(ldev, hash_type, ports); + if (err) +- return err; ++ goto clear_port_sel; + + if (port_sel->tunnel) { + err = mlx5_lag_create_inner_ttc_table(ldev); +@@ -549,6 +549,8 @@ int mlx5_lag_port_sel_create(struct mlx5_lag *ldev, + mlx5_destroy_ttc_table(port_sel->inner.ttc); + destroy_definers: + mlx5_lag_destroy_definers(ldev); ++clear_port_sel: ++ memset(port_sel, 0, sizeof(*port_sel)); + return err; + } + +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5-fix-a-lockdep-warning-as-part-of-the-write-.patch b/queue-6.12/net-mlx5-fix-a-lockdep-warning-as-part-of-the-write-.patch new file mode 100644 index 0000000000..0975cfee89 --- /dev/null +++ b/queue-6.12/net-mlx5-fix-a-lockdep-warning-as-part-of-the-write-.patch @@ -0,0 +1,182 @@ +From 8ad0d10eec030a9460c1d4ca779ae6b39445d0ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Jan 2025 13:39:05 +0200 +Subject: net/mlx5: Fix a lockdep warning as part of the write combining test + +From: Yishai Hadas + +[ Upstream commit 1b10a519a45704d4b06ebd9245b272d145752c18 ] + +Fix a lockdep warning [1] observed during the write combining test. + +The warning indicates a potential nested lock scenario that could lead +to a deadlock. + +However, this is a false positive alarm because the SF lock and its +parent lock are distinct ones. + +The lockdep confusion arises because the locks belong to the same object +class (i.e., struct mlx5_core_dev). + +To resolve this, the code has been refactored to avoid taking both +locks. Instead, only the parent lock is acquired. + +[1] +raw_ethernet_bw/2118 is trying to acquire lock: +[ 213.619032] ffff88811dd75e08 (&dev->wc_state_lock){+.+.}-{3:3}, at: + mlx5_wc_support_get+0x18c/0x210 [mlx5_core] +[ 213.620270] +[ 213.620270] but task is already holding lock: +[ 213.620943] ffff88810b585e08 (&dev->wc_state_lock){+.+.}-{3:3}, at: + mlx5_wc_support_get+0x10c/0x210 [mlx5_core] +[ 213.622045] +[ 213.622045] other info that might help us debug this: +[ 213.622778] Possible unsafe locking scenario: +[ 213.622778] +[ 213.623465] CPU0 +[ 213.623815] ---- +[ 213.624148] lock(&dev->wc_state_lock); +[ 213.624615] lock(&dev->wc_state_lock); +[ 213.625071] +[ 213.625071] *** DEADLOCK *** +[ 213.625071] +[ 213.625805] May be due to missing lock nesting notation +[ 213.625805] +[ 213.626522] 4 locks held by raw_ethernet_bw/2118: +[ 213.627019] #0: ffff88813f80d578 (&uverbs_dev->disassociate_srcu){.+.+}-{0:0}, + at: ib_uverbs_ioctl+0xc4/0x170 [ib_uverbs] +[ 213.628088] #1: ffff88810fb23930 (&file->hw_destroy_rwsem){.+.+}-{3:3}, + at: ib_init_ucontext+0x2d/0xf0 [ib_uverbs] +[ 213.629094] #2: ffff88810fb23878 (&file->ucontext_lock){+.+.}-{3:3}, + at: ib_init_ucontext+0x49/0xf0 [ib_uverbs] +[ 213.630106] #3: ffff88810b585e08 (&dev->wc_state_lock){+.+.}-{3:3}, + at: mlx5_wc_support_get+0x10c/0x210 [mlx5_core] +[ 213.631185] +[ 213.631185] stack backtrace: +[ 213.631718] CPU: 1 UID: 0 PID: 2118 Comm: raw_ethernet_bw Not tainted + 6.12.0-rc7_internal_net_next_mlx5_89a0ad0 #1 +[ 213.632722] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS + rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 +[ 213.633785] Call Trace: +[ 213.634099] +[ 213.634393] dump_stack_lvl+0x7e/0xc0 +[ 213.634806] print_deadlock_bug+0x278/0x3c0 +[ 213.635265] __lock_acquire+0x15f4/0x2c40 +[ 213.635712] lock_acquire+0xcd/0x2d0 +[ 213.636120] ? mlx5_wc_support_get+0x18c/0x210 [mlx5_core] +[ 213.636722] ? mlx5_ib_enable_lb+0x24/0xa0 [mlx5_ib] +[ 213.637277] __mutex_lock+0x81/0xda0 +[ 213.637697] ? mlx5_wc_support_get+0x18c/0x210 [mlx5_core] +[ 213.638305] ? mlx5_wc_support_get+0x18c/0x210 [mlx5_core] +[ 213.638902] ? rcu_read_lock_sched_held+0x3f/0x70 +[ 213.639400] ? mlx5_wc_support_get+0x18c/0x210 [mlx5_core] +[ 213.640016] mlx5_wc_support_get+0x18c/0x210 [mlx5_core] +[ 213.640615] set_ucontext_resp+0x68/0x2b0 [mlx5_ib] +[ 213.641144] ? debug_mutex_init+0x33/0x40 +[ 213.641586] mlx5_ib_alloc_ucontext+0x18e/0x7b0 [mlx5_ib] +[ 213.642145] ib_init_ucontext+0xa0/0xf0 [ib_uverbs] +[ 213.642679] ib_uverbs_handler_UVERBS_METHOD_GET_CONTEXT+0x95/0xc0 + [ib_uverbs] +[ 213.643426] ? _copy_from_user+0x46/0x80 +[ 213.643878] ib_uverbs_cmd_verbs+0xa6b/0xc80 [ib_uverbs] +[ 213.644426] ? ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x130/0x130 + [ib_uverbs] +[ 213.645213] ? __lock_acquire+0xa99/0x2c40 +[ 213.645675] ? lock_acquire+0xcd/0x2d0 +[ 213.646101] ? ib_uverbs_ioctl+0xc4/0x170 [ib_uverbs] +[ 213.646625] ? reacquire_held_locks+0xcf/0x1f0 +[ 213.647102] ? do_user_addr_fault+0x45d/0x770 +[ 213.647586] ib_uverbs_ioctl+0xe0/0x170 [ib_uverbs] +[ 213.648102] ? ib_uverbs_ioctl+0xc4/0x170 [ib_uverbs] +[ 213.648632] __x64_sys_ioctl+0x4d3/0xaa0 +[ 213.649060] ? do_user_addr_fault+0x4a8/0x770 +[ 213.649528] do_syscall_64+0x6d/0x140 +[ 213.649947] entry_SYSCALL_64_after_hwframe+0x4b/0x53 +[ 213.650478] RIP: 0033:0x7fa179b0737b +[ 213.650893] Code: ff ff ff 85 c0 79 9b 49 c7 c4 ff ff ff ff 5b 5d 4c + 89 e0 41 5c c3 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 + 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d + 7d 2a 0f 00 f7 d8 64 89 01 48 +[ 213.652619] RSP: 002b:00007ffd2e6d46e8 EFLAGS: 00000246 ORIG_RAX: + 0000000000000010 +[ 213.653390] RAX: ffffffffffffffda RBX: 00007ffd2e6d47f8 RCX: + 00007fa179b0737b +[ 213.654084] RDX: 00007ffd2e6d47e0 RSI: 00000000c0181b01 RDI: + 0000000000000003 +[ 213.654767] RBP: 00007ffd2e6d47c0 R08: 00007fa1799be010 R09: + 0000000000000002 +[ 213.655453] R10: 00007ffd2e6d4960 R11: 0000000000000246 R12: + 00007ffd2e6d487c +[ 213.656170] R13: 0000000000000027 R14: 0000000000000001 R15: + 00007ffd2e6d4f70 + +Fixes: d98995b4bf98 ("net/mlx5: Reimplement write combining test") +Signed-off-by: Yishai Hadas +Reviewed-by: Michael Guralnik +Reviewed-by: Larysa Zaremba +Signed-off-by: Tariq Toukan +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/wc.c | 24 ++++++++++---------- + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/wc.c b/drivers/net/ethernet/mellanox/mlx5/core/wc.c +index 1bed75eca97db..740b719e7072d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/wc.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/wc.c +@@ -382,6 +382,7 @@ static void mlx5_core_test_wc(struct mlx5_core_dev *mdev) + + bool mlx5_wc_support_get(struct mlx5_core_dev *mdev) + { ++ struct mutex *wc_state_lock = &mdev->wc_state_lock; + struct mlx5_core_dev *parent = NULL; + + if (!MLX5_CAP_GEN(mdev, bf)) { +@@ -400,32 +401,31 @@ bool mlx5_wc_support_get(struct mlx5_core_dev *mdev) + */ + goto out; + +- mutex_lock(&mdev->wc_state_lock); +- +- if (mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED) +- goto unlock; +- + #ifdef CONFIG_MLX5_SF +- if (mlx5_core_is_sf(mdev)) ++ if (mlx5_core_is_sf(mdev)) { + parent = mdev->priv.parent_mdev; ++ wc_state_lock = &parent->wc_state_lock; ++ } + #endif + +- if (parent) { +- mutex_lock(&parent->wc_state_lock); ++ mutex_lock(wc_state_lock); + ++ if (mdev->wc_state != MLX5_WC_STATE_UNINITIALIZED) ++ goto unlock; ++ ++ if (parent) { + mlx5_core_test_wc(parent); + + mlx5_core_dbg(mdev, "parent set wc_state=%d\n", + parent->wc_state); + mdev->wc_state = parent->wc_state; + +- mutex_unlock(&parent->wc_state_lock); ++ } else { ++ mlx5_core_test_wc(mdev); + } + +- mlx5_core_test_wc(mdev); +- + unlock: +- mutex_unlock(&mdev->wc_state_lock); ++ mutex_unlock(wc_state_lock); + out: + mlx5_core_dbg(mdev, "wc_state=%d\n", mdev->wc_state); + +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5-fix-rdma-tx-steering-prio.patch b/queue-6.12/net-mlx5-fix-rdma-tx-steering-prio.patch new file mode 100644 index 0000000000..ad127f92f4 --- /dev/null +++ b/queue-6.12/net-mlx5-fix-rdma-tx-steering-prio.patch @@ -0,0 +1,39 @@ +From 9af9e9d637f1b404a1de562e5cd29a56f3ac597d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Jan 2025 13:39:04 +0200 +Subject: net/mlx5: Fix RDMA TX steering prio + +From: Patrisious Haddad + +[ Upstream commit c08d3e62b2e73e14da318a1d20b52d0486a28ee0 ] + +User added steering rules at RDMA_TX were being added to the first prio, +which is the counters prio. +Fix that so that they are correctly added to the BYPASS_PRIO instead. + +Fixes: 24670b1a3166 ("net/mlx5: Add support for RDMA TX steering") +Signed-off-by: Patrisious Haddad +Reviewed-by: Mark Bloch +Reviewed-by: Jacob Keller +Signed-off-by: Tariq Toukan +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +index 2eabfcc247c6a..0ce999706d412 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +@@ -2709,6 +2709,7 @@ struct mlx5_flow_namespace *mlx5_get_flow_namespace(struct mlx5_core_dev *dev, + break; + case MLX5_FLOW_NAMESPACE_RDMA_TX: + root_ns = steering->rdma_tx_root_ns; ++ prio = RDMA_TX_BYPASS_PRIO; + break; + case MLX5_FLOW_NAMESPACE_RDMA_RX_COUNTERS: + root_ns = steering->rdma_rx_root_ns; +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5-sf-fix-add-port-error-handling.patch b/queue-6.12/net-mlx5-sf-fix-add-port-error-handling.patch new file mode 100644 index 0000000000..378c7f17c7 --- /dev/null +++ b/queue-6.12/net-mlx5-sf-fix-add-port-error-handling.patch @@ -0,0 +1,42 @@ +From e6450ecb8ab8d0e193a4f6d1c632f164e429fb78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Jan 2025 13:39:06 +0200 +Subject: net/mlx5: SF, Fix add port error handling + +From: Chris Mi + +[ Upstream commit 2011a2a18ef00b5b8e4b753acbe6451a8c5f2260 ] + +If failed to add SF, error handling doesn't delete the SF from the +SF table. But the hw resources are deleted. So when unload driver, +hw resources will be deleted again. Firmware will report syndrome +0x68def3 which means "SF is not allocated can not deallocate". + +Fix it by delete SF from SF table if failed to add SF. + +Fixes: 2597ee190b4e ("net/mlx5: Call mlx5_sf_id_erase() once in mlx5_sf_dealloc()") +Signed-off-by: Chris Mi +Reviewed-by: Shay Drori +Reviewed-by: Jacob Keller +Signed-off-by: Tariq Toukan +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c +index a96be98be032f..b96909fbeb12d 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/devlink.c +@@ -257,6 +257,7 @@ static int mlx5_sf_add(struct mlx5_core_dev *dev, struct mlx5_sf_table *table, + return 0; + + esw_err: ++ mlx5_sf_function_id_erase(table, sf); + mlx5_sf_free(table, sf); + return err; + } +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5e-always-start-ipsec-sequence-number-from-1.patch b/queue-6.12/net-mlx5e-always-start-ipsec-sequence-number-from-1.patch new file mode 100644 index 0000000000..d4bcf1c954 --- /dev/null +++ b/queue-6.12/net-mlx5e-always-start-ipsec-sequence-number-from-1.patch @@ -0,0 +1,85 @@ +From 35956515527c7d8b6c6f1490e30e19ed941755fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Jan 2025 13:39:10 +0200 +Subject: net/mlx5e: Always start IPsec sequence number from 1 + +From: Leon Romanovsky + +[ Upstream commit 7f95b0247764acd739d949ff247db4b76138e55a ] + +According to RFC4303, section "3.3.3. Sequence Number Generation", +the first packet sent using a given SA will contain a sequence +number of 1. + +This is applicable to both ESN and non-ESN mode, which was not covered +in commit mentioned in Fixes line. + +Fixes: 3d42c8cc67a8 ("net/mlx5e: Ensure that IPsec sequence packet number starts from 1") +Signed-off-by: Leon Romanovsky +Reviewed-by: Jacob Keller +Signed-off-by: Tariq Toukan +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 6 ++++++ + .../mellanox/mlx5/core/en_accel/ipsec_offload.c | 11 ++++++++--- + 2 files changed, 14 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +index 21857474ad83f..1baf8933a07cb 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +@@ -724,6 +724,12 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x, + /* check esn */ + if (x->props.flags & XFRM_STATE_ESN) + mlx5e_ipsec_update_esn_state(sa_entry); ++ else ++ /* According to RFC4303, section "3.3.3. Sequence Number Generation", ++ * the first packet sent using a given SA will contain a sequence ++ * number of 1. ++ */ ++ sa_entry->esn_state.esn = 1; + + mlx5e_ipsec_build_accel_xfrm_attrs(sa_entry, &sa_entry->attrs); + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +index 53cfa39188cb0..820debf3fbbf2 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_offload.c +@@ -91,8 +91,9 @@ u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev) + EXPORT_SYMBOL_GPL(mlx5_ipsec_device_caps); + + static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn, +- struct mlx5_accel_esp_xfrm_attrs *attrs) ++ struct mlx5e_ipsec_sa_entry *sa_entry) + { ++ struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs; + void *aso_ctx; + + aso_ctx = MLX5_ADDR_OF(ipsec_obj, obj, ipsec_aso); +@@ -120,8 +121,12 @@ static void mlx5e_ipsec_packet_setup(void *obj, u32 pdn, + * active. + */ + MLX5_SET(ipsec_obj, obj, aso_return_reg, MLX5_IPSEC_ASO_REG_C_4_5); +- if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) ++ if (attrs->dir == XFRM_DEV_OFFLOAD_OUT) { + MLX5_SET(ipsec_aso, aso_ctx, mode, MLX5_IPSEC_ASO_INC_SN); ++ if (!attrs->replay_esn.trigger) ++ MLX5_SET(ipsec_aso, aso_ctx, mode_parameter, ++ sa_entry->esn_state.esn); ++ } + + if (attrs->lft.hard_packet_limit != XFRM_INF) { + MLX5_SET(ipsec_aso, aso_ctx, remove_flow_pkt_cnt, +@@ -175,7 +180,7 @@ static int mlx5_create_ipsec_obj(struct mlx5e_ipsec_sa_entry *sa_entry) + + res = &mdev->mlx5e_res.hw_objs; + if (attrs->type == XFRM_DEV_OFFLOAD_PACKET) +- mlx5e_ipsec_packet_setup(obj, res->pdn, attrs); ++ mlx5e_ipsec_packet_setup(obj, res->pdn, sa_entry); + + err = mlx5_cmd_exec(mdev, in, sizeof(in), out, sizeof(out)); + if (!err) +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5e-fix-inversion-dependency-warning-while-ena.patch b/queue-6.12/net-mlx5e-fix-inversion-dependency-warning-while-ena.patch new file mode 100644 index 0000000000..d148daa4e8 --- /dev/null +++ b/queue-6.12/net-mlx5e-fix-inversion-dependency-warning-while-ena.patch @@ -0,0 +1,342 @@ +From cd922d46de1ad35629a41840d55e837edafa6a7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Jan 2025 13:39:08 +0200 +Subject: net/mlx5e: Fix inversion dependency warning while enabling IPsec + tunnel + +From: Leon Romanovsky + +[ Upstream commit 2c3688090f8a1f085230aa839cc63e4a7b977df0 ] + +Attempt to enable IPsec packet offload in tunnel mode in debug kernel +generates the following kernel panic, which is happening due to two +issues: +1. In SA add section, the should be _bh() variant when marking SA mode. +2. There is not needed flush_workqueue in SA delete routine. It is not +needed as at this stage as it is removed from SADB and the running work +will be canceled later in SA free. + + ===================================================== + WARNING: SOFTIRQ-safe -> SOFTIRQ-unsafe lock order detected + 6.12.0+ #4 Not tainted + ----------------------------------------------------- + charon/1337 [HC0[0]:SC0[4]:HE1:SE0] is trying to acquire: + ffff88810f365020 (&xa->xa_lock#24){+.+.}-{3:3}, at: mlx5e_xfrm_del_state+0xca/0x1e0 [mlx5_core] + + and this task is already holding: + ffff88813e0f0d48 (&x->lock){+.-.}-{3:3}, at: xfrm_state_delete+0x16/0x30 + which would create a new lock dependency: + (&x->lock){+.-.}-{3:3} -> (&xa->xa_lock#24){+.+.}-{3:3} + + but this new dependency connects a SOFTIRQ-irq-safe lock: + (&x->lock){+.-.}-{3:3} + + ... which became SOFTIRQ-irq-safe at: + lock_acquire+0x1be/0x520 + _raw_spin_lock_bh+0x34/0x40 + xfrm_timer_handler+0x91/0xd70 + __hrtimer_run_queues+0x1dd/0xa60 + hrtimer_run_softirq+0x146/0x2e0 + handle_softirqs+0x266/0x860 + irq_exit_rcu+0x115/0x1a0 + sysvec_apic_timer_interrupt+0x6e/0x90 + asm_sysvec_apic_timer_interrupt+0x16/0x20 + default_idle+0x13/0x20 + default_idle_call+0x67/0xa0 + do_idle+0x2da/0x320 + cpu_startup_entry+0x50/0x60 + start_secondary+0x213/0x2a0 + common_startup_64+0x129/0x138 + + to a SOFTIRQ-irq-unsafe lock: + (&xa->xa_lock#24){+.+.}-{3:3} + + ... which became SOFTIRQ-irq-unsafe at: + ... + lock_acquire+0x1be/0x520 + _raw_spin_lock+0x2c/0x40 + xa_set_mark+0x70/0x110 + mlx5e_xfrm_add_state+0xe48/0x2290 [mlx5_core] + xfrm_dev_state_add+0x3bb/0xd70 + xfrm_add_sa+0x2451/0x4a90 + xfrm_user_rcv_msg+0x493/0x880 + netlink_rcv_skb+0x12e/0x380 + xfrm_netlink_rcv+0x6d/0x90 + netlink_unicast+0x42f/0x740 + netlink_sendmsg+0x745/0xbe0 + __sock_sendmsg+0xc5/0x190 + __sys_sendto+0x1fe/0x2c0 + __x64_sys_sendto+0xdc/0x1b0 + do_syscall_64+0x6d/0x140 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + + other info that might help us debug this: + + Possible interrupt unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(&xa->xa_lock#24); + local_irq_disable(); + lock(&x->lock); + lock(&xa->xa_lock#24); + + lock(&x->lock); + + *** DEADLOCK *** + + 2 locks held by charon/1337: + #0: ffffffff87f8f858 (&net->xfrm.xfrm_cfg_mutex){+.+.}-{4:4}, at: xfrm_netlink_rcv+0x5e/0x90 + #1: ffff88813e0f0d48 (&x->lock){+.-.}-{3:3}, at: xfrm_state_delete+0x16/0x30 + + the dependencies between SOFTIRQ-irq-safe lock and the holding lock: + -> (&x->lock){+.-.}-{3:3} ops: 29 { + HARDIRQ-ON-W at: + lock_acquire+0x1be/0x520 + _raw_spin_lock_bh+0x34/0x40 + xfrm_alloc_spi+0xc0/0xe60 + xfrm_alloc_userspi+0x5f6/0xbc0 + xfrm_user_rcv_msg+0x493/0x880 + netlink_rcv_skb+0x12e/0x380 + xfrm_netlink_rcv+0x6d/0x90 + netlink_unicast+0x42f/0x740 + netlink_sendmsg+0x745/0xbe0 + __sock_sendmsg+0xc5/0x190 + __sys_sendto+0x1fe/0x2c0 + __x64_sys_sendto+0xdc/0x1b0 + do_syscall_64+0x6d/0x140 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + IN-SOFTIRQ-W at: + lock_acquire+0x1be/0x520 + _raw_spin_lock_bh+0x34/0x40 + xfrm_timer_handler+0x91/0xd70 + __hrtimer_run_queues+0x1dd/0xa60 + hrtimer_run_softirq+0x146/0x2e0 + handle_softirqs+0x266/0x860 + irq_exit_rcu+0x115/0x1a0 + sysvec_apic_timer_interrupt+0x6e/0x90 + asm_sysvec_apic_timer_interrupt+0x16/0x20 + default_idle+0x13/0x20 + default_idle_call+0x67/0xa0 + do_idle+0x2da/0x320 + cpu_startup_entry+0x50/0x60 + start_secondary+0x213/0x2a0 + common_startup_64+0x129/0x138 + INITIAL USE at: + lock_acquire+0x1be/0x520 + _raw_spin_lock_bh+0x34/0x40 + xfrm_alloc_spi+0xc0/0xe60 + xfrm_alloc_userspi+0x5f6/0xbc0 + xfrm_user_rcv_msg+0x493/0x880 + netlink_rcv_skb+0x12e/0x380 + xfrm_netlink_rcv+0x6d/0x90 + netlink_unicast+0x42f/0x740 + netlink_sendmsg+0x745/0xbe0 + __sock_sendmsg+0xc5/0x190 + __sys_sendto+0x1fe/0x2c0 + __x64_sys_sendto+0xdc/0x1b0 + do_syscall_64+0x6d/0x140 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + } + ... key at: [] __key.18+0x0/0x40 + + the dependencies between the lock to be acquired + and SOFTIRQ-irq-unsafe lock: + -> (&xa->xa_lock#24){+.+.}-{3:3} ops: 9 { + HARDIRQ-ON-W at: + lock_acquire+0x1be/0x520 + _raw_spin_lock_bh+0x34/0x40 + mlx5e_xfrm_add_state+0xc5b/0x2290 [mlx5_core] + xfrm_dev_state_add+0x3bb/0xd70 + xfrm_add_sa+0x2451/0x4a90 + xfrm_user_rcv_msg+0x493/0x880 + netlink_rcv_skb+0x12e/0x380 + xfrm_netlink_rcv+0x6d/0x90 + netlink_unicast+0x42f/0x740 + netlink_sendmsg+0x745/0xbe0 + __sock_sendmsg+0xc5/0x190 + __sys_sendto+0x1fe/0x2c0 + __x64_sys_sendto+0xdc/0x1b0 + do_syscall_64+0x6d/0x140 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + SOFTIRQ-ON-W at: + lock_acquire+0x1be/0x520 + _raw_spin_lock+0x2c/0x40 + xa_set_mark+0x70/0x110 + mlx5e_xfrm_add_state+0xe48/0x2290 [mlx5_core] + xfrm_dev_state_add+0x3bb/0xd70 + xfrm_add_sa+0x2451/0x4a90 + xfrm_user_rcv_msg+0x493/0x880 + netlink_rcv_skb+0x12e/0x380 + xfrm_netlink_rcv+0x6d/0x90 + netlink_unicast+0x42f/0x740 + netlink_sendmsg+0x745/0xbe0 + __sock_sendmsg+0xc5/0x190 + __sys_sendto+0x1fe/0x2c0 + __x64_sys_sendto+0xdc/0x1b0 + do_syscall_64+0x6d/0x140 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + INITIAL USE at: + lock_acquire+0x1be/0x520 + _raw_spin_lock_bh+0x34/0x40 + mlx5e_xfrm_add_state+0xc5b/0x2290 [mlx5_core] + xfrm_dev_state_add+0x3bb/0xd70 + xfrm_add_sa+0x2451/0x4a90 + xfrm_user_rcv_msg+0x493/0x880 + netlink_rcv_skb+0x12e/0x380 + xfrm_netlink_rcv+0x6d/0x90 + netlink_unicast+0x42f/0x740 + netlink_sendmsg+0x745/0xbe0 + __sock_sendmsg+0xc5/0x190 + __sys_sendto+0x1fe/0x2c0 + __x64_sys_sendto+0xdc/0x1b0 + do_syscall_64+0x6d/0x140 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + } + ... key at: [] __key.48+0x0/0xfffffffffff210a0 [mlx5_core] + ... acquired at: + __lock_acquire+0x30a0/0x5040 + lock_acquire+0x1be/0x520 + _raw_spin_lock_bh+0x34/0x40 + mlx5e_xfrm_del_state+0xca/0x1e0 [mlx5_core] + xfrm_dev_state_delete+0x90/0x160 + __xfrm_state_delete+0x662/0xae0 + xfrm_state_delete+0x1e/0x30 + xfrm_del_sa+0x1c2/0x340 + xfrm_user_rcv_msg+0x493/0x880 + netlink_rcv_skb+0x12e/0x380 + xfrm_netlink_rcv+0x6d/0x90 + netlink_unicast+0x42f/0x740 + netlink_sendmsg+0x745/0xbe0 + __sock_sendmsg+0xc5/0x190 + __sys_sendto+0x1fe/0x2c0 + __x64_sys_sendto+0xdc/0x1b0 + do_syscall_64+0x6d/0x140 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + + stack backtrace: + CPU: 7 UID: 0 PID: 1337 Comm: charon Not tainted 6.12.0+ #4 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.13.0-0-gf21b5a4aeb02-prebuilt.qemu.org 04/01/2014 + Call Trace: + + dump_stack_lvl+0x74/0xd0 + check_irq_usage+0x12e8/0x1d90 + ? print_shortest_lock_dependencies_backwards+0x1b0/0x1b0 + ? check_chain_key+0x1bb/0x4c0 + ? __lockdep_reset_lock+0x180/0x180 + ? check_path.constprop.0+0x24/0x50 + ? mark_lock+0x108/0x2fb0 + ? print_circular_bug+0x9b0/0x9b0 + ? mark_lock+0x108/0x2fb0 + ? print_usage_bug.part.0+0x670/0x670 + ? check_prev_add+0x1c4/0x2310 + check_prev_add+0x1c4/0x2310 + __lock_acquire+0x30a0/0x5040 + ? lockdep_set_lock_cmp_fn+0x190/0x190 + ? lockdep_set_lock_cmp_fn+0x190/0x190 + lock_acquire+0x1be/0x520 + ? mlx5e_xfrm_del_state+0xca/0x1e0 [mlx5_core] + ? lockdep_hardirqs_on_prepare+0x400/0x400 + ? __xfrm_state_delete+0x5f0/0xae0 + ? lock_downgrade+0x6b0/0x6b0 + _raw_spin_lock_bh+0x34/0x40 + ? mlx5e_xfrm_del_state+0xca/0x1e0 [mlx5_core] + mlx5e_xfrm_del_state+0xca/0x1e0 [mlx5_core] + xfrm_dev_state_delete+0x90/0x160 + __xfrm_state_delete+0x662/0xae0 + xfrm_state_delete+0x1e/0x30 + xfrm_del_sa+0x1c2/0x340 + ? xfrm_get_sa+0x250/0x250 + ? check_chain_key+0x1bb/0x4c0 + xfrm_user_rcv_msg+0x493/0x880 + ? copy_sec_ctx+0x270/0x270 + ? check_chain_key+0x1bb/0x4c0 + ? lockdep_set_lock_cmp_fn+0x190/0x190 + ? lockdep_set_lock_cmp_fn+0x190/0x190 + netlink_rcv_skb+0x12e/0x380 + ? copy_sec_ctx+0x270/0x270 + ? netlink_ack+0xd90/0xd90 + ? netlink_deliver_tap+0xcd/0xb60 + xfrm_netlink_rcv+0x6d/0x90 + netlink_unicast+0x42f/0x740 + ? netlink_attachskb+0x730/0x730 + ? lock_acquire+0x1be/0x520 + netlink_sendmsg+0x745/0xbe0 + ? netlink_unicast+0x740/0x740 + ? __might_fault+0xbb/0x170 + ? netlink_unicast+0x740/0x740 + __sock_sendmsg+0xc5/0x190 + ? fdget+0x163/0x1d0 + __sys_sendto+0x1fe/0x2c0 + ? __x64_sys_getpeername+0xb0/0xb0 + ? do_user_addr_fault+0x856/0xe30 + ? lock_acquire+0x1be/0x520 + ? __task_pid_nr_ns+0x117/0x410 + ? lock_downgrade+0x6b0/0x6b0 + __x64_sys_sendto+0xdc/0x1b0 + ? lockdep_hardirqs_on_prepare+0x284/0x400 + do_syscall_64+0x6d/0x140 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + RIP: 0033:0x7f7d31291ba4 + Code: 7d e8 89 4d d4 e8 4c 42 f7 ff 44 8b 4d d0 4c 8b 45 c8 89 c3 44 8b 55 d4 8b 7d e8 b8 2c 00 00 00 48 8b 55 d8 48 8b 75 e0 0f 05 <48> 3d 00 f0 ff ff 77 34 89 df 48 89 45 e8 e8 99 42 f7 ff 48 8b 45 + RSP: 002b:00007f7d2ccd94f0 EFLAGS: 00000297 ORIG_RAX: 000000000000002c + RAX: ffffffffffffffda RBX: 0000000000000001 RCX: 00007f7d31291ba4 + RDX: 0000000000000028 RSI: 00007f7d2ccd96a0 RDI: 000000000000000a + RBP: 00007f7d2ccd9530 R08: 00007f7d2ccd9598 R09: 000000000000000c + R10: 0000000000000000 R11: 0000000000000297 R12: 0000000000000028 + R13: 00007f7d2ccd9598 R14: 00007f7d2ccd96a0 R15: 00000000000000e1 + + +Fixes: 4c24272b4e2b ("net/mlx5e: Listen to ARP events to update IPsec L2 headers in tunnel mode") +Signed-off-by: Leon Romanovsky +Signed-off-by: Tariq Toukan +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +index ca92e518be766..21857474ad83f 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c +@@ -768,9 +768,12 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x, + MLX5_IPSEC_RESCHED); + + if (x->xso.type == XFRM_DEV_OFFLOAD_PACKET && +- x->props.mode == XFRM_MODE_TUNNEL) +- xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id, +- MLX5E_IPSEC_TUNNEL_SA); ++ x->props.mode == XFRM_MODE_TUNNEL) { ++ xa_lock_bh(&ipsec->sadb); ++ __xa_set_mark(&ipsec->sadb, sa_entry->ipsec_obj_id, ++ MLX5E_IPSEC_TUNNEL_SA); ++ xa_unlock_bh(&ipsec->sadb); ++ } + + out: + x->xso.offload_handle = (unsigned long)sa_entry; +@@ -797,7 +800,6 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x, + static void mlx5e_xfrm_del_state(struct xfrm_state *x) + { + struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x); +- struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs; + struct mlx5e_ipsec *ipsec = sa_entry->ipsec; + struct mlx5e_ipsec_sa_entry *old; + +@@ -806,12 +808,6 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x) + + old = xa_erase_bh(&ipsec->sadb, sa_entry->ipsec_obj_id); + WARN_ON(old != sa_entry); +- +- if (attrs->mode == XFRM_MODE_TUNNEL && +- attrs->type == XFRM_DEV_OFFLOAD_PACKET) +- /* Make sure that no ARP requests are running in parallel */ +- flush_workqueue(ipsec->wq); +- + } + + static void mlx5e_xfrm_free_state(struct xfrm_state *x) +-- +2.39.5 + diff --git a/queue-6.12/net-mlx5e-rely-on-reqid-in-ipsec-tunnel-mode.patch b/queue-6.12/net-mlx5e-rely-on-reqid-in-ipsec-tunnel-mode.patch new file mode 100644 index 0000000000..869fdbc52d --- /dev/null +++ b/queue-6.12/net-mlx5e-rely-on-reqid-in-ipsec-tunnel-mode.patch @@ -0,0 +1,87 @@ +From 69a19552242212aee287e902b20da2a7f5444f34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Jan 2025 13:39:09 +0200 +Subject: net/mlx5e: Rely on reqid in IPsec tunnel mode + +From: Leon Romanovsky + +[ Upstream commit 25f23524dfa227959beb3b2c2c0f38e0222f4cfa ] + +All packet offloads SAs have reqid in it to make sure they have +corresponding policy. While it is not strictly needed for transparent +mode, it is extremely important in tunnel mode. In that mode, policy and +SAs have different match criteria. + +Policy catches the whole subnet addresses, and SA catches the tunnel gateways +addresses. The source address of such tunnel is not known during egress packet +traversal in flow steering as it is added only after successful encryption. + +As reqid is required for packet offload and it is unique for every SA, +we can safely rely on it only. + +The output below shows the configured egress policy and SA by strongswan: + +[leonro@vm ~]$ sudo ip x s +src 192.169.101.2 dst 192.169.101.1 + proto esp spi 0xc88b7652 reqid 1 mode tunnel + replay-window 0 flag af-unspec esn + aead rfc4106(gcm(aes)) 0xe406a01083986e14d116488549094710e9c57bc6 128 + anti-replay esn context: + seq-hi 0x0, seq 0x0, oseq-hi 0x0, oseq 0x0 + replay_window 1, bitmap-length 1 + 00000000 + crypto offload parameters: dev eth2 dir out mode packet + +[leonro@064 ~]$ sudo ip x p +src 192.170.0.0/16 dst 192.170.0.0/16 + dir out priority 383615 ptype main + tmpl src 192.169.101.2 dst 192.169.101.1 + proto esp spi 0xc88b7652 reqid 1 mode tunnel + crypto offload parameters: dev eth2 mode packet + +Fixes: b3beba1fb404 ("net/mlx5e: Allow policies with reqid 0, to support IKE policy holes") +Signed-off-by: Leon Romanovsky +Reviewed-by: Jacob Keller +Signed-off-by: Tariq Toukan +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + .../ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +index e51b03d4c717f..57861d34d46f8 100644 +--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c ++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec_fs.c +@@ -1718,23 +1718,21 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) + goto err_alloc; + } + +- if (attrs->family == AF_INET) +- setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4); +- else +- setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6); +- + setup_fte_no_frags(spec); + setup_fte_upper_proto_match(spec, &attrs->upspec); + + switch (attrs->type) { + case XFRM_DEV_OFFLOAD_CRYPTO: ++ if (attrs->family == AF_INET) ++ setup_fte_addr4(spec, &attrs->saddr.a4, &attrs->daddr.a4); ++ else ++ setup_fte_addr6(spec, attrs->saddr.a6, attrs->daddr.a6); + setup_fte_spi(spec, attrs->spi, false); + setup_fte_esp(spec); + setup_fte_reg_a(spec); + break; + case XFRM_DEV_OFFLOAD_PACKET: +- if (attrs->reqid) +- setup_fte_reg_c4(spec, attrs->reqid); ++ setup_fte_reg_c4(spec, attrs->reqid); + err = setup_pkt_reformat(ipsec, attrs, &flow_act); + if (err) + goto err_pkt_reformat; +-- +2.39.5 + diff --git a/queue-6.12/net-ravb-fix-max-tx-frame-size-for-rz-v2m.patch b/queue-6.12/net-ravb-fix-max-tx-frame-size-for-rz-v2m.patch new file mode 100644 index 0000000000..bfcca6fa9f --- /dev/null +++ b/queue-6.12/net-ravb-fix-max-tx-frame-size-for-rz-v2m.patch @@ -0,0 +1,51 @@ +From 15142367fbab4567e4d720c9799725e57555ac8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Jan 2025 11:37:06 +0000 +Subject: net: ravb: Fix max TX frame size for RZ/V2M +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Paul Barker + +[ Upstream commit e7e441a4100e4bc90b52f80494a28a9667993975 ] + +When tx_max_frame_size was added to struct ravb_hw_info, no value was +set in ravb_rzv2m_hw_info so the default value of zero was used. + +The maximum MTU is set by subtracting from tx_max_frame_size to allow +space for headers and frame checksums. As ndev->max_mtu is unsigned, +this subtraction wraps around leading to a ridiculously large positive +value that is obviously incorrect. + +Before tx_max_frame_size was introduced, the maximum MTU was based on +rx_max_frame_size. So, we can restore the correct maximum MTU by copying +the rx_max_frame_size value into tx_max_frame_size for RZ/V2M. + +Fixes: 1d63864299ca ("net: ravb: Fix maximum TX frame size for GbEth devices") +Signed-off-by: Paul Barker +Reviewed-by: Niklas Söderlund +Reviewed-by: Simon Horman +Reviewed-by: Sergey Shtylyov +Link: https://patch.msgid.link/20250109113706.1409149-1-paul.barker.ct@bp.renesas.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/renesas/ravb_main.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c +index 907af4651c553..6f6b0566c65bc 100644 +--- a/drivers/net/ethernet/renesas/ravb_main.c ++++ b/drivers/net/ethernet/renesas/ravb_main.c +@@ -2756,6 +2756,7 @@ static const struct ravb_hw_info ravb_rzv2m_hw_info = { + .net_features = NETIF_F_RXCSUM, + .stats_len = ARRAY_SIZE(ravb_gstrings_stats), + .tccr_mask = TCCR_TSRQ0 | TCCR_TSRQ1 | TCCR_TSRQ2 | TCCR_TSRQ3, ++ .tx_max_frame_size = SZ_2K, + .rx_max_frame_size = SZ_2K, + .rx_buffer_size = SZ_2K + + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)), +-- +2.39.5 + diff --git a/queue-6.12/net-xilinx-axienet-fix-irq-coalescing-packet-count-o.patch b/queue-6.12/net-xilinx-axienet-fix-irq-coalescing-packet-count-o.patch new file mode 100644 index 0000000000..476285afcf --- /dev/null +++ b/queue-6.12/net-xilinx-axienet-fix-irq-coalescing-packet-count-o.patch @@ -0,0 +1,48 @@ +From 342433c5833d7c376bc8a8c6a46405719814dc87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jan 2025 11:30:00 -0500 +Subject: net: xilinx: axienet: Fix IRQ coalescing packet count overflow + +From: Sean Anderson + +[ Upstream commit c17ff476f53afb30f90bb3c2af77de069c81a622 ] + +If coalesce_count is greater than 255 it will not fit in the register and +will overflow. This can be reproduced by running + + # ethtool -C ethX rx-frames 256 + +which will result in a timeout of 0us instead. Fix this by checking for +invalid values and reporting an error. + +Fixes: 8a3b7a252dca ("drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver") +Signed-off-by: Sean Anderson +Reviewed-by: Shannon Nelson +Reviewed-by: Radhey Shyam Pandey +Link: https://patch.msgid.link/20250113163001.2335235-1-sean.anderson@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +index 1fcbcaa85ebdb..de10a2d08c428 100644 +--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c ++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +@@ -2056,6 +2056,12 @@ axienet_ethtools_set_coalesce(struct net_device *ndev, + return -EBUSY; + } + ++ if (ecoalesce->rx_max_coalesced_frames > 255 || ++ ecoalesce->tx_max_coalesced_frames > 255) { ++ NL_SET_ERR_MSG(extack, "frames must be less than 256"); ++ return -EINVAL; ++ } ++ + if (ecoalesce->rx_max_coalesced_frames) + lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames; + if (ecoalesce->rx_coalesce_usecs) +-- +2.39.5 + diff --git a/queue-6.12/netdev-avoid-cfi-problems-with-sock-priv-helpers.patch b/queue-6.12/netdev-avoid-cfi-problems-with-sock-priv-helpers.patch new file mode 100644 index 0000000000..78d182c50f --- /dev/null +++ b/queue-6.12/netdev-avoid-cfi-problems-with-sock-priv-helpers.patch @@ -0,0 +1,93 @@ +From 2864b1203fcb0a464ff17450bbea10e524401a93 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Jan 2025 08:14:36 -0800 +Subject: netdev: avoid CFI problems with sock priv helpers + +From: Jakub Kicinski + +[ Upstream commit a50da36562cd62b41de9bef08edbb3e8af00f118 ] + +Li Li reports that casting away callback type may cause issues +for CFI. Let's generate a small wrapper for each callback, +to make sure compiler sees the anticipated types. + +Reported-by: Li Li +Link: https://lore.kernel.org/CANBPYPjQVqmzZ4J=rVQX87a9iuwmaetULwbK_5_3YWk2eGzkaA@mail.gmail.com +Fixes: 170aafe35cb9 ("netdev: support binding dma-buf to netdevice") +Signed-off-by: Jakub Kicinski +Reviewed-by: Mina Almasry +Link: https://patch.msgid.link/20250115161436.648646-1-kuba@kernel.org +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/core/netdev-genl-gen.c | 14 ++++++++++++-- + tools/net/ynl/ynl-gen-c.py | 16 +++++++++++++--- + 2 files changed, 25 insertions(+), 5 deletions(-) + +diff --git a/net/core/netdev-genl-gen.c b/net/core/netdev-genl-gen.c +index b28424ae06d5f..8614988fc67b9 100644 +--- a/net/core/netdev-genl-gen.c ++++ b/net/core/netdev-genl-gen.c +@@ -178,6 +178,16 @@ static const struct genl_multicast_group netdev_nl_mcgrps[] = { + [NETDEV_NLGRP_PAGE_POOL] = { "page-pool", }, + }; + ++static void __netdev_nl_sock_priv_init(void *priv) ++{ ++ netdev_nl_sock_priv_init(priv); ++} ++ ++static void __netdev_nl_sock_priv_destroy(void *priv) ++{ ++ netdev_nl_sock_priv_destroy(priv); ++} ++ + struct genl_family netdev_nl_family __ro_after_init = { + .name = NETDEV_FAMILY_NAME, + .version = NETDEV_FAMILY_VERSION, +@@ -189,6 +199,6 @@ struct genl_family netdev_nl_family __ro_after_init = { + .mcgrps = netdev_nl_mcgrps, + .n_mcgrps = ARRAY_SIZE(netdev_nl_mcgrps), + .sock_priv_size = sizeof(struct list_head), +- .sock_priv_init = (void *)netdev_nl_sock_priv_init, +- .sock_priv_destroy = (void *)netdev_nl_sock_priv_destroy, ++ .sock_priv_init = __netdev_nl_sock_priv_init, ++ .sock_priv_destroy = __netdev_nl_sock_priv_destroy, + }; +diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py +index 717530bc9c52e..463f1394ab971 100755 +--- a/tools/net/ynl/ynl-gen-c.py ++++ b/tools/net/ynl/ynl-gen-c.py +@@ -2361,6 +2361,17 @@ def print_kernel_family_struct_src(family, cw): + if not kernel_can_gen_family_struct(family): + return + ++ if 'sock-priv' in family.kernel_family: ++ # Generate "trampolines" to make CFI happy ++ cw.write_func("static void", f"__{family.c_name}_nl_sock_priv_init", ++ [f"{family.c_name}_nl_sock_priv_init(priv);"], ++ ["void *priv"]) ++ cw.nl() ++ cw.write_func("static void", f"__{family.c_name}_nl_sock_priv_destroy", ++ [f"{family.c_name}_nl_sock_priv_destroy(priv);"], ++ ["void *priv"]) ++ cw.nl() ++ + cw.block_start(f"struct genl_family {family.ident_name}_nl_family __ro_after_init =") + cw.p('.name\t\t= ' + family.fam_key + ',') + cw.p('.version\t= ' + family.ver_key + ',') +@@ -2378,9 +2389,8 @@ def print_kernel_family_struct_src(family, cw): + cw.p(f'.n_mcgrps\t= ARRAY_SIZE({family.c_name}_nl_mcgrps),') + if 'sock-priv' in family.kernel_family: + cw.p(f'.sock_priv_size\t= sizeof({family.kernel_family["sock-priv"]}),') +- # Force cast here, actual helpers take pointer to the real type. +- cw.p(f'.sock_priv_init\t= (void *){family.c_name}_nl_sock_priv_init,') +- cw.p(f'.sock_priv_destroy = (void *){family.c_name}_nl_sock_priv_destroy,') ++ cw.p(f'.sock_priv_init\t= __{family.c_name}_nl_sock_priv_init,') ++ cw.p(f'.sock_priv_destroy = __{family.c_name}_nl_sock_priv_destroy,') + cw.block_end(';') + + +-- +2.39.5 + diff --git a/queue-6.12/nfp-bpf-prevent-integer-overflow-in-nfp_bpf_event_ou.patch b/queue-6.12/nfp-bpf-prevent-integer-overflow-in-nfp_bpf_event_ou.patch new file mode 100644 index 0000000000..520025d326 --- /dev/null +++ b/queue-6.12/nfp-bpf-prevent-integer-overflow-in-nfp_bpf_event_ou.patch @@ -0,0 +1,39 @@ +From 12894bff3f5ec9792233e44ba2bf2577320da2b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Jan 2025 09:18:39 +0300 +Subject: nfp: bpf: prevent integer overflow in nfp_bpf_event_output() + +From: Dan Carpenter + +[ Upstream commit 16ebb6f5b6295c9688749862a39a4889c56227f8 ] + +The "sizeof(struct cmsg_bpf_event) + pkt_size + data_size" math could +potentially have an integer wrapping bug on 32bit systems. Check for +this and return an error. + +Fixes: 9816dd35ecec ("nfp: bpf: perf event output helpers support") +Signed-off-by: Dan Carpenter +Link: https://patch.msgid.link/6074805b-e78d-4b8a-bf05-e929b5377c28@stanley.mountain +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/netronome/nfp/bpf/offload.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c +index 9d97cd281f18e..c03558adda91e 100644 +--- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c ++++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c +@@ -458,7 +458,8 @@ int nfp_bpf_event_output(struct nfp_app_bpf *bpf, const void *data, + map_id_full = be64_to_cpu(cbe->map_ptr); + map_id = map_id_full; + +- if (len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size) ++ if (size_add(pkt_size, data_size) > INT_MAX || ++ len < sizeof(struct cmsg_bpf_event) + pkt_size + data_size) + return -EINVAL; + if (cbe->hdr.ver != NFP_CCM_ABI_VERSION) + return -EINVAL; +-- +2.39.5 + diff --git a/queue-6.12/openvswitch-fix-lockup-on-tx-to-unregistering-netdev.patch b/queue-6.12/openvswitch-fix-lockup-on-tx-to-unregistering-netdev.patch new file mode 100644 index 0000000000..5a5d678fc7 --- /dev/null +++ b/queue-6.12/openvswitch-fix-lockup-on-tx-to-unregistering-netdev.patch @@ -0,0 +1,79 @@ +From 02e5baf0f944e0762b522142b1e4f146266358e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Jan 2025 13:21:24 +0100 +Subject: openvswitch: fix lockup on tx to unregistering netdev with carrier + +From: Ilya Maximets + +[ Upstream commit 47e55e4b410f7d552e43011baa5be1aab4093990 ] + +Commit in a fixes tag attempted to fix the issue in the following +sequence of calls: + + do_output + -> ovs_vport_send + -> dev_queue_xmit + -> __dev_queue_xmit + -> netdev_core_pick_tx + -> skb_tx_hash + +When device is unregistering, the 'dev->real_num_tx_queues' goes to +zero and the 'while (unlikely(hash >= qcount))' loop inside the +'skb_tx_hash' becomes infinite, locking up the core forever. + +But unfortunately, checking just the carrier status is not enough to +fix the issue, because some devices may still be in unregistering +state while reporting carrier status OK. + +One example of such device is a net/dummy. It sets carrier ON +on start, but it doesn't implement .ndo_stop to set the carrier off. +And it makes sense, because dummy doesn't really have a carrier. +Therefore, while this device is unregistering, it's still easy to hit +the infinite loop in the skb_tx_hash() from the OVS datapath. There +might be other drivers that do the same, but dummy by itself is +important for the OVS ecosystem, because it is frequently used as a +packet sink for tcpdump while debugging OVS deployments. And when the +issue is hit, the only way to recover is to reboot. + +Fix that by also checking if the device is running. The running +state is handled by the net core during unregistering, so it covers +unregistering case better, and we don't really need to send packets +to devices that are not running anyway. + +While only checking the running state might be enough, the carrier +check is preserved. The running and the carrier states seem disjoined +throughout the code and different drivers. And other core functions +like __dev_direct_xmit() check both before attempting to transmit +a packet. So, it seems safer to check both flags in OVS as well. + +Fixes: 066b86787fa3 ("net: openvswitch: fix race on port output") +Reported-by: Friedrich Weber +Closes: https://mail.openvswitch.org/pipermail/ovs-discuss/2025-January/053423.html +Signed-off-by: Ilya Maximets +Tested-by: Friedrich Weber +Reviewed-by: Aaron Conole +Link: https://patch.msgid.link/20250109122225.4034688-1-i.maximets@ovn.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/openvswitch/actions.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c +index 16e2600146844..704c858cf2093 100644 +--- a/net/openvswitch/actions.c ++++ b/net/openvswitch/actions.c +@@ -934,7 +934,9 @@ static void do_output(struct datapath *dp, struct sk_buff *skb, int out_port, + { + struct vport *vport = ovs_vport_rcu(dp, out_port); + +- if (likely(vport && netif_carrier_ok(vport->dev))) { ++ if (likely(vport && ++ netif_running(vport->dev) && ++ netif_carrier_ok(vport->dev))) { + u16 mru = OVS_CB(skb)->mru; + u32 cutlen = OVS_CB(skb)->cutlen; + +-- +2.39.5 + diff --git a/queue-6.12/pfcp-destroy-device-along-with-udp-socket-s-netns-di.patch b/queue-6.12/pfcp-destroy-device-along-with-udp-socket-s-netns-di.patch new file mode 100644 index 0000000000..695642a48c --- /dev/null +++ b/queue-6.12/pfcp-destroy-device-along-with-udp-socket-s-netns-di.patch @@ -0,0 +1,148 @@ +From 6880ad5a6e0826a49b0f5f191c9d7687221d3d5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Jan 2025 10:47:54 +0900 +Subject: pfcp: Destroy device along with udp socket's netns dismantle. + +From: Kuniyuki Iwashima + +[ Upstream commit ffc90e9ca61b0f619326a1417ff32efd6cc71ed2 ] + +pfcp_newlink() links the device to a list in dev_net(dev) instead +of net, where a udp tunnel socket is created. + +Even when net is removed, the device stays alive on dev_net(dev). +Then, removing net triggers the splat below. [0] + +In this example, pfcp0 is created in ns2, but the udp socket is +created in ns1. + + ip netns add ns1 + ip netns add ns2 + ip -n ns1 link add netns ns2 name pfcp0 type pfcp + ip netns del ns1 + +Let's link the device to the socket's netns instead. + +Now, pfcp_net_exit() needs another netdev iteration to remove +all pfcp devices in the netns. + +pfcp_dev_list is not used under RCU, so the list API is converted +to the non-RCU variant. + +pfcp_net_exit() can be converted to .exit_batch_rtnl() in net-next. + +[0]: +ref_tracker: net notrefcnt@00000000128b34dc has 1/1 users at + sk_alloc (./include/net/net_namespace.h:345 net/core/sock.c:2236) + inet_create (net/ipv4/af_inet.c:326 net/ipv4/af_inet.c:252) + __sock_create (net/socket.c:1558) + udp_sock_create4 (net/ipv4/udp_tunnel_core.c:18) + pfcp_create_sock (drivers/net/pfcp.c:168) + pfcp_newlink (drivers/net/pfcp.c:182 drivers/net/pfcp.c:197) + rtnl_newlink (net/core/rtnetlink.c:3786 net/core/rtnetlink.c:3897 net/core/rtnetlink.c:4012) + rtnetlink_rcv_msg (net/core/rtnetlink.c:6922) + netlink_rcv_skb (net/netlink/af_netlink.c:2542) + netlink_unicast (net/netlink/af_netlink.c:1321 net/netlink/af_netlink.c:1347) + netlink_sendmsg (net/netlink/af_netlink.c:1891) + ____sys_sendmsg (net/socket.c:711 net/socket.c:726 net/socket.c:2583) + ___sys_sendmsg (net/socket.c:2639) + __sys_sendmsg (net/socket.c:2669) + do_syscall_64 (arch/x86/entry/common.c:52 arch/x86/entry/common.c:83) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) + +WARNING: CPU: 1 PID: 11 at lib/ref_tracker.c:179 ref_tracker_dir_exit (lib/ref_tracker.c:179) +Modules linked in: +CPU: 1 UID: 0 PID: 11 Comm: kworker/u16:0 Not tainted 6.13.0-rc5-00147-g4c1224501e9d #5 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 +Workqueue: netns cleanup_net +RIP: 0010:ref_tracker_dir_exit (lib/ref_tracker.c:179) +Code: 00 00 00 fc ff df 4d 8b 26 49 bd 00 01 00 00 00 00 ad de 4c 39 f5 0f 85 df 00 00 00 48 8b 74 24 08 48 89 df e8 a5 cc 12 02 90 <0f> 0b 90 48 8d 6b 44 be 04 00 00 00 48 89 ef e8 80 de 67 ff 48 89 +RSP: 0018:ff11000007f3fb60 EFLAGS: 00010286 +RAX: 00000000000020ef RBX: ff1100000d6481e0 RCX: 1ffffffff0e40d82 +RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffffffff8423ee3c +RBP: ff1100000d648230 R08: 0000000000000001 R09: fffffbfff0e395af +R10: 0000000000000001 R11: 0000000000000000 R12: ff1100000d648230 +R13: dead000000000100 R14: ff1100000d648230 R15: dffffc0000000000 +FS: 0000000000000000(0000) GS:ff1100006ce80000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +CR2: 00005620e1363990 CR3: 000000000eeb2002 CR4: 0000000000771ef0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000fffe07f0 DR7: 0000000000000400 +PKRU: 55555554 +Call Trace: + + ? __warn (kernel/panic.c:748) + ? ref_tracker_dir_exit (lib/ref_tracker.c:179) + ? report_bug (lib/bug.c:201 lib/bug.c:219) + ? handle_bug (arch/x86/kernel/traps.c:285) + ? exc_invalid_op (arch/x86/kernel/traps.c:309 (discriminator 1)) + ? asm_exc_invalid_op (./arch/x86/include/asm/idtentry.h:621) + ? _raw_spin_unlock_irqrestore (./arch/x86/include/asm/irqflags.h:42 ./arch/x86/include/asm/irqflags.h:97 ./arch/x86/include/asm/irqflags.h:155 ./include/linux/spinlock_api_smp.h:151 kernel/locking/spinlock.c:194) + ? ref_tracker_dir_exit (lib/ref_tracker.c:179) + ? __pfx_ref_tracker_dir_exit (lib/ref_tracker.c:158) + ? kfree (mm/slub.c:4613 mm/slub.c:4761) + net_free (net/core/net_namespace.c:476 net/core/net_namespace.c:467) + cleanup_net (net/core/net_namespace.c:664 (discriminator 3)) + process_one_work (kernel/workqueue.c:3229) + worker_thread (kernel/workqueue.c:3304 kernel/workqueue.c:3391) + kthread (kernel/kthread.c:389) + ret_from_fork (arch/x86/kernel/process.c:147) + ret_from_fork_asm (arch/x86/entry/entry_64.S:257) + + +Fixes: 76c8764ef36a ("pfcp: add PFCP module") +Reported-by: Xiao Liang +Closes: https://lore.kernel.org/netdev/20250104125732.17335-1-shaw.leon@gmail.com/ +Signed-off-by: Kuniyuki Iwashima +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/pfcp.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/pfcp.c b/drivers/net/pfcp.c +index 69434fd13f961..68d0d9e92a220 100644 +--- a/drivers/net/pfcp.c ++++ b/drivers/net/pfcp.c +@@ -206,8 +206,8 @@ static int pfcp_newlink(struct net *net, struct net_device *dev, + goto exit_del_pfcp_sock; + } + +- pn = net_generic(dev_net(dev), pfcp_net_id); +- list_add_rcu(&pfcp->list, &pn->pfcp_dev_list); ++ pn = net_generic(net, pfcp_net_id); ++ list_add(&pfcp->list, &pn->pfcp_dev_list); + + netdev_dbg(dev, "registered new PFCP interface\n"); + +@@ -224,7 +224,7 @@ static void pfcp_dellink(struct net_device *dev, struct list_head *head) + { + struct pfcp_dev *pfcp = netdev_priv(dev); + +- list_del_rcu(&pfcp->list); ++ list_del(&pfcp->list); + unregister_netdevice_queue(dev, head); + } + +@@ -247,11 +247,16 @@ static int __net_init pfcp_net_init(struct net *net) + static void __net_exit pfcp_net_exit(struct net *net) + { + struct pfcp_net *pn = net_generic(net, pfcp_net_id); +- struct pfcp_dev *pfcp; ++ struct pfcp_dev *pfcp, *pfcp_next; ++ struct net_device *dev; + LIST_HEAD(list); + + rtnl_lock(); +- list_for_each_entry(pfcp, &pn->pfcp_dev_list, list) ++ for_each_netdev(net, dev) ++ if (dev->rtnl_link_ops == &pfcp_link_ops) ++ pfcp_dellink(dev, &list); ++ ++ list_for_each_entry_safe(pfcp, pfcp_next, &pn->pfcp_dev_list, list) + pfcp_dellink(pfcp->dev, &list); + + unregister_netdevice_many(&list); +-- +2.39.5 + diff --git a/queue-6.12/pktgen-avoid-out-of-bounds-access-in-get_imix_entrie.patch b/queue-6.12/pktgen-avoid-out-of-bounds-access-in-get_imix_entrie.patch new file mode 100644 index 0000000000..f122c81505 --- /dev/null +++ b/queue-6.12/pktgen-avoid-out-of-bounds-access-in-get_imix_entrie.patch @@ -0,0 +1,68 @@ +From d7478c91ea91ff3933bf837b1ad00904ddce04f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Jan 2025 11:30:39 +0300 +Subject: pktgen: Avoid out-of-bounds access in get_imix_entries + +From: Artem Chernyshev + +[ Upstream commit 76201b5979768500bca362871db66d77cb4c225e ] + +Passing a sufficient amount of imix entries leads to invalid access to the +pkt_dev->imix_entries array because of the incorrect boundary check. + +UBSAN: array-index-out-of-bounds in net/core/pktgen.c:874:24 +index 20 is out of range for type 'imix_pkt [20]' +CPU: 2 PID: 1210 Comm: bash Not tainted 6.10.0-rc1 #121 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) +Call Trace: + +dump_stack_lvl lib/dump_stack.c:117 +__ubsan_handle_out_of_bounds lib/ubsan.c:429 +get_imix_entries net/core/pktgen.c:874 +pktgen_if_write net/core/pktgen.c:1063 +pde_write fs/proc/inode.c:334 +proc_reg_write fs/proc/inode.c:346 +vfs_write fs/read_write.c:593 +ksys_write fs/read_write.c:644 +do_syscall_64 arch/x86/entry/common.c:83 +entry_SYSCALL_64_after_hwframe arch/x86/entry/entry_64.S:130 + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 52a62f8603f9 ("pktgen: Parse internet mix (imix) input") +Signed-off-by: Artem Chernyshev +[ fp: allow to fill the array completely; minor changelog cleanup ] +Signed-off-by: Fedor Pchelkin +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + net/core/pktgen.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/net/core/pktgen.c b/net/core/pktgen.c +index 34f68ef74b8f2..b6db4910359bb 100644 +--- a/net/core/pktgen.c ++++ b/net/core/pktgen.c +@@ -851,6 +851,9 @@ static ssize_t get_imix_entries(const char __user *buffer, + unsigned long weight; + unsigned long size; + ++ if (pkt_dev->n_imix_entries >= MAX_IMIX_ENTRIES) ++ return -E2BIG; ++ + len = num_arg(&buffer[i], max_digits, &size); + if (len < 0) + return len; +@@ -880,9 +883,6 @@ static ssize_t get_imix_entries(const char __user *buffer, + + i++; + pkt_dev->n_imix_entries++; +- +- if (pkt_dev->n_imix_entries > MAX_IMIX_ENTRIES) +- return -E2BIG; + } while (c == ' '); + + return i; +-- +2.39.5 + diff --git a/queue-6.12/series b/queue-6.12/series index a2f60826d5..b643f30bfa 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -1 +1,36 @@ efi-zboot-limit-compression-options-to-gzip-and-zstd.patch +net-ethernet-ti-cpsw_ale-fix-cpsw_ale_get_field.patch +bpf-fix-bpf_sk_select_reuseport-memory-leak.patch +eth-bnxt-always-recalculate-features-after-xdp-clear.patch +net-ravb-fix-max-tx-frame-size-for-rz-v2m.patch +openvswitch-fix-lockup-on-tx-to-unregistering-netdev.patch +pktgen-avoid-out-of-bounds-access-in-get_imix_entrie.patch +ice-fix-e825-initialization.patch +ice-fix-quad-registers-read-on-e825.patch +ice-fix-eth56g-fc-fec-rx-offset-value.patch +ice-introduce-ice_get_phy_model-wrapper.patch +ice-add-ice_get_ctrl_ptp-wrapper-to-simplify-the-cod.patch +ice-use-ice_adapter-for-ptp-shared-data-instead-of-a.patch +ice-add-correct-phy-lane-assignment.patch +cpuidle-teo-update-documentation-after-previous-chan.patch +btrfs-add-the-missing-error-handling-inside-get_cano.patch +gtp-use-for_each_netdev_rcu-in-gtp_genl_dump_pdp.patch +gtp-destroy-device-along-with-udp-socket-s-netns-dis.patch +pfcp-destroy-device-along-with-udp-socket-s-netns-di.patch +cpufreq-move-endif-to-the-end-of-kconfig-file.patch +nfp-bpf-prevent-integer-overflow-in-nfp_bpf_event_ou.patch +net-xilinx-axienet-fix-irq-coalescing-packet-count-o.patch +net-fec-handle-page_pool_dev_alloc_pages-error.patch +net-make-page_pool_ref_netmem-work-with-net-iovs.patch +net-mlx5-fix-rdma-tx-steering-prio.patch +net-mlx5-fix-a-lockdep-warning-as-part-of-the-write-.patch +net-mlx5-sf-fix-add-port-error-handling.patch +net-mlx5-clear-port-select-structure-when-fail-to-cr.patch +net-mlx5e-fix-inversion-dependency-warning-while-ena.patch +net-mlx5e-rely-on-reqid-in-ipsec-tunnel-mode.patch +net-mlx5e-always-start-ipsec-sequence-number-from-1.patch +netdev-avoid-cfi-problems-with-sock-priv-helpers.patch +drm-tests-helpers-fix-compiler-warning.patch +drm-vmwgfx-unreserve-bo-on-error.patch +drm-vmwgfx-add-new-keep_resv-bo-param.patch +drm-v3d-ensure-job-pointer-is-set-to-null-after-job-.patch