diff mbox series

[v5,4/4] test: dm: tee: extend with RPC test

Message ID 20210120175530.92057-5-igor.opaniuk@gmail.com
State Superseded
Delegated to: Tom Rini
Headers show
Series OP-TEE I2C trampoline and associated tests | expand

Commit Message

Igor Opaniuk Jan. 20, 2021, 5:55 p.m. UTC
From: Igor Opaniuk <igor.opaniuk@foundries.io>

Extend existing DM tee tests adding test coverage for reverse RPC calls.
Currently this commit only adds tests for I2C requests from TEE driver
to TEE supplicant, for instance reading/writing data to emulated i2c
eeprom defines in standard sandbox test device tree
(arch/sandbox/dts/test.dtb):

=> i2c bus
Bus 0:	i2c@0  (active 0)
   2c: eeprom@2c, offset len 1, flags 0
   ...

Running TEE tests:
=> ut dm tee
Test: dm_test_tee: tee.c
Test: dm_test_tee: tee.c (flat tree)
Failures: 0

Signed-off-by: Igor Opaniuk <igor.opaniuk@foundries.io>
Reviewed-by: Simon Glass <sjg@chromium.org>

---

(no changes since v1)

 test/dm/tee.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 102 insertions(+), 5 deletions(-)

Comments

Etienne Carriere Jan. 21, 2021, 8 a.m. UTC | #1
Hello Igor,

On Wed, 20 Jan 2021 at 18:56, Igor Opaniuk <igor.opaniuk@gmail.com> wrote:
>
> From: Igor Opaniuk <igor.opaniuk@foundries.io>
>
> Extend existing DM tee tests adding test coverage for reverse RPC calls.
> Currently this commit only adds tests for I2C requests from TEE driver
> to TEE supplicant, for instance reading/writing data to emulated i2c
> eeprom defines in standard sandbox test device tree
> (arch/sandbox/dts/test.dtb):
>
> => i2c bus
> Bus 0:  i2c@0  (active 0)
>    2c: eeprom@2c, offset len 1, flags 0
>    ...
>
> Running TEE tests:
> => ut dm tee
> Test: dm_test_tee: tee.c
> Test: dm_test_tee: tee.c (flat tree)
> Failures: 0
>
> Signed-off-by: Igor Opaniuk <igor.opaniuk@foundries.io>
> Reviewed-by: Simon Glass <sjg@chromium.org>
>
> ---
>
> (no changes since v1)
>
>  test/dm/tee.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 102 insertions(+), 5 deletions(-)
>
> diff --git a/test/dm/tee.c b/test/dm/tee.c
> index ddbdcfb0cf..51ffb4e4a9 100644
> --- a/test/dm/tee.c
> +++ b/test/dm/tee.c
> @@ -13,11 +13,12 @@
>  #include <test/test.h>
>  #include <test/ut.h>
>  #include <tee/optee_ta_avb.h>
> +#include <tee/optee_ta_rpc_test.h>
>
> -static int open_session(struct udevice *dev, u32 *session)
> +static int open_session(struct udevice *dev, u32 *session,
> +                       struct tee_optee_ta_uuid uuid)

maybe pass a pointer to the uuid.
or maybe not, uuid is only 16 bytes....

