in optee/ffa_abi.c [269:311]
static int optee_ffa_shm_register(struct tee_context *ctx, struct tee_shm *shm,
struct page **pages, size_t num_pages,
unsigned long start)
{
struct optee *optee = tee_get_drvdata(ctx->teedev);
const struct ffa_dev_ops *ffa_ops = optee->ffa.ffa_ops;
struct ffa_device *ffa_dev = optee->ffa.ffa_dev;
struct ffa_mem_region_attributes mem_attr = {
.receiver = ffa_dev->vm_id,
.attrs = FFA_MEM_RW,
};
struct ffa_mem_ops_args args = {
.use_txbuf = true,
.attrs = &mem_attr,
.nattrs = 1,
};
struct sg_table sgt;
int rc;
rc = optee_check_mem_type(start, num_pages);
if (rc)
return rc;
rc = sg_alloc_table_from_pages(&sgt, pages, num_pages, 0,
num_pages * PAGE_SIZE, GFP_KERNEL);
if (rc)
return rc;
args.sg = sgt.sgl;
rc = ffa_ops->memory_share(ffa_dev, &args);
sg_free_table(&sgt);
if (rc)
return rc;
rc = optee_shm_add_ffa_handle(optee, shm, args.g_handle);
if (rc) {
ffa_ops->memory_reclaim(args.g_handle, 0);
return rc;
}
shm->sec_world_id = args.g_handle;
return 0;
}