1
0
mirror of https://git.yoctoproject.org/meta-arm synced 2026-06-06 14:50:03 +00:00

arm-bsp/linux: TC: Add Trusty FFA adoption patches

Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I5c152ca026dce2a7470d6ee7cfd84fa6b3f2e30a
Signed-off-by: Jon Mason <jon.mason@arm.com>
This commit is contained in:
Arunachalam Ganapathy
2022-05-04 17:58:20 +01:00
committed by Jon Mason
parent b36889fe71
commit cdb6c65f0a
10 changed files with 2787 additions and 0 deletions
@@ -171,6 +171,15 @@ SRC_URI:append:tc = " \
file://0033-firmware-arm_ffa-extern-ffa_bus_type.patch \
file://0034-firmware-arm_ffa-Fix-FFA_MEM_SHARE-and-FFA_MEM_FRAG_.patch \
file://0035-ANDROID-trusty-Backport-of-trusty-driver.patch \
file://0036-ANDROID-trusty-Remove-FFA-specific-initilization.patch \
file://0037-ANDROID-trusty-Rename-transfer-memory-function-to-le.patch \
file://0038-ANDROID-trusty-Separate-out-SMC-based-transport.patch \
file://0039-ANDROID-trusty-Modify-device-compatible-string.patch \
file://0040-ANDROID-trusty-Add-transport-descriptor.patch \
file://0041-ANDROID-trusty-Add-trusty-ffa-driver.patch \
file://0042-ANDROID-trusty-ffa-Add-support-for-FFA-memory-operat.patch \
file://0043-ANDROID-trusty-ffa-Enable-FFA-transport-for-both-mem.patch \
file://0044-ANDROID-trusty-Make-trusty-transports-configurable.patch \
"
KERNEL_FEATURES:append:tc = " bsp/arm-platforms/tc.scc"
KERNEL_FEATURES:append:tc1 = " bsp/arm-platforms/tc-autofdo.scc"
@@ -0,0 +1,191 @@
From 804ef860d9757cbe31b606fd5ec68cc5454c88f8 Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Tue, 18 Jan 2022 18:27:09 +0000
Subject: [PATCH 24/32] ANDROID: trusty: Rename transfer memory function to
lend memory
Renaming trusty_transfer_memory to trusty_lend_memory allows Trusty
to export memory operation like share, lend, reclaim and use common
code for memory share and lend operations.
Define TRUSTY_DEFAULT_MEM_OBJ_TAG as 0 and use that in existing calls.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: Ie165a609cc4398bb916967595d0b748d54d75faf
Upstream-Status: Pending [Not submitted to upstream yet]
---
drivers/trusty/trusty-ipc.c | 14 ++++++++----
drivers/trusty/trusty-test.c | 3 ++-
drivers/trusty/trusty-virtio.c | 3 ++-
drivers/trusty/trusty.c | 41 ++++++++++++++++++++++------------
include/linux/trusty/trusty.h | 11 ++++-----
5 files changed, 47 insertions(+), 25 deletions(-)
diff --git a/drivers/trusty/trusty-ipc.c b/drivers/trusty/trusty-ipc.c
index 82d6ddeb41f4..0a27af2063a7 100644
--- a/drivers/trusty/trusty-ipc.c
+++ b/drivers/trusty/trusty-ipc.c
@@ -1233,10 +1233,16 @@ static int dn_share_fd(struct tipc_dn_chan *dn, int fd,
goto cleanup_handle;
}
- ret = trusty_transfer_memory(tipc_shared_handle_dev(shared_handle),
- &mem_id, shared_handle->sgt->sgl,
- shared_handle->sgt->orig_nents, prot, tag,
- lend);
+ if (lend)
+ ret = trusty_lend_memory(tipc_shared_handle_dev(shared_handle),
+ &mem_id, shared_handle->sgt->sgl,
+ shared_handle->sgt->orig_nents, prot,
+ tag);
+ else
+ ret = trusty_share_memory(tipc_shared_handle_dev(shared_handle),
+ &mem_id, shared_handle->sgt->sgl,
+ shared_handle->sgt->orig_nents, prot,
+ tag);
if (ret < 0) {
dev_dbg(dev, "Transferring memory failed: %d\n", ret);
diff --git a/drivers/trusty/trusty-test.c b/drivers/trusty/trusty-test.c
index 844868981fa5..c25fc0f2fcf0 100644
--- a/drivers/trusty/trusty-test.c
+++ b/drivers/trusty/trusty-test.c
@@ -138,7 +138,8 @@ static int trusty_test_share_objs(struct trusty_test_state *s,
t1 = ktime_get();
tmpret = trusty_share_memory(s->trusty_dev, &obj->mem_id,
obj->sgt.sgl, obj->sgt.nents,
- PAGE_KERNEL);
+ PAGE_KERNEL,
+ TRUSTY_DEFAULT_MEM_OBJ_TAG);
t2 = ktime_get();
if (tmpret) {
ret = tmpret;
diff --git a/drivers/trusty/trusty-virtio.c b/drivers/trusty/trusty-virtio.c
index fea59cd2e218..365e7c04bcf4 100644
--- a/drivers/trusty/trusty-virtio.c
+++ b/drivers/trusty/trusty-virtio.c
@@ -626,7 +626,8 @@ static int trusty_virtio_add_devices(struct trusty_ctx *tctx)
sg_init_one(&tctx->shared_sg, descr_va, descr_buf_sz);
ret = trusty_share_memory(tctx->dev->parent, &descr_id,
- &tctx->shared_sg, 1, PAGE_KERNEL);
+ &tctx->shared_sg, 1, PAGE_KERNEL,
+ TRUSTY_DEFAULT_MEM_OBJ_TAG);
if (ret) {
dev_err(tctx->dev, "trusty_share_memory failed: %d\n", ret);
goto err_share_memory;
diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
index 2dec75398f69..6bd30bc1bbc9 100644
--- a/drivers/trusty/trusty.c
+++ b/drivers/trusty/trusty.c
@@ -222,18 +222,9 @@ s32 trusty_std_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2)
}
EXPORT_SYMBOL(trusty_std_call32);
-int trusty_share_memory(struct device *dev, u64 *id,
- struct scatterlist *sglist, unsigned int nents,
- pgprot_t pgprot)
-{
- return trusty_transfer_memory(dev, id, sglist, nents, pgprot, 0,
- false);
-}
-EXPORT_SYMBOL(trusty_share_memory);
-
-int trusty_transfer_memory(struct device *dev, u64 *id,
- struct scatterlist *sglist, unsigned int nents,
- pgprot_t pgprot, u64 tag, bool lend)
+static int __trusty_share_memory(struct device *dev, u64 *id,
+ struct scatterlist *sglist, unsigned int nents,
+ pgprot_t pgprot, u64 tag, bool mem_share)
{
struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
int ret;
@@ -253,6 +244,12 @@ int trusty_transfer_memory(struct device *dev, u64 *id,
return -EOPNOTSUPP;
}
+ if (mem_share == false && s->api_version < TRUSTY_API_VERSION_MEM_OBJ) {
+ dev_err(s->dev, "%s: old trusty version does not support lending memory objects\n",
+ __func__);
+ return -EOPNOTSUPP;
+ }
+
count = dma_map_sg(dev, sglist, nents, DMA_BIDIRECTIONAL);
if (count != nents) {
dev_err(s->dev, "failed to dma map sg_table\n");
@@ -271,7 +268,22 @@ int trusty_transfer_memory(struct device *dev, u64 *id,
*id = pg_inf.compat_attr;
return 0;
}
-EXPORT_SYMBOL(trusty_transfer_memory);
+
+int trusty_share_memory(struct device *dev, u64 *id,
+ struct scatterlist *sglist, unsigned int nents,
+ pgprot_t pgprot, u64 tag)
+{
+ return __trusty_share_memory(dev, id, sglist, nents, pgprot, tag, true);
+}
+EXPORT_SYMBOL(trusty_share_memory);
+
+int trusty_lend_memory(struct device *dev, u64 *id,
+ struct scatterlist *sglist, unsigned int nents,
+ pgprot_t pgprot, u64 tag)
+{
+ return __trusty_share_memory(dev, id, sglist, nents, pgprot, tag, false);
+}
+EXPORT_SYMBOL(trusty_lend_memory);
/*
* trusty_share_memory_compat - trusty_share_memory wrapper for old apis
@@ -287,7 +299,8 @@ int trusty_share_memory_compat(struct device *dev, u64 *id,
int ret;
struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
- ret = trusty_share_memory(dev, id, sglist, nents, pgprot);
+ ret = trusty_share_memory(dev, id, sglist, nents, pgprot,
+ TRUSTY_DEFAULT_MEM_OBJ_TAG);
if (!ret && s->api_version < TRUSTY_API_VERSION_PHYS_MEM_OBJ)
*id &= 0x0000FFFFFFFFF000ull;
diff --git a/include/linux/trusty/trusty.h b/include/linux/trusty/trusty.h
index 272d96c1c696..27f635f2d12d 100644
--- a/include/linux/trusty/trusty.h
+++ b/include/linux/trusty/trusty.h
@@ -11,6 +11,7 @@
#include <linux/device.h>
#include <linux/pagemap.h>
+#define TRUSTY_DEFAULT_MEM_OBJ_TAG (0)
#if IS_ENABLED(CONFIG_TRUSTY)
s32 trusty_std_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2);
@@ -62,13 +63,13 @@ struct scatterlist;
typedef u64 trusty_shared_mem_id_t;
int trusty_share_memory(struct device *dev, trusty_shared_mem_id_t *id,
struct scatterlist *sglist, unsigned int nents,
- pgprot_t pgprot);
+ pgprot_t pgprot, u64 tag);
int trusty_share_memory_compat(struct device *dev, trusty_shared_mem_id_t *id,
struct scatterlist *sglist, unsigned int nents,
pgprot_t pgprot);
-int trusty_transfer_memory(struct device *dev, u64 *id,
- struct scatterlist *sglist, unsigned int nents,
- pgprot_t pgprot, u64 tag, bool lend);
+int trusty_lend_memory(struct device *dev, u64 *id,
+ struct scatterlist *sglist, unsigned int nents,
+ pgprot_t pgprot, u64 tag);
int trusty_reclaim_memory(struct device *dev, trusty_shared_mem_id_t id,
struct scatterlist *sglist, unsigned int nents);
@@ -78,7 +79,7 @@ u64 trusty_dma_buf_get_ffa_tag(struct dma_buf *dma_buf);
#else
static inline u64 trusty_dma_buf_get_ffa_tag(struct dma_buf *dma_buf)
{
- return 0;
+ return TRUSTY_DEFAULT_MEM_OBJ_TAG;
}
#endif
--
2.30.2
@@ -0,0 +1,495 @@
From 844cdefb8b0f6b1f75cf4cbaa2d9260959a26e02 Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Fri, 14 Jan 2022 14:02:39 +0000
Subject: [PATCH 25/32] ANDROID: trusty: Separate out SMC based transport
This commit refactors SMC based transport operation like
smc_fastcalls, smc memory operations in a separate file.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: Iebee505b7172f6247186e3bf1e0b50740b2e4dfa
Upstream-Status: Pending [Not submitted to upstream yet]
---
drivers/trusty/Makefile | 1 +
drivers/trusty/trusty-private.h | 61 ++++++++++++++
drivers/trusty/trusty-smc.c | 136 ++++++++++++++++++++++++++++++
drivers/trusty/trusty.c | 144 +++++++++-----------------------
4 files changed, 237 insertions(+), 105 deletions(-)
create mode 100644 drivers/trusty/trusty-private.h
create mode 100644 drivers/trusty/trusty-smc.c
diff --git a/drivers/trusty/Makefile b/drivers/trusty/Makefile
index 2cf1cfccf97b..fbb53ee93003 100644
--- a/drivers/trusty/Makefile
+++ b/drivers/trusty/Makefile
@@ -5,6 +5,7 @@
obj-$(CONFIG_TRUSTY) += trusty-core.o
trusty-core-objs += trusty.o trusty-mem.o
+trusty-core-objs += trusty-smc.o
trusty-core-$(CONFIG_ARM) += trusty-smc-arm.o
trusty-core-$(CONFIG_ARM64) += trusty-smc-arm64.o
obj-$(CONFIG_TRUSTY_IRQ) += trusty-irq.o
diff --git a/drivers/trusty/trusty-private.h b/drivers/trusty/trusty-private.h
new file mode 100644
index 000000000000..4d73c6ae35d4
--- /dev/null
+++ b/drivers/trusty/trusty-private.h
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 ARM Ltd.
+ */
+
+#ifndef _TRUSTY_PRIVATE_H
+#define _TRUSTY_PRIVATE_H
+
+#include <linux/types.h>
+
+struct trusty_work {
+ struct trusty_state *ts;
+ struct work_struct work;
+};
+
+struct trusty_msg_ops {
+ u32 (*send_direct_msg)(struct device *dev, unsigned long fid,
+ unsigned long a0, unsigned long a1,
+ unsigned long a2);
+};
+
+struct trusty_mem_ops {
+ int (*trusty_share_memory)(struct device *dev, u64 *id,
+ struct scatterlist *sglist,
+ unsigned int nents, pgprot_t pgprot, u64 tag);
+ int (*trusty_lend_memory)(struct device *dev, u64 *id,
+ struct scatterlist *sglist,
+ unsigned int nents, pgprot_t pgprot, u64 tag);
+ int (*trusty_reclaim_memory)(struct device *dev, u64 id,
+ struct scatterlist *sglist,
+ unsigned int nents);
+};
+
+struct trusty_state {
+ struct mutex smc_lock;
+ struct atomic_notifier_head notifier;
+ struct completion cpu_idle_completion;
+ char *version_str;
+ u32 api_version;
+ bool trusty_panicked;
+ struct device *dev;
+ struct workqueue_struct *nop_wq;
+ struct trusty_work __percpu *nop_works;
+ struct list_head nop_queue;
+ spinlock_t nop_lock; /* protects nop_queue */
+ struct device_dma_parameters dma_parms;
+ const struct trusty_msg_ops *msg_ops;
+ const struct trusty_mem_ops *mem_ops;
+};
+
+int trusty_init_api_version(struct trusty_state *s, struct device *dev,
+ u32 (*send_direct_msg)(struct device *dev,
+ unsigned long fid,
+ unsigned long a0,
+ unsigned long a1,
+ unsigned long a2));
+
+int trusty_smc_transport_setup(struct device *dev);
+void trusty_smc_transport_cleanup(struct device *dev);
+
+#endif /* _TRUSTY_PRIVATE_H */
diff --git a/drivers/trusty/trusty-smc.c b/drivers/trusty/trusty-smc.c
new file mode 100644
index 000000000000..8fa841e0e253
--- /dev/null
+++ b/drivers/trusty/trusty-smc.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2013 Google, Inc.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/trusty/smcall.h>
+#include <linux/trusty/trusty.h>
+
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+
+#include "trusty-smc.h"
+#include "trusty-private.h"
+
+static u32 trusty_smc_send_direct_msg(struct device *dev, unsigned long fid,
+ unsigned long a0, unsigned long a1,
+ unsigned long a2)
+{
+ return trusty_smc8(fid, a0, a1, a2, 0, 0, 0, 0).r0;
+}
+
+static int trusty_smc_share_memory(struct device *dev, u64 *id,
+ struct scatterlist *sglist,
+ unsigned int nents, pgprot_t pgprot, u64 tag)
+{
+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+ int ret;
+ struct ns_mem_page_info pg_inf;
+ struct scatterlist *sg;
+ size_t count;
+
+ if (WARN_ON(nents < 1))
+ return -EINVAL;
+
+ if (nents != 1) {
+ dev_err(s->dev, "%s: old trusty version does not support "
+ "non-contiguous memory objects\n", __func__);
+ return -EOPNOTSUPP;
+ }
+
+ count = dma_map_sg(dev, sglist, nents, DMA_BIDIRECTIONAL);
+ if (count != nents) {
+ dev_err(s->dev, "failed to dma map sg_table\n");
+ return -EINVAL;
+ }
+
+ sg = sglist;
+ ret = trusty_encode_page_info(&pg_inf, phys_to_page(sg_dma_address(sg)),
+ pgprot);
+ if (ret) {
+ dev_err(s->dev, "%s: trusty_encode_page_info failed\n",
+ __func__);
+ dma_unmap_sg(dev, sglist, nents, DMA_BIDIRECTIONAL);
+ return ret;
+ }
+
+ *id = pg_inf.compat_attr;
+ return 0;
+}
+
+static int trusty_smc_lend_memory(struct device *dev, u64 *id,
+ struct scatterlist *sglist,
+ unsigned int nents, pgprot_t pgprot, u64 tag)
+{
+ return -EOPNOTSUPP;
+}
+
+static int trusty_smc_reclaim_memory(struct device *dev, u64 id,
+ struct scatterlist *sglist,
+ unsigned int nents)
+{
+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+
+ if (WARN_ON(nents < 1))
+ return -EINVAL;
+
+ if (WARN_ON(s->api_version >= TRUSTY_API_VERSION_MEM_OBJ))
+ return -EINVAL;
+
+ if (nents != 1) {
+ dev_err(s->dev, "%s: not supported\n", __func__);
+ return -EOPNOTSUPP;
+ }
+
+ dma_unmap_sg(dev, sglist, nents, DMA_BIDIRECTIONAL);
+
+ dev_dbg(s->dev, "%s: done\n", __func__);
+ return 0;
+}
+
+static const struct trusty_msg_ops trusty_smc_msg_ops = {
+ .send_direct_msg = &trusty_smc_send_direct_msg,
+};
+
+static const struct trusty_mem_ops trusty_smc_mem_ops = {
+ .trusty_share_memory = &trusty_smc_share_memory,
+ .trusty_lend_memory = &trusty_smc_lend_memory,
+ .trusty_reclaim_memory = &trusty_smc_reclaim_memory,
+};
+
+int trusty_smc_transport_setup(struct device *dev)
+{
+ int rc;
+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+
+ rc = trusty_init_api_version(s, dev, &trusty_smc_send_direct_msg);
+ if (rc != 0) {
+ return rc;
+ }
+
+ /*
+ * Initialize Trusty msg calls with Trusty SMC ABI
+ */
+ s->msg_ops = &trusty_smc_msg_ops;
+
+ /*
+ * Initialize Trusty memory operations with Trusty SMC ABI only when
+ * Trusty API version is below TRUSTY_API_VERSION_MEM_OBJ.
+ */
+ if (s->api_version < TRUSTY_API_VERSION_MEM_OBJ)
+ s->mem_ops = &trusty_smc_mem_ops;
+
+ return 0;
+}
+
+void trusty_smc_transport_cleanup(struct device *dev)
+{
+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+
+ if (s->msg_ops == &trusty_smc_msg_ops)
+ s->msg_ops = NULL;
+
+ if (s->mem_ops == &trusty_smc_mem_ops)
+ s->mem_ops = NULL;
+}
diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
index 6bd30bc1bbc9..0486827a45ca 100644
--- a/drivers/trusty/trusty.c
+++ b/drivers/trusty/trusty.c
@@ -18,37 +18,10 @@
#include <linux/scatterlist.h>
#include <linux/dma-mapping.h>
-#include "trusty-smc.h"
+#include "trusty-private.h"
-struct trusty_state;
static struct platform_driver trusty_driver;
-struct trusty_work {
- struct trusty_state *ts;
- struct work_struct work;
-};
-
-struct trusty_state {
- struct mutex smc_lock;
- struct atomic_notifier_head notifier;
- struct completion cpu_idle_completion;
- char *version_str;
- u32 api_version;
- bool trusty_panicked;
- struct device *dev;
- struct workqueue_struct *nop_wq;
- struct trusty_work __percpu *nop_works;
- struct list_head nop_queue;
- spinlock_t nop_lock; /* protects nop_queue */
- struct device_dma_parameters dma_parms;
-};
-
-static inline unsigned long smc(unsigned long r0, unsigned long r1,
- unsigned long r2, unsigned long r3)
-{
- return trusty_smc8(r0, r1, r2, r3, 0, 0, 0, 0).r0;
-}
-
s32 trusty_fast_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2)
{
struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
@@ -60,7 +33,7 @@ s32 trusty_fast_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2)
if (WARN_ON(SMC_IS_SMC64(smcnr)))
return SM_ERR_INVALID_PARAMETERS;
- return smc(smcnr, a0, a1, a2);
+ return s->msg_ops->send_direct_msg(dev, smcnr, a0, a1, a2);
}
EXPORT_SYMBOL(trusty_fast_call32);
@@ -76,7 +49,7 @@ s64 trusty_fast_call64(struct device *dev, u64 smcnr, u64 a0, u64 a1, u64 a2)
if (WARN_ON(!SMC_IS_SMC64(smcnr)))
return SM_ERR_INVALID_PARAMETERS;
- return smc(smcnr, a0, a1, a2);
+ return s->msg_ops->send_direct_msg(dev, smcnr, a0, a1, a2);
}
EXPORT_SYMBOL(trusty_fast_call64);
#endif
@@ -88,13 +61,16 @@ static unsigned long trusty_std_call_inner(struct device *dev,
{
unsigned long ret;
int retry = 5;
+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
dev_dbg(dev, "%s(0x%lx 0x%lx 0x%lx 0x%lx)\n",
__func__, smcnr, a0, a1, a2);
while (true) {
- ret = smc(smcnr, a0, a1, a2);
+ ret = s->msg_ops->send_direct_msg(dev, smcnr, a0, a1, a2);
while ((s32)ret == SM_ERR_FIQ_INTERRUPTED)
- ret = smc(SMC_SC_RESTART_FIQ, 0, 0, 0);
+ ret = s->msg_ops->send_direct_msg(dev,
+ SMC_SC_RESTART_FIQ,
+ 0, 0, 0);
if ((int)ret != SM_ERR_BUSY || !retry)
break;
@@ -222,58 +198,17 @@ s32 trusty_std_call32(struct device *dev, u32 smcnr, u32 a0, u32 a1, u32 a2)
}
EXPORT_SYMBOL(trusty_std_call32);
-static int __trusty_share_memory(struct device *dev, u64 *id,
- struct scatterlist *sglist, unsigned int nents,
- pgprot_t pgprot, u64 tag, bool mem_share)
+int trusty_share_memory(struct device *dev, u64 *id,
+ struct scatterlist *sglist, unsigned int nents,
+ pgprot_t pgprot, u64 tag)
{
struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
- int ret;
- struct ns_mem_page_info pg_inf;
- struct scatterlist *sg;
- size_t count;
if (WARN_ON(dev->driver != &trusty_driver.driver))
return -EINVAL;
- if (WARN_ON(nents < 1))
- return -EINVAL;
-
- if (nents != 1 && s->api_version < TRUSTY_API_VERSION_MEM_OBJ) {
- dev_err(s->dev, "%s: old trusty version does not support non-contiguous memory objects\n",
- __func__);
- return -EOPNOTSUPP;
- }
-
- if (mem_share == false && s->api_version < TRUSTY_API_VERSION_MEM_OBJ) {
- dev_err(s->dev, "%s: old trusty version does not support lending memory objects\n",
- __func__);
- return -EOPNOTSUPP;
- }
-
- count = dma_map_sg(dev, sglist, nents, DMA_BIDIRECTIONAL);
- if (count != nents) {
- dev_err(s->dev, "failed to dma map sg_table\n");
- return -EINVAL;
- }
-
- sg = sglist;
- ret = trusty_encode_page_info(&pg_inf, phys_to_page(sg_dma_address(sg)),
- pgprot);
- if (ret) {
- dev_err(s->dev, "%s: trusty_encode_page_info failed\n",
- __func__);
- return ret;
- }
-
- *id = pg_inf.compat_attr;
- return 0;
-}
-
-int trusty_share_memory(struct device *dev, u64 *id,
- struct scatterlist *sglist, unsigned int nents,
- pgprot_t pgprot, u64 tag)
-{
- return __trusty_share_memory(dev, id, sglist, nents, pgprot, tag, true);
+ return s->mem_ops->trusty_share_memory(dev, id, sglist, nents, pgprot,
+ tag);
}
EXPORT_SYMBOL(trusty_share_memory);
@@ -281,7 +216,13 @@ int trusty_lend_memory(struct device *dev, u64 *id,
struct scatterlist *sglist, unsigned int nents,
pgprot_t pgprot, u64 tag)
{
- return __trusty_share_memory(dev, id, sglist, nents, pgprot, tag, false);
+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+
+ if (WARN_ON(dev->driver != &trusty_driver.driver))
+ return -EINVAL;
+
+ return s->mem_ops->trusty_lend_memory(dev, id, sglist, nents, pgprot,
+ tag);
}
EXPORT_SYMBOL(trusty_lend_memory);
@@ -316,22 +257,7 @@ int trusty_reclaim_memory(struct device *dev, u64 id,
if (WARN_ON(dev->driver != &trusty_driver.driver))
return -EINVAL;
- if (WARN_ON(nents < 1))
- return -EINVAL;
-
- if (s->api_version < TRUSTY_API_VERSION_MEM_OBJ) {
- if (nents != 1) {
- dev_err(s->dev, "%s: not supported\n", __func__);
- return -EOPNOTSUPP;
- }
-
- dma_unmap_sg(dev, sglist, nents, DMA_BIDIRECTIONAL);
-
- dev_dbg(s->dev, "%s: done\n", __func__);
- return 0;
- }
-
- return 0;
+ return s->mem_ops->trusty_reclaim_memory(dev, id, sglist, nents);
}
EXPORT_SYMBOL(trusty_reclaim_memory);
@@ -382,7 +308,7 @@ const char *trusty_version_str_get(struct device *dev)
}
EXPORT_SYMBOL(trusty_version_str_get);
-static void trusty_init_version(struct trusty_state *s, struct device *dev)
+static void trusty_init_version_str(struct trusty_state *s, struct device *dev)
{
int ret;
int i;
@@ -430,12 +356,17 @@ bool trusty_get_panic_status(struct device *dev)
}
EXPORT_SYMBOL(trusty_get_panic_status);
-static int trusty_init_api_version(struct trusty_state *s, struct device *dev)
+int trusty_init_api_version(struct trusty_state *s, struct device *dev,
+ u32 (*send_direct_msg)(struct device *dev,
+ unsigned long fid,
+ unsigned long a0,
+ unsigned long a1,
+ unsigned long a2))
{
u32 api_version;
- api_version = trusty_fast_call32(dev, SMC_FC_API_VERSION,
- TRUSTY_API_VERSION_CURRENT, 0, 0);
+ api_version = send_direct_msg(dev, SMC_FC_API_VERSION,
+ TRUSTY_API_VERSION_CURRENT, 0, 0);
if (api_version == SM_ERR_UNDEFINED_SMC)
api_version = 0;
@@ -598,11 +529,12 @@ static int trusty_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, s);
- trusty_init_version(s, &pdev->dev);
+ /* Initialize SMC transport */
+ ret = trusty_smc_transport_setup(s->dev);
+ if (ret != 0 || s->msg_ops == NULL || s->mem_ops == NULL)
+ goto err_transport_setup;
- ret = trusty_init_api_version(s, &pdev->dev);
- if (ret < 0)
- goto err_api_version;
+ trusty_init_version_str(s, &pdev->dev);
s->nop_wq = alloc_workqueue("trusty-nop-wq", WQ_CPU_INTENSIVE, 0);
if (!s->nop_wq) {
@@ -648,9 +580,10 @@ static int trusty_probe(struct platform_device *pdev)
err_alloc_works:
destroy_workqueue(s->nop_wq);
err_create_nop_wq:
-err_api_version:
- s->dev->dma_parms = NULL;
kfree(s->version_str);
+ trusty_smc_transport_cleanup(s->dev);
+err_transport_setup:
+ s->dev->dma_parms = NULL;
device_for_each_child(&pdev->dev, NULL, trusty_remove_child);
mutex_destroy(&s->smc_lock);
kfree(s);
@@ -673,6 +606,7 @@ static int trusty_remove(struct platform_device *pdev)
free_percpu(s->nop_works);
destroy_workqueue(s->nop_wq);
+ trusty_smc_transport_cleanup(s->dev);
mutex_destroy(&s->smc_lock);
s->dev->dma_parms = NULL;
kfree(s->version_str);
--
2.30.2
@@ -0,0 +1,56 @@
From 5566c2a41443e26068fe3a8e4a8e4b0c3a4e8ed6 Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Fri, 14 Jan 2022 14:22:42 +0000
Subject: [PATCH 26/32] ANDROID: trusty: Modify device compatible string
Drop smc keyword from device tree node as Trusty can use SMC or FFA
based transport.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: Id99b52f32a2122434a22f1991c0b4cd52b0676ed
Upstream-Status: Pending [Not submitted to upstream yet]
---
Documentation/devicetree/bindings/trusty/trusty-irq.txt | 2 +-
Documentation/devicetree/bindings/trusty/trusty-smc.txt | 2 +-
drivers/trusty/trusty.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/trusty/trusty-irq.txt b/Documentation/devicetree/bindings/trusty/trusty-irq.txt
index cbb545ad452b..ae02030be4e7 100644
--- a/Documentation/devicetree/bindings/trusty/trusty-irq.txt
+++ b/Documentation/devicetree/bindings/trusty/trusty-irq.txt
@@ -48,7 +48,7 @@ Example:
};
...
trusty {
- compatible = "android,trusty-smc-v1";
+ compatible = "android,trusty-v1";
ranges;
#address-cells = <2>;
#size-cells = <2>;
diff --git a/Documentation/devicetree/bindings/trusty/trusty-smc.txt b/Documentation/devicetree/bindings/trusty/trusty-smc.txt
index 1b39ad317c67..8d02a31ba814 100644
--- a/Documentation/devicetree/bindings/trusty/trusty-smc.txt
+++ b/Documentation/devicetree/bindings/trusty/trusty-smc.txt
@@ -3,4 +3,4 @@ Trusty smc interface
Trusty is running in secure mode on the same (arm) cpu(s) as the current os.
Required properties:
-- compatible: "android,trusty-smc-v1"
+- compatible: "android,trusty-v1"
diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
index 0486827a45ca..757dd7b2c527 100644
--- a/drivers/trusty/trusty.c
+++ b/drivers/trusty/trusty.c
@@ -615,7 +615,7 @@ static int trusty_remove(struct platform_device *pdev)
}
static const struct of_device_id trusty_of_match[] = {
- { .compatible = "android,trusty-smc-v1", },
+ { .compatible = "android,trusty-v1", },
{},
};
--
2.30.2
@@ -0,0 +1,209 @@
From 27248b5c8cb5c1a59b08e46eb3ab918867282c1c Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Fri, 14 Jan 2022 17:52:33 +0000
Subject: [PATCH 27/32] ANDROID: trusty: Add transport descriptor
Use transport descriptor to hold transport specific operations. This
helps to add new transport to Trusty core.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: Ibbde50de0302f6d259a7d572f0910067ce712b37
Upstream-Status: Pending [Not submitted to upstream yet]
---
drivers/trusty/trusty-private.h | 20 +++++++++-
drivers/trusty/trusty-smc.c | 6 +++
drivers/trusty/trusty.c | 71 ++++++++++++++++++++++++++++++---
3 files changed, 90 insertions(+), 7 deletions(-)
diff --git a/drivers/trusty/trusty-private.h b/drivers/trusty/trusty-private.h
index 4d73c6ae35d4..74b88bb8f83b 100644
--- a/drivers/trusty/trusty-private.h
+++ b/drivers/trusty/trusty-private.h
@@ -14,12 +14,14 @@ struct trusty_work {
};
struct trusty_msg_ops {
+ const struct trusty_transport_desc *desc;
u32 (*send_direct_msg)(struct device *dev, unsigned long fid,
unsigned long a0, unsigned long a1,
unsigned long a2);
};
struct trusty_mem_ops {
+ const struct trusty_transport_desc *desc;
int (*trusty_share_memory)(struct device *dev, u64 *id,
struct scatterlist *sglist,
unsigned int nents, pgprot_t pgprot, u64 tag);
@@ -46,6 +48,19 @@ struct trusty_state {
struct device_dma_parameters dma_parms;
const struct trusty_msg_ops *msg_ops;
const struct trusty_mem_ops *mem_ops;
+ struct trusty_ffa_state *ffa;
+};
+
+struct trusty_ffa_state {
+ struct device *dev; /* ffa device */
+ const struct ffa_dev_ops *ops;
+ struct mutex share_memory_msg_lock; /* protects share_memory_msg */
+};
+
+struct trusty_transport_desc {
+ const char *name;
+ int (*setup)(struct device *dev);
+ void (*cleanup)(struct device *dev);
};
int trusty_init_api_version(struct trusty_state *s, struct device *dev,
@@ -55,7 +70,8 @@ int trusty_init_api_version(struct trusty_state *s, struct device *dev,
unsigned long a1,
unsigned long a2));
-int trusty_smc_transport_setup(struct device *dev);
-void trusty_smc_transport_cleanup(struct device *dev);
+typedef const struct trusty_transport_desc *trusty_transports_t;
+
+extern const struct trusty_transport_desc trusty_smc_transport;
#endif /* _TRUSTY_PRIVATE_H */
diff --git a/drivers/trusty/trusty-smc.c b/drivers/trusty/trusty-smc.c
index 8fa841e0e253..62d1d7060744 100644
--- a/drivers/trusty/trusty-smc.c
+++ b/drivers/trusty/trusty-smc.c
@@ -134,3 +134,9 @@ void trusty_smc_transport_cleanup(struct device *dev)
if (s->mem_ops == &trusty_smc_mem_ops)
s->mem_ops = NULL;
}
+
+const struct trusty_transport_desc trusty_smc_transport = {
+ .name = "smc",
+ .setup = trusty_smc_transport_setup,
+ .cleanup = trusty_smc_transport_cleanup,
+};
diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
index 757dd7b2c527..ec0fccfaa24c 100644
--- a/drivers/trusty/trusty.c
+++ b/drivers/trusty/trusty.c
@@ -493,6 +493,46 @@ void trusty_dequeue_nop(struct device *dev, struct trusty_nop *nop)
}
EXPORT_SYMBOL(trusty_dequeue_nop);
+static int
+trusty_transports_setup(const trusty_transports_t *transports,
+ struct device *dev)
+{
+ const struct trusty_transport_desc *transport;
+ int ret;
+ int transports_ret = -ENODEV;
+
+ if (!transports)
+ return -EINVAL;
+
+ for (; (transport = *transports); transports++) {
+ if (!transport->setup)
+ return -EINVAL;
+
+ ret = transport->setup(dev);
+ transports_ret &= ret;
+ }
+
+ /* One transport needs to complete setup without error. */
+ if (transports_ret < 0)
+ return -ENODEV;
+
+ return 0;
+}
+
+static void
+trusty_transports_cleanup(const trusty_transports_t *transports,
+ struct device *dev)
+{
+ const struct trusty_transport_desc *transport;
+
+ for (; (transport = *transports); transports++) {
+ if (!transport->cleanup)
+ continue;
+
+ transport->cleanup(dev);
+ }
+}
+
static int trusty_probe(struct platform_device *pdev)
{
int ret;
@@ -500,6 +540,7 @@ static int trusty_probe(struct platform_device *pdev)
work_func_t work_func;
struct trusty_state *s;
struct device_node *node = pdev->dev.of_node;
+ const trusty_transports_t *descs;
if (!node) {
dev_err(&pdev->dev, "of_node required\n");
@@ -529,8 +570,12 @@ static int trusty_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, s);
- /* Initialize SMC transport */
- ret = trusty_smc_transport_setup(s->dev);
+ /*
+ * Initialize Trusty transport. Trusty msg and mem ops has to be
+ * initialized as part of transport setup.
+ */
+ descs = of_device_get_match_data(&pdev->dev);
+ ret = trusty_transports_setup(descs, s->dev);
if (ret != 0 || s->msg_ops == NULL || s->mem_ops == NULL)
goto err_transport_setup;
@@ -581,7 +626,7 @@ static int trusty_probe(struct platform_device *pdev)
destroy_workqueue(s->nop_wq);
err_create_nop_wq:
kfree(s->version_str);
- trusty_smc_transport_cleanup(s->dev);
+ trusty_transports_cleanup(descs, s->dev);
err_transport_setup:
s->dev->dma_parms = NULL;
device_for_each_child(&pdev->dev, NULL, trusty_remove_child);
@@ -595,6 +640,7 @@ static int trusty_remove(struct platform_device *pdev)
{
unsigned int cpu;
struct trusty_state *s = platform_get_drvdata(pdev);
+ const trusty_transports_t *descs;
device_for_each_child(&pdev->dev, NULL, trusty_remove_child);
@@ -606,7 +652,10 @@ static int trusty_remove(struct platform_device *pdev)
free_percpu(s->nop_works);
destroy_workqueue(s->nop_wq);
- trusty_smc_transport_cleanup(s->dev);
+ /* call transport cleanup */
+ descs = of_device_get_match_data(&pdev->dev);
+ trusty_transports_cleanup(descs, s->dev);
+
mutex_destroy(&s->smc_lock);
s->dev->dma_parms = NULL;
kfree(s->version_str);
@@ -614,8 +663,20 @@ static int trusty_remove(struct platform_device *pdev)
return 0;
}
+/*
+ * Trusty probe will try all compiled in transports and will use the transport
+ * supported by the Trusty kernel.
+ *
+ * For Trusty API version < TRUSTY_API_VERSION_MEM_OBJ:
+ * trusty_smc_transport used for messaging.
+ */
+static const trusty_transports_t trusty_transports[] = {
+ &trusty_smc_transport,
+ NULL,
+};
+
static const struct of_device_id trusty_of_match[] = {
- { .compatible = "android,trusty-v1", },
+ { .compatible = "android,trusty-v1", .data = trusty_transports },
{},
};
--
2.30.2
@@ -0,0 +1,312 @@
From 3104eb14f62df1c7c4b9038eb914514b0ff371dc Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Fri, 14 Jan 2022 18:47:08 +0000
Subject: [PATCH 28/32] ANDROID: trusty: Add trusty-ffa driver
Initial changes related to FFA transport support
- Adds FFA transport descriptor
- Defines Trusty UUID
- Initializes FFA transport does probe, sets ffa_ops
- Defers Trusty probe if ARM FF-A driver is not initialized or
Trusty SP not found.
- Link FF-A device as the supplier for Trusty platform device.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I78f72b85c20e4bad4c24cf0826e96f27dcf2ee1d
Upstream-Status: Pending [Not submitted to upstream yet]
---
drivers/trusty/Makefile | 1 +
drivers/trusty/trusty-ffa.c | 196 ++++++++++++++++++++++++++++++++
drivers/trusty/trusty-ffa.h | 28 +++++
drivers/trusty/trusty-private.h | 1 +
drivers/trusty/trusty.c | 6 +
5 files changed, 232 insertions(+)
create mode 100644 drivers/trusty/trusty-ffa.c
create mode 100644 drivers/trusty/trusty-ffa.h
diff --git a/drivers/trusty/Makefile b/drivers/trusty/Makefile
index fbb53ee93003..797d61bf68ef 100644
--- a/drivers/trusty/Makefile
+++ b/drivers/trusty/Makefile
@@ -6,6 +6,7 @@
obj-$(CONFIG_TRUSTY) += trusty-core.o
trusty-core-objs += trusty.o trusty-mem.o
trusty-core-objs += trusty-smc.o
+trusty-core-objs += trusty-ffa.o
trusty-core-$(CONFIG_ARM) += trusty-smc-arm.o
trusty-core-$(CONFIG_ARM64) += trusty-smc-arm64.o
obj-$(CONFIG_TRUSTY_IRQ) += trusty-irq.o
diff --git a/drivers/trusty/trusty-ffa.c b/drivers/trusty/trusty-ffa.c
new file mode 100644
index 000000000000..c8c16a1fc700
--- /dev/null
+++ b/drivers/trusty/trusty-ffa.c
@@ -0,0 +1,196 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 ARM Ltd.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/trusty/smcall.h>
+#include <linux/arm_ffa.h>
+#include <linux/trusty/trusty.h>
+
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+
+#include "trusty-ffa.h"
+#include "trusty-private.h"
+
+static const struct trusty_mem_ops trusty_ffa_mem_ops = {
+ .desc = &trusty_ffa_transport,
+};
+
+static const struct ffa_device_id trusty_ffa_device_id[] = {
+ /*
+ * Trusty UID: RFC-4122 compliant UUID version 4
+ * 40ee25f0-a2bc-304c-8c4ca173c57d8af1
+ */
+ { UUID_INIT(0x40ee25f0, 0xa2bc, 0x304c,
+ 0x8c, 0x4c, 0xa1, 0x73, 0xc5, 0x7d, 0x8a, 0xf1) },
+ {}
+};
+
+static int trusty_ffa_dev_match(struct device *dev, const void *uuid)
+{
+ struct ffa_device *ffa_dev;
+
+ ffa_dev = to_ffa_dev(dev);
+ if (uuid_equal(&ffa_dev->uuid, uuid))
+ return 1;
+
+ return 0;
+}
+
+static struct ffa_device *trusty_ffa_dev_find(void)
+{
+ const void *data;
+ struct device *dev;
+
+ /* currently only one trusty instance is probed */
+ data = &trusty_ffa_device_id[0].uuid;
+
+ dev = bus_find_device(&ffa_bus_type, NULL, data, trusty_ffa_dev_match);
+ if (dev) {
+ /* drop reference count */
+ put_device(dev);
+ return to_ffa_dev(dev);
+ }
+
+ return NULL;
+}
+
+static int trusty_ffa_link_supplier(struct device *c_dev, struct device *s_dev)
+{
+ if (!c_dev || !s_dev)
+ return -EINVAL;
+
+ if (!device_link_add(c_dev, s_dev, DL_FLAG_AUTOREMOVE_CONSUMER)) {
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/*
+ * called from trusty probe
+ */
+static int trusty_ffa_transport_setup(struct device *dev)
+{
+ int rc;
+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+ struct trusty_ffa_state *ffa_state;
+ struct ffa_device *ffa_dev;
+
+ /* ffa transport not required for lower api versions */
+ if (s->api_version != 0 && s->api_version < TRUSTY_API_VERSION_MEM_OBJ) {
+ return -EINVAL;
+ }
+
+ ffa_dev = trusty_ffa_dev_find();
+ if (!ffa_dev) {
+ dev_dbg(dev, "FFA: Trusty device not found defer probe\n");
+ return -EPROBE_DEFER;
+ }
+
+ ffa_state = ffa_dev_get_drvdata(ffa_dev);
+ if (!ffa_state)
+ return -EINVAL;
+
+ rc = trusty_ffa_link_supplier(dev, &ffa_dev->dev);
+ if (rc != 0)
+ return rc;
+
+ /* FFA used only for memory sharing operations */
+ if (s->api_version == TRUSTY_API_VERSION_MEM_OBJ) {
+ s->ffa = ffa_state;
+ s->mem_ops = &trusty_ffa_mem_ops;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static void trusty_ffa_transport_cleanup(struct device *dev)
+{
+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+
+ /* ffa transport not setup for lower api versions */
+ if (s->api_version < TRUSTY_API_VERSION_MEM_OBJ) {
+ return;
+ }
+
+ s->ffa = NULL;
+ s->mem_ops = NULL;
+}
+
+static int trusty_ffa_probe(struct ffa_device *ffa_dev)
+{
+ const struct ffa_dev_ops *ffa_ops;
+ struct trusty_ffa_state *s;
+ u32 ffa_drv_version;
+
+ ffa_ops = ffa_dev_ops_get(ffa_dev);
+ if (!ffa_ops) {
+ dev_dbg(&ffa_dev->dev, "ffa_dev_ops_get: failed\n");
+ return -ENOENT;
+ }
+
+ /* check ffa driver version compatibility */
+ ffa_drv_version = ffa_ops->api_version_get();
+ if (TO_TRUSTY_FFA_MAJOR(ffa_drv_version) != TRUSTY_FFA_VERSION_MAJOR ||
+ TO_TRUSTY_FFA_MINOR(ffa_drv_version) < TRUSTY_FFA_VERSION_MINOR)
+ return -EINVAL;
+
+ s = kzalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ s->dev = &ffa_dev->dev;
+ s->ops = ffa_ops;
+ mutex_init(&s->share_memory_msg_lock);
+ ffa_dev_set_drvdata(ffa_dev, s);
+
+ ffa_ops->mode_32bit_set(ffa_dev);
+
+ return 0;
+}
+
+static void trusty_ffa_remove(struct ffa_device *ffa_dev)
+{
+ struct trusty_ffa_state *s;
+
+ s = ffa_dev_get_drvdata(ffa_dev);
+
+ mutex_destroy(&s->share_memory_msg_lock);
+ memset(s, 0, sizeof(struct trusty_ffa_state));
+ kfree(s);
+}
+
+static struct ffa_driver trusty_ffa_driver = {
+ .name = "trusty-ffa",
+ .probe = trusty_ffa_probe,
+ .remove = trusty_ffa_remove,
+ .id_table = trusty_ffa_device_id,
+};
+
+static int __init trusty_ffa_transport_init(void)
+{
+ if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)) {
+ return ffa_register(&trusty_ffa_driver);
+ } else
+ return -ENODEV;
+}
+
+static void __exit trusty_ffa_transport_exit(void)
+{
+ if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT))
+ ffa_unregister(&trusty_ffa_driver);
+}
+
+const struct trusty_transport_desc trusty_ffa_transport = {
+ .name = "ffa",
+ .setup = trusty_ffa_transport_setup,
+ .cleanup = trusty_ffa_transport_cleanup,
+};
+
+module_init(trusty_ffa_transport_init);
+module_exit(trusty_ffa_transport_exit);
diff --git a/drivers/trusty/trusty-ffa.h b/drivers/trusty/trusty-ffa.h
new file mode 100644
index 000000000000..267ca2c5db29
--- /dev/null
+++ b/drivers/trusty/trusty-ffa.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 ARM Ltd.
+ */
+
+#ifndef __LINUX_TRUSTY_FFA_H
+#define __LINUX_TRUSTY_FFA_H
+
+#include <linux/types.h>
+#include <linux/uuid.h>
+#include <linux/arm_ffa.h>
+
+#define TRUSTY_FFA_VERSION_MAJOR (1U)
+#define TRUSTY_FFA_VERSION_MINOR (0U)
+#define TRUSTY_FFA_VERSION_MAJOR_SHIFT (16U)
+#define TRUSTY_FFA_VERSION_MAJOR_MASK (0x7fffU)
+#define TRUSTY_FFA_VERSION_MINOR_SHIFT (0U)
+#define TRUSTY_FFA_VERSION_MINOR_MASK (0U)
+
+#define TO_TRUSTY_FFA_MAJOR(v) \
+ ((u16)((v >> TRUSTY_FFA_VERSION_MAJOR_SHIFT) & \
+ TRUSTY_FFA_VERSION_MAJOR_MASK))
+
+#define TO_TRUSTY_FFA_MINOR(v) \
+ ((u16)((v >> TRUSTY_FFA_VERSION_MINOR_SHIFT) & \
+ TRUSTY_FFA_VERSION_MINOR_MASK))
+
+#endif /* __LINUX_TRUSTY_FFA_H */
diff --git a/drivers/trusty/trusty-private.h b/drivers/trusty/trusty-private.h
index 74b88bb8f83b..2496f397e5d2 100644
--- a/drivers/trusty/trusty-private.h
+++ b/drivers/trusty/trusty-private.h
@@ -73,5 +73,6 @@ int trusty_init_api_version(struct trusty_state *s, struct device *dev,
typedef const struct trusty_transport_desc *trusty_transports_t;
extern const struct trusty_transport_desc trusty_smc_transport;
+extern const struct trusty_transport_desc trusty_ffa_transport;
#endif /* _TRUSTY_PRIVATE_H */
diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
index ec0fccfaa24c..4686b0d34f61 100644
--- a/drivers/trusty/trusty.c
+++ b/drivers/trusty/trusty.c
@@ -509,6 +509,11 @@ trusty_transports_setup(const trusty_transports_t *transports,
return -EINVAL;
ret = transport->setup(dev);
+ if (ret == -EPROBE_DEFER) {
+ dev_notice(dev, "transport %s: defer probe\n",
+ transport->name);
+ return ret;
+ }
transports_ret &= ret;
}
@@ -672,6 +677,7 @@ static int trusty_remove(struct platform_device *pdev)
*/
static const trusty_transports_t trusty_transports[] = {
&trusty_smc_transport,
+ &trusty_ffa_transport,
NULL,
};
--
2.30.2
@@ -0,0 +1,151 @@
From c552f8ed6bbd68e838732598ca74055bb696dcb3 Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Tue, 18 Jan 2022 15:11:46 +0000
Subject: [PATCH 29/32] ANDROID: trusty-ffa: Add support for FFA memory
operations
Initializes Trusty mem_ops with FFA memory operations for share,
lend, reclaim.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: Id3a1eb5ae8e4721cb983c624773d39bafe25a77d
Upstream-Status: Pending [Not submitted to upstream yet]
---
drivers/trusty/trusty-ffa.c | 102 ++++++++++++++++++++++++++++++++++++
drivers/trusty/trusty.c | 5 ++
2 files changed, 107 insertions(+)
diff --git a/drivers/trusty/trusty-ffa.c b/drivers/trusty/trusty-ffa.c
index c8c16a1fc700..0655b3887b52 100644
--- a/drivers/trusty/trusty-ffa.c
+++ b/drivers/trusty/trusty-ffa.c
@@ -15,8 +15,110 @@
#include "trusty-ffa.h"
#include "trusty-private.h"
+static int __trusty_ffa_share_memory(struct device *dev, u64 *id,
+ struct scatterlist *sglist,
+ unsigned int nents, pgprot_t pgprot,
+ u64 tag, bool share)
+{
+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+ int ret;
+ struct scatterlist *sg;
+ size_t count;
+ struct ffa_device *ffa_dev = to_ffa_dev(s->ffa->dev);
+ const struct ffa_dev_ops *ffa_ops = s->ffa->ops;
+ struct ffa_mem_region_attributes ffa_mem_attr;
+ struct ffa_mem_ops_args ffa_mem_args;
+
+ if (WARN_ON(nents < 1))
+ return -EINVAL;
+
+ count = dma_map_sg(dev, sglist, nents, DMA_BIDIRECTIONAL);
+ if (count != nents) {
+ dev_err(s->dev, "failed to dma map sg_table\n");
+ return -EINVAL;
+ }
+
+ sg = sglist;
+
+ mutex_lock(&s->ffa->share_memory_msg_lock);
+
+ ffa_mem_attr.receiver = ffa_dev->vm_id;
+ ffa_mem_attr.attrs = FFA_MEM_RW;
+
+ ffa_mem_args.use_txbuf = 1;
+ ffa_mem_args.tag = tag;
+ ffa_mem_args.attrs = &ffa_mem_attr;
+ ffa_mem_args.nattrs = 1;
+ ffa_mem_args.sg = sg;
+ ffa_mem_args.flags = 0;
+
+ if (share) {
+ ret = ffa_ops->memory_share(ffa_dev, &ffa_mem_args);
+ } else {
+ ret = ffa_ops->memory_lend(ffa_dev, &ffa_mem_args);
+ }
+
+ mutex_unlock(&s->ffa->share_memory_msg_lock);
+
+ if (!ret) {
+ *id = ffa_mem_args.g_handle;
+ dev_dbg(s->dev, "%s: done\n", __func__);
+ return 0;
+ }
+
+ dev_err(s->dev, "%s: failed %d", __func__, ret);
+
+ dma_unmap_sg(dev, sglist, nents, DMA_BIDIRECTIONAL);
+ return ret;
+}
+
+static int trusty_ffa_share_memory(struct device *dev, u64 *id,
+ struct scatterlist *sglist,
+ unsigned int nents, pgprot_t pgprot, u64 tag)
+{
+ return __trusty_ffa_share_memory(dev, id, sglist, nents, pgprot, tag,
+ true);
+}
+
+static int trusty_ffa_lend_memory(struct device *dev, u64 *id,
+ struct scatterlist *sglist,
+ unsigned int nents, pgprot_t pgprot, u64 tag)
+{
+ return __trusty_ffa_share_memory(dev, id, sglist, nents, pgprot, tag,
+ false);
+}
+
+static int trusty_ffa_reclaim_memory(struct device *dev, u64 id,
+ struct scatterlist *sglist,
+ unsigned int nents)
+{
+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+ int ret = 0;
+ const struct ffa_dev_ops *ffa_ops = s->ffa->ops;
+
+ if (WARN_ON(nents < 1))
+ return -EINVAL;
+
+ mutex_lock(&s->ffa->share_memory_msg_lock);
+
+ ret = ffa_ops->memory_reclaim(id, 0);
+
+ mutex_unlock(&s->ffa->share_memory_msg_lock);
+
+ if (ret != 0)
+ return ret;
+
+ dma_unmap_sg(dev, sglist, nents, DMA_BIDIRECTIONAL);
+
+ dev_dbg(s->dev, "%s: done\n", __func__);
+ return 0;
+}
+
static const struct trusty_mem_ops trusty_ffa_mem_ops = {
.desc = &trusty_ffa_transport,
+ .trusty_share_memory = &trusty_ffa_share_memory,
+ .trusty_lend_memory = &trusty_ffa_lend_memory,
+ .trusty_reclaim_memory = &trusty_ffa_reclaim_memory,
};
static const struct ffa_device_id trusty_ffa_device_id[] = {
diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
index 4686b0d34f61..f91c255c9897 100644
--- a/drivers/trusty/trusty.c
+++ b/drivers/trusty/trusty.c
@@ -674,6 +674,11 @@ static int trusty_remove(struct platform_device *pdev)
*
* For Trusty API version < TRUSTY_API_VERSION_MEM_OBJ:
* trusty_smc_transport used for messaging.
+ *
+ * For Trusty API version == TRUSTY_API_VERSION_MEM_OBJ:
+ * trusty_smc_transport used for messaging.
+ * trusty_ffa_transport used for memory sharing.
+ *
*/
static const trusty_transports_t trusty_transports[] = {
&trusty_smc_transport,
--
2.30.2
@@ -0,0 +1,142 @@
From e67cd78142984c7c4120f15ef14e1e026746af5a Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Thu, 3 Feb 2022 11:19:38 +0000
Subject: [PATCH 30/32] ANDROID: trusty-ffa: Enable FFA transport for both
memory and message ops
Adds new API version TRUSTY_API_VERSION_FFA and sets this as current
API version.
If Trusty on the secure side supports receipt of FFA direct request,
then trusty core uses FFA calls for messages and memory operations.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I4a8b060f906a96935a7df10713026fb543e2b9a7
Upstream-Status: Pending [Not submitted to upstream yet]
---
drivers/trusty/trusty-ffa.c | 58 +++++++++++++++++++++++++++++++++++
drivers/trusty/trusty.c | 3 ++
include/linux/trusty/smcall.h | 3 +-
3 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/drivers/trusty/trusty-ffa.c b/drivers/trusty/trusty-ffa.c
index 0655b3887b52..543f5a0d31cb 100644
--- a/drivers/trusty/trusty-ffa.c
+++ b/drivers/trusty/trusty-ffa.c
@@ -15,6 +15,36 @@
#include "trusty-ffa.h"
#include "trusty-private.h"
+/* partition property: Supports receipt of direct requests */
+#define FFA_PARTITION_DIRECT_REQ_RECV BIT(0)
+
+/* string representation of trusty UUID used for partition info get call */
+static const char *trusty_uuid = "40ee25f0-a2bc-304c-8c4c-a173c57d8af1";
+
+static u32 trusty_ffa_send_direct_msg(struct device *dev, unsigned long fid,
+ unsigned long a0, unsigned long a1,
+ unsigned long a2)
+{
+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
+ struct ffa_send_direct_data ffa_msg;
+ struct ffa_device *ffa_dev;
+ int ret;
+
+ ffa_dev = to_ffa_dev(s->ffa->dev);
+
+ ffa_msg.data0 = fid;
+ ffa_msg.data1 = a0;
+ ffa_msg.data2 = a1;
+ ffa_msg.data3 = a2;
+ ffa_msg.data4 = 0;
+
+ ret = s->ffa->ops->sync_send_receive(ffa_dev, &ffa_msg);
+ if (!ret)
+ return ffa_msg.data0;
+
+ return ret;
+}
+
static int __trusty_ffa_share_memory(struct device *dev, u64 *id,
struct scatterlist *sglist,
unsigned int nents, pgprot_t pgprot,
@@ -114,6 +144,11 @@ static int trusty_ffa_reclaim_memory(struct device *dev, u64 id,
return 0;
}
+static const struct trusty_msg_ops trusty_ffa_msg_ops = {
+ .desc = &trusty_ffa_transport,
+ .send_direct_msg = &trusty_ffa_send_direct_msg,
+};
+
static const struct trusty_mem_ops trusty_ffa_mem_ops = {
.desc = &trusty_ffa_transport,
.trusty_share_memory = &trusty_ffa_share_memory,
@@ -181,6 +216,7 @@ static int trusty_ffa_transport_setup(struct device *dev)
struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
struct trusty_ffa_state *ffa_state;
struct ffa_device *ffa_dev;
+ struct ffa_partition_info pinfo = { 0 };
/* ffa transport not required for lower api versions */
if (s->api_version != 0 && s->api_version < TRUSTY_API_VERSION_MEM_OBJ) {
@@ -208,6 +244,28 @@ static int trusty_ffa_transport_setup(struct device *dev)
return 0;
}
+ /* check if Trusty partition can support receipt of direct requests. */
+ rc = ffa_state->ops->partition_info_get(trusty_uuid, &pinfo);
+ if (rc || !(pinfo.properties & FFA_PARTITION_DIRECT_REQ_RECV)) {
+ dev_err(ffa_state->dev, "trusty_ffa_pinfo: ret: 0x%x, prop: 0x%x\n",
+ rc, pinfo.properties);
+ return -EINVAL;
+ }
+
+ /* query and check Trusty API version */
+ s->ffa = ffa_state;
+ rc = trusty_init_api_version(s, dev, trusty_ffa_send_direct_msg);
+ if (rc) {
+ s->ffa = NULL;
+ return -EINVAL;
+ }
+
+ if (s->api_version == TRUSTY_API_VERSION_FFA) {
+ s->msg_ops = &trusty_ffa_msg_ops;
+ s->mem_ops = &trusty_ffa_mem_ops;
+ return 0;
+ }
+
return -EINVAL;
}
diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
index f91c255c9897..66273873f169 100644
--- a/drivers/trusty/trusty.c
+++ b/drivers/trusty/trusty.c
@@ -679,6 +679,9 @@ static int trusty_remove(struct platform_device *pdev)
* trusty_smc_transport used for messaging.
* trusty_ffa_transport used for memory sharing.
*
+ * For Trusty API version > TRUSTY_API_VERSION_MEM_OBJ:
+ * trusty_ffa_transport used for messaging and memory sharing operations.
+ *
*/
static const trusty_transports_t trusty_transports[] = {
&trusty_smc_transport,
diff --git a/include/linux/trusty/smcall.h b/include/linux/trusty/smcall.h
index aea3f6068593..17b3d1c2c4f6 100644
--- a/include/linux/trusty/smcall.h
+++ b/include/linux/trusty/smcall.h
@@ -109,7 +109,8 @@
#define TRUSTY_API_VERSION_SMP_NOP (3)
#define TRUSTY_API_VERSION_PHYS_MEM_OBJ (4)
#define TRUSTY_API_VERSION_MEM_OBJ (5)
-#define TRUSTY_API_VERSION_CURRENT (5)
+#define TRUSTY_API_VERSION_FFA (6)
+#define TRUSTY_API_VERSION_CURRENT (6)
#define SMC_FC_API_VERSION SMC_FASTCALL_NR(SMC_ENTITY_SECURE_MONITOR, 11)
/* TRUSTED_OS entity calls */
--
2.30.2
@@ -0,0 +1,146 @@
From 088162ab1852aa0f2034199e97a327b6240231db Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Wed, 16 Mar 2022 11:14:09 +0000
Subject: [PATCH 31/32] ANDROID: trusty: Make trusty transports configurable
With TRUSTY_SMC_TRANSPORT set to 'y', SMC based message passing and
memory sharing support will be compiled in to trusty core.
With TRUSTY_FFA_TRANSPORT set to 'y', FFA based message passing and
memory sharing support will be compiled in to trusty core. This
depends on ARM FF-A driver (ARM_FFA_TRANSPORT).
Enabling any of the transport sets config TRUSTY_HAVE_TRANSPORT to 'y'.
Not enabling any of the transport causes the build to break.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: Ib5bbf0d39202e6897700264d14371ae33101c1d1
Upstream-Status: Pending [Not submitted to upstream yet]
---
drivers/trusty/Kconfig | 30 ++++++++++++++++++++++++++++++
drivers/trusty/Makefile | 26 +++++++++++++++-----------
drivers/trusty/trusty-private.h | 4 ++++
drivers/trusty/trusty.c | 7 +++++++
4 files changed, 56 insertions(+), 11 deletions(-)
diff --git a/drivers/trusty/Kconfig b/drivers/trusty/Kconfig
index fcde7f097acf..260022e4595b 100644
--- a/drivers/trusty/Kconfig
+++ b/drivers/trusty/Kconfig
@@ -21,6 +21,36 @@ config TRUSTY
if TRUSTY
+config TRUSTY_HAVE_TRANSPORT
+ bool
+ help
+ If any of the Trusty transport is enabled then it sets this config
+ option. This variable is used to break the build when none of the
+ Trusty transports are enabled.
+
+config TRUSTY_SMC_TRANSPORT
+ bool "Trusty transport based on SMC"
+ select TRUSTY_HAVE_TRANSPORT
+ default n
+ help
+ Enable SMC based transport for Trusty. This transport is required for
+ Trusty API version <= TRUSTY_API_VERSION_MEM_OBJ.
+
+ If you want to use legacy SMC based transport for sending Trusty
+ messages to secure world, answer Y.
+
+config TRUSTY_FFA_TRANSPORT
+ bool "Trusty transport based on FFA"
+ select TRUSTY_HAVE_TRANSPORT
+ depends on ARM_FFA_TRANSPORT
+ default y
+ help
+ Enable ARM FF-A based transport for Trusty. This transport is required
+ for Trusty API version >= TRUSTY_API_VERSION_MEM_OBJ.
+
+ If you want to use ARM FF-A based transport for sending Trusty messages
+ to secure world, answer Y.
+
config TRUSTY_IRQ
tristate "Trusty IRQ support"
default y
diff --git a/drivers/trusty/Makefile b/drivers/trusty/Makefile
index 797d61bf68ef..104a4d0ed35c 100644
--- a/drivers/trusty/Makefile
+++ b/drivers/trusty/Makefile
@@ -3,14 +3,18 @@
# Makefile for trusty components
#
-obj-$(CONFIG_TRUSTY) += trusty-core.o
-trusty-core-objs += trusty.o trusty-mem.o
-trusty-core-objs += trusty-smc.o
-trusty-core-objs += trusty-ffa.o
-trusty-core-$(CONFIG_ARM) += trusty-smc-arm.o
-trusty-core-$(CONFIG_ARM64) += trusty-smc-arm64.o
-obj-$(CONFIG_TRUSTY_IRQ) += trusty-irq.o
-obj-$(CONFIG_TRUSTY_LOG) += trusty-log.o
-obj-$(CONFIG_TRUSTY_TEST) += trusty-test.o
-obj-$(CONFIG_TRUSTY_VIRTIO) += trusty-virtio.o
-obj-$(CONFIG_TRUSTY_VIRTIO_IPC) += trusty-ipc.o
+obj-$(CONFIG_TRUSTY) += trusty-core.o
+trusty-core-objs += trusty.o
+trusty-arm-smc-$(CONFIG_ARM) += trusty-smc-arm.o
+trusty-arm-smc64-$(CONFIG_ARM64) += trusty-smc-arm64.o
+trusty-transport-$(CONFIG_TRUSTY_SMC_TRANSPORT) += trusty-smc.o
+trusty-transport-$(CONFIG_TRUSTY_SMC_TRANSPORT) += trusty-mem.o
+trusty-transport-$(CONFIG_TRUSTY_SMC_TRANSPORT) += $(trusty-arm-smc-y)
+trusty-transport-$(CONFIG_TRUSTY_SMC_TRANSPORT) += $(trusty-arm-smc64-y)
+trusty-transport-$(CONFIG_TRUSTY_FFA_TRANSPORT) += trusty-ffa.o
+trusty-core-objs += $(trusty-transport-y)
+obj-$(CONFIG_TRUSTY_IRQ) += trusty-irq.o
+obj-$(CONFIG_TRUSTY_LOG) += trusty-log.o
+obj-$(CONFIG_TRUSTY_TEST) += trusty-test.o
+obj-$(CONFIG_TRUSTY_VIRTIO) += trusty-virtio.o
+obj-$(CONFIG_TRUSTY_VIRTIO_IPC) += trusty-ipc.o
diff --git a/drivers/trusty/trusty-private.h b/drivers/trusty/trusty-private.h
index 2496f397e5d2..386ca9ae5af3 100644
--- a/drivers/trusty/trusty-private.h
+++ b/drivers/trusty/trusty-private.h
@@ -72,7 +72,11 @@ int trusty_init_api_version(struct trusty_state *s, struct device *dev,
typedef const struct trusty_transport_desc *trusty_transports_t;
+#ifdef CONFIG_TRUSTY_SMC_TRANSPORT
extern const struct trusty_transport_desc trusty_smc_transport;
+#endif
+#ifdef CONFIG_TRUSTY_FFA_TRANSPORT
extern const struct trusty_transport_desc trusty_ffa_transport;
+#endif
#endif /* _TRUSTY_PRIVATE_H */
diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
index 66273873f169..06698f3c67f9 100644
--- a/drivers/trusty/trusty.c
+++ b/drivers/trusty/trusty.c
@@ -684,8 +684,12 @@ static int trusty_remove(struct platform_device *pdev)
*
*/
static const trusty_transports_t trusty_transports[] = {
+#ifdef CONFIG_TRUSTY_SMC_TRANSPORT
&trusty_smc_transport,
+#endif
+#ifdef CONFIG_TRUSTY_FFA_TRANSPORT
&trusty_ffa_transport,
+#endif
NULL,
};
@@ -708,6 +712,9 @@ static struct platform_driver trusty_driver = {
static int __init trusty_driver_init(void)
{
+ BUILD_BUG_ON_MSG(!IS_ENABLED(CONFIG_TRUSTY_HAVE_TRANSPORT),
+ "Trusty transport not configured");
+
return platform_driver_register(&trusty_driver);
}
--
2.30.2