From 987756f67dee237ec35f3b249ab1ae25260c5340 Mon Sep 17 00:00:00 2001 From: Marc Bonnici Date: Tue, 26 Apr 2022 13:12:19 +0100 Subject: [PATCH 1/5] firmware: arm_ffa: Fix handling of fragmented memory descriptors Fix the handling of MEM_FRAG_TX/RX SMCs when the full memory descriptor does not fit in a single innovation of a memory sharing request. The current implementation expects a FFA_MEM_SHARE/FFA_MEM_LEND call to always receive a FFA_SUCCESS response, however in the case where a full descriptor does not fit inside the partitions TX buffer, the call can instead complete with a FFA_MEM_FRAG_RX SMC to request the next part of the descriptor to be transmitted. Similarly a FFA_MEM_FRAG_TX call currently only expects FFA_MEM_FRAG_RX as a response, however once the full descriptor has been transmitted the FFA_SUCCESS ABI will be used to indicate successful transmission. Update the existing code to match the expected behaviour. Link: https://lore.kernel.org/r/20220426121219.1801601-1-marc.bonnici@arm.com Signed-off-by: Marc Bonnici Signed-off-by: Sudeep Holla --- drivers/firmware/arm_ffa/driver.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c index 14f900047ac0..ccccecae615f 100644 --- a/drivers/firmware/arm_ffa/driver.c +++ b/drivers/firmware/arm_ffa/driver.c @@ -398,11 +398,15 @@ static int ffa_mem_first_frag(u32 func_id, phys_addr_t buf, u32 buf_sz, if (ret.a0 == FFA_ERROR) return ffa_to_linux_errno((int)ret.a2); - if (ret.a0 != FFA_SUCCESS) + if (ret.a0 == FFA_SUCCESS) { + if (handle) + *handle = PACK_HANDLE(ret.a2, ret.a3); + } else if (ret.a0 == FFA_MEM_FRAG_RX) { + if (handle) + *handle = PACK_HANDLE(ret.a1, ret.a2); + } else { return -EOPNOTSUPP; - - if (handle) - *handle = PACK_HANDLE(ret.a2, ret.a3); + } return frag_len; } @@ -426,10 +430,12 @@ static int ffa_mem_next_frag(u64 handle, u32 frag_len) if (ret.a0 == FFA_ERROR) return ffa_to_linux_errno((int)ret.a2); - if (ret.a0 != FFA_MEM_FRAG_RX) - return -EOPNOTSUPP; + if (ret.a0 == FFA_MEM_FRAG_RX) + return ret.a3; + else if (ret.a0 == FFA_SUCCESS) + return 0; - return ret.a3; + return -EOPNOTSUPP; } static int From f3c45c045e25ed52461829d2ce07954f72b6ad15 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 29 Apr 2022 12:39:43 +0100 Subject: [PATCH 2/5] firmware: arm_ffa: Fix uuid parameter to ffa_partition_probe While we pass uuid_null intentionally to ffa_partition_probe in ffa_setup_partitions to get the count of the partitions, it must not be uuid_null in ffa_partition_info_get which is used by the ffa_drivers to fetch the specific partition info passing the UUID of the partition. Fix ffa_partition_info_get by passing the received uuid down to ffa_partition_probe so that the correct partition information is fetched. Link: https://lore.kernel.org/r/20220429113946.2087145-1-sudeep.holla@arm.com Fixes: d0c0bce83122 ("firmware: arm_ffa: Setup in-kernel users of FFA partitions") Reported-by: Arunachalam Ganapathy Signed-off-by: Sudeep Holla --- drivers/firmware/arm_ffa/driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c index ccccecae615f..6a913ac91e8e 100644 --- a/drivers/firmware/arm_ffa/driver.c +++ b/drivers/firmware/arm_ffa/driver.c @@ -588,7 +588,7 @@ static int ffa_partition_info_get(const char *uuid_str, return -ENODEV; } - count = ffa_partition_probe(&uuid_null, &pbuf); + count = ffa_partition_probe(&uuid, &pbuf); if (count <= 0) return -ENOENT; From 00512d2930b338fdd42bd90bbd1793fe212c2d31 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 29 Apr 2022 12:39:44 +0100 Subject: [PATCH 3/5] firmware: arm_ffa: Remove incorrect assignment of driver_data The ffa core driver currently assigns its own driver information to individual ffa device driver_data which is wrong. Firstly, it leaks this core driver information to individual ffa_device and hence to ffa_driver. Secondly the ffa_device driver_data is for use by individual ffa_driver and not for this core driver managing all those devices. Link: https://lore.kernel.org/r/20220429113946.2087145-2-sudeep.holla@arm.com Fixes: d0c0bce83122 ("firmware: arm_ffa: Setup in-kernel users of FFA partitions") Signed-off-by: Sudeep Holla --- drivers/firmware/arm_ffa/driver.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c index 6a913ac91e8e..ec731e9e942b 100644 --- a/drivers/firmware/arm_ffa/driver.c +++ b/drivers/firmware/arm_ffa/driver.c @@ -694,8 +694,6 @@ static void ffa_setup_partitions(void) __func__, tpbuf->id); continue; } - - ffa_dev_set_drvdata(ffa_dev, drv_info); } kfree(pbuf); } From 498af8d1678ae2351218337b47bbf3cb0fc16821 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 29 Apr 2022 12:39:45 +0100 Subject: [PATCH 4/5] firmware: arm_ffa: Add ffa_dev_get_drvdata helper function Add a helper function to fetch ffa_dev's driver_data using dev_get_drvdata. At the same time move existing ffa_dev_set_drvdata to use dev_set_drvdata. Link: https://lore.kernel.org/r/20220429113946.2087145-3-sudeep.holla@arm.com Suggested-by: Arunachalam Ganapathy Signed-off-by: Sudeep Holla --- include/linux/arm_ffa.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h index 85651e41ded8..e5c76c1ef9ed 100644 --- a/include/linux/arm_ffa.h +++ b/include/linux/arm_ffa.h @@ -38,7 +38,12 @@ struct ffa_driver { static inline void ffa_dev_set_drvdata(struct ffa_device *fdev, void *data) { - fdev->dev.driver_data = data; + dev_set_drvdata(&fdev->dev, data); +} + +static inline void *ffa_dev_get_drvdata(struct ffa_device *fdev) +{ + return dev_get_drvdata(&fdev->dev); } #if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT) From f3f3bdbd58cea4fdd088075fdc8864fc47ecd419 Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Fri, 29 Apr 2022 12:39:46 +0100 Subject: [PATCH 5/5] tee: optee: Use ffa_dev_get_drvdata to fetch driver_data Due to lack of an helper like ffa_dev_get_drvdata, this driver was fetching driver_data directly accessing the structure member. Now that we have added an helper, just use the same instead. Link: https://lore.kernel.org/r/20220429113946.2087145-4-sudeep.holla@arm.com Signed-off-by: Sudeep Holla --- drivers/tee/optee/ffa_abi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/tee/optee/ffa_abi.c b/drivers/tee/optee/ffa_abi.c index a5eb4ef46971..b819a65cf89d 100644 --- a/drivers/tee/optee/ffa_abi.c +++ b/drivers/tee/optee/ffa_abi.c @@ -759,7 +759,7 @@ static const struct optee_ops optee_ffa_ops = { static void optee_ffa_remove(struct ffa_device *ffa_dev) { - struct optee *optee = ffa_dev->dev.driver_data; + struct optee *optee = ffa_dev_get_drvdata(ffa_dev); optee_remove_common(optee);