From: Greg Kroah-Hartman Date: Sat, 21 Mar 2026 14:51:44 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v6.1.167~51 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c374ad11b9ee2e8cd29c528248440d7d0332a8dd;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: drm-exynos-vidi-fix-to-avoid-directly-dereferencing-user-pointer.patch drm-exynos-vidi-use-ctx-lock-to-protect-struct-vidi_context-member-variables-related-to-memory-alloc-free.patch drm-exynos-vidi-use-priv-vidi_dev-for-ctx-lookup-in-vidi_connection_ioctl.patch gve-defer-interrupt-enabling-until-napi-registration.patch net-handle-napi_schedule-calls-from-non-interrupt.patch net-stmmac-dwmac-loongson-set-clk_csr_i-to-100-150mhz.patch --- diff --git a/queue-5.15/drm-exynos-vidi-fix-to-avoid-directly-dereferencing-user-pointer.patch b/queue-5.15/drm-exynos-vidi-fix-to-avoid-directly-dereferencing-user-pointer.patch new file mode 100644 index 0000000000..af3f8584cb --- /dev/null +++ b/queue-5.15/drm-exynos-vidi-fix-to-avoid-directly-dereferencing-user-pointer.patch @@ -0,0 +1,57 @@ +From d4c98c077c7fb2dfdece7d605e694b5ea2665085 Mon Sep 17 00:00:00 2001 +From: Jeongjun Park +Date: Mon, 19 Jan 2026 17:25:52 +0900 +Subject: drm/exynos: vidi: fix to avoid directly dereferencing user pointer + +From: Jeongjun Park + +commit d4c98c077c7fb2dfdece7d605e694b5ea2665085 upstream. + +In vidi_connection_ioctl(), vidi->edid(user pointer) is directly +dereferenced in the kernel. + +This allows arbitrary kernel memory access from the user space, so instead +of directly accessing the user pointer in the kernel, we should modify it +to copy edid to kernel memory using copy_from_user() and use it. + +Cc: +Signed-off-by: Jeongjun Park +Signed-off-by: Inki Dae +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/exynos/exynos_drm_vidi.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c +@@ -251,19 +251,26 @@ int vidi_connection_ioctl(struct drm_dev + + if (vidi->connection) { + struct edid *raw_edid; ++ struct edid edid_buf; ++ void *edid_userptr = u64_to_user_ptr(vidi->edid); + +- raw_edid = (struct edid *)(unsigned long)vidi->edid; +- if (!drm_edid_is_valid(raw_edid)) { ++ if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid))) ++ return -EFAULT; ++ ++ if (!drm_edid_is_valid(&edid_buf)) { + DRM_DEV_DEBUG_KMS(ctx->dev, + "edid data is invalid.\n"); + return -EINVAL; + } +- ctx->raw_edid = drm_edid_duplicate(raw_edid); +- if (!ctx->raw_edid) { ++ ++ raw_edid = drm_edid_duplicate(&edid_buf); ++ ++ if (!raw_edid) { + DRM_DEV_DEBUG_KMS(ctx->dev, + "failed to allocate raw_edid.\n"); + return -ENOMEM; + } ++ ctx->raw_edid = raw_edid; + } else { + /* + * with connection = 0, free raw_edid diff --git a/queue-5.15/drm-exynos-vidi-use-ctx-lock-to-protect-struct-vidi_context-member-variables-related-to-memory-alloc-free.patch b/queue-5.15/drm-exynos-vidi-use-ctx-lock-to-protect-struct-vidi_context-member-variables-related-to-memory-alloc-free.patch new file mode 100644 index 0000000000..856a077486 --- /dev/null +++ b/queue-5.15/drm-exynos-vidi-use-ctx-lock-to-protect-struct-vidi_context-member-variables-related-to-memory-alloc-free.patch @@ -0,0 +1,200 @@ +From 52b330799e2d6f825ae2bb74662ec1b10eb954bb Mon Sep 17 00:00:00 2001 +From: Jeongjun Park +Date: Mon, 19 Jan 2026 17:25:53 +0900 +Subject: drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free + +From: Jeongjun Park + +commit 52b330799e2d6f825ae2bb74662ec1b10eb954bb upstream. + +Exynos Virtual Display driver performs memory alloc/free operations +without lock protection, which easily causes concurrency problem. + +For example, use-after-free can occur in race scenario like this: +``` + CPU0 CPU1 CPU2 + ---- ---- ---- + vidi_connection_ioctl() + if (vidi->connection) // true + drm_edid = drm_edid_alloc(); // alloc drm_edid + ... + ctx->raw_edid = drm_edid; + ... + drm_mode_getconnector() + drm_helper_probe_single_connector_modes() + vidi_get_modes() + if (ctx->raw_edid) // true + drm_edid_dup(ctx->raw_edid); + if (!drm_edid) // false + ... + vidi_connection_ioctl() + if (vidi->connection) // false + drm_edid_free(ctx->raw_edid); // free drm_edid + ... + drm_edid_alloc(drm_edid->edid) + kmemdup(edid); // UAF!! + ... +``` + +To prevent these vulns, at least in vidi_context, member variables related +to memory alloc/free should be protected with ctx->lock. + +Cc: +Signed-off-by: Jeongjun Park +Signed-off-by: Inki Dae +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/exynos/exynos_drm_vidi.c | 43 +++++++++++++++++++++++++------ + 1 file changed, 35 insertions(+), 8 deletions(-) + +--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c +@@ -185,15 +185,17 @@ static ssize_t vidi_store_connection(str + const char *buf, size_t len) + { + struct vidi_context *ctx = dev_get_drvdata(dev); +- int ret; ++ int ret, new_connected; + +- ret = kstrtoint(buf, 0, &ctx->connected); ++ ret = kstrtoint(buf, 0, &new_connected); + if (ret) + return ret; + +- if (ctx->connected > 1) ++ if (new_connected > 1) + return -EINVAL; + ++ mutex_lock(&ctx->lock); ++ + /* use fake edid data for test. */ + if (!ctx->raw_edid) + ctx->raw_edid = (struct edid *)fake_edid_info; +@@ -201,14 +203,21 @@ static ssize_t vidi_store_connection(str + /* if raw_edid isn't same as fake data then it can't be tested. */ + if (ctx->raw_edid != (struct edid *)fake_edid_info) { + DRM_DEV_DEBUG_KMS(dev, "edid data is not fake data.\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto fail; + } + ++ ctx->connected = new_connected; ++ mutex_unlock(&ctx->lock); ++ + DRM_DEV_DEBUG_KMS(dev, "requested connection.\n"); + + drm_helper_hpd_irq_event(ctx->drm_dev); + + return len; ++fail: ++ mutex_unlock(&ctx->lock); ++ return ret; + } + + static DEVICE_ATTR(connection, 0644, vidi_show_connection, +@@ -243,11 +252,14 @@ int vidi_connection_ioctl(struct drm_dev + return -EINVAL; + } + ++ mutex_lock(&ctx->lock); + if (ctx->connected == vidi->connection) { ++ mutex_unlock(&ctx->lock); + DRM_DEV_DEBUG_KMS(ctx->dev, + "same connection request.\n"); + return -EINVAL; + } ++ mutex_unlock(&ctx->lock); + + if (vidi->connection) { + struct edid *raw_edid; +@@ -270,20 +282,27 @@ int vidi_connection_ioctl(struct drm_dev + "failed to allocate raw_edid.\n"); + return -ENOMEM; + } ++ mutex_lock(&ctx->lock); + ctx->raw_edid = raw_edid; ++ mutex_unlock(&ctx->lock); + } else { + /* + * with connection = 0, free raw_edid + * only if raw edid data isn't same as fake data. + */ ++ mutex_lock(&ctx->lock); + if (ctx->raw_edid && ctx->raw_edid != + (struct edid *)fake_edid_info) { + kfree(ctx->raw_edid); + ctx->raw_edid = NULL; + } ++ mutex_unlock(&ctx->lock); + } + ++ mutex_lock(&ctx->lock); + ctx->connected = vidi->connection; ++ mutex_unlock(&ctx->lock); ++ + drm_helper_hpd_irq_event(ctx->drm_dev); + + return 0; +@@ -298,7 +317,7 @@ static enum drm_connector_status vidi_de + * connection request would come from user side + * to do hotplug through specific ioctl. + */ +- return ctx->connected ? connector_status_connected : ++ return READ_ONCE(ctx->connected) ? connector_status_connected : + connector_status_disconnected; + } + +@@ -320,22 +339,24 @@ static int vidi_get_modes(struct drm_con + struct vidi_context *ctx = ctx_from_connector(connector); + struct edid *edid; + int edid_len; +- int count; ++ int count = 0; + + /* + * the edid data comes from user side and it would be set + * to ctx->raw_edid through specific ioctl. + */ ++ ++ mutex_lock(&ctx->lock); + if (!ctx->raw_edid) { + DRM_DEV_DEBUG_KMS(ctx->dev, "raw_edid is null.\n"); +- return 0; ++ goto fail; + } + + edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; + edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL); + if (!edid) { + DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate edid\n"); +- return 0; ++ goto fail; + } + + drm_connector_update_edid_property(connector, edid); +@@ -344,6 +365,8 @@ static int vidi_get_modes(struct drm_con + + kfree(edid); + ++fail: ++ mutex_unlock(&ctx->lock); + return count; + } + +@@ -489,11 +512,15 @@ static int vidi_remove(struct platform_d + { + struct vidi_context *ctx = platform_get_drvdata(pdev); + ++ mutex_lock(&ctx->lock); ++ + if (ctx->raw_edid != (struct edid *)fake_edid_info) { + kfree(ctx->raw_edid); + ctx->raw_edid = NULL; + } + ++ mutex_unlock(&ctx->lock); ++ + component_del(&pdev->dev, &vidi_component_ops); + + return 0; diff --git a/queue-5.15/drm-exynos-vidi-use-priv-vidi_dev-for-ctx-lookup-in-vidi_connection_ioctl.patch b/queue-5.15/drm-exynos-vidi-use-priv-vidi_dev-for-ctx-lookup-in-vidi_connection_ioctl.patch new file mode 100644 index 0000000000..0f29063763 --- /dev/null +++ b/queue-5.15/drm-exynos-vidi-use-priv-vidi_dev-for-ctx-lookup-in-vidi_connection_ioctl.patch @@ -0,0 +1,90 @@ +From d3968a0d85b211e197f2f4f06268a7031079e0d0 Mon Sep 17 00:00:00 2001 +From: Jeongjun Park +Date: Mon, 19 Jan 2026 17:25:51 +0900 +Subject: drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl() + +From: Jeongjun Park + +commit d3968a0d85b211e197f2f4f06268a7031079e0d0 upstream. + +vidi_connection_ioctl() retrieves the driver_data from drm_dev->dev to +obtain a struct vidi_context pointer. However, drm_dev->dev is the +exynos-drm master device, and the driver_data contained therein is not +the vidi component device, but a completely different device. + +This can lead to various bugs, ranging from null pointer dereferences and +garbage value accesses to, in unlucky cases, out-of-bounds errors, +use-after-free errors, and more. + +To resolve this issue, we need to store/delete the vidi device pointer in +exynos_drm_private->vidi_dev during bind/unbind, and then read this +exynos_drm_private->vidi_dev within ioctl() to obtain the correct +struct vidi_context pointer. + +Cc: +Signed-off-by: Jeongjun Park +Signed-off-by: Inki Dae +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 + + drivers/gpu/drm/exynos/exynos_drm_vidi.c | 14 +++++++++++++- + 2 files changed, 14 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h ++++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h +@@ -201,6 +201,7 @@ struct exynos_drm_private { + + struct device *g2d_dev; + struct device *dma_dev; ++ struct device *vidi_dev; + void *mapping; + + /* for atomic commit */ +--- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c +@@ -223,9 +223,14 @@ ATTRIBUTE_GROUPS(vidi); + int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, + struct drm_file *file_priv) + { +- struct vidi_context *ctx = dev_get_drvdata(drm_dev->dev); ++ struct exynos_drm_private *priv = drm_dev->dev_private; ++ struct device *dev = priv ? priv->vidi_dev : NULL; ++ struct vidi_context *ctx = dev ? dev_get_drvdata(dev) : NULL; + struct drm_exynos_vidi_connection *vidi = data; + ++ if (!ctx) ++ return -ENODEV; ++ + if (!vidi) { + DRM_DEV_DEBUG_KMS(ctx->dev, + "user data for vidi is null.\n"); +@@ -385,6 +390,7 @@ static int vidi_bind(struct device *dev, + { + struct vidi_context *ctx = dev_get_drvdata(dev); + struct drm_device *drm_dev = data; ++ struct exynos_drm_private *priv = drm_dev->dev_private; + struct drm_encoder *encoder = &ctx->encoder; + struct exynos_drm_plane *exynos_plane; + struct exynos_drm_plane_config plane_config = { 0 }; +@@ -392,6 +398,8 @@ static int vidi_bind(struct device *dev, + int ret; + + ctx->drm_dev = drm_dev; ++ if (priv) ++ priv->vidi_dev = dev; + + plane_config.pixel_formats = formats; + plane_config.num_pixel_formats = ARRAY_SIZE(formats); +@@ -437,8 +445,12 @@ static int vidi_bind(struct device *dev, + static void vidi_unbind(struct device *dev, struct device *master, void *data) + { + struct vidi_context *ctx = dev_get_drvdata(dev); ++ struct drm_device *drm_dev = data; ++ struct exynos_drm_private *priv = drm_dev->dev_private; + + del_timer_sync(&ctx->timer); ++ if (priv) ++ priv->vidi_dev = NULL; + } + + static const struct component_ops vidi_component_ops = { diff --git a/queue-5.15/gve-defer-interrupt-enabling-until-napi-registration.patch b/queue-5.15/gve-defer-interrupt-enabling-until-napi-registration.patch new file mode 100644 index 0000000000..b119b590fe --- /dev/null +++ b/queue-5.15/gve-defer-interrupt-enabling-until-napi-registration.patch @@ -0,0 +1,91 @@ +From 3d970eda003441f66551a91fda16478ac0711617 Mon Sep 17 00:00:00 2001 +From: Ankit Garg +Date: Fri, 19 Dec 2025 10:29:45 +0000 +Subject: gve: defer interrupt enabling until NAPI registration + +From: Ankit Garg + +commit 3d970eda003441f66551a91fda16478ac0711617 upstream. + +Currently, interrupts are automatically enabled immediately upon +request. This allows interrupt to fire before the associated NAPI +context is fully initialized and cause failures like below: + +[ 0.946369] Call Trace: +[ 0.946369] +[ 0.946369] __napi_poll+0x2a/0x1e0 +[ 0.946369] net_rx_action+0x2f9/0x3f0 +[ 0.946369] handle_softirqs+0xd6/0x2c0 +[ 0.946369] ? handle_edge_irq+0xc1/0x1b0 +[ 0.946369] __irq_exit_rcu+0xc3/0xe0 +[ 0.946369] common_interrupt+0x81/0xa0 +[ 0.946369] +[ 0.946369] +[ 0.946369] asm_common_interrupt+0x22/0x40 +[ 0.946369] RIP: 0010:pv_native_safe_halt+0xb/0x10 + +Use the `IRQF_NO_AUTOEN` flag when requesting interrupts to prevent auto +enablement and explicitly enable the interrupt in NAPI initialization +path (and disable it during NAPI teardown). + +This ensures that interrupt lifecycle is strictly coupled with +readiness of NAPI context. + +Cc: stable@vger.kernel.org +Fixes: 1dfc2e46117e ("gve: Refactor napi add and remove functions") +Signed-off-by: Ankit Garg +Reviewed-by: Jordan Rhee +Reviewed-by: Joshua Washington +Signed-off-by: Harshitha Ramamurthy +Link: https://patch.msgid.link/20251219102945.2193617-1-hramamurthy@google.com +Signed-off-by: Paolo Abeni +[ modified to re-introduce the irq member to struct gve_notify_block, + which was introuduced in commit 9a5e0776d11f ("gve: Avoid rescheduling + napi if on wrong cpu"). ] +Signed-off-by: Joshua Washington +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/google/gve/gve.h | 1 + + drivers/net/ethernet/google/gve/gve_main.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/google/gve/gve.h ++++ b/drivers/net/ethernet/google/gve/gve.h +@@ -441,6 +441,7 @@ struct gve_notify_block { + struct gve_priv *priv; + struct gve_tx_ring *tx; /* tx rings on this block */ + struct gve_rx_ring *rx; /* rx rings on this block */ ++ u32 irq; + } ____cacheline_aligned; + + /* Tracks allowed and current queue settings */ +--- a/drivers/net/ethernet/google/gve/gve_main.c ++++ b/drivers/net/ethernet/google/gve/gve_main.c +@@ -339,9 +339,10 @@ static int gve_alloc_notify_blocks(struc + snprintf(block->name, sizeof(block->name), "%s-ntfy-block.%d", + name, i); + block->priv = priv; ++ block->irq = priv->msix_vectors[msix_idx].vector; + err = request_irq(priv->msix_vectors[msix_idx].vector, + gve_is_gqi(priv) ? gve_intr : gve_intr_dqo, +- 0, block->name, block); ++ IRQF_NO_AUTOEN, block->name, block); + if (err) { + dev_err(&priv->pdev->dev, + "Failed to receive msix vector %d\n", i); +@@ -502,6 +503,7 @@ static void gve_add_napi(struct gve_priv + + netif_napi_add(priv->dev, &block->napi, gve_poll, + NAPI_POLL_WEIGHT); ++ enable_irq(block->irq); + } + + static void gve_remove_napi(struct gve_priv *priv, int ntfy_idx) +@@ -509,6 +511,7 @@ static void gve_remove_napi(struct gve_p + struct gve_notify_block *block = &priv->ntfy_blocks[ntfy_idx]; + + netif_napi_del(&block->napi); ++ disable_irq(block->irq); + } + + static int gve_register_qpls(struct gve_priv *priv) diff --git a/queue-5.15/net-handle-napi_schedule-calls-from-non-interrupt.patch b/queue-5.15/net-handle-napi_schedule-calls-from-non-interrupt.patch new file mode 100644 index 0000000000..d798e5cbe0 --- /dev/null +++ b/queue-5.15/net-handle-napi_schedule-calls-from-non-interrupt.patch @@ -0,0 +1,105 @@ +From 77e45145e3039a0fb212556ab3f8c87f54771757 Mon Sep 17 00:00:00 2001 +From: Frederic Weisbecker +Date: Sun, 23 Feb 2025 23:17:08 +0100 +Subject: net: Handle napi_schedule() calls from non-interrupt + +From: Frederic Weisbecker + +commit 77e45145e3039a0fb212556ab3f8c87f54771757 upstream. + +napi_schedule() is expected to be called either: + +* From an interrupt, where raised softirqs are handled on IRQ exit + +* From a softirq disabled section, where raised softirqs are handled on + the next call to local_bh_enable(). + +* From a softirq handler, where raised softirqs are handled on the next + round in do_softirq(), or further deferred to a dedicated kthread. + +Other bare tasks context may end up ignoring the raised NET_RX vector +until the next random softirq handling opportunity, which may not +happen before a while if the CPU goes idle afterwards with the tick +stopped. + +Such "misuses" have been detected on several places thanks to messages +of the kind: + + "NOHZ tick-stop error: local softirq work is pending, handler #08!!!" + +For example: + + __raise_softirq_irqoff + __napi_schedule + rtl8152_runtime_resume.isra.0 + rtl8152_resume + usb_resume_interface.isra.0 + usb_resume_both + __rpm_callback + rpm_callback + rpm_resume + __pm_runtime_resume + usb_autoresume_device + usb_remote_wakeup + hub_event + process_one_work + worker_thread + kthread + ret_from_fork + ret_from_fork_asm + +And also: + +* drivers/net/usb/r8152.c::rtl_work_func_t +* drivers/net/netdevsim/netdev.c::nsim_start_xmit + +There is a long history of issues of this kind: + + 019edd01d174 ("ath10k: sdio: Add missing BH locking around napi_schdule()") + 330068589389 ("idpf: disable local BH when scheduling napi for marker packets") + e3d5d70cb483 ("net: lan78xx: fix "softirq work is pending" error") + e55c27ed9ccf ("mt76: mt7615: add missing bh-disable around rx napi schedule") + c0182aa98570 ("mt76: mt7915: add missing bh-disable around tx napi enable/schedule") + 970be1dff26d ("mt76: disable BH around napi_schedule() calls") + 019edd01d174 ("ath10k: sdio: Add missing BH locking around napi_schdule()") + 30bfec4fec59 ("can: rx-offload: can_rx_offload_threaded_irq_finish(): add new function to be called from threaded interrupt") + e63052a5dd3c ("mlx5e: add add missing BH locking around napi_schdule()") + 83a0c6e58901 ("i40e: Invoke softirqs after napi_reschedule") + bd4ce941c8d5 ("mlx4: Invoke softirqs after napi_reschedule") + 8cf699ec849f ("mlx4: do not call napi_schedule() without care") + ec13ee80145c ("virtio_net: invoke softirqs after __napi_schedule") + +This shows that relying on the caller to arrange a proper context for +the softirqs to be handled while calling napi_schedule() is very fragile +and error prone. Also fixing them can also prove challenging if the +caller may be called from different kinds of contexts. + +Therefore fix this from napi_schedule() itself with waking up ksoftirqd +when softirqs are raised from task contexts. + +Reported-by: Paul Menzel +Reported-by: Jakub Kicinski +Reported-by: Francois Romieu +Closes: https://lore.kernel.org/lkml/354a2690-9bbf-4ccb-8769-fa94707a9340@molgen.mpg.de/ +Cc: Breno Leitao +Signed-off-by: Frederic Weisbecker +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20250223221708.27130-1-frederic@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Jan Kiszka +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -4439,7 +4439,7 @@ static inline void ____napi_schedule(str + } + + list_add_tail(&napi->poll_list, &sd->poll_list); +- __raise_softirq_irqoff(NET_RX_SOFTIRQ); ++ raise_softirq_irqoff(NET_RX_SOFTIRQ); + } + + #ifdef CONFIG_RPS diff --git a/queue-5.15/net-stmmac-dwmac-loongson-set-clk_csr_i-to-100-150mhz.patch b/queue-5.15/net-stmmac-dwmac-loongson-set-clk_csr_i-to-100-150mhz.patch new file mode 100644 index 0000000000..3a7c15dc50 --- /dev/null +++ b/queue-5.15/net-stmmac-dwmac-loongson-set-clk_csr_i-to-100-150mhz.patch @@ -0,0 +1,38 @@ +From e1aa5ef892fb4fa9014a25e87b64b97347919d37 Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Tue, 3 Feb 2026 14:29:01 +0800 +Subject: net: stmmac: dwmac-loongson: Set clk_csr_i to 100-150MHz + +From: Huacai Chen + +commit e1aa5ef892fb4fa9014a25e87b64b97347919d37 upstream. + +Current clk_csr_i setting of Loongson STMMAC (including LS7A1000/2000 +and LS2K1000/2000/3000) are copy & paste from other drivers. In fact, +Loongson STMMAC use 125MHz clocks and need 62 freq division to within +2.5MHz, meeting most PHY MDC requirement. So fix by setting clk_csr_i +to 100-150MHz, otherwise some PHYs may link fail. + +Cc: stable@vger.kernel.org +Fixes: 30bba69d7db40e7 ("stmmac: pci: Add dwmac support for Loongson") +Signed-off-by: Hongliang Wang +Signed-off-by: Huacai Chen +Link: https://patch.msgid.link/20260203062901.2158236-1-chenhuacai@loongson.cn +Signed-off-by: Jakub Kicinski +Signed-off-by: Huacai Chen +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson.c +@@ -11,7 +11,7 @@ + + static int loongson_default_data(struct plat_stmmacenet_data *plat) + { +- plat->clk_csr = 2; /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ ++ plat->clk_csr = 1; /* clk_csr_i = 100-150MHz & MDC = clk_csr_i/62 */ + plat->has_gmac = 1; + plat->force_sf_dma_mode = 1; + diff --git a/queue-5.15/series b/queue-5.15/series index cd81a422a5..397c7444e3 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -217,3 +217,9 @@ mm-hugetlb-fix-hugetlb_pmd_shared.patch mm-hugetlb-fix-two-comments-related-to-huge_pmd_unshare.patch mm-rmap-fix-two-comments-related-to-huge_pmd_unshare.patch mm-hugetlb-fix-excessive-ipi-broadcasts-when-unsharing-pmd-tables-using-mmu_gather.patch +net-stmmac-dwmac-loongson-set-clk_csr_i-to-100-150mhz.patch +net-handle-napi_schedule-calls-from-non-interrupt.patch +gve-defer-interrupt-enabling-until-napi-registration.patch +drm-exynos-vidi-use-priv-vidi_dev-for-ctx-lookup-in-vidi_connection_ioctl.patch +drm-exynos-vidi-fix-to-avoid-directly-dereferencing-user-pointer.patch +drm-exynos-vidi-use-ctx-lock-to-protect-struct-vidi_context-member-variables-related-to-memory-alloc-free.patch