]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.14
authorSasha Levin <sashal@kernel.org>
Sun, 13 Apr 2025 17:12:35 +0000 (13:12 -0400)
committerSasha Levin <sashal@kernel.org>
Sun, 13 Apr 2025 17:12:35 +0000 (13:12 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
48 files changed:
queue-6.14/ata-pata_pxa-fix-potential-null-pointer-dereference-.patch [new file with mode: 0644]
queue-6.14/ata-sata_sx4-add-error-handling-in-pdc20621_i2c_read.patch [new file with mode: 0644]
queue-6.14/cgroup-cpuset-fix-error-handling-in-remote_partition.patch [new file with mode: 0644]
queue-6.14/cgroup-cpuset-fix-incorrect-isolated_cpus-update-in-.patch [new file with mode: 0644]
queue-6.14/cgroup-cpuset-fix-race-between-newly-created-partiti.patch [new file with mode: 0644]
queue-6.14/cifs-fix-support-for-wsl-style-symlinks.patch [new file with mode: 0644]
queue-6.14/codel-remove-sch-q.qlen-check-before-qdisc_tree_redu.patch [new file with mode: 0644]
queue-6.14/drm-i915-disable-rpg-during-live-selftest.patch [new file with mode: 0644]
queue-6.14/drm-i915-huc-fix-fence-not-released-on-early-probe-e.patch [new file with mode: 0644]
queue-6.14/drm-tests-cmdline-fix-drm_display_mode-memory-leak.patch [new file with mode: 0644]
queue-6.14/drm-tests-helpers-create-kunit-helper-to-destroy-a-d.patch [new file with mode: 0644]
queue-6.14/drm-tests-modes-fix-drm_display_mode-memory-leak.patch [new file with mode: 0644]
queue-6.14/drm-tests-modeset-fix-drm_display_mode-memory-leak.patch [new file with mode: 0644]
queue-6.14/drm-tests-probe-helper-fix-drm_display_mode-memory-l.patch [new file with mode: 0644]
queue-6.14/drm-virtio-fix-flickering-issue-seen-with-imported-d.patch [new file with mode: 0644]
queue-6.14/drm-xe-hw_engine-define-sysfs_ops-on-all-directories.patch [new file with mode: 0644]
queue-6.14/drm-xe-restore-eio-errno-return-when-guc-pc-start-fa.patch [new file with mode: 0644]
queue-6.14/ethtool-cmis_cdb-fix-incorrect-read-write-length-ext.patch [new file with mode: 0644]
queue-6.14/gpiolib-of-fix-the-choice-for-ingenic-nand-quirk.patch [new file with mode: 0644]
queue-6.14/iommu-exynos-fix-suspend-resume-with-identity-domain.patch [new file with mode: 0644]
queue-6.14/iommu-mediatek-fix-null-pointer-deference-in-mtk_iom.patch [new file with mode: 0644]
queue-6.14/ipv6-align-behavior-across-nexthops-during-path-sele.patch [new file with mode: 0644]
queue-6.14/net-ethtool-don-t-call-.cleanup_data-when-prepare_da.patch [new file with mode: 0644]
queue-6.14/net-ethtool-fix-ethtool_ringparam_get_cfg-returns-a-.patch [new file with mode: 0644]
queue-6.14/net-libwx-fix-the-wrong-rx-descriptor-field.patch [new file with mode: 0644]
queue-6.14/net-libwx-handle-page_pool_dev_alloc_pages-error.patch [new file with mode: 0644]
queue-6.14/net-phy-allow-mdio-bus-pm-ops-to-start-stop-state-ma.patch [new file with mode: 0644]
queue-6.14/net-phy-move-phy_link_change-prior-to-mdio_bus_phy_m.patch [new file with mode: 0644]
queue-6.14/net-ppp-add-bound-checking-for-skb-data-on-ppp_sync_.patch [new file with mode: 0644]
queue-6.14/net-tls-explicitly-disallow-disconnect.patch [new file with mode: 0644]
queue-6.14/net_sched-sch_sfq-move-the-limit-validation.patch [new file with mode: 0644]
queue-6.14/net_sched-sch_sfq-use-a-temporary-work-area-for-vali.patch [new file with mode: 0644]
queue-6.14/nft_set_pipapo-fix-incorrect-avx2-match-of-5th-field.patch [new file with mode: 0644]
queue-6.14/nvmet-fcloop-swap-list_add_tail-arguments.patch [new file with mode: 0644]
queue-6.14/objtool-fix-insn_context_switch-handling-in-validate.patch [new file with mode: 0644]
queue-6.14/octeontx2-pf-qos-fix-vf-root-node-parent-queue-index.patch [new file with mode: 0644]
queue-6.14/perf-core-simplify-the-perf_event_alloc-error-path.patch [new file with mode: 0644]
queue-6.14/perf-fix-hang-while-freeing-sigtrap-event.patch [new file with mode: 0644]
queue-6.14/s390-cpumf-fix-double-free-on-error-in-cpumf_pmu_eve.patch [new file with mode: 0644]
queue-6.14/selftests-futex-futex_waitv-wouldblock-test-should-f.patch [new file with mode: 0644]
queue-6.14/series
queue-6.14/smb-client-fix-uaf-in-decryption-with-multichannel.patch [new file with mode: 0644]
queue-6.14/tc-ensure-we-have-enough-buffer-space-when-sending-f.patch [new file with mode: 0644]
queue-6.14/tipc-fix-memory-leak-in-tipc_link_xmit.patch [new file with mode: 0644]
queue-6.14/tracing-fprobe-cleanup-fprobe-hash-when-module-unloa.patch [new file with mode: 0644]
queue-6.14/ublk-fix-handling-recovery-reissue-in-ublk_abort_que.patch [new file with mode: 0644]
queue-6.14/x86-acpi-don-t-limit-cpus-to-1-for-xen-pv-guests-due.patch [new file with mode: 0644]
queue-6.14/x86-cpu-avoid-running-off-the-end-of-an-amd-erratum-.patch [new file with mode: 0644]

diff --git a/queue-6.14/ata-pata_pxa-fix-potential-null-pointer-dereference-.patch b/queue-6.14/ata-pata_pxa-fix-potential-null-pointer-dereference-.patch
new file mode 100644 (file)
index 0000000..c786635
--- /dev/null
@@ -0,0 +1,47 @@
+From f89f154b203e5e953bf8499a77d70fcb5c640247 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 14:14:38 +0800
+Subject: ata: pata_pxa: Fix potential NULL pointer dereference in
+ pxa_ata_probe()
+
+From: Henry Martin <bsdhenrymartin@gmail.com>
+
+[ Upstream commit ad320e408a8c95a282ab9c05cdf0c9b95e317985 ]
+
+devm_ioremap() returns NULL on error. Currently, pxa_ata_probe() does
+not check for this case, which can result in a NULL pointer dereference.
+
+Add NULL check after devm_ioremap() to prevent this issue.
+
+Fixes: 2dc6c6f15da9 ("[ARM] pata_pxa: DMA-capable PATA driver")
+Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/pata_pxa.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/ata/pata_pxa.c b/drivers/ata/pata_pxa.c
+index 434f380114af0..03dbaf4a13a75 100644
+--- a/drivers/ata/pata_pxa.c
++++ b/drivers/ata/pata_pxa.c
+@@ -223,10 +223,16 @@ static int pxa_ata_probe(struct platform_device *pdev)
+       ap->ioaddr.cmd_addr     = devm_ioremap(&pdev->dev, cmd_res->start,
+                                               resource_size(cmd_res));
++      if (!ap->ioaddr.cmd_addr)
++              return -ENOMEM;
+       ap->ioaddr.ctl_addr     = devm_ioremap(&pdev->dev, ctl_res->start,
+                                               resource_size(ctl_res));
++      if (!ap->ioaddr.ctl_addr)
++              return -ENOMEM;
+       ap->ioaddr.bmdma_addr   = devm_ioremap(&pdev->dev, dma_res->start,
+                                               resource_size(dma_res));
++      if (!ap->ioaddr.bmdma_addr)
++              return -ENOMEM;
+       /*
+        * Adjust register offsets
+-- 
+2.39.5
+
diff --git a/queue-6.14/ata-sata_sx4-add-error-handling-in-pdc20621_i2c_read.patch b/queue-6.14/ata-sata_sx4-add-error-handling-in-pdc20621_i2c_read.patch
new file mode 100644 (file)
index 0000000..cd397c0
--- /dev/null
@@ -0,0 +1,66 @@
+From 149e789b845bb629db482916408a26e13184badd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 15:30:01 +0800
+Subject: ata: sata_sx4: Add error handling in pdc20621_i2c_read()
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+[ Upstream commit 8d46a27085039158eb5e253ab8a35a0e33b5e864 ]
+
+The function pdc20621_prog_dimm0() calls the function pdc20621_i2c_read()
+but does not handle the error if the read fails. This could lead to
+process with invalid data. A proper implementation can be found in
+/source/drivers/ata/sata_sx4.c, pdc20621_prog_dimm_global(). As mentioned
+in its commit: bb44e154e25125bef31fa956785e90fccd24610b, the variable spd0
+might be used uninitialized when pdc20621_i2c_read() fails.
+
+Add error handling to pdc20621_i2c_read(). If a read operation fails,
+an error message is logged via dev_err(), and return a negative error
+code.
+
+Add error handling to pdc20621_prog_dimm0() in pdc20621_dimm_init(), and
+return a negative error code if pdc20621_prog_dimm0() fails.
+
+Fixes: 4447d3515616 ("libata: convert the remaining SATA drivers to new init model")
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Reviewed-by: Niklas Cassel <cassel@kernel.org>
+Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/ata/sata_sx4.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
+index a482741eb181f..c3042eca6332d 100644
+--- a/drivers/ata/sata_sx4.c
++++ b/drivers/ata/sata_sx4.c
+@@ -1117,9 +1117,14 @@ static int pdc20621_prog_dimm0(struct ata_host *host)
+       mmio += PDC_CHIP0_OFS;
+       for (i = 0; i < ARRAY_SIZE(pdc_i2c_read_data); i++)
+-              pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
+-                                pdc_i2c_read_data[i].reg,
+-                                &spd0[pdc_i2c_read_data[i].ofs]);
++              if (!pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
++                                     pdc_i2c_read_data[i].reg,
++                                     &spd0[pdc_i2c_read_data[i].ofs])) {
++                      dev_err(host->dev,
++                              "Failed in i2c read at index %d: device=%#x, reg=%#x\n",
++                              i, PDC_DIMM0_SPD_DEV_ADDRESS, pdc_i2c_read_data[i].reg);
++                      return -EIO;
++              }
+       data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4);
+       data |= ((spd0[17] / 4) << 6) | ((spd0[5] / 2) << 7) |
+@@ -1284,6 +1289,8 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host)
+       /* Programming DIMM0 Module Control Register (index_CID0:80h) */
+       size = pdc20621_prog_dimm0(host);
++      if (size < 0)
++              return size;
+       dev_dbg(host->dev, "Local DIMM Size = %dMB\n", size);
+       /* Programming DIMM Module Global Control Register (index_CID0:88h) */
+-- 
+2.39.5
+
diff --git a/queue-6.14/cgroup-cpuset-fix-error-handling-in-remote_partition.patch b/queue-6.14/cgroup-cpuset-fix-error-handling-in-remote_partition.patch
new file mode 100644 (file)
index 0000000..b2f770d
--- /dev/null
@@ -0,0 +1,102 @@
+From 9656cf10a53005333507e1911a9a7adb210f5ba5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Mar 2025 17:52:41 -0400
+Subject: cgroup/cpuset: Fix error handling in remote_partition_disable()
+
+From: Waiman Long <longman@redhat.com>
+
+[ Upstream commit 8bf450f3aec3d1bbd725d179502c64b8992588e4 ]
+
+When remote_partition_disable() is called to disable a remote partition,
+it always sets the partition to an invalid partition state. It should
+only do so if an error code (prs_err) has been set. Correct that and
+add proper error code in places where remote_partition_disable() is
+called due to error.
+
+Fixes: 181c8e091aae ("cgroup/cpuset: Introduce remote partition")
+Signed-off-by: Waiman Long <longman@redhat.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/cgroup/cpuset.c | 29 ++++++++++++++++++++---------
+ 1 file changed, 20 insertions(+), 9 deletions(-)
+
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index 0a7ec0f1ce4e7..e8ab1a16076fb 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -1416,6 +1416,7 @@ static int remote_partition_enable(struct cpuset *cs, int new_prs,
+       list_add(&cs->remote_sibling, &remote_children);
+       spin_unlock_irq(&callback_lock);
+       update_unbound_workqueue_cpumask(isolcpus_updated);
++      cs->prs_err = 0;
+       /*
+        * Propagate changes in top_cpuset's effective_cpus down the hierarchy.
+@@ -1446,9 +1447,11 @@ static void remote_partition_disable(struct cpuset *cs, struct tmpmasks *tmp)
+       list_del_init(&cs->remote_sibling);
+       isolcpus_updated = partition_xcpus_del(cs->partition_root_state,
+                                              NULL, tmp->new_cpus);
+-      cs->partition_root_state = -cs->partition_root_state;
+-      if (!cs->prs_err)
+-              cs->prs_err = PERR_INVCPUS;
++      if (cs->prs_err)
++              cs->partition_root_state = -cs->partition_root_state;
++      else
++              cs->partition_root_state = PRS_MEMBER;
++
+       reset_partition_data(cs);
+       spin_unlock_irq(&callback_lock);
+       update_unbound_workqueue_cpumask(isolcpus_updated);
+@@ -1481,8 +1484,10 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *newmask,
+       WARN_ON_ONCE(!cpumask_subset(cs->effective_xcpus, subpartitions_cpus));
+-      if (cpumask_empty(newmask))
++      if (cpumask_empty(newmask)) {
++              cs->prs_err = PERR_CPUSEMPTY;
+               goto invalidate;
++      }
+       adding   = cpumask_andnot(tmp->addmask, newmask, cs->effective_xcpus);
+       deleting = cpumask_andnot(tmp->delmask, cs->effective_xcpus, newmask);
+@@ -1492,10 +1497,15 @@ static void remote_cpus_update(struct cpuset *cs, struct cpumask *newmask,
+        * not allocated to other partitions and there are effective_cpus
+        * left in the top cpuset.
+        */
+-      if (adding && (!capable(CAP_SYS_ADMIN) ||
+-                     cpumask_intersects(tmp->addmask, subpartitions_cpus) ||
+-                     cpumask_subset(top_cpuset.effective_cpus, tmp->addmask)))
+-              goto invalidate;
++      if (adding) {
++              if (!capable(CAP_SYS_ADMIN))
++                      cs->prs_err = PERR_ACCESS;
++              else if (cpumask_intersects(tmp->addmask, subpartitions_cpus) ||
++                       cpumask_subset(top_cpuset.effective_cpus, tmp->addmask))
++                      cs->prs_err = PERR_NOCPUS;
++              if (cs->prs_err)
++                      goto invalidate;
++      }
+       spin_lock_irq(&callback_lock);
+       if (adding)
+@@ -1611,7 +1621,7 @@ static bool prstate_housekeeping_conflict(int prstate, struct cpumask *new_cpus)
+  * The partcmd_update command is used by update_cpumasks_hier() with newmask
+  * NULL and update_cpumask() with newmask set. The partcmd_invalidate is used
+  * by update_cpumask() with NULL newmask. In both cases, the callers won't
+- * check for error and so partition_root_state and prs_error will be updated
++ * check for error and so partition_root_state and prs_err will be updated
+  * directly.
+  */
+ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
+@@ -3749,6 +3759,7 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp)
+       if (remote && cpumask_empty(&new_cpus) &&
+           partition_is_populated(cs, NULL)) {
++              cs->prs_err = PERR_HOTPLUG;
+               remote_partition_disable(cs, tmp);
+               compute_effective_cpumask(&new_cpus, cs, parent);
+               remote = false;
+-- 
+2.39.5
+
diff --git a/queue-6.14/cgroup-cpuset-fix-incorrect-isolated_cpus-update-in-.patch b/queue-6.14/cgroup-cpuset-fix-incorrect-isolated_cpus-update-in-.patch
new file mode 100644 (file)
index 0000000..b9688e0
--- /dev/null
@@ -0,0 +1,56 @@
+From c6349af1ec56d929af1d8027fd32e4b25ea4581d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Mar 2025 17:52:40 -0400
+Subject: cgroup/cpuset: Fix incorrect isolated_cpus update in
+ update_parent_effective_cpumask()
+
+From: Waiman Long <longman@redhat.com>
+
+[ Upstream commit 668e041662e92ab3ebcb9eb606d3ec01884546ab ]
+
+Before commit f0af1bfc27b5 ("cgroup/cpuset: Relax constraints to
+partition & cpus changes"), a cpuset partition cannot be enabled if not
+all the requested CPUs can be granted from the parent cpuset. After
+that commit, a cpuset partition can be created even if the requested
+exclusive CPUs contain CPUs not allowed its parent.  The delmask
+containing exclusive CPUs to be removed from its parent wasn't
+adjusted accordingly.
+
+That is not a problem until the introduction of a new isolated_cpus
+mask in commit 11e5f407b64a ("cgroup/cpuset: Keep track of CPUs in
+isolated partitions") as the CPUs in the delmask may be added directly
+into isolated_cpus.
+
+As a result, isolated_cpus may incorrectly contain CPUs that are not
+isolated leading to incorrect data reporting. Fix this by adjusting
+the delmask to reflect the actual exclusive CPUs for the creation of
+the partition.
+
+Fixes: 11e5f407b64a ("cgroup/cpuset: Keep track of CPUs in isolated partitions")
+Signed-off-by: Waiman Long <longman@redhat.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/cgroup/cpuset.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index 1892dc8cd2119..0a7ec0f1ce4e7 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -1689,9 +1689,9 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,
+               if (nocpu)
+                       return PERR_NOCPUS;
+-              cpumask_copy(tmp->delmask, xcpus);
+-              deleting = true;
+-              subparts_delta++;
++              deleting = cpumask_and(tmp->delmask, xcpus, parent->effective_xcpus);
++              if (deleting)
++                      subparts_delta++;
+               new_prs = (cmd == partcmd_enable) ? PRS_ROOT : PRS_ISOLATED;
+       } else if (cmd == partcmd_disable) {
+               /*
+-- 
+2.39.5
+
diff --git a/queue-6.14/cgroup-cpuset-fix-race-between-newly-created-partiti.patch b/queue-6.14/cgroup-cpuset-fix-race-between-newly-created-partiti.patch
new file mode 100644 (file)
index 0000000..75c6d37
--- /dev/null
@@ -0,0 +1,144 @@
+From e25c9a17dd33b6bc24371957a8038f7cd36acd9e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 30 Mar 2025 17:52:39 -0400
+Subject: cgroup/cpuset: Fix race between newly created partition and dying one
+
+From: Waiman Long <longman@redhat.com>
+
+[ Upstream commit a22b3d54de94f82ca057cc2ebf9496fa91ebf698 ]
+
+There is a possible race between removing a cgroup diectory that is
+a partition root and the creation of a new partition.  The partition
+to be removed can be dying but still online, it doesn't not currently
+participate in checking for exclusive CPUs conflict, but the exclusive
+CPUs are still there in subpartitions_cpus and isolated_cpus. These
+two cpumasks are global states that affect the operation of cpuset
+partitions. The exclusive CPUs in dying cpusets will only be removed
+when cpuset_css_offline() function is called after an RCU delay.
+
+As a result, it is possible that a new partition can be created with
+exclusive CPUs that overlap with those of a dying one. When that dying
+partition is finally offlined, it removes those overlapping exclusive
+CPUs from subpartitions_cpus and maybe isolated_cpus resulting in an
+incorrect CPU configuration.
+
+This bug was found when a warning was triggered in
+remote_partition_disable() during testing because the subpartitions_cpus
+mask was empty.
+
+One possible way to fix this is to iterate the dying cpusets as well and
+avoid using the exclusive CPUs in those dying cpusets. However, this
+can still cause random partition creation failures or other anomalies
+due to racing. A better way to fix this race is to reset the partition
+state at the moment when a cpuset is being killed.
+
+Introduce a new css_killed() CSS function pointer and call it, if
+defined, before setting CSS_DYING flag in kill_css(). Also update the
+css_is_dying() helper to use the CSS_DYING flag introduced by commit
+33c35aa48178 ("cgroup: Prevent kill_css() from being called more than
+once") for proper synchronization.
+
+Add a new cpuset_css_killed() function to reset the partition state of
+a valid partition root if it is being killed.
+
+Fixes: ee8dde0cd2ce ("cpuset: Add new v2 cpuset.sched.partition flag")
+Signed-off-by: Waiman Long <longman@redhat.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/cgroup-defs.h |  1 +
+ include/linux/cgroup.h      |  2 +-
+ kernel/cgroup/cgroup.c      |  6 ++++++
+ kernel/cgroup/cpuset.c      | 20 +++++++++++++++++---
+ 4 files changed, 25 insertions(+), 4 deletions(-)
+
+diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
+index 17960a1e858db..d1aee2d3e189e 100644
+--- a/include/linux/cgroup-defs.h
++++ b/include/linux/cgroup-defs.h
+@@ -711,6 +711,7 @@ struct cgroup_subsys {
+       void (*css_released)(struct cgroup_subsys_state *css);
+       void (*css_free)(struct cgroup_subsys_state *css);
+       void (*css_reset)(struct cgroup_subsys_state *css);
++      void (*css_killed)(struct cgroup_subsys_state *css);
+       void (*css_rstat_flush)(struct cgroup_subsys_state *css, int cpu);
+       int (*css_extra_stat_show)(struct seq_file *seq,
+                                  struct cgroup_subsys_state *css);
+diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
+index f8ef47f8a634d..fc1324ed597d6 100644
+--- a/include/linux/cgroup.h
++++ b/include/linux/cgroup.h
+@@ -343,7 +343,7 @@ static inline u64 cgroup_id(const struct cgroup *cgrp)
+  */
+ static inline bool css_is_dying(struct cgroup_subsys_state *css)
+ {
+-      return !(css->flags & CSS_NO_REF) && percpu_ref_is_dying(&css->refcnt);
++      return css->flags & CSS_DYING;
+ }
+ static inline void cgroup_get(struct cgroup *cgrp)
+diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
+index afc665b7b1fe5..81f078c059e86 100644
+--- a/kernel/cgroup/cgroup.c
++++ b/kernel/cgroup/cgroup.c
+@@ -5909,6 +5909,12 @@ static void kill_css(struct cgroup_subsys_state *css)
+       if (css->flags & CSS_DYING)
+               return;
++      /*
++       * Call css_killed(), if defined, before setting the CSS_DYING flag
++       */
++      if (css->ss->css_killed)
++              css->ss->css_killed(css);
++
+       css->flags |= CSS_DYING;
+       /*
+diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
+index e8ab1a16076fb..d72f843d9feeb 100644
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -3495,9 +3495,6 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css)
+       cpus_read_lock();
+       mutex_lock(&cpuset_mutex);
+-      if (is_partition_valid(cs))
+-              update_prstate(cs, 0);
+-
+       if (!cpuset_v2() && is_sched_load_balance(cs))
+               cpuset_update_flag(CS_SCHED_LOAD_BALANCE, cs, 0);
+@@ -3508,6 +3505,22 @@ static void cpuset_css_offline(struct cgroup_subsys_state *css)
+       cpus_read_unlock();
+ }
++static void cpuset_css_killed(struct cgroup_subsys_state *css)
++{
++      struct cpuset *cs = css_cs(css);
++
++      cpus_read_lock();
++      mutex_lock(&cpuset_mutex);
++
++      /* Reset valid partition back to member */
++      if (is_partition_valid(cs))
++              update_prstate(cs, PRS_MEMBER);
++
++      mutex_unlock(&cpuset_mutex);
++      cpus_read_unlock();
++
++}
++
+ static void cpuset_css_free(struct cgroup_subsys_state *css)
+ {
+       struct cpuset *cs = css_cs(css);
+@@ -3629,6 +3642,7 @@ struct cgroup_subsys cpuset_cgrp_subsys = {
+       .css_alloc      = cpuset_css_alloc,
+       .css_online     = cpuset_css_online,
+       .css_offline    = cpuset_css_offline,
++      .css_killed     = cpuset_css_killed,
+       .css_free       = cpuset_css_free,
+       .can_attach     = cpuset_can_attach,
+       .cancel_attach  = cpuset_cancel_attach,
+-- 
+2.39.5
+
diff --git a/queue-6.14/cifs-fix-support-for-wsl-style-symlinks.patch b/queue-6.14/cifs-fix-support-for-wsl-style-symlinks.patch
new file mode 100644 (file)
index 0000000..5ed94eb
--- /dev/null
@@ -0,0 +1,123 @@
+From 9134a2ddca87b4f78e6b08dc1b4f801cec9b9e83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 00:29:49 +0200
+Subject: cifs: Fix support for WSL-style symlinks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pali Rohár <pali@kernel.org>
+
+[ Upstream commit c7efac7f1c71470ecd9b1a9a49b1b8164583c7dc ]
+
+MS-FSCC in section 2.1.2.7 LX SYMLINK REPARSE_DATA_BUFFER now contains
+documentation about WSL symlink reparse point buffers.
+
+https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/68337353-9153-4ee1-ac6b-419839c3b7ad
+
+Fix the struct reparse_wsl_symlink_data_buffer to reflect buffer fields
+according to the MS-FSCC documentation.
+
+Fix the Linux SMB client to correctly fill the WSL symlink reparse point
+buffer when creaing new WSL-style symlink. There was a mistake during
+filling the data part of the reparse point buffer. It should starts with
+bytes "\x02\x00\x00\x00" (which represents version 2) but this constant was
+written as number 0x02000000 encoded in little endian, which resulted bytes
+"\x00\x00\x00\x02". This change is fixing this mistake.
+
+Fixes: 4e2043be5c14 ("cifs: Add support for creating WSL-style symlinks")
+Signed-off-by: Pali Rohár <pali@kernel.org>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/reparse.c | 25 ++++++++++++++++---------
+ fs/smb/common/smb2pdu.h |  6 +++---
+ 2 files changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c
+index 2b9e9885dc425..7a01f5def58fb 100644
+--- a/fs/smb/client/reparse.c
++++ b/fs/smb/client/reparse.c
+@@ -542,12 +542,12 @@ static int wsl_set_reparse_buf(struct reparse_data_buffer **buf,
+                       kfree(symname_utf16);
+                       return -ENOMEM;
+               }
+-              /* Flag 0x02000000 is unknown, but all wsl symlinks have this value */
+-              symlink_buf->Flags = cpu_to_le32(0x02000000);
+-              /* PathBuffer is in UTF-8 but without trailing null-term byte */
++              /* Version field must be set to 2 (MS-FSCC 2.1.2.7) */
++              symlink_buf->Version = cpu_to_le32(2);
++              /* Target for Version 2 is in UTF-8 but without trailing null-term byte */
+               symname_utf8_len = utf16s_to_utf8s((wchar_t *)symname_utf16, symname_utf16_len/2,
+                                                  UTF16_LITTLE_ENDIAN,
+-                                                 symlink_buf->PathBuffer,
++                                                 symlink_buf->Target,
+                                                  symname_utf8_maxlen);
+               *buf = (struct reparse_data_buffer *)symlink_buf;
+               buf_len = sizeof(struct reparse_wsl_symlink_data_buffer) + symname_utf8_len;
+@@ -1016,29 +1016,36 @@ static int parse_reparse_wsl_symlink(struct reparse_wsl_symlink_data_buffer *buf
+                                    struct cifs_open_info_data *data)
+ {
+       int len = le16_to_cpu(buf->ReparseDataLength);
++      int data_offset = offsetof(typeof(*buf), Target) - offsetof(typeof(*buf), Version);
+       int symname_utf8_len;
+       __le16 *symname_utf16;
+       int symname_utf16_len;
+-      if (len <= sizeof(buf->Flags)) {
++      if (len <= data_offset) {
+               cifs_dbg(VFS, "srv returned malformed wsl symlink buffer\n");
+               return -EIO;
+       }
+-      /* PathBuffer is in UTF-8 but without trailing null-term byte */
+-      symname_utf8_len = len - sizeof(buf->Flags);
++      /* MS-FSCC 2.1.2.7 defines layout of the Target field only for Version 2. */
++      if (le32_to_cpu(buf->Version) != 2) {
++              cifs_dbg(VFS, "srv returned unsupported wsl symlink version %u\n", le32_to_cpu(buf->Version));
++              return -EIO;
++      }
++
++      /* Target for Version 2 is in UTF-8 but without trailing null-term byte */
++      symname_utf8_len = len - data_offset;
+       /*
+        * Check that buffer does not contain null byte
+        * because Linux cannot process symlink with null byte.
+        */
+-      if (strnlen(buf->PathBuffer, symname_utf8_len) != symname_utf8_len) {
++      if (strnlen(buf->Target, symname_utf8_len) != symname_utf8_len) {
+               cifs_dbg(VFS, "srv returned null byte in wsl symlink target location\n");
+               return -EIO;
+       }
+       symname_utf16 = kzalloc(symname_utf8_len * 2, GFP_KERNEL);
+       if (!symname_utf16)
+               return -ENOMEM;
+-      symname_utf16_len = utf8s_to_utf16s(buf->PathBuffer, symname_utf8_len,
++      symname_utf16_len = utf8s_to_utf16s(buf->Target, symname_utf8_len,
+                                           UTF16_LITTLE_ENDIAN,
+                                           (wchar_t *) symname_utf16, symname_utf8_len * 2);
+       if (symname_utf16_len < 0) {
+diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
+index c7a0efda44036..12f0013334057 100644
+--- a/fs/smb/common/smb2pdu.h
++++ b/fs/smb/common/smb2pdu.h
+@@ -1564,13 +1564,13 @@ struct reparse_nfs_data_buffer {
+       __u8    DataBuffer[];
+ } __packed;
+-/* For IO_REPARSE_TAG_LX_SYMLINK */
++/* For IO_REPARSE_TAG_LX_SYMLINK - see MS-FSCC 2.1.2.7 */
+ struct reparse_wsl_symlink_data_buffer {
+       __le32  ReparseTag;
+       __le16  ReparseDataLength;
+       __u16   Reserved;
+-      __le32  Flags;
+-      __u8    PathBuffer[]; /* Variable Length UTF-8 string without nul-term */
++      __le32  Version; /* Always 2 */
++      __u8    Target[]; /* Variable Length UTF-8 string without nul-term */
+ } __packed;
+ struct validate_negotiate_info_req {
+-- 
+2.39.5
+
diff --git a/queue-6.14/codel-remove-sch-q.qlen-check-before-qdisc_tree_redu.patch b/queue-6.14/codel-remove-sch-q.qlen-check-before-qdisc_tree_redu.patch
new file mode 100644 (file)
index 0000000..2eb1ca2
--- /dev/null
@@ -0,0 +1,63 @@
+From 0756615a18439820b3aec4a2f22049b5832ea329 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 14:16:31 -0700
+Subject: codel: remove sch->q.qlen check before qdisc_tree_reduce_backlog()
+
+From: Cong Wang <xiyou.wangcong@gmail.com>
+
+[ Upstream commit 342debc12183b51773b3345ba267e9263bdfaaef ]
+
+After making all ->qlen_notify() callbacks idempotent, now it is safe to
+remove the check of qlen!=0 from both fq_codel_dequeue() and
+codel_qdisc_dequeue().
+
+Reported-by: Gerrard Tai <gerrard.tai@starlabs.sg>
+Fixes: 4b549a2ef4be ("fq_codel: Fair Queue Codel AQM")
+Fixes: 76e3cc126bb2 ("codel: Controlled Delay AQM")
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250403211636.166257-1-xiyou.wangcong@gmail.com
+Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_codel.c    | 5 +----
+ net/sched/sch_fq_codel.c | 6 ++----
+ 2 files changed, 3 insertions(+), 8 deletions(-)
+
+diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c
+index 81189d02fee76..12dd71139da39 100644
+--- a/net/sched/sch_codel.c
++++ b/net/sched/sch_codel.c
+@@ -65,10 +65,7 @@ static struct sk_buff *codel_qdisc_dequeue(struct Qdisc *sch)
+                           &q->stats, qdisc_pkt_len, codel_get_enqueue_time,
+                           drop_func, dequeue_func);
+-      /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
+-       * or HTB crashes. Defer it for next round.
+-       */
+-      if (q->stats.drop_count && sch->q.qlen) {
++      if (q->stats.drop_count) {
+               qdisc_tree_reduce_backlog(sch, q->stats.drop_count, q->stats.drop_len);
+               q->stats.drop_count = 0;
+               q->stats.drop_len = 0;
+diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
+index 799f5397ad4c1..6c9029f71e88d 100644
+--- a/net/sched/sch_fq_codel.c
++++ b/net/sched/sch_fq_codel.c
+@@ -315,10 +315,8 @@ static struct sk_buff *fq_codel_dequeue(struct Qdisc *sch)
+       }
+       qdisc_bstats_update(sch, skb);
+       flow->deficit -= qdisc_pkt_len(skb);
+-      /* We cant call qdisc_tree_reduce_backlog() if our qlen is 0,
+-       * or HTB crashes. Defer it for next round.
+-       */
+-      if (q->cstats.drop_count && sch->q.qlen) {
++
++      if (q->cstats.drop_count) {
+               qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
+                                         q->cstats.drop_len);
+               q->cstats.drop_count = 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-i915-disable-rpg-during-live-selftest.patch b/queue-6.14/drm-i915-disable-rpg-during-live-selftest.patch
new file mode 100644 (file)
index 0000000..1aa6e54
--- /dev/null
@@ -0,0 +1,110 @@
+From c5a4f7caa74326538b450631457fdff8cc98ca66 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 10 Mar 2025 20:58:21 +0530
+Subject: drm/i915: Disable RPG during live selftest
+
+From: Badal Nilawar <badal.nilawar@intel.com>
+
+[ Upstream commit 9d3d9776bd3bd9c32d460dfe6c3363134de578bc ]
+
+The Forcewake timeout issue has been observed on Gen 12.0 and above.
+To address this, disable Render Power-Gating (RPG) during live self-tests
+for these generations. The temporary workaround 'drm/i915/mtl: do not
+enable render power-gating on MTL' disables RPG globally, which is
+unnecessary since the issues were only seen during self-tests.
+
+v2: take runtime pm wakeref
+
+Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/9413
+Fixes: 25e7976db86b ("drm/i915/mtl: do not enable render power-gating on MTL")
+Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
+Cc: Andi Shyti <andi.shyti@intel.com>
+Cc: Andrzej Hajda <andrzej.hajda@intel.com>
+Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
+Signed-off-by: Sk Anirban <sk.anirban@intel.com>
+Reviewed-by: Karthik Poosa <karthik.poosa@intel.com>
+Signed-off-by: Anshuman Gupta <anshuman.gupta@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250310152821.2931678-1-sk.anirban@intel.com
+(cherry picked from commit 0a4ae87706c6d15d14648e428c3a76351f823e48)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/intel_rc6.c           | 19 ++++---------------
+ .../gpu/drm/i915/selftests/i915_selftest.c    | 18 ++++++++++++++++++
+ 2 files changed, 22 insertions(+), 15 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/intel_rc6.c b/drivers/gpu/drm/i915/gt/intel_rc6.c
+index 9378d5901c493..9ca42589da4da 100644
+--- a/drivers/gpu/drm/i915/gt/intel_rc6.c
++++ b/drivers/gpu/drm/i915/gt/intel_rc6.c
+@@ -117,21 +117,10 @@ static void gen11_rc6_enable(struct intel_rc6 *rc6)
+                       GEN6_RC_CTL_RC6_ENABLE |
+                       GEN6_RC_CTL_EI_MODE(1);
+-      /*
+-       * BSpec 52698 - Render powergating must be off.
+-       * FIXME BSpec is outdated, disabling powergating for MTL is just
+-       * temporary wa and should be removed after fixing real cause
+-       * of forcewake timeouts.
+-       */
+-      if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)))
+-              pg_enable =
+-                      GEN9_MEDIA_PG_ENABLE |
+-                      GEN11_MEDIA_SAMPLER_PG_ENABLE;
+-      else
+-              pg_enable =
+-                      GEN9_RENDER_PG_ENABLE |
+-                      GEN9_MEDIA_PG_ENABLE |
+-                      GEN11_MEDIA_SAMPLER_PG_ENABLE;
++      pg_enable =
++              GEN9_RENDER_PG_ENABLE |
++              GEN9_MEDIA_PG_ENABLE |
++              GEN11_MEDIA_SAMPLER_PG_ENABLE;
+       if (GRAPHICS_VER(gt->i915) >= 12 && !IS_DG1(gt->i915)) {
+               for (i = 0; i < I915_MAX_VCS; i++)
+diff --git a/drivers/gpu/drm/i915/selftests/i915_selftest.c b/drivers/gpu/drm/i915/selftests/i915_selftest.c
+index fee76c1d2f450..889281819c5b1 100644
+--- a/drivers/gpu/drm/i915/selftests/i915_selftest.c
++++ b/drivers/gpu/drm/i915/selftests/i915_selftest.c
+@@ -23,7 +23,9 @@
+ #include <linux/random.h>
++#include "gt/intel_gt.h"
+ #include "gt/intel_gt_pm.h"
++#include "gt/intel_gt_regs.h"
+ #include "gt/uc/intel_gsc_fw.h"
+ #include "i915_driver.h"
+@@ -253,11 +255,27 @@ int i915_mock_selftests(void)
+ int i915_live_selftests(struct pci_dev *pdev)
+ {
+       struct drm_i915_private *i915 = pdev_to_i915(pdev);
++      struct intel_uncore *uncore = &i915->uncore;
+       int err;
++      u32 pg_enable;
++      intel_wakeref_t wakeref;
+       if (!i915_selftest.live)
+               return 0;
++      /*
++       * FIXME Disable render powergating, this is temporary wa and should be removed
++       * after fixing real cause of forcewake timeouts.
++       */
++      with_intel_runtime_pm(uncore->rpm, wakeref) {
++              if (IS_GFX_GT_IP_RANGE(to_gt(i915), IP_VER(12, 00), IP_VER(12, 74))) {
++                      pg_enable = intel_uncore_read(uncore, GEN9_PG_ENABLE);
++                      if (pg_enable & GEN9_RENDER_PG_ENABLE)
++                              intel_uncore_write_fw(uncore, GEN9_PG_ENABLE,
++                                                    pg_enable & ~GEN9_RENDER_PG_ENABLE);
++              }
++      }
++
+       __wait_gsc_proxy_completed(i915);
+       __wait_gsc_huc_load_completed(i915);
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-i915-huc-fix-fence-not-released-on-early-probe-e.patch b/queue-6.14/drm-i915-huc-fix-fence-not-released-on-early-probe-e.patch
new file mode 100644 (file)
index 0000000..5b7f8b5
--- /dev/null
@@ -0,0 +1,142 @@
+From ce425e3ac369cef13d88608cdbd1127542018aa6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 19:20:57 +0200
+Subject: drm/i915/huc: Fix fence not released on early probe errors
+
+From: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
+
+[ Upstream commit e3ea2eae70692a455e256787e4f54153fb739b90 ]
+
+HuC delayed loading fence, introduced with commit 27536e03271da
+("drm/i915/huc: track delayed HuC load with a fence"), is registered with
+object tracker early on driver probe but unregistered only from driver
+remove, which is not called on early probe errors.  Since its memory is
+allocated under devres, then released anyway, it may happen to be
+allocated again to the fence and reused on future driver probes, resulting
+in kernel warnings that taint the kernel:
+
+<4> [309.731371] ------------[ cut here ]------------
+<3> [309.731373] ODEBUG: init destroyed (active state 0) object: ffff88813d7dd2e0 object type: i915_sw_fence hint: sw_fence_dummy_notify+0x0/0x20 [i915]
+<4> [309.731575] WARNING: CPU: 2 PID: 3161 at lib/debugobjects.c:612 debug_print_object+0x93/0xf0
+...
+<4> [309.731693] CPU: 2 UID: 0 PID: 3161 Comm: i915_module_loa Tainted: G     U             6.14.0-CI_DRM_16362-gf0fd77956987+ #1
+...
+<4> [309.731700] RIP: 0010:debug_print_object+0x93/0xf0
+...
+<4> [309.731728] Call Trace:
+<4> [309.731730]  <TASK>
+...
+<4> [309.731949]  __debug_object_init+0x17b/0x1c0
+<4> [309.731957]  debug_object_init+0x34/0x50
+<4> [309.732126]  __i915_sw_fence_init+0x34/0x60 [i915]
+<4> [309.732256]  intel_huc_init_early+0x4b/0x1d0 [i915]
+<4> [309.732468]  intel_uc_init_early+0x61/0x680 [i915]
+<4> [309.732667]  intel_gt_common_init_early+0x105/0x130 [i915]
+<4> [309.732804]  intel_root_gt_init_early+0x63/0x80 [i915]
+<4> [309.732938]  i915_driver_probe+0x1fa/0xeb0 [i915]
+<4> [309.733075]  i915_pci_probe+0xe6/0x220 [i915]
+<4> [309.733198]  local_pci_probe+0x44/0xb0
+<4> [309.733203]  pci_device_probe+0xf4/0x270
+<4> [309.733209]  really_probe+0xee/0x3c0
+<4> [309.733215]  __driver_probe_device+0x8c/0x180
+<4> [309.733219]  driver_probe_device+0x24/0xd0
+<4> [309.733223]  __driver_attach+0x10f/0x220
+<4> [309.733230]  bus_for_each_dev+0x7d/0xe0
+<4> [309.733236]  driver_attach+0x1e/0x30
+<4> [309.733239]  bus_add_driver+0x151/0x290
+<4> [309.733244]  driver_register+0x5e/0x130
+<4> [309.733247]  __pci_register_driver+0x7d/0x90
+<4> [309.733251]  i915_pci_register_driver+0x23/0x30 [i915]
+<4> [309.733413]  i915_init+0x34/0x120 [i915]
+<4> [309.733655]  do_one_initcall+0x62/0x3f0
+<4> [309.733667]  do_init_module+0x97/0x2a0
+<4> [309.733671]  load_module+0x25ff/0x2890
+<4> [309.733688]  init_module_from_file+0x97/0xe0
+<4> [309.733701]  idempotent_init_module+0x118/0x330
+<4> [309.733711]  __x64_sys_finit_module+0x77/0x100
+<4> [309.733715]  x64_sys_call+0x1f37/0x2650
+<4> [309.733719]  do_syscall_64+0x91/0x180
+<4> [309.733763]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+<4> [309.733792]  </TASK>
+...
+<4> [309.733806] ---[ end trace 0000000000000000 ]---
+
+That scenario is most easily reproducible with
+igt@i915_module_load@reload-with-fault-injection.
+
+Fix the issue by moving the cleanup step to driver release path.
+
+Fixes: 27536e03271da ("drm/i915/huc: track delayed HuC load with a fence")
+Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13592
+Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Cc: Alan Previn <alan.previn.teres.alexis@intel.com>
+Signed-off-by: Janusz Krzysztofik <janusz.krzysztofik@linux.intel.com>
+Reviewed-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Reviewed-by: Krzysztof Karas <krzysztof.karas@intel.com>
+Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
+Link: https://lore.kernel.org/r/20250402172057.209924-2-janusz.krzysztofik@linux.intel.com
+(cherry picked from commit 795dbde92fe5c6996a02a5b579481de73035e7bf)
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/i915/gt/uc/intel_huc.c | 11 +++++------
+ drivers/gpu/drm/i915/gt/uc/intel_huc.h |  1 +
+ drivers/gpu/drm/i915/gt/uc/intel_uc.c  |  1 +
+ 3 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.c b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+index b3cbf85c00cbd..eb59c1f2dccdc 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.c
+@@ -317,6 +317,11 @@ void intel_huc_init_early(struct intel_huc *huc)
+       }
+ }
++void intel_huc_fini_late(struct intel_huc *huc)
++{
++      delayed_huc_load_fini(huc);
++}
++
+ #define HUC_LOAD_MODE_STRING(x) (x ? "GSC" : "legacy")
+ static int check_huc_loading_mode(struct intel_huc *huc)
+ {
+@@ -414,12 +419,6 @@ int intel_huc_init(struct intel_huc *huc)
+ void intel_huc_fini(struct intel_huc *huc)
+ {
+-      /*
+-       * the fence is initialized in init_early, so we need to clean it up
+-       * even if HuC loading is off.
+-       */
+-      delayed_huc_load_fini(huc);
+-
+       if (huc->heci_pkt)
+               i915_vma_unpin_and_release(&huc->heci_pkt, 0);
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_huc.h b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
+index d5e441b9e08d6..921ad4b1687f0 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_huc.h
++++ b/drivers/gpu/drm/i915/gt/uc/intel_huc.h
+@@ -55,6 +55,7 @@ struct intel_huc {
+ int intel_huc_sanitize(struct intel_huc *huc);
+ void intel_huc_init_early(struct intel_huc *huc);
++void intel_huc_fini_late(struct intel_huc *huc);
+ int intel_huc_init(struct intel_huc *huc);
+ void intel_huc_fini(struct intel_huc *huc);
+ int intel_huc_auth(struct intel_huc *huc, enum intel_huc_authentication_type type);
+diff --git a/drivers/gpu/drm/i915/gt/uc/intel_uc.c b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+index 5b8080ec5315b..4f751ce74214d 100644
+--- a/drivers/gpu/drm/i915/gt/uc/intel_uc.c
++++ b/drivers/gpu/drm/i915/gt/uc/intel_uc.c
+@@ -136,6 +136,7 @@ void intel_uc_init_late(struct intel_uc *uc)
+ void intel_uc_driver_late_release(struct intel_uc *uc)
+ {
++      intel_huc_fini_late(&uc->huc);
+ }
+ /**
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-tests-cmdline-fix-drm_display_mode-memory-leak.patch b/queue-6.14/drm-tests-cmdline-fix-drm_display_mode-memory-leak.patch
new file mode 100644 (file)
index 0000000..95b1716
--- /dev/null
@@ -0,0 +1,58 @@
+From 94c118867c7d9db5252e7de05ab7bdd89e11e2e1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 09:34:10 +0200
+Subject: drm/tests: cmdline: Fix drm_display_mode memory leak
+
+From: Maxime Ripard <mripard@kernel.org>
+
+[ Upstream commit 70f29ca3117a8796cd6bde7612a3ded96d0f2dde ]
+
+drm_analog_tv_mode() and its variants return a drm_display_mode that
+needs to be destroyed later one. The drm_test_cmdline_tv_options() test
+never does however, which leads to a memory leak.
+
+Let's make sure it's freed.
+
+Reported-by: Philipp Stanner <phasta@mailbox.org>
+Closes: https://lore.kernel.org/dri-devel/a7655158a6367ac46194d57f4b7433ef0772a73e.camel@mailbox.org/
+Fixes: e691c9992ae1 ("drm/modes: Introduce the tv_mode property as a command-line option")
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://lore.kernel.org/r/20250408-drm-kunit-drm-display-mode-memleak-v1-4-996305a2e75a@kernel.org
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tests/drm_cmdline_parser_test.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/tests/drm_cmdline_parser_test.c b/drivers/gpu/drm/tests/drm_cmdline_parser_test.c
+index 59c8408c453c2..1cfcb597b088b 100644
+--- a/drivers/gpu/drm/tests/drm_cmdline_parser_test.c
++++ b/drivers/gpu/drm/tests/drm_cmdline_parser_test.c
+@@ -7,6 +7,7 @@
+ #include <kunit/test.h>
+ #include <drm/drm_connector.h>
++#include <drm/drm_kunit_helpers.h>
+ #include <drm/drm_modes.h>
+ static const struct drm_connector no_connector = {};
+@@ -955,8 +956,15 @@ struct drm_cmdline_tv_option_test {
+ static void drm_test_cmdline_tv_options(struct kunit *test)
+ {
+       const struct drm_cmdline_tv_option_test *params = test->param_value;
+-      const struct drm_display_mode *expected_mode = params->mode_fn(NULL);
++      struct drm_display_mode *expected_mode;
+       struct drm_cmdline_mode mode = { };
++      int ret;
++
++      expected_mode = params->mode_fn(NULL);
++      KUNIT_ASSERT_NOT_NULL(test, expected_mode);
++
++      ret = drm_kunit_add_mode_destroy_action(test, expected_mode);
++      KUNIT_ASSERT_EQ(test, ret, 0);
+       KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector(params->cmdline,
+                                                                         &no_connector, &mode));
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-tests-helpers-create-kunit-helper-to-destroy-a-d.patch b/queue-6.14/drm-tests-helpers-create-kunit-helper-to-destroy-a-d.patch
new file mode 100644 (file)
index 0000000..5a8ebb9
--- /dev/null
@@ -0,0 +1,78 @@
+From a21f1417056a5339849e22985843a000624f4f8e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 09:34:07 +0200
+Subject: drm/tests: helpers: Create kunit helper to destroy a drm_display_mode
+
+From: Maxime Ripard <mripard@kernel.org>
+
+[ Upstream commit 13c1d5f3a7fa7b55a26e73bb9e95342374a489b2 ]
+
+A number of test suites call functions that expect the returned
+drm_display_mode to be destroyed eventually.
+
+However, none of the tests called drm_mode_destroy, which results in a
+memory leak.
+
+Since drm_mode_destroy takes two pointers as argument, we can't use a
+kunit wrapper. Let's just create a helper every test suite can use.
+
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://lore.kernel.org/r/20250408-drm-kunit-drm-display-mode-memleak-v1-1-996305a2e75a@kernel.org
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Stable-dep-of: 70f29ca3117a ("drm/tests: cmdline: Fix drm_display_mode memory leak")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tests/drm_kunit_helpers.c | 22 ++++++++++++++++++++++
+ include/drm/drm_kunit_helpers.h           |  3 +++
+ 2 files changed, 25 insertions(+)
+
+diff --git a/drivers/gpu/drm/tests/drm_kunit_helpers.c b/drivers/gpu/drm/tests/drm_kunit_helpers.c
+index 3c0b7824c0be3..922c4b6ed1dc9 100644
+--- a/drivers/gpu/drm/tests/drm_kunit_helpers.c
++++ b/drivers/gpu/drm/tests/drm_kunit_helpers.c
+@@ -319,6 +319,28 @@ static void kunit_action_drm_mode_destroy(void *ptr)
+       drm_mode_destroy(NULL, mode);
+ }
++/**
++ * drm_kunit_add_mode_destroy_action() - Add a drm_destroy_mode kunit action
++ * @test: The test context object
++ * @mode: The drm_display_mode to destroy eventually
++ *
++ * Registers a kunit action that will destroy the drm_display_mode at
++ * the end of the test.
++ *
++ * If an error occurs, the drm_display_mode will be destroyed.
++ *
++ * Returns:
++ * 0 on success, an error code otherwise.
++ */
++int drm_kunit_add_mode_destroy_action(struct kunit *test,
++                                    struct drm_display_mode *mode)
++{
++      return kunit_add_action_or_reset(test,
++                                       kunit_action_drm_mode_destroy,
++                                       mode);
++}
++EXPORT_SYMBOL_GPL(drm_kunit_add_mode_destroy_action);
++
+ /**
+  * drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC for a KUnit test
+  * @test: The test context object
+diff --git a/include/drm/drm_kunit_helpers.h b/include/drm/drm_kunit_helpers.h
+index afdd46ef04f70..c835f113055dc 100644
+--- a/include/drm/drm_kunit_helpers.h
++++ b/include/drm/drm_kunit_helpers.h
+@@ -120,6 +120,9 @@ drm_kunit_helper_create_crtc(struct kunit *test,
+                            const struct drm_crtc_funcs *funcs,
+                            const struct drm_crtc_helper_funcs *helper_funcs);
++int drm_kunit_add_mode_destroy_action(struct kunit *test,
++                                    struct drm_display_mode *mode);
++
+ struct drm_display_mode *
+ drm_kunit_display_mode_from_cea_vic(struct kunit *test, struct drm_device *dev,
+                                   u8 video_code);
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-tests-modes-fix-drm_display_mode-memory-leak.patch b/queue-6.14/drm-tests-modes-fix-drm_display_mode-memory-leak.patch
new file mode 100644 (file)
index 0000000..6d277cd
--- /dev/null
@@ -0,0 +1,117 @@
+From 607c20d3f1f7bba928f06c7b9224727c3b0753fc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 09:34:11 +0200
+Subject: drm/tests: modes: Fix drm_display_mode memory leak
+
+From: Maxime Ripard <mripard@kernel.org>
+
+[ Upstream commit d34146340f95cd9bf06d4ce71cca72127dc0b7cd ]
+
+drm_analog_tv_mode() and its variants return a drm_display_mode that
+needs to be destroyed later one. The drm_modes_analog_tv tests never
+do however, which leads to a memory leak.
+
+Let's make sure it's freed.
+
+Reported-by: Philipp Stanner <phasta@mailbox.org>
+Closes: https://lore.kernel.org/dri-devel/a7655158a6367ac46194d57f4b7433ef0772a73e.camel@mailbox.org/
+Fixes: 4fcd238560ee ("drm/modes: Add a function to generate analog display modes")
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://lore.kernel.org/r/20250408-drm-kunit-drm-display-mode-memleak-v1-5-996305a2e75a@kernel.org
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tests/drm_modes_test.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/drivers/gpu/drm/tests/drm_modes_test.c b/drivers/gpu/drm/tests/drm_modes_test.c
+index 6ed51f99e133c..7ba646d87856f 100644
+--- a/drivers/gpu/drm/tests/drm_modes_test.c
++++ b/drivers/gpu/drm/tests/drm_modes_test.c
+@@ -40,6 +40,7 @@ static void drm_test_modes_analog_tv_ntsc_480i(struct kunit *test)
+ {
+       struct drm_test_modes_priv *priv = test->priv;
+       struct drm_display_mode *mode;
++      int ret;
+       mode = drm_analog_tv_mode(priv->drm,
+                                 DRM_MODE_TV_MODE_NTSC,
+@@ -47,6 +48,9 @@ static void drm_test_modes_analog_tv_ntsc_480i(struct kunit *test)
+                                 true);
+       KUNIT_ASSERT_NOT_NULL(test, mode);
++      ret = drm_kunit_add_mode_destroy_action(test, mode);
++      KUNIT_ASSERT_EQ(test, ret, 0);
++
+       KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 60);
+       KUNIT_EXPECT_EQ(test, mode->hdisplay, 720);
+@@ -70,6 +74,7 @@ static void drm_test_modes_analog_tv_ntsc_480i_inlined(struct kunit *test)
+ {
+       struct drm_test_modes_priv *priv = test->priv;
+       struct drm_display_mode *expected, *mode;
++      int ret;
+       expected = drm_analog_tv_mode(priv->drm,
+                                     DRM_MODE_TV_MODE_NTSC,
+@@ -77,9 +82,15 @@ static void drm_test_modes_analog_tv_ntsc_480i_inlined(struct kunit *test)
+                                     true);
+       KUNIT_ASSERT_NOT_NULL(test, expected);
++      ret = drm_kunit_add_mode_destroy_action(test, expected);
++      KUNIT_ASSERT_EQ(test, ret, 0);
++
+       mode = drm_mode_analog_ntsc_480i(priv->drm);
+       KUNIT_ASSERT_NOT_NULL(test, mode);
++      ret = drm_kunit_add_mode_destroy_action(test, mode);
++      KUNIT_ASSERT_EQ(test, ret, 0);
++
+       KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode));
+ }
+@@ -87,6 +98,7 @@ static void drm_test_modes_analog_tv_pal_576i(struct kunit *test)
+ {
+       struct drm_test_modes_priv *priv = test->priv;
+       struct drm_display_mode *mode;
++      int ret;
+       mode = drm_analog_tv_mode(priv->drm,
+                                 DRM_MODE_TV_MODE_PAL,
+@@ -94,6 +106,9 @@ static void drm_test_modes_analog_tv_pal_576i(struct kunit *test)
+                                 true);
+       KUNIT_ASSERT_NOT_NULL(test, mode);
++      ret = drm_kunit_add_mode_destroy_action(test, mode);
++      KUNIT_ASSERT_EQ(test, ret, 0);
++
+       KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 50);
+       KUNIT_EXPECT_EQ(test, mode->hdisplay, 720);
+@@ -117,6 +132,7 @@ static void drm_test_modes_analog_tv_pal_576i_inlined(struct kunit *test)
+ {
+       struct drm_test_modes_priv *priv = test->priv;
+       struct drm_display_mode *expected, *mode;
++      int ret;
+       expected = drm_analog_tv_mode(priv->drm,
+                                     DRM_MODE_TV_MODE_PAL,
+@@ -124,9 +140,15 @@ static void drm_test_modes_analog_tv_pal_576i_inlined(struct kunit *test)
+                                     true);
+       KUNIT_ASSERT_NOT_NULL(test, expected);
++      ret = drm_kunit_add_mode_destroy_action(test, expected);
++      KUNIT_ASSERT_EQ(test, ret, 0);
++
+       mode = drm_mode_analog_pal_576i(priv->drm);
+       KUNIT_ASSERT_NOT_NULL(test, mode);
++      ret = drm_kunit_add_mode_destroy_action(test, mode);
++      KUNIT_ASSERT_EQ(test, ret, 0);
++
+       KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode));
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-tests-modeset-fix-drm_display_mode-memory-leak.patch b/queue-6.14/drm-tests-modeset-fix-drm_display_mode-memory-leak.patch
new file mode 100644 (file)
index 0000000..be7e6b9
--- /dev/null
@@ -0,0 +1,43 @@
+From 3fd4cee667a7cab1fc24472bc3e86711638ff02a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 09:34:08 +0200
+Subject: drm/tests: modeset: Fix drm_display_mode memory leak
+
+From: Maxime Ripard <mripard@kernel.org>
+
+[ Upstream commit dacafdcc7789cfeb0f0552716db56f210238225d ]
+
+drm_mode_find_dmt() returns a drm_display_mode that needs to be
+destroyed later one. The drm_test_pick_cmdline_res_1920_1080_60() test
+never does however, which leads to a memory leak.
+
+Let's make sure it's freed.
+
+Reported-by: Philipp Stanner <phasta@mailbox.org>
+Closes: https://lore.kernel.org/dri-devel/a7655158a6367ac46194d57f4b7433ef0772a73e.camel@mailbox.org/
+Fixes: 8fc0380f6ba7 ("drm/client: Add some tests for drm_connector_pick_cmdline_mode()")
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://lore.kernel.org/r/20250408-drm-kunit-drm-display-mode-memleak-v1-2-996305a2e75a@kernel.org
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tests/drm_client_modeset_test.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/gpu/drm/tests/drm_client_modeset_test.c b/drivers/gpu/drm/tests/drm_client_modeset_test.c
+index 7516f6cb36e4e..3e9518d7b8b7e 100644
+--- a/drivers/gpu/drm/tests/drm_client_modeset_test.c
++++ b/drivers/gpu/drm/tests/drm_client_modeset_test.c
+@@ -95,6 +95,9 @@ static void drm_test_pick_cmdline_res_1920_1080_60(struct kunit *test)
+       expected_mode = drm_mode_find_dmt(priv->drm, 1920, 1080, 60, false);
+       KUNIT_ASSERT_NOT_NULL(test, expected_mode);
++      ret = drm_kunit_add_mode_destroy_action(test, expected_mode);
++      KUNIT_ASSERT_EQ(test, ret, 0);
++
+       KUNIT_ASSERT_TRUE(test,
+                         drm_mode_parse_command_line_for_connector(cmdline,
+                                                                   connector,
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-tests-probe-helper-fix-drm_display_mode-memory-l.patch b/queue-6.14/drm-tests-probe-helper-fix-drm_display_mode-memory-l.patch
new file mode 100644 (file)
index 0000000..ab03ce9
--- /dev/null
@@ -0,0 +1,63 @@
+From 3f37fe28703ea3010915ae50049055f4920746f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 09:34:13 +0200
+Subject: drm/tests: probe-helper: Fix drm_display_mode memory leak
+
+From: Maxime Ripard <mripard@kernel.org>
+
+[ Upstream commit 8b6f2e28431b2f9f84073bff50353aeaf25559d0 ]
+
+drm_analog_tv_mode() and its variants return a drm_display_mode that
+needs to be destroyed later one. The
+drm_test_connector_helper_tv_get_modes_check() test never does however,
+which leads to a memory leak.
+
+Let's make sure it's freed.
+
+Reported-by: Philipp Stanner <phasta@mailbox.org>
+Closes: https://lore.kernel.org/dri-devel/a7655158a6367ac46194d57f4b7433ef0772a73e.camel@mailbox.org/
+Fixes: 1e4a91db109f ("drm/probe-helper: Provide a TV get_modes helper")
+Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://lore.kernel.org/r/20250408-drm-kunit-drm-display-mode-memleak-v1-7-996305a2e75a@kernel.org
+Signed-off-by: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/tests/drm_probe_helper_test.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/tests/drm_probe_helper_test.c b/drivers/gpu/drm/tests/drm_probe_helper_test.c
+index bc09ff38aca18..db0e4f5df275e 100644
+--- a/drivers/gpu/drm/tests/drm_probe_helper_test.c
++++ b/drivers/gpu/drm/tests/drm_probe_helper_test.c
+@@ -98,7 +98,7 @@ drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
+       struct drm_connector *connector = &priv->connector;
+       struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
+       struct drm_display_mode *mode;
+-      const struct drm_display_mode *expected;
++      struct drm_display_mode *expected;
+       size_t len;
+       int ret;
+@@ -134,6 +134,9 @@ drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
+               KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
+               KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
++
++              ret = drm_kunit_add_mode_destroy_action(test, expected);
++              KUNIT_ASSERT_EQ(test, ret, 0);
+       }
+       if (params->num_expected_modes >= 2) {
+@@ -145,6 +148,9 @@ drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
+               KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
+               KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
++
++              ret = drm_kunit_add_mode_destroy_action(test, expected);
++              KUNIT_ASSERT_EQ(test, ret, 0);
+       }
+       mutex_unlock(&priv->drm->mode_config.mutex);
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-virtio-fix-flickering-issue-seen-with-imported-d.patch b/queue-6.14/drm-virtio-fix-flickering-issue-seen-with-imported-d.patch
new file mode 100644 (file)
index 0000000..063df69
--- /dev/null
@@ -0,0 +1,53 @@
+From 5fb0c5ec3aab513eefc6569c819d570330d9c58a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 25 Mar 2025 13:10:21 -0700
+Subject: drm/virtio: Fix flickering issue seen with imported dmabufs
+
+From: Vivek Kasireddy <vivek.kasireddy@intel.com>
+
+[ Upstream commit 3d50e61a17b642af060566acb0eabe3c0eb3ef1f ]
+
+We need to save the reservation object pointer associated with the
+imported dmabuf in the newly created GEM object to allow
+drm_gem_plane_helper_prepare_fb() to extract the exclusive fence
+from it and attach it to the plane state during prepare phase.
+This is needed to ensure that drm_atomic_helper_wait_for_fences()
+correctly waits for the relevant fences (move, etc) associated with
+the reservation object, thereby implementing proper synchronization.
+
+Otherwise, artifacts or slight flickering can be seen when apps
+are dragged across the screen when running Gnome (Wayland). This
+problem is mostly seen with dGPUs in the case where the FBs are
+allocated in VRAM but need to be migrated to System RAM as they
+are shared with virtio-gpu.
+
+Fixes: ca77f27a2665 ("drm/virtio: Import prime buffers from other devices as guest blobs")
+Cc: Gerd Hoffmann <kraxel@redhat.com>
+Cc: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Cc: Gurchetan Singh <gurchetansingh@chromium.org>
+Cc: Chia-I Wu <olvaffe@gmail.com>
+Signed-off-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
+Reviewed-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
+[dmitry.osipenko@collabora.com: Moved assignment before object_init()]
+Link: https://patchwork.freedesktop.org/patch/msgid/20250325201021.1315080-1-vivek.kasireddy@intel.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/virtio/virtgpu_prime.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/virtio/virtgpu_prime.c b/drivers/gpu/drm/virtio/virtgpu_prime.c
+index f92133a01195a..d28d1c45a703b 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_prime.c
++++ b/drivers/gpu/drm/virtio/virtgpu_prime.c
+@@ -319,6 +319,7 @@ struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
+               return ERR_PTR(-ENOMEM);
+       obj = &bo->base.base;
++      obj->resv = buf->resv;
+       obj->funcs = &virtgpu_gem_dma_buf_funcs;
+       drm_gem_private_object_init(dev, obj, buf->size);
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-xe-hw_engine-define-sysfs_ops-on-all-directories.patch b/queue-6.14/drm-xe-hw_engine-define-sysfs_ops-on-all-directories.patch
new file mode 100644 (file)
index 0000000..671fa15
--- /dev/null
@@ -0,0 +1,179 @@
+From 91808cc1bba64679db5e4a4573cd6470d8420a0b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 27 Mar 2025 17:56:47 +0530
+Subject: drm/xe/hw_engine: define sysfs_ops on all directories
+
+From: Tejas Upadhyay <tejas.upadhyay@intel.com>
+
+[ Upstream commit a5c71fd5b69b9da77e5e0b268e69e256932ba49c ]
+
+Sysfs_ops needs to be defined on all directories which
+can have attr files with set/get method. Add sysfs_ops
+to even those directories which is currently empty but
+would have attr files with set/get method in future.
+Leave .default with default sysfs_ops as it will never
+have setter method.
+
+V2(Himal/Rodrigo):
+ - use single sysfs_ops for all dir and attr with set/get
+ - add default ops as ./default does not need runtime pm at all
+
+Fixes: 3f0e14651ab0 ("drm/xe: Runtime PM wake on every sysfs call")
+Reviewed-by: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
+Link: https://patchwork.freedesktop.org/patch/msgid/20250327122647.886637-1-tejas.upadhyay@intel.com
+Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
+(cherry picked from commit 40780b9760b561e093508d07b8b9b06c94ab201e)
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c | 108 +++++++++---------
+ 1 file changed, 52 insertions(+), 56 deletions(-)
+
+diff --git a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c
+index b53e8d2accdbd..a440442b4d727 100644
+--- a/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c
++++ b/drivers/gpu/drm/xe/xe_hw_engine_class_sysfs.c
+@@ -32,14 +32,61 @@ bool xe_hw_engine_timeout_in_range(u64 timeout, u64 min, u64 max)
+       return timeout >= min && timeout <= max;
+ }
+-static void kobj_xe_hw_engine_release(struct kobject *kobj)
++static void xe_hw_engine_sysfs_kobj_release(struct kobject *kobj)
+ {
+       kfree(kobj);
+ }
++static ssize_t xe_hw_engine_class_sysfs_attr_show(struct kobject *kobj,
++                                                struct attribute *attr,
++                                                char *buf)
++{
++      struct xe_device *xe = kobj_to_xe(kobj);
++      struct kobj_attribute *kattr;
++      ssize_t ret = -EIO;
++
++      kattr = container_of(attr, struct kobj_attribute, attr);
++      if (kattr->show) {
++              xe_pm_runtime_get(xe);
++              ret = kattr->show(kobj, kattr, buf);
++              xe_pm_runtime_put(xe);
++      }
++
++      return ret;
++}
++
++static ssize_t xe_hw_engine_class_sysfs_attr_store(struct kobject *kobj,
++                                                 struct attribute *attr,
++                                                 const char *buf,
++                                                 size_t count)
++{
++      struct xe_device *xe = kobj_to_xe(kobj);
++      struct kobj_attribute *kattr;
++      ssize_t ret = -EIO;
++
++      kattr = container_of(attr, struct kobj_attribute, attr);
++      if (kattr->store) {
++              xe_pm_runtime_get(xe);
++              ret = kattr->store(kobj, kattr, buf, count);
++              xe_pm_runtime_put(xe);
++      }
++
++      return ret;
++}
++
++static const struct sysfs_ops xe_hw_engine_class_sysfs_ops = {
++      .show = xe_hw_engine_class_sysfs_attr_show,
++      .store = xe_hw_engine_class_sysfs_attr_store,
++};
++
+ static const struct kobj_type kobj_xe_hw_engine_type = {
+-      .release = kobj_xe_hw_engine_release,
+-      .sysfs_ops = &kobj_sysfs_ops
++      .release = xe_hw_engine_sysfs_kobj_release,
++      .sysfs_ops = &xe_hw_engine_class_sysfs_ops,
++};
++
++static const struct kobj_type kobj_xe_hw_engine_type_def = {
++      .release = xe_hw_engine_sysfs_kobj_release,
++      .sysfs_ops = &kobj_sysfs_ops,
+ };
+ static ssize_t job_timeout_max_store(struct kobject *kobj,
+@@ -543,7 +590,7 @@ static int xe_add_hw_engine_class_defaults(struct xe_device *xe,
+       if (!kobj)
+               return -ENOMEM;
+-      kobject_init(kobj, &kobj_xe_hw_engine_type);
++      kobject_init(kobj, &kobj_xe_hw_engine_type_def);
+       err = kobject_add(kobj, parent, "%s", ".defaults");
+       if (err)
+               goto err_object;
+@@ -559,57 +606,6 @@ static int xe_add_hw_engine_class_defaults(struct xe_device *xe,
+       return err;
+ }
+-static void xe_hw_engine_sysfs_kobj_release(struct kobject *kobj)
+-{
+-      kfree(kobj);
+-}
+-
+-static ssize_t xe_hw_engine_class_sysfs_attr_show(struct kobject *kobj,
+-                                                struct attribute *attr,
+-                                                char *buf)
+-{
+-      struct xe_device *xe = kobj_to_xe(kobj);
+-      struct kobj_attribute *kattr;
+-      ssize_t ret = -EIO;
+-
+-      kattr = container_of(attr, struct kobj_attribute, attr);
+-      if (kattr->show) {
+-              xe_pm_runtime_get(xe);
+-              ret = kattr->show(kobj, kattr, buf);
+-              xe_pm_runtime_put(xe);
+-      }
+-
+-      return ret;
+-}
+-
+-static ssize_t xe_hw_engine_class_sysfs_attr_store(struct kobject *kobj,
+-                                                 struct attribute *attr,
+-                                                 const char *buf,
+-                                                 size_t count)
+-{
+-      struct xe_device *xe = kobj_to_xe(kobj);
+-      struct kobj_attribute *kattr;
+-      ssize_t ret = -EIO;
+-
+-      kattr = container_of(attr, struct kobj_attribute, attr);
+-      if (kattr->store) {
+-              xe_pm_runtime_get(xe);
+-              ret = kattr->store(kobj, kattr, buf, count);
+-              xe_pm_runtime_put(xe);
+-      }
+-
+-      return ret;
+-}
+-
+-static const struct sysfs_ops xe_hw_engine_class_sysfs_ops = {
+-      .show = xe_hw_engine_class_sysfs_attr_show,
+-      .store = xe_hw_engine_class_sysfs_attr_store,
+-};
+-
+-static const struct kobj_type xe_hw_engine_sysfs_kobj_type = {
+-      .release = xe_hw_engine_sysfs_kobj_release,
+-      .sysfs_ops = &xe_hw_engine_class_sysfs_ops,
+-};
+ static void hw_engine_class_sysfs_fini(void *arg)
+ {
+@@ -640,7 +636,7 @@ int xe_hw_engine_class_sysfs_init(struct xe_gt *gt)
+       if (!kobj)
+               return -ENOMEM;
+-      kobject_init(kobj, &xe_hw_engine_sysfs_kobj_type);
++      kobject_init(kobj, &kobj_xe_hw_engine_type);
+       err = kobject_add(kobj, gt->sysfs, "engines");
+       if (err)
+-- 
+2.39.5
+
diff --git a/queue-6.14/drm-xe-restore-eio-errno-return-when-guc-pc-start-fa.patch b/queue-6.14/drm-xe-restore-eio-errno-return-when-guc-pc-start-fa.patch
new file mode 100644 (file)
index 0000000..b2f04a2
--- /dev/null
@@ -0,0 +1,43 @@
+From 6d5806c3b22e307086f695618a0993c59d4958b2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 28 Mar 2025 14:17:52 -0400
+Subject: drm/xe: Restore EIO errno return when GuC PC start fails
+
+From: Rodrigo Vivi <rodrigo.vivi@intel.com>
+
+[ Upstream commit 88ecb66b9956a14577d513a6c8c28bb2e7989703 ]
+
+Commit b4b05e53b550 ("drm/xe/guc_pc: Retry and wait longer for GuC PC
+start"), leads to the following Smatch static checker warning:
+
+        drivers/gpu/drm/xe/xe_guc_pc.c:1073 xe_guc_pc_start()
+        warn: missing error code here? '_dev_err()' failed. 'ret' = '0'
+
+Fixes: c605acb53f44 ("drm/xe/guc_pc: Retry and wait longer for GuC PC start")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Closes: https://lore.kernel.org/intel-xe/1454a5f1-ee18-4df1-a6b2-a4a3dddcd1cb@stanley.mountain/
+Reviewed-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Link: https://lore.kernel.org/r/20250328181752.26677-1-rodrigo.vivi@intel.com
+Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
+(cherry picked from commit 3f2bdccbccdcb53b0d316474eafff2e3462a51ad)
+Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/xe/xe_guc_pc.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/drivers/gpu/drm/xe/xe_guc_pc.c b/drivers/gpu/drm/xe/xe_guc_pc.c
+index b995d1d51aed0..f382f5d53ca8b 100644
+--- a/drivers/gpu/drm/xe/xe_guc_pc.c
++++ b/drivers/gpu/drm/xe/xe_guc_pc.c
+@@ -1056,6 +1056,7 @@ int xe_guc_pc_start(struct xe_guc_pc *pc)
+               if (wait_for_pc_state(pc, SLPC_GLOBAL_STATE_RUNNING,
+                                     SLPC_RESET_EXTENDED_TIMEOUT_MS)) {
+                       xe_gt_err(gt, "GuC PC Start failed: Dynamic GT frequency control and GT sleep states are now disabled.\n");
++                      ret = -EIO;
+                       goto out;
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/ethtool-cmis_cdb-fix-incorrect-read-write-length-ext.patch b/queue-6.14/ethtool-cmis_cdb-fix-incorrect-read-write-length-ext.patch
new file mode 100644 (file)
index 0000000..d685007
--- /dev/null
@@ -0,0 +1,105 @@
+From 78134b8c364bd08cabe82315c27ddf3aca2dc492 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 14:24:40 +0300
+Subject: ethtool: cmis_cdb: Fix incorrect read / write length extension
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit eaa517b77e63442260640d875f824d1111ca6569 ]
+
+The 'read_write_len_ext' field in 'struct ethtool_cmis_cdb_cmd_args'
+stores the maximum number of bytes that can be read from or written to
+the Local Payload (LPL) page in a single multi-byte access.
+
+Cited commit started overwriting this field with the maximum number of
+bytes that can be read from or written to the Extended Payload (LPL)
+pages in a single multi-byte access. Transceiver modules that support
+auto paging can advertise a number larger than 255 which is problematic
+as 'read_write_len_ext' is a 'u8', resulting in the number getting
+truncated and firmware flashing failing [1].
+
+Fix by ignoring the maximum EPL access size as the kernel does not
+currently support auto paging (even if the transceiver module does) and
+will not try to read / write more than 128 bytes at once.
+
+[1]
+Transceiver module firmware flashing started for device enp177s0np0
+Transceiver module firmware flashing in progress for device enp177s0np0
+Progress: 0%
+Transceiver module firmware flashing encountered an error for device enp177s0np0
+Status message: Write FW block EPL command failed, LPL length is longer
+       than CDB read write length extension allows.
+
+Fixes: 9a3b0d078bd8 ("net: ethtool: Add support for writing firmware blocks using EPL payload")
+Reported-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
+Closes: https://lore.kernel.org/netdev/20250402183123.321036-3-michael.chan@broadcom.com/
+Tested-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Link: https://patch.msgid.link/20250409112440.365672-1-idosch@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/cmis.h     |  1 -
+ net/ethtool/cmis_cdb.c | 18 +++---------------
+ 2 files changed, 3 insertions(+), 16 deletions(-)
+
+diff --git a/net/ethtool/cmis.h b/net/ethtool/cmis.h
+index 1e790413db0e8..4a9a946cabf05 100644
+--- a/net/ethtool/cmis.h
++++ b/net/ethtool/cmis.h
+@@ -101,7 +101,6 @@ struct ethtool_cmis_cdb_rpl {
+ };
+ u32 ethtool_cmis_get_max_lpl_size(u8 num_of_byte_octs);
+-u32 ethtool_cmis_get_max_epl_size(u8 num_of_byte_octs);
+ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
+                                  enum ethtool_cmis_cdb_cmd_id cmd, u8 *lpl,
+diff --git a/net/ethtool/cmis_cdb.c b/net/ethtool/cmis_cdb.c
+index d159dc121bde5..0e2691ccb0df3 100644
+--- a/net/ethtool/cmis_cdb.c
++++ b/net/ethtool/cmis_cdb.c
+@@ -16,15 +16,6 @@ u32 ethtool_cmis_get_max_lpl_size(u8 num_of_byte_octs)
+       return 8 * (1 + min_t(u8, num_of_byte_octs, 15));
+ }
+-/* For accessing the EPL field on page 9Fh, the allowable length extension is
+- * min(i, 255) byte octets where i specifies the allowable additional number of
+- * byte octets in a READ or a WRITE.
+- */
+-u32 ethtool_cmis_get_max_epl_size(u8 num_of_byte_octs)
+-{
+-      return 8 * (1 + min_t(u8, num_of_byte_octs, 255));
+-}
+-
+ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
+                                  enum ethtool_cmis_cdb_cmd_id cmd, u8 *lpl,
+                                  u8 lpl_len, u8 *epl, u16 epl_len,
+@@ -33,19 +24,16 @@ void ethtool_cmis_cdb_compose_args(struct ethtool_cmis_cdb_cmd_args *args,
+ {
+       args->req.id = cpu_to_be16(cmd);
+       args->req.lpl_len = lpl_len;
+-      if (lpl) {
++      if (lpl)
+               memcpy(args->req.payload, lpl, args->req.lpl_len);
+-              args->read_write_len_ext =
+-                      ethtool_cmis_get_max_lpl_size(read_write_len_ext);
+-      }
+       if (epl) {
+               args->req.epl_len = cpu_to_be16(epl_len);
+               args->req.epl = epl;
+-              args->read_write_len_ext =
+-                      ethtool_cmis_get_max_epl_size(read_write_len_ext);
+       }
+       args->max_duration = max_duration;
++      args->read_write_len_ext =
++              ethtool_cmis_get_max_lpl_size(read_write_len_ext);
+       args->msleep_pre_rpl = msleep_pre_rpl;
+       args->rpl_exp_len = rpl_exp_len;
+       args->flags = flags;
+-- 
+2.39.5
+
diff --git a/queue-6.14/gpiolib-of-fix-the-choice-for-ingenic-nand-quirk.patch b/queue-6.14/gpiolib-of-fix-the-choice-for-ingenic-nand-quirk.patch
new file mode 100644 (file)
index 0000000..425eba0
--- /dev/null
@@ -0,0 +1,38 @@
+From 3c338b6742ed74ce9ce522f8b5043039189cb5d7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 2 Apr 2025 15:20:00 +0300
+Subject: gpiolib: of: Fix the choice for Ingenic NAND quirk
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 2b9c536430126c233552cdcd6ec9d5077454ece4 ]
+
+The Ingenic NAND quirk has been added under CONFIG_LCD_HX8357 ifdeffery
+which sounds quite wrong. Fix the choice for Ingenic NAND quirk
+by wrapping it into own ifdeffery related to the respective driver.
+
+Fixes: 3a7fd473bd5d ("mtd: rawnand: ingenic: move the GPIO quirk to gpiolib-of.c")
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20250402122058.1517393-2-andriy.shevchenko@linux.intel.com
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpio/gpiolib-of.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
+index 2e537ee979f3e..176e9142fd8f8 100644
+--- a/drivers/gpio/gpiolib-of.c
++++ b/drivers/gpio/gpiolib-of.c
+@@ -193,6 +193,8 @@ static void of_gpio_try_fixup_polarity(const struct device_node *np,
+                */
+               { "himax,hx8357",       "gpios-reset",  false },
+               { "himax,hx8369",       "gpios-reset",  false },
++#endif
++#if IS_ENABLED(CONFIG_MTD_NAND_JZ4780)
+               /*
+                * The rb-gpios semantics was undocumented and qi,lb60 (along with
+                * the ingenic driver) got it wrong. The active state encodes the
+-- 
+2.39.5
+
diff --git a/queue-6.14/iommu-exynos-fix-suspend-resume-with-identity-domain.patch b/queue-6.14/iommu-exynos-fix-suspend-resume-with-identity-domain.patch
new file mode 100644 (file)
index 0000000..b9c5757
--- /dev/null
@@ -0,0 +1,52 @@
+From ad82692bdc2aa0338ae30a7f973b89f8eb90af91 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 22:27:31 +0200
+Subject: iommu/exynos: Fix suspend/resume with IDENTITY domain
+
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+
+[ Upstream commit 99deffc409b69000ac4877486e69ec6516becd53 ]
+
+Commit bcb81ac6ae3c ("iommu: Get DT/ACPI parsing into the proper probe
+path") changed the sequence of probing the SYSMMU controller devices and
+calls to arm_iommu_attach_device(), what results in resuming SYSMMU
+controller earlier, when it is still set to IDENTITY mapping. Such change
+revealed the bug in IDENTITY handling in the exynos-iommu driver. When
+SYSMMU controller is set to IDENTITY mapping, data->domain is NULL, so
+adjust checks in suspend & resume callbacks to handle this case
+correctly.
+
+Fixes: b3d14960e629 ("iommu/exynos: Implement an IDENTITY domain")
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Link: https://lore.kernel.org/r/20250401202731.2810474-1-m.szyprowski@samsung.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/exynos-iommu.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c
+index 69e23e017d9e5..317266aca6e28 100644
+--- a/drivers/iommu/exynos-iommu.c
++++ b/drivers/iommu/exynos-iommu.c
+@@ -832,7 +832,7 @@ static int __maybe_unused exynos_sysmmu_suspend(struct device *dev)
+               struct exynos_iommu_owner *owner = dev_iommu_priv_get(master);
+               mutex_lock(&owner->rpm_lock);
+-              if (&data->domain->domain != &exynos_identity_domain) {
++              if (data->domain) {
+                       dev_dbg(data->sysmmu, "saving state\n");
+                       __sysmmu_disable(data);
+               }
+@@ -850,7 +850,7 @@ static int __maybe_unused exynos_sysmmu_resume(struct device *dev)
+               struct exynos_iommu_owner *owner = dev_iommu_priv_get(master);
+               mutex_lock(&owner->rpm_lock);
+-              if (&data->domain->domain != &exynos_identity_domain) {
++              if (data->domain) {
+                       dev_dbg(data->sysmmu, "restoring state\n");
+                       __sysmmu_enable(data);
+               }
+-- 
+2.39.5
+
diff --git a/queue-6.14/iommu-mediatek-fix-null-pointer-deference-in-mtk_iom.patch b/queue-6.14/iommu-mediatek-fix-null-pointer-deference-in-mtk_iom.patch
new file mode 100644 (file)
index 0000000..e1ccf49
--- /dev/null
@@ -0,0 +1,87 @@
+From f733d37dee2178a72fc96c60cf39294f9bc248a5 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 12:22:12 +0200
+Subject: iommu/mediatek: Fix NULL pointer deference in mtk_iommu_device_group
+
+From: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+
+[ Upstream commit 38e8844005e6068f336a3ad45451a562a0040ca1 ]
+
+Currently, mtk_iommu calls during probe iommu_device_register before
+the hw_list from driver data is initialized. Since iommu probing issue
+fix, it leads to NULL pointer dereference in mtk_iommu_device_group when
+hw_list is accessed with list_first_entry (not null safe).
+
+So, change the call order to ensure iommu_device_register is called
+after the driver data are initialized.
+
+Fixes: 9e3a2a643653 ("iommu/mediatek: Adapt sharing and non-sharing pgtable case")
+Fixes: bcb81ac6ae3c ("iommu: Get DT/ACPI parsing into the proper probe path")
+Reviewed-by: Yong Wu <yong.wu@mediatek.com>
+Tested-by: Chen-Yu Tsai <wenst@chromium.org> # MT8183 Juniper, MT8186 Tentacruel
+Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
+Signed-off-by: Louis-Alexis Eyraud <louisalexis.eyraud@collabora.com>
+Link: https://lore.kernel.org/r/20250403-fix-mtk-iommu-error-v2-1-fe8b18f8b0a8@collabora.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/mtk_iommu.c | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/iommu/mtk_iommu.c b/drivers/iommu/mtk_iommu.c
+index 034b0e670384a..df98d0c65f546 100644
+--- a/drivers/iommu/mtk_iommu.c
++++ b/drivers/iommu/mtk_iommu.c
+@@ -1372,15 +1372,6 @@ static int mtk_iommu_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, data);
+       mutex_init(&data->mutex);
+-      ret = iommu_device_sysfs_add(&data->iommu, dev, NULL,
+-                                   "mtk-iommu.%pa", &ioaddr);
+-      if (ret)
+-              goto out_link_remove;
+-
+-      ret = iommu_device_register(&data->iommu, &mtk_iommu_ops, dev);
+-      if (ret)
+-              goto out_sysfs_remove;
+-
+       if (MTK_IOMMU_HAS_FLAG(data->plat_data, SHARE_PGTABLE)) {
+               list_add_tail(&data->list, data->plat_data->hw_list);
+               data->hw_list = data->plat_data->hw_list;
+@@ -1390,19 +1381,28 @@ static int mtk_iommu_probe(struct platform_device *pdev)
+               data->hw_list = &data->hw_list_head;
+       }
++      ret = iommu_device_sysfs_add(&data->iommu, dev, NULL,
++                                   "mtk-iommu.%pa", &ioaddr);
++      if (ret)
++              goto out_list_del;
++
++      ret = iommu_device_register(&data->iommu, &mtk_iommu_ops, dev);
++      if (ret)
++              goto out_sysfs_remove;
++
+       if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM)) {
+               ret = component_master_add_with_match(dev, &mtk_iommu_com_ops, match);
+               if (ret)
+-                      goto out_list_del;
++                      goto out_device_unregister;
+       }
+       return ret;
+-out_list_del:
+-      list_del(&data->list);
++out_device_unregister:
+       iommu_device_unregister(&data->iommu);
+ out_sysfs_remove:
+       iommu_device_sysfs_remove(&data->iommu);
+-out_link_remove:
++out_list_del:
++      list_del(&data->list);
+       if (MTK_IOMMU_IS_TYPE(data->plat_data, MTK_IOMMU_TYPE_MM))
+               device_link_remove(data->smicomm_dev, dev);
+ out_runtime_disable:
+-- 
+2.39.5
+
diff --git a/queue-6.14/ipv6-align-behavior-across-nexthops-during-path-sele.patch b/queue-6.14/ipv6-align-behavior-across-nexthops-during-path-sele.patch
new file mode 100644 (file)
index 0000000..d11d222
--- /dev/null
@@ -0,0 +1,63 @@
+From 6614c27d810e87b796ef16cdfc21f705b4385f7c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 11:43:16 +0300
+Subject: ipv6: Align behavior across nexthops during path selection
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit 6933cd4714861eea6848f18396a119d741f25fc3 ]
+
+A nexthop is only chosen when the calculated multipath hash falls in the
+nexthop's hash region (i.e., the hash is smaller than the nexthop's hash
+threshold) and when the nexthop is assigned a non-negative score by
+rt6_score_route().
+
+Commit 4d0ab3a6885e ("ipv6: Start path selection from the first
+nexthop") introduced an unintentional difference between the first
+nexthop and the rest when the score is negative.
+
+When the first nexthop matches, but has a negative score, the code will
+currently evaluate subsequent nexthops until one is found with a
+non-negative score. On the other hand, when a different nexthop matches,
+but has a negative score, the code will fallback to the nexthop with
+which the selection started ('match').
+
+Align the behavior across all nexthops and fallback to 'match' when the
+first nexthop matches, but has a negative score.
+
+Fixes: 3d709f69a3e7 ("ipv6: Use hash-threshold instead of modulo-N")
+Fixes: 4d0ab3a6885e ("ipv6: Start path selection from the first nexthop")
+Reported-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
+Closes: https://lore.kernel.org/netdev/67efef607bc41_1ddca82948c@willemb.c.googlers.com.notmuch/
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250408084316.243559-1-idosch@nvidia.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/route.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 169a7b9bc40ea..08cee62e789e1 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -470,10 +470,10 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,
+               goto out;
+       hash = fl6->mp_hash;
+-      if (hash <= atomic_read(&first->fib6_nh->fib_nh_upper_bound) &&
+-          rt6_score_route(first->fib6_nh, first->fib6_flags, oif,
+-                          strict) >= 0) {
+-              match = first;
++      if (hash <= atomic_read(&first->fib6_nh->fib_nh_upper_bound)) {
++              if (rt6_score_route(first->fib6_nh, first->fib6_flags, oif,
++                                  strict) >= 0)
++                      match = first;
+               goto out;
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-ethtool-don-t-call-.cleanup_data-when-prepare_da.patch b/queue-6.14/net-ethtool-don-t-call-.cleanup_data-when-prepare_da.patch
new file mode 100644 (file)
index 0000000..2609f7d
--- /dev/null
@@ -0,0 +1,78 @@
+From 802daff1a6742080f83f9af272cefed73095e951 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 15:05:10 +0200
+Subject: net: ethtool: Don't call .cleanup_data when prepare_data fails
+
+From: Maxime Chevallier <maxime.chevallier@bootlin.com>
+
+[ Upstream commit 4f038a6a02d20859a3479293cbf172b0f14cbdd6 ]
+
+There's a consistent pattern where the .cleanup_data() callback is
+called when .prepare_data() fails, when it should really be called to
+clean after a successful .prepare_data() as per the documentation.
+
+Rewrite the error-handling paths to make sure we don't cleanup
+un-prepared data.
+
+Fixes: c781ff12a2f3 ("ethtool: Allow network drivers to dump arbitrary EEPROM data")
+Reviewed-by: Kory Maincent <kory.maincent@bootlin.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Michal Kubecek <mkubecek@suse.cz>
+Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
+Link: https://patch.msgid.link/20250407130511.75621-1-maxime.chevallier@bootlin.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/netlink.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
+index 734849a573691..e088a30d1dd26 100644
+--- a/net/ethtool/netlink.c
++++ b/net/ethtool/netlink.c
+@@ -493,7 +493,7 @@ static int ethnl_default_doit(struct sk_buff *skb, struct genl_info *info)
+       ret = ops->prepare_data(req_info, reply_data, info);
+       rtnl_unlock();
+       if (ret < 0)
+-              goto err_cleanup;
++              goto err_dev;
+       ret = ops->reply_size(req_info, reply_data);
+       if (ret < 0)
+               goto err_cleanup;
+@@ -551,7 +551,7 @@ static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev,
+       ret = ctx->ops->prepare_data(ctx->req_info, ctx->reply_data, info);
+       rtnl_unlock();
+       if (ret < 0)
+-              goto out;
++              goto out_cancel;
+       ret = ethnl_fill_reply_header(skb, dev, ctx->ops->hdr_attr);
+       if (ret < 0)
+               goto out;
+@@ -560,6 +560,7 @@ static int ethnl_default_dump_one(struct sk_buff *skb, struct net_device *dev,
+ out:
+       if (ctx->ops->cleanup_data)
+               ctx->ops->cleanup_data(ctx->reply_data);
++out_cancel:
+       ctx->reply_data->dev = NULL;
+       if (ret < 0)
+               genlmsg_cancel(skb, ehdr);
+@@ -780,7 +781,7 @@ static void ethnl_default_notify(struct net_device *dev, unsigned int cmd,
+       ethnl_init_reply_data(reply_data, ops, dev);
+       ret = ops->prepare_data(req_info, reply_data, &info);
+       if (ret < 0)
+-              goto err_cleanup;
++              goto err_rep;
+       ret = ops->reply_size(req_info, reply_data);
+       if (ret < 0)
+               goto err_cleanup;
+@@ -815,6 +816,7 @@ static void ethnl_default_notify(struct net_device *dev, unsigned int cmd,
+ err_cleanup:
+       if (ops->cleanup_data)
+               ops->cleanup_data(reply_data);
++err_rep:
+       kfree(reply_data);
+       kfree(req_info);
+       return;
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-ethtool-fix-ethtool_ringparam_get_cfg-returns-a-.patch b/queue-6.14/net-ethtool-fix-ethtool_ringparam_get_cfg-returns-a-.patch
new file mode 100644 (file)
index 0000000..ed856f6
--- /dev/null
@@ -0,0 +1,58 @@
+From c19c2052bcc9609c5259ab6a9faadc92b9cf5ef8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 12:21:25 +0000
+Subject: net: ethtool: fix ethtool_ringparam_get_cfg() returns a hds_thresh
+ value always as 0.
+
+From: Taehee Yoo <ap420073@gmail.com>
+
+[ Upstream commit 216a61d33c0728a8cf1650aaed2c523c6ce16354 ]
+
+When hds-thresh is configured, ethnl_set_rings() is called, and it calls
+ethtool_ringparam_get_cfg() to get ringparameters from .get_ringparam()
+callback and dev->cfg.
+Both hds_config and hds_thresh values should be set from dev->cfg, not
+from .get_ringparam().
+But ethtool_ringparam_get_cfg() sets only hds_config from dev->cfg.
+So, ethtool_ringparam_get_cfg() returns always a hds_thresh as 0.
+
+If an input value of hds-thresh is 0, a hds_thresh value from
+ethtool_ringparam_get_cfg() are same. So ethnl_set_rings() does
+nothing and returns immediately.
+It causes a bug that setting a hds-thresh value to 0 is not working.
+
+Reproducer:
+    modprobe netdevsim
+    echo 1 > /sys/bus/netdevsim/new_device
+    ethtool -G eth0 hds-thresh 100
+    ethtool -G eth0 hds-thresh 0
+    ethtool -g eth0
+    #hds-thresh value should be 0, but it shows 100.
+
+The tools/testing/selftests/drivers/net/hds.py can test it too with
+applying a following patch for hds.py.
+
+Fixes: 928459bbda19 ("net: ethtool: populate the default HDS params in the core")
+Signed-off-by: Taehee Yoo <ap420073@gmail.com>
+Link: https://patch.msgid.link/20250404122126.1555648-2-ap420073@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ethtool/common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/ethtool/common.c b/net/ethtool/common.c
+index b97374b508f67..e2f8a41cc1084 100644
+--- a/net/ethtool/common.c
++++ b/net/ethtool/common.c
+@@ -785,6 +785,7 @@ void ethtool_ringparam_get_cfg(struct net_device *dev,
+       /* Driver gives us current state, we want to return current config */
+       kparam->tcp_data_split = dev->cfg->hds_config;
++      kparam->hds_thresh = dev->cfg->hds_thresh;
+ }
+ static void ethtool_init_tsinfo(struct kernel_ethtool_ts_info *info)
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-libwx-fix-the-wrong-rx-descriptor-field.patch b/queue-6.14/net-libwx-fix-the-wrong-rx-descriptor-field.patch
new file mode 100644 (file)
index 0000000..19d13b7
--- /dev/null
@@ -0,0 +1,63 @@
+From 05012a4b5816797f525a0022afa23a66ab33baca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 18:33:22 +0800
+Subject: net: libwx: Fix the wrong Rx descriptor field
+
+From: Jiawen Wu <jiawenwu@trustnetic.com>
+
+[ Upstream commit 13e7d7240a43d8ea528c12ae5a912be1ff7fa29b ]
+
+WX_RXD_IPV6EX was incorrectly defined in Rx ring descriptor. In fact, this
+field stores the 802.1ad ID from which the packet was received. The wrong
+definition caused the statistics rx_csum_offload_errors to fail to grow
+when receiving the 802.1ad packet with incorrect checksum.
+
+Fixes: ef4f3c19f912 ("net: wangxun: libwx add rx offload functions")
+Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
+Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
+Link: https://patch.msgid.link/20250407103322.273241-1-jiawenwu@trustnetic.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/wangxun/libwx/wx_lib.c  | 3 ++-
+ drivers/net/ethernet/wangxun/libwx/wx_type.h | 3 +--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+index 43b89509d0fe5..5b113fd71fe2e 100644
+--- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c
++++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+@@ -546,7 +546,8 @@ static void wx_rx_checksum(struct wx_ring *ring,
+               return;
+       /* Hardware can't guarantee csum if IPv6 Dest Header found */
+-      if (dptype.prot != WX_DEC_PTYPE_PROT_SCTP && WX_RXD_IPV6EX(rx_desc))
++      if (dptype.prot != WX_DEC_PTYPE_PROT_SCTP &&
++          wx_test_staterr(rx_desc, WX_RXD_STAT_IPV6EX))
+               return;
+       /* if L4 checksum error */
+diff --git a/drivers/net/ethernet/wangxun/libwx/wx_type.h b/drivers/net/ethernet/wangxun/libwx/wx_type.h
+index b54bffda027b4..1d9ed1cffd67c 100644
+--- a/drivers/net/ethernet/wangxun/libwx/wx_type.h
++++ b/drivers/net/ethernet/wangxun/libwx/wx_type.h
+@@ -460,6 +460,7 @@ enum WX_MSCA_CMD_value {
+ #define WX_RXD_STAT_L4CS             BIT(7) /* L4 xsum calculated */
+ #define WX_RXD_STAT_IPCS             BIT(8) /* IP xsum calculated */
+ #define WX_RXD_STAT_OUTERIPCS        BIT(10) /* Cloud IP xsum calculated*/
++#define WX_RXD_STAT_IPV6EX           BIT(12) /* IPv6 Dest Header */
+ #define WX_RXD_ERR_OUTERIPER         BIT(26) /* CRC IP Header error */
+ #define WX_RXD_ERR_RXE               BIT(29) /* Any MAC Error */
+@@ -535,8 +536,6 @@ enum wx_l2_ptypes {
+ #define WX_RXD_PKTTYPE(_rxd) \
+       ((le32_to_cpu((_rxd)->wb.lower.lo_dword.data) >> 9) & 0xFF)
+-#define WX_RXD_IPV6EX(_rxd) \
+-      ((le32_to_cpu((_rxd)->wb.lower.lo_dword.data) >> 6) & 0x1)
+ /*********************** Transmit Descriptor Config Masks ****************/
+ #define WX_TXD_STAT_DD               BIT(0)  /* Descriptor Done */
+ #define WX_TXD_DTYP_DATA             0       /* Adv Data Descriptor */
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-libwx-handle-page_pool_dev_alloc_pages-error.patch b/queue-6.14/net-libwx-handle-page_pool_dev_alloc_pages-error.patch
new file mode 100644 (file)
index 0000000..d60ff96
--- /dev/null
@@ -0,0 +1,44 @@
+From 0d20fb86fa84585ab1a6741b8cc6ce30756b6233 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 13:49:52 -0500
+Subject: net: libwx: handle page_pool_dev_alloc_pages error
+
+From: Chenyuan Yang <chenyuan0y@gmail.com>
+
+[ Upstream commit 7f1ff1b38a7c8b872382b796023419d87d78c47e ]
+
+page_pool_dev_alloc_pages could return NULL. There was a WARN_ON(!page)
+but it would still proceed to use the NULL pointer and then crash.
+
+This is similar to commit 001ba0902046
+("net: fec: handle page_pool_dev_alloc_pages error").
+
+This is found by our static analysis tool KNighter.
+
+Signed-off-by: Chenyuan Yang <chenyuan0y@gmail.com>
+Fixes: 3c47e8ae113a ("net: libwx: Support to receive packets in NAPI")
+Reviewed-by: Joe Damato <jdamato@fastly.com>
+Link: https://patch.msgid.link/20250407184952.2111299-1-chenyuan0y@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/wangxun/libwx/wx_lib.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/wangxun/libwx/wx_lib.c b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+index 497abf2723a5e..43b89509d0fe5 100644
+--- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c
++++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c
+@@ -309,7 +309,8 @@ static bool wx_alloc_mapped_page(struct wx_ring *rx_ring,
+               return true;
+       page = page_pool_dev_alloc_pages(rx_ring->page_pool);
+-      WARN_ON(!page);
++      if (unlikely(!page))
++              return false;
+       dma = page_pool_get_dma_addr(page);
+       bi->page_dma = dma;
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-phy-allow-mdio-bus-pm-ops-to-start-stop-state-ma.patch b/queue-6.14/net-phy-allow-mdio-bus-pm-ops-to-start-stop-state-ma.patch
new file mode 100644 (file)
index 0000000..336e4ed
--- /dev/null
@@ -0,0 +1,163 @@
+From d55cb3f3ad070cd1638a2681a69fb2944785fb02 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 12:40:42 +0300
+Subject: net: phy: allow MDIO bus PM ops to start/stop state machine for
+ phylink-controlled PHY
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit fc75ea20ffb452652f0d4033f38fe88d7cfdae35 ]
+
+DSA has 2 kinds of drivers:
+
+1. Those who call dsa_switch_suspend() and dsa_switch_resume() from
+   their device PM ops: qca8k-8xxx, bcm_sf2, microchip ksz
+2. Those who don't: all others. The above methods should be optional.
+
+For type 1, dsa_switch_suspend() calls dsa_user_suspend() -> phylink_stop(),
+and dsa_switch_resume() calls dsa_user_resume() -> phylink_start().
+These seem good candidates for setting mac_managed_pm = true because
+that is essentially its definition [1], but that does not seem to be the
+biggest problem for now, and is not what this change focuses on.
+
+Talking strictly about the 2nd category of DSA drivers here (which
+do not have MAC managed PM, meaning that for their attached PHYs,
+mdio_bus_phy_suspend() and mdio_bus_phy_resume() should run in full),
+I have noticed that the following warning from mdio_bus_phy_resume() is
+triggered:
+
+       WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY &&
+               phydev->state != PHY_UP);
+
+because the PHY state machine is running.
+
+It's running as a result of a previous dsa_user_open() -> ... ->
+phylink_start() -> phy_start() having been initiated by the user.
+
+The previous mdio_bus_phy_suspend() was supposed to have called
+phy_stop_machine(), but it didn't. So this is why the PHY is in state
+PHY_NOLINK by the time mdio_bus_phy_resume() runs.
+
+mdio_bus_phy_suspend() did not call phy_stop_machine() because for
+phylink, the phydev->adjust_link function pointer is NULL. This seems a
+technicality introduced by commit fddd91016d16 ("phylib: fix PAL state
+machine restart on resume"). That commit was written before phylink
+existed, and was intended to avoid crashing with consumer drivers which
+don't use the PHY state machine - phylink always does, when using a PHY.
+But phylink itself has historically not been developed with
+suspend/resume in mind, and apparently not tested too much in that
+scenario, allowing this bug to exist unnoticed for so long. Plus, prior
+to the WARN_ON(), it would have likely been invisible.
+
+This issue is not in fact restricted to type 2 DSA drivers (according to
+the above ad-hoc classification), but can be extrapolated to any MAC
+driver with phylink and MDIO-bus-managed PHY PM ops. DSA is just where
+the issue was reported. Assuming mac_managed_pm is set correctly, a
+quick search indicates the following other drivers might be affected:
+
+$ grep -Zlr PHYLINK_NETDEV drivers/ | xargs -0 grep -L mac_managed_pm
+drivers/net/ethernet/atheros/ag71xx.c
+drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+drivers/net/ethernet/microchip/lan966x/lan966x_main.c
+drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
+drivers/net/ethernet/freescale/ucc_geth.c
+drivers/net/ethernet/freescale/enetc/enetc_pf_common.c
+drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
+drivers/net/ethernet/marvell/mvneta.c
+drivers/net/ethernet/marvell/prestera/prestera_main.c
+drivers/net/ethernet/mediatek/mtk_eth_soc.c
+drivers/net/ethernet/altera/altera_tse_main.c
+drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c
+drivers/net/ethernet/meta/fbnic/fbnic_phylink.c
+drivers/net/ethernet/tehuti/tn40_phy.c
+drivers/net/ethernet/mscc/ocelot_net.c
+
+Make the existing conditions dependent on the PHY device having a
+phydev->phy_link_change() implementation equal to the default
+phy_link_change() provided by phylib. Otherwise, we implicitly know that
+the phydev has the phylink-provided phylink_phy_change() callback, and
+when phylink is used, the PHY state machine always needs to be stopped/
+started on the suspend/resume path. The code is structured as such that
+if phydev->phy_link_change() is absent, it is a matter of time until the
+kernel will crash - no need to further complicate the test.
+
+Thus, for the situation where the PM is not managed by the MAC, we will
+make the MDIO bus PM ops treat identically the phylink-controlled PHYs
+with the phylib-controlled PHYs where an adjust_link() callback is
+supplied. In both cases, the MDIO bus PM ops should stop and restart the
+PHY state machine.
+
+[1] https://lore.kernel.org/netdev/Z-1tiW9zjcoFkhwc@shell.armlinux.org.uk/
+
+Fixes: 744d23c71af3 ("net: phy: Warn about incorrect mdio_bus_phy_resume() state")
+Reported-by: Wei Fang <wei.fang@nxp.com>
+Tested-by: Wei Fang <wei.fang@nxp.com>
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Link: https://patch.msgid.link/20250407094042.2155633-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 31 +++++++++++++++++++++++++++++--
+ 1 file changed, 29 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 27d61d95933fa..92161af788afd 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -253,6 +253,33 @@ static void phy_link_change(struct phy_device *phydev, bool up)
+               phydev->mii_ts->link_state(phydev->mii_ts, phydev);
+ }
++/**
++ * phy_uses_state_machine - test whether consumer driver uses PAL state machine
++ * @phydev: the target PHY device structure
++ *
++ * Ultimately, this aims to indirectly determine whether the PHY is attached
++ * to a consumer which uses the state machine by calling phy_start() and
++ * phy_stop().
++ *
++ * When the PHY driver consumer uses phylib, it must have previously called
++ * phy_connect_direct() or one of its derivatives, so that phy_prepare_link()
++ * has set up a hook for monitoring state changes.
++ *
++ * When the PHY driver is used by the MAC driver consumer through phylink (the
++ * only other provider of a phy_link_change() method), using the PHY state
++ * machine is not optional.
++ *
++ * Return: true if consumer calls phy_start() and phy_stop(), false otherwise.
++ */
++static bool phy_uses_state_machine(struct phy_device *phydev)
++{
++      if (phydev->phy_link_change == phy_link_change)
++              return phydev->attached_dev && phydev->adjust_link;
++
++      /* phydev->phy_link_change is implicitly phylink_phy_change() */
++      return true;
++}
++
+ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
+ {
+       struct device_driver *drv = phydev->mdio.dev.driver;
+@@ -319,7 +346,7 @@ static __maybe_unused int mdio_bus_phy_suspend(struct device *dev)
+        * may call phy routines that try to grab the same lock, and that may
+        * lead to a deadlock.
+        */
+-      if (phydev->attached_dev && phydev->adjust_link)
++      if (phy_uses_state_machine(phydev))
+               phy_stop_machine(phydev);
+       if (!mdio_bus_phy_may_suspend(phydev))
+@@ -373,7 +400,7 @@ static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
+               }
+       }
+-      if (phydev->attached_dev && phydev->adjust_link)
++      if (phy_uses_state_machine(phydev))
+               phy_start_machine(phydev);
+       return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-phy-move-phy_link_change-prior-to-mdio_bus_phy_m.patch b/queue-6.14/net-phy-move-phy_link_change-prior-to-mdio_bus_phy_m.patch
new file mode 100644 (file)
index 0000000..d815521
--- /dev/null
@@ -0,0 +1,76 @@
+From 610ce336e568c621f60c6b46e709c42f9c1e316d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 12:38:59 +0300
+Subject: net: phy: move phy_link_change() prior to mdio_bus_phy_may_suspend()
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+[ Upstream commit f40a673d6b4a128fe95dd9b8c3ed02da50a6a862 ]
+
+In an upcoming change, mdio_bus_phy_may_suspend() will need to
+distinguish a phylib-based PHY client from a phylink PHY client.
+For that, it will need to compare the phydev->phy_link_change() function
+pointer with the eponymous phy_link_change() provided by phylib.
+
+To avoid forward function declarations, the default PHY link state
+change method should be moved upwards. There is no functional change
+associated with this patch, it is only to reduce the noise from a real
+bug fix.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/20250407093900.2155112-1-vladimir.oltean@nxp.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: fc75ea20ffb4 ("net: phy: allow MDIO bus PM ops to start/stop state machine for phylink-controlled PHY")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/phy/phy_device.c | 26 +++++++++++++-------------
+ 1 file changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
+index 46713d27412b7..27d61d95933fa 100644
+--- a/drivers/net/phy/phy_device.c
++++ b/drivers/net/phy/phy_device.c
+@@ -240,6 +240,19 @@ static bool phy_drv_wol_enabled(struct phy_device *phydev)
+       return wol.wolopts != 0;
+ }
++static void phy_link_change(struct phy_device *phydev, bool up)
++{
++      struct net_device *netdev = phydev->attached_dev;
++
++      if (up)
++              netif_carrier_on(netdev);
++      else
++              netif_carrier_off(netdev);
++      phydev->adjust_link(netdev);
++      if (phydev->mii_ts && phydev->mii_ts->link_state)
++              phydev->mii_ts->link_state(phydev->mii_ts, phydev);
++}
++
+ static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
+ {
+       struct device_driver *drv = phydev->mdio.dev.driver;
+@@ -1052,19 +1065,6 @@ struct phy_device *phy_find_first(struct mii_bus *bus)
+ }
+ EXPORT_SYMBOL(phy_find_first);
+-static void phy_link_change(struct phy_device *phydev, bool up)
+-{
+-      struct net_device *netdev = phydev->attached_dev;
+-
+-      if (up)
+-              netif_carrier_on(netdev);
+-      else
+-              netif_carrier_off(netdev);
+-      phydev->adjust_link(netdev);
+-      if (phydev->mii_ts && phydev->mii_ts->link_state)
+-              phydev->mii_ts->link_state(phydev->mii_ts, phydev);
+-}
+-
+ /**
+  * phy_prepare_link - prepares the PHY layer to monitor link status
+  * @phydev: target phy_device struct
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-ppp-add-bound-checking-for-skb-data-on-ppp_sync_.patch b/queue-6.14/net-ppp-add-bound-checking-for-skb-data-on-ppp_sync_.patch
new file mode 100644 (file)
index 0000000..f8050e1
--- /dev/null
@@ -0,0 +1,73 @@
+From 11ec9348f31d8f602a8a8fc32975528aceb295a8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 17:55:08 +0200
+Subject: net: ppp: Add bound checking for skb data on ppp_sync_txmung
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arnaud Lecomte <contact@arnaud-lcm.com>
+
+[ Upstream commit aabc6596ffb377c4c9c8f335124b92ea282c9821 ]
+
+Ensure we have enough data in linear buffer from skb before accessing
+initial bytes. This prevents potential out-of-bounds accesses
+when processing short packets.
+
+When ppp_sync_txmung receives an incoming package with an empty
+payload:
+(remote) gef➤  p *(struct pppoe_hdr *) (skb->head + skb->network_header)
+$18 = {
+       type = 0x1,
+       ver = 0x1,
+       code = 0x0,
+       sid = 0x2,
+        length = 0x0,
+       tag = 0xffff8880371cdb96
+}
+
+from the skb struct (trimmed)
+      tail = 0x16,
+      end = 0x140,
+      head = 0xffff88803346f400 "4",
+      data = 0xffff88803346f416 ":\377",
+      truesize = 0x380,
+      len = 0x0,
+      data_len = 0x0,
+      mac_len = 0xe,
+      hdr_len = 0x0,
+
+it is not safe to access data[2].
+
+Reported-by: syzbot+29fc8991b0ecb186cf40@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=29fc8991b0ecb186cf40
+Tested-by: syzbot+29fc8991b0ecb186cf40@syzkaller.appspotmail.com
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Arnaud Lecomte <contact@arnaud-lcm.com>
+Link: https://patch.msgid.link/20250408-bound-checking-ppp_txmung-v2-1-94bb6e1b92d0@arnaud-lcm.com
+[pabeni@redhat.com: fixed subj typo]
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ppp/ppp_synctty.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c
+index 644e99fc3623f..9c4932198931f 100644
+--- a/drivers/net/ppp/ppp_synctty.c
++++ b/drivers/net/ppp/ppp_synctty.c
+@@ -506,6 +506,11 @@ ppp_sync_txmunge(struct syncppp *ap, struct sk_buff *skb)
+       unsigned char *data;
+       int islcp;
++      /* Ensure we can safely access protocol field and LCP code */
++      if (!pskb_may_pull(skb, 3)) {
++              kfree_skb(skb);
++              return NULL;
++      }
+       data  = skb->data;
+       proto = get_unaligned_be16(data);
+-- 
+2.39.5
+
diff --git a/queue-6.14/net-tls-explicitly-disallow-disconnect.patch b/queue-6.14/net-tls-explicitly-disallow-disconnect.patch
new file mode 100644 (file)
index 0000000..a8da1c2
--- /dev/null
@@ -0,0 +1,69 @@
+From d53a4f2602adfd4a02734b12a764da53fbe01395 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 11:03:33 -0700
+Subject: net: tls: explicitly disallow disconnect
+
+From: Jakub Kicinski <kuba@kernel.org>
+
+[ Upstream commit 5071a1e606b30c0c11278d3c6620cd6a24724cf6 ]
+
+syzbot discovered that it can disconnect a TLS socket and then
+run into all sort of unexpected corner cases. I have a vague
+recollection of Eric pointing this out to us a long time ago.
+Supporting disconnect is really hard, for one thing if offload
+is enabled we'd need to wait for all packets to be _acked_.
+Disconnect is not commonly used, disallow it.
+
+The immediate problem syzbot run into is the warning in the strp,
+but that's just the easiest bug to trigger:
+
+  WARNING: CPU: 0 PID: 5834 at net/tls/tls_strp.c:486 tls_strp_msg_load+0x72e/0xa80 net/tls/tls_strp.c:486
+  RIP: 0010:tls_strp_msg_load+0x72e/0xa80 net/tls/tls_strp.c:486
+  Call Trace:
+   <TASK>
+   tls_rx_rec_wait+0x280/0xa60 net/tls/tls_sw.c:1363
+   tls_sw_recvmsg+0x85c/0x1c30 net/tls/tls_sw.c:2043
+   inet6_recvmsg+0x2c9/0x730 net/ipv6/af_inet6.c:678
+   sock_recvmsg_nosec net/socket.c:1023 [inline]
+   sock_recvmsg+0x109/0x280 net/socket.c:1045
+   __sys_recvfrom+0x202/0x380 net/socket.c:2237
+
+Fixes: 3c4d7559159b ("tls: kernel TLS support")
+Reported-by: syzbot+b4cd76826045a1eb93c1@syzkaller.appspotmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
+Link: https://patch.msgid.link/20250404180334.3224206-1-kuba@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tls/tls_main.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
+index 99ca4465f7021..4d7702ce17c06 100644
+--- a/net/tls/tls_main.c
++++ b/net/tls/tls_main.c
+@@ -852,6 +852,11 @@ static int tls_setsockopt(struct sock *sk, int level, int optname,
+       return do_tls_setsockopt(sk, optname, optval, optlen);
+ }
++static int tls_disconnect(struct sock *sk, int flags)
++{
++      return -EOPNOTSUPP;
++}
++
+ struct tls_context *tls_ctx_create(struct sock *sk)
+ {
+       struct inet_connection_sock *icsk = inet_csk(sk);
+@@ -947,6 +952,7 @@ static void build_protos(struct proto prot[TLS_NUM_CONFIG][TLS_NUM_CONFIG],
+       prot[TLS_BASE][TLS_BASE] = *base;
+       prot[TLS_BASE][TLS_BASE].setsockopt     = tls_setsockopt;
+       prot[TLS_BASE][TLS_BASE].getsockopt     = tls_getsockopt;
++      prot[TLS_BASE][TLS_BASE].disconnect     = tls_disconnect;
+       prot[TLS_BASE][TLS_BASE].close          = tls_sk_proto_close;
+       prot[TLS_SW][TLS_BASE] = prot[TLS_BASE][TLS_BASE];
+-- 
+2.39.5
+
diff --git a/queue-6.14/net_sched-sch_sfq-move-the-limit-validation.patch b/queue-6.14/net_sched-sch_sfq-move-the-limit-validation.patch
new file mode 100644 (file)
index 0000000..0ab61e3
--- /dev/null
@@ -0,0 +1,85 @@
+From 5b2010c4ad121142a3208a9755a455dbeada5065 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 13:24:08 -0700
+Subject: net_sched: sch_sfq: move the limit validation
+
+From: Octavian Purdila <tavip@google.com>
+
+[ Upstream commit b3bf8f63e6179076b57c9de660c9f80b5abefe70 ]
+
+It is not sufficient to directly validate the limit on the data that
+the user passes as it can be updated based on how the other parameters
+are changed.
+
+Move the check at the end of the configuration update process to also
+catch scenarios where the limit is indirectly updated, for example
+with the following configurations:
+
+tc qdisc add dev dummy0 handle 1: root sfq limit 2 flows 1 depth 1
+tc qdisc add dev dummy0 handle 1: root sfq limit 2 flows 1 divisor 1
+
+This fixes the following syzkaller reported crash:
+
+------------[ cut here ]------------
+UBSAN: array-index-out-of-bounds in net/sched/sch_sfq.c:203:6
+index 65535 is out of range for type 'struct sfq_head[128]'
+CPU: 1 UID: 0 PID: 3037 Comm: syz.2.16 Not tainted 6.14.0-rc2-syzkaller #0
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 12/27/2024
+Call Trace:
+ <TASK>
+ __dump_stack lib/dump_stack.c:94 [inline]
+ dump_stack_lvl+0x201/0x300 lib/dump_stack.c:120
+ ubsan_epilogue lib/ubsan.c:231 [inline]
+ __ubsan_handle_out_of_bounds+0xf5/0x120 lib/ubsan.c:429
+ sfq_link net/sched/sch_sfq.c:203 [inline]
+ sfq_dec+0x53c/0x610 net/sched/sch_sfq.c:231
+ sfq_dequeue+0x34e/0x8c0 net/sched/sch_sfq.c:493
+ sfq_reset+0x17/0x60 net/sched/sch_sfq.c:518
+ qdisc_reset+0x12e/0x600 net/sched/sch_generic.c:1035
+ tbf_reset+0x41/0x110 net/sched/sch_tbf.c:339
+ qdisc_reset+0x12e/0x600 net/sched/sch_generic.c:1035
+ dev_reset_queue+0x100/0x1b0 net/sched/sch_generic.c:1311
+ netdev_for_each_tx_queue include/linux/netdevice.h:2590 [inline]
+ dev_deactivate_many+0x7e5/0xe70 net/sched/sch_generic.c:1375
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Fixes: 10685681bafc ("net_sched: sch_sfq: don't allow 1 packet limit")
+Signed-off-by: Octavian Purdila <tavip@google.com>
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_sfq.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
+index 7714ae94e0521..58b42dcf8f201 100644
+--- a/net/sched/sch_sfq.c
++++ b/net/sched/sch_sfq.c
+@@ -661,10 +661,6 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
+               if (!p)
+                       return -ENOMEM;
+       }
+-      if (ctl->limit == 1) {
+-              NL_SET_ERR_MSG_MOD(extack, "invalid limit");
+-              return -EINVAL;
+-      }
+       sch_tree_lock(sch);
+@@ -705,6 +701,12 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
+               limit = min_t(u32, ctl->limit, maxdepth * maxflows);
+               maxflows = min_t(u32, maxflows, limit);
+       }
++      if (limit == 1) {
++              sch_tree_unlock(sch);
++              kfree(p);
++              NL_SET_ERR_MSG_MOD(extack, "invalid limit");
++              return -EINVAL;
++      }
+       /* commit configuration */
+       q->limit = limit;
+-- 
+2.39.5
+
diff --git a/queue-6.14/net_sched-sch_sfq-use-a-temporary-work-area-for-vali.patch b/queue-6.14/net_sched-sch_sfq-use-a-temporary-work-area-for-vali.patch
new file mode 100644 (file)
index 0000000..fa42f62
--- /dev/null
@@ -0,0 +1,124 @@
+From dbf99084095d2f3aab2cfc461be9a005adb8d81b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 13:24:07 -0700
+Subject: net_sched: sch_sfq: use a temporary work area for validating
+ configuration
+
+From: Octavian Purdila <tavip@google.com>
+
+[ Upstream commit 8c0cea59d40cf6dd13c2950437631dd614fbade6 ]
+
+Many configuration parameters have influence on others (e.g. divisor
+-> flows -> limit, depth -> limit) and so it is difficult to correctly
+do all of the validation before applying the configuration. And if a
+validation error is detected late it is difficult to roll back a
+partially applied configuration.
+
+To avoid these issues use a temporary work area to update and validate
+the configuration and only then apply the configuration to the
+internal state.
+
+Signed-off-by: Octavian Purdila <tavip@google.com>
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: b3bf8f63e617 ("net_sched: sch_sfq: move the limit validation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_sfq.c | 56 +++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 44 insertions(+), 12 deletions(-)
+
+diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
+index 65d5b59da5830..7714ae94e0521 100644
+--- a/net/sched/sch_sfq.c
++++ b/net/sched/sch_sfq.c
+@@ -631,6 +631,15 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
+       struct red_parms *p = NULL;
+       struct sk_buff *to_free = NULL;
+       struct sk_buff *tail = NULL;
++      unsigned int maxflows;
++      unsigned int quantum;
++      unsigned int divisor;
++      int perturb_period;
++      u8 headdrop;
++      u8 maxdepth;
++      int limit;
++      u8 flags;
++
+       if (opt->nla_len < nla_attr_size(sizeof(*ctl)))
+               return -EINVAL;
+@@ -656,36 +665,59 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
+               NL_SET_ERR_MSG_MOD(extack, "invalid limit");
+               return -EINVAL;
+       }
++
+       sch_tree_lock(sch);
++
++      limit = q->limit;
++      divisor = q->divisor;
++      headdrop = q->headdrop;
++      maxdepth = q->maxdepth;
++      maxflows = q->maxflows;
++      perturb_period = q->perturb_period;
++      quantum = q->quantum;
++      flags = q->flags;
++
++      /* update and validate configuration */
+       if (ctl->quantum)
+-              q->quantum = ctl->quantum;
+-      WRITE_ONCE(q->perturb_period, ctl->perturb_period * HZ);
++              quantum = ctl->quantum;
++      perturb_period = ctl->perturb_period * HZ;
+       if (ctl->flows)
+-              q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
++              maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
+       if (ctl->divisor) {
+-              q->divisor = ctl->divisor;
+-              q->maxflows = min_t(u32, q->maxflows, q->divisor);
++              divisor = ctl->divisor;
++              maxflows = min_t(u32, maxflows, divisor);
+       }
+       if (ctl_v1) {
+               if (ctl_v1->depth)
+-                      q->maxdepth = min_t(u32, ctl_v1->depth, SFQ_MAX_DEPTH);
++                      maxdepth = min_t(u32, ctl_v1->depth, SFQ_MAX_DEPTH);
+               if (p) {
+-                      swap(q->red_parms, p);
+-                      red_set_parms(q->red_parms,
++                      red_set_parms(p,
+                                     ctl_v1->qth_min, ctl_v1->qth_max,
+                                     ctl_v1->Wlog,
+                                     ctl_v1->Plog, ctl_v1->Scell_log,
+                                     NULL,
+                                     ctl_v1->max_P);
+               }
+-              q->flags = ctl_v1->flags;
+-              q->headdrop = ctl_v1->headdrop;
++              flags = ctl_v1->flags;
++              headdrop = ctl_v1->headdrop;
+       }
+       if (ctl->limit) {
+-              q->limit = min_t(u32, ctl->limit, q->maxdepth * q->maxflows);
+-              q->maxflows = min_t(u32, q->maxflows, q->limit);
++              limit = min_t(u32, ctl->limit, maxdepth * maxflows);
++              maxflows = min_t(u32, maxflows, limit);
+       }
++      /* commit configuration */
++      q->limit = limit;
++      q->divisor = divisor;
++      q->headdrop = headdrop;
++      q->maxdepth = maxdepth;
++      q->maxflows = maxflows;
++      WRITE_ONCE(q->perturb_period, perturb_period);
++      q->quantum = quantum;
++      q->flags = flags;
++      if (p)
++              swap(q->red_parms, p);
++
+       qlen = sch->q.qlen;
+       while (sch->q.qlen > q->limit) {
+               dropped += sfq_drop(sch, &to_free);
+-- 
+2.39.5
+
diff --git a/queue-6.14/nft_set_pipapo-fix-incorrect-avx2-match-of-5th-field.patch b/queue-6.14/nft_set_pipapo-fix-incorrect-avx2-match-of-5th-field.patch
new file mode 100644 (file)
index 0000000..e184a3d
--- /dev/null
@@ -0,0 +1,53 @@
+From 5c60d31f711bb2e65e73bd04f1ff72427068f728 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 19:40:18 +0200
+Subject: nft_set_pipapo: fix incorrect avx2 match of 5th field octet
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit e042ed950d4e176379ba4c0722146cd96fb38aa2 ]
+
+Given a set element like:
+
+       icmpv6 . dead:beef:00ff::1
+
+The value of 'ff' is irrelevant, any address will be matched
+as long as the other octets are the same.
+
+This is because of too-early register clobbering:
+ymm7 is reloaded with new packet data (pkt[9])  but it still holds data
+of an earlier load that wasn't processed yet.
+
+The existing tests in nft_concat_range.sh selftests do exercise this code
+path, but do not trigger incorrect matching due to the network prefix
+limitation.
+
+Fixes: 7400b063969b ("nft_set_pipapo: Introduce AVX2-based lookup implementation")
+Reported-by: sontu mazumdar <sontu21@gmail.com>
+Closes: https://lore.kernel.org/netfilter/CANgxkqwnMH7fXra+VUfODT-8+qFLgskq3set1cAzqqJaV4iEZg@mail.gmail.com/T/#t
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_set_pipapo_avx2.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/netfilter/nft_set_pipapo_avx2.c b/net/netfilter/nft_set_pipapo_avx2.c
+index b8d3c3213efee..c15db28c5ebc4 100644
+--- a/net/netfilter/nft_set_pipapo_avx2.c
++++ b/net/netfilter/nft_set_pipapo_avx2.c
+@@ -994,8 +994,9 @@ static int nft_pipapo_avx2_lookup_8b_16(unsigned long *map, unsigned long *fill,
+               NFT_PIPAPO_AVX2_BUCKET_LOAD8(5, lt,  8,  pkt[8], bsize);
+               NFT_PIPAPO_AVX2_AND(6, 2, 3);
++              NFT_PIPAPO_AVX2_AND(3, 4, 7);
+               NFT_PIPAPO_AVX2_BUCKET_LOAD8(7, lt,  9,  pkt[9], bsize);
+-              NFT_PIPAPO_AVX2_AND(0, 4, 5);
++              NFT_PIPAPO_AVX2_AND(0, 3, 5);
+               NFT_PIPAPO_AVX2_BUCKET_LOAD8(1, lt, 10, pkt[10], bsize);
+               NFT_PIPAPO_AVX2_AND(2, 6, 7);
+               NFT_PIPAPO_AVX2_BUCKET_LOAD8(3, lt, 11, pkt[11], bsize);
+-- 
+2.39.5
+
diff --git a/queue-6.14/nvmet-fcloop-swap-list_add_tail-arguments.patch b/queue-6.14/nvmet-fcloop-swap-list_add_tail-arguments.patch
new file mode 100644 (file)
index 0000000..173d45e
--- /dev/null
@@ -0,0 +1,38 @@
+From 899b4e820bad7749a99324a6e5007789e4ec7bbb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 17:29:03 +0200
+Subject: nvmet-fcloop: swap list_add_tail arguments
+
+From: Daniel Wagner <wagi@kernel.org>
+
+[ Upstream commit 2b5f0c5bc819af2b0759a8fcddc1b39102735c0f ]
+
+The newly element to be added to the list is the first argument of
+list_add_tail. This fix is missing dcfad4ab4d67 ("nvmet-fcloop: swap
+the list_add_tail arguments").
+
+Fixes: 437c0b824dbd ("nvme-fcloop: add target to host LS request support")
+Signed-off-by: Daniel Wagner <wagi@kernel.org>
+Reviewed-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/target/fcloop.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/target/fcloop.c b/drivers/nvme/target/fcloop.c
+index e1abb27927ff7..da195d61a9664 100644
+--- a/drivers/nvme/target/fcloop.c
++++ b/drivers/nvme/target/fcloop.c
+@@ -478,7 +478,7 @@ fcloop_t2h_xmt_ls_rsp(struct nvme_fc_local_port *localport,
+       if (targetport) {
+               tport = targetport->private;
+               spin_lock(&tport->lock);
+-              list_add_tail(&tport->ls_list, &tls_req->ls_list);
++              list_add_tail(&tls_req->ls_list, &tport->ls_list);
+               spin_unlock(&tport->lock);
+               queue_work(nvmet_wq, &tport->ls_work);
+       }
+-- 
+2.39.5
+
diff --git a/queue-6.14/objtool-fix-insn_context_switch-handling-in-validate.patch b/queue-6.14/objtool-fix-insn_context_switch-handling-in-validate.patch
new file mode 100644 (file)
index 0000000..a182d25
--- /dev/null
@@ -0,0 +1,53 @@
+From f631477c782d7d58a9f120fa28e164f34ce8b5e4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 8 Apr 2025 00:02:13 -0700
+Subject: objtool: Fix INSN_CONTEXT_SWITCH handling in validate_unret()
+
+From: Josh Poimboeuf <jpoimboe@kernel.org>
+
+[ Upstream commit a8df7d0ef92eca28c610206c6748daf537ac0586 ]
+
+The !CONFIG_IA32_EMULATION version of xen_entry_SYSCALL_compat() ends
+with a SYSCALL instruction which is classified by objtool as
+INSN_CONTEXT_SWITCH.
+
+Unlike validate_branch(), validate_unret() doesn't consider
+INSN_CONTEXT_SWITCH in a non-function to be a dead end, so it keeps
+going past the end of xen_entry_SYSCALL_compat(), resulting in the
+following warning:
+
+  vmlinux.o: warning: objtool: xen_reschedule_interrupt+0x2a: RET before UNTRAIN
+
+Fix that by adding INSN_CONTEXT_SWITCH handling to validate_unret() to
+match what validate_branch() is already doing.
+
+Fixes: a09a6e2399ba ("objtool: Add entry UNRET validation")
+Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Link: https://lore.kernel.org/r/f5eda46fd09f15b1f5cde3d9ae3b92b958342add.1744095216.git.jpoimboe@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/objtool/check.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/tools/objtool/check.c b/tools/objtool/check.c
+index 159fb130e2827..9f4c54fe6f56f 100644
+--- a/tools/objtool/check.c
++++ b/tools/objtool/check.c
+@@ -3846,6 +3846,11 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn)
+                       WARN_INSN(insn, "RET before UNTRAIN");
+                       return 1;
++              case INSN_CONTEXT_SWITCH:
++                      if (insn_func(insn))
++                              break;
++                      return 0;
++
+               case INSN_NOP:
+                       if (insn->retpoline_safe)
+                               return 0;
+-- 
+2.39.5
+
diff --git a/queue-6.14/octeontx2-pf-qos-fix-vf-root-node-parent-queue-index.patch b/queue-6.14/octeontx2-pf-qos-fix-vf-root-node-parent-queue-index.patch
new file mode 100644 (file)
index 0000000..832ba9d
--- /dev/null
@@ -0,0 +1,57 @@
+From c58d65a5e6ea716f96683f6c529c0f5e448c9c58 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 12:33:41 +0530
+Subject: octeontx2-pf: qos: fix VF root node parent queue index
+
+From: Hariprasad Kelam <hkelam@marvell.com>
+
+[ Upstream commit b7db94734e785e380b0db0f9295e07024f4d42a0 ]
+
+The current code configures the Physical Function (PF) root node at TL1
+and the Virtual Function (VF) root node at TL2.
+
+This ensure at any given point of time PF traffic gets more priority.
+
+                    PF root node
+                      TL1
+                     /  \
+                    TL2  TL2 VF root node
+                    /     \
+                   TL3    TL3
+                   /       \
+                  TL4      TL4
+                  /         \
+                 SMQ        SMQ
+
+Due to a bug in the current code, the TL2 parent queue index on the
+VF interface is not being configured, leading to 'SMQ Flush' errors
+
+Fixes: 5e6808b4c68d ("octeontx2-pf: Add support for HTB offload")
+Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20250407070341.2765426-1-hkelam@marvell.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/qos.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
+index 0f844c14485a0..35acc07bd9648 100644
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
+@@ -165,6 +165,11 @@ static void __otx2_qos_txschq_cfg(struct otx2_nic *pfvf,
+               otx2_config_sched_shaping(pfvf, node, cfg, &num_regs);
+       } else if (level == NIX_TXSCH_LVL_TL2) {
++              /* configure parent txschq */
++              cfg->reg[num_regs] = NIX_AF_TL2X_PARENT(node->schq);
++              cfg->regval[num_regs] = (u64)hw->tx_link << 16;
++              num_regs++;
++
+               /* configure link cfg */
+               if (level == pfvf->qos.link_cfg_lvl) {
+                       cfg->reg[num_regs] = NIX_AF_TL3_TL2X_LINKX_CFG(node->schq, hw->tx_link);
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-core-simplify-the-perf_event_alloc-error-path.patch b/queue-6.14/perf-core-simplify-the-perf_event_alloc-error-path.patch
new file mode 100644 (file)
index 0000000..3426af0
--- /dev/null
@@ -0,0 +1,328 @@
+From 7afd37b387e1476abdf6babee25290726d338e7b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Nov 2024 14:39:13 +0100
+Subject: perf/core: Simplify the perf_event_alloc() error path
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+[ Upstream commit c70ca298036c58a88686ff388d3d367e9d21acf0 ]
+
+The error cleanup sequence in perf_event_alloc() is a subset of the
+existing _free_event() function (it must of course be).
+
+Split this out into __free_event() and simplify the error path.
+
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Ravi Bangoria <ravi.bangoria@amd.com>
+Link: https://lore.kernel.org/r/20241104135517.967889521@infradead.org
+Stable-dep-of: 56799bc03565 ("perf: Fix hang while freeing sigtrap event")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/perf_event.h |  16 +++--
+ kernel/events/core.c       | 138 ++++++++++++++++++-------------------
+ 2 files changed, 78 insertions(+), 76 deletions(-)
+
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index bcb764c3a8034..677f80249458e 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -673,13 +673,15 @@ struct swevent_hlist {
+       struct rcu_head                 rcu_head;
+ };
+-#define PERF_ATTACH_CONTEXT   0x01
+-#define PERF_ATTACH_GROUP     0x02
+-#define PERF_ATTACH_TASK      0x04
+-#define PERF_ATTACH_TASK_DATA 0x08
+-#define PERF_ATTACH_ITRACE    0x10
+-#define PERF_ATTACH_SCHED_CB  0x20
+-#define PERF_ATTACH_CHILD     0x40
++#define PERF_ATTACH_CONTEXT   0x0001
++#define PERF_ATTACH_GROUP     0x0002
++#define PERF_ATTACH_TASK      0x0004
++#define PERF_ATTACH_TASK_DATA 0x0008
++#define PERF_ATTACH_ITRACE    0x0010
++#define PERF_ATTACH_SCHED_CB  0x0020
++#define PERF_ATTACH_CHILD     0x0040
++#define PERF_ATTACH_EXCLUSIVE 0x0080
++#define PERF_ATTACH_CALLCHAIN 0x0100
+ struct bpf_prog;
+ struct perf_cgroup;
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index f6cf17929bb98..3a69e816d6f12 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -5253,6 +5253,8 @@ static int exclusive_event_init(struct perf_event *event)
+                       return -EBUSY;
+       }
++      event->attach_state |= PERF_ATTACH_EXCLUSIVE;
++
+       return 0;
+ }
+@@ -5260,14 +5262,13 @@ static void exclusive_event_destroy(struct perf_event *event)
+ {
+       struct pmu *pmu = event->pmu;
+-      if (!is_exclusive_pmu(pmu))
+-              return;
+-
+       /* see comment in exclusive_event_init() */
+       if (event->attach_state & PERF_ATTACH_TASK)
+               atomic_dec(&pmu->exclusive_cnt);
+       else
+               atomic_inc(&pmu->exclusive_cnt);
++
++      event->attach_state &= ~PERF_ATTACH_EXCLUSIVE;
+ }
+ static bool exclusive_event_match(struct perf_event *e1, struct perf_event *e2)
+@@ -5326,40 +5327,20 @@ static void perf_pending_task_sync(struct perf_event *event)
+       rcuwait_wait_event(&event->pending_work_wait, !event->pending_work, TASK_UNINTERRUPTIBLE);
+ }
+-static void _free_event(struct perf_event *event)
++/* vs perf_event_alloc() error */
++static void __free_event(struct perf_event *event)
+ {
+-      irq_work_sync(&event->pending_irq);
+-      irq_work_sync(&event->pending_disable_irq);
+-      perf_pending_task_sync(event);
++      if (event->attach_state & PERF_ATTACH_CALLCHAIN)
++              put_callchain_buffers();
+-      unaccount_event(event);
++      kfree(event->addr_filter_ranges);
+-      security_perf_event_free(event);
+-
+-      if (event->rb) {
+-              /*
+-               * Can happen when we close an event with re-directed output.
+-               *
+-               * Since we have a 0 refcount, perf_mmap_close() will skip
+-               * over us; possibly making our ring_buffer_put() the last.
+-               */
+-              mutex_lock(&event->mmap_mutex);
+-              ring_buffer_attach(event, NULL);
+-              mutex_unlock(&event->mmap_mutex);
+-      }
++      if (event->attach_state & PERF_ATTACH_EXCLUSIVE)
++              exclusive_event_destroy(event);
+       if (is_cgroup_event(event))
+               perf_detach_cgroup(event);
+-      if (!event->parent) {
+-              if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN)
+-                      put_callchain_buffers();
+-      }
+-
+-      perf_event_free_bpf_prog(event);
+-      perf_addr_filters_splice(event, NULL);
+-      kfree(event->addr_filter_ranges);
+-
+       if (event->destroy)
+               event->destroy(event);
+@@ -5370,22 +5351,58 @@ static void _free_event(struct perf_event *event)
+       if (event->hw.target)
+               put_task_struct(event->hw.target);
+-      if (event->pmu_ctx)
++      if (event->pmu_ctx) {
++              /*
++               * put_pmu_ctx() needs an event->ctx reference, because of
++               * epc->ctx.
++               */
++              WARN_ON_ONCE(!event->ctx);
++              WARN_ON_ONCE(event->pmu_ctx->ctx != event->ctx);
+               put_pmu_ctx(event->pmu_ctx);
++      }
+       /*
+-       * perf_event_free_task() relies on put_ctx() being 'last', in particular
+-       * all task references must be cleaned up.
++       * perf_event_free_task() relies on put_ctx() being 'last', in
++       * particular all task references must be cleaned up.
+        */
+       if (event->ctx)
+               put_ctx(event->ctx);
+-      exclusive_event_destroy(event);
+-      module_put(event->pmu->module);
++      if (event->pmu)
++              module_put(event->pmu->module);
+       call_rcu(&event->rcu_head, free_event_rcu);
+ }
++/* vs perf_event_alloc() success */
++static void _free_event(struct perf_event *event)
++{
++      irq_work_sync(&event->pending_irq);
++      irq_work_sync(&event->pending_disable_irq);
++      perf_pending_task_sync(event);
++
++      unaccount_event(event);
++
++      security_perf_event_free(event);
++
++      if (event->rb) {
++              /*
++               * Can happen when we close an event with re-directed output.
++               *
++               * Since we have a 0 refcount, perf_mmap_close() will skip
++               * over us; possibly making our ring_buffer_put() the last.
++               */
++              mutex_lock(&event->mmap_mutex);
++              ring_buffer_attach(event, NULL);
++              mutex_unlock(&event->mmap_mutex);
++      }
++
++      perf_event_free_bpf_prog(event);
++      perf_addr_filters_splice(event, NULL);
++
++      __free_event(event);
++}
++
+ /*
+  * Used to free events which have a known refcount of 1, such as in error paths
+  * where the event isn't exposed yet and inherited events.
+@@ -12056,8 +12073,10 @@ static int perf_try_init_event(struct pmu *pmu, struct perf_event *event)
+                       event->destroy(event);
+       }
+-      if (ret)
++      if (ret) {
++              event->pmu = NULL;
+               module_put(pmu->module);
++      }
+       return ret;
+ }
+@@ -12385,7 +12404,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+        * See perf_output_read().
+        */
+       if (has_inherit_and_sample_read(attr) && !(attr->sample_type & PERF_SAMPLE_TID))
+-              goto err_ns;
++              goto err;
+       if (!has_branch_stack(event))
+               event->attr.branch_sample_type = 0;
+@@ -12393,7 +12412,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+       pmu = perf_init_event(event);
+       if (IS_ERR(pmu)) {
+               err = PTR_ERR(pmu);
+-              goto err_ns;
++              goto err;
+       }
+       /*
+@@ -12403,25 +12422,25 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+        */
+       if (pmu->task_ctx_nr == perf_invalid_context && (task || cgroup_fd != -1)) {
+               err = -EINVAL;
+-              goto err_pmu;
++              goto err;
+       }
+       if (event->attr.aux_output &&
+           (!(pmu->capabilities & PERF_PMU_CAP_AUX_OUTPUT) ||
+            event->attr.aux_pause || event->attr.aux_resume)) {
+               err = -EOPNOTSUPP;
+-              goto err_pmu;
++              goto err;
+       }
+       if (event->attr.aux_pause && event->attr.aux_resume) {
+               err = -EINVAL;
+-              goto err_pmu;
++              goto err;
+       }
+       if (event->attr.aux_start_paused) {
+               if (!(pmu->capabilities & PERF_PMU_CAP_AUX_PAUSE)) {
+                       err = -EOPNOTSUPP;
+-                      goto err_pmu;
++                      goto err;
+               }
+               event->hw.aux_paused = 1;
+       }
+@@ -12429,12 +12448,12 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+       if (cgroup_fd != -1) {
+               err = perf_cgroup_connect(cgroup_fd, event, attr, group_leader);
+               if (err)
+-                      goto err_pmu;
++                      goto err;
+       }
+       err = exclusive_event_init(event);
+       if (err)
+-              goto err_pmu;
++              goto err;
+       if (has_addr_filter(event)) {
+               event->addr_filter_ranges = kcalloc(pmu->nr_addr_filters,
+@@ -12442,7 +12461,7 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+                                                   GFP_KERNEL);
+               if (!event->addr_filter_ranges) {
+                       err = -ENOMEM;
+-                      goto err_per_task;
++                      goto err;
+               }
+               /*
+@@ -12467,41 +12486,22 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+               if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
+                       err = get_callchain_buffers(attr->sample_max_stack);
+                       if (err)
+-                              goto err_addr_filters;
++                              goto err;
++                      event->attach_state |= PERF_ATTACH_CALLCHAIN;
+               }
+       }
+       err = security_perf_event_alloc(event);
+       if (err)
+-              goto err_callchain_buffer;
++              goto err;
+       /* symmetric to unaccount_event() in _free_event() */
+       account_event(event);
+       return event;
+-err_callchain_buffer:
+-      if (!event->parent) {
+-              if (event->attr.sample_type & PERF_SAMPLE_CALLCHAIN)
+-                      put_callchain_buffers();
+-      }
+-err_addr_filters:
+-      kfree(event->addr_filter_ranges);
+-
+-err_per_task:
+-      exclusive_event_destroy(event);
+-
+-err_pmu:
+-      if (is_cgroup_event(event))
+-              perf_detach_cgroup(event);
+-      if (event->destroy)
+-              event->destroy(event);
+-      module_put(pmu->module);
+-err_ns:
+-      if (event->hw.target)
+-              put_task_struct(event->hw.target);
+-      call_rcu(&event->rcu_head, free_event_rcu);
+-
++err:
++      __free_event(event);
+       return ERR_PTR(err);
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/perf-fix-hang-while-freeing-sigtrap-event.patch b/queue-6.14/perf-fix-hang-while-freeing-sigtrap-event.patch
new file mode 100644 (file)
index 0000000..6d32257
--- /dev/null
@@ -0,0 +1,260 @@
+From 0638641d37a990e6034d15297baa3b31d8eaea24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 4 Mar 2025 14:54:46 +0100
+Subject: perf: Fix hang while freeing sigtrap event
+
+From: Frederic Weisbecker <frederic@kernel.org>
+
+[ Upstream commit 56799bc035658738f362acec3e7647bb84e68933 ]
+
+Perf can hang while freeing a sigtrap event if a related deferred
+signal hadn't managed to be sent before the file got closed:
+
+perf_event_overflow()
+   task_work_add(perf_pending_task)
+
+fput()
+   task_work_add(____fput())
+
+task_work_run()
+    ____fput()
+        perf_release()
+            perf_event_release_kernel()
+                _free_event()
+                    perf_pending_task_sync()
+                        task_work_cancel() -> FAILED
+                        rcuwait_wait_event()
+
+Once task_work_run() is running, the list of pending callbacks is
+removed from the task_struct and from this point on task_work_cancel()
+can't remove any pending and not yet started work items, hence the
+task_work_cancel() failure and the hang on rcuwait_wait_event().
+
+Task work could be changed to remove one work at a time, so a work
+running on the current task can always cancel a pending one, however
+the wait / wake design is still subject to inverted dependencies when
+remote targets are involved, as pictured by Oleg:
+
+T1                                                      T2
+
+fd = perf_event_open(pid => T2->pid);                  fd = perf_event_open(pid => T1->pid);
+close(fd)                                              close(fd)
+    <IRQ>                                                  <IRQ>
+    perf_event_overflow()                                  perf_event_overflow()
+       task_work_add(perf_pending_task)                        task_work_add(perf_pending_task)
+    </IRQ>                                                 </IRQ>
+    fput()                                                 fput()
+        task_work_add(____fput())                              task_work_add(____fput())
+
+    task_work_run()                                        task_work_run()
+        ____fput()                                             ____fput()
+            perf_release()                                         perf_release()
+                perf_event_release_kernel()                            perf_event_release_kernel()
+                    _free_event()                                          _free_event()
+                        perf_pending_task_sync()                               perf_pending_task_sync()
+                            rcuwait_wait_event()                                   rcuwait_wait_event()
+
+Therefore the only option left is to acquire the event reference count
+upon queueing the perf task work and release it from the task work, just
+like it was done before 3a5465418f5f ("perf: Fix event leak upon exec and file release")
+but without the leaks it fixed.
+
+Some adjustments are necessary to make it work:
+
+* A child event might dereference its parent upon freeing. Care must be
+  taken to release the parent last.
+
+* Some places assuming the event doesn't have any reference held and
+  therefore can be freed right away must instead put the reference and
+  let the reference counting to its job.
+
+Reported-by: "Yi Lai" <yi1.lai@linux.intel.com>
+Closes: https://lore.kernel.org/all/Zx9Losv4YcJowaP%2F@ly-workstation/
+Reported-by: syzbot+3c4321e10eea460eb606@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/all/673adf75.050a0220.87769.0024.GAE@google.com/
+Fixes: 3a5465418f5f ("perf: Fix event leak upon exec and file release")
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Link: https://lkml.kernel.org/r/20250304135446.18905-1-frederic@kernel.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/linux/perf_event.h |  1 -
+ kernel/events/core.c       | 64 +++++++++++---------------------------
+ 2 files changed, 18 insertions(+), 47 deletions(-)
+
+diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
+index 677f80249458e..93ea9c6672f0e 100644
+--- a/include/linux/perf_event.h
++++ b/include/linux/perf_event.h
+@@ -833,7 +833,6 @@ struct perf_event {
+       struct irq_work                 pending_disable_irq;
+       struct callback_head            pending_task;
+       unsigned int                    pending_work;
+-      struct rcuwait                  pending_work_wait;
+       atomic_t                        event_limit;
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index 3a69e816d6f12..ee6b7281a1994 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -5303,30 +5303,6 @@ static bool exclusive_event_installable(struct perf_event *event,
+ static void perf_addr_filters_splice(struct perf_event *event,
+                                      struct list_head *head);
+-static void perf_pending_task_sync(struct perf_event *event)
+-{
+-      struct callback_head *head = &event->pending_task;
+-
+-      if (!event->pending_work)
+-              return;
+-      /*
+-       * If the task is queued to the current task's queue, we
+-       * obviously can't wait for it to complete. Simply cancel it.
+-       */
+-      if (task_work_cancel(current, head)) {
+-              event->pending_work = 0;
+-              local_dec(&event->ctx->nr_no_switch_fast);
+-              return;
+-      }
+-
+-      /*
+-       * All accesses related to the event are within the same RCU section in
+-       * perf_pending_task(). The RCU grace period before the event is freed
+-       * will make sure all those accesses are complete by then.
+-       */
+-      rcuwait_wait_event(&event->pending_work_wait, !event->pending_work, TASK_UNINTERRUPTIBLE);
+-}
+-
+ /* vs perf_event_alloc() error */
+ static void __free_event(struct perf_event *event)
+ {
+@@ -5379,7 +5355,6 @@ static void _free_event(struct perf_event *event)
+ {
+       irq_work_sync(&event->pending_irq);
+       irq_work_sync(&event->pending_disable_irq);
+-      perf_pending_task_sync(event);
+       unaccount_event(event);
+@@ -5472,10 +5447,17 @@ static void perf_remove_from_owner(struct perf_event *event)
+ static void put_event(struct perf_event *event)
+ {
++      struct perf_event *parent;
++
+       if (!atomic_long_dec_and_test(&event->refcount))
+               return;
++      parent = event->parent;
+       _free_event(event);
++
++      /* Matches the refcount bump in inherit_event() */
++      if (parent)
++              put_event(parent);
+ }
+ /*
+@@ -5559,11 +5541,6 @@ int perf_event_release_kernel(struct perf_event *event)
+               if (tmp == child) {
+                       perf_remove_from_context(child, DETACH_GROUP);
+                       list_move(&child->child_list, &free_list);
+-                      /*
+-                       * This matches the refcount bump in inherit_event();
+-                       * this can't be the last reference.
+-                       */
+-                      put_event(event);
+               } else {
+                       var = &ctx->refcount;
+               }
+@@ -5589,7 +5566,8 @@ int perf_event_release_kernel(struct perf_event *event)
+               void *var = &child->ctx->refcount;
+               list_del(&child->child_list);
+-              free_event(child);
++              /* Last reference unless ->pending_task work is pending */
++              put_event(child);
+               /*
+                * Wake any perf_event_free_task() waiting for this event to be
+@@ -5600,7 +5578,11 @@ int perf_event_release_kernel(struct perf_event *event)
+       }
+ no_ctx:
+-      put_event(event); /* Must be the 'last' reference */
++      /*
++       * Last reference unless ->pending_task work is pending on this event
++       * or any of its children.
++       */
++      put_event(event);
+       return 0;
+ }
+ EXPORT_SYMBOL_GPL(perf_event_release_kernel);
+@@ -7014,12 +6996,6 @@ static void perf_pending_task(struct callback_head *head)
+       struct perf_event *event = container_of(head, struct perf_event, pending_task);
+       int rctx;
+-      /*
+-       * All accesses to the event must belong to the same implicit RCU read-side
+-       * critical section as the ->pending_work reset. See comment in
+-       * perf_pending_task_sync().
+-       */
+-      rcu_read_lock();
+       /*
+        * If we 'fail' here, that's OK, it means recursion is already disabled
+        * and we won't recurse 'further'.
+@@ -7030,9 +7006,8 @@ static void perf_pending_task(struct callback_head *head)
+               event->pending_work = 0;
+               perf_sigtrap(event);
+               local_dec(&event->ctx->nr_no_switch_fast);
+-              rcuwait_wake_up(&event->pending_work_wait);
+       }
+-      rcu_read_unlock();
++      put_event(event);
+       if (rctx >= 0)
+               perf_swevent_put_recursion_context(rctx);
+@@ -9978,6 +9953,7 @@ static int __perf_event_overflow(struct perf_event *event,
+                   !task_work_add(current, &event->pending_task, notify_mode)) {
+                       event->pending_work = pending_id;
+                       local_inc(&event->ctx->nr_no_switch_fast);
++                      WARN_ON_ONCE(!atomic_long_inc_not_zero(&event->refcount));
+                       event->pending_addr = 0;
+                       if (valid_sample && (data->sample_flags & PERF_SAMPLE_ADDR))
+@@ -12325,7 +12301,6 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
+       init_irq_work(&event->pending_irq, perf_pending_irq);
+       event->pending_disable_irq = IRQ_WORK_INIT_HARD(perf_pending_disable);
+       init_task_work(&event->pending_task, perf_pending_task);
+-      rcuwait_init(&event->pending_work_wait);
+       mutex_init(&event->mmap_mutex);
+       raw_spin_lock_init(&event->addr_filters.lock);
+@@ -13466,8 +13441,7 @@ perf_event_exit_event(struct perf_event *event, struct perf_event_context *ctx)
+                * Kick perf_poll() for is_event_hup();
+                */
+               perf_event_wakeup(parent_event);
+-              free_event(event);
+-              put_event(parent_event);
++              put_event(event);
+               return;
+       }
+@@ -13585,13 +13559,11 @@ static void perf_free_event(struct perf_event *event,
+       list_del_init(&event->child_list);
+       mutex_unlock(&parent->child_mutex);
+-      put_event(parent);
+-
+       raw_spin_lock_irq(&ctx->lock);
+       perf_group_detach(event);
+       list_del_event(event, ctx);
+       raw_spin_unlock_irq(&ctx->lock);
+-      free_event(event);
++      put_event(event);
+ }
+ /*
+-- 
+2.39.5
+
diff --git a/queue-6.14/s390-cpumf-fix-double-free-on-error-in-cpumf_pmu_eve.patch b/queue-6.14/s390-cpumf-fix-double-free-on-error-in-cpumf_pmu_eve.patch
new file mode 100644 (file)
index 0000000..f7de493
--- /dev/null
@@ -0,0 +1,126 @@
+From 5ef6afa8f73232698e66b9e2702d42d8253f41d0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 10:03:53 +0200
+Subject: s390/cpumf: Fix double free on error in cpumf_pmu_event_init()
+
+From: Thomas Richter <tmricht@linux.ibm.com>
+
+[ Upstream commit aa1ac98268cd1f380c713f07e39b1fa1d5c7650c ]
+
+In PMU event initialization functions
+ - cpumsf_pmu_event_init()
+ - cpumf_pmu_event_init()
+ - cfdiag_event_init()
+the partially created event had to be removed when an error was detected.
+The event::event_init() member function had to release all resources
+it allocated in case of error. event::destroy() had to be called
+on freeing an event after it was successfully created and
+event::event_init() returned success.
+
+With
+
+commit c70ca298036c ("perf/core: Simplify the perf_event_alloc() error path")
+
+this is not necessary anymore. The performance subsystem common
+code now always calls event::destroy() to clean up the allocated
+resources created during event initialization.
+
+Remove the event::destroy() invocation in PMU event initialization
+or that function is called twice for each event that runs into an
+error condition in event creation.
+
+This is the kernel log entry which shows up without the fix:
+
+------------[ cut here ]------------
+refcount_t: underflow; use-after-free.
+WARNING: CPU: 0 PID: 43388 at lib/refcount.c:87        refcount_dec_not_one+0x74/0x90
+CPU: 0 UID: 0 PID: 43388 Comm: perf Not tainted 6.15.0-20250407.rc1.git0.300.fc41.s390x+git #1 NONE
+Hardware name: IBM 3931 A01 704 (LPAR)
+Krnl PSW : 0704c00180000000 00000209cb2c1b88 (refcount_dec_not_one+0x78/0x90)
+           R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:0 PM:0 RI:0 EA:3
+Krnl GPRS: 0000020900000027 0000020900000023 0000000000000026 0000018900000000
+           00000004a2200a00 0000000000000000 0000000000000057 ffffffffffffffea
+           00000002b386c600 00000002b3f5b3e0 00000209cc51f140 00000209cc7fc550
+           0000000001449d38 ffffffffffffffff 00000209cb2c1b84 00000189d67dfb80
+Krnl Code: 00000209cb2c1b78: c02000506727      larl    %r2,00000209cbcce9c6
+           00000209cb2c1b7e: c0e5ffbd4431      brasl   %r14,00000209caa6a3e0
+          #00000209cb2c1b84: af000000          mc      0,0
+          >00000209cb2c1b88: a7480001          lhi     %r4,1
+           00000209cb2c1b8c: ebeff0a00004      lmg     %r14,%r15,160(%r15)
+           00000209cb2c1b92: ec243fbf0055      risbg   %r2,%r4,63,191,0
+           00000209cb2c1b98: 07fe              bcr     15,%r14
+           00000209cb2c1b9a: 47000700          bc      0,1792
+Call Trace:
+ [<00000209cb2c1b88>] refcount_dec_not_one+0x78/0x90
+ [<00000209cb2c1dc4>] refcount_dec_and_mutex_lock+0x24/0x90
+ [<00000209caa3c29e>] hw_perf_event_destroy+0x2e/0x80
+ [<00000209cacaf8b4>] __free_event+0x74/0x270
+ [<00000209cacb47c4>] perf_event_alloc.part.0+0x4a4/0x730
+ [<00000209cacbf3e8>] __do_sys_perf_event_open+0x248/0xc20
+ [<00000209cacc14a4>] __s390x_sys_perf_event_open+0x44/0x50
+ [<00000209cb8114de>] __do_syscall+0x12e/0x260
+ [<00000209cb81ce34>] system_call+0x74/0x98
+Last Breaking-Event-Address:
+ [<00000209caa6a4d2>] __warn_printk+0xf2/0x100
+---[ end trace 0000000000000000 ]---
+
+Fixes: c70ca298036c ("perf/core: Simplify the perf_event_alloc() error path")
+Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
+Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
+Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/s390/kernel/perf_cpum_cf.c | 9 +--------
+ arch/s390/kernel/perf_cpum_sf.c | 3 ---
+ 2 files changed, 1 insertion(+), 11 deletions(-)
+
+diff --git a/arch/s390/kernel/perf_cpum_cf.c b/arch/s390/kernel/perf_cpum_cf.c
+index 33205dd410e47..60a60185b1d4d 100644
+--- a/arch/s390/kernel/perf_cpum_cf.c
++++ b/arch/s390/kernel/perf_cpum_cf.c
+@@ -858,18 +858,13 @@ static int cpumf_pmu_event_type(struct perf_event *event)
+ static int cpumf_pmu_event_init(struct perf_event *event)
+ {
+       unsigned int type = event->attr.type;
+-      int err;
++      int err = -ENOENT;
+       if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_RAW)
+               err = __hw_perf_event_init(event, type);
+       else if (event->pmu->type == type)
+               /* Registered as unknown PMU */
+               err = __hw_perf_event_init(event, cpumf_pmu_event_type(event));
+-      else
+-              return -ENOENT;
+-
+-      if (unlikely(err) && event->destroy)
+-              event->destroy(event);
+       return err;
+ }
+@@ -1819,8 +1814,6 @@ static int cfdiag_event_init(struct perf_event *event)
+       event->destroy = hw_perf_event_destroy;
+       err = cfdiag_event_init2(event);
+-      if (unlikely(err))
+-              event->destroy(event);
+ out:
+       return err;
+ }
+diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c
+index 5f60248cb4687..ad22799d8a7d9 100644
+--- a/arch/s390/kernel/perf_cpum_sf.c
++++ b/arch/s390/kernel/perf_cpum_sf.c
+@@ -885,9 +885,6 @@ static int cpumsf_pmu_event_init(struct perf_event *event)
+               event->attr.exclude_idle = 0;
+       err = __hw_perf_event_init(event);
+-      if (unlikely(err))
+-              if (event->destroy)
+-                      event->destroy(event);
+       return err;
+ }
+-- 
+2.39.5
+
diff --git a/queue-6.14/selftests-futex-futex_waitv-wouldblock-test-should-f.patch b/queue-6.14/selftests-futex-futex_waitv-wouldblock-test-should-f.patch
new file mode 100644 (file)
index 0000000..aa6adb1
--- /dev/null
@@ -0,0 +1,42 @@
+From 78af8e2c646bed3018b644fbb244da8e75575824 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 4 Apr 2025 22:12:20 +0000
+Subject: selftests/futex: futex_waitv wouldblock test should fail
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Edward Liaw <edliaw@google.com>
+
+[ Upstream commit 7d50e00fef2832e98d7e06bbfc85c1d66ee110ca ]
+
+Testcase should fail if -EWOULDBLOCK is not returned when expected value
+differs from actual value from the waiter.
+
+Link: https://lore.kernel.org/r/20250404221225.1596324-1-edliaw@google.com
+Fixes: 9d57f7c79748920636f8293d2f01192d702fe390 ("selftests: futex: Test sys_futex_waitv() wouldblock")
+Signed-off-by: Edward Liaw <edliaw@google.com>
+Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: André Almeida <andrealmeid@igalia.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../testing/selftests/futex/functional/futex_wait_wouldblock.c  | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c b/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c
+index 7d7a6a06cdb75..2d8230da90642 100644
+--- a/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c
++++ b/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c
+@@ -98,7 +98,7 @@ int main(int argc, char *argv[])
+       info("Calling futex_waitv on f1: %u @ %p with val=%u\n", f1, &f1, f1+1);
+       res = futex_waitv(&waitv, 1, 0, &to, CLOCK_MONOTONIC);
+       if (!res || errno != EWOULDBLOCK) {
+-              ksft_test_result_pass("futex_waitv returned: %d %s\n",
++              ksft_test_result_fail("futex_waitv returned: %d %s\n",
+                                     res ? errno : res,
+                                     res ? strerror(errno) : "");
+               ret = RET_FAIL;
+-- 
+2.39.5
+
index 5d6c73e1ad90b057c5dba21c5dea20b9cff79395..7276205f963392a0267f69636144a76fb1f02a07 100644 (file)
@@ -1 +1,48 @@
 asoc-intel-adl-add-2xrt1316-audio-configuration.patch
+cgroup-cpuset-fix-incorrect-isolated_cpus-update-in-.patch
+cgroup-cpuset-fix-error-handling-in-remote_partition.patch
+cgroup-cpuset-fix-race-between-newly-created-partiti.patch
+tracing-fprobe-cleanup-fprobe-hash-when-module-unloa.patch
+gpiolib-of-fix-the-choice-for-ingenic-nand-quirk.patch
+selftests-futex-futex_waitv-wouldblock-test-should-f.patch
+ublk-fix-handling-recovery-reissue-in-ublk_abort_que.patch
+drm-virtio-fix-flickering-issue-seen-with-imported-d.patch
+drm-i915-disable-rpg-during-live-selftest.patch
+x86-acpi-don-t-limit-cpus-to-1-for-xen-pv-guests-due.patch
+net-ethtool-fix-ethtool_ringparam_get_cfg-returns-a-.patch
+drm-xe-hw_engine-define-sysfs_ops-on-all-directories.patch
+drm-xe-restore-eio-errno-return-when-guc-pc-start-fa.patch
+ata-pata_pxa-fix-potential-null-pointer-dereference-.patch
+objtool-fix-insn_context_switch-handling-in-validate.patch
+tipc-fix-memory-leak-in-tipc_link_xmit.patch
+codel-remove-sch-q.qlen-check-before-qdisc_tree_redu.patch
+net-tls-explicitly-disallow-disconnect.patch
+octeontx2-pf-qos-fix-vf-root-node-parent-queue-index.patch
+tc-ensure-we-have-enough-buffer-space-when-sending-f.patch
+net-ethtool-don-t-call-.cleanup_data-when-prepare_da.patch
+drm-tests-modeset-fix-drm_display_mode-memory-leak.patch
+drm-tests-helpers-create-kunit-helper-to-destroy-a-d.patch
+drm-tests-cmdline-fix-drm_display_mode-memory-leak.patch
+drm-tests-modes-fix-drm_display_mode-memory-leak.patch
+drm-tests-probe-helper-fix-drm_display_mode-memory-l.patch
+net-libwx-handle-page_pool_dev_alloc_pages-error.patch
+cifs-fix-support-for-wsl-style-symlinks.patch
+ata-sata_sx4-add-error-handling-in-pdc20621_i2c_read.patch
+drm-i915-huc-fix-fence-not-released-on-early-probe-e.patch
+s390-cpumf-fix-double-free-on-error-in-cpumf_pmu_eve.patch
+nvmet-fcloop-swap-list_add_tail-arguments.patch
+net_sched-sch_sfq-use-a-temporary-work-area-for-vali.patch
+net_sched-sch_sfq-move-the-limit-validation.patch
+x86-cpu-avoid-running-off-the-end-of-an-amd-erratum-.patch
+smb-client-fix-uaf-in-decryption-with-multichannel.patch
+net-phy-move-phy_link_change-prior-to-mdio_bus_phy_m.patch
+net-phy-allow-mdio-bus-pm-ops-to-start-stop-state-ma.patch
+ipv6-align-behavior-across-nexthops-during-path-sele.patch
+net-ppp-add-bound-checking-for-skb-data-on-ppp_sync_.patch
+nft_set_pipapo-fix-incorrect-avx2-match-of-5th-field.patch
+ethtool-cmis_cdb-fix-incorrect-read-write-length-ext.patch
+iommu-exynos-fix-suspend-resume-with-identity-domain.patch
+iommu-mediatek-fix-null-pointer-deference-in-mtk_iom.patch
+net-libwx-fix-the-wrong-rx-descriptor-field.patch
+perf-core-simplify-the-perf_event_alloc-error-path.patch
+perf-fix-hang-while-freeing-sigtrap-event.patch
diff --git a/queue-6.14/smb-client-fix-uaf-in-decryption-with-multichannel.patch b/queue-6.14/smb-client-fix-uaf-in-decryption-with-multichannel.patch
new file mode 100644 (file)
index 0000000..2500e43
--- /dev/null
@@ -0,0 +1,164 @@
+From f9659181bd45bb484c3d16e37d406a0db2a51a63 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 11:14:21 -0300
+Subject: smb: client: fix UAF in decryption with multichannel
+
+From: Paulo Alcantara <pc@manguebit.com>
+
+[ Upstream commit 9502dd5c7029902f4a425bf959917a5a9e7c0e50 ]
+
+After commit f7025d861694 ("smb: client: allocate crypto only for
+primary server") and commit b0abcd65ec54 ("smb: client: fix UAF in
+async decryption"), the channels started reusing AEAD TFM from primary
+channel to perform synchronous decryption, but that can't done as
+there could be multiple cifsd threads (one per channel) simultaneously
+accessing it to perform decryption.
+
+This fixes the following KASAN splat when running fstest generic/249
+with 'vers=3.1.1,multichannel,max_channels=4,seal' against Windows
+Server 2022:
+
+BUG: KASAN: slab-use-after-free in gf128mul_4k_lle+0xba/0x110
+Read of size 8 at addr ffff8881046c18a0 by task cifsd/986
+CPU: 3 UID: 0 PID: 986 Comm: cifsd Not tainted 6.15.0-rc1 #1
+PREEMPT(voluntary)
+Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-3.fc41
+04/01/2014
+Call Trace:
+ <TASK>
+ dump_stack_lvl+0x5d/0x80
+ print_report+0x156/0x528
+ ? gf128mul_4k_lle+0xba/0x110
+ ? __virt_addr_valid+0x145/0x300
+ ? __phys_addr+0x46/0x90
+ ? gf128mul_4k_lle+0xba/0x110
+ kasan_report+0xdf/0x1a0
+ ? gf128mul_4k_lle+0xba/0x110
+ gf128mul_4k_lle+0xba/0x110
+ ghash_update+0x189/0x210
+ shash_ahash_update+0x295/0x370
+ ? __pfx_shash_ahash_update+0x10/0x10
+ ? __pfx_shash_ahash_update+0x10/0x10
+ ? __pfx_extract_iter_to_sg+0x10/0x10
+ ? ___kmalloc_large_node+0x10e/0x180
+ ? __asan_memset+0x23/0x50
+ crypto_ahash_update+0x3c/0xc0
+ gcm_hash_assoc_remain_continue+0x93/0xc0
+ crypt_message+0xe09/0xec0 [cifs]
+ ? __pfx_crypt_message+0x10/0x10 [cifs]
+ ? _raw_spin_unlock+0x23/0x40
+ ? __pfx_cifs_readv_from_socket+0x10/0x10 [cifs]
+ decrypt_raw_data+0x229/0x380 [cifs]
+ ? __pfx_decrypt_raw_data+0x10/0x10 [cifs]
+ ? __pfx_cifs_read_iter_from_socket+0x10/0x10 [cifs]
+ smb3_receive_transform+0x837/0xc80 [cifs]
+ ? __pfx_smb3_receive_transform+0x10/0x10 [cifs]
+ ? __pfx___might_resched+0x10/0x10
+ ? __pfx_smb3_is_transform_hdr+0x10/0x10 [cifs]
+ cifs_demultiplex_thread+0x692/0x1570 [cifs]
+ ? __pfx_cifs_demultiplex_thread+0x10/0x10 [cifs]
+ ? rcu_is_watching+0x20/0x50
+ ? rcu_lockdep_current_cpu_online+0x62/0xb0
+ ? find_held_lock+0x32/0x90
+ ? kvm_sched_clock_read+0x11/0x20
+ ? local_clock_noinstr+0xd/0xd0
+ ? trace_irq_enable.constprop.0+0xa8/0xe0
+ ? __pfx_cifs_demultiplex_thread+0x10/0x10 [cifs]
+ kthread+0x1fe/0x380
+ ? kthread+0x10f/0x380
+ ? __pfx_kthread+0x10/0x10
+ ? local_clock_noinstr+0xd/0xd0
+ ? ret_from_fork+0x1b/0x60
+ ? local_clock+0x15/0x30
+ ? lock_release+0x29b/0x390
+ ? rcu_is_watching+0x20/0x50
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork+0x31/0x60
+ ? __pfx_kthread+0x10/0x10
+ ret_from_fork_asm+0x1a/0x30
+ </TASK>
+
+Tested-by: David Howells <dhowells@redhat.com>
+Reported-by: Steve French <stfrench@microsoft.com>
+Closes: https://lore.kernel.org/r/CAH2r5mu6Yc0-RJXM3kFyBYUB09XmXBrNodOiCVR4EDrmxq5Szg@mail.gmail.com
+Fixes: f7025d861694 ("smb: client: allocate crypto only for primary server")
+Fixes: b0abcd65ec54 ("smb: client: fix UAF in async decryption")
+Signed-off-by: Paulo Alcantara (Red Hat) <pc@manguebit.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/smb/client/cifsencrypt.c | 16 +++++-----------
+ fs/smb/client/smb2ops.c     |  6 +++---
+ fs/smb/client/smb2pdu.c     | 11 ++---------
+ 3 files changed, 10 insertions(+), 23 deletions(-)
+
+diff --git a/fs/smb/client/cifsencrypt.c b/fs/smb/client/cifsencrypt.c
+index e69968e88fe72..35892df7335c7 100644
+--- a/fs/smb/client/cifsencrypt.c
++++ b/fs/smb/client/cifsencrypt.c
+@@ -704,18 +704,12 @@ cifs_crypto_secmech_release(struct TCP_Server_Info *server)
+       cifs_free_hash(&server->secmech.md5);
+       cifs_free_hash(&server->secmech.sha512);
+-      if (!SERVER_IS_CHAN(server)) {
+-              if (server->secmech.enc) {
+-                      crypto_free_aead(server->secmech.enc);
+-                      server->secmech.enc = NULL;
+-              }
+-
+-              if (server->secmech.dec) {
+-                      crypto_free_aead(server->secmech.dec);
+-                      server->secmech.dec = NULL;
+-              }
+-      } else {
++      if (server->secmech.enc) {
++              crypto_free_aead(server->secmech.enc);
+               server->secmech.enc = NULL;
++      }
++      if (server->secmech.dec) {
++              crypto_free_aead(server->secmech.dec);
+               server->secmech.dec = NULL;
+       }
+ }
+diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
+index 4dd11eafb69d9..7aeac8dd9a1d1 100644
+--- a/fs/smb/client/smb2ops.c
++++ b/fs/smb/client/smb2ops.c
+@@ -4549,9 +4549,9 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
+                       return rc;
+               }
+       } else {
+-              if (unlikely(!server->secmech.dec))
+-                      return -EIO;
+-
++              rc = smb3_crypto_aead_allocate(server);
++              if (unlikely(rc))
++                      return rc;
+               tfm = server->secmech.dec;
+       }
+diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
+index f9c521b3c65ee..163b8fea47e8a 100644
+--- a/fs/smb/client/smb2pdu.c
++++ b/fs/smb/client/smb2pdu.c
+@@ -1251,15 +1251,8 @@ SMB2_negotiate(const unsigned int xid,
+                       cifs_server_dbg(VFS, "Missing expected negotiate contexts\n");
+       }
+-      if (server->cipher_type && !rc) {
+-              if (!SERVER_IS_CHAN(server)) {
+-                      rc = smb3_crypto_aead_allocate(server);
+-              } else {
+-                      /* For channels, just reuse the primary server crypto secmech. */
+-                      server->secmech.enc = server->primary_server->secmech.enc;
+-                      server->secmech.dec = server->primary_server->secmech.dec;
+-              }
+-      }
++      if (server->cipher_type && !rc)
++              rc = smb3_crypto_aead_allocate(server);
+ neg_exit:
+       free_rsp_buf(resp_buftype, rsp);
+       return rc;
+-- 
+2.39.5
+
diff --git a/queue-6.14/tc-ensure-we-have-enough-buffer-space-when-sending-f.patch b/queue-6.14/tc-ensure-we-have-enough-buffer-space-when-sending-f.patch
new file mode 100644 (file)
index 0000000..fb51f04
--- /dev/null
@@ -0,0 +1,162 @@
+From 21c02c7796a8d7801f70ba9165de1e1f916e3b0a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 12:55:34 +0200
+Subject: tc: Ensure we have enough buffer space when sending filter netlink
+ notifications
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@redhat.com>
+
+[ Upstream commit 369609fc6272c2f6ad666ba4fd913f3baf32908f ]
+
+The tfilter_notify() and tfilter_del_notify() functions assume that
+NLMSG_GOODSIZE is always enough to dump the filter chain. This is not
+always the case, which can lead to silent notify failures (because the
+return code of tfilter_notify() is not always checked). In particular,
+this can lead to NLM_F_ECHO not being honoured even though an action
+succeeds, which forces userspace to create workarounds[0].
+
+Fix this by increasing the message size if dumping the filter chain into
+the allocated skb fails. Use the size of the incoming skb as a size hint
+if set, so we can start at a larger value when appropriate.
+
+To trigger this, run the following commands:
+
+ # ip link add type veth
+ # tc qdisc replace dev veth0 root handle 1: fq_codel
+ # tc -echo filter add dev veth0 parent 1: u32 match u32 0 0 $(for i in $(seq 32); do echo action pedit munge ip dport set 22; done)
+
+Before this fix, tc just returns:
+
+Not a filter(cmd 2)
+
+After the fix, we get the correct echo:
+
+added filter dev veth0 parent 1: protocol all pref 49152 u32 chain 0 fh 800::800 order 2048 key ht 800 bkt 0 terminal flowid not_in_hw
+  match 00000000/00000000 at 0
+       action order 1:  pedit action pass keys 1
+       index 1 ref 1 bind 1
+       key #0  at 20: val 00000016 mask ffff0000
+[repeated 32 times]
+
+[0] https://github.com/openvswitch/ovs/commit/106ef21860c935e5e0017a88bf42b94025c4e511
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Reported-by: Frode Nordahl <frode.nordahl@canonical.com>
+Closes: https://bugs.launchpad.net/ubuntu/+source/openvswitch/+bug/2018500
+Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
+Reviewed-by: Jiri Pirko <jiri@nvidia.com>
+Link: https://patch.msgid.link/20250407105542.16601-1-toke@redhat.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/cls_api.c | 66 ++++++++++++++++++++++++++++++---------------
+ 1 file changed, 45 insertions(+), 21 deletions(-)
+
+diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
+index 4f648af8cfaaf..ecec0a1e1c1a0 100644
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -2057,6 +2057,7 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
+       struct tcmsg *tcm;
+       struct nlmsghdr  *nlh;
+       unsigned char *b = skb_tail_pointer(skb);
++      int ret = -EMSGSIZE;
+       nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags);
+       if (!nlh)
+@@ -2101,11 +2102,45 @@ static int tcf_fill_node(struct net *net, struct sk_buff *skb,
+       return skb->len;
++cls_op_not_supp:
++      ret = -EOPNOTSUPP;
+ out_nlmsg_trim:
+ nla_put_failure:
+-cls_op_not_supp:
+       nlmsg_trim(skb, b);
+-      return -1;
++      return ret;
++}
++
++static struct sk_buff *tfilter_notify_prep(struct net *net,
++                                         struct sk_buff *oskb,
++                                         struct nlmsghdr *n,
++                                         struct tcf_proto *tp,
++                                         struct tcf_block *block,
++                                         struct Qdisc *q, u32 parent,
++                                         void *fh, int event,
++                                         u32 portid, bool rtnl_held,
++                                         struct netlink_ext_ack *extack)
++{
++      unsigned int size = oskb ? max(NLMSG_GOODSIZE, oskb->len) : NLMSG_GOODSIZE;
++      struct sk_buff *skb;
++      int ret;
++
++retry:
++      skb = alloc_skb(size, GFP_KERNEL);
++      if (!skb)
++              return ERR_PTR(-ENOBUFS);
++
++      ret = tcf_fill_node(net, skb, tp, block, q, parent, fh, portid,
++                          n->nlmsg_seq, n->nlmsg_flags, event, false,
++                          rtnl_held, extack);
++      if (ret <= 0) {
++              kfree_skb(skb);
++              if (ret == -EMSGSIZE) {
++                      size += NLMSG_GOODSIZE;
++                      goto retry;
++              }
++              return ERR_PTR(-EINVAL);
++      }
++      return skb;
+ }
+ static int tfilter_notify(struct net *net, struct sk_buff *oskb,
+@@ -2121,16 +2156,10 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb,
+       if (!unicast && !rtnl_notify_needed(net, n->nlmsg_flags, RTNLGRP_TC))
+               return 0;
+-      skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
+-      if (!skb)
+-              return -ENOBUFS;
+-
+-      if (tcf_fill_node(net, skb, tp, block, q, parent, fh, portid,
+-                        n->nlmsg_seq, n->nlmsg_flags, event,
+-                        false, rtnl_held, extack) <= 0) {
+-              kfree_skb(skb);
+-              return -EINVAL;
+-      }
++      skb = tfilter_notify_prep(net, oskb, n, tp, block, q, parent, fh, event,
++                                portid, rtnl_held, extack);
++      if (IS_ERR(skb))
++              return PTR_ERR(skb);
+       if (unicast)
+               err = rtnl_unicast(skb, net, portid);
+@@ -2153,16 +2182,11 @@ static int tfilter_del_notify(struct net *net, struct sk_buff *oskb,
+       if (!rtnl_notify_needed(net, n->nlmsg_flags, RTNLGRP_TC))
+               return tp->ops->delete(tp, fh, last, rtnl_held, extack);
+-      skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
+-      if (!skb)
+-              return -ENOBUFS;
+-
+-      if (tcf_fill_node(net, skb, tp, block, q, parent, fh, portid,
+-                        n->nlmsg_seq, n->nlmsg_flags, RTM_DELTFILTER,
+-                        false, rtnl_held, extack) <= 0) {
++      skb = tfilter_notify_prep(net, oskb, n, tp, block, q, parent, fh,
++                                RTM_DELTFILTER, portid, rtnl_held, extack);
++      if (IS_ERR(skb)) {
+               NL_SET_ERR_MSG(extack, "Failed to build del event notification");
+-              kfree_skb(skb);
+-              return -EINVAL;
++              return PTR_ERR(skb);
+       }
+       err = tp->ops->delete(tp, fh, last, rtnl_held, extack);
+-- 
+2.39.5
+
diff --git a/queue-6.14/tipc-fix-memory-leak-in-tipc_link_xmit.patch b/queue-6.14/tipc-fix-memory-leak-in-tipc_link_xmit.patch
new file mode 100644 (file)
index 0000000..6c5bd11
--- /dev/null
@@ -0,0 +1,40 @@
+From a492ceb1f2e254f941025e0e34ce3ae15e3d6305 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 3 Apr 2025 09:24:31 +0000
+Subject: tipc: fix memory leak in tipc_link_xmit
+
+From: Tung Nguyen <tung.quang.nguyen@est.tech>
+
+[ Upstream commit 69ae94725f4fc9e75219d2d69022029c5b24bc9a ]
+
+In case the backlog transmit queue for system-importance messages is overloaded,
+tipc_link_xmit() returns -ENOBUFS but the skb list is not purged. This leads to
+memory leak and failure when a skb is allocated.
+
+This commit fixes this issue by purging the skb list before tipc_link_xmit()
+returns.
+
+Fixes: 365ad353c256 ("tipc: reduce risk of user starvation during link congestion")
+Signed-off-by: Tung Nguyen <tung.quang.nguyen@est.tech>
+Link: https://patch.msgid.link/20250403092431.514063-1-tung.quang.nguyen@est.tech
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/link.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/net/tipc/link.c b/net/tipc/link.c
+index 5c2088a469cea..5689e1f485479 100644
+--- a/net/tipc/link.c
++++ b/net/tipc/link.c
+@@ -1046,6 +1046,7 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list,
+       if (unlikely(l->backlog[imp].len >= l->backlog[imp].limit)) {
+               if (imp == TIPC_SYSTEM_IMPORTANCE) {
+                       pr_warn("%s<%s>, link overflow", link_rst_msg, l->name);
++                      __skb_queue_purge(list);
+                       return -ENOBUFS;
+               }
+               rc = link_schedule_user(l, hdr);
+-- 
+2.39.5
+
diff --git a/queue-6.14/tracing-fprobe-cleanup-fprobe-hash-when-module-unloa.patch b/queue-6.14/tracing-fprobe-cleanup-fprobe-hash-when-module-unloa.patch
new file mode 100644 (file)
index 0000000..9801dfb
--- /dev/null
@@ -0,0 +1,153 @@
+From df4b013184b30987f9ee3a0cf2a2f31387d140ab Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Apr 2025 00:35:44 +0900
+Subject: tracing: fprobe: Cleanup fprobe hash when module unloading
+
+From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+
+[ Upstream commit a3dc2983ca7b90fd35f978502de6d4664d965cfb ]
+
+Cleanup fprobe address hash table on module unloading because the
+target symbols will be disappeared when unloading module and not
+sure the same symbol is mapped on the same address.
+
+Note that this is at least disables the fprobes if a part of target
+symbols on the unloaded modules. Unlike kprobes, fprobe does not
+re-enable the probe point by itself. To do that, the caller should
+take care register/unregister fprobe when loading/unloading modules.
+This simplifies the fprobe state managememt related to the module
+loading/unloading.
+
+Link: https://lore.kernel.org/all/174343534473.843280.13988101014957210732.stgit@devnote2/
+
+Fixes: 4346ba160409 ("fprobe: Rewrite fprobe on function-graph tracer")
+Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ kernel/trace/fprobe.c | 103 +++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 101 insertions(+), 2 deletions(-)
+
+diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c
+index 33082c4e8154e..c4bf59d625f75 100644
+--- a/kernel/trace/fprobe.c
++++ b/kernel/trace/fprobe.c
+@@ -89,8 +89,11 @@ static bool delete_fprobe_node(struct fprobe_hlist_node *node)
+ {
+       lockdep_assert_held(&fprobe_mutex);
+-      WRITE_ONCE(node->fp, NULL);
+-      hlist_del_rcu(&node->hlist);
++      /* Avoid double deleting */
++      if (READ_ONCE(node->fp) != NULL) {
++              WRITE_ONCE(node->fp, NULL);
++              hlist_del_rcu(&node->hlist);
++      }
+       return !!find_first_fprobe_node(node->addr);
+ }
+@@ -411,6 +414,102 @@ static void fprobe_graph_remove_ips(unsigned long *addrs, int num)
+               ftrace_set_filter_ips(&fprobe_graph_ops.ops, addrs, num, 1, 0);
+ }
++#ifdef CONFIG_MODULES
++
++#define FPROBE_IPS_BATCH_INIT 8
++/* instruction pointer address list */
++struct fprobe_addr_list {
++      int index;
++      int size;
++      unsigned long *addrs;
++};
++
++static int fprobe_addr_list_add(struct fprobe_addr_list *alist, unsigned long addr)
++{
++      unsigned long *addrs;
++
++      if (alist->index >= alist->size)
++              return -ENOMEM;
++
++      alist->addrs[alist->index++] = addr;
++      if (alist->index < alist->size)
++              return 0;
++
++      /* Expand the address list */
++      addrs = kcalloc(alist->size * 2, sizeof(*addrs), GFP_KERNEL);
++      if (!addrs)
++              return -ENOMEM;
++
++      memcpy(addrs, alist->addrs, alist->size * sizeof(*addrs));
++      alist->size *= 2;
++      kfree(alist->addrs);
++      alist->addrs = addrs;
++
++      return 0;
++}
++
++static void fprobe_remove_node_in_module(struct module *mod, struct hlist_head *head,
++                                      struct fprobe_addr_list *alist)
++{
++      struct fprobe_hlist_node *node;
++      int ret = 0;
++
++      hlist_for_each_entry_rcu(node, head, hlist) {
++              if (!within_module(node->addr, mod))
++                      continue;
++              if (delete_fprobe_node(node))
++                      continue;
++              /*
++               * If failed to update alist, just continue to update hlist.
++               * Therefore, at list user handler will not hit anymore.
++               */
++              if (!ret)
++                      ret = fprobe_addr_list_add(alist, node->addr);
++      }
++}
++
++/* Handle module unloading to manage fprobe_ip_table. */
++static int fprobe_module_callback(struct notifier_block *nb,
++                                unsigned long val, void *data)
++{
++      struct fprobe_addr_list alist = {.size = FPROBE_IPS_BATCH_INIT};
++      struct module *mod = data;
++      int i;
++
++      if (val != MODULE_STATE_GOING)
++              return NOTIFY_DONE;
++
++      alist.addrs = kcalloc(alist.size, sizeof(*alist.addrs), GFP_KERNEL);
++      /* If failed to alloc memory, we can not remove ips from hash. */
++      if (!alist.addrs)
++              return NOTIFY_DONE;
++
++      mutex_lock(&fprobe_mutex);
++      for (i = 0; i < FPROBE_IP_TABLE_SIZE; i++)
++              fprobe_remove_node_in_module(mod, &fprobe_ip_table[i], &alist);
++
++      if (alist.index < alist.size && alist.index > 0)
++              ftrace_set_filter_ips(&fprobe_graph_ops.ops,
++                                    alist.addrs, alist.index, 1, 0);
++      mutex_unlock(&fprobe_mutex);
++
++      kfree(alist.addrs);
++
++      return NOTIFY_DONE;
++}
++
++static struct notifier_block fprobe_module_nb = {
++      .notifier_call = fprobe_module_callback,
++      .priority = 0,
++};
++
++static int __init init_fprobe_module(void)
++{
++      return register_module_notifier(&fprobe_module_nb);
++}
++early_initcall(init_fprobe_module);
++#endif
++
+ static int symbols_cmp(const void *a, const void *b)
+ {
+       const char **str_a = (const char **) a;
+-- 
+2.39.5
+
diff --git a/queue-6.14/ublk-fix-handling-recovery-reissue-in-ublk_abort_que.patch b/queue-6.14/ublk-fix-handling-recovery-reissue-in-ublk_abort_que.patch
new file mode 100644 (file)
index 0000000..98ebac8
--- /dev/null
@@ -0,0 +1,91 @@
+From 3617e11b14d744c89344ff1d7ac92d9c57fd69d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 09:14:41 +0800
+Subject: ublk: fix handling recovery & reissue in ublk_abort_queue()
+
+From: Ming Lei <ming.lei@redhat.com>
+
+[ Upstream commit 6ee6bd5d4fce502a5b5a2ea805e9ff16e6aa890f ]
+
+Commit 8284066946e6 ("ublk: grab request reference when the request is handled
+by userspace") doesn't grab request reference in case of recovery reissue.
+Then the request can be requeued & re-dispatch & failed when canceling
+uring command.
+
+If it is one zc request, the request can be freed before io_uring
+returns the zc buffer back, then cause kernel panic:
+
+[  126.773061] BUG: kernel NULL pointer dereference, address: 00000000000000c8
+[  126.773657] #PF: supervisor read access in kernel mode
+[  126.774052] #PF: error_code(0x0000) - not-present page
+[  126.774455] PGD 0 P4D 0
+[  126.774698] Oops: Oops: 0000 [#1] SMP NOPTI
+[  126.775034] CPU: 13 UID: 0 PID: 1612 Comm: kworker/u64:55 Not tainted 6.14.0_blk+ #182 PREEMPT(full)
+[  126.775676] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-1.fc39 04/01/2014
+[  126.776275] Workqueue: iou_exit io_ring_exit_work
+[  126.776651] RIP: 0010:ublk_io_release+0x14/0x130 [ublk_drv]
+
+Fixes it by always grabbing request reference for aborting the request.
+
+Reported-by: Caleb Sander Mateos <csander@purestorage.com>
+Closes: https://lore.kernel.org/linux-block/CADUfDZodKfOGUeWrnAxcZiLT+puaZX8jDHoj_sfHZCOZwhzz6A@mail.gmail.com/
+Fixes: 8284066946e6 ("ublk: grab request reference when the request is handled by userspace")
+Signed-off-by: Ming Lei <ming.lei@redhat.com>
+Link: https://lore.kernel.org/r/20250409011444.2142010-2-ming.lei@redhat.com
+Signed-off-by: Jens Axboe <axboe@kernel.dk>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/block/ublk_drv.c | 30 ++++++++++++++++++++++++++----
+ 1 file changed, 26 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
+index b7adfaddc3abb..971b793dedd03 100644
+--- a/drivers/block/ublk_drv.c
++++ b/drivers/block/ublk_drv.c
+@@ -1094,6 +1094,25 @@ static void ublk_complete_rq(struct kref *ref)
+       __ublk_complete_rq(req);
+ }
++static void ublk_do_fail_rq(struct request *req)
++{
++      struct ublk_queue *ubq = req->mq_hctx->driver_data;
++
++      if (ublk_nosrv_should_reissue_outstanding(ubq->dev))
++              blk_mq_requeue_request(req, false);
++      else
++              __ublk_complete_rq(req);
++}
++
++static void ublk_fail_rq_fn(struct kref *ref)
++{
++      struct ublk_rq_data *data = container_of(ref, struct ublk_rq_data,
++                      ref);
++      struct request *req = blk_mq_rq_from_pdu(data);
++
++      ublk_do_fail_rq(req);
++}
++
+ /*
+  * Since __ublk_rq_task_work always fails requests immediately during
+  * exiting, __ublk_fail_req() is only called from abort context during
+@@ -1107,10 +1126,13 @@ static void __ublk_fail_req(struct ublk_queue *ubq, struct ublk_io *io,
+ {
+       WARN_ON_ONCE(io->flags & UBLK_IO_FLAG_ACTIVE);
+-      if (ublk_nosrv_should_reissue_outstanding(ubq->dev))
+-              blk_mq_requeue_request(req, false);
+-      else
+-              ublk_put_req_ref(ubq, req);
++      if (ublk_need_req_ref(ubq)) {
++              struct ublk_rq_data *data = blk_mq_rq_to_pdu(req);
++
++              kref_put(&data->ref, ublk_fail_rq_fn);
++      } else {
++              ublk_do_fail_rq(req);
++      }
+ }
+ static void ubq_complete_io_cmd(struct ublk_io *io, int res,
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-acpi-don-t-limit-cpus-to-1-for-xen-pv-guests-due.patch b/queue-6.14/x86-acpi-don-t-limit-cpus-to-1-for-xen-pv-guests-due.patch
new file mode 100644 (file)
index 0000000..82b1e72
--- /dev/null
@@ -0,0 +1,67 @@
+From 0dc73586a806663b67b3da66087ed70ff7b6ec72 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 7 Apr 2025 15:24:27 +0200
+Subject: x86/acpi: Don't limit CPUs to 1 for Xen PV guests due to disabled
+ ACPI
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Petr Vaněk <arkamar@atlas.cz>
+
+[ Upstream commit 8b37357a78d7fa13d88ea822b35b40137da1c85e ]
+
+Xen disables ACPI for PV guests in DomU, which causes acpi_mps_check() to
+return 1 when CONFIG_X86_MPPARSE is not set. As a result, the local APIC is
+disabled and the guest is later limited to a single vCPU, despite being
+configured with more.
+
+This regression was introduced in version 6.9 in commit 7c0edad3643f
+("x86/cpu/topology: Rework possible CPU management"), which added an
+early check that limits CPUs to 1 if apic_is_disabled.
+
+Update the acpi_mps_check() logic to return 0 early when running as a Xen
+PV guest in DomU, preventing APIC from being disabled in this specific case
+and restoring correct multi-vCPU behaviour.
+
+Fixes: 7c0edad3643f ("x86/cpu/topology: Rework possible CPU management")
+Signed-off-by: Petr Vaněk <arkamar@atlas.cz>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Link: https://lore.kernel.org/all/20250407132445.6732-2-arkamar@atlas.cz
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/acpi/boot.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
+index dae6a73be40e1..9fa321a95eb33 100644
+--- a/arch/x86/kernel/acpi/boot.c
++++ b/arch/x86/kernel/acpi/boot.c
+@@ -23,6 +23,8 @@
+ #include <linux/serial_core.h>
+ #include <linux/pgtable.h>
++#include <xen/xen.h>
++
+ #include <asm/e820/api.h>
+ #include <asm/irqdomain.h>
+ #include <asm/pci_x86.h>
+@@ -1729,6 +1731,15 @@ int __init acpi_mps_check(void)
+ {
+ #if defined(CONFIG_X86_LOCAL_APIC) && !defined(CONFIG_X86_MPPARSE)
+ /* mptable code is not built-in*/
++
++      /*
++       * Xen disables ACPI in PV DomU guests but it still emulates APIC and
++       * supports SMP. Returning early here ensures that APIC is not disabled
++       * unnecessarily and the guest is not limited to a single vCPU.
++       */
++      if (xen_pv_domain() && !xen_initial_domain())
++              return 0;
++
+       if (acpi_disabled || acpi_noirq) {
+               pr_warn("MPS support code is not built-in, using acpi=off or acpi=noirq or pci=noacpi may have problem\n");
+               return 1;
+-- 
+2.39.5
+
diff --git a/queue-6.14/x86-cpu-avoid-running-off-the-end-of-an-amd-erratum-.patch b/queue-6.14/x86-cpu-avoid-running-off-the-end-of-an-amd-erratum-.patch
new file mode 100644 (file)
index 0000000..8f74373
--- /dev/null
@@ -0,0 +1,38 @@
+From 43fd9d7b6cfefc5f405079415c629658e6d7e7d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 9 Apr 2025 06:58:37 -0700
+Subject: x86/cpu: Avoid running off the end of an AMD erratum table
+
+From: Dave Hansen <dave.hansen@linux.intel.com>
+
+[ Upstream commit f0df00ebc57f803603f2a2e0df197e51f06fbe90 ]
+
+The NULL array terminator at the end of erratum_1386_microcode was
+removed during the switch from x86_cpu_desc to x86_cpu_id. This
+causes readers to run off the end of the array.
+
+Replace the NULL.
+
+Fixes: f3f325152673 ("x86/cpu: Move AMD erratum 1386 table over to 'x86_cpu_id'")
+Reported-by: Jiri Slaby <jirislaby@kernel.org>
+Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/cpu/amd.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
+index 54194f5995de3..ce71f49654ee3 100644
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -803,6 +803,7 @@ static void init_amd_bd(struct cpuinfo_x86 *c)
+ static const struct x86_cpu_id erratum_1386_microcode[] = {
+       X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, 0x17, 0x01), 0x2, 0x2, 0x0800126e),
+       X86_MATCH_VFM_STEPS(VFM_MAKE(X86_VENDOR_AMD, 0x17, 0x31), 0x0, 0x0, 0x08301052),
++      {}
+ };
+ static void fix_erratum_1386(struct cpuinfo_x86 *c)
+-- 
+2.39.5
+