firmware: arm_ffa: Add support for MEM_LEND
authorMarc Bonnici <marc.bonnici@arm.com>
Fri, 15 Oct 2021 16:57:42 +0000 (17:57 +0100)
committerSudeep Holla <sudeep.holla@arm.com>
Mon, 18 Oct 2021 12:11:06 +0000 (13:11 +0100)
As part of the FF-A spec, an endpoint is allowed to transfer access of,
or lend, a memory region to one or more borrowers.

Extend the existing memory sharing implementation to support
FF-A MEM_LEND functionality and expose this to other kernel drivers.

Note that upon a successful MEM_LEND request the caller must ensure that
the memory region specified is not accessed until a successful
MEM_RECALIM call has been made. On systems with a hypervisor present
this will been enforced, however on systems without a hypervisor the
responsibility falls to the calling kernel driver to prevent access.

Link: https://lore.kernel.org/r/20211015165742.2513065-1-marc.bonnici@arm.com
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Marc Bonnici <marc.bonnici@arm.com>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
drivers/firmware/arm_ffa/driver.c
include/linux/arm_ffa.h

index 6e0c883ab7086022bf7cb5630d8b7cc63ac0be68..12f4c87c45556d20edcc58adf9b81a9553d39dd6 100644 (file)
@@ -613,6 +613,22 @@ ffa_memory_share(struct ffa_device *dev, struct ffa_mem_ops_args *args)
        return ffa_memory_ops(FFA_FN_NATIVE(MEM_SHARE), args);
 }
 
+static int
+ffa_memory_lend(struct ffa_device *dev, struct ffa_mem_ops_args *args)
+{
+       /* Note that upon a successful MEM_LEND request the caller
+        * must ensure that the memory region specified is not accessed
+        * until a successful MEM_RECALIM call has been made.
+        * On systems with a hypervisor present this will been enforced,
+        * however on systems without a hypervisor the responsibility
+        * falls to the calling kernel driver to prevent access.
+        */
+       if (dev->mode_32bit)
+               return ffa_memory_ops(FFA_MEM_LEND, args);
+
+       return ffa_memory_ops(FFA_FN_NATIVE(MEM_LEND), args);
+}
+
 static const struct ffa_dev_ops ffa_ops = {
        .api_version_get = ffa_api_version_get,
        .partition_info_get = ffa_partition_info_get,
@@ -620,6 +636,7 @@ static const struct ffa_dev_ops ffa_ops = {
        .sync_send_receive = ffa_sync_send_receive,
        .memory_reclaim = ffa_memory_reclaim,
        .memory_share = ffa_memory_share,
+       .memory_lend = ffa_memory_lend,
 };
 
 const struct ffa_dev_ops *ffa_dev_ops_get(struct ffa_device *dev)
index 505c679b6a9b726021e613a637de73bfd1596363..85651e41ded866f8279d94a2c5cd9d3448c9792f 100644 (file)
@@ -262,6 +262,8 @@ struct ffa_dev_ops {
        int (*memory_reclaim)(u64 g_handle, u32 flags);
        int (*memory_share)(struct ffa_device *dev,
                            struct ffa_mem_ops_args *args);
+       int (*memory_lend)(struct ffa_device *dev,
+                          struct ffa_mem_ops_args *args);
 };
 
 #endif /* _LINUX_ARM_FFA_H */