Re: [PATCH v2 18/18] firmware: arm_ffa: Allow multiple UUIDs per partition to register SRI callback

From: Sudeep Holla
Date: Wed Feb 12 2025 - 06:06:06 EST


On Fri, Jan 31, 2025 at 11:24:18AM +0000, Sudeep Holla wrote:
> A partition can implement multiple UUIDs and currently we successfully
> register each UUID service as a FF-A device. However when adding the
> same partition info to the XArray which tracks the SRI callbacks more
> than once, it fails.
>
> In order to allow multiple UUIDs per partition to register SRI callbacks
> the partition information stored in the XArray needs to be extended to
> a listed list.
>
> A function to remove the list of partition information in the XArray
> is not added as there are no users at the time. All the partitions are
> added at probe/initialisation and removed at cleanup stage.
>
> Signed-off-by: Sudeep Holla <sudeep.holla@xxxxxxx>
> ---
> drivers/firmware/arm_ffa/driver.c | 157 ++++++++++++++++++++++++++++----------
> 1 file changed, 116 insertions(+), 41 deletions(-)
>

[...]

> static void ffa_partitions_cleanup(void)
> {
> - struct ffa_dev_part_info *info;
> + struct ffa_dev_part_info *info, *tmp;
> unsigned long idx;
>
> /* Clean up/free all registered devices */
> ffa_devices_unregister();
>
> xa_for_each(&drv_info->partition_info, idx, info) {
> + struct list_head *phead = (struct list_head *)idx;
> +
> xa_erase(&drv_info->partition_info, idx);
> - kfree(info);
> + list_for_each_entry_safe(info, tmp, phead, node) {
> + list_del(&info->node);
> + kfree(info);
> + }
> + kfree(phead);

Issue was discovered when testing it as module(that's when cleanup
gets executed). It is now fixed here[1] with the below patch.

Regards,
Sudeep

[1] https://git.kernel.org/sudeep.holla/l/ffa_updates

-->8

diff --git c/drivers/firmware/arm_ffa/driver.c w/drivers/firmware/arm_ffa/driver.c
index 3c49ab3fe118..c184a220147f 100644
--- c/drivers/firmware/arm_ffa/driver.c
+++ w/drivers/firmware/arm_ffa/driver.c
@@ -1644,14 +1644,14 @@ static int ffa_setup_host_partition(int vm_id)

static void ffa_partitions_cleanup(void)
{
- struct ffa_dev_part_info *info, *tmp;
+ struct list_head *phead;
unsigned long idx;

/* Clean up/free all registered devices */
ffa_devices_unregister();

- xa_for_each(&drv_info->partition_info, idx, info) {
- struct list_head *phead = (struct list_head *)idx;
+ xa_for_each(&drv_info->partition_info, idx, phead) {
+ struct ffa_dev_part_info *info, *tmp;

xa_erase(&drv_info->partition_info, idx);
list_for_each_entry_safe(info, tmp, phead, node) {