[RFC PATCH] tee: tstee: Add initial Trusted Services TEE driver

Sumit Garg sumit.garg at linaro.org
Tue Oct 17 04:13:58 PDT 2023


On Mon, 16 Oct 2023 at 13:27, Jens Wiklander <jens.wiklander at linaro.org> wrote:
>
> On Fri, Oct 13, 2023 at 1:38 PM Sumit Garg <sumit.garg at linaro.org> wrote:
> >
> > On Tue, 10 Oct 2023 at 21:11, Balint Dobszay <balint.dobszay at arm.com> wrote:
> > >
> > > Hi Sumit,
> > >
> > > On 3 Oct 2023, at 17:42, Sumit Garg wrote:
> > > > On Wed, 27 Sept 2023 at 20:56, Balint Dobszay <balint.dobszay at arm.com> wrote:
> > > >>
> > > >> The Trusted Services project provides a framework for developing and
> > > >> deploying device Root Of Trust services in FF-A Secure Partitions. The
> > > >> FF-A SPs are accessible through the FF-A driver, but this doesn't
> > > >> provide a user space interface. The goal of this TEE driver is to make
> > > >> Trusted Services SPs accessible for user space clients.
> > > >
> > > > I am interested in exploring the user space library/applications. Do
> > > > you have a standard library implementation and some example user-space
> > > > applications leveraging this driver interface?
> > >
> > > Yes we have a library reference implementation in Trusted Services using
> > > this driver called libts [1]. There are some test applications that rely
> > > on this library, e.g. ts-service-test [2]. Also, the Parsec project can
> > > use Trusted Services as backend through libts [3] (note, the version of
> > > TS currently integrated in Parsec is not recent, thus the libts in there
> > > still uses an earlier version of this driver).
> >
> > Although I am currently exploring the user-space interface, I would
> > like to give it a hands-on. Is it possible to run this trusted
> > services setup on Qemu? If yes then can you share instructions how to
> > test them?
> >
> > >
> > > [snip]
> > >
> > > >> +static int tstee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg,
> > > >> +                            struct tee_param *param)
> > > >> +{
> > > >> +       struct tstee *tstee = tee_get_drvdata(ctx->teedev);
> > > >> +       struct ffa_device *ffa_dev = tstee->ffa_dev;
> > > >> +       struct ts_context_data *ctxdata = ctx->data;
> > > >> +       struct ffa_send_direct_data ffa_data;
> > > >> +       struct tee_shm *shm = NULL;
> > > >> +       struct ts_session *sess;
> > > >> +       u32 req_len, ffa_args[5] = {};
> > > >> +       int shm_id, rc;
> > > >> +       u8 iface_id;
> > > >> +       u64 handle;
> > > >> +       u16 opcode;
> > > >> +
> > > >> +       mutex_lock(&ctxdata->mutex);
> > > >> +       sess = find_session(ctxdata, arg->session);
> > > >> +
> > > >> +       /* Do this while holding the mutex to make sure that the session wasn't closed meanwhile */
> > > >> +       if (sess)
> > > >> +               iface_id = sess->iface_id;
> > > >> +
> > > >> +       mutex_unlock(&ctxdata->mutex);
> > > >> +       if (!sess)
> > > >> +               return -EINVAL;
> > > >> +
> > > >> +       opcode = lower_16_bits(arg->func);
> > > >> +       shm_id = lower_32_bits(param[0].u.value.a);
> > > >> +       req_len = lower_32_bits(param[0].u.value.b);
> > > >> +
> > > >> +       if (shm_id != 0) {
> > > >> +               shm = tee_shm_get_from_id(ctx, shm_id);
> > > >> +               if (IS_ERR(shm))
> > > >> +                       return PTR_ERR(shm);
> > > >> +
> > > >> +               if (shm->size < req_len) {
> > > >> +                       pr_err("request doesn't fit into shared memory buffer\n");
> > > >> +                       rc = -EINVAL;
> > > >> +                       goto out;
> > > >> +               }
> > > >> +
> > > >> +               handle = shm->sec_world_id;
> > > >> +       } else {
> > > >> +               handle = FFA_INVALID_MEM_HANDLE;
> > > >> +       }
> > > >> +
> > > >> +       ffa_args[TS_RPC_CTRL_REG] = TS_RPC_CTRL_PACK_IFACE_OPCODE(iface_id, opcode);
> > > >> +       ffa_args[TS_RPC_SERVICE_MEM_HANDLE_LSW] = lower_32_bits(handle);
> > > >> +       ffa_args[TS_RPC_SERVICE_MEM_HANDLE_MSW] = upper_32_bits(handle);
> > > >> +       ffa_args[TS_RPC_SERVICE_REQ_LEN] = req_len;
> > > >> +       ffa_args[TS_RPC_SERVICE_CLIENT_ID] = 0;
> > > >> +
> > > >> +       arg_list_to_ffa_data(ffa_args, &ffa_data);
> > > >> +       rc = ffa_dev->ops->msg_ops->sync_send_receive(ffa_dev, &ffa_data);
> > > >
> > > > I haven't dug deeper into the ABI yet, which is something I will look
> > > > into. But these RPC commands caught my attention. Are these RPC calls
> > > > blocking in nature? Is there a possibility that these could cause CPU
> > > > stalls? Do the Linux interrupts remain unhandled until the RPC calls
> > > > return?
> > >
> > > Yes, that is correct. We did encounter CPU stalls indeed, our solution
> > > was to enable preemption of S-EL0 SPs in OP-TEE [3] which solved the
> > > issue.
> >
> > I would have preferred to unite FFA_INTERRUPT and
> > OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT since underneath both are
> > using FFA ABI.
> >
> > Jens,
> >
> > Can we change OP-TEE to use FFA_INTERRUPT as well when using FFA ABI?
>
> No, OP-TEE uses managed exit. Among other advantages, it allows
> resuming execution on a different CPU.
>

I suppose that should be the case with FFA_INTERRUPT too. OP-TEE
should be able to resume SPs on different CPUs as well, right?

-Sumit

> Cheers,
> Jens
>
> >
> > -Sumit
> >
> > >
> > > Regards,
> > > Balint
> > >
> > > [1] https://git.trustedfirmware.org/TS/trusted-services.git/tree/deployments/libts/arm-linux?h=v1.0.0
> > > [2] https://git.trustedfirmware.org/TS/trusted-services.git/tree/deployments/ts-service-test/arm-linux?h=v1.0.0
> > > [3] https://github.com/parallaxsecond/parsec/tree/3bcd732b92009612109517a6c9075643ef648ca7/src/providers/trusted_service
> > > [4] https://github.com/OP-TEE/optee_os/pull/6002



More information about the linux-arm-kernel mailing list