diff --git a/meta-arm-bsp/recipes-kernel/linux/linux-arm-platforms.inc b/meta-arm-bsp/recipes-kernel/linux/linux-arm-platforms.inc index b8526440..39cde7a0 100644 --- a/meta-arm-bsp/recipes-kernel/linux/linux-arm-platforms.inc +++ b/meta-arm-bsp/recipes-kernel/linux/linux-arm-platforms.inc @@ -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 \ " # diff --git a/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.4/tc0/0016-drivers-buf-Add-userspace-ff-a-driver-buf-and-add-to.patch b/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.4/tc0/0016-drivers-buf-Add-userspace-ff-a-driver-buf-and-add-to.patch new file mode 100644 index 00000000..f6768cbb --- /dev/null +++ b/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.4/tc0/0016-drivers-buf-Add-userspace-ff-a-driver-buf-and-add-to.patch @@ -0,0 +1,357 @@ +From 1d85316ed0571300c12216c9cafb634db6fe4a8a Mon Sep 17 00:00:00 2001 +From: Ben Horgan +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 +Signed-off-by: Ben Horgan +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 ++#include ++#else ++#include ++#include ++#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 + diff --git a/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.4/tc0/0017-drivers-ffa-modify-FFA-ABIs-with-supported-conventio.patch b/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.4/tc0/0017-drivers-ffa-modify-FFA-ABIs-with-supported-conventio.patch new file mode 100644 index 00000000..91a3dc47 --- /dev/null +++ b/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.4/tc0/0017-drivers-ffa-modify-FFA-ABIs-with-supported-conventio.patch @@ -0,0 +1,87 @@ +From e4bc772637c8aaf4dc6fa64c6d3e3df237ee5e3d Mon Sep 17 00:00:00 2001 +From: Arunachalam Ganapathy +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 +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 +