>  {
>         struct tee_open_session_arg arg;
> -       const struct tee_optee_ta_uuid uuid = TA_AVB_UUID;
>         int rc;
>
>         memset(&arg, 0, sizeof(arg));
> @@ -32,7 +33,7 @@ static int open_session(struct udevice *dev, u32 *session)
>         return 0;
>  }
>
> -static int invoke_func(struct udevice *dev, u32 session)
> +static int invoke_func_avb(struct udevice *dev, u32 session)
>  {
>         struct tee_param param = { .attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT };
>         struct tee_invoke_arg arg;
> @@ -47,6 +48,47 @@ static int invoke_func(struct udevice *dev, u32 session)
>         return 0;
>  }
>
> +static int invoke_func_rpc_test(struct udevice *dev, u32 session,
> +                               u64 op, u64 busnum, u64 chip_addr,
> +                               u8 *buf, size_t buf_size)
> +{
> +       struct tee_param param[2];
> +       struct tee_invoke_arg arg;
> +       struct tee_shm *shm_buf;
> +       int rc;
> +
> +       memset(&arg, 0, sizeof(arg));
> +       arg.session = session;
> +       arg.func = op;
> +
> +       rc = tee_shm_alloc(dev, buf_size,
> +                          TEE_SHM_ALLOC, &shm_buf);
> +       if (rc)
> +               return rc;
> +
> +       if (op == TA_RPC_TEST_CMD_I2C_WRITE)
> +               memcpy(shm_buf->addr, buf, buf_size);
> +
> +       memset(param, 0, sizeof(param));
> +       param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
> +       param[0].u.value.a = busnum;
> +       param[0].u.value.b = chip_addr;
> +       param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
> +       param[1].u.memref.shm = shm_buf;
> +       param[1].u.memref.size = buf_size;
> +
> +       if (tee_invoke_func(dev, &arg, 2, param) || arg.ret) {
> +               goto out;
> +               rc = -1;

Looks like those lines shall be swapped!

> +       }
> +
> +       if (op == TA_RPC_TEST_CMD_I2C_READ)
> +               memcpy(buf, shm_buf->addr, buf_size);
> +out:
> +       tee_shm_free(shm_buf);
> +       return rc;
> +}
> +
>  static int match(struct tee_version_data *vers, const void *data)
>  {
>         return vers->gen_caps & TEE_GEN_CAP_GP;
> @@ -62,6 +104,7 @@ static int test_tee(struct unit_test_state *uts, struct test_tee_vars *vars)
>         struct tee_version_data vers;
>         struct udevice *dev;
>         struct sandbox_tee_state *state;
> +       struct tee_optee_ta_uuid avb_uuid = TA_AVB_UUID;
>         u32 session = 0;
>         int rc;
>         u8 data[128];
> @@ -71,11 +114,11 @@ static int test_tee(struct unit_test_state *uts, struct test_tee_vars *vars)
>         state = dev_get_priv(dev);
>         ut_assert(!state->session);
>
> -       rc = open_session(dev, &session);
> +       rc = open_session(dev, &session, avb_uuid);
>         ut_assert(!rc);
>         ut_assert(session == state->session);
>
> -       rc = invoke_func(dev, session);
> +       rc = invoke_func_avb(dev, session);
>         ut_assert(!rc);
>
>         rc = tee_close_session(dev, session);
> @@ -103,11 +146,65 @@ static int test_tee(struct unit_test_state *uts, struct test_tee_vars *vars)
>         return 0;
>  }
>
> +#define I2C_BUF_SIZE 64
> +
> +static int test_tee_rpc(struct unit_test_state *uts)
> +{
> +       struct tee_version_data vers;
> +       struct udevice *dev;
> +       struct sandbox_tee_state *state;
> +       struct tee_optee_ta_uuid rpc_test_uuid = TA_RPC_TEST_UUID;
> +       u32 session = 0;
> +       int rc;
> +
> +       char *test_str = "Test string";
> +       u8 data[I2C_BUF_SIZE] = {0};
> +       u8 data_from_eeprom[I2C_BUF_SIZE] = {0};
> +
> +       /* Use sandbox I2C EEPROM emulation; bus: 0, chip: 0x2c */
> +       u64 bus = 0;
> +       u64 chip = 0x2c;
> +
> +       dev = tee_find_device(NULL, match, NULL, &vers);
> +       ut_assert(dev);
> +       state = dev_get_priv(dev);
> +       ut_assert(!state->session);
> +
> +       /* Test RPC call asking for I2C sevice */
> +       rc = open_session(dev, &session, rpc_test_uuid);
> +       ut_assert(!rc);
> +       ut_assert(session == state->session);
> +
> +       /* Write buffer */
> +       strncpy((char *)data, test_str, strlen(test_str));
> +       rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_WRITE,
> +                                 bus, chip, data, sizeof(data));
> +       ut_assert(!rc);
> +
> +       /* Read buffer */
> +       rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_READ,
> +                                 bus, chip, data_from_eeprom,
> +                                 sizeof(data_from_eeprom));
> +       ut_assert(!rc);
> +
> +       /* Compare */
> +       ut_assert(!memcmp(data, data_from_eeprom, sizeof(data)));
> +
> +       rc = tee_close_session(dev, session);
> +       ut_assert(!rc);
> +       ut_assert(!state->session);
> +
> +       return 0;
> +}
> +
>  static int dm_test_tee(struct unit_test_state *uts)
>  {
>         struct test_tee_vars vars = { NULL, NULL };
>         int rc = test_tee(uts, &vars);
>
> +       if (IS_ENABLED(CONFIG_OPTEE_TA_RPC_TEST))
> +               rc = test_tee_rpc(uts);
> +

This scratches return code from test_tee().

Best regards,
Etienne

>         /* In case test_tee() asserts these may still remain allocated */
>         tee_shm_free(vars.reg_shm);
>         tee_shm_free(vars.alloc_shm);
> --
> 2.25.1
>
Igor Opaniuk Jan. 21, 2021, 10:44 a.m. UTC | #2
Hi Etienne,

On Thu, Jan 21, 2021 at 10:00 AM Etienne Carriere
<etienne.carriere@linaro.org> wrote:
>
> Hello Igor,
>
> On Wed, 20 Jan 2021 at 18:56, Igor Opaniuk <igor.opaniuk@gmail.com> wrote:
> >
> > From: Igor Opaniuk <igor.opaniuk@foundries.io>
> >
> > Extend existing DM tee tests adding test coverage for reverse RPC calls.
> > Currently this commit only adds tests for I2C requests from TEE driver
> > to TEE supplicant, for instance reading/writing data to emulated i2c
> > eeprom defines in standard sandbox test device tree
> > (arch/sandbox/dts/test.dtb):
> >
> > => i2c bus
> > Bus 0:  i2c@0  (active 0)
> >    2c: eeprom@2c, offset len 1, flags 0
> >    ...
> >
> > Running TEE tests:
> > => ut dm tee
> > Test: dm_test_tee: tee.c
> > Test: dm_test_tee: tee.c (flat tree)
> > Failures: 0
> >
> > Signed-off-by: Igor Opaniuk <igor.opaniuk@foundries.io>
> > Reviewed-by: Simon Glass <sjg@chromium.org>
> >
> > ---
> >
> > (no changes since v1)
> >
> >  test/dm/tee.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 102 insertions(+), 5 deletions(-)
> >
> > diff --git a/test/dm/tee.c b/test/dm/tee.c
> > index ddbdcfb0cf..51ffb4e4a9 100644
> > --- a/test/dm/tee.c
> > +++ b/test/dm/tee.c
> > @@ -13,11 +13,12 @@
> >  #include <test/test.h>
> >  #include <test/ut.h>
> >  #include <tee/optee_ta_avb.h>
> > +#include <tee/optee_ta_rpc_test.h>
> >
> > -static int open_session(struct udevice *dev, u32 *session)
> > +static int open_session(struct udevice *dev, u32 *session,
> > +                       struct tee_optee_ta_uuid uuid)
>
> maybe pass a pointer to the uuid.
> or maybe not, uuid is only 16 bytes....
>
> >  {
> >         struct tee_open_session_arg arg;
> > -       const struct tee_optee_ta_uuid uuid = TA_AVB_UUID;
> >         int rc;
> >
> >         memset(&arg, 0, sizeof(arg));
> > @@ -32,7 +33,7 @@ static int open_session(struct udevice *dev, u32 *session)
> >         return 0;
> >  }
> >
> > -static int invoke_func(struct udevice *dev, u32 session)
> > +static int invoke_func_avb(struct udevice *dev, u32 session)
> >  {
> >         struct tee_param param = { .attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT };
> >         struct tee_invoke_arg arg;
> > @@ -47,6 +48,47 @@ static int invoke_func(struct udevice *dev, u32 session)
> >         return 0;
> >  }
> >
> > +static int invoke_func_rpc_test(struct udevice *dev, u32 session,
> > +                               u64 op, u64 busnum, u64 chip_addr,
> > +                               u8 *buf, size_t buf_size)
> > +{
> > +       struct tee_param param[2];
> > +       struct tee_invoke_arg arg;
> > +       struct tee_shm *shm_buf;
> > +       int rc;
> > +
> > +       memset(&arg, 0, sizeof(arg));
> > +       arg.session = session;
> > +       arg.func = op;
> > +
> > +       rc = tee_shm_alloc(dev, buf_size,
> > +                          TEE_SHM_ALLOC, &shm_buf);
> > +       if (rc)
> > +               return rc;
> > +
> > +       if (op == TA_RPC_TEST_CMD_I2C_WRITE)
> > +               memcpy(shm_buf->addr, buf, buf_size);
> > +
> > +       memset(param, 0, sizeof(param));
> > +       param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
> > +       param[0].u.value.a = busnum;
> > +       param[0].u.value.b = chip_addr;
> > +       param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
> > +       param[1].u.memref.shm = shm_buf;
> > +       param[1].u.memref.size = buf_size;
> > +
> > +       if (tee_invoke_func(dev, &arg, 2, param) || arg.ret) {
> > +               goto out;
> > +               rc = -1;
>
> Looks like those lines shall be swapped!
yep, nice catch, thanks!

>
> > +       }
> > +
> > +       if (op == TA_RPC_TEST_CMD_I2C_READ)
> > +               memcpy(buf, shm_buf->addr, buf_size);
> > +out:
> > +       tee_shm_free(shm_buf);
> > +       return rc;
> > +}
> > +
> >  static int match(struct tee_version_data *vers, const void *data)
> >  {
> >         return vers->gen_caps & TEE_GEN_CAP_GP;
> > @@ -62,6 +104,7 @@ static int test_tee(struct unit_test_state *uts, struct test_tee_vars *vars)
> >         struct tee_version_data vers;
> >         struct udevice *dev;
> >         struct sandbox_tee_state *state;
> > +       struct tee_optee_ta_uuid avb_uuid = TA_AVB_UUID;
> >         u32 session = 0;
> >         int rc;
> >         u8 data[128];
> > @@ -71,11 +114,11 @@ static int test_tee(struct unit_test_state *uts, struct test_tee_vars *vars)
> >         state = dev_get_priv(dev);
> >         ut_assert(!state->session);
> >
> > -       rc = open_session(dev, &session);
> > +       rc = open_session(dev, &session, avb_uuid);
> >         ut_assert(!rc);
> >         ut_assert(session == state->session);
> >
> > -       rc = invoke_func(dev, session);
> > +       rc = invoke_func_avb(dev, session);
> >         ut_assert(!rc);
> >
> >         rc = tee_close_session(dev, session);
> > @@ -103,11 +146,65 @@ static int test_tee(struct unit_test_state *uts, struct test_tee_vars *vars)
> >         return 0;
> >  }
> >
> > +#define I2C_BUF_SIZE 64
> > +
> > +static int test_tee_rpc(struct unit_test_state *uts)
> > +{
> > +       struct tee_version_data vers;
> > +       struct udevice *dev;
> > +       struct sandbox_tee_state *state;
> > +       struct tee_optee_ta_uuid rpc_test_uuid = TA_RPC_TEST_UUID;
> > +       u32 session = 0;
> > +       int rc;
> > +
> > +       char *test_str = "Test string";
> > +       u8 data[I2C_BUF_SIZE] = {0};
> > +       u8 data_from_eeprom[I2C_BUF_SIZE] = {0};
> > +
> > +       /* Use sandbox I2C EEPROM emulation; bus: 0, chip: 0x2c */
> > +       u64 bus = 0;
> > +       u64 chip = 0x2c;
> > +
> > +       dev = tee_find_device(NULL, match, NULL, &vers);
> > +       ut_assert(dev);
> > +       state = dev_get_priv(dev);
> > +       ut_assert(!state->session);
> > +
> > +       /* Test RPC call asking for I2C sevice */
> > +       rc = open_session(dev, &session, rpc_test_uuid);
> > +       ut_assert(!rc);
> > +       ut_assert(session == state->session);
> > +
> > +       /* Write buffer */
> > +       strncpy((char *)data, test_str, strlen(test_str));
> > +       rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_WRITE,
> > +                                 bus, chip, data, sizeof(data));
> > +       ut_assert(!rc);
> > +
> > +       /* Read buffer */
> > +       rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_READ,
> > +                                 bus, chip, data_from_eeprom,
> > +                                 sizeof(data_from_eeprom));
> > +       ut_assert(!rc);
> > +
> > +       /* Compare */
> > +       ut_assert(!memcmp(data, data_from_eeprom, sizeof(data)));
> > +
> > +       rc = tee_close_session(dev, session);
> > +       ut_assert(!rc);
> > +       ut_assert(!state->session);
> > +
> > +       return 0;
> > +}
> > +
> >  static int dm_test_tee(struct unit_test_state *uts)
> >  {
> >         struct test_tee_vars vars = { NULL, NULL };
> >         int rc = test_tee(uts, &vars);
> >
> > +       if (IS_ENABLED(CONFIG_OPTEE_TA_RPC_TEST))
> > +               rc = test_tee_rpc(uts);
> > +
>
> This scratches return code from test_tee().
Will fix that, thanks!

>
> Best regards,
> Etienne
>
> >         /* In case test_tee() asserts these may still remain allocated */
> >         tee_shm_free(vars.reg_shm);
> >         tee_shm_free(vars.alloc_shm);
> > --
> > 2.25.1
> >
diff mbox series

Patch

diff --git a/test/dm/tee.c b/test/dm/tee.c
index ddbdcfb0cf..51ffb4e4a9 100644
--- a/test/dm/tee.c
+++ b/test/dm/tee.c
@@ -13,11 +13,12 @@ 
 #include <test/test.h>
 #include <test/ut.h>
 #include <tee/optee_ta_avb.h>
+#include <tee/optee_ta_rpc_test.h>
 
-static int open_session(struct udevice *dev, u32 *session)
+static int open_session(struct udevice *dev, u32 *session,
+			struct tee_optee_ta_uuid uuid)
 {
 	struct tee_open_session_arg arg;
-	const struct tee_optee_ta_uuid uuid = TA_AVB_UUID;
 	int rc;
 
 	memset(&arg, 0, sizeof(arg));
@@ -32,7 +33,7 @@  static int open_session(struct udevice *dev, u32 *session)
 	return 0;
 }
 
-static int invoke_func(struct udevice *dev, u32 session)
+static int invoke_func_avb(struct udevice *dev, u32 session)
 {
 	struct tee_param param = { .attr = TEE_PARAM_ATTR_TYPE_VALUE_OUTPUT };
 	struct tee_invoke_arg arg;
@@ -47,6 +48,47 @@  static int invoke_func(struct udevice *dev, u32 session)
 	return 0;
 }
 
+static int invoke_func_rpc_test(struct udevice *dev, u32 session,
+				u64 op, u64 busnum, u64 chip_addr,
+				u8 *buf, size_t buf_size)
+{
+	struct tee_param param[2];
+	struct tee_invoke_arg arg;
+	struct tee_shm *shm_buf;
+	int rc;
+
+	memset(&arg, 0, sizeof(arg));
+	arg.session = session;
+	arg.func = op;
+
+	rc = tee_shm_alloc(dev, buf_size,
+			   TEE_SHM_ALLOC, &shm_buf);
+	if (rc)
+		return rc;
+
+	if (op == TA_RPC_TEST_CMD_I2C_WRITE)
+		memcpy(shm_buf->addr, buf, buf_size);
+
+	memset(param, 0, sizeof(param));
+	param[0].attr = TEE_PARAM_ATTR_TYPE_VALUE_INPUT;
+	param[0].u.value.a = busnum;
+	param[0].u.value.b = chip_addr;
+	param[1].attr = TEE_PARAM_ATTR_TYPE_MEMREF_INOUT;
+	param[1].u.memref.shm = shm_buf;
+	param[1].u.memref.size = buf_size;
+
+	if (tee_invoke_func(dev, &arg, 2, param) || arg.ret) {
+		goto out;
+		rc = -1;
+	}
+
+	if (op == TA_RPC_TEST_CMD_I2C_READ)
+		memcpy(buf, shm_buf->addr, buf_size);
+out:
+	tee_shm_free(shm_buf);
+	return rc;
+}
+
 static int match(struct tee_version_data *vers, const void *data)
 {
 	return vers->gen_caps & TEE_GEN_CAP_GP;
@@ -62,6 +104,7 @@  static int test_tee(struct unit_test_state *uts, struct test_tee_vars *vars)
 	struct tee_version_data vers;
 	struct udevice *dev;
 	struct sandbox_tee_state *state;
+	struct tee_optee_ta_uuid avb_uuid = TA_AVB_UUID;
 	u32 session = 0;
 	int rc;
 	u8 data[128];
@@ -71,11 +114,11 @@  static int test_tee(struct unit_test_state *uts, struct test_tee_vars *vars)
 	state = dev_get_priv(dev);
 	ut_assert(!state->session);
 
-	rc = open_session(dev, &session);
+	rc = open_session(dev, &session, avb_uuid);
 	ut_assert(!rc);
 	ut_assert(session == state->session);
 
-	rc = invoke_func(dev, session);
+	rc = invoke_func_avb(dev, session);
 	ut_assert(!rc);
 
 	rc = tee_close_session(dev, session);
@@ -103,11 +146,65 @@  static int test_tee(struct unit_test_state *uts, struct test_tee_vars *vars)
 	return 0;
 }
 
+#define I2C_BUF_SIZE 64
+
+static int test_tee_rpc(struct unit_test_state *uts)
+{
+	struct tee_version_data vers;
+	struct udevice *dev;
+	struct sandbox_tee_state *state;
+	struct tee_optee_ta_uuid rpc_test_uuid = TA_RPC_TEST_UUID;
+	u32 session = 0;
+	int rc;
+
+	char *test_str = "Test string";
+	u8 data[I2C_BUF_SIZE] = {0};
+	u8 data_from_eeprom[I2C_BUF_SIZE] = {0};
+
+	/* Use sandbox I2C EEPROM emulation; bus: 0, chip: 0x2c */
+	u64 bus = 0;
+	u64 chip = 0x2c;
+
+	dev = tee_find_device(NULL, match, NULL, &vers);
+	ut_assert(dev);
+	state = dev_get_priv(dev);
+	ut_assert(!state->session);
+
+	/* Test RPC call asking for I2C sevice */
+	rc = open_session(dev, &session, rpc_test_uuid);
+	ut_assert(!rc);
+	ut_assert(session == state->session);
+
+	/* Write buffer */
+	strncpy((char *)data, test_str, strlen(test_str));
+	rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_WRITE,
+				  bus, chip, data, sizeof(data));
+	ut_assert(!rc);
+
+	/* Read buffer */
+	rc = invoke_func_rpc_test(dev, session, TA_RPC_TEST_CMD_I2C_READ,
+				  bus, chip, data_from_eeprom,
+				  sizeof(data_from_eeprom));
+	ut_assert(!rc);
+
+	/* Compare */
+	ut_assert(!memcmp(data, data_from_eeprom, sizeof(data)));
+
+	rc = tee_close_session(dev, session);
+	ut_assert(!rc);
+	ut_assert(!state->session);
+
+	return 0;
+}
+
 static int dm_test_tee(struct unit_test_state *uts)
 {
 	struct test_tee_vars vars = { NULL, NULL };
 	int rc = test_tee(uts, &vars);
 
+	if (IS_ENABLED(CONFIG_OPTEE_TA_RPC_TEST))
+		rc = test_tee_rpc(uts);
+
 	/* In case test_tee() asserts these may still remain allocated */
 	tee_shm_free(vars.reg_shm);
 	tee_shm_free(vars.alloc_shm);