]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
7.0-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 May 2026 16:04:49 +0000 (18:04 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 May 2026 16:04:49 +0000 (18:04 +0200)
added patches:
eventfs-simplify-code-using-guard-s.patch
eventfs-use-list_add_tail_rcu-for-srcu-protected-children-list.patch
smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch
spi-sifive-fix-controller-deregistration.patch
spi-sifive-simplify-clock-handling-with-devm_clk_get_enabled.patch

queue-7.0/eventfs-simplify-code-using-guard-s.patch [new file with mode: 0644]
queue-7.0/eventfs-use-list_add_tail_rcu-for-srcu-protected-children-list.patch [new file with mode: 0644]
queue-7.0/series
queue-7.0/smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch [new file with mode: 0644]
queue-7.0/spi-sifive-fix-controller-deregistration.patch [new file with mode: 0644]
queue-7.0/spi-sifive-simplify-clock-handling-with-devm_clk_get_enabled.patch [new file with mode: 0644]

diff --git a/queue-7.0/eventfs-simplify-code-using-guard-s.patch b/queue-7.0/eventfs-simplify-code-using-guard-s.patch
new file mode 100644 (file)
index 0000000..5529f43
--- /dev/null
@@ -0,0 +1,234 @@
+From stable+bounces-247810-greg=kroah.com@vger.kernel.org Fri May 15 17:14:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 11:06:59 -0400
+Subject: eventfs: Simplify code using guard()s
+To: stable@vger.kernel.org
+Cc: Steven Rostedt <rostedt@goodmis.org>, Mathieu Desnoyers <mathieu.desnoyers@efficios.com>, "Masami Hiramatsu (Google)" <mhiramat@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515150700.3261577-1-sashal@kernel.org>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit 4d9b262031ffef203243e53577a90ae6e1090e67 ]
+
+Use guard(mutex), scoped_guard(mutex) and guard(src) to simplify the code
+and remove a lot of the jumps to "out:" labels.
+
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: https://lore.kernel.org/20250604151625.250d13e1@gandalf.local.home
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Stable-dep-of: f67950b2887f ("eventfs: Use list_add_tail_rcu() for SRCU-protected children list")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/tracefs/event_inode.c |   96 +++++++++++++++++------------------------------
+ 1 file changed, 36 insertions(+), 60 deletions(-)
+
+--- a/fs/tracefs/event_inode.c
++++ b/fs/tracefs/event_inode.c
+@@ -180,29 +180,25 @@ static int eventfs_set_attr(struct mnt_i
+       const char *name;
+       int ret;
+-      mutex_lock(&eventfs_mutex);
++      guard(mutex)(&eventfs_mutex);
+       ei = dentry->d_fsdata;
+-      if (ei->is_freed) {
+-              /* Do not allow changes if the event is about to be removed. */
+-              mutex_unlock(&eventfs_mutex);
++      /* Do not allow changes if the event is about to be removed. */
++      if (ei->is_freed)
+               return -ENODEV;
+-      }
+       /* Preallocate the children mode array if necessary */
+       if (!(dentry->d_inode->i_mode & S_IFDIR)) {
+               if (!ei->entry_attrs) {
+                       ei->entry_attrs = kzalloc_objs(*ei->entry_attrs,
+                                                      ei->nr_entries, GFP_NOFS);
+-                      if (!ei->entry_attrs) {
+-                              ret = -ENOMEM;
+-                              goto out;
+-                      }
++                      if (!ei->entry_attrs)
++                              return -ENOMEM;
+               }
+       }
+       ret = simple_setattr(idmap, dentry, iattr);
+       if (ret < 0)
+-              goto out;
++              return ret;
+       /*
+        * If this is a dir, then update the ei cache, only the file
+@@ -225,8 +221,6 @@ static int eventfs_set_attr(struct mnt_i
+                       }
+               }
+       }
+- out:
+-      mutex_unlock(&eventfs_mutex);
+       return ret;
+ }
+@@ -530,26 +524,24 @@ static struct dentry *eventfs_root_looku
+       struct tracefs_inode *ti;
+       struct eventfs_inode *ei;
+       const char *name = dentry->d_name.name;
+-      struct dentry *result = NULL;
+       ti = get_tracefs(dir);
+       if (WARN_ON_ONCE(!(ti->flags & TRACEFS_EVENT_INODE)))
+               return ERR_PTR(-EIO);
+-      mutex_lock(&eventfs_mutex);
++      guard(mutex)(&eventfs_mutex);
+       ei = ti->private;
+       if (!ei || ei->is_freed)
+-              goto out;
++              return NULL;
+       list_for_each_entry(ei_child, &ei->children, list) {
+               if (strcmp(ei_child->name, name) != 0)
+                       continue;
+               /* A child is freed and removed from the list at the same time */
+               if (WARN_ON_ONCE(ei_child->is_freed))
+-                      goto out;
+-              result = lookup_dir_entry(dentry, ei, ei_child);
+-              goto out;
++                      return NULL;
++              return lookup_dir_entry(dentry, ei, ei_child);
+       }
+       for (int i = 0; i < ei->nr_entries; i++) {
+@@ -563,14 +555,12 @@ static struct dentry *eventfs_root_looku
+               data = ei->data;
+               if (entry->callback(name, &mode, &data, &fops) <= 0)
+-                      goto out;
++                      return NULL;
++
++              return lookup_file_dentry(dentry, ei, i, mode, data, fops);
+-              result = lookup_file_dentry(dentry, ei, i, mode, data, fops);
+-              goto out;
+       }
+- out:
+-      mutex_unlock(&eventfs_mutex);
+-      return result;
++      return NULL;
+ }
+ /*
+@@ -586,7 +576,6 @@ static int eventfs_iterate(struct file *
+       struct eventfs_inode *ei;
+       const char *name;
+       umode_t mode;
+-      int idx;
+       int ret = -EINVAL;
+       int ino;
+       int i, r, c;
+@@ -600,16 +589,13 @@ static int eventfs_iterate(struct file *
+       c = ctx->pos - 2;
+-      idx = srcu_read_lock(&eventfs_srcu);
++      guard(srcu)(&eventfs_srcu);
+-      mutex_lock(&eventfs_mutex);
+-      ei = READ_ONCE(ti->private);
+-      if (ei && ei->is_freed)
+-              ei = NULL;
+-      mutex_unlock(&eventfs_mutex);
+-
+-      if (!ei)
+-              goto out;
++      scoped_guard(mutex, &eventfs_mutex) {
++              ei = READ_ONCE(ti->private);
++              if (!ei || ei->is_freed)
++                      return -EINVAL;
++      }
+       /*
+        * Need to create the dentries and inodes to have a consistent
+@@ -624,21 +610,19 @@ static int eventfs_iterate(struct file *
+               entry = &ei->entries[i];
+               name = entry->name;
+-              mutex_lock(&eventfs_mutex);
+               /* If ei->is_freed then just bail here, nothing more to do */
+-              if (ei->is_freed) {
+-                      mutex_unlock(&eventfs_mutex);
+-                      goto out;
++              scoped_guard(mutex, &eventfs_mutex) {
++                      if (ei->is_freed)
++                              return -EINVAL;
++                      r = entry->callback(name, &mode, &cdata, &fops);
+               }
+-              r = entry->callback(name, &mode, &cdata, &fops);
+-              mutex_unlock(&eventfs_mutex);
+               if (r <= 0)
+                       continue;
+               ino = EVENTFS_FILE_INODE_INO;
+               if (!dir_emit(ctx, name, strlen(name), ino, DT_REG))
+-                      goto out;
++                      return -EINVAL;
+       }
+       /* Subtract the skipped entries above */
+@@ -661,19 +645,13 @@ static int eventfs_iterate(struct file *
+               ino = eventfs_dir_ino(ei_child);
+-              if (!dir_emit(ctx, name, strlen(name), ino, DT_DIR))
+-                      goto out_dec;
++              if (!dir_emit(ctx, name, strlen(name), ino, DT_DIR)) {
++                      /* Incremented ctx->pos without adding something, reset it */
++                      ctx->pos--;
++                      return -EINVAL;
++              }
+       }
+-      ret = 1;
+- out:
+-      srcu_read_unlock(&eventfs_srcu, idx);
+-
+-      return ret;
+-
+- out_dec:
+-      /* Incremented ctx->pos without adding something, reset it */
+-      ctx->pos--;
+-      goto out;
++      return 1;
+ }
+ /**
+@@ -730,11 +708,10 @@ struct eventfs_inode *eventfs_create_dir
+       INIT_LIST_HEAD(&ei->children);
+       INIT_LIST_HEAD(&ei->list);
+-      mutex_lock(&eventfs_mutex);
+-      if (!parent->is_freed)
+-              list_add_tail(&ei->list, &parent->children);
+-      mutex_unlock(&eventfs_mutex);
+-
++      scoped_guard(mutex, &eventfs_mutex) {
++              if (!parent->is_freed)
++                      list_add_tail(&ei->list, &parent->children);
++      }
+       /* Was the parent freed? */
+       if (list_empty(&ei->list)) {
+               cleanup_ei(ei);
+@@ -880,9 +857,8 @@ void eventfs_remove_dir(struct eventfs_i
+       if (!ei)
+               return;
+-      mutex_lock(&eventfs_mutex);
++      guard(mutex)(&eventfs_mutex);
+       eventfs_remove_rec(ei, 0);
+-      mutex_unlock(&eventfs_mutex);
+ }
+ /**
diff --git a/queue-7.0/eventfs-use-list_add_tail_rcu-for-srcu-protected-children-list.patch b/queue-7.0/eventfs-use-list_add_tail_rcu-for-srcu-protected-children-list.patch
new file mode 100644 (file)
index 0000000..7108d58
--- /dev/null
@@ -0,0 +1,44 @@
+From stable+bounces-247811-greg=kroah.com@vger.kernel.org Fri May 15 17:14:38 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 11:07:00 -0400
+Subject: eventfs: Use list_add_tail_rcu() for SRCU-protected children list
+To: stable@vger.kernel.org
+Cc: David Carlier <devnexen@gmail.com>, Steven Rostedt <rostedt@goodmis.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515150700.3261577-2-sashal@kernel.org>
+
+From: David Carlier <devnexen@gmail.com>
+
+[ Upstream commit f67950b2887fa10df50c4317a1fe98a65bc6875b ]
+
+Commit d2603279c7d6 ("eventfs: Use list_del_rcu() for SRCU protected
+list variable") converted the removal side to pair with the
+list_for_each_entry_srcu() walker in eventfs_iterate(). The insertion
+in eventfs_create_dir() was left as a plain list_add_tail(), which on
+weakly-ordered architectures can expose a new entry to the SRCU reader
+before its list pointers and fields are observable.
+
+Use list_add_tail_rcu() so the publication pairs with the existing
+list_del_rcu() and list_for_each_entry_srcu().
+
+Fixes: 43aa6f97c2d0 ("eventfs: Get rid of dentry pointers without refcounts")
+Cc: stable@vger.kernel.org
+Link: https://patch.msgid.link/20260418152251.199343-1-devnexen@gmail.com
+Signed-off-by: David Carlier <devnexen@gmail.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/tracefs/event_inode.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/tracefs/event_inode.c
++++ b/fs/tracefs/event_inode.c
+@@ -710,7 +710,7 @@ struct eventfs_inode *eventfs_create_dir
+       scoped_guard(mutex, &eventfs_mutex) {
+               if (!parent->is_freed)
+-                      list_add_tail(&ei->list, &parent->children);
++                      list_add_tail_rcu(&ei->list, &parent->children);
+       }
+       /* Was the parent freed? */
+       if (list_empty(&ei->list)) {
index f384273966c947f7b8e0d4e2945cfd930bd9b88b..9023ec89b32b2e84099eb1465905d35b41dba141 100644 (file)
@@ -1139,3 +1139,8 @@ arm_mpam-pretend-that-nrdy-is-always-hardware-managed.patch
 arm_mpam-improve-check-for-whether-or-not-nrdy-is-hardware-managed.patch
 arm_mpam-fix-false-positive-assert-failure-during-mpam_disable.patch
 arm_mpam-check-whether-the-config-array-is-allocated-before-destroying-it.patch
+eventfs-simplify-code-using-guard-s.patch
+eventfs-use-list_add_tail_rcu-for-srcu-protected-children-list.patch
+smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch
+spi-sifive-simplify-clock-handling-with-devm_clk_get_enabled.patch
+spi-sifive-fix-controller-deregistration.patch
diff --git a/queue-7.0/smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch b/queue-7.0/smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch
new file mode 100644 (file)
index 0000000..f04ccbe
--- /dev/null
@@ -0,0 +1,153 @@
+From stable+bounces-248470-greg=kroah.com@vger.kernel.org Fri May 15 18:53:17 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 12:16:50 -0400
+Subject: smb: client: Use FullSessionKey for AES-256 encryption key derivation
+To: stable@vger.kernel.org
+Cc: Piyush Sachdeva <s.piyush1024@gmail.com>, Bharath SM <bharathsm@microsoft.com>, Piyush Sachdeva <psachdeva@microsoft.com>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515161650.3376272-1-sashal@kernel.org>
+
+From: Piyush Sachdeva <s.piyush1024@gmail.com>
+
+[ Upstream commit 5be7a0cef3229fb3b63a07c0d289daf752545424 ]
+
+When Kerberos authentication is used with AES-256 encryption (AES-256-CCM
+or AES-256-GCM), the SMB3 encryption and decryption keys must be derived
+using the full session key (Session.FullSessionKey) rather than just the
+first 16 bytes (Session.SessionKey).
+
+Per MS-SMB2 section 3.2.5.3.1, when Connection.Dialect is "3.1.1" and
+Connection.CipherId is AES-256-CCM or AES-256-GCM, Session.FullSessionKey
+must be set to the full cryptographic key from the GSS authentication
+context. The encryption and decryption key derivation (SMBC2SCipherKey,
+SMBS2CCipherKey) must use this FullSessionKey as the KDF input. The
+signing key derivation continues to use Session.SessionKey (first 16
+bytes) in all cases.
+
+Previously, generate_key() hardcoded SMB2_NTLMV2_SESSKEY_SIZE (16) as the
+HMAC-SHA256 key input length for all derivations. When Kerberos with
+AES-256 provides a 32-byte session key, the KDF for encryption/decryption
+was using only the first 16 bytes, producing keys that did not match the
+server's, causing mount failures with sec=krb5 and require_gcm_256=1.
+
+Add a full_key_size parameter to generate_key() and pass the appropriate
+size from generate_smb3signingkey():
+ - Signing: always SMB2_NTLMV2_SESSKEY_SIZE (16 bytes)
+ - Encryption/Decryption: ses->auth_key.len when AES-256, otherwise 16
+
+Also fix cifs_dump_full_key() to report the actual session key length for
+AES-256 instead of hardcoded CIFS_SESS_KEY_SIZE, so that userspace tools
+like Wireshark receive the correct key for decryption.
+
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Bharath SM <bharathsm@microsoft.com>
+Signed-off-by: Piyush Sachdeva <psachdeva@microsoft.com>
+Signed-off-by: Piyush Sachdeva <s.piyush1024@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/ioctl.c         |    2 +-
+ fs/smb/client/smb2transport.c |   32 +++++++++++++++++++++++++-------
+ 2 files changed, 26 insertions(+), 8 deletions(-)
+
+--- a/fs/smb/client/ioctl.c
++++ b/fs/smb/client/ioctl.c
+@@ -296,7 +296,7 @@ search_end:
+               break;
+       case SMB2_ENCRYPTION_AES256_CCM:
+       case SMB2_ENCRYPTION_AES256_GCM:
+-              out.session_key_length = CIFS_SESS_KEY_SIZE;
++              out.session_key_length = ses->auth_key.len;
+               out.server_in_key_length = out.server_out_key_length = SMB3_GCM256_CRYPTKEY_SIZE;
+               break;
+       default:
+--- a/fs/smb/client/smb2transport.c
++++ b/fs/smb/client/smb2transport.c
+@@ -259,7 +259,8 @@ smb2_calc_signature(struct smb_rqst *rqs
+ }
+ static int generate_key(struct cifs_ses *ses, struct kvec label,
+-                      struct kvec context, __u8 *key, unsigned int key_size)
++                      struct kvec context, __u8 *key, unsigned int key_size,
++                      unsigned int full_key_size)
+ {
+       unsigned char zero = 0x0;
+       __u8 i[4] = {0, 0, 0, 1};
+@@ -280,7 +281,7 @@ static int generate_key(struct cifs_ses
+       }
+       hmac_sha256_init_usingrawkey(&hmac_ctx, ses->auth_key.response,
+-                                   SMB2_NTLMV2_SESSKEY_SIZE);
++                                   full_key_size);
+       hmac_sha256_update(&hmac_ctx, i, 4);
+       hmac_sha256_update(&hmac_ctx, label.iov_base, label.iov_len);
+       hmac_sha256_update(&hmac_ctx, &zero, 1);
+@@ -314,6 +315,7 @@ generate_smb3signingkey(struct cifs_ses
+                       struct TCP_Server_Info *server,
+                       const struct derivation_triplet *ptriplet)
+ {
++      unsigned int full_key_size = SMB2_NTLMV2_SESSKEY_SIZE;
+       int rc;
+       bool is_binding = false;
+       int chan_index = 0;
+@@ -348,17 +350,31 @@ generate_smb3signingkey(struct cifs_ses
+               rc = generate_key(ses, ptriplet->signing.label,
+                                 ptriplet->signing.context,
+                                 ses->chans[chan_index].signkey,
+-                                SMB3_SIGN_KEY_SIZE);
++                                SMB3_SIGN_KEY_SIZE,
++                                SMB2_NTLMV2_SESSKEY_SIZE);
+               if (rc)
+                       return rc;
+       } else {
+               rc = generate_key(ses, ptriplet->signing.label,
+                                 ptriplet->signing.context,
+                                 ses->smb3signingkey,
+-                                SMB3_SIGN_KEY_SIZE);
++                                SMB3_SIGN_KEY_SIZE,
++                                SMB2_NTLMV2_SESSKEY_SIZE);
+               if (rc)
+                       return rc;
++              /*
++               * Per MS-SMB2 3.2.5.3.1, signing key always uses Session.SessionKey
++               * (first 16 bytes). Encryption/decryption keys use
++               * Session.FullSessionKey when dialect is 3.1.1 and cipher is
++               * AES-256-CCM or AES-256-GCM, otherwise Session.SessionKey.
++               */
++
++              if (server->dialect == SMB311_PROT_ID &&
++                  (server->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
++                   server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
++                      full_key_size = ses->auth_key.len;
++
+               /* safe to access primary channel, since it will never go away */
+               spin_lock(&ses->chan_lock);
+               memcpy(ses->chans[chan_index].signkey, ses->smb3signingkey,
+@@ -368,13 +384,15 @@ generate_smb3signingkey(struct cifs_ses
+               rc = generate_key(ses, ptriplet->encryption.label,
+                                 ptriplet->encryption.context,
+                                 ses->smb3encryptionkey,
+-                                SMB3_ENC_DEC_KEY_SIZE);
++                                SMB3_ENC_DEC_KEY_SIZE,
++                                full_key_size);
+               if (rc)
+                       return rc;
+               rc = generate_key(ses, ptriplet->decryption.label,
+                                 ptriplet->decryption.context,
+                                 ses->smb3decryptionkey,
+-                                SMB3_ENC_DEC_KEY_SIZE);
++                                SMB3_ENC_DEC_KEY_SIZE,
++                                full_key_size);
+               if (rc)
+                       return rc;
+       }
+@@ -389,7 +407,7 @@ generate_smb3signingkey(struct cifs_ses
+                       &ses->Suid);
+       cifs_dbg(VFS, "Cipher type   %d\n", server->cipher_type);
+       cifs_dbg(VFS, "Session Key   %*ph\n",
+-               SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
++               (int)ses->auth_key.len, ses->auth_key.response);
+       cifs_dbg(VFS, "Signing Key   %*ph\n",
+                SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
+       if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
diff --git a/queue-7.0/spi-sifive-fix-controller-deregistration.patch b/queue-7.0/spi-sifive-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..a4a1c20
--- /dev/null
@@ -0,0 +1,57 @@
+From stable+bounces-249909-greg=kroah.com@vger.kernel.org Wed May 20 15:01:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 08:55:41 -0400
+Subject: spi: sifive: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Yash Shah <yash.shah@sifive.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520125541.3536279-2-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 0f25236694a2854627c1597465a071e6bb6fe572 ]
+
+Make sure to deregister the controller before disabling underlying
+resources like interrupts during driver unbind.
+
+Note that clocks were also disabled before the recent commit
+140039c23aca ("spi: sifive: Simplify clock handling with
+devm_clk_get_enabled()").
+
+Fixes: 484a9a68d669 ("spi: sifive: Add driver for the SiFive SPI controller")
+Cc: stable@vger.kernel.org     # 5.1
+Cc: Yash Shah <yash.shah@sifive.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-15-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-sifive.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-sifive.c
++++ b/drivers/spi/spi-sifive.c
+@@ -392,7 +392,7 @@ static int sifive_spi_probe(struct platf
+       dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n",
+                irq, host->num_chipselect);
+-      ret = devm_spi_register_controller(&pdev->dev, host);
++      ret = spi_register_controller(host);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "spi_register_host failed\n");
+               goto put_host;
+@@ -411,8 +411,14 @@ static void sifive_spi_remove(struct pla
+       struct spi_controller *host = platform_get_drvdata(pdev);
+       struct sifive_spi *spi = spi_controller_get_devdata(host);
++      spi_controller_get(host);
++
++      spi_unregister_controller(host);
++
+       /* Disable all the interrupts just in case */
+       sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0);
++
++      spi_controller_put(host);
+ }
+ static int sifive_spi_suspend(struct device *dev)
diff --git a/queue-7.0/spi-sifive-simplify-clock-handling-with-devm_clk_get_enabled.patch b/queue-7.0/spi-sifive-simplify-clock-handling-with-devm_clk_get_enabled.patch
new file mode 100644 (file)
index 0000000..5db593e
--- /dev/null
@@ -0,0 +1,106 @@
+From stable+bounces-249908-greg=kroah.com@vger.kernel.org Wed May 20 15:01:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 08:55:40 -0400
+Subject: spi: sifive: Simplify clock handling with devm_clk_get_enabled()
+To: stable@vger.kernel.org
+Cc: Pei Xiao <xiaopei01@kylinos.cn>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520125541.3536279-1-sashal@kernel.org>
+
+From: Pei Xiao <xiaopei01@kylinos.cn>
+
+[ Upstream commit 140039c23aca067b9ff0242e3c0ce96276bb95f3 ]
+
+Replace devm_clk_get() followed by clk_prepare_enable() with
+devm_clk_get_enabled() for the bus clock. This reduces boilerplate code
+and error handling, as the managed API automatically disables the clock
+when the device is removed or if probe fails.
+
+Remove the now-unnecessary clk_disable_unprepare() calls from the probe
+error path and the remove callback. Adjust the error handling to use the
+existing put_host label.
+
+Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
+Link: https://patch.msgid.link/73d0d8ecb4e1af5a558d6a7866c0f886d94fe3d1.1773885292.git.xiaopei01@kylinos.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0f25236694a2 ("spi: sifive: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-sifive.c |   21 ++++++---------------
+ 1 file changed, 6 insertions(+), 15 deletions(-)
+
+--- a/drivers/spi/spi-sifive.c
++++ b/drivers/spi/spi-sifive.c
+@@ -312,7 +312,8 @@ static int sifive_spi_probe(struct platf
+               goto put_host;
+       }
+-      spi->clk = devm_clk_get(&pdev->dev, NULL);
++      /* Spin up the bus clock before hitting registers */
++      spi->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+       if (IS_ERR(spi->clk)) {
+               dev_err(&pdev->dev, "Unable to find bus clock\n");
+               ret = PTR_ERR(spi->clk);
+@@ -342,13 +343,6 @@ static int sifive_spi_probe(struct platf
+               goto put_host;
+       }
+-      /* Spin up the bus clock before hitting registers */
+-      ret = clk_prepare_enable(spi->clk);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Unable to enable bus clock\n");
+-              goto put_host;
+-      }
+-
+       /* probe the number of CS lines */
+       spi->cs_inactive = sifive_spi_read(spi, SIFIVE_SPI_REG_CSDEF);
+       sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, 0xffffffffU);
+@@ -357,14 +351,14 @@ static int sifive_spi_probe(struct platf
+       if (!cs_bits) {
+               dev_err(&pdev->dev, "Could not auto probe CS lines\n");
+               ret = -EINVAL;
+-              goto disable_clk;
++              goto put_host;
+       }
+       num_cs = ilog2(cs_bits) + 1;
+       if (num_cs > SIFIVE_SPI_MAX_CS) {
+               dev_err(&pdev->dev, "Invalid number of spi targets\n");
+               ret = -EINVAL;
+-              goto disable_clk;
++              goto put_host;
+       }
+       /* Define our host */
+@@ -392,7 +386,7 @@ static int sifive_spi_probe(struct platf
+                              dev_name(&pdev->dev), spi);
+       if (ret) {
+               dev_err(&pdev->dev, "Unable to bind to interrupt\n");
+-              goto disable_clk;
++              goto put_host;
+       }
+       dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n",
+@@ -401,13 +395,11 @@ static int sifive_spi_probe(struct platf
+       ret = devm_spi_register_controller(&pdev->dev, host);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "spi_register_host failed\n");
+-              goto disable_clk;
++              goto put_host;
+       }
+       return 0;
+-disable_clk:
+-      clk_disable_unprepare(spi->clk);
+ put_host:
+       spi_controller_put(host);
+@@ -421,7 +413,6 @@ static void sifive_spi_remove(struct pla
+       /* Disable all the interrupts just in case */
+       sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0);
+-      clk_disable_unprepare(spi->clk);
+ }
+ static int sifive_spi_suspend(struct device *dev)