+++ /dev/null
-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
-
+++ /dev/null
-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
-
--- /dev/null
+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;
+ }
+++ /dev/null
-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
-
--- /dev/null
+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;
+++ /dev/null
-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
-
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