]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 Jul 2025 08:38:46 +0000 (10:38 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 9 Jul 2025 08:38:46 +0000 (10:38 +0200)
added patches:
firmware-arm_ffa-move-memory-allocation-outside-the-mutex-locking.patch
firmware-arm_ffa-replace-mutex-with-rwlock-to-avoid-sleep-in-atomic-context.patch

queue-6.12/firmware-arm_ffa-add-support-for-un-registration-of-.patch [deleted file]
queue-6.12/firmware-arm_ffa-move-memory-allocation-outside-the-.patch [deleted file]
queue-6.12/firmware-arm_ffa-move-memory-allocation-outside-the-mutex-locking.patch [new file with mode: 0644]
queue-6.12/firmware-arm_ffa-refactoring-to-prepare-for-framewor.patch [deleted file]
queue-6.12/firmware-arm_ffa-replace-mutex-with-rwlock-to-avoid-sleep-in-atomic-context.patch [new file with mode: 0644]
queue-6.12/firmware-arm_ffa-stash-ffa_device-instead-of-notify_.patch [deleted file]
queue-6.12/series

diff --git a/queue-6.12/firmware-arm_ffa-add-support-for-un-registration-of-.patch b/queue-6.12/firmware-arm_ffa-add-support-for-un-registration-of-.patch
deleted file mode 100644 (file)
index ac28700..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-From 39d93731826e452a9266714b570c6696b185724c Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 17 Feb 2025 15:38:57 +0000
-Subject: firmware: arm_ffa: Add support for {un,}registration of framework
- notifications
-
-From: Sudeep Holla <sudeep.holla@arm.com>
-
-[ Upstream commit c10debfe7f028c11f7a501a0f8e937c9be9e5327 ]
-
-Framework notifications are doorbells that are rung by the partition
-managers to signal common events to an endpoint. These doorbells cannot
-be rung by an endpoint directly. A partition manager can signal a
-Framework notification in response to an FF-A ABI invocation by an
-endpoint.
-
-Two additional notify_ops interface is being added for any FF-A device/
-driver to register and unregister for such a framework notifications.
-
-Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
-Message-Id: <20250217-ffa_updates-v3-16-bd1d9de615e7@arm.com>
-Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
-Stable-dep-of: 27e850c88df0 ("firmware: arm_ffa: Move memory allocation outside the mutex locking")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/firmware/arm_ffa/driver.c | 113 ++++++++++++++++++++++++------
- include/linux/arm_ffa.h           |   5 ++
- 2 files changed, 97 insertions(+), 21 deletions(-)
-
-diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
-index f0c7f417d7524..f19b142645cc5 100644
---- a/drivers/firmware/arm_ffa/driver.c
-+++ b/drivers/firmware/arm_ffa/driver.c
-@@ -1079,6 +1079,7 @@ static int ffa_memory_lend(struct ffa_mem_ops_args *args)
- struct notifier_cb_info {
-       struct hlist_node hnode;
-       struct ffa_device *dev;
-+      ffa_fwk_notifier_cb fwk_cb;
-       ffa_notifier_cb cb;
-       void *cb_data;
- };
-@@ -1142,28 +1143,61 @@ static enum notify_type ffa_notify_type_get(u16 vm_id)
-               return NON_SECURE_VM;
- }
--/* Should be called while the notify_lock is taken */
-+/* notifier_hnode_get* should be called with notify_lock held */
- static struct notifier_cb_info *
--notifier_hash_node_get(u16 notify_id, enum notify_type type)
-+notifier_hnode_get_by_vmid(u16 notify_id, int vmid)
- {
-       struct notifier_cb_info *node;
-       hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id)
--              if (type == ffa_notify_type_get(node->dev->vm_id))
-+              if (node->fwk_cb && vmid == node->dev->vm_id)
-+                      return node;
-+
-+      return NULL;
-+}
-+
-+static struct notifier_cb_info *
-+notifier_hnode_get_by_vmid_uuid(u16 notify_id, int vmid, const uuid_t *uuid)
-+{
-+      struct notifier_cb_info *node;
-+
-+      if (uuid_is_null(uuid))
-+              return notifier_hnode_get_by_vmid(notify_id, vmid);
-+
-+      hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id)
-+              if (node->fwk_cb && vmid == node->dev->vm_id &&
-+                  uuid_equal(&node->dev->uuid, uuid))
-+                      return node;
-+
-+      return NULL;
-+}
-+
-+static struct notifier_cb_info *
-+notifier_hnode_get_by_type(u16 notify_id, enum notify_type type)
-+{
-+      struct notifier_cb_info *node;
-+
-+      hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id)
-+              if (node->cb && type == ffa_notify_type_get(node->dev->vm_id))
-                       return node;
-       return NULL;
- }
- static int
--update_notifier_cb(struct ffa_device *dev, int notify_id, ffa_notifier_cb cb,
--                 void *cb_data, bool is_registration)
-+update_notifier_cb(struct ffa_device *dev, int notify_id, void *cb,
-+                 void *cb_data, bool is_registration, bool is_framework)
- {
-       struct notifier_cb_info *cb_info = NULL;
-       enum notify_type type = ffa_notify_type_get(dev->vm_id);
-       bool cb_found;
--      cb_info = notifier_hash_node_get(notify_id, type);
-+      if (is_framework)
-+              cb_info = notifier_hnode_get_by_vmid_uuid(notify_id, dev->vm_id,
-+                                                        &dev->uuid);
-+      else
-+              cb_info = notifier_hnode_get_by_type(notify_id, type);
-+
-       cb_found = !!cb_info;
-       if (!(is_registration ^ cb_found))
-@@ -1175,8 +1209,11 @@ update_notifier_cb(struct ffa_device *dev, int notify_id, ffa_notifier_cb cb,
-                       return -ENOMEM;
-               cb_info->dev = dev;
--              cb_info->cb = cb;
-               cb_info->cb_data = cb_data;
-+              if (is_framework)
-+                      cb_info->fwk_cb = cb;
-+              else
-+                      cb_info->cb = cb;
-               hash_add(drv_info->notifier_hash, &cb_info->hnode, notify_id);
-       } else {
-@@ -1187,7 +1224,8 @@ update_notifier_cb(struct ffa_device *dev, int notify_id, ffa_notifier_cb cb,
-       return 0;
- }
--static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
-+static int __ffa_notify_relinquish(struct ffa_device *dev, int notify_id,
-+                                 bool is_framework)
- {
-       int rc;
-@@ -1199,22 +1237,35 @@ static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
-       mutex_lock(&drv_info->notify_lock);
--      rc = update_notifier_cb(dev, notify_id, NULL, NULL, false);
-+      rc = update_notifier_cb(dev, notify_id, NULL, NULL, false,
-+                              is_framework);
-       if (rc) {
-               pr_err("Could not unregister notification callback\n");
-               mutex_unlock(&drv_info->notify_lock);
-               return rc;
-       }
--      rc = ffa_notification_unbind(dev->vm_id, BIT(notify_id));
-+      if (!is_framework)
-+              rc = ffa_notification_unbind(dev->vm_id, BIT(notify_id));
-       mutex_unlock(&drv_info->notify_lock);
-       return rc;
- }
--static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
--                            ffa_notifier_cb cb, void *cb_data, int notify_id)
-+static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
-+{
-+      return __ffa_notify_relinquish(dev, notify_id, false);
-+}
-+
-+static int ffa_fwk_notify_relinquish(struct ffa_device *dev, int notify_id)
-+{
-+      return __ffa_notify_relinquish(dev, notify_id, true);
-+}
-+
-+static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
-+                              void *cb, void *cb_data,
-+                              int notify_id, bool is_framework)
- {
-       int rc;
-       u32 flags = 0;
-@@ -1227,26 +1278,44 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
-       mutex_lock(&drv_info->notify_lock);
--      if (is_per_vcpu)
--              flags = PER_VCPU_NOTIFICATION_FLAG;
-+      if (!is_framework) {
-+              if (is_per_vcpu)
-+                      flags = PER_VCPU_NOTIFICATION_FLAG;
--      rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags);
--      if (rc) {
--              mutex_unlock(&drv_info->notify_lock);
--              return rc;
-+              rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags);
-+              if (rc) {
-+                      mutex_unlock(&drv_info->notify_lock);
-+                      return rc;
-+              }
-       }
--      rc = update_notifier_cb(dev, notify_id, cb, cb_data, true);
-+      rc = update_notifier_cb(dev, notify_id, cb, cb_data, true,
-+                              is_framework);
-       if (rc) {
-               pr_err("Failed to register callback for %d - %d\n",
-                      notify_id, rc);
--              ffa_notification_unbind(dev->vm_id, BIT(notify_id));
-+              if (!is_framework)
-+                      ffa_notification_unbind(dev->vm_id, BIT(notify_id));
-       }
-       mutex_unlock(&drv_info->notify_lock);
-       return rc;
- }
-+static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
-+                            ffa_notifier_cb cb, void *cb_data, int notify_id)
-+{
-+      return __ffa_notify_request(dev, is_per_vcpu, cb, cb_data, notify_id,
-+                                  false);
-+}
-+
-+static int
-+ffa_fwk_notify_request(struct ffa_device *dev, ffa_fwk_notifier_cb cb,
-+                     void *cb_data, int notify_id)
-+{
-+      return __ffa_notify_request(dev, false, cb, cb_data, notify_id, true);
-+}
-+
- static int ffa_notify_send(struct ffa_device *dev, int notify_id,
-                          bool is_per_vcpu, u16 vcpu)
- {
-@@ -1276,7 +1345,7 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
-                       continue;
-               mutex_lock(&drv_info->notify_lock);
--              cb_info = notifier_hash_node_get(notify_id, type);
-+              cb_info = notifier_hnode_get_by_type(notify_id, type);
-               mutex_unlock(&drv_info->notify_lock);
-               if (cb_info && cb_info->cb)
-@@ -1349,6 +1418,8 @@ static const struct ffa_notifier_ops ffa_drv_notifier_ops = {
-       .sched_recv_cb_unregister = ffa_sched_recv_cb_unregister,
-       .notify_request = ffa_notify_request,
-       .notify_relinquish = ffa_notify_relinquish,
-+      .fwk_notify_request = ffa_fwk_notify_request,
-+      .fwk_notify_relinquish = ffa_fwk_notify_relinquish,
-       .notify_send = ffa_notify_send,
- };
-diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
-index 74169dd0f6594..5e2530f23b793 100644
---- a/include/linux/arm_ffa.h
-+++ b/include/linux/arm_ffa.h
-@@ -455,6 +455,7 @@ struct ffa_cpu_ops {
- typedef void (*ffa_sched_recv_cb)(u16 vcpu, bool is_per_vcpu, void *cb_data);
- typedef void (*ffa_notifier_cb)(int notify_id, void *cb_data);
-+typedef void (*ffa_fwk_notifier_cb)(int notify_id, void *cb_data, void *buf);
- struct ffa_notifier_ops {
-       int (*sched_recv_cb_register)(struct ffa_device *dev,
-@@ -463,6 +464,10 @@ struct ffa_notifier_ops {
-       int (*notify_request)(struct ffa_device *dev, bool per_vcpu,
-                             ffa_notifier_cb cb, void *cb_data, int notify_id);
-       int (*notify_relinquish)(struct ffa_device *dev, int notify_id);
-+      int (*fwk_notify_request)(struct ffa_device *dev,
-+                                ffa_fwk_notifier_cb cb, void *cb_data,
-+                                int notify_id);
-+      int (*fwk_notify_relinquish)(struct ffa_device *dev, int notify_id);
-       int (*notify_send)(struct ffa_device *dev, int notify_id, bool per_vcpu,
-                          u16 vcpu);
- };
--- 
-2.39.5
-
diff --git a/queue-6.12/firmware-arm_ffa-move-memory-allocation-outside-the-.patch b/queue-6.12/firmware-arm_ffa-move-memory-allocation-outside-the-.patch
deleted file mode 100644 (file)
index 322c3eb..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-From 1a6f005f801af4f40bb68ecdce8e6c1c0df68255 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Wed, 28 May 2025 09:49:42 +0100
-Subject: firmware: arm_ffa: Move memory allocation outside the mutex locking
-
-From: Sudeep Holla <sudeep.holla@arm.com>
-
-[ Upstream commit 27e850c88df0e25474a8caeb2903e2e90b62c1dc ]
-
-The notifier callback node allocation is currently done while holding
-the notify_lock mutex. While this is safe even if memory allocation may
-sleep, we need to move the allocation outside the locked region in
-preparation to move from using muxtes to rwlocks.
-
-Move the memory allocation to avoid potential sleeping in atomic context
-once the locks are moved from mutex to rwlocks.
-
-Fixes: e0573444edbf ("firmware: arm_ffa: Add interfaces to request notification callbacks")
-Message-Id: <20250528-ffa_notif_fix-v1-2-5ed7bc7f8437@arm.com>
-Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
-Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/firmware/arm_ffa/driver.c | 48 +++++++++++++++----------------
- 1 file changed, 24 insertions(+), 24 deletions(-)
-
-diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
-index f19b142645cc5..33f7bdb5c86dd 100644
---- a/drivers/firmware/arm_ffa/driver.c
-+++ b/drivers/firmware/arm_ffa/driver.c
-@@ -1184,13 +1184,12 @@ notifier_hnode_get_by_type(u16 notify_id, enum notify_type type)
-       return NULL;
- }
--static int
--update_notifier_cb(struct ffa_device *dev, int notify_id, void *cb,
--                 void *cb_data, bool is_registration, bool is_framework)
-+static int update_notifier_cb(struct ffa_device *dev, int notify_id,
-+                            struct notifier_cb_info *cb, bool is_framework)
- {
-       struct notifier_cb_info *cb_info = NULL;
-       enum notify_type type = ffa_notify_type_get(dev->vm_id);
--      bool cb_found;
-+      bool cb_found, is_registration = !!cb;
-       if (is_framework)
-               cb_info = notifier_hnode_get_by_vmid_uuid(notify_id, dev->vm_id,
-@@ -1204,18 +1203,7 @@ update_notifier_cb(struct ffa_device *dev, int notify_id, void *cb,
-               return -EINVAL;
-       if (is_registration) {
--              cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL);
--              if (!cb_info)
--                      return -ENOMEM;
--
--              cb_info->dev = dev;
--              cb_info->cb_data = cb_data;
--              if (is_framework)
--                      cb_info->fwk_cb = cb;
--              else
--                      cb_info->cb = cb;
--
--              hash_add(drv_info->notifier_hash, &cb_info->hnode, notify_id);
-+              hash_add(drv_info->notifier_hash, &cb->hnode, notify_id);
-       } else {
-               hash_del(&cb_info->hnode);
-               kfree(cb_info);
-@@ -1237,8 +1225,7 @@ static int __ffa_notify_relinquish(struct ffa_device *dev, int notify_id,
-       mutex_lock(&drv_info->notify_lock);
--      rc = update_notifier_cb(dev, notify_id, NULL, NULL, false,
--                              is_framework);
-+      rc = update_notifier_cb(dev, notify_id, NULL, is_framework);
-       if (rc) {
-               pr_err("Could not unregister notification callback\n");
-               mutex_unlock(&drv_info->notify_lock);
-@@ -1269,6 +1256,7 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
- {
-       int rc;
-       u32 flags = 0;
-+      struct notifier_cb_info *cb_info = NULL;
-       if (ffa_notifications_disabled())
-               return -EOPNOTSUPP;
-@@ -1276,6 +1264,17 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
-       if (notify_id >= FFA_MAX_NOTIFICATIONS)
-               return -EINVAL;
-+      cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL);
-+      if (!cb_info)
-+              return -ENOMEM;
-+
-+      cb_info->dev = dev;
-+      cb_info->cb_data = cb_data;
-+      if (is_framework)
-+              cb_info->fwk_cb = cb;
-+      else
-+              cb_info->cb = cb;
-+
-       mutex_lock(&drv_info->notify_lock);
-       if (!is_framework) {
-@@ -1283,21 +1282,22 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
-                       flags = PER_VCPU_NOTIFICATION_FLAG;
-               rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags);
--              if (rc) {
--                      mutex_unlock(&drv_info->notify_lock);
--                      return rc;
--              }
-+              if (rc)
-+                      goto out_unlock_free;
-       }
--      rc = update_notifier_cb(dev, notify_id, cb, cb_data, true,
--                              is_framework);
-+      rc = update_notifier_cb(dev, notify_id, cb_info, is_framework);
-       if (rc) {
-               pr_err("Failed to register callback for %d - %d\n",
-                      notify_id, rc);
-               if (!is_framework)
-                       ffa_notification_unbind(dev->vm_id, BIT(notify_id));
-       }
-+
-+out_unlock_free:
-       mutex_unlock(&drv_info->notify_lock);
-+      if (rc)
-+              kfree(cb_info);
-       return rc;
- }
--- 
-2.39.5
-
diff --git a/queue-6.12/firmware-arm_ffa-move-memory-allocation-outside-the-mutex-locking.patch b/queue-6.12/firmware-arm_ffa-move-memory-allocation-outside-the-mutex-locking.patch
new file mode 100644 (file)
index 0000000..8bcd0dc
--- /dev/null
@@ -0,0 +1,120 @@
+From 27e850c88df0e25474a8caeb2903e2e90b62c1dc Mon Sep 17 00:00:00 2001
+From: Sudeep Holla <sudeep.holla@arm.com>
+Date: Wed, 28 May 2025 09:49:42 +0100
+Subject: firmware: arm_ffa: Move memory allocation outside the mutex locking
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+commit 27e850c88df0e25474a8caeb2903e2e90b62c1dc upstream.
+
+The notifier callback node allocation is currently done while holding
+the notify_lock mutex. While this is safe even if memory allocation may
+sleep, we need to move the allocation outside the locked region in
+preparation to move from using muxtes to rwlocks.
+
+Move the memory allocation to avoid potential sleeping in atomic context
+once the locks are moved from mutex to rwlocks.
+
+Fixes: e0573444edbf ("firmware: arm_ffa: Add interfaces to request notification callbacks")
+Message-Id: <20250528-ffa_notif_fix-v1-2-5ed7bc7f8437@arm.com>
+Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+
+---
+ drivers/firmware/arm_ffa/driver.c |   40 +++++++++++++++++++-------------------
+ 1 file changed, 21 insertions(+), 19 deletions(-)
+
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -1141,12 +1141,11 @@ notifier_hash_node_get(u16 notify_id, en
+       return NULL;
+ }
+-static int
+-update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
+-                 void *cb_data, bool is_registration)
++static int update_notifier_cb(int notify_id, enum notify_type type,
++                            struct notifier_cb_info *cb)
+ {
+       struct notifier_cb_info *cb_info = NULL;
+-      bool cb_found;
++      bool cb_found, is_registration = !!cb;
+       cb_info = notifier_hash_node_get(notify_id, type);
+       cb_found = !!cb_info;
+@@ -1155,15 +1154,7 @@ update_notifier_cb(int notify_id, enum n
+               return -EINVAL;
+       if (is_registration) {
+-              cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL);
+-              if (!cb_info)
+-                      return -ENOMEM;
+-
+-              cb_info->type = type;
+-              cb_info->cb = cb;
+-              cb_info->cb_data = cb_data;
+-
+-              hash_add(drv_info->notifier_hash, &cb_info->hnode, notify_id);
++              hash_add(drv_info->notifier_hash, &cb->hnode, notify_id);
+       } else {
+               hash_del(&cb_info->hnode);
+               kfree(cb_info);
+@@ -1193,7 +1184,7 @@ static int ffa_notify_relinquish(struct
+       mutex_lock(&drv_info->notify_lock);
+-      rc = update_notifier_cb(notify_id, type, NULL, NULL, false);
++      rc = update_notifier_cb(notify_id, type, NULL);
+       if (rc) {
+               pr_err("Could not unregister notification callback\n");
+               mutex_unlock(&drv_info->notify_lock);
+@@ -1212,6 +1203,7 @@ static int ffa_notify_request(struct ffa
+ {
+       int rc;
+       u32 flags = 0;
++      struct notifier_cb_info *cb_info = NULL;
+       enum notify_type type = ffa_notify_type_get(dev->vm_id);
+       if (ffa_notifications_disabled())
+@@ -1220,24 +1212,34 @@ static int ffa_notify_request(struct ffa
+       if (notify_id >= FFA_MAX_NOTIFICATIONS)
+               return -EINVAL;
++      cb_info = kzalloc(sizeof(*cb_info), GFP_KERNEL);
++      if (!cb_info)
++              return -ENOMEM;
++
++      cb_info->type = type;
++      cb_info->cb_data = cb_data;
++      cb_info->cb = cb;
++
+       mutex_lock(&drv_info->notify_lock);
+       if (is_per_vcpu)
+               flags = PER_VCPU_NOTIFICATION_FLAG;
+       rc = ffa_notification_bind(dev->vm_id, BIT(notify_id), flags);
+-      if (rc) {
+-              mutex_unlock(&drv_info->notify_lock);
+-              return rc;
+-      }
++      if (rc)
++              goto out_unlock_free;
+-      rc = update_notifier_cb(notify_id, type, cb, cb_data, true);
++      rc = update_notifier_cb(notify_id, type, cb_info);
+       if (rc) {
+               pr_err("Failed to register callback for %d - %d\n",
+                      notify_id, rc);
+               ffa_notification_unbind(dev->vm_id, BIT(notify_id));
+       }
++
++out_unlock_free:
+       mutex_unlock(&drv_info->notify_lock);
++      if (rc)
++              kfree(cb_info);
+       return rc;
+ }
diff --git a/queue-6.12/firmware-arm_ffa-refactoring-to-prepare-for-framewor.patch b/queue-6.12/firmware-arm_ffa-refactoring-to-prepare-for-framewor.patch
deleted file mode 100644 (file)
index bdb00d5..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-From 922f199a91b30879211f73469530dfe767e784f8 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 17 Feb 2025 15:38:55 +0000
-Subject: firmware: arm_ffa: Refactoring to prepare for framework notification
- support
-
-From: Sudeep Holla <sudeep.holla@arm.com>
-
-[ Upstream commit 07b760e713255a2224cfaad62eeaae85de913bac ]
-
-Currently, the framework notifications are not supported at all.
-handle_notif_callbacks() doesn't handle them though it is called with
-framework bitmap. Make that explicit by adding checks for the same.
-
-Also, we need to further classify the framework notifications as Secure
-Partition Manager(SPM) and NonSecure Hypervisor(NS_HYP). Extend/change
-notify_type enumeration to accommodate all the 4 type and rejig the
-values so that it can be reused in the bitmap enable mask macros.
-
-While at this, move ffa_notify_type_get() so that it can be used in
-notifier_hash_node_get() in the future.
-
-No functional change.
-
-Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
-Message-Id: <20250217-ffa_updates-v3-14-bd1d9de615e7@arm.com>
-Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
-Stable-dep-of: 27e850c88df0 ("firmware: arm_ffa: Move memory allocation outside the mutex locking")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/firmware/arm_ffa/driver.c | 57 ++++++++++++++++++-------------
- 1 file changed, 34 insertions(+), 23 deletions(-)
-
-diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
-index c0f3b7cdb6edb..5ac6dbde31f53 100644
---- a/drivers/firmware/arm_ffa/driver.c
-+++ b/drivers/firmware/arm_ffa/driver.c
-@@ -769,6 +769,13 @@ static int ffa_notification_bitmap_destroy(void)
-       return 0;
- }
-+enum notify_type {
-+      SECURE_PARTITION,
-+      NON_SECURE_VM,
-+      SPM_FRAMEWORK,
-+      NS_HYP_FRAMEWORK,
-+};
-+
- #define NOTIFICATION_LOW_MASK         GENMASK(31, 0)
- #define NOTIFICATION_HIGH_MASK                GENMASK(63, 32)
- #define NOTIFICATION_BITMAP_HIGH(x)   \
-@@ -792,10 +799,17 @@ static int ffa_notification_bitmap_destroy(void)
- #define MAX_IDS_32                            10
- #define PER_VCPU_NOTIFICATION_FLAG            BIT(0)
--#define SECURE_PARTITION_BITMAP                       BIT(0)
--#define NON_SECURE_VM_BITMAP                  BIT(1)
--#define SPM_FRAMEWORK_BITMAP                  BIT(2)
--#define NS_HYP_FRAMEWORK_BITMAP                       BIT(3)
-+#define SECURE_PARTITION_BITMAP_ENABLE                BIT(SECURE_PARTITION)
-+#define NON_SECURE_VM_BITMAP_ENABLE           BIT(NON_SECURE_VM)
-+#define SPM_FRAMEWORK_BITMAP_ENABLE           BIT(SPM_FRAMEWORK)
-+#define NS_HYP_FRAMEWORK_BITMAP_ENABLE                BIT(NS_HYP_FRAMEWORK)
-+#define FFA_BITMAP_ENABLE_MASK                        \
-+      (SECURE_PARTITION_BITMAP_ENABLE | SPM_FRAMEWORK_BITMAP_ENABLE)
-+
-+#define FFA_SECURE_PARTITION_ID_FLAG          BIT(15)
-+
-+#define SPM_FRAMEWORK_BITMAP(x)                       NOTIFICATION_BITMAP_LOW(x)
-+#define NS_HYP_FRAMEWORK_BITMAP(x)            NOTIFICATION_BITMAP_HIGH(x)
- static int ffa_notification_bind_common(u16 dst_id, u64 bitmap,
-                                       u32 flags, bool is_bind)
-@@ -1060,16 +1074,8 @@ static int ffa_memory_lend(struct ffa_mem_ops_args *args)
-       return ffa_memory_ops(FFA_MEM_LEND, args);
- }
--#define FFA_SECURE_PARTITION_ID_FLAG  BIT(15)
--
- #define ffa_notifications_disabled()  (!drv_info->notif_enabled)
--enum notify_type {
--      NON_SECURE_VM,
--      SECURE_PARTITION,
--      FRAMEWORK,
--};
--
- struct notifier_cb_info {
-       struct hlist_node hnode;
-       ffa_notifier_cb cb;
-@@ -1128,6 +1134,14 @@ static int ffa_notification_unbind(u16 dst_id, u64 bitmap)
-       return ffa_notification_bind_common(dst_id, bitmap, 0, false);
- }
-+static enum notify_type ffa_notify_type_get(u16 vm_id)
-+{
-+      if (vm_id & FFA_SECURE_PARTITION_ID_FLAG)
-+              return SECURE_PARTITION;
-+      else
-+              return NON_SECURE_VM;
-+}
-+
- /* Should be called while the notify_lock is taken */
- static struct notifier_cb_info *
- notifier_hash_node_get(u16 notify_id, enum notify_type type)
-@@ -1172,14 +1186,6 @@ update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
-       return 0;
- }
--static enum notify_type ffa_notify_type_get(u16 vm_id)
--{
--      if (vm_id & FFA_SECURE_PARTITION_ID_FLAG)
--              return SECURE_PARTITION;
--      else
--              return NON_SECURE_VM;
--}
--
- static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
- {
-       int rc;
-@@ -1262,6 +1268,9 @@ static void handle_notif_callbacks(u64 bitmap, enum notify_type type)
-       int notify_id;
-       struct notifier_cb_info *cb_info = NULL;
-+      if (type == SPM_FRAMEWORK || type == NS_HYP_FRAMEWORK)
-+              return;
-+
-       for (notify_id = 0; notify_id <= FFA_MAX_NOTIFICATIONS && bitmap;
-            notify_id++, bitmap >>= 1) {
-               if (!(bitmap & 1))
-@@ -1281,16 +1290,18 @@ static void notif_get_and_handle(void *unused)
-       int rc;
-       struct ffa_notify_bitmaps bitmaps;
--      rc = ffa_notification_get(SECURE_PARTITION_BITMAP |
--                                SPM_FRAMEWORK_BITMAP, &bitmaps);
-+      rc = ffa_notification_get(FFA_BITMAP_ENABLE_MASK, &bitmaps);
-       if (rc) {
-               pr_err("Failed to retrieve notifications with %d!\n", rc);
-               return;
-       }
-+      handle_notif_callbacks(SPM_FRAMEWORK_BITMAP(bitmaps.arch_map),
-+                             SPM_FRAMEWORK);
-+      handle_notif_callbacks(NS_HYP_FRAMEWORK_BITMAP(bitmaps.arch_map),
-+                             NS_HYP_FRAMEWORK);
-       handle_notif_callbacks(bitmaps.vm_map, NON_SECURE_VM);
-       handle_notif_callbacks(bitmaps.sp_map, SECURE_PARTITION);
--      handle_notif_callbacks(bitmaps.arch_map, FRAMEWORK);
- }
- static void
--- 
-2.39.5
-
diff --git a/queue-6.12/firmware-arm_ffa-replace-mutex-with-rwlock-to-avoid-sleep-in-atomic-context.patch b/queue-6.12/firmware-arm_ffa-replace-mutex-with-rwlock-to-avoid-sleep-in-atomic-context.patch
new file mode 100644 (file)
index 0000000..b013de9
--- /dev/null
@@ -0,0 +1,133 @@
+From 9ca7a421229bbdfbe2e1e628cff5cfa782720a10 Mon Sep 17 00:00:00 2001
+From: Sudeep Holla <sudeep.holla@arm.com>
+Date: Wed, 28 May 2025 09:49:43 +0100
+Subject: firmware: arm_ffa: Replace mutex with rwlock to avoid sleep in atomic context
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Sudeep Holla <sudeep.holla@arm.com>
+
+commit 9ca7a421229bbdfbe2e1e628cff5cfa782720a10 upstream.
+
+The current use of a mutex to protect the notifier hashtable accesses
+can lead to issues in the atomic context. It results in the below
+kernel warnings:
+
+  |  BUG: sleeping function called from invalid context at kernel/locking/mutex.c:258
+  |  in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 9, name: kworker/0:0
+  |  preempt_count: 1, expected: 0
+  |  RCU nest depth: 0, expected: 0
+  |  CPU: 0 UID: 0 PID: 9 Comm: kworker/0:0 Not tainted 6.14.0 #4
+  |  Workqueue: ffa_pcpu_irq_notification notif_pcpu_irq_work_fn
+  |  Call trace:
+  |   show_stack+0x18/0x24 (C)
+  |   dump_stack_lvl+0x78/0x90
+  |   dump_stack+0x18/0x24
+  |   __might_resched+0x114/0x170
+  |   __might_sleep+0x48/0x98
+  |   mutex_lock+0x24/0x80
+  |   handle_notif_callbacks+0x54/0xe0
+  |   notif_get_and_handle+0x40/0x88
+  |   generic_exec_single+0x80/0xc0
+  |   smp_call_function_single+0xfc/0x1a0
+  |   notif_pcpu_irq_work_fn+0x2c/0x38
+  |   process_one_work+0x14c/0x2b4
+  |   worker_thread+0x2e4/0x3e0
+  |   kthread+0x13c/0x210
+  |   ret_from_fork+0x10/0x20
+
+To address this, replace the mutex with an rwlock to protect the notifier
+hashtable accesses. This ensures that read-side locking does not sleep and
+multiple readers can acquire the lock concurrently, avoiding unnecessary
+contention and potential deadlocks. Writer access remains exclusive,
+preserving correctness.
+
+This change resolves warnings from lockdep about potential sleep in
+atomic context.
+
+Cc: Jens Wiklander <jens.wiklander@linaro.org>
+Reported-by: Jérôme Forissier <jerome.forissier@linaro.org>
+Closes: https://github.com/OP-TEE/optee_os/issues/7394
+Fixes: e0573444edbf ("firmware: arm_ffa: Add interfaces to request notification callbacks")
+Message-Id: <20250528-ffa_notif_fix-v1-3-5ed7bc7f8437@arm.com>
+Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
+Tested-by: Jens Wiklander <jens.wiklander@linaro.org>
+Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/firmware/arm_ffa/driver.c |   18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/drivers/firmware/arm_ffa/driver.c
++++ b/drivers/firmware/arm_ffa/driver.c
+@@ -110,7 +110,7 @@ struct ffa_drv_info {
+       struct work_struct sched_recv_irq_work;
+       struct xarray partition_info;
+       DECLARE_HASHTABLE(notifier_hash, ilog2(FFA_MAX_NOTIFICATIONS));
+-      struct mutex notify_lock; /* lock to protect notifier hashtable  */
++      rwlock_t notify_lock; /* lock to protect notifier hashtable  */
+ };
+ static struct ffa_drv_info *drv_info;
+@@ -1182,18 +1182,18 @@ static int ffa_notify_relinquish(struct
+       if (notify_id >= FFA_MAX_NOTIFICATIONS)
+               return -EINVAL;
+-      mutex_lock(&drv_info->notify_lock);
++      write_lock(&drv_info->notify_lock);
+       rc = update_notifier_cb(notify_id, type, NULL);
+       if (rc) {
+               pr_err("Could not unregister notification callback\n");
+-              mutex_unlock(&drv_info->notify_lock);
++              write_unlock(&drv_info->notify_lock);
+               return rc;
+       }
+       rc = ffa_notification_unbind(dev->vm_id, BIT(notify_id));
+-      mutex_unlock(&drv_info->notify_lock);
++      write_unlock(&drv_info->notify_lock);
+       return rc;
+ }
+@@ -1220,7 +1220,7 @@ static int ffa_notify_request(struct ffa
+       cb_info->cb_data = cb_data;
+       cb_info->cb = cb;
+-      mutex_lock(&drv_info->notify_lock);
++      write_lock(&drv_info->notify_lock);
+       if (is_per_vcpu)
+               flags = PER_VCPU_NOTIFICATION_FLAG;
+@@ -1237,7 +1237,7 @@ static int ffa_notify_request(struct ffa
+       }
+ out_unlock_free:
+-      mutex_unlock(&drv_info->notify_lock);
++      write_unlock(&drv_info->notify_lock);
+       if (rc)
+               kfree(cb_info);
+@@ -1269,9 +1269,9 @@ static void handle_notif_callbacks(u64 b
+               if (!(bitmap & 1))
+                       continue;
+-              mutex_lock(&drv_info->notify_lock);
++              read_lock(&drv_info->notify_lock);
+               cb_info = notifier_hash_node_get(notify_id, type);
+-              mutex_unlock(&drv_info->notify_lock);
++              read_unlock(&drv_info->notify_lock);
+               if (cb_info && cb_info->cb)
+                       cb_info->cb(notify_id, cb_info->cb_data);
+@@ -1721,7 +1721,7 @@ static void ffa_notifications_setup(void
+               goto cleanup;
+       hash_init(drv_info->notifier_hash);
+-      mutex_init(&drv_info->notify_lock);
++      rwlock_init(&drv_info->notify_lock);
+       drv_info->notif_enabled = true;
+       return;
diff --git a/queue-6.12/firmware-arm_ffa-stash-ffa_device-instead-of-notify_.patch b/queue-6.12/firmware-arm_ffa-stash-ffa_device-instead-of-notify_.patch
deleted file mode 100644 (file)
index 826f9f4..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-From 9aaed6f314ca39a11bee06f95ae6495bf761c73b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 17 Feb 2025 15:38:56 +0000
-Subject: firmware: arm_ffa: Stash ffa_device instead of notify_type in
- notifier_cb_info
-
-From: Sudeep Holla <sudeep.holla@arm.com>
-
-[ Upstream commit a3d73fe8ae5db389f2108a052c0a9c3c3fbc29cf ]
-
-Currently, we store the type of the notification in the notifier_cb_info
-structure that is put into the hast list to identify if the notification
-block is for the secure partition or the non secure VM.
-
-In order to support framework notifications to reuse the hash list and
-to avoid creating one for each time, we need store the ffa_device pointer
-itself as the same notification ID in framework notifications can be
-registered by multiple FF-A devices.
-
-Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
-Message-Id: <20250217-ffa_updates-v3-15-bd1d9de615e7@arm.com>
-Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
-Stable-dep-of: 27e850c88df0 ("firmware: arm_ffa: Move memory allocation outside the mutex locking")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- drivers/firmware/arm_ffa/driver.c | 15 +++++++--------
- 1 file changed, 7 insertions(+), 8 deletions(-)
-
-diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
-index 5ac6dbde31f53..f0c7f417d7524 100644
---- a/drivers/firmware/arm_ffa/driver.c
-+++ b/drivers/firmware/arm_ffa/driver.c
-@@ -1078,9 +1078,9 @@ static int ffa_memory_lend(struct ffa_mem_ops_args *args)
- struct notifier_cb_info {
-       struct hlist_node hnode;
-+      struct ffa_device *dev;
-       ffa_notifier_cb cb;
-       void *cb_data;
--      enum notify_type type;
- };
- static int ffa_sched_recv_cb_update(u16 part_id, ffa_sched_recv_cb callback,
-@@ -1149,17 +1149,18 @@ notifier_hash_node_get(u16 notify_id, enum notify_type type)
-       struct notifier_cb_info *node;
-       hash_for_each_possible(drv_info->notifier_hash, node, hnode, notify_id)
--              if (type == node->type)
-+              if (type == ffa_notify_type_get(node->dev->vm_id))
-                       return node;
-       return NULL;
- }
- static int
--update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
-+update_notifier_cb(struct ffa_device *dev, int notify_id, ffa_notifier_cb cb,
-                  void *cb_data, bool is_registration)
- {
-       struct notifier_cb_info *cb_info = NULL;
-+      enum notify_type type = ffa_notify_type_get(dev->vm_id);
-       bool cb_found;
-       cb_info = notifier_hash_node_get(notify_id, type);
-@@ -1173,7 +1174,7 @@ update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
-               if (!cb_info)
-                       return -ENOMEM;
--              cb_info->type = type;
-+              cb_info->dev = dev;
-               cb_info->cb = cb;
-               cb_info->cb_data = cb_data;
-@@ -1189,7 +1190,6 @@ update_notifier_cb(int notify_id, enum notify_type type, ffa_notifier_cb cb,
- static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
- {
-       int rc;
--      enum notify_type type = ffa_notify_type_get(dev->vm_id);
-       if (ffa_notifications_disabled())
-               return -EOPNOTSUPP;
-@@ -1199,7 +1199,7 @@ static int ffa_notify_relinquish(struct ffa_device *dev, int notify_id)
-       mutex_lock(&drv_info->notify_lock);
--      rc = update_notifier_cb(notify_id, type, NULL, NULL, false);
-+      rc = update_notifier_cb(dev, notify_id, NULL, NULL, false);
-       if (rc) {
-               pr_err("Could not unregister notification callback\n");
-               mutex_unlock(&drv_info->notify_lock);
-@@ -1218,7 +1218,6 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
- {
-       int rc;
-       u32 flags = 0;
--      enum notify_type type = ffa_notify_type_get(dev->vm_id);
-       if (ffa_notifications_disabled())
-               return -EOPNOTSUPP;
-@@ -1237,7 +1236,7 @@ static int ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
-               return rc;
-       }
--      rc = update_notifier_cb(notify_id, type, cb, cb_data, true);
-+      rc = update_notifier_cb(dev, notify_id, cb, cb_data, true);
-       if (rc) {
-               pr_err("Failed to register callback for %d - %d\n",
-                      notify_id, rc);
--- 
-2.39.5
-
index ca914ee84d5393428efbaffa734db05bd68182b5..8315111f47044e139e52aa6c9e23471d70d6104b 100644 (file)
@@ -24,10 +24,8 @@ mtk-sd-prevent-memory-corruption-from-dma-map-failure.patch
 mtk-sd-reset-host-mrq-on-prepare_data-error.patch
 drm-v3d-disable-interrupts-before-resetting-the-gpu.patch
 firmware-arm_ffa-fix-memory-leak-by-freeing-notifier.patch
-firmware-arm_ffa-refactoring-to-prepare-for-framewor.patch
-firmware-arm_ffa-stash-ffa_device-instead-of-notify_.patch
-firmware-arm_ffa-add-support-for-un-registration-of-.patch
-firmware-arm_ffa-move-memory-allocation-outside-the-.patch
+firmware-arm_ffa-move-memory-allocation-outside-the-mutex-locking.patch
+firmware-arm_ffa-replace-mutex-with-rwlock-to-avoid-sleep-in-atomic-context.patch
 arm64-dts-apple-t8103-fix-pcie-bcm4377-nodename.patch
 platform-mellanox-mlxbf-tmfifo-fix-vring_desc.len-as.patch
 rdma-mlx5-fix-unsafe-xarray-access-in-implicit-odp-h.patch