Hi Sumit,
On 3 Oct 2023, at 17:42, Sumit Garg wrote:
On Wed, 27 Sept 2023 at 20:56, Balint Dobszay balint.dobszay@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).
[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.
Regards, Balint
[1] https://git.trustedfirmware.org/TS/trusted-services.git/tree/deployments/lib... [2] https://git.trustedfirmware.org/TS/trusted-services.git/tree/deployments/ts-... [3] https://github.com/parallaxsecond/parsec/tree/3bcd732b92009612109517a6c90756... [4] https://github.com/OP-TEE/optee_os/pull/6002