mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
misc: mods: Add OP-TEE TA communication support
This patch adds OP-TEE TA support in the mods driver using Linux kernel TEE API. Jira OPTEE-40 Signed-off-by: Jason Li (SW-TEGRA) <jasl@nvidia.com> Change-Id: I75338f3b6941419acc0745b374c79035a58c98c7 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2708753 (cherry picked from commit 33520bc012e8e0b5cfb5de341ff8ff488df8a68f) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2709426 Reviewed-by: Rohith Talluri <sitalluri@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: svc-mobile-cert <svc-mobile-cert@nvidia.com> Reviewed-by: Chris Dragan <kdragan@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Tested-by: Rohith Talluri <sitalluri@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
Laxman Dewangan
parent
14ab31a527
commit
aa01c9a907
@@ -19,6 +19,7 @@ mods-$(CONFIG_DEBUG_FS) += mods_debugfs.o
|
||||
mods-$(CONFIG_DMA_ENGINE) += mods_dma.o
|
||||
mods-$(CONFIG_NET) += mods_netdevice.o
|
||||
mods-$(CONFIG_ARCH_TEGRA) += mods_oist.o
|
||||
mods-$(CONFIG_OPTEE) += mods_optee.o
|
||||
mods-$(CONFIG_PCI) += mods_pci.o
|
||||
mods-$(CONFIG_ARCH_TEGRA_19x_SOC) += mods_ras.o
|
||||
mods-$(CONFIG_ARCH_TEGRA) += mods_smmu_drv.o
|
||||
|
||||
@@ -715,6 +715,12 @@ int esc_mods_tegra_prod_set_prod_exact(struct mods_client *client,
|
||||
int esc_mods_send_trustzone_msg(struct mods_client *client,
|
||||
struct MODS_TZ_PARAMS *p);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OPTEE
|
||||
/* OP-TEE TA call */
|
||||
int esc_mods_invoke_optee_ta(struct mods_client *client,
|
||||
struct MODS_OPTEE_PARAMS *p);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
@@ -2585,6 +2585,13 @@ static long mods_krnl_ioctl(struct file *fp,
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OPTEE
|
||||
case MODS_ESC_INVOKE_OPTEE_TA:
|
||||
MODS_IOCTL(MODS_ESC_INVOKE_OPTEE_TA,
|
||||
esc_mods_invoke_optee_ta, MODS_OPTEE_PARAMS);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MODS_ESC_OIST_STATUS:
|
||||
MODS_IOCTL(MODS_ESC_OIST_STATUS,
|
||||
esc_mods_oist_status, MODS_TEGRA_OIST_STATUS);
|
||||
|
||||
113
drivers/misc/mods/mods_optee.c
Normal file
113
drivers/misc/mods/mods_optee.c
Normal file
@@ -0,0 +1,113 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*/
|
||||
|
||||
#include "mods_internal.h"
|
||||
|
||||
#include <linux/tee_drv.h>
|
||||
#include <linux/uuid.h>
|
||||
|
||||
static const uuid_t mods_ta_uuid =
|
||||
UUID_INIT(0xf14e9858, 0x1526, 0x4935,
|
||||
0xb1, 0x92, 0x4d, 0xf3, 0x86, 0x4f, 0x1f, 0xf9);
|
||||
|
||||
static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
|
||||
{
|
||||
if (ver->impl_id == TEE_IMPL_ID_OPTEE)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int esc_mods_invoke_optee_ta(struct mods_client *client,
|
||||
struct MODS_OPTEE_PARAMS *p)
|
||||
{
|
||||
int ret;
|
||||
u32 session_id;
|
||||
u8 *temp_buf;
|
||||
struct tee_context *ctx;
|
||||
struct tee_ioctl_open_session_arg sess_arg;
|
||||
struct tee_ioctl_invoke_arg invoke_arg;
|
||||
struct tee_shm *shm;
|
||||
struct tee_param params[4];
|
||||
|
||||
/* Open context with TEE driver */
|
||||
ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL);
|
||||
if (IS_ERR(ctx)) {
|
||||
ret = -ENODEV;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Open session with TA */
|
||||
memset(&sess_arg, 0, sizeof(sess_arg));
|
||||
export_uuid(sess_arg.uuid, &mods_ta_uuid);
|
||||
sess_arg.clnt_login = TEE_IOCTL_LOGIN_PUBLIC;
|
||||
sess_arg.num_params = 0;
|
||||
|
||||
ret = tee_client_open_session(ctx, &sess_arg, NULL);
|
||||
if ((ret < 0) || (sess_arg.ret != 0)) {
|
||||
cl_info("tee_client_open_session failed, err: %x\n", sess_arg.ret);
|
||||
ret = -EINVAL;
|
||||
goto out_ctx;
|
||||
}
|
||||
session_id = sess_arg.session;
|
||||
|
||||
/* Allocate dynamic shared memory with TA */
|
||||
shm = tee_shm_alloc_kernel_buf(ctx, p->buf_size);
|
||||
if (IS_ERR(shm)) {
|
||||
cl_info("tee_shm_alloc_kernel_buf failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto out_session;
|
||||
}
|
||||
|
||||
/* Invoke comannd of TA */
|
||||
memset(&invoke_arg, 0, sizeof(invoke_arg));
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
|
||||
invoke_arg.func = p->command_id;
|
||||
invoke_arg.session = session_id;
|
||||
invoke_arg.num_params = 4;
|
||||
|
||||
params[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT;
|
||||
params[0].u.memref.shm = shm;
|
||||
params[0].u.memref.size = p->buf_size;
|
||||
params[0].u.memref.shm_offs = 0;
|
||||
params[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
|
||||
|
||||
temp_buf = tee_shm_get_va(shm, 0);
|
||||
if (IS_ERR(temp_buf)) {
|
||||
cl_info("tee_shm_get_va failed\n");
|
||||
ret = PTR_ERR(temp_buf);
|
||||
goto out_shm;
|
||||
}
|
||||
memmove(temp_buf, p->buf, p->buf_size);
|
||||
|
||||
ret = tee_client_invoke_func(ctx, &invoke_arg, params);
|
||||
if (ret < 0) {
|
||||
cl_info("tee_client_invoke_func failed.\n");
|
||||
goto out_shm;
|
||||
}
|
||||
memmove(p->buf, temp_buf, p->buf_size);
|
||||
p->tee_ret = invoke_arg.ret;
|
||||
p->out_a = params[1].u.value.a;
|
||||
p->out_b = params[1].u.value.b;
|
||||
|
||||
out_shm:
|
||||
tee_shm_free(shm);
|
||||
out_session:
|
||||
tee_client_close_session(ctx, session_id);
|
||||
out_ctx:
|
||||
tee_client_close_context(ctx);
|
||||
fail:
|
||||
return ret;
|
||||
}
|
||||
@@ -1806,6 +1806,23 @@ struct MODS_TZ_PARAMS {
|
||||
int status;
|
||||
};
|
||||
|
||||
#define MAX_OPTEE_BUFFER_SIZE 512
|
||||
/* Used by MODS_ESC_INVOKE_OPTEE_TA.
|
||||
*
|
||||
* Available only on Tegra.
|
||||
*/
|
||||
struct MODS_OPTEE_PARAMS {
|
||||
/* IN */
|
||||
__u8 buf[MAX_OPTEE_BUFFER_SIZE];
|
||||
__u32 buf_size;
|
||||
__u32 command_id;
|
||||
|
||||
/* OUT */
|
||||
__u32 tee_ret;
|
||||
__u32 out_a;
|
||||
__u32 out_b;
|
||||
};
|
||||
|
||||
/* Used by MODS_ESC_OIST_STATUS ioctl.
|
||||
*
|
||||
* Available only on Tegra.
|
||||
@@ -2023,5 +2040,6 @@ struct MODS_TEGRA_OIST_STATUS {
|
||||
#define MODS_ESC_GET_ACPI_DEV_CHILDREN MODSIO(WR, 138, MODS_GET_ACPI_DEV_CHILDREN)
|
||||
#define MODS_ESC_SEND_TZ_MSG MODSIO(WR, 139, MODS_TZ_PARAMS)
|
||||
#define MODS_ESC_OIST_STATUS MODSIO(WR, 140, MODS_TEGRA_OIST_STATUS)
|
||||
#define MODS_ESC_INVOKE_OPTEE_TA MODSIO(WR, 141, MODS_OPTEE_PARAMS)
|
||||
|
||||
#endif /* _UAPI_MODS_H_ */
|
||||
|
||||
Reference in New Issue
Block a user