mirror of
https://git.yoctoproject.org/meta-arm
synced 2026-07-16 03:47: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:
committed by
Tushar Khandelwal
parent
9d1724c3d4
commit
5d47d3f9db
@@ -83,6 +83,8 @@ SRC_URI_append_tc0 = " \
|
||||
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://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 \
|
||||
"
|
||||
|
||||
#
|
||||
|
||||
+357
@@ -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
|
||||
|
||||
+87
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user