From mboxrd@z Thu Jan 1 00:00:00 1970 From: Igor Opaniuk Date: Thu, 21 Jan 2021 12:41:14 +0200 Subject: [PATCH v5 3/4] drivers: tee: sandbox: add rpc test ta emulation In-Reply-To: References: <20210120175530.92057-1-igor.opaniuk@gmail.com> <20210120175530.92057-4-igor.opaniuk@gmail.com> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de HI Etienne, On Thu, Jan 21, 2021 at 9:39 AM Etienne Carriere wrote: > > Hi Igor, > > On Wed, 20 Jan 2021 at 18:56, Igor Opaniuk wrote: > > > > From: Igor Opaniuk > > > > This adds support for RPC test trusted application emulation, which > > permits to test reverse RPC calls to TEE supplicant. Currently it covers > > requests to the I2C bus from TEE. > > > > Signed-off-by: Igor Opaniuk > > Reviewed-by: Simon Glass > > --- > > > > (no changes since v1) > > > > drivers/tee/Makefile | 2 + > > drivers/tee/optee/Kconfig | 9 ++ > > drivers/tee/sandbox.c | 143 +++++++++++++++++++++++++++++++- > > include/tee/optee_ta_rpc_test.h | 28 +++++++ > > 4 files changed, 178 insertions(+), 4 deletions(-) > > create mode 100644 include/tee/optee_ta_rpc_test.h > > > > diff --git a/drivers/tee/Makefile b/drivers/tee/Makefile > > index 5c8ffdbce8..ff844195ae 100644 > > --- a/drivers/tee/Makefile > > +++ b/drivers/tee/Makefile > > @@ -2,5 +2,7 @@ > > > > obj-y += tee-uclass.o > > obj-$(CONFIG_SANDBOX) += sandbox.o > > +obj-$(CONFIG_OPTEE_TA_RPC_TEST) += optee/supplicant.o > > +obj-$(CONFIG_OPTEE_TA_RPC_TEST) += optee/i2c.o > > I think this line should move to drivers/tee/optee/Makefile for consistency. Well, what we do here is testing TEE supplicant from TEE sandbox driver. So this is why I pull that bits and pieces from OP-TEE driver, however OP-TEE driver itself isn't compiled (CONFIG_OPTEE=n when CONFIG_SANDBOX=y). I don't either like this idea, but currently that's the only way to add some RPC test coverage that was requested in v1. CONFIG_OPTEE_TA_RPC_TEST is currently supposed to be used only in sandbox setups (for testing RPC call paths with DM tests). > > > > obj-$(CONFIG_OPTEE) += optee/ > > obj-y += broadcom/ > > diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig > > index d489834df9..65622f30b1 100644 > > --- a/drivers/tee/optee/Kconfig > > +++ b/drivers/tee/optee/Kconfig > > @@ -22,6 +22,15 @@ config OPTEE_TA_AVB > > The TA can support the "avb" subcommands "read_rb", "write"rb" > > and "is_unlocked". > > > > +config OPTEE_TA_RPC_TEST > > + bool "Support RPC TEST TA" > > + depends on SANDBOX_TEE > > + default y > > + help > > + Enables support for RPC test trusted application emulation, which > > + permits to test reverse RPC calls to TEE supplicant. Should > > + be used only in sandbox env. > > + > > endmenu > > > > endif > > diff --git a/drivers/tee/sandbox.c b/drivers/tee/sandbox.c > > index e1ba027fd6..d075701b4e 100644 > > --- a/drivers/tee/sandbox.c > > +++ b/drivers/tee/sandbox.c > > @@ -7,11 +7,15 @@ > > #include > > #include > > #include > > +#include > > + > > +#include "optee/optee_msg.h" > > +#include "optee/optee_private.h" > > > > /* > > * The sandbox tee driver tries to emulate a generic Trusted Exectution > > - * Environment (TEE) with the Trusted Application (TA) OPTEE_TA_AVB > > - * available. > > + * Environment (TEE) with the Trusted Applications (TA) OPTEE_TA_AVB and > > + * OPTEE_TA_RPC_TEST available. > > */ > > > > static const u32 pstorage_max = 16; > > @@ -32,7 +36,38 @@ struct ta_entry { > > struct tee_param *params); > > }; > > > > -#ifdef CONFIG_OPTEE_TA_AVB > > +static int get_msg_arg(struct udevice *dev, uint num_params, > > + struct tee_shm **shmp, struct optee_msg_arg **msg_arg) > > +{ > > + int rc; > > + struct optee_msg_arg *ma; > > + > > + rc = __tee_shm_add(dev, OPTEE_MSG_NONCONTIG_PAGE_SIZE, NULL, > > + OPTEE_MSG_GET_ARG_SIZE(num_params), TEE_SHM_ALLOC, > > + shmp); > > + if (rc) > > + return rc; > > + > > + ma = (*shmp)->addr; > > + memset(ma, 0, OPTEE_MSG_GET_ARG_SIZE(num_params)); > > + ma->num_params = num_params; > > + *msg_arg = ma; > > + > > + return 0; > > +} > > + > > +void *optee_alloc_and_init_page_list(void *buf, ulong len, > > + u64 *phys_buf_ptr) > > +{ > > + /* > > + * An empty stub is added just to fix linking issues. > > + * This function isn't supposed to be called in sandbox > > + * setup, otherwise replace this with a proper > > + * implementation from optee/core.c > > + */ > > + return NULL; > > +} > > + > > static u32 get_attr(uint n, uint num_params, struct tee_param *params) > > { > > if (n >= num_params) > > @@ -63,6 +98,7 @@ bad_params: > > return TEE_ERROR_BAD_PARAMETERS; > > } > > > > +#ifdef CONFIG_OPTEE_TA_AVB > > static u32 ta_avb_open_session(struct udevice *dev, uint num_params, > > struct tee_param *params) > > { > > @@ -214,7 +250,100 @@ static u32 ta_avb_invoke_func(struct udevice *dev, u32 func, uint num_params, > > return TEE_ERROR_NOT_SUPPORTED; > > } > > } > > -#endif /*OPTEE_TA_AVB*/ > > +#endif /* OPTEE_TA_AVB */ > > + > > +#ifdef CONFIG_OPTEE_TA_RPC_TEST > > +static u32 ta_rpc_test_open_session(struct udevice *dev, uint num_params, > > + struct tee_param *params) > > +{ > > + /* > > + * We don't expect additional parameters when opening a session to > > + * this TA. > > + */ > > + return check_params(TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE, > > + TEE_PARAM_ATTR_TYPE_NONE, TEE_PARAM_ATTR_TYPE_NONE, > > + num_params, params); > > +} > > + > > +static void fill_i2c_rpc_params(struct optee_msg_arg *msg_arg, u64 bus_num, > > + u64 chip_addr, u64 op, > > + struct tee_param_memref memref) > > +{ > > + msg_arg->params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; > > + msg_arg->params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT; > > + msg_arg->params[2].attr = OPTEE_MSG_ATTR_TYPE_RMEM_INOUT; > > + msg_arg->params[3].attr = OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT; > > + > > + /* trigger I2C services of TEE supplicant */ > > + msg_arg->cmd = OPTEE_MSG_RPC_CMD_I2C_TRANSFER; > > + > > + msg_arg->params[0].u.value.a = op; > > + msg_arg->params[0].u.value.b = bus_num; > > + msg_arg->params[0].u.value.c = chip_addr; > > + > > + /* buffer to read/write data */ > > + msg_arg->params[2].u.rmem.shm_ref = (ulong)memref.shm; > > + msg_arg->params[2].u.rmem.size = memref.size; > > + msg_arg->params[2].u.rmem.offs = memref.shm_offs; > > + > > + msg_arg->num_params = 4; > > +} > > + > > +static u32 ta_rpc_test_invoke_func(struct udevice *dev, u32 func, > > + uint num_params, > > + struct tee_param *params) > > +{ > > + struct tee_shm *shm; > > + struct tee_param_memref memref_data; > > + struct optee_msg_arg *msg_arg; > > + int chip_addr, bus_num, op; > > + int res; > > + > > + res = check_params(TEE_PARAM_ATTR_TYPE_VALUE_INPUT, > > + TEE_PARAM_ATTR_TYPE_MEMREF_INOUT, > > + TEE_PARAM_ATTR_TYPE_NONE, > > + TEE_PARAM_ATTR_TYPE_NONE, > > + num_params, params); > > + if (res) > > + return TEE_ERROR_BAD_PARAMETERS; > > + > > + bus_num = params[0].u.value.a; > > + chip_addr = params[0].u.value.b; > > + memref_data = params[1].u.memref; > > + > > + switch (func) { > > + case TA_RPC_TEST_CMD_I2C_READ: > > + op = OPTEE_MSG_RPC_CMD_I2C_TRANSFER_RD; > > + break; > > + case TA_RPC_TEST_CMD_I2C_WRITE: > > + op = OPTEE_MSG_RPC_CMD_I2C_TRANSFER_WR; > > + break; > > + default: > > + return TEE_ERROR_NOT_SUPPORTED; > > + } > > + > > + /* > > + * Fill params for an RPC call to tee supplicant > > + */ > > + res = get_msg_arg(dev, 4, &shm, &msg_arg); > > + if (res) > > + goto bad; > > + > > + fill_i2c_rpc_params(msg_arg, bus_num, chip_addr, op, memref_data); > > + > > + /* Make an RPC call to tee supplicant */ > > + optee_suppl_cmd(dev, shm, 0); > > + res = msg_arg->ret; > > + > > +bad: > > maye rename to out since not a error only path. ok, will do > > > + tee_shm_free(shm); > > + > > + if (res) > > + return res; > > + > > + return TEE_SUCCESS; > > 'return res;' will do the job. sure, will fix > > > +} > > +#endif /* CONFIG_OPTEE_TA_RPC_TEST */ > > > > static const struct ta_entry ta_entries[] = { > > #ifdef CONFIG_OPTEE_TA_AVB > > @@ -223,6 +352,12 @@ static const struct ta_entry ta_entries[] = { > > .invoke_func = ta_avb_invoke_func, > > }, > > #endif > > +#ifdef CONFIG_OPTEE_TA_RPC_TEST > > + { .uuid = TA_RPC_TEST_UUID, > > + .open_session = ta_rpc_test_open_session, > > + .invoke_func = ta_rpc_test_invoke_func, > > + }, > > +#endif > > }; > > > > static void sandbox_tee_get_version(struct udevice *dev, > > diff --git a/include/tee/optee_ta_rpc_test.h b/include/tee/optee_ta_rpc_test.h > > new file mode 100644 > > index 0000000000..cae2fb04b4 > > --- /dev/null > > +++ b/include/tee/optee_ta_rpc_test.h > > @@ -0,0 +1,28 @@ > > +/* SPDX-License-Identifier: BSD-2-Clause */ > > +/* Copyright (c) 2020 Foundries Ltd */ > > + > > +#ifndef __TA_RPC_TEST_H > > +#define __TA_RPC_TEST_H > > + > > +#define TA_RPC_TEST_UUID { 0x48420575, 0x96ca, 0x401a, \ > > + { 0x89, 0x91, 0x1e, 0xfd, 0xce, 0xbd, 0x7d, 0x04 } } > > + > > +/* > > + * Does a reverse RPC call for I2C read > > + * > > + * in params[0].value.a: bus number > > + * in params[0].value.b: chip address > > Should maybe consider the so-called 'i2c control flags' in the test > (i.?. 7 or 10 bit i2c address) since these flags are checked in the > RPC implementation. Yes, makes sense. > > > + * inout params[1].u.memref: buffer to read data > > + */ > > +#define TA_RPC_TEST_CMD_I2C_READ 0 > > + > > +/* > > + * Does a reverse RPC call for I2C write > > + * > > + * in params[0].value.a: bus number > > + * in params[0].value.b: chip address > > + * inout params[1].u.memref: buffer with data to write > > + */ > > +#define TA_RPC_TEST_CMD_I2C_WRITE 1 > > + > > +#endif /* __TA_RPC_TEST_H */ > > -- > > 2.25.1 > > -- Best regards - Freundliche Gr?sse - Meilleures salutations Igor Opaniuk Embedded Software Engineer T: +380 938364067 E: igor.opaniuk at foundries.io W: www.foundries.io