* [PATCH] firmware: arm_ffa: Compare notify_id when looking up notifier callbacks
@ 2026-10-20 22:09 David Cemin
2026-10-21 14:53 ` Sudeep Holla
0 siblings, 1 reply; 2+ messages in thread
From: David Cemin @ 2026-10-20 22:09 UTC (permalink / raw)
To: Sudeep Holla; +Cc: linux-arm-kernel, linux-kernel, linux-tegra
The notifier callbacks are kept in a hash table keyed by notification ID,
but struct notifier_cb_info does not store the ID and none of the lookup
helpers compare it. hash_for_each_possible() walks the whole bucket, so
any two IDs that hash to the same bucket are treated as the same
registration.
With the 64-bucket table, hash_32() maps IDs 2 and 36 to the same
bucket. A driver that requests notifications sequentially therefore
fails at the 37th request:
ARM FF-A: Failed to register callback for 36 - -22
because update_notifier_cb() finds the node registered for ID 2 and
rejects the new registration as a duplicate. The same lookup is used on
the delivery path, so a notification for a colliding ID can also be
dispatched to the callback registered for the other ID.
Store the notification ID in the node and compare it in all three
lookup helpers.
This was found on an arm64 laptop whose embedded controller partition
declares 38 notifications: the EC driver failed to probe and every
EC event (AC, battery, lid, hotkeys) was lost.
Fixes: e0573444edbf ("firmware: arm_ffa: Add interfaces to request notification callbacks")
Fixes: c10debfe7f02 ("firmware: arm_ffa: Add support for {un,}registration of framework notifications")
Signed-off-by: David Cemin <dcemin@nvidia.com>
---
drivers/firmware/arm_ffa/driver.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 28abc808fd32..ae8cc3a2ba2e 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1223,6 +1223,7 @@ struct notifier_cb_info {
ffa_fwk_notifier_cb fwk_cb;
ffa_notifier_cb cb;
void *cb_data;
+ u16 notify_id;
};
static int
@@ -1302,7 +1303,8 @@ 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 (node->fwk_cb && vmid == node->dev->vm_id)
+ if (node->notify_id == notify_id && node->fwk_cb &&
+ vmid == node->dev->vm_id)
return node;
return NULL;
@@ -1317,7 +1319,8 @@ notifier_hnode_get_by_vmid_uuid(u16 notify_id, int vmid, const uuid_t *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 &&
+ if (node->notify_id == notify_id && node->fwk_cb &&
+ vmid == node->dev->vm_id &&
uuid_equal(&node->dev->uuid, uuid))
return node;
@@ -1330,7 +1333,8 @@ 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))
+ if (node->notify_id == notify_id && node->cb &&
+ type == ffa_notify_type_get(node->dev->vm_id))
return node;
return NULL;
@@ -1422,6 +1426,7 @@ static int __ffa_notify_request(struct ffa_device *dev, bool is_per_vcpu,
cb_info->dev = dev;
cb_info->cb_data = cb_data;
+ cb_info->notify_id = notify_id;
if (is_framework)
cb_info->fwk_cb = cb;
else
base-commit: 70dd4ee72eb2d5793c62e71c14e3aba78e5a4e56
--
2.55.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] firmware: arm_ffa: Compare notify_id when looking up notifier callbacks
2026-10-20 22:09 [PATCH] firmware: arm_ffa: Compare notify_id when looking up notifier callbacks David Cemin
@ 2026-10-21 14:53 ` Sudeep Holla
0 siblings, 0 replies; 2+ messages in thread
From: Sudeep Holla @ 2026-10-21 14:53 UTC (permalink / raw)
To: David Cemin; +Cc: linux-arm-kernel, linux-kernel, Sudeep Holla, linux-tegra
On Tue, Oct 20, 2026 at 03:09:01PM -0700, David Cemin wrote:
> The notifier callbacks are kept in a hash table keyed by notification ID,
> but struct notifier_cb_info does not store the ID and none of the lookup
> helpers compare it. hash_for_each_possible() walks the whole bucket, so
> any two IDs that hash to the same bucket are treated as the same
> registration.
>
> With the 64-bucket table, hash_32() maps IDs 2 and 36 to the same
> bucket. A driver that requests notifications sequentially therefore
> fails at the 37th request:
>
> ARM FF-A: Failed to register callback for 36 - -22
>
Nice catch. I dropped the exact same change before posting the support
on the list. For some unknown reason, I assumed there will be no collisions
for such small sized buckets, my bad.
> because update_notifier_cb() finds the node registered for ID 2 and
> rejects the new registration as a duplicate. The same lookup is used on
> the delivery path, so a notification for a colliding ID can also be
> dispatched to the callback registered for the other ID.
>
> Store the notification ID in the node and compare it in all three
> lookup helpers.
>
> This was found on an arm64 laptop whose embedded controller partition
> declares 38 notifications: the EC driver failed to probe and every
> EC event (AC, battery, lid, hotkeys) was lost.
>
I will queue it soon and send it as fix at -rc1 or later.
Thanks for finding and fixing the issue.
> Fixes: e0573444edbf ("firmware: arm_ffa: Add interfaces to request notification callbacks")
> Fixes: c10debfe7f02 ("firmware: arm_ffa: Add support for {un,}registration of framework notifications")
Is this because of rework we have 2 fixes tag. Need to check how backport
would work, hence asking. I will also check before applying.
--
Regards,
Sudeep
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-21 14:53 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-20 22:09 [PATCH] firmware: arm_ffa: Compare notify_id when looking up notifier callbacks David Cemin
2026-10-21 14:53 ` Sudeep Holla
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®