]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for all trees
authorSasha Levin <sashal@kernel.org>
Wed, 27 May 2026 19:48:47 +0000 (15:48 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 27 May 2026 19:48:47 +0000 (15:48 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
32 files changed:
queue-5.15/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch [new file with mode: 0644]
queue-5.15/series
queue-6.1/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch [new file with mode: 0644]
queue-6.1/series
queue-6.12/arm64-kconfig-remove-selecting-replaced-have_functio.patch [new file with mode: 0644]
queue-6.12/hwmon-pmbus-core-protect-regulator-operations-with-m.patch [new file with mode: 0644]
queue-6.12/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch [new file with mode: 0644]
queue-6.12/iommu-vt-d-draining-prq-in-sva-unbind-path-when-fpd-.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-trigger-neighbor-resolution-for-unresolved.patch [new file with mode: 0644]
queue-6.12/net-mlx5e-use-ip6_dst_lookup-instead-of-ipv6_dst_loo.patch [new file with mode: 0644]
queue-6.12/perf-parse-events-expose-rename-config_term_name.patch [new file with mode: 0644]
queue-6.12/revert-ice-fix-double-free-of-tx_buf-skb.patch [new file with mode: 0644]
queue-6.12/revert-ice-remove-jumbo_remove-step-from-tx-path.patch [new file with mode: 0644]
queue-6.12/riscv-fgraph-fix-stack-layout-to-match-__arch_ftrace.patch [new file with mode: 0644]
queue-6.12/riscv-fgraph-select-have_function_graph_tracer-depen.patch [new file with mode: 0644]
queue-6.12/series
queue-6.12/tracing-fix-the-bug-where-bpf_get_stackid-returns-ef.patch [new file with mode: 0644]
queue-6.12/x86-fgraph-fix-return_to_handler-regs.rsp-value.patch [new file with mode: 0644]
queue-6.18/drm-atomic-increase-timeout-in-drm_atomic_helper_wai.patch [new file with mode: 0644]
queue-6.18/drm-vblank-add-crtc-helpers-for-simple-use-cases.patch [new file with mode: 0644]
queue-6.18/drm-vblank-add-vblank-timer.patch [new file with mode: 0644]
queue-6.18/drm-vblank-fix-kernel-docs-for-vblank-timer.patch [new file with mode: 0644]
queue-6.18/drm-vkms-convert-to-drm-s-vblank-timer.patch [new file with mode: 0644]
queue-6.18/revert-ice-fix-double-free-of-tx_buf-skb.patch [new file with mode: 0644]
queue-6.18/revert-ice-remove-jumbo_remove-step-from-tx-path.patch [new file with mode: 0644]
queue-6.18/series
queue-6.6/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch [new file with mode: 0644]
queue-6.6/revert-af_unix-reject-siocatmark-on-non-stream-socke.patch [new file with mode: 0644]
queue-6.6/revert-ice-fix-double-free-of-tx_buf-skb.patch [new file with mode: 0644]
queue-6.6/revert-ice-remove-jumbo_remove-step-from-tx-path.patch [new file with mode: 0644]
queue-6.6/revert-s390-cio-update-purge-function-to-unregister-.patch [new file with mode: 0644]
queue-6.6/series

diff --git a/queue-5.15/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch b/queue-5.15/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch
new file mode 100644 (file)
index 0000000..c9281d2
--- /dev/null
@@ -0,0 +1,78 @@
+From 7b32286981d332a4970cd8847bdf3808f229908e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 16:37:47 +0800
+Subject: i3c: mipi-i3c-hci: Correct RING_CTRL_ABORT handling in DMA dequeue
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit b795e68bf3073d67bebbb5a44d93f49efc5b8cc7 ]
+
+The logic used to abort the DMA ring contains several flaws:
+
+ 1. The driver unconditionally issues a ring abort even when the ring has
+    already stopped.
+ 2. The completion used to wait for abort completion is never
+    re-initialized, resulting in incorrect wait behavior.
+ 3. The abort sequence unintentionally clears RING_CTRL_ENABLE, which
+    resets hardware ring pointers and disrupts the controller state.
+ 4. If the ring is already stopped, the abort operation should be
+    considered successful without attempting further action.
+
+Fix the abort handling by checking whether the ring is running before
+issuing an abort, re-initializing the completion when needed, ensuring that
+RING_CTRL_ENABLE remains asserted during abort, and treating an already
+stopped ring as a successful condition.
+
+Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260306072451.11131-9-adrian.hunter@intel.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Jianqiang kang <jianqkang@sina.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master/mipi-i3c-hci/dma.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c
+index 168b21f6cf37c..d6678bee725b6 100644
+--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
+@@ -448,16 +448,23 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci,
+       struct hci_rh_data *rh = &rings->headers[xfer_list[0].ring_number];
+       unsigned int i;
+       bool did_unqueue = false;
+-
+-      /* stop the ring */
+-      rh_reg_write(RING_CONTROL, RING_CTRL_ABORT);
+-      if (wait_for_completion_timeout(&rh->op_done, HZ) == 0) {
+-              /*
+-               * We're deep in it if ever this condition is ever met.
+-               * Hardware might still be writing to memory, etc.
+-               */
+-              dev_crit(&hci->master.dev, "unable to abort the ring\n");
+-              WARN_ON(1);
++      u32 ring_status;
++
++      ring_status = rh_reg_read(RING_STATUS);
++      if (ring_status & RING_STATUS_RUNNING) {
++              /* stop the ring */
++              reinit_completion(&rh->op_done);
++              rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE | RING_CTRL_ABORT);
++              wait_for_completion_timeout(&rh->op_done, HZ);
++              ring_status = rh_reg_read(RING_STATUS);
++              if (ring_status & RING_STATUS_RUNNING) {
++                      /*
++                       * We're deep in it if ever this condition is ever met.
++                       * Hardware might still be writing to memory, etc.
++                       */
++                      dev_crit(&hci->master.dev, "unable to abort the ring\n");
++                      WARN_ON(1);
++              }
+       }
+       for (i = 0; i < n; i++) {
+-- 
+2.53.0
+
index fd27f2b761a9b67cb22051ed825d40e8be4ae60d..a95e4b877604bdd587f05f01fa72b15df87f0658 100644 (file)
@@ -680,3 +680,4 @@ wifi-mac80211-check-tdls-flag-in-ieee80211_tdls_oper.patch
 kvm-x86-acquire-srcu-in-kvm_get_mp_state-to-protect-.patch
 revert-s390-cio-fix-device-lifecycle-handling-in-css.patch
 smb-client-reject-userspace-cifs.spnego-descriptions.patch
+i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch
diff --git a/queue-6.1/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch b/queue-6.1/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch
new file mode 100644 (file)
index 0000000..298e5f8
--- /dev/null
@@ -0,0 +1,78 @@
+From 65cff8906fcf152c60bf7130fb4004824dc54288 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 14:21:07 +0800
+Subject: i3c: mipi-i3c-hci: Correct RING_CTRL_ABORT handling in DMA dequeue
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit b795e68bf3073d67bebbb5a44d93f49efc5b8cc7 ]
+
+The logic used to abort the DMA ring contains several flaws:
+
+ 1. The driver unconditionally issues a ring abort even when the ring has
+    already stopped.
+ 2. The completion used to wait for abort completion is never
+    re-initialized, resulting in incorrect wait behavior.
+ 3. The abort sequence unintentionally clears RING_CTRL_ENABLE, which
+    resets hardware ring pointers and disrupts the controller state.
+ 4. If the ring is already stopped, the abort operation should be
+    considered successful without attempting further action.
+
+Fix the abort handling by checking whether the ring is running before
+issuing an abort, re-initializing the completion when needed, ensuring that
+RING_CTRL_ENABLE remains asserted during abort, and treating an already
+stopped ring as a successful condition.
+
+Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260306072451.11131-9-adrian.hunter@intel.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Jianqiang kang <jianqkang@sina.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master/mipi-i3c-hci/dma.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c
+index 624d00b853a51..61007167606fd 100644
+--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
+@@ -448,16 +448,23 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci,
+       struct hci_rh_data *rh = &rings->headers[xfer_list[0].ring_number];
+       unsigned int i;
+       bool did_unqueue = false;
+-
+-      /* stop the ring */
+-      rh_reg_write(RING_CONTROL, RING_CTRL_ABORT);
+-      if (wait_for_completion_timeout(&rh->op_done, HZ) == 0) {
+-              /*
+-               * We're deep in it if ever this condition is ever met.
+-               * Hardware might still be writing to memory, etc.
+-               */
+-              dev_crit(&hci->master.dev, "unable to abort the ring\n");
+-              WARN_ON(1);
++      u32 ring_status;
++
++      ring_status = rh_reg_read(RING_STATUS);
++      if (ring_status & RING_STATUS_RUNNING) {
++              /* stop the ring */
++              reinit_completion(&rh->op_done);
++              rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE | RING_CTRL_ABORT);
++              wait_for_completion_timeout(&rh->op_done, HZ);
++              ring_status = rh_reg_read(RING_STATUS);
++              if (ring_status & RING_STATUS_RUNNING) {
++                      /*
++                       * We're deep in it if ever this condition is ever met.
++                       * Hardware might still be writing to memory, etc.
++                       */
++                      dev_crit(&hci->master.dev, "unable to abort the ring\n");
++                      WARN_ON(1);
++              }
+       }
+       for (i = 0; i < n; i++) {
+-- 
+2.53.0
+
index 2c7bbfb56a7a94658c3aedfceeec2ae4644f719e..e394830c4e4f4c4decedfe186b68f3fb06890a00 100644 (file)
@@ -836,3 +836,4 @@ wifi-mac80211-check-tdls-flag-in-ieee80211_tdls_oper.patch
 revert-x86-vdso-fix-output-operand-size-of-rdpid.patch
 revert-s390-cio-fix-device-lifecycle-handling-in-css.patch
 smb-client-reject-userspace-cifs.spnego-descriptions.patch
+i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch
diff --git a/queue-6.12/arm64-kconfig-remove-selecting-replaced-have_functio.patch b/queue-6.12/arm64-kconfig-remove-selecting-replaced-have_functio.patch
new file mode 100644 (file)
index 0000000..056df53
--- /dev/null
@@ -0,0 +1,44 @@
+From 39bda3851566c41919488aecade3f727e3a3696d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:24:40 +0000
+Subject: arm64: Kconfig: Remove selecting replaced HAVE_FUNCTION_GRAPH_RETVAL
+
+From: Lukas Bulwahn <lukas.bulwahn@redhat.com>
+
+commit f458b2165d7ac0f2401fff48f19c8f864e7e1e38 upstream.
+
+Commit a3ed4157b7d8 ("fgraph: Replace fgraph_ret_regs with ftrace_regs")
+replaces the config HAVE_FUNCTION_GRAPH_RETVAL with the config
+HAVE_FUNCTION_GRAPH_FREGS, and it replaces all the select commands in the
+various architecture Kconfig files. In the arm64 architecture, the commit
+adds the 'select HAVE_FUNCTION_GRAPH_FREGS', but misses to remove the
+'select HAVE_FUNCTION_GRAPH_RETVAL', i.e., the select on the replaced
+config.
+
+Remove selecting the replaced config. No functional change, just cleanup.
+
+Fixes: a3ed4157b7d8 ("fgraph: Replace fgraph_ret_regs with ftrace_regs")
+Signed-off-by: Lukas Bulwahn <lukas.bulwahn@redhat.com>
+Link: https://lore.kernel.org/r/20250117125522.99071-1-lukas.bulwahn@redhat.com
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Gyokhan Kochmarla <gyokhan@amazon.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/Kconfig | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
+index f487c5e21e2f1..d4ebdc16cdb4f 100644
+--- a/arch/arm64/Kconfig
++++ b/arch/arm64/Kconfig
+@@ -219,7 +219,6 @@ config ARM64
+       select HAVE_FUNCTION_ERROR_INJECTION
+       select HAVE_FUNCTION_GRAPH_FREGS
+       select HAVE_FUNCTION_GRAPH_TRACER
+-      select HAVE_FUNCTION_GRAPH_RETVAL
+       select HAVE_GCC_PLUGINS
+       select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && \
+               HW_PERF_EVENTS && HAVE_PERF_EVENTS_NMI
+-- 
+2.53.0
+
diff --git a/queue-6.12/hwmon-pmbus-core-protect-regulator-operations-with-m.patch b/queue-6.12/hwmon-pmbus-core-protect-regulator-operations-with-m.patch
new file mode 100644 (file)
index 0000000..d36fa96
--- /dev/null
@@ -0,0 +1,261 @@
+From b0c77c3a6481a24fcdf012f078666dcff4bf3c00 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 10:22:30 +0800
+Subject: hwmon: (pmbus/core) Protect regulator operations with mutex
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+[ Upstream commit 754bd2b4a084b90b5e7b630e1f423061a9b9b761 ]
+
+The regulator operations pmbus_regulator_get_voltage(),
+pmbus_regulator_set_voltage(), and pmbus_regulator_list_voltage()
+access PMBus registers and shared data but were not protected by
+the update_lock mutex. This could lead to race conditions.
+
+However, adding mutex protection directly to these functions causes
+a deadlock because pmbus_regulator_notify() (which calls
+regulator_notifier_call_chain()) is often called with the mutex
+already held (e.g., from pmbus_fault_handler()). If a regulator
+callback then calls one of the now-protected voltage functions,
+it will attempt to acquire the same mutex.
+
+Rework pmbus_regulator_notify() to utilize a worker function to
+send notifications outside of the mutex protection. Events are
+stored as atomics in a per-page bitmask and processed by the worker.
+
+Initialize the worker and its associated data during regulator
+registration, and ensure it is cancelled on device removal using
+devm_add_action_or_reset().
+
+While at it, remove the unnecessary include of linux/of.h.
+
+Cc: Sanman Pradhan <psanman@juniper.net>
+Fixes: ddbb4db4ced1b ("hwmon: (pmbus) Add regulator support")
+Reviewed-by: Sanman Pradhan <psanman@juniper.net>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Fang Wang <32840572@qq.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/hwmon/pmbus/pmbus_core.c | 117 ++++++++++++++++++++++++-------
+ 1 file changed, 91 insertions(+), 26 deletions(-)
+
+diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c
+index 41c66ece5177e..e37fd206510a6 100644
+--- a/drivers/hwmon/pmbus/pmbus_core.c
++++ b/drivers/hwmon/pmbus/pmbus_core.c
+@@ -6,6 +6,7 @@
+  * Copyright (c) 2012 Guenter Roeck
+  */
++#include <linux/atomic.h>
+ #include <linux/debugfs.h>
+ #include <linux/delay.h>
+ #include <linux/kernel.h>
+@@ -20,8 +21,8 @@
+ #include <linux/pmbus.h>
+ #include <linux/regulator/driver.h>
+ #include <linux/regulator/machine.h>
+-#include <linux/of.h>
+ #include <linux/thermal.h>
++#include <linux/workqueue.h>
+ #include "pmbus.h"
+ /*
+@@ -102,6 +103,11 @@ struct pmbus_data {
+       struct mutex update_lock;
++#if IS_ENABLED(CONFIG_REGULATOR)
++      atomic_t regulator_events[PMBUS_PAGES];
++      struct work_struct regulator_notify_work;
++#endif
++
+       bool has_status_word;           /* device uses STATUS_WORD register */
+       int (*read_status)(struct i2c_client *client, int page);
+@@ -3181,12 +3187,19 @@ static int pmbus_regulator_get_voltage(struct regulator_dev *rdev)
+               .class = PSC_VOLTAGE_OUT,
+               .convert = true,
+       };
++      int ret;
++      mutex_lock(&data->update_lock);
+       s.data = _pmbus_read_word_data(client, s.page, 0xff, PMBUS_READ_VOUT);
+-      if (s.data < 0)
+-              return s.data;
++      if (s.data < 0) {
++              ret = s.data;
++              goto unlock;
++      }
+-      return (int)pmbus_reg2data(data, &s) * 1000; /* unit is uV */
++      ret = (int)pmbus_reg2data(data, &s) * 1000; /* unit is uV */
++unlock:
++      mutex_unlock(&data->update_lock);
++      return ret;
+ }
+ static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv,
+@@ -3203,16 +3216,22 @@ static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv,
+       };
+       int val = DIV_ROUND_CLOSEST(min_uv, 1000); /* convert to mV */
+       int low, high;
++      int ret;
+       *selector = 0;
++      mutex_lock(&data->update_lock);
+       low = pmbus_regulator_get_low_margin(client, s.page);
+-      if (low < 0)
+-              return low;
++      if (low < 0) {
++              ret = low;
++              goto unlock;
++      }
+       high = pmbus_regulator_get_high_margin(client, s.page);
+-      if (high < 0)
+-              return high;
++      if (high < 0) {
++              ret = high;
++              goto unlock;
++      }
+       /* Make sure we are within margins */
+       if (low > val)
+@@ -3222,7 +3241,10 @@ static int pmbus_regulator_set_voltage(struct regulator_dev *rdev, int min_uv,
+       val = pmbus_data2reg(data, &s, val);
+-      return _pmbus_write_word_data(client, s.page, PMBUS_VOUT_COMMAND, (u16)val);
++      ret = _pmbus_write_word_data(client, s.page, PMBUS_VOUT_COMMAND, (u16)val);
++unlock:
++      mutex_unlock(&data->update_lock);
++      return ret;
+ }
+ static int pmbus_regulator_list_voltage(struct regulator_dev *rdev,
+@@ -3230,7 +3252,9 @@ static int pmbus_regulator_list_voltage(struct regulator_dev *rdev,
+ {
+       struct device *dev = rdev_get_dev(rdev);
+       struct i2c_client *client = to_i2c_client(dev->parent);
++      struct pmbus_data *data = i2c_get_clientdata(client);
+       int val, low, high;
++      int ret;
+       if (selector >= rdev->desc->n_voltages ||
+           selector < rdev->desc->linear_min_sel)
+@@ -3240,18 +3264,29 @@ static int pmbus_regulator_list_voltage(struct regulator_dev *rdev,
+       val = DIV_ROUND_CLOSEST(rdev->desc->min_uV +
+                               (rdev->desc->uV_step * selector), 1000); /* convert to mV */
++      mutex_lock(&data->update_lock);
++
+       low = pmbus_regulator_get_low_margin(client, rdev_get_id(rdev));
+-      if (low < 0)
+-              return low;
++      if (low < 0) {
++              ret = low;
++              goto unlock;
++      }
+       high = pmbus_regulator_get_high_margin(client, rdev_get_id(rdev));
+-      if (high < 0)
+-              return high;
++      if (high < 0) {
++              ret = high;
++              goto unlock;
++      }
+-      if (val >= low && val <= high)
+-              return val * 1000; /* unit is uV */
++      if (val >= low && val <= high) {
++              ret = val * 1000; /* unit is uV */
++              goto unlock;
++      }
+-      return 0;
++      ret = 0;
++unlock:
++      mutex_unlock(&data->update_lock);
++      return ret;
+ }
+ const struct regulator_ops pmbus_regulator_ops = {
+@@ -3266,12 +3301,42 @@ const struct regulator_ops pmbus_regulator_ops = {
+ };
+ EXPORT_SYMBOL_NS_GPL(pmbus_regulator_ops, PMBUS);
++static void pmbus_regulator_notify_work_cancel(void *data)
++{
++      struct pmbus_data *pdata = data;
++
++      cancel_work_sync(&pdata->regulator_notify_work);
++}
++
++static void pmbus_regulator_notify_worker(struct work_struct *work)
++{
++      struct pmbus_data *data =
++              container_of(work, struct pmbus_data, regulator_notify_work);
++      int i, j;
++
++      for (i = 0; i < data->info->pages; i++) {
++              int event;
++
++              event = atomic_xchg(&data->regulator_events[i], 0);
++              if (!event)
++                      continue;
++
++              for (j = 0; j < data->info->num_regulators; j++) {
++                      if (i == rdev_get_id(data->rdevs[j])) {
++                              regulator_notifier_call_chain(data->rdevs[j],
++                                                            event, NULL);
++                              break;
++                      }
++              }
++      }
++}
++
+ static int pmbus_regulator_register(struct pmbus_data *data)
+ {
+       struct device *dev = data->dev;
+       const struct pmbus_driver_info *info = data->info;
+       const struct pmbus_platform_data *pdata = dev_get_platdata(dev);
+-      int i;
++      int i, ret;
+       data->rdevs = devm_kzalloc(dev, sizeof(struct regulator_dev *) * info->num_regulators,
+                                  GFP_KERNEL);
+@@ -3295,20 +3360,20 @@ static int pmbus_regulator_register(struct pmbus_data *data)
+                                            info->reg_desc[i].name);
+       }
++      INIT_WORK(&data->regulator_notify_work, pmbus_regulator_notify_worker);
++
++      ret = devm_add_action_or_reset(dev, pmbus_regulator_notify_work_cancel, data);
++      if (ret)
++              return ret;
++
+       return 0;
+ }
+ static int pmbus_regulator_notify(struct pmbus_data *data, int page, int event)
+ {
+-              int j;
+-
+-              for (j = 0; j < data->info->num_regulators; j++) {
+-                      if (page == rdev_get_id(data->rdevs[j])) {
+-                              regulator_notifier_call_chain(data->rdevs[j], event, NULL);
+-                              break;
+-                      }
+-              }
+-              return 0;
++      atomic_or(event, &data->regulator_events[page]);
++      schedule_work(&data->regulator_notify_work);
++      return 0;
+ }
+ #else
+ static int pmbus_regulator_register(struct pmbus_data *data)
+-- 
+2.53.0
+
diff --git a/queue-6.12/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch b/queue-6.12/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch
new file mode 100644 (file)
index 0000000..b36c612
--- /dev/null
@@ -0,0 +1,78 @@
+From 840018a00e1073ee50daf3f11644707b6c5bc9a1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 14:19:33 +0800
+Subject: i3c: mipi-i3c-hci: Correct RING_CTRL_ABORT handling in DMA dequeue
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit b795e68bf3073d67bebbb5a44d93f49efc5b8cc7 ]
+
+The logic used to abort the DMA ring contains several flaws:
+
+ 1. The driver unconditionally issues a ring abort even when the ring has
+    already stopped.
+ 2. The completion used to wait for abort completion is never
+    re-initialized, resulting in incorrect wait behavior.
+ 3. The abort sequence unintentionally clears RING_CTRL_ENABLE, which
+    resets hardware ring pointers and disrupts the controller state.
+ 4. If the ring is already stopped, the abort operation should be
+    considered successful without attempting further action.
+
+Fix the abort handling by checking whether the ring is running before
+issuing an abort, re-initializing the completion when needed, ensuring that
+RING_CTRL_ENABLE remains asserted during abort, and treating an already
+stopped ring as a successful condition.
+
+Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260306072451.11131-9-adrian.hunter@intel.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Jianqiang kang <jianqkang@sina.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master/mipi-i3c-hci/dma.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c
+index b9496e8c4784d..44461f13b54cd 100644
+--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
+@@ -457,16 +457,23 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci,
+       struct hci_rh_data *rh = &rings->headers[xfer_list[0].ring_number];
+       unsigned int i;
+       bool did_unqueue = false;
+-
+-      /* stop the ring */
+-      rh_reg_write(RING_CONTROL, RING_CTRL_ABORT);
+-      if (wait_for_completion_timeout(&rh->op_done, HZ) == 0) {
+-              /*
+-               * We're deep in it if ever this condition is ever met.
+-               * Hardware might still be writing to memory, etc.
+-               */
+-              dev_crit(&hci->master.dev, "unable to abort the ring\n");
+-              WARN_ON(1);
++      u32 ring_status;
++
++      ring_status = rh_reg_read(RING_STATUS);
++      if (ring_status & RING_STATUS_RUNNING) {
++              /* stop the ring */
++              reinit_completion(&rh->op_done);
++              rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE | RING_CTRL_ABORT);
++              wait_for_completion_timeout(&rh->op_done, HZ);
++              ring_status = rh_reg_read(RING_STATUS);
++              if (ring_status & RING_STATUS_RUNNING) {
++                      /*
++                       * We're deep in it if ever this condition is ever met.
++                       * Hardware might still be writing to memory, etc.
++                       */
++                      dev_crit(&hci->master.dev, "unable to abort the ring\n");
++                      WARN_ON(1);
++              }
+       }
+       for (i = 0; i < n; i++) {
+-- 
+2.53.0
+
diff --git a/queue-6.12/iommu-vt-d-draining-prq-in-sva-unbind-path-when-fpd-.patch b/queue-6.12/iommu-vt-d-draining-prq-in-sva-unbind-path-when-fpd-.patch
new file mode 100644 (file)
index 0000000..24e61c4
--- /dev/null
@@ -0,0 +1,92 @@
+From 4143b816f34d1f9422e57b4c2f0de6445cb720f3 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:24:01 +0000
+Subject: iommu/vt-d: Draining PRQ in sva unbind path when FPD bit set
+
+From: Lu Baolu <baolu.lu@linux.intel.com>
+
+commit cf08ca81d08a04b3b304e8fb4e052f323a09783d upstream.
+
+When a device uses a PASID for SVA (Shared Virtual Address), it's possible
+that the PASID entry is marked as non-present and FPD bit set before the
+device flushes all ongoing DMA requests and removes the SVA domain. This
+can occur when an exception happens and the process terminates before the
+device driver stops DMA and calls the iommu driver to unbind the PASID.
+
+There's no need to drain the PRQ in the mm release path. Instead, the PRQ
+will be drained in the SVA unbind path. But in such case,
+intel_pasid_tear_down_entry() only checks the presence of the pasid entry
+and returns directly.
+
+Add the code to clear the FPD bit and drain the PRQ.
+
+Fixes: c43e1ccdebf2 ("iommu/vt-d: Drain PRQs when domain removed from RID")
+Suggested-by: Kevin Tian <kevin.tian@intel.com>
+Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
+Reviewed-by: Kevin Tian <kevin.tian@intel.com>
+Link: https://lore.kernel.org/r/20241217024240.139615-1-baolu.lu@linux.intel.com
+Signed-off-by: Joerg Roedel <jroedel@suse.de>
+Signed-off-by: Gyokhan Kochmarla <gyokhan@amazon.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/iommu/intel/pasid.c | 22 +++++++++++++++++++++-
+ drivers/iommu/intel/pasid.h |  6 ++++++
+ 2 files changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
+index 3d1d43675bf22..74be6b547fc0c 100644
+--- a/drivers/iommu/intel/pasid.c
++++ b/drivers/iommu/intel/pasid.c
+@@ -245,11 +245,31 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu, struct device *dev,
+       spin_lock(&iommu->lock);
+       pte = intel_pasid_get_entry(dev, pasid);
+-      if (WARN_ON(!pte) || !pasid_pte_is_present(pte)) {
++      if (WARN_ON(!pte)) {
+               spin_unlock(&iommu->lock);
+               return;
+       }
++      if (!pasid_pte_is_present(pte)) {
++              if (!pasid_pte_is_fault_disabled(pte)) {
++                      WARN_ON(READ_ONCE(pte->val[0]) != 0);
++                      spin_unlock(&iommu->lock);
++                      return;
++              }
++
++              /*
++               * When a PASID is used for SVA by a device, it's possible
++               * that the pasid entry is non-present with the Fault
++               * Processing Disabled bit set. Clear the pasid entry and
++               * drain the PRQ for the PASID before return.
++               */
++              pasid_clear_entry(pte);
++              spin_unlock(&iommu->lock);
++              intel_iommu_drain_pasid_prq(dev, pasid);
++
++              return;
++      }
++
+       did = pasid_get_domain_id(pte);
+       pgtt = pasid_pte_get_pgtt(pte);
+       pasid_clear_present(pte);
+diff --git a/drivers/iommu/intel/pasid.h b/drivers/iommu/intel/pasid.h
+index 55cad7bfa294e..8ffb01163f0e6 100644
+--- a/drivers/iommu/intel/pasid.h
++++ b/drivers/iommu/intel/pasid.h
+@@ -80,6 +80,12 @@ static inline bool pasid_pte_is_present(struct pasid_entry *pte)
+       return READ_ONCE(pte->val[0]) & PASID_PTE_PRESENT;
+ }
++/* Get FPD(Fault Processing Disable) bit of a PASID table entry */
++static inline bool pasid_pte_is_fault_disabled(struct pasid_entry *pte)
++{
++      return READ_ONCE(pte->val[0]) & PASID_PTE_FPD;
++}
++
+ /* Get PGTT field of a PASID table entry */
+ static inline u16 pasid_pte_get_pgtt(struct pasid_entry *pte)
+ {
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-mlx5e-trigger-neighbor-resolution-for-unresolved.patch b/queue-6.12/net-mlx5e-trigger-neighbor-resolution-for-unresolved.patch
new file mode 100644 (file)
index 0000000..2e7fb51
--- /dev/null
@@ -0,0 +1,61 @@
+From eefae856833005cae6b15cc7bb544820027cf712 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:21:20 +0000
+Subject: net/mlx5e: Trigger neighbor resolution for unresolved destinations
+
+From: Jianbo Liu <jianbol@nvidia.com>
+
+commit 9ab89bde13e5251e1d0507e1cc426edcdfe19142 upstream.
+
+When initializing the MAC addresses for an outbound IPsec packet offload
+rule in mlx5e_ipsec_init_macs, the call to dst_neigh_lookup is used to
+find the next-hop neighbor (typically the gateway in tunnel mode).
+This call might create a new neighbor entry if one doesn't already
+exist. This newly created entry starts in the INCOMPLETE state, as the
+kernel hasn't yet sent an ARP or NDISC probe to resolve the MAC
+address. In this case, neigh_ha_snapshot will correctly return an
+all-zero MAC address.
+
+IPsec packet offload requires the actual next-hop MAC address to
+program the rule correctly. If the neighbor state is INCOMPLETE when
+the rule is created, the hardware rule is programmed with an all-zero
+destination MAC address. Packets sent using this rule will be
+subsequently dropped by the receiving network infrastructure or host.
+
+This patch adds a check specifically for the outbound offload path. If
+neigh_ha_snapshot returns an all-zero MAC address, it proactively
+calls neigh_event_send(n, NULL). This ensures the kernel immediately
+sends the initial ARP or NDISC probe if one isn't already pending,
+accelerating the resolution process. This helps prevent the hardware
+rule from being programmed with an invalid MAC address and avoids
+packet drops due to unresolved neighbors.
+
+Fixes: 71670f766b8f ("net/mlx5e: Support routed networks during IPsec MACs initialization")
+Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-8-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Gyokhan Kochmarla <gyokhan@amazon.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index 486f05112f5a6..e2915d3143e6b 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -365,6 +365,9 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry,
+       neigh_ha_snapshot(addr, n, netdev);
+       ether_addr_copy(dst, addr);
++      if (attrs->dir == XFRM_DEV_OFFLOAD_OUT &&
++          is_zero_ether_addr(addr))
++              neigh_event_send(n, NULL);
+       dst_release(rt_dst_entry);
+       neigh_release(n);
+       return;
+-- 
+2.53.0
+
diff --git a/queue-6.12/net-mlx5e-use-ip6_dst_lookup-instead-of-ipv6_dst_loo.patch b/queue-6.12/net-mlx5e-use-ip6_dst_lookup-instead-of-ipv6_dst_loo.patch
new file mode 100644 (file)
index 0000000..34715c2
--- /dev/null
@@ -0,0 +1,51 @@
+From e36c6858da13c57ce6af47635049cc0342db4c12 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:22:14 +0000
+Subject: net/mlx5e: Use ip6_dst_lookup instead of ipv6_dst_lookup_flow for MAC
+ init
+
+From: Jianbo Liu <jianbol@nvidia.com>
+
+commit e35d7da8dd9e55b37c3e8ab548f6793af0c2ab49 upstream.
+
+Replace ipv6_stub->ipv6_dst_lookup_flow() with ip6_dst_lookup() in
+mlx5e_ipsec_init_macs() since IPsec transformations are not needed
+during Security Association setup - only basic routing information is
+required for nexthop MAC address resolution.
+
+This resolves an issue where XfrmOutNoStates error counter would be
+incremented when xfrm policy is configured before xfrm state, as the
+IPsec-aware routing function would attempt policy checks during SA
+initialization.
+
+Fixes: 71670f766b8f ("net/mlx5e: Support routed networks during IPsec MACs initialization")
+Signed-off-by: Jianbo Liu <jianbol@nvidia.com>
+Reviewed-by: Leon Romanovsky <leonro@nvidia.com>
+Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
+Link: https://patch.msgid.link/1765284977-1363052-7-git-send-email-tariqt@nvidia.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Gyokhan Kochmarla <gyokhan@amazon.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+index e2915d3143e6b..c1b6893389fdf 100644
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/ipsec.c
+@@ -348,9 +348,8 @@ static void mlx5e_ipsec_init_macs(struct mlx5e_ipsec_sa_entry *sa_entry,
+               rt_dst_entry = &rt->dst;
+               break;
+       case AF_INET6:
+-              rt_dst_entry = ipv6_stub->ipv6_dst_lookup_flow(
+-                      dev_net(netdev), NULL, &fl6, NULL);
+-              if (IS_ERR(rt_dst_entry))
++              if (!IS_ENABLED(CONFIG_IPV6) ||
++                  ip6_dst_lookup(dev_net(netdev), NULL, &rt_dst_entry, &fl6))
+                       goto neigh;
+               break;
+       default:
+-- 
+2.53.0
+
diff --git a/queue-6.12/perf-parse-events-expose-rename-config_term_name.patch b/queue-6.12/perf-parse-events-expose-rename-config_term_name.patch
new file mode 100644 (file)
index 0000000..7066fc8
--- /dev/null
@@ -0,0 +1,118 @@
+From 81f79355bf3e5904a5f34f00e759683ba4325e38 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 1 Oct 2024 20:20:06 -0700
+Subject: perf parse-events: Expose/rename config_term_name
+
+From: Ian Rogers <irogers@google.com>
+
+[ Upstream commit d2f3ecb0ca2099d13bf8bf69219214c1425dc453 ]
+
+Expose config_term_name as parse_events__term_type_str so that PMUs not
+in pmu.c may access it.
+
+Signed-off-by: Ian Rogers <irogers@google.com>
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Link: https://lore.kernel.org/r/20241002032016.333748-4-irogers@google.com
+Signed-off-by: Namhyung Kim <namhyung@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ tools/perf/util/parse-events.c | 20 +++++++++++---------
+ tools/perf/util/parse-events.h |  2 ++
+ 2 files changed, 13 insertions(+), 9 deletions(-)
+
+diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
+index fcc4dab618bee..3d221608b13a5 100644
+--- a/tools/perf/util/parse-events.c
++++ b/tools/perf/util/parse-events.c
+@@ -801,7 +801,7 @@ static int check_type_val(struct parse_events_term *term,
+ static bool config_term_shrinked;
+-static const char *config_term_name(enum parse_events__term_type term_type)
++const char *parse_events__term_type_str(enum parse_events__term_type term_type)
+ {
+       /*
+        * Update according to parse-events.l
+@@ -887,7 +887,7 @@ config_term_avail(enum parse_events__term_type term_type, struct parse_events_er
+               /* term_type is validated so indexing is safe */
+               if (asprintf(&err_str, "'%s' is not usable in 'perf stat'",
+-                           config_term_name(term_type)) >= 0)
++                           parse_events__term_type_str(term_type)) >= 0)
+                       parse_events_error__handle(err, -1, err_str, NULL);
+               return false;
+       }
+@@ -1011,7 +1011,7 @@ do {                                                                        \
+       case PARSE_EVENTS__TERM_TYPE_HARDWARE:
+       default:
+               parse_events_error__handle(err, term->err_term,
+-                                      strdup(config_term_name(term->type_term)),
++                                      strdup(parse_events__term_type_str(term->type_term)),
+                                       parse_events_formats_error_string(NULL));
+               return -EINVAL;
+       }
+@@ -1135,8 +1135,9 @@ static int config_term_tracepoint(struct perf_event_attr *attr,
+       default:
+               if (err) {
+                       parse_events_error__handle(err, term->err_term,
+-                                                 strdup(config_term_name(term->type_term)),
+-                              strdup("valid terms: call-graph,stack-size\n"));
++                                      strdup(parse_events__term_type_str(term->type_term)),
++                                      strdup("valid terms: call-graph,stack-size\n")
++                              );
+               }
+               return -EINVAL;
+       }
+@@ -2581,7 +2582,7 @@ int parse_events_term__num(struct parse_events_term **term,
+       struct parse_events_term temp = {
+               .type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
+               .type_term = type_term,
+-              .config    = config ? : strdup(config_term_name(type_term)),
++              .config    = config ? : strdup(parse_events__term_type_str(type_term)),
+               .no_value  = no_value,
+               .err_term  = loc_term ? loc_term->first_column : 0,
+               .err_val   = loc_val  ? loc_val->first_column  : 0,
+@@ -2615,7 +2616,7 @@ int parse_events_term__term(struct parse_events_term **term,
+                           void *loc_term, void *loc_val)
+ {
+       return parse_events_term__str(term, term_lhs, NULL,
+-                                    strdup(config_term_name(term_rhs)),
++                                    strdup(parse_events__term_type_str(term_rhs)),
+                                     loc_term, loc_val);
+ }
+@@ -2722,7 +2723,8 @@ int parse_events_terms__to_strbuf(const struct parse_events_terms *terms, struct
+                               if (ret < 0)
+                                       return ret;
+                       } else if ((unsigned int)term->type_term < __PARSE_EVENTS__TERM_TYPE_NR) {
+-                              ret = strbuf_addf(sb, "%s=", config_term_name(term->type_term));
++                              ret = strbuf_addf(sb, "%s=",
++                                                parse_events__term_type_str(term->type_term));
+                               if (ret < 0)
+                                       return ret;
+                       }
+@@ -2742,7 +2744,7 @@ static void config_terms_list(char *buf, size_t buf_sz)
+       buf[0] = '\0';
+       for (i = 0; i < __PARSE_EVENTS__TERM_TYPE_NR; i++) {
+-              const char *name = config_term_name(i);
++              const char *name = parse_events__term_type_str(i);
+               if (!config_term_avail(i, NULL))
+                       continue;
+diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
+index 2b52f8d6aa29a..ac1feaaeb8d5d 100644
+--- a/tools/perf/util/parse-events.h
++++ b/tools/perf/util/parse-events.h
+@@ -168,6 +168,8 @@ struct parse_events_state {
+       bool                       wild_card_pmus;
+ };
++const char *parse_events__term_type_str(enum parse_events__term_type term_type);
++
+ bool parse_events__filter_pmu(const struct parse_events_state *parse_state,
+                             const struct perf_pmu *pmu);
+ void parse_events__shrink_config_terms(void);
+-- 
+2.53.0
+
diff --git a/queue-6.12/revert-ice-fix-double-free-of-tx_buf-skb.patch b/queue-6.12/revert-ice-fix-double-free-of-tx_buf-skb.patch
new file mode 100644 (file)
index 0000000..9981d4f
--- /dev/null
@@ -0,0 +1,46 @@
+From 097e408d8dfd97daea39ac7ea757eaa1e084bab9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 12:48:53 -0400
+Subject: Revert "ice: fix double-free of tx_buf skb"
+
+This reverts commit fd95ef8d0f6dbe2daa95d6488c9e0f8a95a7e048.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index 48434a79869cb..08d1757f40888 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -2346,9 +2346,6 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+       ice_trace(xmit_frame_ring, tx_ring, skb);
+-      /* record the location of the first descriptor for this packet */
+-      first = &tx_ring->tx_buf[tx_ring->next_to_use];
+-
+       count = ice_xmit_desc_count(skb);
+       if (ice_chk_linearize(skb, count)) {
+               if (__skb_linearize(skb))
+@@ -2374,6 +2371,8 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+       offload.tx_ring = tx_ring;
++      /* record the location of the first descriptor for this packet */
++      first = &tx_ring->tx_buf[tx_ring->next_to_use];
+       first->skb = skb;
+       first->type = ICE_TX_BUF_SKB;
+       first->bytecount = max_t(unsigned int, skb->len, ETH_ZLEN);
+@@ -2437,7 +2436,6 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+ out_drop:
+       ice_trace(xmit_frame_ring_drop, tx_ring, skb);
+       dev_kfree_skb_any(skb);
+-      first->type = ICE_TX_BUF_EMPTY;
+       return NETDEV_TX_OK;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.12/revert-ice-remove-jumbo_remove-step-from-tx-path.patch b/queue-6.12/revert-ice-remove-jumbo_remove-step-from-tx-path.patch
new file mode 100644 (file)
index 0000000..9be0b15
--- /dev/null
@@ -0,0 +1,29 @@
+From a651eade212687e1f5055b5308d1024c67dba31d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 12:48:54 -0400
+Subject: Revert "ice: Remove jumbo_remove step from TX path"
+
+This reverts commit 7332d208c9d2067546eb7af5339773c966ac5625.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index 08d1757f40888..431a6ed498a4e 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -2346,6 +2346,9 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+       ice_trace(xmit_frame_ring, tx_ring, skb);
++      if (unlikely(ipv6_hopopt_jumbo_remove(skb)))
++              goto out_drop;
++
+       count = ice_xmit_desc_count(skb);
+       if (ice_chk_linearize(skb, count)) {
+               if (__skb_linearize(skb))
+-- 
+2.53.0
+
diff --git a/queue-6.12/riscv-fgraph-fix-stack-layout-to-match-__arch_ftrace.patch b/queue-6.12/riscv-fgraph-fix-stack-layout-to-match-__arch_ftrace.patch
new file mode 100644 (file)
index 0000000..1b2c100
--- /dev/null
@@ -0,0 +1,128 @@
+From d1e3c23c1423204d2f3a13b121ccb3e2e05dce2b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:25:17 +0000
+Subject: riscv: fgraph: Fix stack layout to match __arch_ftrace_regs argument
+ of ftrace_return_to_handler
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pu Lehui <pulehui@huawei.com>
+
+commit 67a5ba8f742f247bc83e46dd2313c142b1383276 upstream.
+
+Naresh Kamboju reported a "Bad frame pointer" kernel warning while
+running LTP trace ftrace_stress_test.sh in riscv. We can reproduce the
+same issue with the following command:
+
+```
+$ cd /sys/kernel/debug/tracing
+$ echo 'f:myprobe do_nanosleep%return args1=$retval' > dynamic_events
+$ echo 1 > events/fprobes/enable
+$ echo 1 > tracing_on
+$ sleep 1
+```
+
+And we can get the following kernel warning:
+
+[  127.692888] ------------[ cut here ]------------
+[  127.693755] Bad frame pointer: expected ff2000000065be50, received ba34c141e9594000
+[  127.693755]   from func do_nanosleep return to ffffffff800ccb16
+[  127.698699] WARNING: CPU: 1 PID: 129 at kernel/trace/fgraph.c:755 ftrace_return_to_handler+0x1b2/0x1be
+[  127.699894] Modules linked in:
+[  127.700908] CPU: 1 UID: 0 PID: 129 Comm: sleep Not tainted 6.14.0-rc3-g0ab191c74642 #32
+[  127.701453] Hardware name: riscv-virtio,qemu (DT)
+[  127.701859] epc : ftrace_return_to_handler+0x1b2/0x1be
+[  127.702032]  ra : ftrace_return_to_handler+0x1b2/0x1be
+[  127.702151] epc : ffffffff8013b5e0 ra : ffffffff8013b5e0 sp : ff2000000065bd10
+[  127.702221]  gp : ffffffff819c12f8 tp : ff60000080853100 t0 : 6e00000000000000
+[  127.702284]  t1 : 0000000000000020 t2 : 6e7566206d6f7266 s0 : ff2000000065bd80
+[  127.702346]  s1 : ff60000081262000 a0 : 000000000000007b a1 : ffffffff81894f20
+[  127.702408]  a2 : 0000000000000010 a3 : fffffffffffffffe a4 : 0000000000000000
+[  127.702470]  a5 : 0000000000000000 a6 : 0000000000000008 a7 : 0000000000000038
+[  127.702530]  s2 : ba34c141e9594000 s3 : 0000000000000000 s4 : ff2000000065bdd0
+[  127.702591]  s5 : 00007fff8adcf400 s6 : 000055556dc1d8c0 s7 : 0000000000000068
+[  127.702651]  s8 : 00007fff8adf5d10 s9 : 000000000000006d s10: 0000000000000001
+[  127.702710]  s11: 00005555737377c8 t3 : ffffffff819d899e t4 : ffffffff819d899e
+[  127.702769]  t5 : ffffffff819d89a0 t6 : ff2000000065bb18
+[  127.702826] status: 0000000200000120 badaddr: 0000000000000000 cause: 0000000000000003
+[  127.703292] [<ffffffff8013b5e0>] ftrace_return_to_handler+0x1b2/0x1be
+[  127.703760] [<ffffffff80017bce>] return_to_handler+0x16/0x26
+[  127.704009] [<ffffffff80017bb8>] return_to_handler+0x0/0x26
+[  127.704057] [<ffffffff800d3352>] common_nsleep+0x42/0x54
+[  127.704117] [<ffffffff800d44a2>] __riscv_sys_clock_nanosleep+0xba/0x10a
+[  127.704176] [<ffffffff80901c56>] do_trap_ecall_u+0x188/0x218
+[  127.704295] [<ffffffff8090cc3e>] handle_exception+0x14a/0x156
+[  127.705436] ---[ end trace 0000000000000000 ]---
+
+The reason is that the stack layout for constructing argument for the
+ftrace_return_to_handler in the return_to_handler does not match the
+__arch_ftrace_regs structure of riscv, leading to unexpected results.
+
+Fixes: a3ed4157b7d8 ("fgraph: Replace fgraph_ret_regs with ftrace_regs")
+Reported-by: Linux Kernel Functional Testing <lkft@linaro.org>
+Closes: https://lore.kernel.org/all/CA+G9fYvp_oAxeDFj88Tk2rfEZ7jtYKAKSwfYS66=57Db9TBdyA@mail.gmail.com
+Signed-off-by: Pu Lehui <pulehui@huawei.com>
+Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Tested-by: Björn Töpel <bjorn@rivosinc.com>
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Link: https://lore.kernel.org/r/20250317031214.4138436-2-pulehui@huaweicloud.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Gyokhan Kochmarla <gyokhan@amazon.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/kernel/mcount.S | 24 +++++++++++-------------
+ 1 file changed, 11 insertions(+), 13 deletions(-)
+
+diff --git a/arch/riscv/kernel/mcount.S b/arch/riscv/kernel/mcount.S
+index 068168046e0ef..da4a4000e57ea 100644
+--- a/arch/riscv/kernel/mcount.S
++++ b/arch/riscv/kernel/mcount.S
+@@ -12,8 +12,6 @@
+ #include <asm/asm-offsets.h>
+ #include <asm/ftrace.h>
+-#define ABI_SIZE_ON_STACK     80
+-
+       .text
+       .macro SAVE_ABI_STATE
+@@ -28,12 +26,12 @@
+        * register if a0 was not saved.
+        */
+       .macro SAVE_RET_ABI_STATE
+-      addi    sp, sp, -ABI_SIZE_ON_STACK
+-      REG_S   ra, 1*SZREG(sp)
+-      REG_S   s0, 8*SZREG(sp)
+-      REG_S   a0, 10*SZREG(sp)
+-      REG_S   a1, 11*SZREG(sp)
+-      addi    s0, sp, ABI_SIZE_ON_STACK
++      addi    sp, sp, -FREGS_SIZE_ON_STACK
++      REG_S   ra, FREGS_RA(sp)
++      REG_S   s0, FREGS_S0(sp)
++      REG_S   a0, FREGS_A0(sp)
++      REG_S   a1, FREGS_A1(sp)
++      addi    s0, sp, FREGS_SIZE_ON_STACK
+       .endm
+       .macro RESTORE_ABI_STATE
+@@ -43,11 +41,11 @@
+       .endm
+       .macro RESTORE_RET_ABI_STATE
+-      REG_L   ra, 1*SZREG(sp)
+-      REG_L   s0, 8*SZREG(sp)
+-      REG_L   a0, 10*SZREG(sp)
+-      REG_L   a1, 11*SZREG(sp)
+-      addi    sp, sp, ABI_SIZE_ON_STACK
++      REG_L   ra, FREGS_RA(sp)
++      REG_L   s0, FREGS_S0(sp)
++      REG_L   a0, FREGS_A0(sp)
++      REG_L   a1, FREGS_A1(sp)
++      addi    sp, sp, FREGS_SIZE_ON_STACK
+       .endm
+ SYM_TYPED_FUNC_START(ftrace_stub)
+-- 
+2.53.0
+
diff --git a/queue-6.12/riscv-fgraph-select-have_function_graph_tracer-depen.patch b/queue-6.12/riscv-fgraph-select-have_function_graph_tracer-depen.patch
new file mode 100644 (file)
index 0000000..7770049
--- /dev/null
@@ -0,0 +1,48 @@
+From b8b94d07bdbd6d9b0401fc3054f7a0cd6ddfd21b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:26:35 +0000
+Subject: riscv: fgraph: Select HAVE_FUNCTION_GRAPH_TRACER depends on
+ HAVE_DYNAMIC_FTRACE_WITH_ARGS
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Pu Lehui <pulehui@huawei.com>
+
+commit e8eb8e1bdae94b9e003f5909519fd311d0936890 upstream.
+
+Currently, fgraph on riscv relies on the infrastructure of
+DYNAMIC_FTRACE_WITH_ARGS. However, DYNAMIC_FTRACE_WITH_ARGS may be
+turned off on riscv, which will cause the enabled fgraph to be abnormal.
+Therefore, let's select HAVE_FUNCTION_GRAPH_TRACER depends on
+HAVE_DYNAMIC_FTRACE_WITH_ARGS.
+
+Fixes: a3ed4157b7d8 ("fgraph: Replace fgraph_ret_regs with ftrace_regs")
+Reported-by: kernel test robot <lkp@intel.com>
+Closes: https://lore.kernel.org/oe-kbuild-all/202503160820.dvqMpH0g-lkp@intel.com/
+Signed-off-by: Pu Lehui <pulehui@huawei.com>
+Reviewed-by: Björn Töpel <bjorn@rivosinc.com>
+Link: https://lore.kernel.org/r/20250317031214.4138436-1-pulehui@huaweicloud.com
+Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
+Signed-off-by: Gyokhan Kochmarla <gyokhan@amazon.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/riscv/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index 9e8667a523d55..1c75758167956 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -143,7 +143,7 @@ config RISCV
+       select HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+       select HAVE_DYNAMIC_FTRACE_WITH_ARGS if HAVE_DYNAMIC_FTRACE
+       select HAVE_FTRACE_MCOUNT_RECORD if !XIP_KERNEL
+-      select HAVE_FUNCTION_GRAPH_TRACER
++      select HAVE_FUNCTION_GRAPH_TRACER if HAVE_DYNAMIC_FTRACE_WITH_ARGS
+       select HAVE_FUNCTION_GRAPH_FREGS
+       select HAVE_FUNCTION_TRACER if !XIP_KERNEL && !PREEMPTION
+       select HAVE_EBPF_JIT if MMU
+-- 
+2.53.0
+
index cacdfafa3d56a030e9b301c41fcdd7e81b36027e..44e259ab5415042855d4ae526e1c42e6f2c9a1fd 100644 (file)
@@ -26,3 +26,16 @@ ata-libata-scsi-improve-readability-of-ata_scsi_qc_issue.patch
 ata-libata-scsi-do-not-use-the-deferred-qc-feature-for-ata_defer_port.patch
 ata-libata-scsi-do-not-use-the-deferred-qc-feature-on-pmps-with-cbs.patch
 ata-libata-scsi-do-not-needlessly-defer-commands-when-using-pmp-with-fbs.patch
+perf-parse-events-expose-rename-config_term_name.patch
+revert-ice-fix-double-free-of-tx_buf-skb.patch
+revert-ice-remove-jumbo_remove-step-from-tx-path.patch
+tracing-fix-the-bug-where-bpf_get_stackid-returns-ef.patch
+net-mlx5e-trigger-neighbor-resolution-for-unresolved.patch
+net-mlx5e-use-ip6_dst_lookup-instead-of-ipv6_dst_loo.patch
+x86-fgraph-fix-return_to_handler-regs.rsp-value.patch
+iommu-vt-d-draining-prq-in-sva-unbind-path-when-fpd-.patch
+riscv-fgraph-select-have_function_graph_tracer-depen.patch
+riscv-fgraph-fix-stack-layout-to-match-__arch_ftrace.patch
+hwmon-pmbus-core-protect-regulator-operations-with-m.patch
+arm64-kconfig-remove-selecting-replaced-have_functio.patch
+i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch
diff --git a/queue-6.12/tracing-fix-the-bug-where-bpf_get_stackid-returns-ef.patch b/queue-6.12/tracing-fix-the-bug-where-bpf_get_stackid-returns-ef.patch
new file mode 100644 (file)
index 0000000..00a5c08
--- /dev/null
@@ -0,0 +1,50 @@
+From b09ae9b26fe5bac4704da61c7a946b391ea35e35 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:20:12 +0000
+Subject: tracing: Fix the bug where bpf_get_stackid returns -EFAULT on the
+ ARM64
+
+From: Feng Yang <yangfeng@kylinos.cn>
+
+commit fd2f74f8f3d3c1a524637caf5bead9757fae4332 upstream.
+
+When using bpf_program__attach_kprobe_multi_opts on ARM64 to hook a BPF program
+that contains the bpf_get_stackid function, the BPF program fails
+to obtain the stack trace and returns -EFAULT.
+
+This is because ftrace_partial_regs omits the configuration of the pstate register,
+leaving pstate at the default value of 0. When get_perf_callchain executes,
+it uses user_mode(regs) to determine whether it is in kernel mode.
+This leads to a misjudgment that the code is in user mode,
+so perf_callchain_kernel is not executed and the function returns directly.
+As a result, trace->nr becomes 0, and finally -EFAULT is returned.
+
+Therefore, the assignment of the pstate register is added here.
+
+Fixes: b9b55c8912ce ("tracing: Add ftrace_partial_regs() for converting ftrace_regs to pt_regs")
+Closes: https://lore.kernel.org/bpf/20250919071902.554223-1-yangfeng59949@163.com/
+Signed-off-by: Feng Yang <yangfeng@kylinos.cn>
+Tested-by: Jiri Olsa <jolsa@kernel.org>
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Signed-off-by: Will Deacon <will@kernel.org>
+Signed-off-by: Gyokhan Kochmarla <gyokhan@amazon.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm64/include/asm/ftrace.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/arm64/include/asm/ftrace.h b/arch/arm64/include/asm/ftrace.h
+index 10e56522122aa..46d4300dd48d3 100644
+--- a/arch/arm64/include/asm/ftrace.h
++++ b/arch/arm64/include/asm/ftrace.h
+@@ -145,6 +145,7 @@ ftrace_partial_regs(const struct ftrace_regs *fregs, struct pt_regs *regs)
+       regs->pc = afregs->pc;
+       regs->regs[29] = afregs->fp;
+       regs->regs[30] = afregs->lr;
++      regs->pstate = PSR_MODE_EL1h;
+       return regs;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.12/x86-fgraph-fix-return_to_handler-regs.rsp-value.patch b/queue-6.12/x86-fgraph-fix-return_to_handler-regs.rsp-value.patch
new file mode 100644 (file)
index 0000000..7030db8
--- /dev/null
@@ -0,0 +1,67 @@
+From f98c446f5e4b7846cf8940726cbc4f76c642e8c4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 19:23:24 +0000
+Subject: x86/fgraph: Fix return_to_handler regs.rsp value
+
+From: Jiri Olsa <jolsa@kernel.org>
+
+commit 8bc11700e0d23d4fdb7d8d5a73b2e95de427cabc upstream.
+
+The previous change (Fixes commit) messed up the rsp register value,
+which is wrong because it's already adjusted with FRAME_SIZE, we need
+the original rsp value.
+
+This change does not affect fprobe current kernel unwind, the !perf_hw_regs
+path perf_callchain_kernel:
+
+        if (perf_hw_regs(regs)) {
+                if (perf_callchain_store(entry, regs->ip))
+                        return;
+                unwind_start(&state, current, regs, NULL);
+        } else {
+                unwind_start(&state, current, NULL, (void *)regs->sp);
+        }
+
+which uses pt_regs.sp as first_frame boundary (FRAME_SIZE shift makes
+no difference, unwind stil stops at the right frame).
+
+This change fixes the other path when we want to unwind directly from
+pt_regs sp/fp/ip state, which is coming in following change.
+
+Fixes: 20a0bc10272f ("x86/fgraph,bpf: Fix stack ORC unwind from kprobe_multi return probe")
+Signed-off-by: Jiri Olsa <jolsa@kernel.org>
+Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
+Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Link: https://lore.kernel.org/bpf/20260126211837.472802-2-jolsa@kernel.org
+Signed-off-by: Gyokhan Kochmarla <gyokhan@amazon.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/x86/kernel/ftrace_64.S | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S
+index 8a3cff618692c..143fc62bf6f88 100644
+--- a/arch/x86/kernel/ftrace_64.S
++++ b/arch/x86/kernel/ftrace_64.S
+@@ -349,6 +349,9 @@ SYM_CODE_START(return_to_handler)
+       UNWIND_HINT_UNDEFINED
+       ANNOTATE_NOENDBR
++      /* Store original rsp for pt_regs.sp value. */
++      movq %rsp, %rdi
++
+       /* Restore return_to_handler value that got eaten by previous ret instruction. */
+       subq $8, %rsp
+       UNWIND_HINT_FUNC
+@@ -359,7 +362,7 @@ SYM_CODE_START(return_to_handler)
+       movq %rax, RAX(%rsp)
+       movq %rdx, RDX(%rsp)
+       movq %rbp, RBP(%rsp)
+-      movq %rsp, RSP(%rsp)
++      movq %rdi, RSP(%rsp)
+       movq %rsp, %rdi
+       call ftrace_return_to_handler
+-- 
+2.53.0
+
diff --git a/queue-6.18/drm-atomic-increase-timeout-in-drm_atomic_helper_wai.patch b/queue-6.18/drm-atomic-increase-timeout-in-drm_atomic_helper_wai.patch
new file mode 100644 (file)
index 0000000..e47d165
--- /dev/null
@@ -0,0 +1,50 @@
+From 0328cc6de2e09b3894ef93b56b4708d2420fd0c1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 21:31:22 +0800
+Subject: drm/atomic: Increase timeout in drm_atomic_helper_wait_for_vblanks()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 79ae8510b5b81b9500370f89c619b50ca9c0990f ]
+
+Increase the timeout for vblank events from 100 ms to 1000 ms. This
+is the same fix as in commit f050da08a4ed ("drm/vblank: Increase
+timeout in drm_wait_one_vblank()") for another vblank timeout.
+
+After merging generic DRM vblank timers [1] and converting several
+DRM drivers for virtual hardware, these drivers synchronize their
+vblank events to the display refresh rate. This can trigger timeouts
+within the DRM framework.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Link: https://lore.kernel.org/dri-devel/20250904145806.430568-1-tzimmermann@suse.de/ # [1]
+Reported-by: syzbot+fcede535e7eb57cf5b43@syzkaller.appspotmail.com
+Closes: https://lore.kernel.org/dri-devel/69381d6c.050a0220.4004e.0017.GAE@google.com/
+Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Fixes: 74afeb812850 ("drm/vblank: Add vblank timer")
+Link: https://patch.msgid.link/20251209143325.102056-1-tzimmermann@suse.de
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_atomic_helper.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
+index bbec1c184f652..b06a5cba52958 100644
+--- a/drivers/gpu/drm/drm_atomic_helper.c
++++ b/drivers/gpu/drm/drm_atomic_helper.c
+@@ -1913,7 +1913,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
+               ret = wait_event_timeout(dev->vblank[i].queue,
+                                        state->crtcs[i].last_vblank_count !=
+                                               drm_crtc_vblank_count(crtc),
+-                                       msecs_to_jiffies(100));
++                                       msecs_to_jiffies(1000));
+               WARN(!ret, "[CRTC:%d:%s] vblank wait timed out\n",
+                    crtc->base.id, crtc->name);
+-- 
+2.53.0
+
diff --git a/queue-6.18/drm-vblank-add-crtc-helpers-for-simple-use-cases.patch b/queue-6.18/drm-vblank-add-crtc-helpers-for-simple-use-cases.patch
new file mode 100644 (file)
index 0000000..42c5027
--- /dev/null
@@ -0,0 +1,177 @@
+From b0fe7515c74d5c520f8a3fdb83dc5eaf1747fcc7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 21:31:20 +0800
+Subject: drm/vblank: Add CRTC helpers for simple use cases
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit d54dbb5963bdbdf8559903fe2b2343e871adcb30 ]
+
+Implement atomic_flush, atomic_enable and atomic_disable of struct
+drm_crtc_helper_funcs for vblank handling. Driver with no further
+requirements can use these functions instead of adding their own.
+Also simplifies the use of vblank timers.
+
+The code has been adopted from vkms, which added the funtionality
+in commit 3a0709928b17 ("drm/vkms: Add vblank events simulated by
+hrtimers").
+
+v3:
+- mention vkms (Javier)
+v2:
+- fix docs
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Tested-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://lore.kernel.org/r/20250916083816.30275-3-tzimmermann@suse.de
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_vblank_helper.c | 80 +++++++++++++++++++++++++++++
+ include/drm/drm_vblank_helper.h     | 23 +++++++++
+ 2 files changed, 103 insertions(+)
+
+diff --git a/drivers/gpu/drm/drm_vblank_helper.c b/drivers/gpu/drm/drm_vblank_helper.c
+index f94d1e706191b..a04a6ba1b0ca0 100644
+--- a/drivers/gpu/drm/drm_vblank_helper.c
++++ b/drivers/gpu/drm/drm_vblank_helper.c
+@@ -1,5 +1,6 @@
+ // SPDX-License-Identifier: MIT
++#include <drm/drm_atomic.h>
+ #include <drm/drm_crtc.h>
+ #include <drm/drm_managed.h>
+ #include <drm/drm_modeset_helper_vtables.h>
+@@ -17,6 +18,12 @@
+  * Drivers enable support for vblank timers by setting the vblank callbacks
+  * in struct &drm_crtc_funcs to the helpers provided by this library. The
+  * initializer macro DRM_CRTC_VBLANK_TIMER_FUNCS does this conveniently.
++ * The driver further has to send the VBLANK event from its atomic_flush
++ * callback and control vblank from the CRTC's atomic_enable and atomic_disable
++ * callbacks. The callbacks are located in struct &drm_crtc_helper_funcs.
++ * The vblank helper library provides implementations of these callbacks
++ * for drivers without further requirements. The initializer macro
++ * DRM_CRTC_HELPER_VBLANK_FUNCS sets them coveniently.
+  *
+  * Once the driver enables vblank support with drm_vblank_init(), each
+  * CRTC's vblank timer fires according to the programmed display mode. By
+@@ -25,6 +32,79 @@
+  * struct &drm_crtc_helper_funcs.handle_vblank_timeout.
+  */
++/*
++ * VBLANK helpers
++ */
++
++/**
++ * drm_crtc_vblank_atomic_flush -
++ *    Implements struct &drm_crtc_helper_funcs.atomic_flush
++ * @crtc: The CRTC
++ * @state: The atomic state to apply
++ *
++ * The helper drm_crtc_vblank_atomic_flush() implements atomic_flush of
++ * struct drm_crtc_helper_funcs for CRTCs that only need to send out a
++ * VBLANK event.
++ *
++ * See also struct &drm_crtc_helper_funcs.atomic_flush.
++ */
++void drm_crtc_vblank_atomic_flush(struct drm_crtc *crtc,
++                                struct drm_atomic_state *state)
++{
++      struct drm_device *dev = crtc->dev;
++      struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
++      struct drm_pending_vblank_event *event;
++
++      spin_lock_irq(&dev->event_lock);
++
++      event = crtc_state->event;
++      crtc_state->event = NULL;
++
++      if (event) {
++              if (drm_crtc_vblank_get(crtc) == 0)
++                      drm_crtc_arm_vblank_event(crtc, event);
++              else
++                      drm_crtc_send_vblank_event(crtc, event);
++      }
++
++      spin_unlock_irq(&dev->event_lock);
++}
++EXPORT_SYMBOL(drm_crtc_vblank_atomic_flush);
++
++/**
++ * drm_crtc_vblank_atomic_enable - Implements struct &drm_crtc_helper_funcs.atomic_enable
++ * @crtc: The CRTC
++ * @state: The atomic state
++ *
++ * The helper drm_crtc_vblank_atomic_enable() implements atomic_enable
++ * of struct drm_crtc_helper_funcs for CRTCs the only need to enable VBLANKs.
++ *
++ * See also struct &drm_crtc_helper_funcs.atomic_enable.
++ */
++void drm_crtc_vblank_atomic_enable(struct drm_crtc *crtc,
++                                 struct drm_atomic_state *state)
++{
++      drm_crtc_vblank_on(crtc);
++}
++EXPORT_SYMBOL(drm_crtc_vblank_atomic_enable);
++
++/**
++ * drm_crtc_vblank_atomic_disable - Implements struct &drm_crtc_helper_funcs.atomic_disable
++ * @crtc: The CRTC
++ * @state: The atomic state
++ *
++ * The helper drm_crtc_vblank_atomic_disable() implements atomic_disable
++ * of struct drm_crtc_helper_funcs for CRTCs the only need to disable VBLANKs.
++ *
++ * See also struct &drm_crtc_funcs.atomic_disable.
++ */
++void drm_crtc_vblank_atomic_disable(struct drm_crtc *crtc,
++                                  struct drm_atomic_state *state)
++{
++      drm_crtc_vblank_off(crtc);
++}
++EXPORT_SYMBOL(drm_crtc_vblank_atomic_disable);
++
+ /*
+  * VBLANK timer
+  */
+diff --git a/include/drm/drm_vblank_helper.h b/include/drm/drm_vblank_helper.h
+index 74a971d0cfba0..fcd8a9b358463 100644
+--- a/include/drm/drm_vblank_helper.h
++++ b/include/drm/drm_vblank_helper.h
+@@ -6,8 +6,31 @@
+ #include <linux/hrtimer_types.h>
+ #include <linux/types.h>
++struct drm_atomic_state;
+ struct drm_crtc;
++/*
++ * VBLANK helpers
++ */
++
++void drm_crtc_vblank_atomic_flush(struct drm_crtc *crtc,
++                                struct drm_atomic_state *state);
++void drm_crtc_vblank_atomic_enable(struct drm_crtc *crtc,
++                                 struct drm_atomic_state *state);
++void drm_crtc_vblank_atomic_disable(struct drm_crtc *crtc,
++                                  struct drm_atomic_state *crtc_state);
++
++/**
++ * DRM_CRTC_HELPER_VBLANK_FUNCS - Default implementation for VBLANK helpers
++ *
++ * This macro initializes struct &drm_crtc_helper_funcs to default helpers
++ * for VBLANK handling.
++ */
++#define DRM_CRTC_HELPER_VBLANK_FUNCS \
++      .atomic_flush = drm_crtc_vblank_atomic_flush, \
++      .atomic_enable = drm_crtc_vblank_atomic_enable, \
++      .atomic_disable = drm_crtc_vblank_atomic_disable
++
+ /*
+  * VBLANK timer
+  */
+-- 
+2.53.0
+
diff --git a/queue-6.18/drm-vblank-add-vblank-timer.patch b/queue-6.18/drm-vblank-add-vblank-timer.patch
new file mode 100644 (file)
index 0000000..e4eba95
--- /dev/null
@@ -0,0 +1,537 @@
+From 6f54e07c43a2d03aa6245613760eb1d1288d3ef0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 21:31:19 +0800
+Subject: drm/vblank: Add vblank timer
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 74afeb8128502a529041a2566febd26053a7be11 ]
+
+The vblank timer simulates a vblank interrupt for hardware without
+support. Rate-limits the display update frequency.
+
+DRM drivers for hardware without vblank support apply display updates
+ASAP. A vblank event informs DRM clients of the completed update.
+Userspace compositors immediately schedule the next update, which
+creates significant load on virtualization outputs. Display updates
+are usually fast on virtualization outputs, as their framebuffers are
+in regular system memory and there's no hardware vblank interrupt to
+throttle the update rate.
+
+The vblank timer is a HR timer that signals the vblank in software.
+It limits the update frequency of a DRM driver similar to a hardware
+vblank interrupt. The timer is not synchronized to the actual vblank
+interval of the display.
+
+The code has been adopted from vkms, which added the funtionality
+in commit 3a0709928b17 ("drm/vkms: Add vblank events simulated by
+hrtimers").
+
+The new implementation is part of the existing vblank support,
+which sets up the timer automatically. Drivers only have to start
+and cancel the vblank timer as part of enabling and disabling the
+CRTC. The new vblank helper library provides callbacks for struct
+drm_crtc_funcs.
+
+The standard way for handling vblank is to call drm_crtc_handle_vblank().
+Drivers that require additional processing, such as vkms, can init
+handle_vblank_timeout in struct drm_crtc_helper_funcs to refer to
+their timeout handler.
+
+There's a possible deadlock between drm_crtc_handle_vblank() and
+hrtimer_cancel(). [1] The implementation avoids to call hrtimer_cancel()
+directly and instead signals to the timer function to not restart
+itself.
+
+v4:
+- fix possible race condition between timeout and atomic commit (Michael)
+v3:
+- avoid deadlock when cancelling timer (Ville, Lyude)
+v2:
+- implement vblank timer entirely in vblank helpers
+- downgrade overrun warning to debug
+- fix docs
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Tested-by: Louis Chauvet <louis.chauvet@bootlin.com>
+Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Tested-by: Michael Kelley <mhklinux@outlook.com>
+Link: https://lore.kernel.org/all/20250510094757.4174662-1-zengheng4@huawei.com/ # [1]
+Link: https://lore.kernel.org/r/20250916083816.30275-2-tzimmermann@suse.de
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ Documentation/gpu/drm-kms-helpers.rst    |  12 ++
+ drivers/gpu/drm/Makefile                 |   3 +-
+ drivers/gpu/drm/drm_vblank.c             | 172 ++++++++++++++++++++++-
+ drivers/gpu/drm/drm_vblank_helper.c      |  96 +++++++++++++
+ include/drm/drm_modeset_helper_vtables.h |  12 ++
+ include/drm/drm_vblank.h                 |  32 +++++
+ include/drm/drm_vblank_helper.h          |  33 +++++
+ 7 files changed, 357 insertions(+), 3 deletions(-)
+ create mode 100644 drivers/gpu/drm/drm_vblank_helper.c
+ create mode 100644 include/drm/drm_vblank_helper.h
+
+diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
+index 5139705089f20..781129f78b06b 100644
+--- a/Documentation/gpu/drm-kms-helpers.rst
++++ b/Documentation/gpu/drm-kms-helpers.rst
+@@ -92,6 +92,18 @@ GEM Atomic Helper Reference
+ .. kernel-doc:: drivers/gpu/drm/drm_gem_atomic_helper.c
+    :export:
++VBLANK Helper Reference
++-----------------------
++
++.. kernel-doc:: drivers/gpu/drm/drm_vblank_helper.c
++   :doc: overview
++
++.. kernel-doc:: include/drm/drm_vblank_helper.h
++   :internal:
++
++.. kernel-doc:: drivers/gpu/drm/drm_vblank_helper.c
++   :export:
++
+ Simple KMS Helper Reference
+ ===========================
+diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
+index 742f0d590c5af..b248e64587ed4 100644
+--- a/drivers/gpu/drm/Makefile
++++ b/drivers/gpu/drm/Makefile
+@@ -152,7 +152,8 @@ drm_kms_helper-y := \
+       drm_plane_helper.o \
+       drm_probe_helper.o \
+       drm_self_refresh_helper.o \
+-      drm_simple_kms_helper.o
++      drm_simple_kms_helper.o \
++      drm_vblank_helper.o
+ drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
+ drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
+ obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
+diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
+index 46f59883183d9..61e211fd3c9c8 100644
+--- a/drivers/gpu/drm/drm_vblank.c
++++ b/drivers/gpu/drm/drm_vblank.c
+@@ -136,8 +136,17 @@
+  * vblanks after a timer has expired, which can be configured through the
+  * ``vblankoffdelay`` module parameter.
+  *
+- * Drivers for hardware without support for vertical-blanking interrupts
+- * must not call drm_vblank_init(). For such drivers, atomic helpers will
++ * Drivers for hardware without support for vertical-blanking interrupts can
++ * use DRM vblank timers to send vblank events at the rate of the current
++ * display mode's refresh. While not synchronized to the hardware's
++ * vertical-blanking regions, the timer helps DRM clients and compositors to
++ * adapt their update cycle to the display output. Drivers should set up
++ * vblanking as usual, but call drm_crtc_vblank_start_timer() and
++ * drm_crtc_vblank_cancel_timer() as part of their atomic mode setting.
++ * See also DRM vblank helpers for more information.
++ *
++ * Drivers without support for vertical-blanking interrupts nor timers must
++ * not call drm_vblank_init(). For these drivers, atomic helpers will
+  * automatically generate fake vblank events as part of the display update.
+  * This functionality also can be controlled by the driver by enabling and
+  * disabling struct drm_crtc_state.no_vblank.
+@@ -508,6 +517,9 @@ static void drm_vblank_init_release(struct drm_device *dev, void *ptr)
+       drm_WARN_ON(dev, READ_ONCE(vblank->enabled) &&
+                   drm_core_check_feature(dev, DRIVER_MODESET));
++      if (vblank->vblank_timer.crtc)
++              hrtimer_cancel(&vblank->vblank_timer.timer);
++
+       drm_vblank_destroy_worker(vblank);
+       timer_delete_sync(&vblank->disable_timer);
+ }
+@@ -2162,3 +2174,159 @@ int drm_crtc_queue_sequence_ioctl(struct drm_device *dev, void *data,
+       return ret;
+ }
++/*
++ * VBLANK timer
++ */
++
++static enum hrtimer_restart drm_vblank_timer_function(struct hrtimer *timer)
++{
++      struct drm_vblank_crtc_timer *vtimer =
++              container_of(timer, struct drm_vblank_crtc_timer, timer);
++      struct drm_crtc *crtc = vtimer->crtc;
++      const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
++      struct drm_device *dev = crtc->dev;
++      unsigned long flags;
++      ktime_t interval;
++      u64 ret_overrun;
++      bool succ;
++
++      spin_lock_irqsave(&vtimer->interval_lock, flags);
++      interval = vtimer->interval;
++      spin_unlock_irqrestore(&vtimer->interval_lock, flags);
++
++      if (!interval)
++              return HRTIMER_NORESTART;
++
++      ret_overrun = hrtimer_forward_now(&vtimer->timer, interval);
++      if (ret_overrun != 1)
++              drm_dbg_vbl(dev, "vblank timer overrun\n");
++
++      if (crtc_funcs->handle_vblank_timeout)
++              succ = crtc_funcs->handle_vblank_timeout(crtc);
++      else
++              succ = drm_crtc_handle_vblank(crtc);
++      if (!succ)
++              return HRTIMER_NORESTART;
++
++      return HRTIMER_RESTART;
++}
++
++/**
++ * drm_crtc_vblank_start_timer - Starts the vblank timer on the given CRTC
++ * @crtc: the CRTC
++ *
++ * Drivers should call this function from their CRTC's enable_vblank
++ * function to start a vblank timer. The timer will fire after the duration
++ * of a full frame. drm_crtc_vblank_cancel_timer() disables a running timer.
++ *
++ * Returns:
++ * 0 on success, or a negative errno code otherwise.
++ */
++int drm_crtc_vblank_start_timer(struct drm_crtc *crtc)
++{
++      struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
++      struct drm_vblank_crtc_timer *vtimer = &vblank->vblank_timer;
++      unsigned long flags;
++
++      if (!vtimer->crtc) {
++              /*
++               * Set up the data structures on the first invocation.
++               */
++              vtimer->crtc = crtc;
++              spin_lock_init(&vtimer->interval_lock);
++              hrtimer_setup(&vtimer->timer, drm_vblank_timer_function,
++                            CLOCK_MONOTONIC, HRTIMER_MODE_REL);
++      } else {
++              /*
++               * Timer should not be active. If it is, wait for the
++               * previous cancel operations to finish.
++               */
++              while (hrtimer_active(&vtimer->timer))
++                      hrtimer_try_to_cancel(&vtimer->timer);
++      }
++
++      drm_calc_timestamping_constants(crtc, &crtc->mode);
++
++      spin_lock_irqsave(&vtimer->interval_lock, flags);
++      vtimer->interval = ns_to_ktime(vblank->framedur_ns);
++      spin_unlock_irqrestore(&vtimer->interval_lock, flags);
++
++      hrtimer_start(&vtimer->timer, vtimer->interval, HRTIMER_MODE_REL);
++
++      return 0;
++}
++EXPORT_SYMBOL(drm_crtc_vblank_start_timer);
++
++/**
++ * drm_crtc_vblank_start_timer - Cancels the given CRTC's vblank timer
++ * @crtc: the CRTC
++ *
++ * Drivers should call this function from their CRTC's disable_vblank
++ * function to stop a vblank timer.
++ */
++void drm_crtc_vblank_cancel_timer(struct drm_crtc *crtc)
++{
++      struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
++      struct drm_vblank_crtc_timer *vtimer = &vblank->vblank_timer;
++      unsigned long flags;
++
++      /*
++       * Calling hrtimer_cancel() can result in a deadlock with DRM's
++       * vblank_time_lime_lock and hrtimers' softirq_expiry_lock. So
++       * clear interval and indicate cancellation. The timer function
++       * will cancel itself on the next invocation.
++       */
++
++      spin_lock_irqsave(&vtimer->interval_lock, flags);
++      vtimer->interval = 0;
++      spin_unlock_irqrestore(&vtimer->interval_lock, flags);
++
++      hrtimer_try_to_cancel(&vtimer->timer);
++}
++EXPORT_SYMBOL(drm_crtc_vblank_cancel_timer);
++
++/**
++ * drm_crtc_vblank_get_vblank_timeout - Returns the vblank timeout
++ * @crtc: The CRTC
++ * @vblank_time: Returns the next vblank timestamp
++ *
++ * The helper drm_crtc_vblank_get_vblank_timeout() returns the next vblank
++ * timestamp of the CRTC's vblank timer according to the timer's expiry
++ * time.
++ */
++void drm_crtc_vblank_get_vblank_timeout(struct drm_crtc *crtc, ktime_t *vblank_time)
++{
++      struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
++      struct drm_vblank_crtc_timer *vtimer = &vblank->vblank_timer;
++      u64 cur_count;
++      ktime_t cur_time;
++
++      if (!READ_ONCE(vblank->enabled)) {
++              *vblank_time = ktime_get();
++              return;
++      }
++
++      /*
++       * A concurrent vblank timeout could update the expires field before
++       * we compare it with the vblank time. Hence we'd compare the old
++       * expiry time to the new vblank time; deducing the timer had already
++       * expired. Reread until we get consistent values from both fields.
++       */
++      do {
++              cur_count = drm_crtc_vblank_count_and_time(crtc, &cur_time);
++              *vblank_time = READ_ONCE(vtimer->timer.node.expires);
++      } while (cur_count != drm_crtc_vblank_count_and_time(crtc, &cur_time));
++
++      if (drm_WARN_ON(crtc->dev, !ktime_compare(*vblank_time, cur_time)))
++              return; /* Already expired */
++
++      /*
++       * To prevent races we roll the hrtimer forward before we do any
++       * interrupt processing - this is how real hw works (the interrupt
++       * is only generated after all the vblank registers are updated)
++       * and what the vblank core expects. Therefore we need to always
++       * correct the timestamp by one frame.
++       */
++      *vblank_time = ktime_sub(*vblank_time, vtimer->interval);
++}
++EXPORT_SYMBOL(drm_crtc_vblank_get_vblank_timeout);
+diff --git a/drivers/gpu/drm/drm_vblank_helper.c b/drivers/gpu/drm/drm_vblank_helper.c
+new file mode 100644
+index 0000000000000..f94d1e706191b
+--- /dev/null
++++ b/drivers/gpu/drm/drm_vblank_helper.c
+@@ -0,0 +1,96 @@
++// SPDX-License-Identifier: MIT
++
++#include <drm/drm_crtc.h>
++#include <drm/drm_managed.h>
++#include <drm/drm_modeset_helper_vtables.h>
++#include <drm/drm_print.h>
++#include <drm/drm_vblank.h>
++#include <drm/drm_vblank_helper.h>
++
++/**
++ * DOC: overview
++ *
++ * The vblank helper library provides functions for supporting vertical
++ * blanking in DRM drivers.
++ *
++ * For vblank timers, several callback implementations are available.
++ * Drivers enable support for vblank timers by setting the vblank callbacks
++ * in struct &drm_crtc_funcs to the helpers provided by this library. The
++ * initializer macro DRM_CRTC_VBLANK_TIMER_FUNCS does this conveniently.
++ *
++ * Once the driver enables vblank support with drm_vblank_init(), each
++ * CRTC's vblank timer fires according to the programmed display mode. By
++ * default, the vblank timer invokes drm_crtc_handle_vblank(). Drivers with
++ * more specific requirements can set their own handler function in
++ * struct &drm_crtc_helper_funcs.handle_vblank_timeout.
++ */
++
++/*
++ * VBLANK timer
++ */
++
++/**
++ * drm_crtc_vblank_helper_enable_vblank_timer - Implements struct &drm_crtc_funcs.enable_vblank
++ * @crtc: The CRTC
++ *
++ * The helper drm_crtc_vblank_helper_enable_vblank_timer() implements
++ * enable_vblank of struct drm_crtc_helper_funcs for CRTCs that require
++ * a VBLANK timer. It sets up the timer on the first invocation. The
++ * started timer expires after the current frame duration. See struct
++ * &drm_vblank_crtc.framedur_ns.
++ *
++ * See also struct &drm_crtc_helper_funcs.enable_vblank.
++ *
++ * Returns:
++ * 0 on success, or a negative errno code otherwise.
++ */
++int drm_crtc_vblank_helper_enable_vblank_timer(struct drm_crtc *crtc)
++{
++      return drm_crtc_vblank_start_timer(crtc);
++}
++EXPORT_SYMBOL(drm_crtc_vblank_helper_enable_vblank_timer);
++
++/**
++ * drm_crtc_vblank_helper_disable_vblank_timer - Implements struct &drm_crtc_funcs.disable_vblank
++ * @crtc: The CRTC
++ *
++ * The helper drm_crtc_vblank_helper_disable_vblank_timer() implements
++ * disable_vblank of struct drm_crtc_funcs for CRTCs that require a
++ * VBLANK timer.
++ *
++ * See also struct &drm_crtc_helper_funcs.disable_vblank.
++ */
++void drm_crtc_vblank_helper_disable_vblank_timer(struct drm_crtc *crtc)
++{
++      drm_crtc_vblank_cancel_timer(crtc);
++}
++EXPORT_SYMBOL(drm_crtc_vblank_helper_disable_vblank_timer);
++
++/**
++ * drm_crtc_vblank_helper_get_vblank_timestamp_from_timer -
++ *    Implements struct &drm_crtc_funcs.get_vblank_timestamp
++ * @crtc: The CRTC
++ * @max_error: Maximum acceptable error
++ * @vblank_time: Returns the next vblank timestamp
++ * @in_vblank_irq: True is called from drm_crtc_handle_vblank()
++ *
++ * The helper drm_crtc_helper_get_vblank_timestamp_from_timer() implements
++ * get_vblank_timestamp of struct drm_crtc_funcs for CRTCs that require a
++ * VBLANK timer. It returns the timestamp according to the timer's expiry
++ * time.
++ *
++ * See also struct &drm_crtc_funcs.get_vblank_timestamp.
++ *
++ * Returns:
++ * True on success, or false otherwise.
++ */
++bool drm_crtc_vblank_helper_get_vblank_timestamp_from_timer(struct drm_crtc *crtc,
++                                                          int *max_error,
++                                                          ktime_t *vblank_time,
++                                                          bool in_vblank_irq)
++{
++      drm_crtc_vblank_get_vblank_timeout(crtc, vblank_time);
++
++      return true;
++}
++EXPORT_SYMBOL(drm_crtc_vblank_helper_get_vblank_timestamp_from_timer);
+diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
+index ce7c7aeac887b..fe32854b7ffec 100644
+--- a/include/drm/drm_modeset_helper_vtables.h
++++ b/include/drm/drm_modeset_helper_vtables.h
+@@ -490,6 +490,18 @@ struct drm_crtc_helper_funcs {
+                                    bool in_vblank_irq, int *vpos, int *hpos,
+                                    ktime_t *stime, ktime_t *etime,
+                                    const struct drm_display_mode *mode);
++
++      /**
++       * @handle_vblank_timeout: Handles timeouts of the vblank timer.
++       *
++       * Called by CRTC's the vblank timer on each timeout. Semantics is
++       * equivalient to drm_crtc_handle_vblank(). Implementations should
++       * invoke drm_crtc_handle_vblank() as part of processing the timeout.
++       *
++       * This callback is optional. If unset, the vblank timer invokes
++       * drm_crtc_handle_vblank() directly.
++       */
++      bool (*handle_vblank_timeout)(struct drm_crtc *crtc);
+ };
+ /**
+diff --git a/include/drm/drm_vblank.h b/include/drm/drm_vblank.h
+index 151ab1e85b1b7..ffa564d796384 100644
+--- a/include/drm/drm_vblank.h
++++ b/include/drm/drm_vblank.h
+@@ -25,6 +25,7 @@
+ #define _DRM_VBLANK_H_
+ #include <linux/seqlock.h>
++#include <linux/hrtimer.h>
+ #include <linux/idr.h>
+ #include <linux/poll.h>
+ #include <linux/kthread.h>
+@@ -103,6 +104,28 @@ struct drm_vblank_crtc_config {
+       bool disable_immediate;
+ };
++/**
++ * struct drm_vblank_crtc_timer - vblank timer for a CRTC
++ */
++struct drm_vblank_crtc_timer {
++      /**
++       * @timer: The vblank's high-resolution timer
++       */
++      struct hrtimer timer;
++      /**
++       * @interval_lock: Protects @interval
++       */
++      spinlock_t interval_lock;
++      /**
++       * @interval: Duration between two vblanks
++       */
++      ktime_t interval;
++      /**
++       * @crtc: The timer's CRTC
++       */
++      struct drm_crtc *crtc;
++};
++
+ /**
+  * struct drm_vblank_crtc - vblank tracking for a CRTC
+  *
+@@ -254,6 +277,11 @@ struct drm_vblank_crtc {
+        * cancelled.
+        */
+       wait_queue_head_t work_wait_queue;
++
++      /**
++       * @vblank_timer: Holds the state of the vblank timer
++       */
++      struct drm_vblank_crtc_timer vblank_timer;
+ };
+ struct drm_vblank_crtc *drm_crtc_vblank_crtc(struct drm_crtc *crtc);
+@@ -290,6 +318,10 @@ wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc);
+ void drm_crtc_set_max_vblank_count(struct drm_crtc *crtc,
+                                  u32 max_vblank_count);
++int drm_crtc_vblank_start_timer(struct drm_crtc *crtc);
++void drm_crtc_vblank_cancel_timer(struct drm_crtc *crtc);
++void drm_crtc_vblank_get_vblank_timeout(struct drm_crtc *crtc, ktime_t *vblank_time);
++
+ /*
+  * Helpers for struct drm_crtc_funcs
+  */
+diff --git a/include/drm/drm_vblank_helper.h b/include/drm/drm_vblank_helper.h
+new file mode 100644
+index 0000000000000..74a971d0cfba0
+--- /dev/null
++++ b/include/drm/drm_vblank_helper.h
+@@ -0,0 +1,33 @@
++/* SPDX-License-Identifier: GPL-2.0+ */
++
++#ifndef _DRM_VBLANK_HELPER_H_
++#define _DRM_VBLANK_HELPER_H_
++
++#include <linux/hrtimer_types.h>
++#include <linux/types.h>
++
++struct drm_crtc;
++
++/*
++ * VBLANK timer
++ */
++
++int drm_crtc_vblank_helper_enable_vblank_timer(struct drm_crtc *crtc);
++void drm_crtc_vblank_helper_disable_vblank_timer(struct drm_crtc *crtc);
++bool drm_crtc_vblank_helper_get_vblank_timestamp_from_timer(struct drm_crtc *crtc,
++                                                          int *max_error,
++                                                          ktime_t *vblank_time,
++                                                          bool in_vblank_irq);
++
++/**
++ * DRM_CRTC_VBLANK_TIMER_FUNCS - Default implementation for VBLANK timers
++ *
++ * This macro initializes struct &drm_crtc_funcs to default helpers for
++ * VBLANK timers.
++ */
++#define DRM_CRTC_VBLANK_TIMER_FUNCS \
++      .enable_vblank = drm_crtc_vblank_helper_enable_vblank_timer, \
++      .disable_vblank = drm_crtc_vblank_helper_disable_vblank_timer, \
++      .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp_from_timer
++
++#endif
+-- 
+2.53.0
+
diff --git a/queue-6.18/drm-vblank-fix-kernel-docs-for-vblank-timer.patch b/queue-6.18/drm-vblank-fix-kernel-docs-for-vblank-timer.patch
new file mode 100644 (file)
index 0000000..2c2e4df
--- /dev/null
@@ -0,0 +1,48 @@
+From f7b83fd63a3e176b3c85143f712c8a32246b036e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 21:31:23 +0800
+Subject: drm/vblank: Fix kernel docs for vblank timer
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 3946d3ba99342f3b9996e621f05e7003d4308171 ]
+
+Fix documentation for drm_crtc_vblank_start_timer(), which referred
+to drm_crtc_vblank_cancel_timer().
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Closes: https://lore.kernel.org/dri-devel/20251106152201.6f248c09@canb.auug.org.au/
+Fixes: 74afeb812850 ("drm/vblank: Add vblank timer")
+Cc: Thomas Zimmermann <tzimmermann@suse.de>
+Cc: Louis Chauvet <louis.chauvet@bootlin.com>
+Cc: Javier Martinez Canillas <javierm@redhat.com>
+Cc: David Airlie <airlied@gmail.com>
+Cc: Simona Vetter <simona@ffwll.ch>
+Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
+Cc: Maxime Ripard <mripard@kernel.org>
+Cc: dri-devel@lists.freedesktop.org
+Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
+Link: https://patch.msgid.link/20251106073207.11192-1-tzimmermann@suse.de
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/drm_vblank.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/gpu/drm/drm_vblank.c b/drivers/gpu/drm/drm_vblank.c
+index 61e211fd3c9c8..451ec96202266 100644
+--- a/drivers/gpu/drm/drm_vblank.c
++++ b/drivers/gpu/drm/drm_vblank.c
+@@ -2258,7 +2258,7 @@ int drm_crtc_vblank_start_timer(struct drm_crtc *crtc)
+ EXPORT_SYMBOL(drm_crtc_vblank_start_timer);
+ /**
+- * drm_crtc_vblank_start_timer - Cancels the given CRTC's vblank timer
++ * drm_crtc_vblank_cancel_timer - Cancels the given CRTC's vblank timer
+  * @crtc: the CRTC
+  *
+  * Drivers should call this function from their CRTC's disable_vblank
+-- 
+2.53.0
+
diff --git a/queue-6.18/drm-vkms-convert-to-drm-s-vblank-timer.patch b/queue-6.18/drm-vkms-convert-to-drm-s-vblank-timer.patch
new file mode 100644 (file)
index 0000000..c14ae40
--- /dev/null
@@ -0,0 +1,176 @@
+From 3bc5cf9c4b89d0278f2334a736e18ffca4cd279a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 May 2026 21:31:21 +0800
+Subject: drm/vkms: Convert to DRM's vblank timer
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit 02e2681ffe1addde1fc8c35d05657b16bfa79613 ]
+
+Replace vkms' vblank timer with the DRM implementation. The DRM
+code is identical in concept, but differs in implementation.
+
+Vblank timers are covered in vblank helpers and initializer macros,
+so remove the corresponding hrtimer in struct vkms_output. The
+vblank timer calls vkms' custom timeout code via handle_vblank_timeout
+in struct drm_crtc_helper_funcs.
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Tested-by: Louis Chauvet <louis.chauvet@bootlin.com>
+Reviewed-by: Louis Chauvet <louis.chauvet@bootlin.com>
+Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
+Link: https://lore.kernel.org/r/20250916083816.30275-4-tzimmermann@suse.de
+Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/gpu/drm/vkms/vkms_crtc.c | 83 +++-----------------------------
+ drivers/gpu/drm/vkms/vkms_drv.h  |  2 -
+ 2 files changed, 7 insertions(+), 78 deletions(-)
+
+diff --git a/drivers/gpu/drm/vkms/vkms_crtc.c b/drivers/gpu/drm/vkms/vkms_crtc.c
+index e60573e0f3e95..bd79f24686dce 100644
+--- a/drivers/gpu/drm/vkms/vkms_crtc.c
++++ b/drivers/gpu/drm/vkms/vkms_crtc.c
+@@ -7,25 +7,18 @@
+ #include <drm/drm_managed.h>
+ #include <drm/drm_probe_helper.h>
+ #include <drm/drm_vblank.h>
++#include <drm/drm_vblank_helper.h>
+ #include "vkms_drv.h"
+-static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
++static bool vkms_crtc_handle_vblank_timeout(struct drm_crtc *crtc)
+ {
+-      struct vkms_output *output = container_of(timer, struct vkms_output,
+-                                                vblank_hrtimer);
+-      struct drm_crtc *crtc = &output->crtc;
++      struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
+       struct vkms_crtc_state *state;
+-      u64 ret_overrun;
+       bool ret, fence_cookie;
+       fence_cookie = dma_fence_begin_signalling();
+-      ret_overrun = hrtimer_forward_now(&output->vblank_hrtimer,
+-                                        output->period_ns);
+-      if (ret_overrun != 1)
+-              pr_warn("%s: vblank timer overrun\n", __func__);
+-
+       spin_lock(&output->lock);
+       ret = drm_crtc_handle_vblank(crtc);
+       if (!ret)
+@@ -57,55 +50,6 @@ static enum hrtimer_restart vkms_vblank_simulate(struct hrtimer *timer)
+       dma_fence_end_signalling(fence_cookie);
+-      return HRTIMER_RESTART;
+-}
+-
+-static int vkms_enable_vblank(struct drm_crtc *crtc)
+-{
+-      struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
+-      struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
+-
+-      hrtimer_setup(&out->vblank_hrtimer, &vkms_vblank_simulate, CLOCK_MONOTONIC,
+-                    HRTIMER_MODE_REL);
+-      out->period_ns = ktime_set(0, vblank->framedur_ns);
+-      hrtimer_start(&out->vblank_hrtimer, out->period_ns, HRTIMER_MODE_REL);
+-
+-      return 0;
+-}
+-
+-static void vkms_disable_vblank(struct drm_crtc *crtc)
+-{
+-      struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
+-
+-      hrtimer_cancel(&out->vblank_hrtimer);
+-}
+-
+-static bool vkms_get_vblank_timestamp(struct drm_crtc *crtc,
+-                                    int *max_error, ktime_t *vblank_time,
+-                                    bool in_vblank_irq)
+-{
+-      struct vkms_output *output = drm_crtc_to_vkms_output(crtc);
+-      struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
+-
+-      if (!READ_ONCE(vblank->enabled)) {
+-              *vblank_time = ktime_get();
+-              return true;
+-      }
+-
+-      *vblank_time = READ_ONCE(output->vblank_hrtimer.node.expires);
+-
+-      if (WARN_ON(*vblank_time == vblank->time))
+-              return true;
+-
+-      /*
+-       * To prevent races we roll the hrtimer forward before we do any
+-       * interrupt processing - this is how real hw works (the interrupt is
+-       * only generated after all the vblank registers are updated) and what
+-       * the vblank core expects. Therefore we need to always correct the
+-       * timestampe by one frame.
+-       */
+-      *vblank_time -= output->period_ns;
+-
+       return true;
+ }
+@@ -159,9 +103,7 @@ static const struct drm_crtc_funcs vkms_crtc_funcs = {
+       .reset                  = vkms_atomic_crtc_reset,
+       .atomic_duplicate_state = vkms_atomic_crtc_duplicate_state,
+       .atomic_destroy_state   = vkms_atomic_crtc_destroy_state,
+-      .enable_vblank          = vkms_enable_vblank,
+-      .disable_vblank         = vkms_disable_vblank,
+-      .get_vblank_timestamp   = vkms_get_vblank_timestamp,
++      DRM_CRTC_VBLANK_TIMER_FUNCS,
+       .get_crc_sources        = vkms_get_crc_sources,
+       .set_crc_source         = vkms_set_crc_source,
+       .verify_crc_source      = vkms_verify_crc_source,
+@@ -213,18 +155,6 @@ static int vkms_crtc_atomic_check(struct drm_crtc *crtc,
+       return 0;
+ }
+-static void vkms_crtc_atomic_enable(struct drm_crtc *crtc,
+-                                  struct drm_atomic_state *state)
+-{
+-      drm_crtc_vblank_on(crtc);
+-}
+-
+-static void vkms_crtc_atomic_disable(struct drm_crtc *crtc,
+-                                   struct drm_atomic_state *state)
+-{
+-      drm_crtc_vblank_off(crtc);
+-}
+-
+ static void vkms_crtc_atomic_begin(struct drm_crtc *crtc,
+                                  struct drm_atomic_state *state)
+       __acquires(&vkms_output->lock)
+@@ -265,8 +195,9 @@ static const struct drm_crtc_helper_funcs vkms_crtc_helper_funcs = {
+       .atomic_check   = vkms_crtc_atomic_check,
+       .atomic_begin   = vkms_crtc_atomic_begin,
+       .atomic_flush   = vkms_crtc_atomic_flush,
+-      .atomic_enable  = vkms_crtc_atomic_enable,
+-      .atomic_disable = vkms_crtc_atomic_disable,
++      .atomic_enable  = drm_crtc_vblank_atomic_enable,
++      .atomic_disable = drm_crtc_vblank_atomic_disable,
++      .handle_vblank_timeout = vkms_crtc_handle_vblank_timeout,
+ };
+ struct vkms_output *vkms_crtc_init(struct drm_device *dev, struct drm_plane *primary,
+diff --git a/drivers/gpu/drm/vkms/vkms_drv.h b/drivers/gpu/drm/vkms/vkms_drv.h
+index 8013c31efe3b1..fb9711e1c6fbd 100644
+--- a/drivers/gpu/drm/vkms/vkms_drv.h
++++ b/drivers/gpu/drm/vkms/vkms_drv.h
+@@ -215,8 +215,6 @@ struct vkms_output {
+       struct drm_crtc crtc;
+       struct drm_writeback_connector wb_connector;
+       struct drm_encoder wb_encoder;
+-      struct hrtimer vblank_hrtimer;
+-      ktime_t period_ns;
+       struct workqueue_struct *composer_workq;
+       spinlock_t lock;
+-- 
+2.53.0
+
diff --git a/queue-6.18/revert-ice-fix-double-free-of-tx_buf-skb.patch b/queue-6.18/revert-ice-fix-double-free-of-tx_buf-skb.patch
new file mode 100644 (file)
index 0000000..bc144a2
--- /dev/null
@@ -0,0 +1,46 @@
+From cc19b6039a7bfce8697df1337fe7bc53e9de3563 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 12:43:10 -0400
+Subject: Revert "ice: fix double-free of tx_buf skb"
+
+This reverts commit 7cb19ec8ac087f33bee60f5d6054b284a5b9bb6f.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index e0774a640955d..90dbe5266ce78 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -2594,9 +2594,6 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+       ice_trace(xmit_frame_ring, tx_ring, skb);
+-      /* record the location of the first descriptor for this packet */
+-      first = &tx_ring->tx_buf[tx_ring->next_to_use];
+-
+       count = ice_xmit_desc_count(skb);
+       if (ice_chk_linearize(skb, count)) {
+               if (__skb_linearize(skb))
+@@ -2622,6 +2619,8 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+       offload.tx_ring = tx_ring;
++      /* record the location of the first descriptor for this packet */
++      first = &tx_ring->tx_buf[tx_ring->next_to_use];
+       first->skb = skb;
+       first->type = ICE_TX_BUF_SKB;
+       first->bytecount = max_t(unsigned int, skb->len, ETH_ZLEN);
+@@ -2686,7 +2685,6 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+ out_drop:
+       ice_trace(xmit_frame_ring_drop, tx_ring, skb);
+       dev_kfree_skb_any(skb);
+-      first->type = ICE_TX_BUF_EMPTY;
+       return NETDEV_TX_OK;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.18/revert-ice-remove-jumbo_remove-step-from-tx-path.patch b/queue-6.18/revert-ice-remove-jumbo_remove-step-from-tx-path.patch
new file mode 100644 (file)
index 0000000..147c7bd
--- /dev/null
@@ -0,0 +1,29 @@
+From eafbcb9f51dc7061cc6b9f26c2302151d5e35aa2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 12:43:10 -0400
+Subject: Revert "ice: Remove jumbo_remove step from TX path"
+
+This reverts commit 55500245ec0420df96b2a89444aabf0cff2c60bc.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index 90dbe5266ce78..73f08d02f9c76 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -2594,6 +2594,9 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+       ice_trace(xmit_frame_ring, tx_ring, skb);
++      if (unlikely(ipv6_hopopt_jumbo_remove(skb)))
++              goto out_drop;
++
+       count = ice_xmit_desc_count(skb);
+       if (ice_chk_linearize(skb, count)) {
+               if (__skb_linearize(skb))
+-- 
+2.53.0
+
index c1613fec99031342e4308ff97c3187b3888d8b36..0aa542dba6fa6c012f8b46b35581b353ae0e0461 100644 (file)
@@ -16,3 +16,10 @@ ata-libata-scsi-improve-readability-of-ata_scsi_qc_issue.patch
 ata-libata-scsi-do-not-use-the-deferred-qc-feature-for-ata_defer_port.patch
 ata-libata-scsi-do-not-use-the-deferred-qc-feature-on-pmps-with-cbs.patch
 ata-libata-scsi-do-not-needlessly-defer-commands-when-using-pmp-with-fbs.patch
+revert-ice-fix-double-free-of-tx_buf-skb.patch
+revert-ice-remove-jumbo_remove-step-from-tx-path.patch
+drm-vblank-add-vblank-timer.patch
+drm-vblank-add-crtc-helpers-for-simple-use-cases.patch
+drm-vkms-convert-to-drm-s-vblank-timer.patch
+drm-atomic-increase-timeout-in-drm_atomic_helper_wai.patch
+drm-vblank-fix-kernel-docs-for-vblank-timer.patch
diff --git a/queue-6.6/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch b/queue-6.6/i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch
new file mode 100644 (file)
index 0000000..684a560
--- /dev/null
@@ -0,0 +1,78 @@
+From 05e5798e389f1bc3a815f1eeefd0c0c2641bbbd0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 14:20:39 +0800
+Subject: i3c: mipi-i3c-hci: Correct RING_CTRL_ABORT handling in DMA dequeue
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+[ Upstream commit b795e68bf3073d67bebbb5a44d93f49efc5b8cc7 ]
+
+The logic used to abort the DMA ring contains several flaws:
+
+ 1. The driver unconditionally issues a ring abort even when the ring has
+    already stopped.
+ 2. The completion used to wait for abort completion is never
+    re-initialized, resulting in incorrect wait behavior.
+ 3. The abort sequence unintentionally clears RING_CTRL_ENABLE, which
+    resets hardware ring pointers and disrupts the controller state.
+ 4. If the ring is already stopped, the abort operation should be
+    considered successful without attempting further action.
+
+Fix the abort handling by checking whether the ring is running before
+issuing an abort, re-initializing the completion when needed, ensuring that
+RING_CTRL_ENABLE remains asserted during abort, and treating an already
+stopped ring as a successful condition.
+
+Fixes: 9ad9a52cce282 ("i3c/master: introduce the mipi-i3c-hci driver")
+Cc: stable@vger.kernel.org
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Reviewed-by: Frank Li <Frank.Li@nxp.com>
+Link: https://patch.msgid.link/20260306072451.11131-9-adrian.hunter@intel.com
+Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
+Signed-off-by: Jianqiang kang <jianqkang@sina.cn>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/i3c/master/mipi-i3c-hci/dma.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/i3c/master/mipi-i3c-hci/dma.c b/drivers/i3c/master/mipi-i3c-hci/dma.c
+index 624d00b853a51..61007167606fd 100644
+--- a/drivers/i3c/master/mipi-i3c-hci/dma.c
++++ b/drivers/i3c/master/mipi-i3c-hci/dma.c
+@@ -448,16 +448,23 @@ static bool hci_dma_dequeue_xfer(struct i3c_hci *hci,
+       struct hci_rh_data *rh = &rings->headers[xfer_list[0].ring_number];
+       unsigned int i;
+       bool did_unqueue = false;
+-
+-      /* stop the ring */
+-      rh_reg_write(RING_CONTROL, RING_CTRL_ABORT);
+-      if (wait_for_completion_timeout(&rh->op_done, HZ) == 0) {
+-              /*
+-               * We're deep in it if ever this condition is ever met.
+-               * Hardware might still be writing to memory, etc.
+-               */
+-              dev_crit(&hci->master.dev, "unable to abort the ring\n");
+-              WARN_ON(1);
++      u32 ring_status;
++
++      ring_status = rh_reg_read(RING_STATUS);
++      if (ring_status & RING_STATUS_RUNNING) {
++              /* stop the ring */
++              reinit_completion(&rh->op_done);
++              rh_reg_write(RING_CONTROL, RING_CTRL_ENABLE | RING_CTRL_ABORT);
++              wait_for_completion_timeout(&rh->op_done, HZ);
++              ring_status = rh_reg_read(RING_STATUS);
++              if (ring_status & RING_STATUS_RUNNING) {
++                      /*
++                       * We're deep in it if ever this condition is ever met.
++                       * Hardware might still be writing to memory, etc.
++                       */
++                      dev_crit(&hci->master.dev, "unable to abort the ring\n");
++                      WARN_ON(1);
++              }
+       }
+       for (i = 0; i < n; i++) {
+-- 
+2.53.0
+
diff --git a/queue-6.6/revert-af_unix-reject-siocatmark-on-non-stream-socke.patch b/queue-6.6/revert-af_unix-reject-siocatmark-on-non-stream-socke.patch
new file mode 100644 (file)
index 0000000..72cbefa
--- /dev/null
@@ -0,0 +1,29 @@
+From 4936aa60494249ff9b7c7521fb9efef33ede4b8b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:04:10 -0400
+Subject: Revert "af_unix: Reject SIOCATMARK on non-stream sockets"
+
+This reverts commit 0d7e7235bc543c6ed7b873e3015db814d8e8c414.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/unix/af_unix.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index c621f00902752..8f785b2600ae4 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -2809,9 +2809,6 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
+                               goto out;
+                       }
+-                      if (sk->sk_type != SOCK_STREAM)
+-                              return -EOPNOTSUPP;
+-
+                       mutex_lock(&u->iolock);
+                       goto redo;
+ unlock:
+-- 
+2.53.0
+
diff --git a/queue-6.6/revert-ice-fix-double-free-of-tx_buf-skb.patch b/queue-6.6/revert-ice-fix-double-free-of-tx_buf-skb.patch
new file mode 100644 (file)
index 0000000..c4066b9
--- /dev/null
@@ -0,0 +1,46 @@
+From db24f54e9526802a835bd0142be95c76f5e7ade1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 12:55:37 -0400
+Subject: Revert "ice: fix double-free of tx_buf skb"
+
+This reverts commit ca6f9d9aee5408c47e6c0fac10955cb6825ecd96.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index 4e110a008a257..66da8a34be0f1 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -2364,9 +2364,6 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+       ice_trace(xmit_frame_ring, tx_ring, skb);
+-      /* record the location of the first descriptor for this packet */
+-      first = &tx_ring->tx_buf[tx_ring->next_to_use];
+-
+       count = ice_xmit_desc_count(skb);
+       if (ice_chk_linearize(skb, count)) {
+               if (__skb_linearize(skb))
+@@ -2392,6 +2389,8 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+       offload.tx_ring = tx_ring;
++      /* record the location of the first descriptor for this packet */
++      first = &tx_ring->tx_buf[tx_ring->next_to_use];
+       first->skb = skb;
+       first->type = ICE_TX_BUF_SKB;
+       first->bytecount = max_t(unsigned int, skb->len, ETH_ZLEN);
+@@ -2453,7 +2452,6 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+ out_drop:
+       ice_trace(xmit_frame_ring_drop, tx_ring, skb);
+       dev_kfree_skb_any(skb);
+-      first->type = ICE_TX_BUF_EMPTY;
+       return NETDEV_TX_OK;
+ }
+-- 
+2.53.0
+
diff --git a/queue-6.6/revert-ice-remove-jumbo_remove-step-from-tx-path.patch b/queue-6.6/revert-ice-remove-jumbo_remove-step-from-tx-path.patch
new file mode 100644 (file)
index 0000000..853cdfb
--- /dev/null
@@ -0,0 +1,29 @@
+From 5120d53452c0531c33ff477f195a7c2b2213affb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 12:55:37 -0400
+Subject: Revert "ice: Remove jumbo_remove step from TX path"
+
+This reverts commit a753619ffecfe629ee73c821469edd8b37c72d3b.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ice/ice_txrx.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/ice/ice_txrx.c b/drivers/net/ethernet/intel/ice/ice_txrx.c
+index 66da8a34be0f1..eae4376c68595 100644
+--- a/drivers/net/ethernet/intel/ice/ice_txrx.c
++++ b/drivers/net/ethernet/intel/ice/ice_txrx.c
+@@ -2364,6 +2364,9 @@ ice_xmit_frame_ring(struct sk_buff *skb, struct ice_tx_ring *tx_ring)
+       ice_trace(xmit_frame_ring, tx_ring, skb);
++      if (unlikely(ipv6_hopopt_jumbo_remove(skb)))
++              goto out_drop;
++
+       count = ice_xmit_desc_count(skb);
+       if (ice_chk_linearize(skb, count)) {
+               if (__skb_linearize(skb))
+-- 
+2.53.0
+
diff --git a/queue-6.6/revert-s390-cio-update-purge-function-to-unregister-.patch b/queue-6.6/revert-s390-cio-update-purge-function-to-unregister-.patch
new file mode 100644 (file)
index 0000000..cf575f9
--- /dev/null
@@ -0,0 +1,76 @@
+From 17b1afa05c17845b837c24b5151c8b86b05957f0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 27 May 2026 13:03:59 -0400
+Subject: Revert "s390/cio: Update purge function to unregister the unused
+ subchannels"
+
+This reverts commit c34b09cbd6fc06f0f234182e462a1b010d13a5a6.
+
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/s390/cio/device.c | 37 +++++++++++++------------------------
+ 1 file changed, 13 insertions(+), 24 deletions(-)
+
+diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
+index 93307ca75c10b..e623359862ea2 100644
+--- a/drivers/s390/cio/device.c
++++ b/drivers/s390/cio/device.c
+@@ -1318,34 +1318,23 @@ void ccw_device_schedule_recovery(void)
+       spin_unlock_irqrestore(&recovery_lock, flags);
+ }
+-static int purge_fn(struct subchannel *sch, void *data)
++static int purge_fn(struct device *dev, void *data)
+ {
+-      struct ccw_device *cdev;
+-
+-      spin_lock_irq(sch->lock);
+-      if (sch->st != SUBCHANNEL_TYPE_IO || !sch->schib.pmcw.dnv)
+-              goto unlock;
+-
+-      if (!is_blacklisted(sch->schid.ssid, sch->schib.pmcw.dev))
+-              goto unlock;
+-
+-      cdev = sch_get_cdev(sch);
+-      if (cdev) {
+-              if (cdev->private->state != DEV_STATE_OFFLINE)
+-                      goto unlock;
++      struct ccw_device *cdev = to_ccwdev(dev);
++      struct ccw_dev_id *id = &cdev->private->dev_id;
++      struct subchannel *sch = to_subchannel(cdev->dev.parent);
+-              if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
+-                      goto unlock;
++      spin_lock_irq(cdev->ccwlock);
++      if (is_blacklisted(id->ssid, id->devno) &&
++          (cdev->private->state == DEV_STATE_OFFLINE) &&
++          (atomic_cmpxchg(&cdev->private->onoff, 0, 1) == 0)) {
++              CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", id->ssid,
++                            id->devno);
+               ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
++              css_sched_sch_todo(sch, SCH_TODO_UNREG);
+               atomic_set(&cdev->private->onoff, 0);
+       }
+-
+-      css_sched_sch_todo(sch, SCH_TODO_UNREG);
+-      CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x%s\n", sch->schid.ssid,
+-                    sch->schib.pmcw.dev, cdev ? "" : " (no cdev)");
+-
+-unlock:
+-      spin_unlock_irq(sch->lock);
++      spin_unlock_irq(cdev->ccwlock);
+       /* Abort loop in case of pending signal. */
+       if (signal_pending(current))
+               return -EINTR;
+@@ -1361,7 +1350,7 @@ static int purge_fn(struct subchannel *sch, void *data)
+ int ccw_purge_blacklisted(void)
+ {
+       CIO_MSG_EVENT(2, "ccw: purging blacklisted devices\n");
+-      for_each_subchannel_staged(purge_fn, NULL, NULL);
++      bus_for_each_dev(&ccw_bus_type, NULL, NULL, purge_fn);
+       return 0;
+ }
+-- 
+2.53.0
+
index dab275f248217513f3c64bd20f58847785a6427d..de80bd717809a7e4eb5ed8ed7e4059329d251f43 100644 (file)
@@ -14,3 +14,8 @@ ksmbd-validate-owner-of-durable-handle-on-reconnect.patch
 ksmbd-close-durable-scavenger-races-against-m_fp_lis.patch
 af_unix-give-up-gc-if-msg_peek-intervened.patch
 smb-client-reject-userspace-cifs.spnego-descriptions.patch
+revert-ice-fix-double-free-of-tx_buf-skb.patch
+revert-ice-remove-jumbo_remove-step-from-tx-path.patch
+revert-s390-cio-update-purge-function-to-unregister-.patch
+revert-af_unix-reject-siocatmark-on-non-stream-socke.patch
+i3c-mipi-i3c-hci-correct-ring_ctrl_abort-handling-in.patch