1
0
mirror of https://git.yoctoproject.org/meta-arm synced 2026-07-16 15:57:19 +00:00

arm-bsp/linux: Add linux-trusted-services driver, FF-A ABI changes for TC0

This adds below patches:
     - buf driver for trusted service test applications
     - Fix in FFA-ABI aligning with latest SPMC (hafnium)

Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I6b36a73a910f6e10748d78b2ad74603dde42c8a9
This commit is contained in:
Arunachalam Ganapathy
2021-04-15 11:36:54 +01:00
committed by Tushar Khandelwal
parent 9d1724c3d4
commit 5d47d3f9db
3 changed files with 446 additions and 0 deletions
@@ -83,6 +83,8 @@ SRC_URI_append_tc0 = " \
file://0013-tee-optee-fix-mem-handle-removal-in-ffa_shm_unregist.patch \ file://0013-tee-optee-fix-mem-handle-removal-in-ffa_shm_unregist.patch \
file://0014-arm64-Add-support-for-asymmetric-AArch32-EL0-configu.patch \ file://0014-arm64-Add-support-for-asymmetric-AArch32-EL0-configu.patch \
file://0015-arm64-smp-Prevent-hotplugging-the-last-AArch32-able-.patch \ file://0015-arm64-smp-Prevent-hotplugging-the-last-AArch32-able-.patch \
file://0016-drivers-buf-Add-userspace-ff-a-driver-buf-and-add-to.patch \
file://0017-drivers-ffa-modify-FFA-ABIs-with-supported-conventio.patch \
" "
# #
@@ -0,0 +1,357 @@
From 1d85316ed0571300c12216c9cafb634db6fe4a8a Mon Sep 17 00:00:00 2001
From: Ben Horgan <ben.horgan@arm.com>
Date: Tue, 16 Mar 2021 16:08:54 +0000
Subject: [PATCH 1/2] drivers: buf: Add userspace ff-a driver (buf) and add to
build
This is an earlier revision of:
https://gitlab.arm.com/linux-arm/linux-trusted-services/
Change-Id: Iffa92583826285d616aef8d32f3a3326ec4f1f96
Signed-off-by: Balint Dobszay <balint.dobszay@arm.com>
Signed-off-by: Ben Horgan <ben.horgan@arm.com>
Upstream-Status: Backport [https://git.gitlab.arm.com/linux-arm/linux-trusted-services/-/commit/4696c6f92e991072052d7ef8297db6fa4695994a]
---
drivers/Makefile | 3 +
drivers/buf/Makefile | 3 +
drivers/buf/buf_common.h | 45 +++++++
drivers/buf/buf_driver.c | 254 +++++++++++++++++++++++++++++++++++++++
4 files changed, 305 insertions(+)
create mode 100644 drivers/buf/Makefile
create mode 100644 drivers/buf/buf_common.h
create mode 100644 drivers/buf/buf_driver.c
diff --git a/drivers/Makefile b/drivers/Makefile
index aaef17cc6512..67cb5965ab94 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -186,3 +186,6 @@ obj-$(CONFIG_SIOX) += siox/
obj-$(CONFIG_GNSS) += gnss/
obj-$(CONFIG_INTERCONNECT) += interconnect/
obj-$(CONFIG_COUNTER) += counter/
+
+# FF-A debugfs userspace driver
+obj-y += buf/
diff --git a/drivers/buf/Makefile b/drivers/buf/Makefile
new file mode 100644
index 000000000000..d42b20734770
--- /dev/null
+++ b/drivers/buf/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+
+obj-y := buf_driver.o
diff --git a/drivers/buf/buf_common.h b/drivers/buf/buf_common.h
new file mode 100644
index 000000000000..397b234bad30
--- /dev/null
+++ b/drivers/buf/buf_common.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020-2021, Arm Limited
+ */
+
+#ifndef __BUF_COMMON_H
+#define __BUF_COMMON_H
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#include <uapi/asm-generic/ioctl.h>
+#else
+#include <stdint.h>
+#include <sys/ioctl.h>
+#endif
+
+struct buf_descr {
+ uint8_t *buf;
+ size_t length;
+};
+
+struct msg_args {
+ uint16_t dst_id;
+ uint32_t args[5];
+};
+
+struct endpoint_id {
+ uint32_t uuid_0;
+ uint32_t uuid_1;
+ uint32_t uuid_2;
+ uint32_t uuid_3;
+ uint16_t id;
+};
+
+#define IOCTL_TYPE 0xf0
+
+#define GET_PART_ID _IOWR(IOCTL_TYPE, 0x00, struct endpoint_id)
+#define SEND_SYNC_MSG _IOWR(IOCTL_TYPE, 0x01, struct msg_args)
+
+#define SHARE_INIT _IOR(IOCTL_TYPE, 0x10, unsigned long)
+#define SHARE_DEINIT _IO(IOCTL_TYPE, 0x11)
+#define SHARE_READ _IOW(IOCTL_TYPE, 0x12, struct buf_descr)
+#define SHARE_WRITE _IOW(IOCTL_TYPE, 0x13, struct buf_descr)
+
+#endif /* __BUF_COMMON_H */
diff --git a/drivers/buf/buf_driver.c b/drivers/buf/buf_driver.c
new file mode 100644
index 000000000000..2403709c3757
--- /dev/null
+++ b/drivers/buf/buf_driver.c
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Thin layer to expose FF-A operations towards user space
+ *
+ * The FF-A driver operations are currently not accessible from user space. This
+ * module creates a debugfs interface to expose them. This is only a temporary
+ * workaround, not intended to be merged.
+ *
+ * Copyright (c) 2020-2021, Arm Limited
+ */
+
+#include <asm/uaccess.h>
+#include <linux/arm_ffa.h>
+#include <linux/arm-smcccv1_2.h>
+#include <linux/debugfs.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/printk.h>
+#include <linux/slab.h>
+#include <linux/scatterlist.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <uapi/linux/stat.h>
+
+#include "buf_common.h"
+
+static struct dentry *debugfs_file = NULL;
+static struct ffa_ops *ops = NULL;
+static const ffa_sp_id_t spm_id = 0x8001;
+
+static void *mem_region = NULL;
+static size_t mem_size = 4096;
+struct page **pages;
+static struct sg_table sgt;
+static ffa_mem_handle_t handle;
+static struct endpoint_id sp_id;
+static struct ffa_mem_region_attributes attrs[1] = { 0 };
+
+static int get_part_id(struct endpoint_id *sp_id)
+{
+ int n;
+ struct ffa_partition_info *sp_infos = NULL;
+
+ n = ops->partition_info_get(sp_id->uuid_0, sp_id->uuid_1, sp_id->uuid_2,
+ sp_id->uuid_3, &sp_infos);
+
+ if (n >= 1) {
+ if (n > 1) {
+ pr_warn("Multiple SP with same UUID");
+ }
+ sp_id->id = sp_infos->id;
+ kfree(sp_infos);
+ return 0;
+ }
+ else {
+ pr_err("Partition info get failed");
+ return -1;
+ }
+}
+
+static int send_sync_msg(struct msg_args *args)
+{
+ struct arm_smcccv1_2_return resp;
+
+ resp = ops->sync_msg_send(args->dst_id, args->args[0], args->args[1],
+ args->args[2], args->args[3], args->args[4]);
+
+ if (resp.arg0) {
+ pr_err("FFA response: 0x%llx", resp.arg0);
+ return -1;
+ }
+
+ /* TODO: sort out argument widths */
+ args->args[0] = (uint32_t)resp.arg3;
+ args->args[1] = (uint32_t)resp.arg4;
+ args->args[2] = (uint32_t)resp.arg5;
+ args->args[3] = (uint32_t)resp.arg6;
+ args->args[4] = (uint32_t)resp.arg7;
+
+ return 0;
+}
+
+static int init_share(void)
+{
+ int ret;
+
+ mem_region = kzalloc(mem_size, GFP_KERNEL);
+ if (IS_ERR_OR_NULL(mem_region)) {
+ pr_err("Out of memory");
+ return -ENOMEM;
+ }
+
+ pages = kzalloc(1 * sizeof(void *), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(pages)) {
+ kfree(mem_region);
+ pr_err("Out of memory");
+ return -ENOMEM;
+ }
+
+ pages[0] = virt_to_page(mem_region);
+
+ sg_alloc_table_from_pages(&sgt, pages, 1, 0, 4096, GFP_KERNEL);
+
+ attrs[0].receiver = sp_id.id;
+ attrs[0].attrs = FFA_MEM_RW;
+
+ ret = ops->mem_share(0, 0, attrs, 1, sgt.sgl, sgt.nents, &handle, true);
+ if (ret) {
+ pr_err("Mem share failed");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int close_share(void)
+{
+ int ret;
+
+ ret = ops->mem_reclaim(handle, FFA_KEEP_MEMORY);
+ if (ret) {
+ pr_err("Mem reclaim failed");
+ }
+
+ kfree(mem_region);
+
+ return ret;
+}
+
+static int read_buf(struct buf_descr descr)
+{
+ if (descr.length > 4096) {
+ return -ENOMEM;
+ }
+
+ if(copy_to_user(descr.buf, mem_region, descr.length)) {
+ pr_err("Copy to user failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int write_buf(struct buf_descr descr)
+{
+ if (descr.length > 4096) {
+ return -ENOMEM;
+ }
+
+ if(copy_from_user(mem_region, descr.buf, descr.length)) {
+ pr_err("Copy from user failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+static long ioctl(struct file *fp, unsigned int cmd, unsigned long arg)
+{
+ int ret = 0;
+ void __user *uarg = (void __user *)arg;
+ struct buf_descr descr;
+ struct msg_args args;
+
+ switch (cmd) {
+ case GET_PART_ID:
+ if(copy_from_user(&sp_id, uarg, sizeof(struct endpoint_id))) {
+ pr_err("Copy from user failed");
+ return -1;
+ }
+ ret = get_part_id(&sp_id);
+ if(copy_to_user(uarg, &sp_id, sizeof(struct endpoint_id))) {
+ pr_err("Copy to user failed");
+ return -1;
+ }
+ break;
+ case SEND_SYNC_MSG:
+ if(copy_from_user(&args, uarg, sizeof(struct msg_args))) {
+ pr_err("Copy from user failed");
+ return -1;
+ }
+ ret = send_sync_msg(&args);
+ if(copy_to_user(uarg, &args, sizeof(struct msg_args))) {
+ pr_err("Copy to user failed");
+ return -1;
+ }
+ break;
+ case SHARE_INIT:
+ ret = init_share();
+ if(copy_to_user(uarg, &handle, sizeof(unsigned long))) {
+ pr_err("Copy to user failed");
+ return -1;
+ }
+ break;
+ case SHARE_DEINIT:
+ ret = close_share();
+ break;
+ case SHARE_READ:
+ if(copy_from_user(&descr, uarg, sizeof(struct buf_descr))) {
+ pr_err("Copy from user failed");
+ return -1;
+ }
+ ret = read_buf(descr);
+ break;
+ case SHARE_WRITE:
+ if(copy_from_user(&descr, uarg, sizeof(struct buf_descr))) {
+ pr_err("Copy from user failed");
+ return -1;
+ }
+ ret = write_buf(descr);
+ break;
+ default:
+ pr_warn("Unknown command: %d", cmd);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static const struct file_operations fops = {
+ .unlocked_ioctl = ioctl,
+};
+
+static int mod_init(void)
+{
+ ops = get_ffa_ops();
+
+ if (IS_ERR_OR_NULL(ops)) {
+ pr_err("Cannot get FFA ops");
+ return -1;
+ }
+
+ debugfs_file = debugfs_create_file("buf", S_IRUSR | S_IWUSR, NULL, NULL, &fops);
+
+ if (IS_ERR_OR_NULL(debugfs_file)) {
+ pr_err("Cannot create debugfs file");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void mod_exit(void)
+{
+ debugfs_remove_recursive(debugfs_file);
+}
+
+module_init(mod_init)
+module_exit(mod_exit)
+MODULE_LICENSE("GPL");
--
2.29.2
@@ -0,0 +1,87 @@
From e4bc772637c8aaf4dc6fa64c6d3e3df237ee5e3d Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Mon, 12 Apr 2021 10:44:13 +0100
Subject: [PATCH 2/2] drivers/ffa: modify FFA ABIs with supported convention
SPMC (hafnium) only supports 64-bit variant of FFA_RXTX_MAP and
32-bit variant of FFA_MEM_SHARE.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: I2fbddb7b9bf061b529d4e1f2e93172b1aab73492
Upstream-Status: Inappropriate [will not be submitted as its only required for ACK 5.4]
---
drivers/firmware/ffa/arm_ffa.c | 8 ++++----
include/linux/arm_ffa.h | 4 +++-
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/ffa/arm_ffa.c b/drivers/firmware/ffa/arm_ffa.c
index 21838f8c4632..0524deac1ce7 100644
--- a/drivers/firmware/ffa/arm_ffa.c
+++ b/drivers/firmware/ffa/arm_ffa.c
@@ -7,7 +7,7 @@
* residing on other Secure Partitions or Virtual Machines managed by any FFA
* compliant firmware framework.
*
- * Copyright (C) 2019, 2020 Arm Ltd.
+ * Copyright (C) 2019 - 2021 Arm Ltd.
*/
#define DEBUG
@@ -171,7 +171,7 @@ static int ffa_share_init_frag(phys_addr_t buffer, u32 buffer_size,
struct arm_smcccv1_2_return smccc_return;
smccc_return =
- arm_ffa_smccc(FFA_MEM_SHARE_64, total_len, fragment_len, buffer,
+ arm_ffa_smccc(FFA_MEM_SHARE_32, total_len, fragment_len, buffer,
buffer_size, 0, 0, 0);
while (smccc_return.arg0 != FFA_SUCCESS_32) {
@@ -649,7 +649,7 @@ static int ffa_rxtx_map(uintptr_t tx_page, uintptr_t rx_page)
{
struct arm_smcccv1_2_return map_return;
- map_return = arm_ffa_smccc(FFA_RXTX_MAP_32, tx_page,
+ map_return = arm_ffa_smccc(FFA_RXTX_MAP_64, tx_page,
rx_page, 1, 0, 0, 0, 0);
if (map_return.arg0 == FFA_ERROR_32) {
@@ -716,7 +716,7 @@ static int ffa_probe(struct platform_device *pdev)
/* Initialize VM ID. */
ret = ffa_id_get(&vm_id);
if (ret) {
- pr_warn("%s: failed to obtain own FFA endpoint ID\n", __func__);
+ pr_err("%s: failed to obtain own FFA endpoint ID\n", __func__);
return ret;
}
diff --git a/include/linux/arm_ffa.h b/include/linux/arm_ffa.h
index d3c80b7f9e07..9a8b32e2c846 100644
--- a/include/linux/arm_ffa.h
+++ b/include/linux/arm_ffa.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C) 2019, 2020 Arm Ltd.
+ * Copyright (C) 2019 - 2021 Arm Ltd.
*/
#ifndef __LINUX_ARM_FFA_H
@@ -13,6 +13,7 @@
#define FFA_FEATURES_32 0x84000064
#define FFA_RX_RELEASE_32 0x84000065
#define FFA_RXTX_MAP_32 0x84000066
+#define FFA_RXTX_MAP_64 0xc4000066
#define FFA_PARTITION_INFO_GET_32 0x84000068
#define FFA_ID_GET_32 0x84000069
@@ -25,6 +26,7 @@
#define FFA_MEM_OP_PAUSE_32 0x84000078
#define FFA_MEM_OP_RESUME_32 0x84000079
+#define FFA_MEM_SHARE_32 0x84000073
#define FFA_MEM_SHARE_64 0xC4000073
#define FFA_MEM_FRAG_RX_32 0x8400007A
--
2.29.2