]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.6-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 May 2026 10:33:24 +0000 (12:33 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 May 2026 10:33:24 +0000 (12:33 +0200)
added patches:
alsa-core-serialize-deferred-fasync-state-checks.patch
alsa-hda-cs35l56-propagate-asp-tx-source-control-errors.patch
alsa-misc-use-guard-for-spin-locks.patch
alsa-seq-fix-ump-group-16-filtering.patch
alsa-seq-notify-client-and-port-info-changes.patch
bluetooth-hci_conn-fix-potential-uaf-in-create_big_sync.patch
crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch
crypto-nx-avoid-wflex-array-member-not-at-end-warning.patch
crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch
crypto-nx-migrate-to-scomp-api.patch
erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch
fbcon-avoid-oob-font-access-if-console-rotation-fails.patch
mm-hugetlb_cma-round-up-per_node-before-logging-it.patch
net-ipv4-stop-checking-crypto_ahash_alignmask.patch
net-ipv6-stop-checking-crypto_ahash_alignmask.patch
net-stmmac-avoid-shadowing-global-buf_sz.patch
net-stmmac-prevent-null-deref-when-rx-memory-exhausted.patch
net-stmmac-rename-stmmac_get_entry-stmmac_next_entry.patch
printk-add-print_hex_dump_devel.patch
rxrpc-fix-conn-level-packet-handling-to-unshare-response-packets.patch
spi-microchip-core-qspi-fix-controller-deregistration.patch
spi-microchip-core-qspi-use-helper-function-devm_clk_get_enabled.patch
spi-spi-ti-qspi-convert-to-platform-remove-callback-returning-void.patch
spi-spi-ti-qspi-switch-to-use-modern-name.patch
spi-sun4i-fix-controller-deregistration.patch
spi-sun4i-switch-to-use-modern-name.patch
spi-sun6i-fix-controller-deregistration.patch
spi-sun6i-switch-to-use-modern-name.patch
spi-syncuacer-fix-controller-deregistration.patch
spi-synquacer-switch-to-use-modern-name.patch
spi-tegra114-fix-controller-deregistration.patch
spi-tegra20-sflash-fix-controller-deregistration.patch
spi-ti-qspi-fix-controller-deregistration.patch
spi-uniphier-fix-controller-deregistration.patch
spi-uniphier-simplify-clock-handling-with-devm_clk_get_enabled.patch
spi-uniphier-switch-to-use-modern-name.patch
spi-zynq-qspi-fix-controller-deregistration.patch
spi-zynq-qspi-simplify-clock-handling-with-devm_clk_get_enabled.patch
spi-zynq-qspi-switch-to-use-modern-name.patch
tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch
xfrm-ah-account-for-esn-high-bits-in-async-callbacks.patch
xfrm-defensively-unhash-xfrm_state-lists-in-__xfrm_state_delete.patch

43 files changed:
queue-6.6/alsa-core-serialize-deferred-fasync-state-checks.patch [new file with mode: 0644]
queue-6.6/alsa-hda-cs35l56-propagate-asp-tx-source-control-errors.patch [new file with mode: 0644]
queue-6.6/alsa-misc-use-guard-for-spin-locks.patch [new file with mode: 0644]
queue-6.6/alsa-seq-fix-ump-group-16-filtering.patch [new file with mode: 0644]
queue-6.6/alsa-seq-notify-client-and-port-info-changes.patch [new file with mode: 0644]
queue-6.6/bluetooth-hci_conn-fix-potential-uaf-in-create_big_sync.patch [new file with mode: 0644]
queue-6.6/crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch [new file with mode: 0644]
queue-6.6/crypto-nx-avoid-wflex-array-member-not-at-end-warning.patch [new file with mode: 0644]
queue-6.6/crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch [new file with mode: 0644]
queue-6.6/crypto-nx-migrate-to-scomp-api.patch [new file with mode: 0644]
queue-6.6/erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch [new file with mode: 0644]
queue-6.6/fbcon-avoid-oob-font-access-if-console-rotation-fails.patch [new file with mode: 0644]
queue-6.6/mm-hugetlb_cma-round-up-per_node-before-logging-it.patch [new file with mode: 0644]
queue-6.6/net-ipv4-stop-checking-crypto_ahash_alignmask.patch [new file with mode: 0644]
queue-6.6/net-ipv6-stop-checking-crypto_ahash_alignmask.patch [new file with mode: 0644]
queue-6.6/net-stmmac-avoid-shadowing-global-buf_sz.patch [new file with mode: 0644]
queue-6.6/net-stmmac-prevent-null-deref-when-rx-memory-exhausted.patch [new file with mode: 0644]
queue-6.6/net-stmmac-rename-stmmac_get_entry-stmmac_next_entry.patch [new file with mode: 0644]
queue-6.6/printk-add-print_hex_dump_devel.patch [new file with mode: 0644]
queue-6.6/rxrpc-fix-conn-level-packet-handling-to-unshare-response-packets.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/spi-microchip-core-qspi-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.6/spi-microchip-core-qspi-use-helper-function-devm_clk_get_enabled.patch [new file with mode: 0644]
queue-6.6/spi-spi-ti-qspi-convert-to-platform-remove-callback-returning-void.patch [new file with mode: 0644]
queue-6.6/spi-spi-ti-qspi-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.6/spi-sun4i-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.6/spi-sun4i-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.6/spi-sun6i-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.6/spi-sun6i-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.6/spi-syncuacer-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.6/spi-synquacer-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.6/spi-tegra114-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.6/spi-tegra20-sflash-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.6/spi-ti-qspi-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.6/spi-uniphier-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.6/spi-uniphier-simplify-clock-handling-with-devm_clk_get_enabled.patch [new file with mode: 0644]
queue-6.6/spi-uniphier-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.6/spi-zynq-qspi-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.6/spi-zynq-qspi-simplify-clock-handling-with-devm_clk_get_enabled.patch [new file with mode: 0644]
queue-6.6/spi-zynq-qspi-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.6/tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch [new file with mode: 0644]
queue-6.6/xfrm-ah-account-for-esn-high-bits-in-async-callbacks.patch [new file with mode: 0644]
queue-6.6/xfrm-defensively-unhash-xfrm_state-lists-in-__xfrm_state_delete.patch [new file with mode: 0644]

diff --git a/queue-6.6/alsa-core-serialize-deferred-fasync-state-checks.patch b/queue-6.6/alsa-core-serialize-deferred-fasync-state-checks.patch
new file mode 100644 (file)
index 0000000..0ccac42
--- /dev/null
@@ -0,0 +1,64 @@
+From stable+bounces-246879-greg=kroah.com@vger.kernel.org Wed May 13 17:15:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 10:10:25 -0400
+Subject: ALSA: core: Serialize deferred fasync state checks
+To: stable@vger.kernel.org
+Cc: "Cássio Gabriel" <cassiogabrielcontato@gmail.com>, "Takashi Iwai" <tiwai@suse.de>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260513141025.3748103-3-sashal@kernel.org>
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit 5337213381df578058e2e41da93cbd0e4639935f ]
+
+snd_fasync_helper() updates fasync->on under snd_fasync_lock, and
+snd_fasync_work_fn() now also evaluates fasync->on under the same
+lock. snd_kill_fasync() still tests the flag before taking the lock,
+leaving an unsynchronized read against FASYNC enable/disable updates.
+
+Move the enabled-state check into the locked section.
+
+Also clear fasync->on under snd_fasync_lock in snd_fasync_free()
+before unlinking the pending entry. Together with the locked sender-side
+check, this publishes teardown before flushing the deferred work and
+prevents a racing sender from requeueing the entry after free has
+started.
+
+Fixes: ef34a0ae7a26 ("ALSA: core: Add async signal helpers")
+Fixes: 8146cd333d23 ("ALSA: core: Fix potential data race at fasync handling")
+Cc: stable@vger.kernel.org
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260506-alsa-core-fasync-on-lock-v1-1-ea48c77d6ca4@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/core/misc.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/sound/core/misc.c
++++ b/sound/core/misc.c
+@@ -219,9 +219,11 @@ EXPORT_SYMBOL_GPL(snd_fasync_helper);
+ void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll)
+ {
+-      if (!fasync || !fasync->on)
++      if (!fasync)
+               return;
+       guard(spinlock_irqsave)(&snd_fasync_lock);
++      if (!fasync->on)
++              return;
+       fasync->signal = signal;
+       fasync->poll = poll;
+       list_move(&fasync->list, &snd_fasync_list);
+@@ -234,8 +236,10 @@ void snd_fasync_free(struct snd_fasync *
+       if (!fasync)
+               return;
+-      scoped_guard(spinlock_irq, &snd_fasync_lock)
++      scoped_guard(spinlock_irq, &snd_fasync_lock) {
++              fasync->on = 0;
+               list_del_init(&fasync->list);
++      }
+       flush_work(&snd_fasync_work);
+       kfree(fasync);
diff --git a/queue-6.6/alsa-hda-cs35l56-propagate-asp-tx-source-control-errors.patch b/queue-6.6/alsa-hda-cs35l56-propagate-asp-tx-source-control-errors.patch
new file mode 100644 (file)
index 0000000..197f6df
--- /dev/null
@@ -0,0 +1,76 @@
+From stable+bounces-246871-greg=kroah.com@vger.kernel.org Wed May 13 16:09:46 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 09:53:59 -0400
+Subject: ALSA: hda: cs35l56: Propagate ASP TX source control errors
+To: stable@vger.kernel.org
+Cc: "Cássio Gabriel" <cassiogabrielcontato@gmail.com>, "Richard Fitzgerald" <rf@opensource.cirrus.com>, "Takashi Iwai" <tiwai@suse.de>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260513135359.3741836-1-sashal@kernel.org>
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit 0faacc0841d66f3cf51989c10a83f3a82d52ff2c ]
+
+cs35l56_hda_mixer_get() ignores regmap_read() and
+cs35l56_hda_mixer_put() ignores regmap_update_bits_check().
+
+This makes the ASP TX source controls report success when a regmap
+access fails. The write path returns no change instead of an error,
+and the read path continues after a failed read instead of aborting
+the control callback.
+
+Propagate the regmap errors, matching the posture and volume controls
+in this driver.
+
+Fixes: 73cfbfa9caea ("ALSA: hda/cs35l56: Add driver for Cirrus Logic CS35L56 amplifier")
+Cc: stable@vger.kernel.org
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Reviewed-by: Richard Fitzgerald <rf@opensource.cirrus.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20260423-alsa-cs35l56-asp-tx-source-errors-v1-1-17ea7c62ec31@gmail.com
+[ adjusted path to sound/pci/hda/ and dropped cs35l56_hda_wait_dsp_ready() context ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/pci/hda/cs35l56_hda.c |   19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/sound/pci/hda/cs35l56_hda.c
++++ b/sound/pci/hda/cs35l56_hda.c
+@@ -176,9 +176,13 @@ static int cs35l56_hda_mixer_get(struct
+ {
+       struct cs35l56_hda *cs35l56 = snd_kcontrol_chip(kcontrol);
+       unsigned int reg_val;
+-      int i;
++      int i, ret;
++
++      ret = regmap_read(cs35l56->base.regmap, kcontrol->private_value,
++                        &reg_val);
++      if (ret)
++              return ret;
+-      regmap_read(cs35l56->base.regmap, kcontrol->private_value, &reg_val);
+       reg_val &= CS35L56_ASP_TXn_SRC_MASK;
+       for (i = 0; i < CS35L56_NUM_INPUT_SRC; ++i) {
+@@ -197,13 +201,18 @@ static int cs35l56_hda_mixer_put(struct
+       struct cs35l56_hda *cs35l56 = snd_kcontrol_chip(kcontrol);
+       unsigned int item = ucontrol->value.enumerated.item[0];
+       bool changed;
++      int ret;
+       if (item >= CS35L56_NUM_INPUT_SRC)
+               return -EINVAL;
+-      regmap_update_bits_check(cs35l56->base.regmap, kcontrol->private_value,
+-                               CS35L56_INPUT_MASK, cs35l56_tx_input_values[item],
+-                               &changed);
++      ret = regmap_update_bits_check(cs35l56->base.regmap,
++                                     kcontrol->private_value,
++                                     CS35L56_INPUT_MASK,
++                                     cs35l56_tx_input_values[item],
++                                     &changed);
++      if (ret)
++              return ret;
+       return changed;
+ }
diff --git a/queue-6.6/alsa-misc-use-guard-for-spin-locks.patch b/queue-6.6/alsa-misc-use-guard-for-spin-locks.patch
new file mode 100644 (file)
index 0000000..81f47ca
--- /dev/null
@@ -0,0 +1,73 @@
+From stable+bounces-246877-greg=kroah.com@vger.kernel.org Wed May 13 16:24:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 10:10:23 -0400
+Subject: ALSA: misc: Use guard() for spin locks
+To: stable@vger.kernel.org
+Cc: Takashi Iwai <tiwai@suse.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513141025.3748103-1-sashal@kernel.org>
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit b8e1684163ae52db90f428965bd9aaff7205c02e ]
+
+Clean up the code using guard() for spin locks.
+
+Merely code refactoring, and no behavior change.
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20250829151335.7342-20-tiwai@suse.de
+Stable-dep-of: 5337213381df ("ALSA: core: Serialize deferred fasync state checks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/core/misc.c |   25 ++++++++++---------------
+ 1 file changed, 10 insertions(+), 15 deletions(-)
+
+--- a/sound/core/misc.c
++++ b/sound/core/misc.c
+@@ -202,35 +202,30 @@ int snd_fasync_helper(int fd, struct fil
+               INIT_LIST_HEAD(&fasync->list);
+       }
+-      spin_lock_irq(&snd_fasync_lock);
+-      if (*fasyncp) {
+-              kfree(fasync);
+-              fasync = *fasyncp;
+-      } else {
+-              if (!fasync) {
+-                      spin_unlock_irq(&snd_fasync_lock);
+-                      return 0;
++      scoped_guard(spinlock_irq, &snd_fasync_lock) {
++              if (*fasyncp) {
++                      kfree(fasync);
++                      fasync = *fasyncp;
++              } else {
++                      if (!fasync)
++                              return 0;
++                      *fasyncp = fasync;
+               }
+-              *fasyncp = fasync;
++              fasync->on = on;
+       }
+-      fasync->on = on;
+-      spin_unlock_irq(&snd_fasync_lock);
+       return fasync_helper(fd, file, on, &fasync->fasync);
+ }
+ EXPORT_SYMBOL_GPL(snd_fasync_helper);
+ void snd_kill_fasync(struct snd_fasync *fasync, int signal, int poll)
+ {
+-      unsigned long flags;
+-
+       if (!fasync || !fasync->on)
+               return;
+-      spin_lock_irqsave(&snd_fasync_lock, flags);
++      guard(spinlock_irqsave)(&snd_fasync_lock);
+       fasync->signal = signal;
+       fasync->poll = poll;
+       list_move(&fasync->list, &snd_fasync_list);
+       schedule_work(&snd_fasync_work);
+-      spin_unlock_irqrestore(&snd_fasync_lock, flags);
+ }
+ EXPORT_SYMBOL_GPL(snd_kill_fasync);
diff --git a/queue-6.6/alsa-seq-fix-ump-group-16-filtering.patch b/queue-6.6/alsa-seq-fix-ump-group-16-filtering.patch
new file mode 100644 (file)
index 0000000..c5f1cb8
--- /dev/null
@@ -0,0 +1,79 @@
+From stable+bounces-246886-greg=kroah.com@vger.kernel.org Wed May 13 16:39:59 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 10:34:30 -0400
+Subject: ALSA: seq: Fix UMP group 16 filtering
+To: stable@vger.kernel.org
+Cc: "Cássio Gabriel" <cassiogabrielcontato@gmail.com>, "Takashi Iwai" <tiwai@suse.de>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260513143430.3755036-2-sashal@kernel.org>
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit 92429ca999db99febced82f23362a71b2ba4c1d8 ]
+
+The sequencer UAPI defines group_filter as an unsigned int bitmap.
+Bit 0 filters groupless messages and bits 1-16 filter UMP groups 1-16.
+
+The internal snd_seq_client storage is only unsigned short, so bit 16
+is truncated when userspace sets the filter. The same truncation affects
+the automatic UMP client filter used to avoid delivery to inactive
+groups, so events for group 16 cannot be filtered.
+
+Store the internal bitmap as unsigned int and keep both userspace-provided
+and automatically generated values limited to the defined UAPI bits.
+
+Fixes: d2b706077792 ("ALSA: seq: Add UMP group filter")
+Cc: stable@vger.kernel.org
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Link: https://patch.msgid.link/20260506-alsa-seq-ump-group16-filter-v1-1-b75160bf6993@gmail.com
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/core/seq/seq_clientmgr.c  |    2 +-
+ sound/core/seq/seq_clientmgr.h  |    5 ++++-
+ sound/core/seq/seq_ump_client.c |    2 +-
+ 3 files changed, 6 insertions(+), 3 deletions(-)
+
+--- a/sound/core/seq/seq_clientmgr.c
++++ b/sound/core/seq/seq_clientmgr.c
+@@ -1333,7 +1333,7 @@ static int snd_seq_ioctl_set_client_info
+       if (client->user_pversion >= SNDRV_PROTOCOL_VERSION(1, 0, 3))
+               client->midi_version = client_info->midi_version;
+       memcpy(client->event_filter, client_info->event_filter, 32);
+-      client->group_filter = client_info->group_filter;
++      client->group_filter = client_info->group_filter & SND_SEQ_GROUP_FILTER_MASK;
+       /* notify the change */
+       snd_seq_system_client_ev_client_change(client->number);
+--- a/sound/core/seq/seq_clientmgr.h
++++ b/sound/core/seq/seq_clientmgr.h
+@@ -14,6 +14,9 @@
+ /* client manager */
++#define SND_SEQ_GROUP_FILTER_MASK     GENMASK(SNDRV_UMP_MAX_GROUPS, 0)
++#define SND_SEQ_GROUP_FILTER_GROUPS   GENMASK(SNDRV_UMP_MAX_GROUPS, 1)
++
+ struct snd_seq_user_client {
+       struct file *file;      /* file struct of client */
+       /* ... */
+@@ -40,7 +43,7 @@ struct snd_seq_client {
+       int number;             /* client number */
+       unsigned int filter;    /* filter flags */
+       DECLARE_BITMAP(event_filter, 256);
+-      unsigned short group_filter;
++      unsigned int group_filter;
+       snd_use_lock_t use_lock;
+       int event_lost;
+       /* ports */
+--- a/sound/core/seq/seq_ump_client.c
++++ b/sound/core/seq/seq_ump_client.c
+@@ -370,7 +370,7 @@ static void setup_client_group_filter(st
+       cptr = snd_seq_kernel_client_get(client->seq_client);
+       if (!cptr)
+               return;
+-      filter = ~(1U << 0); /* always allow groupless messages */
++      filter = SND_SEQ_GROUP_FILTER_GROUPS; /* always allow groupless messages */
+       for (p = 0; p < SNDRV_UMP_MAX_GROUPS; p++) {
+               if (client->ump->groups[p].active)
+                       filter &= ~(1U << (p + 1));
diff --git a/queue-6.6/alsa-seq-notify-client-and-port-info-changes.patch b/queue-6.6/alsa-seq-notify-client-and-port-info-changes.patch
new file mode 100644 (file)
index 0000000..02fa2c2
--- /dev/null
@@ -0,0 +1,69 @@
+From stable+bounces-246885-greg=kroah.com@vger.kernel.org Wed May 13 16:41:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 10:34:29 -0400
+Subject: ALSA: seq: Notify client and port info changes
+To: stable@vger.kernel.org
+Cc: Takashi Iwai <tiwai@suse.de>, Mark Lentczner <mark@glyphic.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513143430.3755036-1-sashal@kernel.org>
+
+From: Takashi Iwai <tiwai@suse.de>
+
+[ Upstream commit b8e49e24cdba27a0810a0988e810e2c68f2033cb ]
+
+It was supposed to be notified when a sequencer client info and a port
+info has changed (via SNDRV_SEQ_EVENT_CLIENT_CHANGE and
+SNDRV_SEQ_EVENT_PORT_CHANGE event, respectively), and there are
+already helper functions.  But those aren't really sent from the
+driver so far, except for the recent support of UMP, simply due to the
+lack of implementations.
+
+This patch adds the missing notifications at updating the client and
+the port info.  The formerly added notification for UMP is dropped
+because it's handled now in the port info side.
+
+Reported-by: Mark Lentczner <mark@glyphic.com>
+Link: https://lore.kernel.org/CAPnksqRok7xGa4bxq9WWimVV=28-7_j628OmrWLS=S0=hzaTHQ@mail.gmail.com
+Link: https://patch.msgid.link/20241128074734.32165-1-tiwai@suse.de
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Stable-dep-of: 92429ca999db ("ALSA: seq: Fix UMP group 16 filtering")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/core/seq/seq_clientmgr.c  |    7 +++++++
+ sound/core/seq/seq_ump_client.c |    2 --
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+--- a/sound/core/seq/seq_clientmgr.c
++++ b/sound/core/seq/seq_clientmgr.c
+@@ -1334,6 +1334,10 @@ static int snd_seq_ioctl_set_client_info
+               client->midi_version = client_info->midi_version;
+       memcpy(client->event_filter, client_info->event_filter, 32);
+       client->group_filter = client_info->group_filter;
++
++      /* notify the change */
++      snd_seq_system_client_ev_client_change(client->number);
++
+       return 0;
+ }
+@@ -1457,6 +1461,9 @@ static int snd_seq_ioctl_set_port_info(s
+       if (port) {
+               snd_seq_set_port_info(port, info);
+               snd_seq_port_unlock(port);
++              /* notify the change */
++              snd_seq_system_client_ev_port_change(info->addr.client,
++                                                   info->addr.port);
+       }
+       return 0;
+ }
+--- a/sound/core/seq/seq_ump_client.c
++++ b/sound/core/seq/seq_ump_client.c
+@@ -273,8 +273,6 @@ static void update_port_infos(struct seq
+                                               new);
+               if (err < 0)
+                       continue;
+-              /* notify to system port */
+-              snd_seq_system_client_ev_port_change(client->seq_client, i);
+       }
+ }
diff --git a/queue-6.6/bluetooth-hci_conn-fix-potential-uaf-in-create_big_sync.patch b/queue-6.6/bluetooth-hci_conn-fix-potential-uaf-in-create_big_sync.patch
new file mode 100644 (file)
index 0000000..4bb47eb
--- /dev/null
@@ -0,0 +1,96 @@
+From stable+bounces-246967-greg=kroah.com@vger.kernel.org Wed May 13 19:49:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:31:46 -0400
+Subject: Bluetooth: hci_conn: fix potential UAF in create_big_sync
+To: stable@vger.kernel.org
+Cc: David Carlier <devnexen@gmail.com>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513173146.3885958-1-sashal@kernel.org>
+
+From: David Carlier <devnexen@gmail.com>
+
+[ Upstream commit 0beddb0c380bed5f5b8e61ddbe14635bb73d0b41 ]
+
+Add hci_conn_valid() check in create_big_sync() to detect stale
+connections before proceeding with BIG creation. Handle the
+resulting -ECANCELED in create_big_complete() and re-validate the
+connection under hci_dev_lock() before dereferencing, matching the
+pattern used by create_le_conn_complete() and create_pa_complete().
+
+Keep the hci_conn object alive across the async boundary by taking
+a reference via hci_conn_get() when queueing create_big_sync(), and
+dropping it in the completion callback. The refcount and the lock
+are complementary: the refcount keeps the object allocated, while
+hci_dev_lock() serializes hci_conn_hash_del()'s list_del_rcu() on
+hdev->conn_hash, as required by hci_conn_del().
+
+hci_conn_put() is called outside hci_dev_unlock() so the final put
+(which resolves to kfree() via bt_link_release) does not run under
+hdev->lock, though the release path would be safe either way.
+
+Without this, create_big_complete() would unconditionally
+dereference the conn pointer on error, causing a use-after-free
+via hci_connect_cfm() and hci_conn_del().
+
+Fixes: eca0ae4aea66 ("Bluetooth: Add initial implementation of BIS connections")
+Cc: stable@vger.kernel.org
+Co-developed-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: David Carlier <devnexen@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+[ kept stable's `qos->bcast.out.phy == 0x02` context line instead of upstream's renamed `qos->bcast.out.phys == BIT(1)` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/hci_conn.c |   19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+--- a/net/bluetooth/hci_conn.c
++++ b/net/bluetooth/hci_conn.c
+@@ -2014,6 +2014,9 @@ static int create_big_sync(struct hci_de
+       u32 flags = 0;
+       int err;
++      if (!hci_conn_valid(hdev, conn))
++              return -ECANCELED;
++
+       if (qos->bcast.out.phy == 0x02)
+               flags |= MGMT_ADV_FLAG_SEC_2M;
+@@ -2125,11 +2128,24 @@ static void create_big_complete(struct h
+       bt_dev_dbg(hdev, "conn %p", conn);
++      if (err == -ECANCELED)
++              goto done;
++
++      hci_dev_lock(hdev);
++
++      if (!hci_conn_valid(hdev, conn))
++              goto unlock;
++
+       if (err) {
+               bt_dev_err(hdev, "Unable to create BIG: %d", err);
+               hci_connect_cfm(conn, err);
+               hci_conn_del(conn);
+       }
++
++unlock:
++      hci_dev_unlock(hdev);
++done:
++      hci_conn_put(conn);
+ }
+ struct hci_conn *hci_bind_bis(struct hci_dev *hdev, bdaddr_t *dst,
+@@ -2230,10 +2246,11 @@ struct hci_conn *hci_connect_bis(struct
+                                BT_BOUND, &data);
+       /* Queue start periodic advertising and create BIG */
+-      err = hci_cmd_sync_queue(hdev, create_big_sync, conn,
++      err = hci_cmd_sync_queue(hdev, create_big_sync, hci_conn_get(conn),
+                                create_big_complete);
+       if (err < 0) {
+               hci_conn_drop(conn);
++              hci_conn_put(conn);
+               return ERR_PTR(err);
+       }
diff --git a/queue-6.6/crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch b/queue-6.6/crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch
new file mode 100644 (file)
index 0000000..83e1507
--- /dev/null
@@ -0,0 +1,68 @@
+From stable+bounces-245016-greg=kroah.com@vger.kernel.org Sun May 10 15:15:17 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 09:15:08 -0400
+Subject: crypto: caam - guard HMAC key hex dumps in hash_digest_key
+To: stable@vger.kernel.org
+Cc: Thorsten Blum <thorsten.blum@linux.dev>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260510131508.4113857-2-sashal@kernel.org>
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ Upstream commit 177730a273b18e195263ed953853273e901b5064 ]
+
+Use print_hex_dump_devel() for dumping sensitive HMAC key bytes in
+hash_digest_key() to avoid leaking secrets at runtime when
+CONFIG_DYNAMIC_DEBUG is enabled.
+
+Fixes: 045e36780f11 ("crypto: caam - ahash hmac support")
+Fixes: 3f16f6c9d632 ("crypto: caam/qi2 - add support for ahash algorithms")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/caam/caamalg_qi2.c |    4 ++--
+ drivers/crypto/caam/caamhash.c    |    4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/crypto/caam/caamalg_qi2.c
++++ b/drivers/crypto/caam/caamalg_qi2.c
+@@ -3268,7 +3268,7 @@ static int hash_digest_key(struct caam_h
+       dpaa2_fl_set_addr(out_fle, key_dma);
+       dpaa2_fl_set_len(out_fle, digestsize);
+-      print_hex_dump_debug("key_in@" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key_in@" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, *keylen, 1);
+       print_hex_dump_debug("shdesc@" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
+@@ -3288,7 +3288,7 @@ static int hash_digest_key(struct caam_h
+               /* in progress */
+               wait_for_completion(&result.completion);
+               ret = result.err;
+-              print_hex_dump_debug("digested key@" __stringify(__LINE__)": ",
++              print_hex_dump_devel("digested key@" __stringify(__LINE__)": ",
+                                    DUMP_PREFIX_ADDRESS, 16, 4, key,
+                                    digestsize, 1);
+       }
+--- a/drivers/crypto/caam/caamhash.c
++++ b/drivers/crypto/caam/caamhash.c
+@@ -393,7 +393,7 @@ static int hash_digest_key(struct caam_h
+       append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
+                        LDST_SRCDST_BYTE_CONTEXT);
+-      print_hex_dump_debug("key_in@"__stringify(__LINE__)": ",
++      print_hex_dump_devel("key_in@"__stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, *keylen, 1);
+       print_hex_dump_debug("jobdesc@"__stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
+@@ -408,7 +408,7 @@ static int hash_digest_key(struct caam_h
+               wait_for_completion(&result.completion);
+               ret = result.err;
+-              print_hex_dump_debug("digested key@"__stringify(__LINE__)": ",
++              print_hex_dump_devel("digested key@"__stringify(__LINE__)": ",
+                                    DUMP_PREFIX_ADDRESS, 16, 4, key,
+                                    digestsize, 1);
+       }
diff --git a/queue-6.6/crypto-nx-avoid-wflex-array-member-not-at-end-warning.patch b/queue-6.6/crypto-nx-avoid-wflex-array-member-not-at-end-warning.patch
new file mode 100644 (file)
index 0000000..c6195ee
--- /dev/null
@@ -0,0 +1,120 @@
+From stable+bounces-244898-greg=kroah.com@vger.kernel.org Sat May  9 05:31:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  8 May 2026 23:31:48 -0400
+Subject: crypto: nx - Avoid -Wflex-array-member-not-at-end warning
+To: stable@vger.kernel.org
+Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260509033150.3082044-1-sashal@kernel.org>
+
+From: "Gustavo A. R. Silva" <gustavoars@kernel.org>
+
+[ Upstream commit 1e6b251ce1759392666856908113dd5d7cea044d ]
+
+-Wflex-array-member-not-at-end is coming in GCC-14, and we are getting
+ready to enable it globally. So, we are deprecating flexible-array
+members in the middle of another structure.
+
+There is currently an object (`header`) in `struct nx842_crypto_ctx`
+that contains a flexible structure (`struct nx842_crypto_header`):
+
+struct nx842_crypto_ctx {
+       ...
+        struct nx842_crypto_header header;
+        struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX];
+       ...
+};
+
+So, in order to avoid ending up with a flexible-array member in the
+middle of another struct, we use the `struct_group_tagged()` helper to
+separate the flexible array from the rest of the members in the flexible
+structure:
+
+struct nx842_crypto_header {
+       struct_group_tagged(nx842_crypto_header_hdr, hdr,
+
+               ... the rest of the members
+
+       );
+        struct nx842_crypto_header_group group[];
+} __packed;
+
+With the change described above, we can now declare an object of the
+type of the tagged struct, without embedding the flexible array in the
+middle of another struct:
+
+struct nx842_crypto_ctx {
+       ...
+        struct nx842_crypto_header_hdr header;
+        struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX];
+       ...
+ } __packed;
+
+We also use `container_of()` whenever we need to retrieve a pointer to
+the flexible structure, through which we can access the flexible
+array if needed.
+
+So, with these changes, fix the following warning:
+
+In file included from drivers/crypto/nx/nx-842.c:55:
+drivers/crypto/nx/nx-842.h:174:36: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
+  174 |         struct nx842_crypto_header header;
+      |                                    ^~~~~~
+
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: adb3faf2db1a ("crypto: nx - fix bounce buffer leaks in nx842_crypto_{alloc,free}_ctx")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/nx/nx-842.c |    6 ++++--
+ drivers/crypto/nx/nx-842.h |   10 ++++++----
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/crypto/nx/nx-842.c
++++ b/drivers/crypto/nx/nx-842.c
+@@ -251,7 +251,9 @@ int nx842_crypto_compress(struct crypto_
+                         u8 *dst, unsigned int *dlen)
+ {
+       struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
+-      struct nx842_crypto_header *hdr = &ctx->header;
++      struct nx842_crypto_header *hdr =
++                              container_of(&ctx->header,
++                                           struct nx842_crypto_header, hdr);
+       struct nx842_crypto_param p;
+       struct nx842_constraints c = *ctx->driver->constraints;
+       unsigned int groups, hdrsize, h;
+@@ -490,7 +492,7 @@ int nx842_crypto_decompress(struct crypt
+       }
+       memcpy(&ctx->header, src, hdr_len);
+-      hdr = &ctx->header;
++      hdr = container_of(&ctx->header, struct nx842_crypto_header, hdr);
+       for (n = 0; n < hdr->groups; n++) {
+               /* ignore applies to last group */
+--- a/drivers/crypto/nx/nx-842.h
++++ b/drivers/crypto/nx/nx-842.h
+@@ -157,9 +157,11 @@ struct nx842_crypto_header_group {
+ } __packed;
+ struct nx842_crypto_header {
+-      __be16 magic;           /* NX842_CRYPTO_MAGIC */
+-      __be16 ignore;          /* decompressed end bytes to ignore */
+-      u8 groups;              /* total groups in this header */
++      struct_group_tagged(nx842_crypto_header_hdr, hdr,
++              __be16 magic;           /* NX842_CRYPTO_MAGIC */
++              __be16 ignore;          /* decompressed end bytes to ignore */
++              u8 groups;              /* total groups in this header */
++      );
+       struct nx842_crypto_header_group group[];
+ } __packed;
+@@ -171,7 +173,7 @@ struct nx842_crypto_ctx {
+       u8 *wmem;
+       u8 *sbounce, *dbounce;
+-      struct nx842_crypto_header header;
++      struct nx842_crypto_header_hdr header;
+       struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX];
+       struct nx842_driver *driver;
diff --git a/queue-6.6/crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch b/queue-6.6/crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch
new file mode 100644 (file)
index 0000000..7161948
--- /dev/null
@@ -0,0 +1,51 @@
+From stable+bounces-244900-greg=kroah.com@vger.kernel.org Sat May  9 05:31:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  8 May 2026 23:31:50 -0400
+Subject: crypto: nx - fix bounce buffer leaks in nx842_crypto_{alloc,free}_ctx
+To: stable@vger.kernel.org
+Cc: Thorsten Blum <thorsten.blum@linux.dev>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260509033150.3082044-3-sashal@kernel.org>
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ Upstream commit adb3faf2db1a66d0f015b44ac909a32dfc7f2f9c ]
+
+The bounce buffers are allocated with __get_free_pages() using
+BOUNCE_BUFFER_ORDER (order 2 = 4 pages), but both the allocation error
+path and nx842_crypto_free_ctx() release the buffers with free_page().
+Use free_pages() with the matching order instead.
+
+Fixes: ed70b479c2c0 ("crypto: nx - add hardware 842 crypto comp alg")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/nx/nx-842.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/crypto/nx/nx-842.c
++++ b/drivers/crypto/nx/nx-842.c
+@@ -116,8 +116,8 @@ void *nx842_crypto_alloc_ctx(struct nx84
+       ctx->dbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER);
+       if (!ctx->wmem || !ctx->sbounce || !ctx->dbounce) {
+               kfree(ctx->wmem);
+-              free_page((unsigned long)ctx->sbounce);
+-              free_page((unsigned long)ctx->dbounce);
++              free_pages((unsigned long)ctx->sbounce, BOUNCE_BUFFER_ORDER);
++              free_pages((unsigned long)ctx->dbounce, BOUNCE_BUFFER_ORDER);
+               kfree(ctx);
+               return ERR_PTR(-ENOMEM);
+       }
+@@ -131,8 +131,8 @@ void nx842_crypto_free_ctx(void *p)
+       struct nx842_crypto_ctx *ctx = p;
+       kfree(ctx->wmem);
+-      free_page((unsigned long)ctx->sbounce);
+-      free_page((unsigned long)ctx->dbounce);
++      free_pages((unsigned long)ctx->sbounce, BOUNCE_BUFFER_ORDER);
++      free_pages((unsigned long)ctx->dbounce, BOUNCE_BUFFER_ORDER);
+ }
+ EXPORT_SYMBOL_GPL(nx842_crypto_free_ctx);
diff --git a/queue-6.6/crypto-nx-migrate-to-scomp-api.patch b/queue-6.6/crypto-nx-migrate-to-scomp-api.patch
new file mode 100644 (file)
index 0000000..6dadaa8
--- /dev/null
@@ -0,0 +1,287 @@
+From stable+bounces-244899-greg=kroah.com@vger.kernel.org Sat May  9 05:31:59 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  8 May 2026 23:31:49 -0400
+Subject: crypto: nx - Migrate to scomp API
+To: stable@vger.kernel.org
+Cc: Ard Biesheuvel <ardb@kernel.org>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260509033150.3082044-2-sashal@kernel.org>
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit 980b5705f4e73f567e405cd18337cc32fd51cf79 ]
+
+The only remaining user of 842 compression has been migrated to the
+acomp compression API, and so the NX hardware driver has to follow suit,
+given that no users of the obsolete 'comp' API remain, and it is going
+to be removed.
+
+So migrate the NX driver code to scomp. These will be wrapped and
+exposed as acomp implementation via the crypto subsystem's
+acomp-to-scomp adaptation layer.
+
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: adb3faf2db1a ("crypto: nx - fix bounce buffer leaks in nx842_crypto_{alloc,free}_ctx")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/nx/nx-842.c            |   33 +++++++++++++++++++--------------
+ drivers/crypto/nx/nx-842.h            |   15 ++++++++-------
+ drivers/crypto/nx/nx-common-powernv.c |   31 +++++++++++++++----------------
+ drivers/crypto/nx/nx-common-pseries.c |   33 ++++++++++++++++-----------------
+ 4 files changed, 58 insertions(+), 54 deletions(-)
+
+--- a/drivers/crypto/nx/nx-842.c
++++ b/drivers/crypto/nx/nx-842.c
+@@ -101,9 +101,13 @@ static int update_param(struct nx842_cry
+       return 0;
+ }
+-int nx842_crypto_init(struct crypto_tfm *tfm, struct nx842_driver *driver)
++void *nx842_crypto_alloc_ctx(struct nx842_driver *driver)
+ {
+-      struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
++      struct nx842_crypto_ctx *ctx;
++
++      ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
++      if (!ctx)
++              return ERR_PTR(-ENOMEM);
+       spin_lock_init(&ctx->lock);
+       ctx->driver = driver;
+@@ -114,22 +118,23 @@ int nx842_crypto_init(struct crypto_tfm
+               kfree(ctx->wmem);
+               free_page((unsigned long)ctx->sbounce);
+               free_page((unsigned long)ctx->dbounce);
+-              return -ENOMEM;
++              kfree(ctx);
++              return ERR_PTR(-ENOMEM);
+       }
+-      return 0;
++      return ctx;
+ }
+-EXPORT_SYMBOL_GPL(nx842_crypto_init);
++EXPORT_SYMBOL_GPL(nx842_crypto_alloc_ctx);
+-void nx842_crypto_exit(struct crypto_tfm *tfm)
++void nx842_crypto_free_ctx(void *p)
+ {
+-      struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
++      struct nx842_crypto_ctx *ctx = p;
+       kfree(ctx->wmem);
+       free_page((unsigned long)ctx->sbounce);
+       free_page((unsigned long)ctx->dbounce);
+ }
+-EXPORT_SYMBOL_GPL(nx842_crypto_exit);
++EXPORT_SYMBOL_GPL(nx842_crypto_free_ctx);
+ static void check_constraints(struct nx842_constraints *c)
+ {
+@@ -246,11 +251,11 @@ nospc:
+       return update_param(p, slen, dskip + dlen);
+ }
+-int nx842_crypto_compress(struct crypto_tfm *tfm,
++int nx842_crypto_compress(struct crypto_scomp *tfm,
+                         const u8 *src, unsigned int slen,
+-                        u8 *dst, unsigned int *dlen)
++                        u8 *dst, unsigned int *dlen, void *pctx)
+ {
+-      struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
++      struct nx842_crypto_ctx *ctx = pctx;
+       struct nx842_crypto_header *hdr =
+                               container_of(&ctx->header,
+                                            struct nx842_crypto_header, hdr);
+@@ -431,11 +436,11 @@ usesw:
+       return update_param(p, slen + padding, dlen);
+ }
+-int nx842_crypto_decompress(struct crypto_tfm *tfm,
++int nx842_crypto_decompress(struct crypto_scomp *tfm,
+                           const u8 *src, unsigned int slen,
+-                          u8 *dst, unsigned int *dlen)
++                          u8 *dst, unsigned int *dlen, void *pctx)
+ {
+-      struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
++      struct nx842_crypto_ctx *ctx = pctx;
+       struct nx842_crypto_header *hdr;
+       struct nx842_crypto_param p;
+       struct nx842_constraints c = *ctx->driver->constraints;
+--- a/drivers/crypto/nx/nx-842.h
++++ b/drivers/crypto/nx/nx-842.h
+@@ -3,7 +3,6 @@
+ #ifndef __NX_842_H__
+ #define __NX_842_H__
+-#include <crypto/algapi.h>
+ #include <linux/kernel.h>
+ #include <linux/init.h>
+ #include <linux/module.h>
+@@ -101,6 +100,8 @@
+ #define LEN_ON_SIZE(pa, size) ((size) - ((pa) & ((size) - 1)))
+ #define LEN_ON_PAGE(pa)               LEN_ON_SIZE(pa, PAGE_SIZE)
++struct crypto_scomp;
++
+ static inline unsigned long nx842_get_pa(void *addr)
+ {
+       if (!is_vmalloc_addr(addr))
+@@ -179,13 +180,13 @@ struct nx842_crypto_ctx {
+       struct nx842_driver *driver;
+ };
+-int nx842_crypto_init(struct crypto_tfm *tfm, struct nx842_driver *driver);
+-void nx842_crypto_exit(struct crypto_tfm *tfm);
+-int nx842_crypto_compress(struct crypto_tfm *tfm,
++void *nx842_crypto_alloc_ctx(struct nx842_driver *driver);
++void nx842_crypto_free_ctx(void *ctx);
++int nx842_crypto_compress(struct crypto_scomp *tfm,
+                         const u8 *src, unsigned int slen,
+-                        u8 *dst, unsigned int *dlen);
+-int nx842_crypto_decompress(struct crypto_tfm *tfm,
++                        u8 *dst, unsigned int *dlen, void *ctx);
++int nx842_crypto_decompress(struct crypto_scomp *tfm,
+                           const u8 *src, unsigned int slen,
+-                          u8 *dst, unsigned int *dlen);
++                          u8 *dst, unsigned int *dlen, void *ctx);
+ #endif /* __NX_842_H__ */
+--- a/drivers/crypto/nx/nx-common-powernv.c
++++ b/drivers/crypto/nx/nx-common-powernv.c
+@@ -9,6 +9,7 @@
+ #include "nx-842.h"
++#include <crypto/internal/scompress.h>
+ #include <linux/timer.h>
+ #include <asm/prom.h>
+@@ -1031,23 +1032,21 @@ static struct nx842_driver nx842_powernv
+       .decompress =   nx842_powernv_decompress,
+ };
+-static int nx842_powernv_crypto_init(struct crypto_tfm *tfm)
++static void *nx842_powernv_crypto_alloc_ctx(void)
+ {
+-      return nx842_crypto_init(tfm, &nx842_powernv_driver);
++      return nx842_crypto_alloc_ctx(&nx842_powernv_driver);
+ }
+-static struct crypto_alg nx842_powernv_alg = {
+-      .cra_name               = "842",
+-      .cra_driver_name        = "842-nx",
+-      .cra_priority           = 300,
+-      .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
+-      .cra_ctxsize            = sizeof(struct nx842_crypto_ctx),
+-      .cra_module             = THIS_MODULE,
+-      .cra_init               = nx842_powernv_crypto_init,
+-      .cra_exit               = nx842_crypto_exit,
+-      .cra_u                  = { .compress = {
+-      .coa_compress           = nx842_crypto_compress,
+-      .coa_decompress         = nx842_crypto_decompress } }
++static struct scomp_alg nx842_powernv_alg = {
++      .base.cra_name          = "842",
++      .base.cra_driver_name   = "842-nx",
++      .base.cra_priority      = 300,
++      .base.cra_module        = THIS_MODULE,
++
++      .alloc_ctx              = nx842_powernv_crypto_alloc_ctx,
++      .free_ctx               = nx842_crypto_free_ctx,
++      .compress               = nx842_crypto_compress,
++      .decompress             = nx842_crypto_decompress,
+ };
+ static __init int nx_compress_powernv_init(void)
+@@ -1107,7 +1106,7 @@ static __init int nx_compress_powernv_in
+               nx842_powernv_exec = nx842_exec_vas;
+       }
+-      ret = crypto_register_alg(&nx842_powernv_alg);
++      ret = crypto_register_scomp(&nx842_powernv_alg);
+       if (ret) {
+               nx_delete_coprocs();
+               return ret;
+@@ -1128,7 +1127,7 @@ static void __exit nx_compress_powernv_e
+       if (!nx842_ct)
+               vas_unregister_api_powernv();
+-      crypto_unregister_alg(&nx842_powernv_alg);
++      crypto_unregister_scomp(&nx842_powernv_alg);
+       nx_delete_coprocs();
+ }
+--- a/drivers/crypto/nx/nx-common-pseries.c
++++ b/drivers/crypto/nx/nx-common-pseries.c
+@@ -11,6 +11,7 @@
+ #include <asm/vio.h>
+ #include <asm/hvcall.h>
+ #include <asm/vas.h>
++#include <crypto/internal/scompress.h>
+ #include "nx-842.h"
+ #include "nx_csbcpb.h" /* struct nx_csbcpb */
+@@ -1008,23 +1009,21 @@ static struct nx842_driver nx842_pseries
+       .decompress =   nx842_pseries_decompress,
+ };
+-static int nx842_pseries_crypto_init(struct crypto_tfm *tfm)
++static void *nx842_pseries_crypto_alloc_ctx(void)
+ {
+-      return nx842_crypto_init(tfm, &nx842_pseries_driver);
++      return nx842_crypto_alloc_ctx(&nx842_pseries_driver);
+ }
+-static struct crypto_alg nx842_pseries_alg = {
+-      .cra_name               = "842",
+-      .cra_driver_name        = "842-nx",
+-      .cra_priority           = 300,
+-      .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
+-      .cra_ctxsize            = sizeof(struct nx842_crypto_ctx),
+-      .cra_module             = THIS_MODULE,
+-      .cra_init               = nx842_pseries_crypto_init,
+-      .cra_exit               = nx842_crypto_exit,
+-      .cra_u                  = { .compress = {
+-      .coa_compress           = nx842_crypto_compress,
+-      .coa_decompress         = nx842_crypto_decompress } }
++static struct scomp_alg nx842_pseries_alg = {
++      .base.cra_name          = "842",
++      .base.cra_driver_name   = "842-nx",
++      .base.cra_priority      = 300,
++      .base.cra_module        = THIS_MODULE,
++
++      .alloc_ctx              = nx842_pseries_crypto_alloc_ctx,
++      .free_ctx               = nx842_crypto_free_ctx,
++      .compress               = nx842_crypto_compress,
++      .decompress             = nx842_crypto_decompress,
+ };
+ static int nx842_probe(struct vio_dev *viodev,
+@@ -1072,7 +1071,7 @@ static int nx842_probe(struct vio_dev *v
+       if (ret)
+               goto error;
+-      ret = crypto_register_alg(&nx842_pseries_alg);
++      ret = crypto_register_scomp(&nx842_pseries_alg);
+       if (ret) {
+               dev_err(&viodev->dev, "could not register comp alg: %d\n", ret);
+               goto error;
+@@ -1120,7 +1119,7 @@ static void nx842_remove(struct vio_dev
+       if (caps_feat)
+               sysfs_remove_group(&viodev->dev.kobj, &nxcop_caps_attr_group);
+-      crypto_unregister_alg(&nx842_pseries_alg);
++      crypto_unregister_scomp(&nx842_pseries_alg);
+       spin_lock_irqsave(&devdata_mutex, flags);
+       old_devdata = rcu_dereference_check(devdata,
+@@ -1252,7 +1251,7 @@ static void __exit nx842_pseries_exit(vo
+       vas_unregister_api_pseries();
+-      crypto_unregister_alg(&nx842_pseries_alg);
++      crypto_unregister_scomp(&nx842_pseries_alg);
+       spin_lock_irqsave(&devdata_mutex, flags);
+       old_devdata = rcu_dereference_check(devdata,
diff --git a/queue-6.6/erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch b/queue-6.6/erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch
new file mode 100644 (file)
index 0000000..4788b53
--- /dev/null
@@ -0,0 +1,58 @@
+From stable+bounces-244910-greg=kroah.com@vger.kernel.org Sat May  9 05:54:40 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  8 May 2026 23:54:21 -0400
+Subject: erofs: fix unsigned underflow in z_erofs_lz4_handle_overlap()
+To: stable@vger.kernel.org
+Cc: Junrui Luo <moonafterrain@outlook.com>, Yuhao Jiang <danisjiang@gmail.com>, Gao Xiang <hsiangkao@linux.alibaba.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260509035421.3122562-1-sashal@kernel.org>
+
+From: Junrui Luo <moonafterrain@outlook.com>
+
+[ Upstream commit 21e161de2dc660b1bb70ef5b156ab8e6e1cca3ab ]
+
+Some crafted images can have illegal (!partial_decoding &&
+m_llen < m_plen) extents, and the LZ4 inplace decompression path
+can be wrongly hit, but it cannot handle (outpages < inpages)
+properly: "outpages - inpages" wraps to a large value and
+the subsequent rq->out[] access reads past the decompressed_pages
+array.
+
+However, such crafted cases can correctly result in a corruption
+report in the normal LZ4 non-inplace path.
+
+Let's add an additional check to fix this for backporting.
+
+Reproducible image (base64-encoded gzipped blob):
+
+H4sIAJGR12kCA+3SPUoDQRgG4MkmkkZk8QRbRFIIi9hbpEjrHQI5ghfwCN5BLCzTGtLbBI+g
+dilSJo1CnIm7GEXFxhT6PDDwfrs73/ywIQD/1ePD4r7Ou6ETsrq4mu7XcWfj++Pb58nJU/9i
+PNtbjhan04/9GtX4qVYc814WDqt6FaX5s+ZwXXeq52lndT6IuVvlblytLMvh4Gzwaf90nsvz
+2DF/21+20T/ldgp5s1jXRaN4t/8izsy/OUB6e/Qa79r+JwAAAAAAAL52vQVuGQAAAP6+my1w
+ywAAAAAAAADwu14ATsEYtgBQAAA=
+
+$ mount -t erofs -o cache_strategy=disabled foo.erofs /mnt
+$ dd if=/mnt/data of=/dev/null bs=4096 count=1
+
+Fixes: 598162d05080 ("erofs: support decompress big pcluster for lz4 backend")
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
+Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+[ inverted condition to early-out `goto docopy` form and used `ctx->inpages`/`ctx->outpages` instead of `rq->` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/erofs/decompressor.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/erofs/decompressor.c
++++ b/fs/erofs/decompressor.c
+@@ -133,6 +133,7 @@ static void *z_erofs_lz4_handle_overlap(
+       if (rq->inplace_io) {
+               omargin = PAGE_ALIGN(ctx->oend) - ctx->oend;
+               if (rq->partial_decoding || !may_inplace ||
++                  ctx->outpages < ctx->inpages ||
+                   omargin < LZ4_DECOMPRESS_INPLACE_MARGIN(rq->inputsize))
+                       goto docopy;
diff --git a/queue-6.6/fbcon-avoid-oob-font-access-if-console-rotation-fails.patch b/queue-6.6/fbcon-avoid-oob-font-access-if-console-rotation-fails.patch
new file mode 100644 (file)
index 0000000..cca1514
--- /dev/null
@@ -0,0 +1,56 @@
+From stable+bounces-247304-greg=kroah.com@vger.kernel.org Fri May 15 03:30:44 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 21:26:17 -0400
+Subject: fbcon: Avoid OOB font access if console rotation fails
+To: stable@vger.kernel.org
+Cc: Thomas Zimmermann <tzimmermann@suse.de>, Helge Deller <deller@gmx.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515012617.2652194-1-sashal@kernel.org>
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit e4ef723d8975a2694cc90733a6b888a5e2841842 ]
+
+Clear the font buffer if the reallocation during console rotation fails
+in fbcon_rotate_font(). The putcs implementations for the rotated buffer
+will return early in this case. See [1] for an example.
+
+Currently, fbcon_rotate_font() keeps the old buffer, which is too small
+for the rotated font. Printing to the rotated console with a high-enough
+character code will overflow the font buffer.
+
+v2:
+- fix typos in commit message
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Fixes: 6cc50e1c5b57 ("[PATCH] fbcon: Console Rotation - Add support to rotate font bitmap")
+Cc: stable@vger.kernel.org # v2.6.15+
+Link: https://elixir.bootlin.com/linux/v6.19/source/drivers/video/fbdev/core/fbcon_ccw.c#L144 # [1]
+Signed-off-by: Helge Deller <deller@gmx.de>
+[ renamed `par` to `ops` to match the 6.12 local pointer name ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/core/fbcon_rotate.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/video/fbdev/core/fbcon_rotate.c
++++ b/drivers/video/fbdev/core/fbcon_rotate.c
+@@ -46,6 +46,10 @@ static int fbcon_rotate_font(struct fb_i
+               info->fbops->fb_sync(info);
+       if (ops->fd_size < d_cellsize * len) {
++              kfree(ops->fontbuffer);
++              ops->fontbuffer = NULL;
++              ops->fd_size = 0;
++
+               dst = kmalloc_array(len, d_cellsize, GFP_KERNEL);
+               if (dst == NULL) {
+@@ -54,7 +58,6 @@ static int fbcon_rotate_font(struct fb_i
+               }
+               ops->fd_size = d_cellsize * len;
+-              kfree(ops->fontbuffer);
+               ops->fontbuffer = dst;
+       }
diff --git a/queue-6.6/mm-hugetlb_cma-round-up-per_node-before-logging-it.patch b/queue-6.6/mm-hugetlb_cma-round-up-per_node-before-logging-it.patch
new file mode 100644 (file)
index 0000000..42d4dd4
--- /dev/null
@@ -0,0 +1,79 @@
+From stable+bounces-247201-greg=kroah.com@vger.kernel.org Thu May 14 15:07:38 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 09:06:35 -0400
+Subject: mm/hugetlb_cma: round up per_node before logging it
+To: stable@vger.kernel.org
+Cc: Sang-Heon Jeon <ekffu200098@gmail.com>, Muchun Song <muchun.song@linux.dev>, David Hildenbrand <david@kernel.org>, Oscar Salvador <osalvador@suse.de>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514130635.228150-1-sashal@kernel.org>
+
+From: Sang-Heon Jeon <ekffu200098@gmail.com>
+
+[ Upstream commit 8f5ce56b76303c55b78a87af996e2e0f8535f979 ]
+
+When the user requests a total hugetlb CMA size without per-node
+specification, hugetlb_cma_reserve() computes per_node from
+hugetlb_cma_size and the number of nodes that have memory
+
+        per_node = DIV_ROUND_UP(hugetlb_cma_size,
+                                nodes_weight(hugetlb_bootmem_nodes));
+
+The reservation loop later computes
+
+        size = round_up(min(per_node, hugetlb_cma_size - reserved),
+                          PAGE_SIZE << order);
+
+So the actually reserved per_node size is multiple of (PAGE_SIZE <<
+order), but the logged per_node is not rounded up, so it may be smaller
+than the actual reserved size.
+
+For example, as the existing comment describes, if a 3 GB area is
+requested on a machine with 4 NUMA nodes that have memory, 1 GB is
+allocated on the first three nodes, but the printed log is
+
+        hugetlb_cma: reserve 3072 MiB, up to 768 MiB per node
+
+Round per_node up to (PAGE_SIZE << order) before logging so that the
+printed log always matches the actual reserved size.  No functional change
+to the actual reservation size, as the following case analysis shows
+
+1. remaining (hugetlb_cma_size - reserved) >= rounded per_node
+ - AS-IS: min() picks unrounded per_node;
+    round_up() returns rounded per_node
+ - TO-BE: min() picks rounded per_node;
+    round_up() returns rounded per_node (no-op)
+2. remaining < unrounded per_node
+ - AS-IS: min() picks remaining;
+    round_up() returns round_up(remaining)
+ - TO-BE: min() picks remaining;
+    round_up() returns round_up(remaining)
+3. unrounded per_node <= remaining < rounded per_node
+ - AS-IS: min() picks unrounded per_node;
+    round_up() returns rounded per_node
+ - TO-BE: min() picks remaining;
+    round_up() returns round_up(remaining) equals rounded per_node
+
+Link: https://lore.kernel.org/20260422143353.852257-1-ekffu200098@gmail.com
+Fixes: cf11e85fc08c ("mm: hugetlb: optionally allocate gigantic hugepages using cma") # 5.7
+Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
+Reviewed-by: Muchun Song <muchun.song@linux.dev>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[ applied the single-line addition to mm/hugetlb.c since mm/hugetlb_cma.c didn't exist yet in 6.12 ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/hugetlb.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -7493,6 +7493,7 @@ void __init hugetlb_cma_reserve(int orde
+                * let's allocate 1 GB on first three nodes and ignore the last one.
+                */
+               per_node = DIV_ROUND_UP(hugetlb_cma_size, nr_online_nodes);
++              per_node = round_up(per_node, PAGE_SIZE << order);
+               pr_info("hugetlb_cma: reserve %lu MiB, up to %lu MiB per node\n",
+                       hugetlb_cma_size / SZ_1M, per_node / SZ_1M);
+       }
diff --git a/queue-6.6/net-ipv4-stop-checking-crypto_ahash_alignmask.patch b/queue-6.6/net-ipv4-stop-checking-crypto_ahash_alignmask.patch
new file mode 100644 (file)
index 0000000..e4124ce
--- /dev/null
@@ -0,0 +1,87 @@
+From stable+bounces-246943-greg=kroah.com@vger.kernel.org Wed May 13 18:49:24 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 12:46:33 -0400
+Subject: net: ipv4: stop checking crypto_ahash_alignmask
+To: stable@vger.kernel.org
+Cc: Eric Biggers <ebiggers@google.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513164635.3816490-1-sashal@kernel.org>
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit e77f5dd701381cef35b9ea8b6dea6e62c8a7f9f3 ]
+
+Now that the alignmask for ahash and shash algorithms is always 0,
+crypto_ahash_alignmask() always returns 0 and will be removed.  In
+preparation for this, stop checking crypto_ahash_alignmask() in ah4.c.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ec54093e6a8f ("xfrm: ah: account for ESN high bits in async callbacks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ah4.c |   17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+--- a/net/ipv4/ah4.c
++++ b/net/ipv4/ah4.c
+@@ -27,9 +27,7 @@ static void *ah_alloc_tmp(struct crypto_
+ {
+       unsigned int len;
+-      len = size + crypto_ahash_digestsize(ahash) +
+-            (crypto_ahash_alignmask(ahash) &
+-             ~(crypto_tfm_ctx_alignment() - 1));
++      len = size + crypto_ahash_digestsize(ahash);
+       len = ALIGN(len, crypto_tfm_ctx_alignment());
+@@ -46,10 +44,9 @@ static inline u8 *ah_tmp_auth(void *tmp,
+       return tmp + offset;
+ }
+-static inline u8 *ah_tmp_icv(struct crypto_ahash *ahash, void *tmp,
+-                           unsigned int offset)
++static inline u8 *ah_tmp_icv(void *tmp, unsigned int offset)
+ {
+-      return PTR_ALIGN((u8 *)tmp + offset, crypto_ahash_alignmask(ahash) + 1);
++      return tmp + offset;
+ }
+ static inline struct ahash_request *ah_tmp_req(struct crypto_ahash *ahash,
+@@ -129,7 +126,7 @@ static void ah_output_done(void *data, i
+       int ihl = ip_hdrlen(skb);
+       iph = AH_SKB_CB(skb)->tmp;
+-      icv = ah_tmp_icv(ahp->ahash, iph, ihl);
++      icv = ah_tmp_icv(iph, ihl);
+       memcpy(ah->auth_data, icv, ahp->icv_trunc_len);
+       top_iph->tos = iph->tos;
+@@ -182,7 +179,7 @@ static int ah_output(struct xfrm_state *
+       if (!iph)
+               goto out;
+       seqhi = (__be32 *)((char *)iph + ihl);
+-      icv = ah_tmp_icv(ahash, seqhi, seqhi_len);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       req = ah_tmp_req(ahash, icv);
+       sg = ah_req_sg(ahash, req);
+       seqhisg = sg + nfrags;
+@@ -279,7 +276,7 @@ static void ah_input_done(void *data, in
+       work_iph = AH_SKB_CB(skb)->tmp;
+       auth_data = ah_tmp_auth(work_iph, ihl);
+-      icv = ah_tmp_icv(ahp->ahash, auth_data, ahp->icv_trunc_len);
++      icv = ah_tmp_icv(auth_data, ahp->icv_trunc_len);
+       err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
+       if (err)
+@@ -374,7 +371,7 @@ static int ah_input(struct xfrm_state *x
+       seqhi = (__be32 *)((char *)work_iph + ihl);
+       auth_data = ah_tmp_auth(seqhi, seqhi_len);
+-      icv = ah_tmp_icv(ahash, auth_data, ahp->icv_trunc_len);
++      icv = ah_tmp_icv(auth_data, ahp->icv_trunc_len);
+       req = ah_tmp_req(ahash, icv);
+       sg = ah_req_sg(ahash, req);
+       seqhisg = sg + nfrags;
diff --git a/queue-6.6/net-ipv6-stop-checking-crypto_ahash_alignmask.patch b/queue-6.6/net-ipv6-stop-checking-crypto_ahash_alignmask.patch
new file mode 100644 (file)
index 0000000..7eb3318
--- /dev/null
@@ -0,0 +1,87 @@
+From stable+bounces-246944-greg=kroah.com@vger.kernel.org Wed May 13 18:49:27 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 12:46:34 -0400
+Subject: net: ipv6: stop checking crypto_ahash_alignmask
+To: stable@vger.kernel.org
+Cc: Eric Biggers <ebiggers@google.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513164635.3816490-2-sashal@kernel.org>
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit 0a6bfaa0e695facb072f2fedfb55df37c4483b50 ]
+
+Now that the alignmask for ahash and shash algorithms is always 0,
+crypto_ahash_alignmask() always returns 0 and will be removed.  In
+preparation for this, stop checking crypto_ahash_alignmask() in ah6.c.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ec54093e6a8f ("xfrm: ah: account for ESN high bits in async callbacks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ah6.c |   17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+--- a/net/ipv6/ah6.c
++++ b/net/ipv6/ah6.c
+@@ -79,9 +79,7 @@ static void *ah_alloc_tmp(struct crypto_
+ {
+       unsigned int len;
+-      len = size + crypto_ahash_digestsize(ahash) +
+-            (crypto_ahash_alignmask(ahash) &
+-             ~(crypto_tfm_ctx_alignment() - 1));
++      len = size + crypto_ahash_digestsize(ahash);
+       len = ALIGN(len, crypto_tfm_ctx_alignment());
+@@ -103,10 +101,9 @@ static inline u8 *ah_tmp_auth(u8 *tmp, u
+       return tmp + offset;
+ }
+-static inline u8 *ah_tmp_icv(struct crypto_ahash *ahash, void *tmp,
+-                           unsigned int offset)
++static inline u8 *ah_tmp_icv(void *tmp, unsigned int offset)
+ {
+-      return PTR_ALIGN((u8 *)tmp + offset, crypto_ahash_alignmask(ahash) + 1);
++      return tmp + offset;
+ }
+ static inline struct ahash_request *ah_tmp_req(struct crypto_ahash *ahash,
+@@ -327,7 +324,7 @@ static void ah6_output_done(void *data,
+       iph_base = AH_SKB_CB(skb)->tmp;
+       iph_ext = ah_tmp_ext(iph_base);
+-      icv = ah_tmp_icv(ahp->ahash, iph_ext, extlen);
++      icv = ah_tmp_icv(iph_ext, extlen);
+       memcpy(ah->auth_data, icv, ahp->icv_trunc_len);
+       memcpy(top_iph, iph_base, IPV6HDR_BASELEN);
+@@ -384,7 +381,7 @@ static int ah6_output(struct xfrm_state
+       iph_ext = ah_tmp_ext(iph_base);
+       seqhi = (__be32 *)((char *)iph_ext + extlen);
+-      icv = ah_tmp_icv(ahash, seqhi, seqhi_len);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       req = ah_tmp_req(ahash, icv);
+       sg = ah_req_sg(ahash, req);
+       seqhisg = sg + nfrags;
+@@ -480,7 +477,7 @@ static void ah6_input_done(void *data, i
+       work_iph = AH_SKB_CB(skb)->tmp;
+       auth_data = ah_tmp_auth(work_iph, hdr_len);
+-      icv = ah_tmp_icv(ahp->ahash, auth_data, ahp->icv_trunc_len);
++      icv = ah_tmp_icv(auth_data, ahp->icv_trunc_len);
+       err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
+       if (err)
+@@ -588,7 +585,7 @@ static int ah6_input(struct xfrm_state *
+       auth_data = ah_tmp_auth((u8 *)work_iph, hdr_len);
+       seqhi = (__be32 *)(auth_data + ahp->icv_trunc_len);
+-      icv = ah_tmp_icv(ahash, seqhi, seqhi_len);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       req = ah_tmp_req(ahash, icv);
+       sg = ah_req_sg(ahash, req);
+       seqhisg = sg + nfrags;
diff --git a/queue-6.6/net-stmmac-avoid-shadowing-global-buf_sz.patch b/queue-6.6/net-stmmac-avoid-shadowing-global-buf_sz.patch
new file mode 100644 (file)
index 0000000..e503b0a
--- /dev/null
@@ -0,0 +1,51 @@
+From stable+bounces-245032-greg=kroah.com@vger.kernel.org Sun May 10 17:10:25 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 11:10:17 -0400
+Subject: net: stmmac: avoid shadowing global buf_sz
+To: stable@vger.kernel.org
+Cc: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>, Furong Xu <0x1207@gmail.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260510151019.38468-1-sashal@kernel.org>
+
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit 876cfb20e8892143c0c967b3657074f9131f9b5f ]
+
+stmmac_rx() declares a local variable named "buf_sz" but there is also
+a global variable for a module parameter which is called the same. To
+avoid confusion, rename the local variable.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Furong Xu <0x1207@gmail.com>
+Link: https://patch.msgid.link/E1tpswi-005U6C-Py@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 0bb05e6adfa9 ("net: stmmac: Prevent NULL deref when RX memory exhausted")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -5279,10 +5279,10 @@ static int stmmac_rx(struct stmmac_priv
+       struct sk_buff *skb = NULL;
+       struct stmmac_xdp_buff ctx;
+       int xdp_status = 0;
+-      int buf_sz;
++      int bufsz;
+       dma_dir = page_pool_get_dma_dir(rx_q->page_pool);
+-      buf_sz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE;
++      bufsz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE;
+       limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit);
+       if (netif_msg_rx_status(priv)) {
+@@ -5397,7 +5397,7 @@ read_again:
+                       dma_sync_single_for_cpu(priv->device, buf->addr,
+                                               buf1_len, dma_dir);
+-                      xdp_init_buff(&ctx.xdp, buf_sz, &rx_q->xdp_rxq);
++                      xdp_init_buff(&ctx.xdp, bufsz, &rx_q->xdp_rxq);
+                       xdp_prepare_buff(&ctx.xdp, page_address(buf->page),
+                                        buf->page_offset, buf1_len, true);
diff --git a/queue-6.6/net-stmmac-prevent-null-deref-when-rx-memory-exhausted.patch b/queue-6.6/net-stmmac-prevent-null-deref-when-rx-memory-exhausted.patch
new file mode 100644 (file)
index 0000000..903cb10
--- /dev/null
@@ -0,0 +1,120 @@
+From stable+bounces-245034-greg=kroah.com@vger.kernel.org Sun May 10 17:10:28 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 11:10:19 -0400
+Subject: net: stmmac: Prevent NULL deref when RX memory exhausted
+To: stable@vger.kernel.org
+Cc: Sam Edwards <cfsworks@gmail.com>, Russell King <linux@armlinux.org.uk>, Sam Edwards <CFSworks@gmail.com>, Paolo Abeni <pabeni@redhat.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260510151019.38468-3-sashal@kernel.org>
+
+From: Sam Edwards <cfsworks@gmail.com>
+
+[ Upstream commit 0bb05e6adfa99a2ea1fee1125cc0953409f83ed8 ]
+
+The CPU receives frames from the MAC through conventional DMA: the CPU
+allocates buffers for the MAC, then the MAC fills them and returns
+ownership to the CPU. For each hardware RX queue, the CPU and MAC
+coordinate through a shared ring array of DMA descriptors: one
+descriptor per DMA buffer. Each descriptor includes the buffer's
+physical address and a status flag ("OWN") indicating which side owns
+the buffer: OWN=0 for CPU, OWN=1 for MAC. The CPU is only allowed to set
+the flag and the MAC is only allowed to clear it, and both must move
+through the ring in sequence: thus the ring is used for both
+"submissions" and "completions."
+
+In the stmmac driver, stmmac_rx() bookmarks its position in the ring
+with the `cur_rx` index. The main receive loop in that function checks
+for rx_descs[cur_rx].own=0, gives the corresponding buffer to the
+network stack (NULLing the pointer), and increments `cur_rx` modulo the
+ring size. After the loop exits, stmmac_rx_refill(), which bookmarks its
+position with `dirty_rx`, allocates fresh buffers and rearms the
+descriptors (setting OWN=1). If it fails any allocation, it simply stops
+early (leaving OWN=0) and will retry where it left off when next called.
+
+This means descriptors have a three-stage lifecycle (terms my own):
+- `empty` (OWN=1, buffer valid)
+- `full` (OWN=0, buffer valid and populated)
+- `dirty` (OWN=0, buffer NULL)
+
+But because stmmac_rx() only checks OWN, it confuses `full`/`dirty`. In
+the past (see 'Fixes:'), there was a bug where the loop could cycle
+`cur_rx` all the way back to the first descriptor it dirtied, resulting
+in a NULL dereference when mistaken for `full`. The aforementioned
+commit resolved that *specific* failure by capping the loop's iteration
+limit at `dma_rx_size - 1`, but this is only a partial fix: if the
+previous stmmac_rx_refill() didn't complete, then there are leftover
+`dirty` descriptors that the loop might encounter without needing to
+cycle fully around. The current code therefore panics (see 'Closes:')
+when stmmac_rx_refill() is memory-starved long enough for `cur_rx` to
+catch up to `dirty_rx`.
+
+Fix this by explicitly checking, before advancing `cur_rx`, if the next
+entry is dirty; exit the loop if so. This prevents processing of the
+final, used descriptor until stmmac_rx_refill() succeeds, but
+fully prevents the `cur_rx == dirty_rx` ambiguity as the previous bugfix
+intended: so remove the clamp as well. Since stmmac_rx_zc() is a
+copy-paste-and-tweak of stmmac_rx() and the code structure is identical,
+any fix to stmmac_rx() will also need a corresponding fix for
+stmmac_rx_zc(). Therefore, apply the same check there.
+
+In stmmac_rx() (not stmmac_rx_zc()), a related bug remains: after the
+MAC sets OWN=0 on the final descriptor, it will be unable to send any
+further DMA-complete IRQs until it's given more `empty` descriptors.
+Currently, the driver simply *hopes* that the next stmmac_rx_refill()
+succeeds, risking an indefinite stall of the receive process if not. But
+this is not a regression, so it can be addressed in a future change.
+
+Fixes: b6cb4541853c7 ("net: stmmac: avoid rx queue overrun")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221010
+Cc: stable@vger.kernel.org
+Suggested-by: Russell King <linux@armlinux.org.uk>
+Signed-off-by: Sam Edwards <CFSworks@gmail.com>
+Link: https://patch.msgid.link/20260422044503.5349-1-CFSworks@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |   19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -5143,9 +5143,12 @@ read_again:
+                       break;
+               /* Prefetch the next RX descriptor */
+-              rx_q->cur_rx = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
+-                                              priv->dma_conf.dma_rx_size);
+-              next_entry = rx_q->cur_rx;
++              next_entry = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
++                                             priv->dma_conf.dma_rx_size);
++              if (unlikely(next_entry == rx_q->dirty_rx))
++                      break;
++
++              rx_q->cur_rx = next_entry;
+               if (priv->extend_desc)
+                       np = (struct dma_desc *)(rx_q->dma_erx + next_entry);
+@@ -5283,7 +5286,6 @@ static int stmmac_rx(struct stmmac_priv
+       dma_dir = page_pool_get_dma_dir(rx_q->page_pool);
+       bufsz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE;
+-      limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit);
+       if (netif_msg_rx_status(priv)) {
+               void *rx_head;
+@@ -5339,9 +5341,12 @@ read_again:
+               if (unlikely(status & dma_own))
+                       break;
+-              rx_q->cur_rx = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
+-                                              priv->dma_conf.dma_rx_size);
+-              next_entry = rx_q->cur_rx;
++              next_entry = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
++                                             priv->dma_conf.dma_rx_size);
++              if (unlikely(next_entry == rx_q->dirty_rx))
++                      break;
++
++              rx_q->cur_rx = next_entry;
+               if (priv->extend_desc)
+                       np = (struct dma_desc *)(rx_q->dma_erx + next_entry);
diff --git a/queue-6.6/net-stmmac-rename-stmmac_get_entry-stmmac_next_entry.patch b/queue-6.6/net-stmmac-rename-stmmac_get_entry-stmmac_next_entry.patch
new file mode 100644 (file)
index 0000000..70ff814
--- /dev/null
@@ -0,0 +1,181 @@
+From stable+bounces-245033-greg=kroah.com@vger.kernel.org Sun May 10 17:10:27 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 11:10:18 -0400
+Subject: net: stmmac: rename STMMAC_GET_ENTRY() -> STMMAC_NEXT_ENTRY()
+To: stable@vger.kernel.org
+Cc: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260510151019.38468-2-sashal@kernel.org>
+
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit 6b4286e0550814cdc4b897f881ec1fa8b0313227 ]
+
+STMMAC_GET_ENTRY() doesn't describe what this macro is doing - it is
+incrementing the provided index for the circular array of descriptors.
+Replace "GET" with "NEXT" as this better describes the action here.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/E1w2vba-0000000DbWo-1oL5@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 0bb05e6adfa9 ("net: stmmac: Prevent NULL deref when RX memory exhausted")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/chain_mode.c  |    2 -
+ drivers/net/ethernet/stmicro/stmmac/common.h      |    2 -
+ drivers/net/ethernet/stmicro/stmmac/ring_mode.c   |    2 -
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |   26 +++++++++++-----------
+ 4 files changed, 16 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
++++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
+@@ -47,7 +47,7 @@ static int jumbo_frm(struct stmmac_tx_qu
+       while (len != 0) {
+               tx_q->tx_skbuff[entry] = NULL;
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+               desc = tx_q->dma_tx + entry;
+               if (len > bmax) {
+--- a/drivers/net/ethernet/stmicro/stmmac/common.h
++++ b/drivers/net/ethernet/stmicro/stmmac/common.h
+@@ -54,7 +54,7 @@
+ #define DMA_MIN_RX_SIZE               64
+ #define DMA_MAX_RX_SIZE               1024
+ #define DMA_DEFAULT_RX_SIZE   512
+-#define STMMAC_GET_ENTRY(x, size)     ((x + 1) & (size - 1))
++#define STMMAC_NEXT_ENTRY(x, size)    ((x + 1) & (size - 1))
+ #undef FRAME_FILTER_DEBUG
+ /* #define FRAME_FILTER_DEBUG */
+--- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
++++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
+@@ -51,7 +51,7 @@ static int jumbo_frm(struct stmmac_tx_qu
+               stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum,
+                               STMMAC_RING_MODE, 0, false, skb->len);
+               tx_q->tx_skbuff[entry] = NULL;
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+               if (priv->extend_desc)
+                       desc = (struct dma_desc *)(tx_q->dma_etx + entry);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2503,7 +2503,7 @@ static bool stmmac_xdp_xmit_zc(struct st
+               stmmac_enable_dma_transmission(priv, priv->ioaddr);
+-              tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
++              tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
+               entry = tx_q->cur_tx;
+       }
+       u64_stats_update_begin(&txq_stats->napi_syncp);
+@@ -2659,7 +2659,7 @@ static int stmmac_tx_clean(struct stmmac
+               stmmac_release_tx_desc(priv, p, priv->mode);
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+       }
+       tx_q->dirty_tx = entry;
+@@ -3973,7 +3973,7 @@ static bool stmmac_vlan_insert(struct st
+               return false;
+       stmmac_set_tx_owner(priv, p);
+-      tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
++      tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
+       return true;
+ }
+@@ -4001,7 +4001,7 @@ static void stmmac_tso_allocator(struct
+       while (tmp_len > 0) {
+               dma_addr_t curr_addr;
+-              tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx,
++              tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx,
+                                               priv->dma_conf.dma_tx_size);
+               WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]);
+@@ -4133,7 +4133,7 @@ static netdev_tx_t stmmac_tso_xmit(struc
+               stmmac_set_mss(priv, mss_desc, mss);
+               tx_q->mss = mss;
+-              tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx,
++              tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx,
+                                               priv->dma_conf.dma_tx_size);
+               WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]);
+       }
+@@ -4258,7 +4258,7 @@ static netdev_tx_t stmmac_tso_xmit(struc
+        * ndo_start_xmit will fill this descriptor the next time it's
+        * called and stmmac_tx_clean may clean up to this descriptor.
+        */
+-      tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
++      tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
+       if (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 1))) {
+               netif_dbg(priv, hw, priv->dev, "%s: stop transmitted packets\n",
+@@ -4451,7 +4451,7 @@ static netdev_tx_t stmmac_xmit(struct sk
+               int len = skb_frag_size(frag);
+               bool last_segment = (i == (nfrags - 1));
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+               WARN_ON(tx_q->tx_skbuff[entry]);
+               if (likely(priv->extend_desc))
+@@ -4521,7 +4521,7 @@ static netdev_tx_t stmmac_xmit(struct sk
+        * ndo_start_xmit will fill this descriptor the next time it's
+        * called and stmmac_tx_clean may clean up to this descriptor.
+        */
+-      entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++      entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+       tx_q->cur_tx = entry;
+       if (netif_msg_pktdata(priv)) {
+@@ -4691,7 +4691,7 @@ static inline void stmmac_rx_refill(stru
+               dma_wmb();
+               stmmac_set_rx_owner(priv, p, use_rx_wd);
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_rx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_rx_size);
+       }
+       rx_q->dirty_rx = entry;
+       rx_q->rx_tail_addr = rx_q->dma_rx_phy +
+@@ -4818,7 +4818,7 @@ static int stmmac_xdp_xmit_xdpf(struct s
+       stmmac_enable_dma_transmission(priv, priv->ioaddr);
+-      entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++      entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+       tx_q->cur_tx = entry;
+       return STMMAC_XDP_TX;
+@@ -5048,7 +5048,7 @@ static bool stmmac_rx_refill_zc(struct s
+               dma_wmb();
+               stmmac_set_rx_owner(priv, rx_desc, use_rx_wd);
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_rx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_rx_size);
+       }
+       if (rx_desc) {
+@@ -5143,7 +5143,7 @@ read_again:
+                       break;
+               /* Prefetch the next RX descriptor */
+-              rx_q->cur_rx = STMMAC_GET_ENTRY(rx_q->cur_rx,
++              rx_q->cur_rx = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
+                                               priv->dma_conf.dma_rx_size);
+               next_entry = rx_q->cur_rx;
+@@ -5339,7 +5339,7 @@ read_again:
+               if (unlikely(status & dma_own))
+                       break;
+-              rx_q->cur_rx = STMMAC_GET_ENTRY(rx_q->cur_rx,
++              rx_q->cur_rx = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
+                                               priv->dma_conf.dma_rx_size);
+               next_entry = rx_q->cur_rx;
diff --git a/queue-6.6/printk-add-print_hex_dump_devel.patch b/queue-6.6/printk-add-print_hex_dump_devel.patch
new file mode 100644 (file)
index 0000000..0761898
--- /dev/null
@@ -0,0 +1,49 @@
+From stable+bounces-245015-greg=kroah.com@vger.kernel.org Sun May 10 15:15:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 09:15:07 -0400
+Subject: printk: add print_hex_dump_devel()
+To: stable@vger.kernel.org
+Cc: Thorsten Blum <thorsten.blum@linux.dev>, Herbert Xu <herbert@gondor.apana.org.au>, John Ogness <john.ogness@linutronix.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260510131508.4113857-1-sashal@kernel.org>
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ Upstream commit d134feeb5df33fbf77f482f52a366a44642dba09 ]
+
+Add print_hex_dump_devel() as the hex dump equivalent of pr_devel(),
+which emits output only when DEBUG is enabled, but keeps call sites
+compiled otherwise.
+
+Suggested-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Reviewed-by: John Ogness <john.ogness@linutronix.de>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 177730a273b1 ("crypto: caam - guard HMAC key hex dumps in hash_digest_key")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/printk.h |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/include/linux/printk.h
++++ b/include/linux/printk.h
+@@ -745,6 +745,19 @@ static inline void print_hex_dump_debug(
+ }
+ #endif
++#if defined(DEBUG)
++#define print_hex_dump_devel(prefix_str, prefix_type, rowsize,                \
++                           groupsize, buf, len, ascii)                \
++      print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, rowsize,    \
++                     groupsize, buf, len, ascii)
++#else
++static inline void print_hex_dump_devel(const char *prefix_str, int prefix_type,
++                                      int rowsize, int groupsize,
++                                      const void *buf, size_t len, bool ascii)
++{
++}
++#endif
++
+ /**
+  * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params
+  * @prefix_str: string to prefix each line with;
diff --git a/queue-6.6/rxrpc-fix-conn-level-packet-handling-to-unshare-response-packets.patch b/queue-6.6/rxrpc-fix-conn-level-packet-handling-to-unshare-response-packets.patch
new file mode 100644 (file)
index 0000000..76fd8af
--- /dev/null
@@ -0,0 +1,81 @@
+From stable+bounces-242797-greg=kroah.com@vger.kernel.org Sun May  3 16:33:27 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun,  3 May 2026 10:33:17 -0400
+Subject: rxrpc: Fix conn-level packet handling to unshare RESPONSE packets
+To: stable@vger.kernel.org
+Cc: David Howells <dhowells@redhat.com>, Marc Dionne <marc.dionne@auristor.com>, Jeffrey Altman <jaltman@auristor.com>, Simon Horman <horms@kernel.org>, linux-afs@lists.infradead.org, stable@kernel.org, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260503143317.1089945-1-sashal@kernel.org>
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 24481a7f573305706054c59e275371f8d0fe919f ]
+
+The security operations that verify the RESPONSE packets decrypt bits of it
+in place - however, the sk_buff may be shared with a packet sniffer, which
+would lead to the sniffer seeing an apparently corrupt packet (actually
+decrypted).
+
+Fix this by handing a copy of the packet off to the specific security
+handler if the packet was cloned.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Closes: https://sashiko.dev/#/patchset/20260408121252.2249051-1-dhowells%40redhat.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Jeffrey Altman <jaltman@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260422161438.2593376-5-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/conn_event.c |   29 ++++++++++++++++++++++++++++-
+ 1 file changed, 28 insertions(+), 1 deletion(-)
+
+--- a/net/rxrpc/conn_event.c
++++ b/net/rxrpc/conn_event.c
+@@ -226,6 +226,33 @@ static void rxrpc_call_is_secure(struct
+               rxrpc_notify_socket(call);
+ }
++static int rxrpc_verify_response(struct rxrpc_connection *conn,
++                               struct sk_buff *skb)
++{
++      int ret;
++
++      if (skb_cloned(skb)) {
++              /* Copy the packet if shared so that we can do in-place
++               * decryption.
++               */
++              struct sk_buff *nskb = skb_copy(skb, GFP_NOFS);
++
++              if (nskb) {
++                      rxrpc_new_skb(nskb, rxrpc_skb_new_unshared);
++                      ret = conn->security->verify_response(conn, nskb);
++                      rxrpc_free_skb(nskb, rxrpc_skb_put_response_copy);
++              } else {
++                      /* OOM - Drop the packet. */
++                      rxrpc_see_skb(skb, rxrpc_skb_see_unshare_nomem);
++                      ret = -ENOMEM;
++              }
++      } else {
++              ret = conn->security->verify_response(conn, skb);
++      }
++
++      return ret;
++}
++
+ /*
+  * connection-level Rx packet processor
+  */
+@@ -253,7 +280,7 @@ static int rxrpc_process_event(struct rx
+               }
+               spin_unlock(&conn->state_lock);
+-              ret = conn->security->verify_response(conn, skb);
++              ret = rxrpc_verify_response(conn, skb);
+               if (ret < 0)
+                       return ret;
index bd7d2d4a9cacdb871550db5ffb6e8cd74ab1e8e5..35b02d71232713bb5177ebdb92f087b55703ef1e 100644 (file)
@@ -402,3 +402,45 @@ hfsplus-fix-uninit-value-by-validating-catalog-record-size.patch
 hfsplus-fix-held-lock-freed-on-hfsplus_fill_super.patch
 wifi-rtl8xxxu-fix-potential-use-of-uninitialized-value.patch
 ksmbd-reset-rcount-per-connection-in-ksmbd_conn_wait_idle_sess_id.patch
+crypto-nx-avoid-wflex-array-member-not-at-end-warning.patch
+crypto-nx-migrate-to-scomp-api.patch
+crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch
+erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch
+printk-add-print_hex_dump_devel.patch
+crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch
+net-stmmac-avoid-shadowing-global-buf_sz.patch
+net-stmmac-rename-stmmac_get_entry-stmmac_next_entry.patch
+net-stmmac-prevent-null-deref-when-rx-memory-exhausted.patch
+tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch
+alsa-hda-cs35l56-propagate-asp-tx-source-control-errors.patch
+alsa-misc-use-guard-for-spin-locks.patch
+alsa-core-serialize-deferred-fasync-state-checks.patch
+alsa-seq-notify-client-and-port-info-changes.patch
+alsa-seq-fix-ump-group-16-filtering.patch
+net-ipv4-stop-checking-crypto_ahash_alignmask.patch
+net-ipv6-stop-checking-crypto_ahash_alignmask.patch
+xfrm-ah-account-for-esn-high-bits-in-async-callbacks.patch
+xfrm-defensively-unhash-xfrm_state-lists-in-__xfrm_state_delete.patch
+bluetooth-hci_conn-fix-potential-uaf-in-create_big_sync.patch
+spi-synquacer-switch-to-use-modern-name.patch
+spi-syncuacer-fix-controller-deregistration.patch
+spi-sun4i-switch-to-use-modern-name.patch
+spi-sun4i-fix-controller-deregistration.patch
+spi-spi-ti-qspi-convert-to-platform-remove-callback-returning-void.patch
+spi-spi-ti-qspi-switch-to-use-modern-name.patch
+spi-ti-qspi-fix-controller-deregistration.patch
+spi-zynq-qspi-switch-to-use-modern-name.patch
+spi-zynq-qspi-simplify-clock-handling-with-devm_clk_get_enabled.patch
+spi-zynq-qspi-fix-controller-deregistration.patch
+spi-sun6i-switch-to-use-modern-name.patch
+spi-sun6i-fix-controller-deregistration.patch
+spi-tegra114-fix-controller-deregistration.patch
+spi-tegra20-sflash-fix-controller-deregistration.patch
+spi-uniphier-switch-to-use-modern-name.patch
+spi-uniphier-simplify-clock-handling-with-devm_clk_get_enabled.patch
+spi-uniphier-fix-controller-deregistration.patch
+mm-hugetlb_cma-round-up-per_node-before-logging-it.patch
+spi-microchip-core-qspi-use-helper-function-devm_clk_get_enabled.patch
+spi-microchip-core-qspi-fix-controller-deregistration.patch
+fbcon-avoid-oob-font-access-if-console-rotation-fails.patch
+rxrpc-fix-conn-level-packet-handling-to-unshare-response-packets.patch
diff --git a/queue-6.6/spi-microchip-core-qspi-fix-controller-deregistration.patch b/queue-6.6/spi-microchip-core-qspi-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..9c4c74c
--- /dev/null
@@ -0,0 +1,64 @@
+From stable+bounces-247275-greg=kroah.com@vger.kernel.org Thu May 14 20:33:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 14:33:36 -0400
+Subject: spi: microchip-core-qspi: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Naga Sureshkumar Relli <nagasuresh.relli@microchip.com>, Conor Dooley <conor.dooley@microchip.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514183336.771790-2-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit e6464140d439f2d42f072eb422a5b1fec470c5a6 ]
+
+Make sure to deregister the controller before disabling underlying
+resources like interrupts during driver unbind.
+
+Fixes: 8596124c4c1b ("spi: microchip-core-qspi: Add support for microchip fpga qspi controllers")
+Cc: stable@vger.kernel.org     # 6.1
+Cc: Naga Sureshkumar Relli <nagasuresh.relli@microchip.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://patch.msgid.link/20260409120419.388546-19-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-microchip-core-qspi.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-microchip-core-qspi.c
++++ b/drivers/spi/spi-microchip-core-qspi.c
+@@ -512,7 +512,7 @@ static int mchp_coreqspi_probe(struct pl
+                                    "unable to allocate master for QSPI controller\n");
+       qspi = spi_controller_get_devdata(ctlr);
+-      platform_set_drvdata(pdev, qspi);
++      platform_set_drvdata(pdev, ctlr);
+       qspi->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(qspi->regs))
+@@ -545,7 +545,7 @@ static int mchp_coreqspi_probe(struct pl
+                         SPI_TX_DUAL | SPI_TX_QUAD;
+       ctlr->dev.of_node = np;
+-      ret = devm_spi_register_controller(&pdev->dev, ctlr);
++      ret = spi_register_controller(ctlr);
+       if (ret)
+               return dev_err_probe(&pdev->dev, ret,
+                                    "spi_register_controller failed\n");
+@@ -555,9 +555,13 @@ static int mchp_coreqspi_probe(struct pl
+ static void mchp_coreqspi_remove(struct platform_device *pdev)
+ {
+-      struct mchp_coreqspi *qspi = platform_get_drvdata(pdev);
+-      u32 control = readl_relaxed(qspi->regs + REG_CONTROL);
++      struct spi_controller *ctlr = platform_get_drvdata(pdev);
++      struct mchp_coreqspi *qspi = spi_controller_get_devdata(ctlr);
++      u32 control;
++      spi_unregister_controller(ctlr);
++
++      control = readl_relaxed(qspi->regs + REG_CONTROL);
+       mchp_coreqspi_disable_ints(qspi);
+       control &= ~CONTROL_ENABLE;
+       writel_relaxed(control, qspi->regs + REG_CONTROL);
diff --git a/queue-6.6/spi-microchip-core-qspi-use-helper-function-devm_clk_get_enabled.patch b/queue-6.6/spi-microchip-core-qspi-use-helper-function-devm_clk_get_enabled.patch
new file mode 100644 (file)
index 0000000..beff8a2
--- /dev/null
@@ -0,0 +1,96 @@
+From stable+bounces-247274-greg=kroah.com@vger.kernel.org Thu May 14 20:33:42 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 14:33:35 -0400
+Subject: spi: microchip-core-qspi: Use helper function devm_clk_get_enabled()
+To: stable@vger.kernel.org
+Cc: Li Zetao <lizetao1@huawei.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514183336.771790-1-sashal@kernel.org>
+
+From: Li Zetao <lizetao1@huawei.com>
+
+[ Upstream commit e922f3fff21445117e9196bd8e940ad8e15ca8c7 ]
+
+Since commit 7ef9651e9792 ("clk: Provide new devm_clk helpers for prepared
+and enabled clocks"), devm_clk_get() and clk_prepare_enable() can now be
+replaced by devm_clk_get_enabled() when driver enables (and possibly
+prepares) the clocks for the whole lifetime of the device. Moreover, it is
+no longer necessary to unprepare and disable the clocks explicitly.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Link: https://lore.kernel.org/r/20230823133938.1359106-18-lizetao1@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: e6464140d439 ("spi: microchip-core-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-microchip-core-qspi.c |   29 +++++++----------------------
+ 1 file changed, 7 insertions(+), 22 deletions(-)
+
+--- a/drivers/spi/spi-microchip-core-qspi.c
++++ b/drivers/spi/spi-microchip-core-qspi.c
+@@ -519,30 +519,23 @@ static int mchp_coreqspi_probe(struct pl
+               return dev_err_probe(&pdev->dev, PTR_ERR(qspi->regs),
+                                    "failed to map registers\n");
+-      qspi->clk = devm_clk_get(&pdev->dev, NULL);
++      qspi->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+       if (IS_ERR(qspi->clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(qspi->clk),
+                                    "could not get clock\n");
+-      ret = clk_prepare_enable(qspi->clk);
+-      if (ret)
+-              return dev_err_probe(&pdev->dev, ret,
+-                                   "failed to enable clock\n");
+-
+       init_completion(&qspi->data_completion);
+       mutex_init(&qspi->op_lock);
+       qspi->irq = platform_get_irq(pdev, 0);
+-      if (qspi->irq < 0) {
+-              ret = qspi->irq;
+-              goto out;
+-      }
++      if (qspi->irq < 0)
++              return qspi->irq;
+       ret = devm_request_irq(&pdev->dev, qspi->irq, mchp_coreqspi_isr,
+                              IRQF_SHARED, pdev->name, qspi);
+       if (ret) {
+               dev_err(&pdev->dev, "request_irq failed %d\n", ret);
+-              goto out;
++              return ret;
+       }
+       ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
+@@ -553,18 +546,11 @@ static int mchp_coreqspi_probe(struct pl
+       ctlr->dev.of_node = np;
+       ret = devm_spi_register_controller(&pdev->dev, ctlr);
+-      if (ret) {
+-              dev_err_probe(&pdev->dev, ret,
+-                            "spi_register_controller failed\n");
+-              goto out;
+-      }
++      if (ret)
++              return dev_err_probe(&pdev->dev, ret,
++                                   "spi_register_controller failed\n");
+       return 0;
+-
+-out:
+-      clk_disable_unprepare(qspi->clk);
+-
+-      return ret;
+ }
+ static void mchp_coreqspi_remove(struct platform_device *pdev)
+@@ -575,7 +561,6 @@ static void mchp_coreqspi_remove(struct
+       mchp_coreqspi_disable_ints(qspi);
+       control &= ~CONTROL_ENABLE;
+       writel_relaxed(control, qspi->regs + REG_CONTROL);
+-      clk_disable_unprepare(qspi->clk);
+ }
+ static const struct of_device_id mchp_coreqspi_of_match[] = {
diff --git a/queue-6.6/spi-spi-ti-qspi-convert-to-platform-remove-callback-returning-void.patch b/queue-6.6/spi-spi-ti-qspi-convert-to-platform-remove-callback-returning-void.patch
new file mode 100644 (file)
index 0000000..fa75191
--- /dev/null
@@ -0,0 +1,76 @@
+From stable+bounces-246995-greg=kroah.com@vger.kernel.org Wed May 13 20:11:11 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 14:08:40 -0400
+Subject: spi: spi-ti-qspi: Convert to platform remove callback returning void
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Mark Brown" <broonie@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260513180842.3912849-1-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 2f2802d1a59d79a3d00cb429841db502c2bbc3df ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is ignored (apart
+from emitting a warning) and this typically results in resource leaks.
+
+To improve here there is a quest to make the remove callback return
+void. In the first step of this quest all drivers are converted to
+.remove_new(), which already returns void. Eventually after all drivers
+are converted, .remove_new() will be renamed to .remove().
+
+Add an error message to the error path that returned an error before to
+replace the core's error message with more information. Apart from the
+different wording of the error message, this patch doesn't introduce a
+semantic difference.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20231105172649.3738556-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0c18a1bacbb1 ("spi: ti-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-ti-qspi.c |   13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/drivers/spi/spi-ti-qspi.c
++++ b/drivers/spi/spi-ti-qspi.c
+@@ -907,21 +907,22 @@ free_master:
+       return ret;
+ }
+-static int ti_qspi_remove(struct platform_device *pdev)
++static void ti_qspi_remove(struct platform_device *pdev)
+ {
+       struct ti_qspi *qspi = platform_get_drvdata(pdev);
+       int rc;
+       rc = spi_master_suspend(qspi->master);
+-      if (rc)
+-              return rc;
++      if (rc) {
++              dev_alert(&pdev->dev, "spi_master_suspend() failed (%pe)\n",
++                        ERR_PTR(rc));
++              return;
++      }
+       pm_runtime_put_sync(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       ti_qspi_dma_cleanup(qspi);
+-
+-      return 0;
+ }
+ static const struct dev_pm_ops ti_qspi_pm_ops = {
+@@ -930,7 +931,7 @@ static const struct dev_pm_ops ti_qspi_p
+ static struct platform_driver ti_qspi_driver = {
+       .probe  = ti_qspi_probe,
+-      .remove = ti_qspi_remove,
++      .remove_new = ti_qspi_remove,
+       .driver = {
+               .name   = "ti-qspi",
+               .pm =   &ti_qspi_pm_ops,
diff --git a/queue-6.6/spi-spi-ti-qspi-switch-to-use-modern-name.patch b/queue-6.6/spi-spi-ti-qspi-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..2e7e149
--- /dev/null
@@ -0,0 +1,293 @@
+From stable+bounces-246996-greg=kroah.com@vger.kernel.org Wed May 13 20:15:40 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 14:08:41 -0400
+Subject: spi: spi-ti-qspi: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513180842.3912849-2-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 9d93c8d97b4cdb5edddb4c5530881c90eecb7e44 ]
+
+Change legacy name master to modern name host or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-16-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0c18a1bacbb1 ("spi: ti-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-ti-qspi.c |   88 +++++++++++++++++++++++-----------------------
+ 1 file changed, 44 insertions(+), 44 deletions(-)
+
+--- a/drivers/spi/spi-ti-qspi.c
++++ b/drivers/spi/spi-ti-qspi.c
+@@ -40,7 +40,7 @@ struct ti_qspi {
+       /* list synchronization */
+       struct mutex            list_lock;
+-      struct spi_master       *master;
++      struct spi_controller   *host;
+       void __iomem            *base;
+       void __iomem            *mmap_base;
+       size_t                  mmap_size;
+@@ -137,20 +137,20 @@ static inline void ti_qspi_write(struct
+ static int ti_qspi_setup(struct spi_device *spi)
+ {
+-      struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
++      struct ti_qspi  *qspi = spi_controller_get_devdata(spi->controller);
+       int ret;
+-      if (spi->master->busy) {
+-              dev_dbg(qspi->dev, "master busy doing other transfers\n");
++      if (spi->controller->busy) {
++              dev_dbg(qspi->dev, "host busy doing other transfers\n");
+               return -EBUSY;
+       }
+-      if (!qspi->master->max_speed_hz) {
++      if (!qspi->host->max_speed_hz) {
+               dev_err(qspi->dev, "spi max frequency not defined\n");
+               return -EINVAL;
+       }
+-      spi->max_speed_hz = min(spi->max_speed_hz, qspi->master->max_speed_hz);
++      spi->max_speed_hz = min(spi->max_speed_hz, qspi->host->max_speed_hz);
+       ret = pm_runtime_resume_and_get(qspi->dev);
+       if (ret < 0) {
+@@ -526,7 +526,7 @@ static int ti_qspi_dma_xfer_sg(struct ti
+ static void ti_qspi_enable_memory_map(struct spi_device *spi)
+ {
+-      struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
++      struct ti_qspi  *qspi = spi_controller_get_devdata(spi->controller);
+       ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG);
+       if (qspi->ctrl_base) {
+@@ -540,7 +540,7 @@ static void ti_qspi_enable_memory_map(st
+ static void ti_qspi_disable_memory_map(struct spi_device *spi)
+ {
+-      struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
++      struct ti_qspi  *qspi = spi_controller_get_devdata(spi->controller);
+       ti_qspi_write(qspi, 0, QSPI_SPI_SWITCH_REG);
+       if (qspi->ctrl_base)
+@@ -554,7 +554,7 @@ static void ti_qspi_setup_mmap_read(stru
+                                   u8 data_nbits, u8 addr_width,
+                                   u8 dummy_bytes)
+ {
+-      struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
++      struct ti_qspi  *qspi = spi_controller_get_devdata(spi->controller);
+       u32 memval = opcode;
+       switch (data_nbits) {
+@@ -576,7 +576,7 @@ static void ti_qspi_setup_mmap_read(stru
+ static int ti_qspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+ {
+-      struct ti_qspi *qspi = spi_controller_get_devdata(mem->spi->master);
++      struct ti_qspi *qspi = spi_controller_get_devdata(mem->spi->controller);
+       size_t max_len;
+       if (op->data.dir == SPI_MEM_DATA_IN) {
+@@ -606,7 +606,7 @@ static int ti_qspi_adjust_op_size(struct
+ static int ti_qspi_exec_mem_op(struct spi_mem *mem,
+                              const struct spi_mem_op *op)
+ {
+-      struct ti_qspi *qspi = spi_master_get_devdata(mem->spi->master);
++      struct ti_qspi *qspi = spi_controller_get_devdata(mem->spi->controller);
+       u32 from = 0;
+       int ret = 0;
+@@ -633,10 +633,10 @@ static int ti_qspi_exec_mem_op(struct sp
+               struct sg_table sgt;
+               if (virt_addr_valid(op->data.buf.in) &&
+-                  !spi_controller_dma_map_mem_op_data(mem->spi->master, op,
++                  !spi_controller_dma_map_mem_op_data(mem->spi->controller, op,
+                                                       &sgt)) {
+                       ret = ti_qspi_dma_xfer_sg(qspi, sgt, from);
+-                      spi_controller_dma_unmap_mem_op_data(mem->spi->master,
++                      spi_controller_dma_unmap_mem_op_data(mem->spi->controller,
+                                                            op, &sgt);
+               } else {
+                       ret = ti_qspi_dma_bounce_buffer(qspi, from,
+@@ -658,10 +658,10 @@ static const struct spi_controller_mem_o
+       .adjust_op_size = ti_qspi_adjust_op_size,
+ };
+-static int ti_qspi_start_transfer_one(struct spi_master *master,
++static int ti_qspi_start_transfer_one(struct spi_controller *host,
+               struct spi_message *m)
+ {
+-      struct ti_qspi *qspi = spi_master_get_devdata(master);
++      struct ti_qspi *qspi = spi_controller_get_devdata(host);
+       struct spi_device *spi = m->spi;
+       struct spi_transfer *t;
+       int status = 0, ret;
+@@ -720,7 +720,7 @@ static int ti_qspi_start_transfer_one(st
+       ti_qspi_write(qspi, qspi->cmd | QSPI_INVAL, QSPI_SPI_CMD_REG);
+       m->status = status;
+-      spi_finalize_current_message(master);
++      spi_finalize_current_message(host);
+       return status;
+ }
+@@ -756,33 +756,33 @@ MODULE_DEVICE_TABLE(of, ti_qspi_match);
+ static int ti_qspi_probe(struct platform_device *pdev)
+ {
+       struct  ti_qspi *qspi;
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct resource         *r, *res_mmap;
+       struct device_node *np = pdev->dev.of_node;
+       u32 max_freq;
+       int ret = 0, num_cs, irq;
+       dma_cap_mask_t mask;
+-      master = spi_alloc_master(&pdev->dev, sizeof(*qspi));
+-      if (!master)
++      host = spi_alloc_host(&pdev->dev, sizeof(*qspi));
++      if (!host)
+               return -ENOMEM;
+-      master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD;
++      host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD;
+-      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+-      master->setup = ti_qspi_setup;
+-      master->auto_runtime_pm = true;
+-      master->transfer_one_message = ti_qspi_start_transfer_one;
+-      master->dev.of_node = pdev->dev.of_node;
+-      master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) |
+-                                   SPI_BPW_MASK(8);
+-      master->mem_ops = &ti_qspi_mem_ops;
++      host->flags = SPI_CONTROLLER_HALF_DUPLEX;
++      host->setup = ti_qspi_setup;
++      host->auto_runtime_pm = true;
++      host->transfer_one_message = ti_qspi_start_transfer_one;
++      host->dev.of_node = pdev->dev.of_node;
++      host->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) |
++                                 SPI_BPW_MASK(8);
++      host->mem_ops = &ti_qspi_mem_ops;
+       if (!of_property_read_u32(np, "num-cs", &num_cs))
+-              master->num_chipselect = num_cs;
++              host->num_chipselect = num_cs;
+-      qspi = spi_master_get_devdata(master);
+-      qspi->master = master;
++      qspi = spi_controller_get_devdata(host);
++      qspi->host = host;
+       qspi->dev = &pdev->dev;
+       platform_set_drvdata(pdev, qspi);
+@@ -792,7 +792,7 @@ static int ti_qspi_probe(struct platform
+               if (r == NULL) {
+                       dev_err(&pdev->dev, "missing platform data\n");
+                       ret = -ENODEV;
+-                      goto free_master;
++                      goto free_host;
+               }
+       }
+@@ -812,7 +812,7 @@ static int ti_qspi_probe(struct platform
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = irq;
+-              goto free_master;
++              goto free_host;
+       }
+       mutex_init(&qspi->list_lock);
+@@ -820,7 +820,7 @@ static int ti_qspi_probe(struct platform
+       qspi->base = devm_ioremap_resource(&pdev->dev, r);
+       if (IS_ERR(qspi->base)) {
+               ret = PTR_ERR(qspi->base);
+-              goto free_master;
++              goto free_host;
+       }
+@@ -830,7 +830,7 @@ static int ti_qspi_probe(struct platform
+                                               "syscon-chipselects");
+               if (IS_ERR(qspi->ctrl_base)) {
+                       ret = PTR_ERR(qspi->ctrl_base);
+-                      goto free_master;
++                      goto free_host;
+               }
+               ret = of_property_read_u32_index(np,
+                                                "syscon-chipselects",
+@@ -838,7 +838,7 @@ static int ti_qspi_probe(struct platform
+               if (ret) {
+                       dev_err(&pdev->dev,
+                               "couldn't get ctrl_mod reg index\n");
+-                      goto free_master;
++                      goto free_host;
+               }
+       }
+@@ -853,7 +853,7 @@ static int ti_qspi_probe(struct platform
+       pm_runtime_enable(&pdev->dev);
+       if (!of_property_read_u32(np, "spi-max-frequency", &max_freq))
+-              master->max_speed_hz = max_freq;
++              host->max_speed_hz = max_freq;
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_MEMCPY, mask);
+@@ -876,7 +876,7 @@ static int ti_qspi_probe(struct platform
+               dma_release_channel(qspi->rx_chan);
+               goto no_dma;
+       }
+-      master->dma_rx = qspi->rx_chan;
++      host->dma_rx = qspi->rx_chan;
+       init_completion(&qspi->transfer_complete);
+       if (res_mmap)
+               qspi->mmap_phys_base = (dma_addr_t)res_mmap->start;
+@@ -889,21 +889,21 @@ no_dma:
+                                "mmap failed with error %ld using PIO mode\n",
+                                PTR_ERR(qspi->mmap_base));
+                       qspi->mmap_base = NULL;
+-                      master->mem_ops = NULL;
++                      host->mem_ops = NULL;
+               }
+       }
+       qspi->mmap_enabled = false;
+       qspi->current_cs = -1;
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = devm_spi_register_controller(&pdev->dev, host);
+       if (!ret)
+               return 0;
+       ti_qspi_dma_cleanup(qspi);
+       pm_runtime_disable(&pdev->dev);
+-free_master:
+-      spi_master_put(master);
++free_host:
++      spi_controller_put(host);
+       return ret;
+ }
+@@ -912,9 +912,9 @@ static void ti_qspi_remove(struct platfo
+       struct ti_qspi *qspi = platform_get_drvdata(pdev);
+       int rc;
+-      rc = spi_master_suspend(qspi->master);
++      rc = spi_controller_suspend(qspi->host);
+       if (rc) {
+-              dev_alert(&pdev->dev, "spi_master_suspend() failed (%pe)\n",
++              dev_alert(&pdev->dev, "spi_controller_suspend() failed (%pe)\n",
+                         ERR_PTR(rc));
+               return;
+       }
diff --git a/queue-6.6/spi-sun4i-fix-controller-deregistration.patch b/queue-6.6/spi-sun4i-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..e8f3249
--- /dev/null
@@ -0,0 +1,54 @@
+From stable+bounces-246971-greg=kroah.com@vger.kernel.org Wed May 13 19:32:40 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:32:02 -0400
+Subject: spi: sun4i: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Maxime Ripard <mripard@kernel.org>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513173202.3886782-2-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 42108a2f03e0fdeabe9d02d085bdb058baa1189f ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: b5f6517948cc ("spi: sunxi: Add Allwinner A10 SPI controller driver")
+Cc: stable@vger.kernel.org     # 3.15
+Cc: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-19-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-sun4i.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-sun4i.c
++++ b/drivers/spi/spi-sun4i.c
+@@ -503,7 +503,7 @@ static int sun4i_spi_probe(struct platfo
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_idle(&pdev->dev);
+-      ret = devm_spi_register_controller(&pdev->dev, host);
++      ret = spi_register_controller(host);
+       if (ret) {
+               dev_err(&pdev->dev, "cannot register SPI host\n");
+               goto err_pm_disable;
+@@ -521,7 +521,15 @@ err_free_host:
+ static void sun4i_spi_remove(struct platform_device *pdev)
+ {
++      struct spi_controller *host = platform_get_drvdata(pdev);
++
++      spi_controller_get(host);
++
++      spi_unregister_controller(host);
++
+       pm_runtime_force_suspend(&pdev->dev);
++
++      spi_controller_put(host);
+ }
+ static const struct of_device_id sun4i_spi_match[] = {
diff --git a/queue-6.6/spi-sun4i-switch-to-use-modern-name.patch b/queue-6.6/spi-sun4i-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..5429bd4
--- /dev/null
@@ -0,0 +1,207 @@
+From stable+bounces-246970-greg=kroah.com@vger.kernel.org Wed May 13 19:32:37 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:32:01 -0400
+Subject: spi: sun4i: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513173202.3886782-1-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 6d232cc8a7e59af0c083319827541966a68817a0 ]
+
+Change legacy name master to modern name host or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-7-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 42108a2f03e0 ("spi: sun4i: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-sun4i.c |   72 ++++++++++++++++++++++++------------------------
+ 1 file changed, 36 insertions(+), 36 deletions(-)
+
+--- a/drivers/spi/spi-sun4i.c
++++ b/drivers/spi/spi-sun4i.c
+@@ -75,7 +75,7 @@
+ #define SUN4I_FIFO_STA_TF_CNT_BITS            16
+ struct sun4i_spi {
+-      struct spi_master       *master;
++      struct spi_controller   *host;
+       void __iomem            *base_addr;
+       struct clk              *hclk;
+       struct clk              *mclk;
+@@ -161,7 +161,7 @@ static inline void sun4i_spi_fill_fifo(s
+ static void sun4i_spi_set_cs(struct spi_device *spi, bool enable)
+ {
+-      struct sun4i_spi *sspi = spi_master_get_devdata(spi->master);
++      struct sun4i_spi *sspi = spi_controller_get_devdata(spi->controller);
+       u32 reg;
+       reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
+@@ -201,11 +201,11 @@ static size_t sun4i_spi_max_transfer_siz
+       return SUN4I_MAX_XFER_SIZE - 1;
+ }
+-static int sun4i_spi_transfer_one(struct spi_master *master,
++static int sun4i_spi_transfer_one(struct spi_controller *host,
+                                 struct spi_device *spi,
+                                 struct spi_transfer *tfr)
+ {
+-      struct sun4i_spi *sspi = spi_master_get_devdata(master);
++      struct sun4i_spi *sspi = spi_controller_get_devdata(host);
+       unsigned int mclk_rate, div, timeout;
+       unsigned int start, end, tx_time;
+       unsigned int tx_len = 0;
+@@ -334,7 +334,7 @@ static int sun4i_spi_transfer_one(struct
+                                             msecs_to_jiffies(tx_time));
+       end = jiffies;
+       if (!timeout) {
+-              dev_warn(&master->dev,
++              dev_warn(&host->dev,
+                        "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
+                        dev_name(&spi->dev), tfr->len, tfr->speed_hz,
+                        jiffies_to_msecs(end - start), tx_time);
+@@ -389,8 +389,8 @@ static irqreturn_t sun4i_spi_handler(int
+ static int sun4i_spi_runtime_resume(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct sun4i_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct sun4i_spi *sspi = spi_controller_get_devdata(host);
+       int ret;
+       ret = clk_prepare_enable(sspi->hclk);
+@@ -418,8 +418,8 @@ out:
+ static int sun4i_spi_runtime_suspend(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct sun4i_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct sun4i_spi *sspi = spi_controller_get_devdata(host);
+       clk_disable_unprepare(sspi->mclk);
+       clk_disable_unprepare(sspi->hclk);
+@@ -429,62 +429,62 @@ static int sun4i_spi_runtime_suspend(str
+ static int sun4i_spi_probe(struct platform_device *pdev)
+ {
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct sun4i_spi *sspi;
+       int ret = 0, irq;
+-      master = spi_alloc_master(&pdev->dev, sizeof(struct sun4i_spi));
+-      if (!master) {
+-              dev_err(&pdev->dev, "Unable to allocate SPI Master\n");
++      host = spi_alloc_host(&pdev->dev, sizeof(struct sun4i_spi));
++      if (!host) {
++              dev_err(&pdev->dev, "Unable to allocate SPI Host\n");
+               return -ENOMEM;
+       }
+-      platform_set_drvdata(pdev, master);
+-      sspi = spi_master_get_devdata(master);
++      platform_set_drvdata(pdev, host);
++      sspi = spi_controller_get_devdata(host);
+       sspi->base_addr = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(sspi->base_addr)) {
+               ret = PTR_ERR(sspi->base_addr);
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = -ENXIO;
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       ret = devm_request_irq(&pdev->dev, irq, sun4i_spi_handler,
+                              0, "sun4i-spi", sspi);
+       if (ret) {
+               dev_err(&pdev->dev, "Cannot request IRQ\n");
+-              goto err_free_master;
++              goto err_free_host;
+       }
+-      sspi->master = master;
+-      master->max_speed_hz = 100 * 1000 * 1000;
+-      master->min_speed_hz = 3 * 1000;
+-      master->set_cs = sun4i_spi_set_cs;
+-      master->transfer_one = sun4i_spi_transfer_one;
+-      master->num_chipselect = 4;
+-      master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
+-      master->bits_per_word_mask = SPI_BPW_MASK(8);
+-      master->dev.of_node = pdev->dev.of_node;
+-      master->auto_runtime_pm = true;
+-      master->max_transfer_size = sun4i_spi_max_transfer_size;
++      sspi->host = host;
++      host->max_speed_hz = 100 * 1000 * 1000;
++      host->min_speed_hz = 3 * 1000;
++      host->set_cs = sun4i_spi_set_cs;
++      host->transfer_one = sun4i_spi_transfer_one;
++      host->num_chipselect = 4;
++      host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
++      host->bits_per_word_mask = SPI_BPW_MASK(8);
++      host->dev.of_node = pdev->dev.of_node;
++      host->auto_runtime_pm = true;
++      host->max_transfer_size = sun4i_spi_max_transfer_size;
+       sspi->hclk = devm_clk_get(&pdev->dev, "ahb");
+       if (IS_ERR(sspi->hclk)) {
+               dev_err(&pdev->dev, "Unable to acquire AHB clock\n");
+               ret = PTR_ERR(sspi->hclk);
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       sspi->mclk = devm_clk_get(&pdev->dev, "mod");
+       if (IS_ERR(sspi->mclk)) {
+               dev_err(&pdev->dev, "Unable to acquire module clock\n");
+               ret = PTR_ERR(sspi->mclk);
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       init_completion(&sspi->done);
+@@ -496,16 +496,16 @@ static int sun4i_spi_probe(struct platfo
+       ret = sun4i_spi_runtime_resume(&pdev->dev);
+       if (ret) {
+               dev_err(&pdev->dev, "Couldn't resume the device\n");
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_idle(&pdev->dev);
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = devm_spi_register_controller(&pdev->dev, host);
+       if (ret) {
+-              dev_err(&pdev->dev, "cannot register SPI master\n");
++              dev_err(&pdev->dev, "cannot register SPI host\n");
+               goto err_pm_disable;
+       }
+@@ -514,8 +514,8 @@ static int sun4i_spi_probe(struct platfo
+ err_pm_disable:
+       pm_runtime_disable(&pdev->dev);
+       sun4i_spi_runtime_suspend(&pdev->dev);
+-err_free_master:
+-      spi_master_put(master);
++err_free_host:
++      spi_controller_put(host);
+       return ret;
+ }
diff --git a/queue-6.6/spi-sun6i-fix-controller-deregistration.patch b/queue-6.6/spi-sun6i-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..c559c43
--- /dev/null
@@ -0,0 +1,57 @@
+From stable+bounces-247048-greg=kroah.com@vger.kernel.org Thu May 14 01:06:27 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 19:05:13 -0400
+Subject: spi: sun6i: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Maxime Ripard <mripard@kernel.org>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513230513.4027915-2-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit d874a1c33aee0d88fb4ba2f8aeadaa9f1965209a ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: 3558fe900e8a ("spi: sunxi: Add Allwinner A31 SPI controller driver")
+Cc: stable@vger.kernel.org     # 3.15
+Cc: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-20-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-sun6i.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-sun6i.c
++++ b/drivers/spi/spi-sun6i.c
+@@ -742,7 +742,7 @@ static int sun6i_spi_probe(struct platfo
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+-      ret = devm_spi_register_controller(&pdev->dev, host);
++      ret = spi_register_controller(host);
+       if (ret) {
+               dev_err(&pdev->dev, "cannot register SPI host\n");
+               goto err_pm_disable;
+@@ -768,12 +768,18 @@ static void sun6i_spi_remove(struct plat
+ {
+       struct spi_controller *host = platform_get_drvdata(pdev);
++      spi_controller_get(host);
++
++      spi_unregister_controller(host);
++
+       pm_runtime_force_suspend(&pdev->dev);
+       if (host->dma_tx)
+               dma_release_channel(host->dma_tx);
+       if (host->dma_rx)
+               dma_release_channel(host->dma_rx);
++
++      spi_controller_put(host);
+ }
+ static const struct sun6i_spi_cfg sun6i_a31_spi_cfg = {
diff --git a/queue-6.6/spi-sun6i-switch-to-use-modern-name.patch b/queue-6.6/spi-sun6i-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..2e1de74
--- /dev/null
@@ -0,0 +1,392 @@
+From stable+bounces-247047-greg=kroah.com@vger.kernel.org Thu May 14 01:06:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 19:05:12 -0400
+Subject: spi: sun6i: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513230513.4027915-1-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 9f55bb79893a9dc75982372bee1307bdce48976b ]
+
+Change legacy name master to modern name host or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-8-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: d874a1c33aee ("spi: sun6i: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-sun6i.c |  148 ++++++++++++++++++++++++------------------------
+ 1 file changed, 74 insertions(+), 74 deletions(-)
+
+--- a/drivers/spi/spi-sun6i.c
++++ b/drivers/spi/spi-sun6i.c
+@@ -97,7 +97,7 @@ struct sun6i_spi_cfg {
+ };
+ struct sun6i_spi {
+-      struct spi_master       *master;
++      struct spi_controller   *host;
+       void __iomem            *base_addr;
+       dma_addr_t              dma_addr_rx;
+       dma_addr_t              dma_addr_tx;
+@@ -181,7 +181,7 @@ static inline void sun6i_spi_fill_fifo(s
+ static void sun6i_spi_set_cs(struct spi_device *spi, bool enable)
+ {
+-      struct sun6i_spi *sspi = spi_master_get_devdata(spi->master);
++      struct sun6i_spi *sspi = spi_controller_get_devdata(spi->controller);
+       u32 reg;
+       reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
+@@ -212,7 +212,7 @@ static int sun6i_spi_prepare_dma(struct
+                                struct spi_transfer *tfr)
+ {
+       struct dma_async_tx_descriptor *rxdesc, *txdesc;
+-      struct spi_master *master = sspi->master;
++      struct spi_controller *host = sspi->host;
+       rxdesc = NULL;
+       if (tfr->rx_buf) {
+@@ -223,9 +223,9 @@ static int sun6i_spi_prepare_dma(struct
+                       .src_maxburst = 8,
+               };
+-              dmaengine_slave_config(master->dma_rx, &rxconf);
++              dmaengine_slave_config(host->dma_rx, &rxconf);
+-              rxdesc = dmaengine_prep_slave_sg(master->dma_rx,
++              rxdesc = dmaengine_prep_slave_sg(host->dma_rx,
+                                                tfr->rx_sg.sgl,
+                                                tfr->rx_sg.nents,
+                                                DMA_DEV_TO_MEM,
+@@ -245,38 +245,38 @@ static int sun6i_spi_prepare_dma(struct
+                       .dst_maxburst = 8,
+               };
+-              dmaengine_slave_config(master->dma_tx, &txconf);
++              dmaengine_slave_config(host->dma_tx, &txconf);
+-              txdesc = dmaengine_prep_slave_sg(master->dma_tx,
++              txdesc = dmaengine_prep_slave_sg(host->dma_tx,
+                                                tfr->tx_sg.sgl,
+                                                tfr->tx_sg.nents,
+                                                DMA_MEM_TO_DEV,
+                                                DMA_PREP_INTERRUPT);
+               if (!txdesc) {
+                       if (rxdesc)
+-                              dmaengine_terminate_sync(master->dma_rx);
++                              dmaengine_terminate_sync(host->dma_rx);
+                       return -EINVAL;
+               }
+       }
+       if (tfr->rx_buf) {
+               dmaengine_submit(rxdesc);
+-              dma_async_issue_pending(master->dma_rx);
++              dma_async_issue_pending(host->dma_rx);
+       }
+       if (tfr->tx_buf) {
+               dmaengine_submit(txdesc);
+-              dma_async_issue_pending(master->dma_tx);
++              dma_async_issue_pending(host->dma_tx);
+       }
+       return 0;
+ }
+-static int sun6i_spi_transfer_one(struct spi_master *master,
++static int sun6i_spi_transfer_one(struct spi_controller *host,
+                                 struct spi_device *spi,
+                                 struct spi_transfer *tfr)
+ {
+-      struct sun6i_spi *sspi = spi_master_get_devdata(master);
++      struct sun6i_spi *sspi = spi_controller_get_devdata(host);
+       unsigned int div, div_cdr1, div_cdr2, timeout;
+       unsigned int start, end, tx_time;
+       unsigned int trig_level;
+@@ -293,7 +293,7 @@ static int sun6i_spi_transfer_one(struct
+       sspi->tx_buf = tfr->tx_buf;
+       sspi->rx_buf = tfr->rx_buf;
+       sspi->len = tfr->len;
+-      use_dma = master->can_dma ? master->can_dma(master, spi, tfr) : false;
++      use_dma = host->can_dma ? host->can_dma(host, spi, tfr) : false;
+       /* Clear pending interrupts */
+       sun6i_spi_write(sspi, SUN6I_INT_STA_REG, ~0);
+@@ -463,7 +463,7 @@ static int sun6i_spi_transfer_one(struct
+       } else {
+               ret = sun6i_spi_prepare_dma(sspi, tfr);
+               if (ret) {
+-                      dev_warn(&master->dev,
++                      dev_warn(&host->dev,
+                                "%s: prepare DMA failed, ret=%d",
+                                dev_name(&spi->dev), ret);
+                       return ret;
+@@ -486,7 +486,7 @@ static int sun6i_spi_transfer_one(struct
+       reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
+       sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH);
+-      tx_time = spi_controller_xfer_timeout(master, tfr);
++      tx_time = spi_controller_xfer_timeout(host, tfr);
+       start = jiffies;
+       timeout = wait_for_completion_timeout(&sspi->done,
+                                             msecs_to_jiffies(tx_time));
+@@ -502,13 +502,13 @@ static int sun6i_spi_transfer_one(struct
+                       timeout = wait_for_completion_timeout(&sspi->dma_rx_done,
+                                                             timeout);
+                       if (!timeout)
+-                              dev_warn(&master->dev, "RX DMA timeout\n");
++                              dev_warn(&host->dev, "RX DMA timeout\n");
+               }
+       }
+       end = jiffies;
+       if (!timeout) {
+-              dev_warn(&master->dev,
++              dev_warn(&host->dev,
+                        "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
+                        dev_name(&spi->dev), tfr->len, tfr->speed_hz,
+                        jiffies_to_msecs(end - start), tx_time);
+@@ -518,8 +518,8 @@ static int sun6i_spi_transfer_one(struct
+       sun6i_spi_write(sspi, SUN6I_INT_CTL_REG, 0);
+       if (ret && use_dma) {
+-              dmaengine_terminate_sync(master->dma_rx);
+-              dmaengine_terminate_sync(master->dma_tx);
++              dmaengine_terminate_sync(host->dma_rx);
++              dmaengine_terminate_sync(host->dma_tx);
+       }
+       return ret;
+@@ -564,8 +564,8 @@ static irqreturn_t sun6i_spi_handler(int
+ static int sun6i_spi_runtime_resume(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct sun6i_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct sun6i_spi *sspi = spi_controller_get_devdata(host);
+       int ret;
+       ret = clk_prepare_enable(sspi->hclk);
+@@ -601,8 +601,8 @@ out:
+ static int sun6i_spi_runtime_suspend(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct sun6i_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct sun6i_spi *sspi = spi_controller_get_devdata(host);
+       reset_control_assert(sspi->rstc);
+       clk_disable_unprepare(sspi->mclk);
+@@ -611,11 +611,11 @@ static int sun6i_spi_runtime_suspend(str
+       return 0;
+ }
+-static bool sun6i_spi_can_dma(struct spi_master *master,
++static bool sun6i_spi_can_dma(struct spi_controller *host,
+                             struct spi_device *spi,
+                             struct spi_transfer *xfer)
+ {
+-      struct sun6i_spi *sspi = spi_master_get_devdata(master);
++      struct sun6i_spi *sspi = spi_controller_get_devdata(host);
+       /*
+        * If the number of spi words to transfer is less or equal than
+@@ -627,67 +627,67 @@ static bool sun6i_spi_can_dma(struct spi
+ static int sun6i_spi_probe(struct platform_device *pdev)
+ {
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct sun6i_spi *sspi;
+       struct resource *mem;
+       int ret = 0, irq;
+-      master = spi_alloc_master(&pdev->dev, sizeof(struct sun6i_spi));
+-      if (!master) {
+-              dev_err(&pdev->dev, "Unable to allocate SPI Master\n");
++      host = spi_alloc_host(&pdev->dev, sizeof(struct sun6i_spi));
++      if (!host) {
++              dev_err(&pdev->dev, "Unable to allocate SPI Host\n");
+               return -ENOMEM;
+       }
+-      platform_set_drvdata(pdev, master);
+-      sspi = spi_master_get_devdata(master);
++      platform_set_drvdata(pdev, host);
++      sspi = spi_controller_get_devdata(host);
+       sspi->base_addr = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
+       if (IS_ERR(sspi->base_addr)) {
+               ret = PTR_ERR(sspi->base_addr);
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = -ENXIO;
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       ret = devm_request_irq(&pdev->dev, irq, sun6i_spi_handler,
+                              0, "sun6i-spi", sspi);
+       if (ret) {
+               dev_err(&pdev->dev, "Cannot request IRQ\n");
+-              goto err_free_master;
++              goto err_free_host;
+       }
+-      sspi->master = master;
++      sspi->host = host;
+       sspi->cfg = of_device_get_match_data(&pdev->dev);
+-      master->max_speed_hz = 100 * 1000 * 1000;
+-      master->min_speed_hz = 3 * 1000;
+-      master->use_gpio_descriptors = true;
+-      master->set_cs = sun6i_spi_set_cs;
+-      master->transfer_one = sun6i_spi_transfer_one;
+-      master->num_chipselect = 4;
+-      master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST |
+-                          sspi->cfg->mode_bits;
+-      master->bits_per_word_mask = SPI_BPW_MASK(8);
+-      master->dev.of_node = pdev->dev.of_node;
+-      master->auto_runtime_pm = true;
+-      master->max_transfer_size = sun6i_spi_max_transfer_size;
++      host->max_speed_hz = 100 * 1000 * 1000;
++      host->min_speed_hz = 3 * 1000;
++      host->use_gpio_descriptors = true;
++      host->set_cs = sun6i_spi_set_cs;
++      host->transfer_one = sun6i_spi_transfer_one;
++      host->num_chipselect = 4;
++      host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST |
++                        sspi->cfg->mode_bits;
++      host->bits_per_word_mask = SPI_BPW_MASK(8);
++      host->dev.of_node = pdev->dev.of_node;
++      host->auto_runtime_pm = true;
++      host->max_transfer_size = sun6i_spi_max_transfer_size;
+       sspi->hclk = devm_clk_get(&pdev->dev, "ahb");
+       if (IS_ERR(sspi->hclk)) {
+               dev_err(&pdev->dev, "Unable to acquire AHB clock\n");
+               ret = PTR_ERR(sspi->hclk);
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       sspi->mclk = devm_clk_get(&pdev->dev, "mod");
+       if (IS_ERR(sspi->mclk)) {
+               dev_err(&pdev->dev, "Unable to acquire module clock\n");
+               ret = PTR_ERR(sspi->mclk);
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       init_completion(&sspi->done);
+@@ -697,34 +697,34 @@ static int sun6i_spi_probe(struct platfo
+       if (IS_ERR(sspi->rstc)) {
+               dev_err(&pdev->dev, "Couldn't get reset controller\n");
+               ret = PTR_ERR(sspi->rstc);
+-              goto err_free_master;
++              goto err_free_host;
+       }
+-      master->dma_tx = dma_request_chan(&pdev->dev, "tx");
+-      if (IS_ERR(master->dma_tx)) {
++      host->dma_tx = dma_request_chan(&pdev->dev, "tx");
++      if (IS_ERR(host->dma_tx)) {
+               /* Check tx to see if we need defer probing driver */
+-              if (PTR_ERR(master->dma_tx) == -EPROBE_DEFER) {
++              if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+-                      goto err_free_master;
++                      goto err_free_host;
+               }
+               dev_warn(&pdev->dev, "Failed to request TX DMA channel\n");
+-              master->dma_tx = NULL;
++              host->dma_tx = NULL;
+       }
+-      master->dma_rx = dma_request_chan(&pdev->dev, "rx");
+-      if (IS_ERR(master->dma_rx)) {
+-              if (PTR_ERR(master->dma_rx) == -EPROBE_DEFER) {
++      host->dma_rx = dma_request_chan(&pdev->dev, "rx");
++      if (IS_ERR(host->dma_rx)) {
++              if (PTR_ERR(host->dma_rx) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+                       goto err_free_dma_tx;
+               }
+               dev_warn(&pdev->dev, "Failed to request RX DMA channel\n");
+-              master->dma_rx = NULL;
++              host->dma_rx = NULL;
+       }
+-      if (master->dma_tx && master->dma_rx) {
++      if (host->dma_tx && host->dma_rx) {
+               sspi->dma_addr_tx = mem->start + SUN6I_TXDATA_REG;
+               sspi->dma_addr_rx = mem->start + SUN6I_RXDATA_REG;
+-              master->can_dma = sun6i_spi_can_dma;
++              host->can_dma = sun6i_spi_can_dma;
+       }
+       /*
+@@ -742,9 +742,9 @@ static int sun6i_spi_probe(struct platfo
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = devm_spi_register_controller(&pdev->dev, host);
+       if (ret) {
+-              dev_err(&pdev->dev, "cannot register SPI master\n");
++              dev_err(&pdev->dev, "cannot register SPI host\n");
+               goto err_pm_disable;
+       }
+@@ -754,26 +754,26 @@ err_pm_disable:
+       pm_runtime_disable(&pdev->dev);
+       sun6i_spi_runtime_suspend(&pdev->dev);
+ err_free_dma_rx:
+-      if (master->dma_rx)
+-              dma_release_channel(master->dma_rx);
++      if (host->dma_rx)
++              dma_release_channel(host->dma_rx);
+ err_free_dma_tx:
+-      if (master->dma_tx)
+-              dma_release_channel(master->dma_tx);
+-err_free_master:
+-      spi_master_put(master);
++      if (host->dma_tx)
++              dma_release_channel(host->dma_tx);
++err_free_host:
++      spi_controller_put(host);
+       return ret;
+ }
+ static void sun6i_spi_remove(struct platform_device *pdev)
+ {
+-      struct spi_master *master = platform_get_drvdata(pdev);
++      struct spi_controller *host = platform_get_drvdata(pdev);
+       pm_runtime_force_suspend(&pdev->dev);
+-      if (master->dma_tx)
+-              dma_release_channel(master->dma_tx);
+-      if (master->dma_rx)
+-              dma_release_channel(master->dma_rx);
++      if (host->dma_tx)
++              dma_release_channel(host->dma_tx);
++      if (host->dma_rx)
++              dma_release_channel(host->dma_rx);
+ }
+ static const struct sun6i_spi_cfg sun6i_a31_spi_cfg = {
diff --git a/queue-6.6/spi-syncuacer-fix-controller-deregistration.patch b/queue-6.6/spi-syncuacer-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..cc20399
--- /dev/null
@@ -0,0 +1,54 @@
+From stable+bounces-246969-greg=kroah.com@vger.kernel.org Wed May 13 19:42:05 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:31:54 -0400
+Subject: spi: syncuacer: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Masahisa Kojima <masahisa.kojima@linaro.org>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513173154.3886494-2-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 75d849c3452e9611de031db45b3149ba9a99035f ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: b0823ee35cf9 ("spi: Add spi driver for Socionext SynQuacer platform")
+Cc: stable@vger.kernel.org     # 5.3
+Cc: Masahisa Kojima <masahisa.kojima@linaro.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-21-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-synquacer.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-synquacer.c
++++ b/drivers/spi/spi-synquacer.c
+@@ -719,7 +719,7 @@ static int synquacer_spi_probe(struct pl
+       pm_runtime_set_active(sspi->dev);
+       pm_runtime_enable(sspi->dev);
+-      ret = devm_spi_register_controller(sspi->dev, host);
++      ret = spi_register_controller(host);
+       if (ret)
+               goto disable_pm;
+@@ -740,9 +740,15 @@ static void synquacer_spi_remove(struct
+       struct spi_controller *host = platform_get_drvdata(pdev);
+       struct synquacer_spi *sspi = spi_controller_get_devdata(host);
++      spi_controller_get(host);
++
++      spi_unregister_controller(host);
++
+       pm_runtime_disable(sspi->dev);
+       clk_disable_unprepare(sspi->clk);
++
++      spi_controller_put(host);
+ }
+ static int __maybe_unused synquacer_spi_suspend(struct device *dev)
diff --git a/queue-6.6/spi-synquacer-switch-to-use-modern-name.patch b/queue-6.6/spi-synquacer-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..efa3713
--- /dev/null
@@ -0,0 +1,260 @@
+From stable+bounces-246968-greg=kroah.com@vger.kernel.org Wed May 13 19:32:28 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:31:53 -0400
+Subject: spi: synquacer: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513173154.3886494-1-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 3524d1b727a66712f02f92807219a3650e5cf910 ]
+
+Change legacy name master to modern name host or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-10-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 75d849c3452e ("spi: syncuacer: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-synquacer.c |   84 ++++++++++++++++++++++----------------------
+ 1 file changed, 42 insertions(+), 42 deletions(-)
+
+--- a/drivers/spi/spi-synquacer.c
++++ b/drivers/spi/spi-synquacer.c
+@@ -225,11 +225,11 @@ static int write_fifo(struct synquacer_s
+       return 0;
+ }
+-static int synquacer_spi_config(struct spi_master *master,
++static int synquacer_spi_config(struct spi_controller *host,
+                               struct spi_device *spi,
+                               struct spi_transfer *xfer)
+ {
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       unsigned int speed, mode, bpw, cs, bus_width, transfer_mode;
+       u32 rate, val, div;
+@@ -263,7 +263,7 @@ static int synquacer_spi_config(struct s
+       }
+       sspi->transfer_mode = transfer_mode;
+-      rate = master->max_speed_hz;
++      rate = host->max_speed_hz;
+       div = DIV_ROUND_UP(rate, speed);
+       if (div > 254) {
+@@ -350,11 +350,11 @@ static int synquacer_spi_config(struct s
+       return 0;
+ }
+-static int synquacer_spi_transfer_one(struct spi_master *master,
++static int synquacer_spi_transfer_one(struct spi_controller *host,
+                                     struct spi_device *spi,
+                                     struct spi_transfer *xfer)
+ {
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       int ret;
+       int status = 0;
+       u32 words;
+@@ -378,7 +378,7 @@ static int synquacer_spi_transfer_one(st
+       if (bpw == 8 && !(xfer->len % 4) && !(spi->mode & SPI_LSB_FIRST))
+               xfer->bits_per_word = 32;
+-      ret = synquacer_spi_config(master, spi, xfer);
++      ret = synquacer_spi_config(host, spi, xfer);
+       /* restore */
+       xfer->bits_per_word = bpw;
+@@ -482,7 +482,7 @@ static int synquacer_spi_transfer_one(st
+ static void synquacer_spi_set_cs(struct spi_device *spi, bool enable)
+ {
+-      struct synquacer_spi *sspi = spi_master_get_devdata(spi->master);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(spi->controller);
+       u32 val;
+       val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
+@@ -517,11 +517,11 @@ static int synquacer_spi_wait_status_upd
+       return -EBUSY;
+ }
+-static int synquacer_spi_enable(struct spi_master *master)
++static int synquacer_spi_enable(struct spi_controller *host)
+ {
+       u32 val;
+       int status;
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       /* Disable module */
+       writel(0, sspi->regs + SYNQUACER_HSSPI_REG_MCTRL);
+@@ -601,18 +601,18 @@ static irqreturn_t sq_spi_tx_handler(int
+ static int synquacer_spi_probe(struct platform_device *pdev)
+ {
+       struct device_node *np = pdev->dev.of_node;
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct synquacer_spi *sspi;
+       int ret;
+       int rx_irq, tx_irq;
+-      master = spi_alloc_master(&pdev->dev, sizeof(*sspi));
+-      if (!master)
++      host = spi_alloc_host(&pdev->dev, sizeof(*sspi));
++      if (!host)
+               return -ENOMEM;
+-      platform_set_drvdata(pdev, master);
++      platform_set_drvdata(pdev, host);
+-      sspi = spi_master_get_devdata(master);
++      sspi = spi_controller_get_devdata(host);
+       sspi->dev = &pdev->dev;
+       init_completion(&sspi->transfer_done);
+@@ -625,7 +625,7 @@ static int synquacer_spi_probe(struct pl
+       sspi->clk_src_type = SYNQUACER_HSSPI_CLOCK_SRC_IHCLK; /* Default */
+       device_property_read_u32(&pdev->dev, "socionext,ihclk-rate",
+-                               &master->max_speed_hz); /* for ACPI */
++                               &host->max_speed_hz); /* for ACPI */
+       if (dev_of_node(&pdev->dev)) {
+               if (device_property_match_string(&pdev->dev,
+@@ -655,21 +655,21 @@ static int synquacer_spi_probe(struct pl
+                       goto put_spi;
+               }
+-              master->max_speed_hz = clk_get_rate(sspi->clk);
++              host->max_speed_hz = clk_get_rate(sspi->clk);
+       }
+-      if (!master->max_speed_hz) {
++      if (!host->max_speed_hz) {
+               dev_err(&pdev->dev, "missing clock source\n");
+               ret = -EINVAL;
+               goto disable_clk;
+       }
+-      master->min_speed_hz = master->max_speed_hz / 254;
++      host->min_speed_hz = host->max_speed_hz / 254;
+       sspi->aces = device_property_read_bool(&pdev->dev,
+                                              "socionext,set-aces");
+       sspi->rtm = device_property_read_bool(&pdev->dev, "socionext,use-rtm");
+-      master->num_chipselect = SYNQUACER_HSSPI_NUM_CHIP_SELECT;
++      host->num_chipselect = SYNQUACER_HSSPI_NUM_CHIP_SELECT;
+       rx_irq = platform_get_irq(pdev, 0);
+       if (rx_irq <= 0) {
+@@ -699,27 +699,27 @@ static int synquacer_spi_probe(struct pl
+               goto disable_clk;
+       }
+-      master->dev.of_node = np;
+-      master->dev.fwnode = pdev->dev.fwnode;
+-      master->auto_runtime_pm = true;
+-      master->bus_num = pdev->id;
+-
+-      master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_DUAL | SPI_RX_DUAL |
+-                          SPI_TX_QUAD | SPI_RX_QUAD;
+-      master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(24) |
+-                                   SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
++      host->dev.of_node = np;
++      host->dev.fwnode = pdev->dev.fwnode;
++      host->auto_runtime_pm = true;
++      host->bus_num = pdev->id;
++
++      host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_DUAL | SPI_RX_DUAL |
++                        SPI_TX_QUAD | SPI_RX_QUAD;
++      host->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(24) |
++                                 SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
+-      master->set_cs = synquacer_spi_set_cs;
+-      master->transfer_one = synquacer_spi_transfer_one;
++      host->set_cs = synquacer_spi_set_cs;
++      host->transfer_one = synquacer_spi_transfer_one;
+-      ret = synquacer_spi_enable(master);
++      ret = synquacer_spi_enable(host);
+       if (ret)
+               goto disable_clk;
+       pm_runtime_set_active(sspi->dev);
+       pm_runtime_enable(sspi->dev);
+-      ret = devm_spi_register_master(sspi->dev, master);
++      ret = devm_spi_register_controller(sspi->dev, host);
+       if (ret)
+               goto disable_pm;
+@@ -730,15 +730,15 @@ disable_pm:
+ disable_clk:
+       clk_disable_unprepare(sspi->clk);
+ put_spi:
+-      spi_master_put(master);
++      spi_controller_put(host);
+       return ret;
+ }
+ static void synquacer_spi_remove(struct platform_device *pdev)
+ {
+-      struct spi_master *master = platform_get_drvdata(pdev);
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = platform_get_drvdata(pdev);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       pm_runtime_disable(sspi->dev);
+@@ -747,11 +747,11 @@ static void synquacer_spi_remove(struct
+ static int __maybe_unused synquacer_spi_suspend(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       int ret;
+-      ret = spi_master_suspend(master);
++      ret = spi_controller_suspend(host);
+       if (ret)
+               return ret;
+@@ -763,8 +763,8 @@ static int __maybe_unused synquacer_spi_
+ static int __maybe_unused synquacer_spi_resume(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       int ret;
+       if (!pm_runtime_suspended(dev)) {
+@@ -778,7 +778,7 @@ static int __maybe_unused synquacer_spi_
+                       return ret;
+               }
+-              ret = synquacer_spi_enable(master);
++              ret = synquacer_spi_enable(host);
+               if (ret) {
+                       clk_disable_unprepare(sspi->clk);
+                       dev_err(dev, "failed to enable spi (%d)\n", ret);
+@@ -786,7 +786,7 @@ static int __maybe_unused synquacer_spi_
+               }
+       }
+-      ret = spi_master_resume(master);
++      ret = spi_controller_resume(host);
+       if (ret < 0)
+               clk_disable_unprepare(sspi->clk);
diff --git a/queue-6.6/spi-tegra114-fix-controller-deregistration.patch b/queue-6.6/spi-tegra114-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..00a547f
--- /dev/null
@@ -0,0 +1,59 @@
+From stable+bounces-247112-greg=kroah.com@vger.kernel.org Thu May 14 06:59:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 00:59:22 -0400
+Subject: spi: tegra114: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Jingoo Han <jg1.han@samsung.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514045922.25250-1-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 9c9c27ff2058142d8f800de3186d6864184958de ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: 5c8096439600 ("spi: tegra114: use devm_spi_register_master()")
+Cc: stable@vger.kernel.org     # 3.13
+Cc: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-22-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+[ renamed spi_controller/host API calls to spi_master/master equivalents ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-tegra114.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-tegra114.c
++++ b/drivers/spi/spi-tegra114.c
+@@ -1416,7 +1416,7 @@ static int tegra_spi_probe(struct platfo
+       }
+       master->dev.of_node = pdev->dev.of_node;
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = spi_register_master(master);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "can not register to master err %d\n", ret);
+               goto exit_free_irq;
+@@ -1442,6 +1442,10 @@ static void tegra_spi_remove(struct plat
+       struct spi_master *master = platform_get_drvdata(pdev);
+       struct tegra_spi_data   *tspi = spi_master_get_devdata(master);
++      spi_master_get(master);
++
++      spi_unregister_master(master);
++
+       free_irq(tspi->irq, tspi);
+       if (tspi->tx_dma_chan)
+@@ -1453,6 +1457,8 @@ static void tegra_spi_remove(struct plat
+       pm_runtime_disable(&pdev->dev);
+       if (!pm_runtime_status_suspended(&pdev->dev))
+               tegra_spi_runtime_suspend(&pdev->dev);
++
++      spi_master_put(master);
+ }
+ #ifdef CONFIG_PM_SLEEP
diff --git a/queue-6.6/spi-tegra20-sflash-fix-controller-deregistration.patch b/queue-6.6/spi-tegra20-sflash-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..55ff036
--- /dev/null
@@ -0,0 +1,57 @@
+From stable+bounces-247113-greg=kroah.com@vger.kernel.org Thu May 14 06:59:42 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 00:59:34 -0400
+Subject: spi: tegra20-sflash: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Jingoo Han <jg1.han@samsung.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514045934.26261-1-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit ad7310e983327f939dd6c4e801eab13238992572 ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: f12f7318c44a ("spi: tegra20-sflash: use devm_spi_register_master()")
+Cc: stable@vger.kernel.org     # 3.13
+Cc: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-23-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+[ translated spi_controller/host API to legacy spi_master/master naming and dropped devm-managed registration ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-tegra20-sflash.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-tegra20-sflash.c
++++ b/drivers/spi/spi-tegra20-sflash.c
+@@ -506,7 +506,7 @@ static int tegra_sflash_probe(struct pla
+       pm_runtime_put(&pdev->dev);
+       master->dev.of_node = pdev->dev.of_node;
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = spi_register_master(master);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "can not register to master err %d\n", ret);
+               goto exit_pm_disable;
+@@ -529,11 +529,17 @@ static void tegra_sflash_remove(struct p
+       struct spi_master *master = platform_get_drvdata(pdev);
+       struct tegra_sflash_data        *tsd = spi_master_get_devdata(master);
++      spi_master_get(master);
++
++      spi_unregister_master(master);
++
+       free_irq(tsd->irq, tsd);
+       pm_runtime_disable(&pdev->dev);
+       if (!pm_runtime_status_suspended(&pdev->dev))
+               tegra_sflash_runtime_suspend(&pdev->dev);
++
++      spi_master_put(master);
+ }
+ #ifdef CONFIG_PM_SLEEP
diff --git a/queue-6.6/spi-ti-qspi-fix-controller-deregistration.patch b/queue-6.6/spi-ti-qspi-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..18f53f5
--- /dev/null
@@ -0,0 +1,69 @@
+From stable+bounces-246997-greg=kroah.com@vger.kernel.org Wed May 13 20:10:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 14:08:42 -0400
+Subject: spi: ti-qspi: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Sebastian Andrzej Siewior <bigeasy@linutronix.de>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513180842.3912849-3-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 0c18a1bacbb1d8b8aa34d3d004a2cb8226c8b1ea ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Note that the controller is suspended before disabling and releasing
+resources since commit 3ac066e2227c ("spi: spi-ti-qspi: Suspend the
+queue before removing the device") which avoids issues like unclocked
+accesses but prevents SPI device drivers from doing I/O during
+deregistration.
+
+Fixes: 3b3a80019ff1 ("spi: ti-qspi: one only one interrupt handler")
+Cc: stable@vger.kernel.org     # 3.13
+Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-24-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-ti-qspi.c |   14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+--- a/drivers/spi/spi-ti-qspi.c
++++ b/drivers/spi/spi-ti-qspi.c
+@@ -895,7 +895,7 @@ no_dma:
+       qspi->mmap_enabled = false;
+       qspi->current_cs = -1;
+-      ret = devm_spi_register_controller(&pdev->dev, host);
++      ret = spi_register_controller(host);
+       if (!ret)
+               return 0;
+@@ -910,19 +910,17 @@ free_host:
+ static void ti_qspi_remove(struct platform_device *pdev)
+ {
+       struct ti_qspi *qspi = platform_get_drvdata(pdev);
+-      int rc;
+-      rc = spi_controller_suspend(qspi->host);
+-      if (rc) {
+-              dev_alert(&pdev->dev, "spi_controller_suspend() failed (%pe)\n",
+-                        ERR_PTR(rc));
+-              return;
+-      }
++      spi_controller_get(qspi->host);
++
++      spi_unregister_controller(qspi->host);
+       pm_runtime_put_sync(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       ti_qspi_dma_cleanup(qspi);
++
++      spi_controller_put(qspi->host);
+ }
+ static const struct dev_pm_ops ti_qspi_pm_ops = {
diff --git a/queue-6.6/spi-uniphier-fix-controller-deregistration.patch b/queue-6.6/spi-uniphier-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..8013e96
--- /dev/null
@@ -0,0 +1,59 @@
+From stable+bounces-247177-greg=kroah.com@vger.kernel.org Thu May 14 13:46:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 07:46:35 -0400
+Subject: spi: uniphier: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Keiji Hayashibara <hayashibara.keiji@socionext.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514114635.181243-3-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 0245435f777264ac45945ed2f325dd095a41d1af ]
+
+Make sure to deregister the controller before releasing underlying
+resources like DMA during driver unbind.
+
+Note that clocks were also disabled before the recent commit
+fdca270f8f87 ("spi: uniphier: Simplify clock handling with
+devm_clk_get_enabled()").
+
+Fixes: 5ba155a4d4cc ("spi: add SPI controller driver for UniPhier SoC")
+Cc: stable@vger.kernel.org     # 4.19
+Cc: Keiji Hayashibara <hayashibara.keiji@socionext.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-25-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-uniphier.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-uniphier.c
++++ b/drivers/spi/spi-uniphier.c
+@@ -747,7 +747,7 @@ static int uniphier_spi_probe(struct pla
+       host->max_dma_len = min(dma_tx_burst, dma_rx_burst);
+-      ret = devm_spi_register_controller(&pdev->dev, host);
++      ret = spi_register_controller(host);
+       if (ret)
+               goto out_release_dma;
+@@ -772,10 +772,16 @@ static void uniphier_spi_remove(struct p
+ {
+       struct spi_controller *host = platform_get_drvdata(pdev);
++      spi_controller_get(host);
++
++      spi_unregister_controller(host);
++
+       if (host->dma_tx)
+               dma_release_channel(host->dma_tx);
+       if (host->dma_rx)
+               dma_release_channel(host->dma_rx);
++
++      spi_controller_put(host);
+ }
+ static const struct of_device_id uniphier_spi_match[] = {
diff --git a/queue-6.6/spi-uniphier-simplify-clock-handling-with-devm_clk_get_enabled.patch b/queue-6.6/spi-uniphier-simplify-clock-handling-with-devm_clk_get_enabled.patch
new file mode 100644 (file)
index 0000000..d7fc766
--- /dev/null
@@ -0,0 +1,99 @@
+From stable+bounces-247176-greg=kroah.com@vger.kernel.org Thu May 14 13:46:42 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 07:46:34 -0400
+Subject: spi: uniphier: Simplify clock handling with devm_clk_get_enabled()
+To: stable@vger.kernel.org
+Cc: Pei Xiao <xiaopei01@kylinos.cn>, Kunihiko Hayashi <hayashi.kunihiko@socionext.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514114635.181243-2-sashal@kernel.org>
+
+From: Pei Xiao <xiaopei01@kylinos.cn>
+
+[ Upstream commit fdca270f8f87cae2eb5b619234b9dd11a863ce6b ]
+
+Replace devm_clk_get() followed by clk_prepare_enable() with
+devm_clk_get_enabled() for the clock. This removes the need for
+explicit clock enable and disable calls, as the managed API automatically
+handles clock disabling on device removal or probe failure.
+
+Remove the now-unnecessary clk_disable_unprepare() calls from the probe
+error path and the remove callback. Adjust error labels accordingly.
+
+Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
+Reviewed-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Link: https://patch.msgid.link/b2deeefd4ef1a4bce71116aabfcb7e81400f6d37.1775546948.git.xiaopei01@kylinos.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0245435f7772 ("spi: uniphier: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-uniphier.c |   18 ++++--------------
+ 1 file changed, 4 insertions(+), 14 deletions(-)
+
+--- a/drivers/spi/spi-uniphier.c
++++ b/drivers/spi/spi-uniphier.c
+@@ -666,28 +666,24 @@ static int uniphier_spi_probe(struct pla
+       }
+       priv->base_dma_addr = res->start;
+-      priv->clk = devm_clk_get(&pdev->dev, NULL);
++      priv->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+       if (IS_ERR(priv->clk)) {
+               dev_err(&pdev->dev, "failed to get clock\n");
+               ret = PTR_ERR(priv->clk);
+               goto out_host_put;
+       }
+-      ret = clk_prepare_enable(priv->clk);
+-      if (ret)
+-              goto out_host_put;
+-
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = irq;
+-              goto out_disable_clk;
++              goto out_host_put;
+       }
+       ret = devm_request_irq(&pdev->dev, irq, uniphier_spi_handler,
+                              0, "uniphier-spi", priv);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to request IRQ\n");
+-              goto out_disable_clk;
++              goto out_host_put;
+       }
+       init_completion(&priv->xfer_done);
+@@ -717,7 +713,7 @@ static int uniphier_spi_probe(struct pla
+       if (IS_ERR_OR_NULL(host->dma_tx)) {
+               if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+-                      goto out_disable_clk;
++                      goto out_host_put;
+               }
+               host->dma_tx = NULL;
+               dma_tx_burst = INT_MAX;
+@@ -767,9 +763,6 @@ out_release_dma:
+               host->dma_tx = NULL;
+       }
+-out_disable_clk:
+-      clk_disable_unprepare(priv->clk);
+-
+ out_host_put:
+       spi_controller_put(host);
+       return ret;
+@@ -778,14 +771,11 @@ out_host_put:
+ static void uniphier_spi_remove(struct platform_device *pdev)
+ {
+       struct spi_controller *host = platform_get_drvdata(pdev);
+-      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       if (host->dma_tx)
+               dma_release_channel(host->dma_tx);
+       if (host->dma_rx)
+               dma_release_channel(host->dma_rx);
+-
+-      clk_disable_unprepare(priv->clk);
+ }
+ static const struct of_device_id uniphier_spi_match[] = {
diff --git a/queue-6.6/spi-uniphier-switch-to-use-modern-name.patch b/queue-6.6/spi-uniphier-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..00c8127
--- /dev/null
@@ -0,0 +1,513 @@
+From stable+bounces-247175-greg=kroah.com@vger.kernel.org Thu May 14 13:46:42 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 07:46:33 -0400
+Subject: spi: uniphier: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514114635.181243-1-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 4c2ee0991013ca8a32bb093a017d460204790112 ]
+
+Change legacy name master to modern name host or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-19-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0245435f7772 ("spi: uniphier: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-uniphier.c |  198 ++++++++++++++++++++++-----------------------
+ 1 file changed, 99 insertions(+), 99 deletions(-)
+
+--- a/drivers/spi/spi-uniphier.c
++++ b/drivers/spi/spi-uniphier.c
+@@ -26,7 +26,7 @@ struct uniphier_spi_priv {
+       void __iomem *base;
+       dma_addr_t base_dma_addr;
+       struct clk *clk;
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct completion xfer_done;
+       int error;
+@@ -127,7 +127,7 @@ static inline void uniphier_spi_irq_disa
+ static void uniphier_spi_set_mode(struct spi_device *spi)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(spi->controller);
+       u32 val1, val2;
+       /*
+@@ -180,7 +180,7 @@ static void uniphier_spi_set_mode(struct
+ static void uniphier_spi_set_transfer_size(struct spi_device *spi, int size)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(spi->controller);
+       u32 val;
+       val = readl(priv->base + SSI_TXWDS);
+@@ -198,7 +198,7 @@ static void uniphier_spi_set_transfer_si
+ static void uniphier_spi_set_baudrate(struct spi_device *spi,
+                                     unsigned int speed)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(spi->controller);
+       u32 val, ckdiv;
+       /*
+@@ -217,7 +217,7 @@ static void uniphier_spi_set_baudrate(st
+ static void uniphier_spi_setup_transfer(struct spi_device *spi,
+                                      struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(spi->controller);
+       u32 val;
+       priv->error = 0;
+@@ -333,7 +333,7 @@ static void uniphier_spi_fill_tx_fifo(st
+ static void uniphier_spi_set_cs(struct spi_device *spi, bool enable)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(spi->controller);
+       u32 val;
+       val = readl(priv->base + SSI_FPS);
+@@ -346,16 +346,16 @@ static void uniphier_spi_set_cs(struct s
+       writel(val, priv->base + SSI_FPS);
+ }
+-static bool uniphier_spi_can_dma(struct spi_master *master,
++static bool uniphier_spi_can_dma(struct spi_controller *host,
+                                struct spi_device *spi,
+                                struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       unsigned int bpw = bytes_per_word(priv->bits_per_word);
+-      if ((!master->dma_tx && !master->dma_rx)
+-          || (!master->dma_tx && t->tx_buf)
+-          || (!master->dma_rx && t->rx_buf))
++      if ((!host->dma_tx && !host->dma_rx)
++          || (!host->dma_tx && t->tx_buf)
++          || (!host->dma_rx && t->rx_buf))
+               return false;
+       return DIV_ROUND_UP(t->len, bpw) > SSI_FIFO_DEPTH;
+@@ -363,33 +363,33 @@ static bool uniphier_spi_can_dma(struct
+ static void uniphier_spi_dma_rxcb(void *data)
+ {
+-      struct spi_master *master = data;
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct spi_controller *host = data;
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       int state = atomic_fetch_andnot(SSI_DMA_RX_BUSY, &priv->dma_busy);
+       uniphier_spi_irq_disable(priv, SSI_IE_RXRE);
+       if (!(state & SSI_DMA_TX_BUSY))
+-              spi_finalize_current_transfer(master);
++              spi_finalize_current_transfer(host);
+ }
+ static void uniphier_spi_dma_txcb(void *data)
+ {
+-      struct spi_master *master = data;
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct spi_controller *host = data;
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       int state = atomic_fetch_andnot(SSI_DMA_TX_BUSY, &priv->dma_busy);
+       uniphier_spi_irq_disable(priv, SSI_IE_TXRE);
+       if (!(state & SSI_DMA_RX_BUSY))
+-              spi_finalize_current_transfer(master);
++              spi_finalize_current_transfer(host);
+ }
+-static int uniphier_spi_transfer_one_dma(struct spi_master *master,
++static int uniphier_spi_transfer_one_dma(struct spi_controller *host,
+                                        struct spi_device *spi,
+                                        struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       struct dma_async_tx_descriptor *rxdesc = NULL, *txdesc = NULL;
+       int buswidth;
+@@ -412,23 +412,23 @@ static int uniphier_spi_transfer_one_dma
+                       .src_maxburst = SSI_FIFO_BURST_NUM,
+               };
+-              dmaengine_slave_config(master->dma_rx, &rxconf);
++              dmaengine_slave_config(host->dma_rx, &rxconf);
+               rxdesc = dmaengine_prep_slave_sg(
+-                      master->dma_rx,
++                      host->dma_rx,
+                       t->rx_sg.sgl, t->rx_sg.nents,
+                       DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+               if (!rxdesc)
+                       goto out_err_prep;
+               rxdesc->callback = uniphier_spi_dma_rxcb;
+-              rxdesc->callback_param = master;
++              rxdesc->callback_param = host;
+               uniphier_spi_irq_enable(priv, SSI_IE_RXRE);
+               atomic_or(SSI_DMA_RX_BUSY, &priv->dma_busy);
+               dmaengine_submit(rxdesc);
+-              dma_async_issue_pending(master->dma_rx);
++              dma_async_issue_pending(host->dma_rx);
+       }
+       if (priv->tx_buf) {
+@@ -439,23 +439,23 @@ static int uniphier_spi_transfer_one_dma
+                       .dst_maxburst = SSI_FIFO_BURST_NUM,
+               };
+-              dmaengine_slave_config(master->dma_tx, &txconf);
++              dmaengine_slave_config(host->dma_tx, &txconf);
+               txdesc = dmaengine_prep_slave_sg(
+-                      master->dma_tx,
++                      host->dma_tx,
+                       t->tx_sg.sgl, t->tx_sg.nents,
+                       DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+               if (!txdesc)
+                       goto out_err_prep;
+               txdesc->callback = uniphier_spi_dma_txcb;
+-              txdesc->callback_param = master;
++              txdesc->callback_param = host;
+               uniphier_spi_irq_enable(priv, SSI_IE_TXRE);
+               atomic_or(SSI_DMA_TX_BUSY, &priv->dma_busy);
+               dmaengine_submit(txdesc);
+-              dma_async_issue_pending(master->dma_tx);
++              dma_async_issue_pending(host->dma_tx);
+       }
+       /* signal that we need to wait for completion */
+@@ -463,17 +463,17 @@ static int uniphier_spi_transfer_one_dma
+ out_err_prep:
+       if (rxdesc)
+-              dmaengine_terminate_sync(master->dma_rx);
++              dmaengine_terminate_sync(host->dma_rx);
+       return -EINVAL;
+ }
+-static int uniphier_spi_transfer_one_irq(struct spi_master *master,
++static int uniphier_spi_transfer_one_irq(struct spi_controller *host,
+                                        struct spi_device *spi,
+                                        struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
+-      struct device *dev = master->dev.parent;
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
++      struct device *dev = host->dev.parent;
+       unsigned long time_left;
+       reinit_completion(&priv->xfer_done);
+@@ -495,11 +495,11 @@ static int uniphier_spi_transfer_one_irq
+       return priv->error;
+ }
+-static int uniphier_spi_transfer_one_poll(struct spi_master *master,
++static int uniphier_spi_transfer_one_poll(struct spi_controller *host,
+                                         struct spi_device *spi,
+                                         struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       int loop = SSI_POLL_TIMEOUT_US * 10;
+       while (priv->tx_bytes) {
+@@ -520,14 +520,14 @@ static int uniphier_spi_transfer_one_pol
+       return 0;
+ irq_transfer:
+-      return uniphier_spi_transfer_one_irq(master, spi, t);
++      return uniphier_spi_transfer_one_irq(host, spi, t);
+ }
+-static int uniphier_spi_transfer_one(struct spi_master *master,
++static int uniphier_spi_transfer_one(struct spi_controller *host,
+                                    struct spi_device *spi,
+                                    struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       unsigned long threshold;
+       bool use_dma;
+@@ -537,9 +537,9 @@ static int uniphier_spi_transfer_one(str
+       uniphier_spi_setup_transfer(spi, t);
+-      use_dma = master->can_dma ? master->can_dma(master, spi, t) : false;
++      use_dma = host->can_dma ? host->can_dma(host, spi, t) : false;
+       if (use_dma)
+-              return uniphier_spi_transfer_one_dma(master, spi, t);
++              return uniphier_spi_transfer_one_dma(host, spi, t);
+       /*
+        * If the transfer operation will take longer than
+@@ -548,33 +548,33 @@ static int uniphier_spi_transfer_one(str
+       threshold = DIV_ROUND_UP(SSI_POLL_TIMEOUT_US * priv->speed_hz,
+                                       USEC_PER_SEC * BITS_PER_BYTE);
+       if (t->len > threshold)
+-              return uniphier_spi_transfer_one_irq(master, spi, t);
++              return uniphier_spi_transfer_one_irq(host, spi, t);
+       else
+-              return uniphier_spi_transfer_one_poll(master, spi, t);
++              return uniphier_spi_transfer_one_poll(host, spi, t);
+ }
+-static int uniphier_spi_prepare_transfer_hardware(struct spi_master *master)
++static int uniphier_spi_prepare_transfer_hardware(struct spi_controller *host)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       writel(SSI_CTL_EN, priv->base + SSI_CTL);
+       return 0;
+ }
+-static int uniphier_spi_unprepare_transfer_hardware(struct spi_master *master)
++static int uniphier_spi_unprepare_transfer_hardware(struct spi_controller *host)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       writel(0, priv->base + SSI_CTL);
+       return 0;
+ }
+-static void uniphier_spi_handle_err(struct spi_master *master,
++static void uniphier_spi_handle_err(struct spi_controller *host,
+                                   struct spi_message *msg)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       u32 val;
+       /* stop running spi transfer */
+@@ -587,12 +587,12 @@ static void uniphier_spi_handle_err(stru
+       uniphier_spi_irq_disable(priv, SSI_IE_ALL_MASK);
+       if (atomic_read(&priv->dma_busy) & SSI_DMA_TX_BUSY) {
+-              dmaengine_terminate_async(master->dma_tx);
++              dmaengine_terminate_async(host->dma_tx);
+               atomic_andnot(SSI_DMA_TX_BUSY, &priv->dma_busy);
+       }
+       if (atomic_read(&priv->dma_busy) & SSI_DMA_RX_BUSY) {
+-              dmaengine_terminate_async(master->dma_rx);
++              dmaengine_terminate_async(host->dma_rx);
+               atomic_andnot(SSI_DMA_RX_BUSY, &priv->dma_busy);
+       }
+ }
+@@ -641,7 +641,7 @@ done:
+ static int uniphier_spi_probe(struct platform_device *pdev)
+ {
+       struct uniphier_spi_priv *priv;
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct resource *res;
+       struct dma_slave_caps caps;
+       u32 dma_tx_burst = 0, dma_rx_burst = 0;
+@@ -649,20 +649,20 @@ static int uniphier_spi_probe(struct pla
+       int irq;
+       int ret;
+-      master = spi_alloc_master(&pdev->dev, sizeof(*priv));
+-      if (!master)
++      host = spi_alloc_host(&pdev->dev, sizeof(*priv));
++      if (!host)
+               return -ENOMEM;
+-      platform_set_drvdata(pdev, master);
++      platform_set_drvdata(pdev, host);
+-      priv = spi_master_get_devdata(master);
+-      priv->master = master;
++      priv = spi_controller_get_devdata(host);
++      priv->host = host;
+       priv->is_save_param = false;
+       priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+       if (IS_ERR(priv->base)) {
+               ret = PTR_ERR(priv->base);
+-              goto out_master_put;
++              goto out_host_put;
+       }
+       priv->base_dma_addr = res->start;
+@@ -670,12 +670,12 @@ static int uniphier_spi_probe(struct pla
+       if (IS_ERR(priv->clk)) {
+               dev_err(&pdev->dev, "failed to get clock\n");
+               ret = PTR_ERR(priv->clk);
+-              goto out_master_put;
++              goto out_host_put;
+       }
+       ret = clk_prepare_enable(priv->clk);
+       if (ret)
+-              goto out_master_put;
++              goto out_host_put;
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+@@ -694,35 +694,35 @@ static int uniphier_spi_probe(struct pla
+       clk_rate = clk_get_rate(priv->clk);
+-      master->max_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MIN_CLK_DIVIDER);
+-      master->min_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MAX_CLK_DIVIDER);
+-      master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
+-      master->dev.of_node = pdev->dev.of_node;
+-      master->bus_num = pdev->id;
+-      master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
+-
+-      master->set_cs = uniphier_spi_set_cs;
+-      master->transfer_one = uniphier_spi_transfer_one;
+-      master->prepare_transfer_hardware
++      host->max_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MIN_CLK_DIVIDER);
++      host->min_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MAX_CLK_DIVIDER);
++      host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
++      host->dev.of_node = pdev->dev.of_node;
++      host->bus_num = pdev->id;
++      host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
++
++      host->set_cs = uniphier_spi_set_cs;
++      host->transfer_one = uniphier_spi_transfer_one;
++      host->prepare_transfer_hardware
+                               = uniphier_spi_prepare_transfer_hardware;
+-      master->unprepare_transfer_hardware
++      host->unprepare_transfer_hardware
+                               = uniphier_spi_unprepare_transfer_hardware;
+-      master->handle_err = uniphier_spi_handle_err;
+-      master->can_dma = uniphier_spi_can_dma;
++      host->handle_err = uniphier_spi_handle_err;
++      host->can_dma = uniphier_spi_can_dma;
+-      master->num_chipselect = 1;
+-      master->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX;
++      host->num_chipselect = 1;
++      host->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX;
+-      master->dma_tx = dma_request_chan(&pdev->dev, "tx");
+-      if (IS_ERR_OR_NULL(master->dma_tx)) {
+-              if (PTR_ERR(master->dma_tx) == -EPROBE_DEFER) {
++      host->dma_tx = dma_request_chan(&pdev->dev, "tx");
++      if (IS_ERR_OR_NULL(host->dma_tx)) {
++              if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+                       goto out_disable_clk;
+               }
+-              master->dma_tx = NULL;
++              host->dma_tx = NULL;
+               dma_tx_burst = INT_MAX;
+       } else {
+-              ret = dma_get_slave_caps(master->dma_tx, &caps);
++              ret = dma_get_slave_caps(host->dma_tx, &caps);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to get TX DMA capacities: %d\n",
+                               ret);
+@@ -731,16 +731,16 @@ static int uniphier_spi_probe(struct pla
+               dma_tx_burst = caps.max_burst;
+       }
+-      master->dma_rx = dma_request_chan(&pdev->dev, "rx");
+-      if (IS_ERR_OR_NULL(master->dma_rx)) {
+-              if (PTR_ERR(master->dma_rx) == -EPROBE_DEFER) {
++      host->dma_rx = dma_request_chan(&pdev->dev, "rx");
++      if (IS_ERR_OR_NULL(host->dma_rx)) {
++              if (PTR_ERR(host->dma_rx) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+                       goto out_release_dma;
+               }
+-              master->dma_rx = NULL;
++              host->dma_rx = NULL;
+               dma_rx_burst = INT_MAX;
+       } else {
+-              ret = dma_get_slave_caps(master->dma_rx, &caps);
++              ret = dma_get_slave_caps(host->dma_rx, &caps);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to get RX DMA capacities: %d\n",
+                               ret);
+@@ -749,41 +749,41 @@ static int uniphier_spi_probe(struct pla
+               dma_rx_burst = caps.max_burst;
+       }
+-      master->max_dma_len = min(dma_tx_burst, dma_rx_burst);
++      host->max_dma_len = min(dma_tx_burst, dma_rx_burst);
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = devm_spi_register_controller(&pdev->dev, host);
+       if (ret)
+               goto out_release_dma;
+       return 0;
+ out_release_dma:
+-      if (!IS_ERR_OR_NULL(master->dma_rx)) {
+-              dma_release_channel(master->dma_rx);
+-              master->dma_rx = NULL;
+-      }
+-      if (!IS_ERR_OR_NULL(master->dma_tx)) {
+-              dma_release_channel(master->dma_tx);
+-              master->dma_tx = NULL;
++      if (!IS_ERR_OR_NULL(host->dma_rx)) {
++              dma_release_channel(host->dma_rx);
++              host->dma_rx = NULL;
++      }
++      if (!IS_ERR_OR_NULL(host->dma_tx)) {
++              dma_release_channel(host->dma_tx);
++              host->dma_tx = NULL;
+       }
+ out_disable_clk:
+       clk_disable_unprepare(priv->clk);
+-out_master_put:
+-      spi_master_put(master);
++out_host_put:
++      spi_controller_put(host);
+       return ret;
+ }
+ static void uniphier_spi_remove(struct platform_device *pdev)
+ {
+-      struct spi_master *master = platform_get_drvdata(pdev);
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct spi_controller *host = platform_get_drvdata(pdev);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+-      if (master->dma_tx)
+-              dma_release_channel(master->dma_tx);
+-      if (master->dma_rx)
+-              dma_release_channel(master->dma_rx);
++      if (host->dma_tx)
++              dma_release_channel(host->dma_tx);
++      if (host->dma_rx)
++              dma_release_channel(host->dma_rx);
+       clk_disable_unprepare(priv->clk);
+ }
diff --git a/queue-6.6/spi-zynq-qspi-fix-controller-deregistration.patch b/queue-6.6/spi-zynq-qspi-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..dde9db4
--- /dev/null
@@ -0,0 +1,73 @@
+From stable+bounces-247015-greg=kroah.com@vger.kernel.org Wed May 13 20:40:59 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 14:33:48 -0400
+Subject: spi: zynq-qspi: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513183348.3927281-3-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit c9c012706c9fa8ca6d129a9161caf92ab625a3fd ]
+
+Make sure to deregister the controller before disabling it during driver
+unbind.
+
+Note that clocks were also disabled before the recent commit
+1f8fd9490e31 ("spi: zynq-qspi: Simplify clock handling with
+devm_clk_get_enabled()").
+
+Fixes: 67dca5e580f1 ("spi: spi-mem: Add support for Zynq QSPI controller")
+Cc: stable@vger.kernel.org     # 5.2: 8eb2fd00f65a
+Cc: stable@vger.kernel.org     # 5.2
+Cc: Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-27-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-zynq-qspi.c |   15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-zynq-qspi.c
++++ b/drivers/spi/spi-zynq-qspi.c
+@@ -641,7 +641,7 @@ static int zynq_qspi_probe(struct platfo
+       xqspi = spi_controller_get_devdata(ctlr);
+       xqspi->dev = dev;
+-      platform_set_drvdata(pdev, xqspi);
++      platform_set_drvdata(pdev, ctlr);
+       xqspi->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(xqspi->regs)) {
+               ret = PTR_ERR(xqspi->regs);
+@@ -699,9 +699,9 @@ static int zynq_qspi_probe(struct platfo
+       /* QSPI controller initializations */
+       zynq_qspi_init_hw(xqspi, ctlr->num_chipselect);
+-      ret = devm_spi_register_controller(&pdev->dev, ctlr);
++      ret = spi_register_controller(ctlr);
+       if (ret) {
+-              dev_err(&pdev->dev, "devm_spi_register_controller failed\n");
++              dev_err(&pdev->dev, "failed to register controller\n");
+               goto remove_ctlr;
+       }
+@@ -725,9 +725,16 @@ remove_ctlr:
+  */
+ static void zynq_qspi_remove(struct platform_device *pdev)
+ {
+-      struct zynq_qspi *xqspi = platform_get_drvdata(pdev);
++      struct spi_controller *ctlr = platform_get_drvdata(pdev);
++      struct zynq_qspi *xqspi = spi_controller_get_devdata(ctlr);
++
++      spi_controller_get(ctlr);
++
++      spi_unregister_controller(ctlr);
+       zynq_qspi_write(xqspi, ZYNQ_QSPI_ENABLE_OFFSET, 0);
++
++      spi_controller_put(ctlr);
+ }
+ static const struct of_device_id zynq_qspi_of_match[] = {
diff --git a/queue-6.6/spi-zynq-qspi-simplify-clock-handling-with-devm_clk_get_enabled.patch b/queue-6.6/spi-zynq-qspi-simplify-clock-handling-with-devm_clk_get_enabled.patch
new file mode 100644 (file)
index 0000000..d3dc1ed
--- /dev/null
@@ -0,0 +1,142 @@
+From stable+bounces-247014-greg=kroah.com@vger.kernel.org Wed May 13 20:41:03 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 14:33:47 -0400
+Subject: spi: zynq-qspi: Simplify clock handling with devm_clk_get_enabled()
+To: stable@vger.kernel.org
+Cc: Pei Xiao <xiaopei01@kylinos.cn>, Michal Simek <michal.simek@amd.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513183348.3927281-2-sashal@kernel.org>
+
+From: Pei Xiao <xiaopei01@kylinos.cn>
+
+[ Upstream commit 1f8fd9490e3184e9a2394df2e682901a1d57ce71 ]
+
+Replace devm_clk_get() followed by clk_prepare_enable() with
+devm_clk_get_enabled() for both "pclk" and "ref_clk". This removes
+the need for explicit clock enable and disable calls, as the managed
+API automatically disables the clocks on device removal or probe
+failure.
+
+Remove the now-unnecessary clk_disable_unprepare() calls from the
+probe error paths and the remove callback. Simplify error handling
+by jumping directly to the remove_ctlr label.
+
+Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
+Acked-by: Michal Simek <michal.simek@amd.com>
+Link: https://patch.msgid.link/24043625f89376da36feca2408f990a85be7ab36.1775555500.git.xiaopei01@kylinos.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: c9c012706c9f ("spi: zynq-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-zynq-qspi.c |   42 ++++++------------------------------------
+ 1 file changed, 6 insertions(+), 36 deletions(-)
+
+--- a/drivers/spi/spi-zynq-qspi.c
++++ b/drivers/spi/spi-zynq-qspi.c
+@@ -379,21 +379,10 @@ static int zynq_qspi_setup_op(struct spi
+ {
+       struct spi_controller *ctlr = spi->controller;
+       struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
+-      int ret;
+       if (ctlr->busy)
+               return -EBUSY;
+-      ret = clk_enable(qspi->refclk);
+-      if (ret)
+-              return ret;
+-
+-      ret = clk_enable(qspi->pclk);
+-      if (ret) {
+-              clk_disable(qspi->refclk);
+-              return ret;
+-      }
+-
+       zynq_qspi_write(qspi, ZYNQ_QSPI_ENABLE_OFFSET,
+                       ZYNQ_QSPI_ENABLE_ENABLE_MASK);
+@@ -659,7 +648,7 @@ static int zynq_qspi_probe(struct platfo
+               goto remove_ctlr;
+       }
+-      xqspi->pclk = devm_clk_get(&pdev->dev, "pclk");
++      xqspi->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
+       if (IS_ERR(xqspi->pclk)) {
+               dev_err(&pdev->dev, "pclk clock not found.\n");
+               ret = PTR_ERR(xqspi->pclk);
+@@ -668,36 +657,24 @@ static int zynq_qspi_probe(struct platfo
+       init_completion(&xqspi->data_completion);
+-      xqspi->refclk = devm_clk_get(&pdev->dev, "ref_clk");
++      xqspi->refclk = devm_clk_get_enabled(&pdev->dev, "ref_clk");
+       if (IS_ERR(xqspi->refclk)) {
+               dev_err(&pdev->dev, "ref_clk clock not found.\n");
+               ret = PTR_ERR(xqspi->refclk);
+               goto remove_ctlr;
+       }
+-      ret = clk_prepare_enable(xqspi->pclk);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Unable to enable APB clock.\n");
+-              goto remove_ctlr;
+-      }
+-
+-      ret = clk_prepare_enable(xqspi->refclk);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Unable to enable device clock.\n");
+-              goto clk_dis_pclk;
+-      }
+-
+       xqspi->irq = platform_get_irq(pdev, 0);
+       if (xqspi->irq < 0) {
+               ret = xqspi->irq;
+-              goto clk_dis_all;
++              goto remove_ctlr;
+       }
+       ret = devm_request_irq(&pdev->dev, xqspi->irq, zynq_qspi_irq,
+                              0, pdev->name, xqspi);
+       if (ret != 0) {
+               ret = -ENXIO;
+               dev_err(&pdev->dev, "request_irq failed\n");
+-              goto clk_dis_all;
++              goto remove_ctlr;
+       }
+       ret = of_property_read_u32(np, "num-cs",
+@@ -707,7 +684,7 @@ static int zynq_qspi_probe(struct platfo
+       } else if (num_cs > ZYNQ_QSPI_MAX_NUM_CS) {
+               ret = -EINVAL;
+               dev_err(&pdev->dev, "only 2 chip selects are available\n");
+-              goto clk_dis_all;
++              goto remove_ctlr;
+       } else {
+               ctlr->num_chipselect = num_cs;
+       }
+@@ -725,15 +702,11 @@ static int zynq_qspi_probe(struct platfo
+       ret = devm_spi_register_controller(&pdev->dev, ctlr);
+       if (ret) {
+               dev_err(&pdev->dev, "devm_spi_register_controller failed\n");
+-              goto clk_dis_all;
++              goto remove_ctlr;
+       }
+       return ret;
+-clk_dis_all:
+-      clk_disable_unprepare(xqspi->refclk);
+-clk_dis_pclk:
+-      clk_disable_unprepare(xqspi->pclk);
+ remove_ctlr:
+       spi_controller_put(ctlr);
+@@ -755,9 +728,6 @@ static void zynq_qspi_remove(struct plat
+       struct zynq_qspi *xqspi = platform_get_drvdata(pdev);
+       zynq_qspi_write(xqspi, ZYNQ_QSPI_ENABLE_OFFSET, 0);
+-
+-      clk_disable_unprepare(xqspi->refclk);
+-      clk_disable_unprepare(xqspi->pclk);
+ }
+ static const struct of_device_id zynq_qspi_of_match[] = {
diff --git a/queue-6.6/spi-zynq-qspi-switch-to-use-modern-name.patch b/queue-6.6/spi-zynq-qspi-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..e55d0fb
--- /dev/null
@@ -0,0 +1,145 @@
+From stable+bounces-247013-greg=kroah.com@vger.kernel.org Wed May 13 20:39:57 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 14:33:46 -0400
+Subject: spi: zynq-qspi: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513183348.3927281-1-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 178ebb0c505b0a35edb4fb2a0e23a1f29e1db14d ]
+
+Change legacy name master/slave to modern name host/target or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-24-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: c9c012706c9f ("spi: zynq-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-zynq-qspi.c |   28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+--- a/drivers/spi/spi-zynq-qspi.c
++++ b/drivers/spi/spi-zynq-qspi.c
+@@ -54,10 +54,10 @@
+ #define ZYNQ_QSPI_CONFIG_MSTREN_MASK  BIT(0) /* Master Mode */
+ /*
+- * QSPI Configuration Register - Baud rate and slave select
++ * QSPI Configuration Register - Baud rate and target select
+  *
+  * These are the values used in the calculation of baud rate divisor and
+- * setting the slave select.
++ * setting the target select.
+  */
+ #define ZYNQ_QSPI_CONFIG_BAUD_DIV_MAX GENMASK(2, 0) /* Baud rate maximum */
+ #define ZYNQ_QSPI_CONFIG_BAUD_DIV_SHIFT       3 /* Baud rate divisor shift */
+@@ -164,14 +164,14 @@ static inline void zynq_qspi_write(struc
+  *
+  * The default settings of the QSPI controller's configurable parameters on
+  * reset are
+- *    - Master mode
++ *    - Host mode
+  *    - Baud rate divisor is set to 2
+  *    - Tx threshold set to 1l Rx threshold set to 32
+  *    - Flash memory interface mode enabled
+  *    - Size of the word to be transferred as 8 bit
+  * This function performs the following actions
+  *    - Disable and clear all the interrupts
+- *    - Enable manual slave select
++ *    - Enable manual target select
+  *    - Enable manual start
+  *    - Deselect all the chip select lines
+  *    - Set the size of the word to be transferred as 32 bit
+@@ -289,7 +289,7 @@ static void zynq_qspi_txfifo_op(struct z
+  */
+ static void zynq_qspi_chipselect(struct spi_device *spi, bool assert)
+ {
+-      struct spi_controller *ctlr = spi->master;
++      struct spi_controller *ctlr = spi->controller;
+       struct zynq_qspi *xqspi = spi_controller_get_devdata(ctlr);
+       u32 config_reg;
+@@ -377,7 +377,7 @@ static int zynq_qspi_config_op(struct zy
+  */
+ static int zynq_qspi_setup_op(struct spi_device *spi)
+ {
+-      struct spi_controller *ctlr = spi->master;
++      struct spi_controller *ctlr = spi->controller;
+       struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
+       int ret;
+@@ -534,7 +534,7 @@ static irqreturn_t zynq_qspi_irq(int irq
+ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
+                                const struct spi_mem_op *op)
+ {
+-      struct zynq_qspi *xqspi = spi_controller_get_devdata(mem->spi->master);
++      struct zynq_qspi *xqspi = spi_controller_get_devdata(mem->spi->controller);
+       int err = 0, i;
+       u8 *tmpbuf;
+@@ -646,7 +646,7 @@ static int zynq_qspi_probe(struct platfo
+       struct zynq_qspi *xqspi;
+       u32 num_cs;
+-      ctlr = spi_alloc_master(&pdev->dev, sizeof(*xqspi));
++      ctlr = spi_alloc_host(&pdev->dev, sizeof(*xqspi));
+       if (!ctlr)
+               return -ENOMEM;
+@@ -656,14 +656,14 @@ static int zynq_qspi_probe(struct platfo
+       xqspi->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(xqspi->regs)) {
+               ret = PTR_ERR(xqspi->regs);
+-              goto remove_master;
++              goto remove_ctlr;
+       }
+       xqspi->pclk = devm_clk_get(&pdev->dev, "pclk");
+       if (IS_ERR(xqspi->pclk)) {
+               dev_err(&pdev->dev, "pclk clock not found.\n");
+               ret = PTR_ERR(xqspi->pclk);
+-              goto remove_master;
++              goto remove_ctlr;
+       }
+       init_completion(&xqspi->data_completion);
+@@ -672,13 +672,13 @@ static int zynq_qspi_probe(struct platfo
+       if (IS_ERR(xqspi->refclk)) {
+               dev_err(&pdev->dev, "ref_clk clock not found.\n");
+               ret = PTR_ERR(xqspi->refclk);
+-              goto remove_master;
++              goto remove_ctlr;
+       }
+       ret = clk_prepare_enable(xqspi->pclk);
+       if (ret) {
+               dev_err(&pdev->dev, "Unable to enable APB clock.\n");
+-              goto remove_master;
++              goto remove_ctlr;
+       }
+       ret = clk_prepare_enable(xqspi->refclk);
+@@ -724,7 +724,7 @@ static int zynq_qspi_probe(struct platfo
+       ret = devm_spi_register_controller(&pdev->dev, ctlr);
+       if (ret) {
+-              dev_err(&pdev->dev, "spi_register_master failed\n");
++              dev_err(&pdev->dev, "devm_spi_register_controller failed\n");
+               goto clk_dis_all;
+       }
+@@ -734,7 +734,7 @@ clk_dis_all:
+       clk_disable_unprepare(xqspi->refclk);
+ clk_dis_pclk:
+       clk_disable_unprepare(xqspi->pclk);
+-remove_master:
++remove_ctlr:
+       spi_controller_put(ctlr);
+       return ret;
diff --git a/queue-6.6/tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch b/queue-6.6/tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch
new file mode 100644 (file)
index 0000000..f6da3dd
--- /dev/null
@@ -0,0 +1,56 @@
+From stable+bounces-245065-greg=kroah.com@vger.kernel.org Sun May 10 22:00:00 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 15:59:53 -0400
+Subject: tracepoint: balance regfunc() on func_add() failure in tracepoint_add_func()
+To: stable@vger.kernel.org
+Cc: David Carlier <devnexen@gmail.com>, Masami Hiramatsu <mhiramat@kernel.org>, Mathieu Desnoyers <mathieu.desnoyers@efficios.com>, "Steven Rostedt (Google)" <rostedt@goodmis.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260510195953.593373-1-sashal@kernel.org>
+
+From: David Carlier <devnexen@gmail.com>
+
+[ Upstream commit fad217e16fded7f3c09f8637b0f6a224d58b5f2e ]
+
+When a tracepoint goes through the 0 -> 1 transition, tracepoint_add_func()
+invokes the subsystem's ext->regfunc() before attempting to install the
+new probe via func_add(). If func_add() then fails (for example, when
+allocate_probes() cannot allocate a new probe array under memory pressure
+and returns -ENOMEM), the function returns the error without calling the
+matching ext->unregfunc(), leaving the side effects of regfunc() behind
+with no installed probe to justify them.
+
+For syscall tracepoints this is particularly unpleasant: syscall_regfunc()
+bumps sys_tracepoint_refcount and sets SYSCALL_TRACEPOINT on every task.
+After a leaked failure, the refcount is stuck at a non-zero value with no
+consumer, and every task continues paying the syscall trace entry/exit
+overhead until reboot. Other subsystems providing regfunc()/unregfunc()
+pairs exhibit similarly scoped persistent state.
+
+Mirror the existing 1 -> 0 cleanup and call ext->unregfunc() in the
+func_add() error path, gated on the same condition used there so the
+unwind is symmetric with the registration.
+
+Fixes: 8cf868affdc4 ("tracing: Have the reg function allow to fail")
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: https://patch.msgid.link/20260413190601.21993-1-devnexen@gmail.com
+Signed-off-by: David Carlier <devnexen@gmail.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+[ changed `tp->ext->unregfunc` to `tp->unregfunc` to match older struct layout ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/tracepoint.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/kernel/tracepoint.c
++++ b/kernel/tracepoint.c
+@@ -337,6 +337,8 @@ static int tracepoint_add_func(struct tr
+                       lockdep_is_held(&tracepoints_mutex));
+       old = func_add(&tp_funcs, func, prio);
+       if (IS_ERR(old)) {
++              if (tp->unregfunc && !static_key_enabled(&tp->key))
++                      tp->unregfunc();
+               WARN_ON_ONCE(warn && PTR_ERR(old) != -ENOMEM);
+               return PTR_ERR(old);
+       }
diff --git a/queue-6.6/xfrm-ah-account-for-esn-high-bits-in-async-callbacks.patch b/queue-6.6/xfrm-ah-account-for-esn-high-bits-in-async-callbacks.patch
new file mode 100644 (file)
index 0000000..b35ca80
--- /dev/null
@@ -0,0 +1,132 @@
+From stable+bounces-246945-greg=kroah.com@vger.kernel.org Wed May 13 19:18:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 12:46:35 -0400
+Subject: xfrm: ah: account for ESN high bits in async callbacks
+To: stable@vger.kernel.org
+Cc: Michael Bommarito <michael.bommarito@gmail.com>, Steffen Klassert <steffen.klassert@secunet.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513164635.3816490-3-sashal@kernel.org>
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit ec54093e6a8f87e800bb6aa15eb7fc1e33faa524 ]
+
+AH allocates its temporary auth/ICV layout differently when ESN is enabled:
+the async ahash setup appends a 4-byte seqhi slot before the ICV or
+auth_data area, but the async completion callbacks still reconstruct the
+temporary layout as if seqhi were absent.
+
+With an async AH implementation selected, that makes AH copy or compare
+the wrong bytes on both the IPv4 and IPv6 paths. In UML repro on IPv4 AH
+with ESN and forced async hmac(sha1), ping fails with 100% packet loss,
+and the callback logs show the pre-fix drift:
+
+  ah4 output_done: esn=1 err=0 icv_off=20 expected_off=24
+  ah4 input_done: esn=1 auth_off=20 expected_auth_off=24 icv_off=32 expected_icv_off=36
+
+Reconstruct the callback-side layout the same way the setup path built it
+by skipping the ESN seqhi slot before locating the saved auth_data or ICV.
+Per RFC 4302, the ESN high-order 32 bits participate in the AH ICV
+computation, so the async callbacks must account for the seqhi slot.
+
+Post-fix, the same IPv4 AH+ESN+forced-async-hmac(sha1) UML repro shows
+the corrected offset (ah4 output_done: esn=1 err=0 icv_off=24
+expected_off=24) and ping succeeds; net/ipv4/ah4.o and net/ipv6/ah6.o
+build clean at W=1. IPv6 AH+ESN was not exercised at runtime, and the
+change has not been tested against a real async hardware AH engine.
+
+Fixes: d4d573d0334d ("{IPv4,xfrm} Add ESN support for AH egress part")
+Fixes: d8b2a8600b0e ("{IPv4,xfrm} Add ESN support for AH ingress part")
+Fixes: 26dd70c3fad3 ("{IPv6,xfrm} Add ESN support for AH egress part")
+Fixes: 8d6da6f32557 ("{IPv6,xfrm} Add ESN support for AH ingress part")
+Cc: stable@vger.kernel.org
+Assisted-by: Codex:gpt-5-4
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ah4.c |   14 ++++++++++++--
+ net/ipv6/ah6.c |   14 ++++++++++++--
+ 2 files changed, 24 insertions(+), 4 deletions(-)
+
+--- a/net/ipv4/ah4.c
++++ b/net/ipv4/ah4.c
+@@ -124,9 +124,14 @@ static void ah_output_done(void *data, i
+       struct iphdr *top_iph = ip_hdr(skb);
+       struct ip_auth_hdr *ah = ip_auth_hdr(skb);
+       int ihl = ip_hdrlen(skb);
++      int seqhi_len = 0;
++      __be32 *seqhi;
++      if (x->props.flags & XFRM_STATE_ESN)
++              seqhi_len = sizeof(*seqhi);
+       iph = AH_SKB_CB(skb)->tmp;
+-      icv = ah_tmp_icv(iph, ihl);
++      seqhi = (__be32 *)((char *)iph + ihl);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       memcpy(ah->auth_data, icv, ahp->icv_trunc_len);
+       top_iph->tos = iph->tos;
+@@ -270,12 +275,17 @@ static void ah_input_done(void *data, in
+       struct ip_auth_hdr *ah = ip_auth_hdr(skb);
+       int ihl = ip_hdrlen(skb);
+       int ah_hlen = (ah->hdrlen + 2) << 2;
++      int seqhi_len = 0;
++      __be32 *seqhi;
+       if (err)
+               goto out;
++      if (x->props.flags & XFRM_STATE_ESN)
++              seqhi_len = sizeof(*seqhi);
+       work_iph = AH_SKB_CB(skb)->tmp;
+-      auth_data = ah_tmp_auth(work_iph, ihl);
++      seqhi = (__be32 *)((char *)work_iph + ihl);
++      auth_data = ah_tmp_auth(seqhi, seqhi_len);
+       icv = ah_tmp_icv(auth_data, ahp->icv_trunc_len);
+       err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
+--- a/net/ipv6/ah6.c
++++ b/net/ipv6/ah6.c
+@@ -317,14 +317,19 @@ static void ah6_output_done(void *data,
+       struct ipv6hdr *top_iph = ipv6_hdr(skb);
+       struct ip_auth_hdr *ah = ip_auth_hdr(skb);
+       struct tmp_ext *iph_ext;
++      int seqhi_len = 0;
++      __be32 *seqhi;
+       extlen = skb_network_header_len(skb) - sizeof(struct ipv6hdr);
+       if (extlen)
+               extlen += sizeof(*iph_ext);
++      if (x->props.flags & XFRM_STATE_ESN)
++              seqhi_len = sizeof(*seqhi);
+       iph_base = AH_SKB_CB(skb)->tmp;
+       iph_ext = ah_tmp_ext(iph_base);
+-      icv = ah_tmp_icv(iph_ext, extlen);
++      seqhi = (__be32 *)((char *)iph_ext + extlen);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       memcpy(ah->auth_data, icv, ahp->icv_trunc_len);
+       memcpy(top_iph, iph_base, IPV6HDR_BASELEN);
+@@ -471,13 +476,18 @@ static void ah6_input_done(void *data, i
+       struct ip_auth_hdr *ah = ip_auth_hdr(skb);
+       int hdr_len = skb_network_header_len(skb);
+       int ah_hlen = ipv6_authlen(ah);
++      int seqhi_len = 0;
++      __be32 *seqhi;
+       if (err)
+               goto out;
++      if (x->props.flags & XFRM_STATE_ESN)
++              seqhi_len = sizeof(*seqhi);
+       work_iph = AH_SKB_CB(skb)->tmp;
+       auth_data = ah_tmp_auth(work_iph, hdr_len);
+-      icv = ah_tmp_icv(auth_data, ahp->icv_trunc_len);
++      seqhi = (__be32 *)(auth_data + ahp->icv_trunc_len);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
+       if (err)
diff --git a/queue-6.6/xfrm-defensively-unhash-xfrm_state-lists-in-__xfrm_state_delete.patch b/queue-6.6/xfrm-defensively-unhash-xfrm_state-lists-in-__xfrm_state_delete.patch
new file mode 100644 (file)
index 0000000..da80a2c
--- /dev/null
@@ -0,0 +1,119 @@
+From stable+bounces-246964-greg=kroah.com@vger.kernel.org Wed May 13 19:16:52 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:16:28 -0400
+Subject: xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete
+To: stable@vger.kernel.org
+Cc: Michal Kosiorek <mkosiorek121@gmail.com>, Steffen Klassert <steffen.klassert@secunet.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513171628.3878131-1-sashal@kernel.org>
+
+From: Michal Kosiorek <mkosiorek121@gmail.com>
+
+[ Upstream commit 14acf9652e5690de3c7486c6db5fb8dafd0a32a3 ]
+
+KASAN reproduces a slab-use-after-free in __xfrm_state_delete()'s
+hlist_del_rcu calls under syzkaller load on linux-6.12.y stable
+(reproduced on 6.12.47, also reachable via the same code path on
+torvalds/master and on the ipsec tree). Nine unique signatures cluster
+in the xfrm_state lifecycle, the load-bearing one being:
+
+  BUG: KASAN: slab-use-after-free in __hlist_del include/linux/list.h:990 [inline]
+  BUG: KASAN: slab-use-after-free in hlist_del_rcu include/linux/rculist.h:516 [inline]
+  BUG: KASAN: slab-use-after-free in __xfrm_state_delete net/xfrm/xfrm_state.c
+  Write of size 8 at addr ffff8881198bcb70 by task kworker/u8:9/435
+
+  Workqueue: netns cleanup_net
+  Call Trace:
+   __hlist_del / hlist_del_rcu
+   __xfrm_state_delete
+   xfrm_state_delete
+   xfrm_state_flush
+   xfrm_state_fini
+   ops_exit_list
+   cleanup_net
+
+The other observed signatures hit the same slab object from
+__xfrm_state_lookup, xfrm_alloc_spi, __xfrm_state_insert and an OOB
+write variant of __xfrm_state_delete, all on the byseq/byspi
+hash chains.
+
+__xfrm_state_delete() guards its byseq and byspi unhashes with
+value-based predicates:
+
+       if (x->km.seq)
+               hlist_del_rcu(&x->byseq);
+       if (x->id.spi)
+               hlist_del_rcu(&x->byspi);
+
+while everywhere else in the file (e.g. state_cache, state_cache_input)
+the safer hlist_unhashed() check is used. xfrm_alloc_spi() sets
+x->id.spi = newspi inside xfrm_state_lock and then immediately inserts
+into byspi, but a path that observes x->id.spi != 0 outside of
+xfrm_state_lock can still skip-or-hit the byspi unhash inconsistently
+with whether x is actually on the list. The same holds for x->km.seq
+versus byseq, and the bydst/bysrc unhashes have no predicate at all,
+so a second __xfrm_state_delete() on the same object writes through
+LIST_POISON pprev.
+
+The defensive change here:
+
+  - Use hlist_del_init_rcu() instead of hlist_del_rcu() on bydst,
+    bysrc, byseq and byspi so a second deletion is a no-op rather
+    than a write through LIST_POISON pprev. The byseq/byspi nodes
+    are already initialised in xfrm_state_alloc().
+  - Test hlist_unhashed() rather than the value predicate for
+    byseq/byspi, so the unhash decision tracks list state rather than
+    mutable scalar fields.
+
+Empirical verification: applied this patch on top of v6.12.47, rebuilt,
+and re-ran the same syzkaller harness for 1h16m on a previously-crashy
+configuration that produced ~100 hits each of slab-use-after-free
+Read in xfrm_alloc_spi / Read in __xfrm_state_lookup / Write in
+__xfrm_state_delete. After the patch, 7.1M execs across 32 VMs at
+~1550 exec/sec produced zero xfrm_state UAF/OOB hits. /proc/slabinfo
+confirms the xfrm_state slab is actively allocated and freed during
+the run (~143 KiB resident), so the fuzzer is still exercising those
+code paths -- they just no longer crash.
+
+Reproduction:
+
+  - Linux 6.12.47 x86_64 + KASAN_GENERIC + KASAN_INLINE + KCOV
+  - syzkaller @ 746545b8b1e4c3a128db8652b340d3df90ce61db
+  - 32 QEMU/KVM VMs x 2 vCPU on AWS c5.metal bare metal
+  - 9 unique signatures collected in ~9h, all within xfrm_state
+    lifecycle
+
+Fixes: fe9f1d8779cb ("xfrm: add state hashtable keyed by seq")
+Fixes: 7b4dc3600e48 ("[XFRM]: Do not add a state whose SPI is zero to the SPI hash.")
+Reported-by: Michal Kosiorek <mkosiorek121@gmail.com>
+Tested-by: Michal Kosiorek <mkosiorek121@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Michal Kosiorek <mkosiorek121@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+[ dropped state_cache/state_cache_input unhash hunks and xfrm_nat_keepalive_state_updated() call ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/xfrm/xfrm_state.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -752,12 +752,12 @@ int __xfrm_state_delete(struct xfrm_stat
+               x->km.state = XFRM_STATE_DEAD;
+               spin_lock(&net->xfrm.xfrm_state_lock);
+               list_del(&x->km.all);
+-              hlist_del_rcu(&x->bydst);
+-              hlist_del_rcu(&x->bysrc);
+-              if (x->km.seq)
+-                      hlist_del_rcu(&x->byseq);
+-              if (x->id.spi)
+-                      hlist_del_rcu(&x->byspi);
++              hlist_del_init_rcu(&x->bydst);
++              hlist_del_init_rcu(&x->bysrc);
++              if (!hlist_unhashed(&x->byseq))
++                      hlist_del_init_rcu(&x->byseq);
++              if (!hlist_unhashed(&x->byspi))
++                      hlist_del_init_rcu(&x->byspi);
+               net->xfrm.state_num--;
+               spin_unlock(&net->xfrm.xfrm_state_lock);