/* * This file implement the FF-A ABI used when communicating with secure world * OP-TEE OS via FF-A. * This file is divided into the following sections: * 1. Maintain a hash table for lookup of a global FF-A memory handle * 2. Convert between struct tee_param and struct optee_msg_param * 3. Low level support functions to register shared memory in secure world * 4. Dynamic shared memory pool based on alloc_pages() * 5. Do a normal scheduled call into secure world * 6. Driver initialization.
*/
/* * 1. Maintain a hash table for lookup of a global FF-A memory handle * * FF-A assigns a global memory handle for each piece shared memory. * This handle is then used when communicating with secure world. * * Main functions are optee_shm_add_ffa_handle() and optee_shm_rem_ffa_handle()
*/ struct shm_rhash { struct tee_shm *shm;
u64 global_id; struct rhash_head linkage;
};
mutex_lock(&optee->ffa.mutex);
r = rhashtable_lookup_fast(&optee->ffa.global_ids, &global_id,
shm_rhash_params); if (r)
rc = rhashtable_remove_fast(&optee->ffa.global_ids,
&r->linkage, shm_rhash_params);
mutex_unlock(&optee->ffa.mutex);
if (!rc)
kfree(r);
return rc;
}
/* * 2. Convert between struct tee_param and struct optee_msg_param * * optee_ffa_from_msg_param() and optee_ffa_to_msg_param() are the main * functions.
*/
switch (p->attr) { case TEE_IOCTL_PARAM_ATTR_TYPE_NONE:
mp->attr = TEE_IOCTL_PARAM_ATTR_TYPE_NONE;
memset(&mp->u, 0, sizeof(mp->u)); break; case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT:
optee_to_msg_param_value(mp, p); break; case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT: case TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT: if (to_msg_param_ffa_mem(mp, p)) return -EINVAL; break; default: return -EINVAL;
}
}
return0;
}
/* * 3. Low level support functions to register shared memory in secure world * * Functions to register and unregister shared memory both for normal * clients and for tee-supplicant.
*/
/* * 4. Dynamic shared memory pool based on alloc_pages() * * Implements an OP-TEE specific shared memory pool. * The main function is optee_ffa_shm_pool_alloc_pages().
*/
/** * optee_ffa_shm_pool_alloc_pages() - create page-based allocator pool * * This pool is used with OP-TEE over FF-A. In this case command buffers * and such are allocated from kernel's own memory.
*/ staticstruct tee_shm_pool *optee_ffa_shm_pool_alloc_pages(void)
{ struct tee_shm_pool *pool = kzalloc(sizeof(*pool), GFP_KERNEL);
if (!pool) return ERR_PTR(-ENOMEM);
pool->ops = &pool_ffa_ops;
return pool;
}
/* * 5. Do a normal scheduled call into secure world * * The function optee_ffa_do_call_with_arg() performs a normal scheduled * call into secure world. During this call may normal world request help * from normal world using RPCs, Remote Procedure Calls. This includes * delivery of non-secure interrupts to for instance allow rescheduling of * the current task.
*/
/* Initialize waiter */
optee_cq_wait_init(&optee->call_queue, &w, system_thread); while (true) {
rc = msg_ops->sync_send_receive(ffa_dev, data); if (rc) goto done;
switch ((int)data->data0) { case TEEC_SUCCESS: break; case TEEC_ERROR_BUSY: if (cmd == OPTEE_FFA_YIELDING_CALL_RESUME) {
rc = -EIO; goto done;
}
/* * Out of threads in secure world, wait for a thread * become available.
*/
optee_cq_wait_for_completion(&optee->call_queue, &w);
data->data0 = cmd;
data->data1 = w4;
data->data2 = w5;
data->data3 = w6; continue; default:
rc = -EIO; goto done;
}
if (data->data1 == OPTEE_FFA_YIELDING_CALL_RETURN_DONE) goto done;
/* * OP-TEE has returned with a RPC request. * * Note that data->data4 (passed in register w7) is already * filled in by ffa_mem_ops->sync_send_receive() returning * above.
*/
cond_resched();
optee_handle_ffa_rpc(ctx, optee, data->data1, rpc_arg);
cmd = OPTEE_FFA_YIELDING_CALL_RESUME;
data->data0 = cmd;
data->data1 = 0;
data->data2 = 0;
data->data3 = 0;
}
done: /* * We're done with our thread in secure world, if there's any * thread waiters wake up one.
*/
optee_cq_wait_final(&optee->call_queue, &w);
return rc;
}
/** * optee_ffa_do_call_with_arg() - Do a FF-A call to enter OP-TEE in secure world * @ctx: calling context * @shm: shared memory holding the message to pass to secure world * @offs: offset of the message in @shm * @system_thread: true if caller requests TEE system thread support * * Does a FF-A call to OP-TEE in secure world and handles eventual resulting * Remote Procedure Calls (RPC) from OP-TEE. * * Returns return code from FF-A, 0 is OK
*/
/* * The shared memory object has to start on a page when passed as * an argument struct. This is also what the shm pool allocator * returns, but check this before calling secure world to catch * eventual errors early in case something changes.
*/ if (shm->offset) return -EINVAL;
arg = tee_shm_get_va(shm, offs); if (IS_ERR(arg)) return PTR_ERR(arg);
/* * 6. Driver initialization * * During driver inititialization is the OP-TEE Secure Partition is probed * to find out which features it supports so the driver can be initialized * with a matching configuration.
*/
while (true) {
rc = ffa_dev->ops->notifier_ops->notify_request(ffa_dev,
is_per_vcpu,
notif_callback,
optee,
notif_id); if (!rc) break; /* * -EACCES means that the notification ID was * already bound, try the next one as long as we * haven't reached the max. Any other error is a * permanent error, so skip asynchronous * notifications in that case.
*/ if (rc != -EACCES) goto err_wq;
notif_id++; if (notif_id >= OPTEE_FFA_MAX_ASYNC_NOTIF_VALUE) goto err_wq;
}
optee->ffa.bottom_half_value = notif_id;
rc = enable_async_notif(optee); if (rc < 0) goto err_rel;
int optee_ffa_abi_register(void)
{ if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)) return ffa_register(&optee_ffa_driver); else return -EOPNOTSUPP;
}
void optee_ffa_abi_unregister(void)
{ if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT))
ffa_unregister(&optee_ffa_driver);
}
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.3Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-06-07)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.