staticint tee_params_to_amd_params(struct tee_param *tee, u32 count, struct tee_operation *amd)
{ int i, ret = 0;
u32 type;
if (!count) return 0;
if (!tee || !amd || count > TEE_MAX_PARAMS) return -EINVAL;
amd->param_types = 0; for (i = 0; i < count; i++) { /* AMD TEE does not support meta parameter */ if (tee[i].attr > TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INOUT) return -EINVAL;
amd->param_types |= ((tee[i].attr & 0xF) << i * 4);
}
for (i = 0; i < count; i++) {
type = TEE_PARAM_TYPE_GET(amd->param_types, i);
pr_debug("%s: type[%d] = 0x%x\n", __func__, i, type);
if (type == TEE_OP_PARAM_TYPE_INVALID) return -EINVAL;
if (type == TEE_OP_PARAM_TYPE_NONE) continue;
/* It is assumed that all values are within 2^32-1 */ if (type > TEE_OP_PARAM_TYPE_VALUE_INOUT) {
u32 buf_id = get_buffer_id(tee[i].u.memref.shm);
amd->params[i].mref.buf_id = buf_id;
amd->params[i].mref.offset = tee[i].u.memref.shm_offs;
amd->params[i].mref.size = tee[i].u.memref.size;
pr_debug("%s: bufid[%d] = 0x%x, offset[%d] = 0x%x, size[%d] = 0x%x\n",
__func__,
i, amd->params[i].mref.buf_id,
i, amd->params[i].mref.offset,
i, amd->params[i].mref.size);
} else { if (tee[i].u.value.c)
pr_warn("%s: Discarding value c", __func__);
staticint amd_params_to_tee_params(struct tee_param *tee, u32 count, struct tee_operation *amd)
{ int i, ret = 0;
u32 type;
if (!count) return 0;
if (!tee || !amd || count > TEE_MAX_PARAMS) return -EINVAL;
/* Assumes amd->param_types is valid */ for (i = 0; i < count; i++) {
type = TEE_PARAM_TYPE_GET(amd->param_types, i);
pr_debug("%s: type[%d] = 0x%x\n", __func__, i, type);
if (type == TEE_OP_PARAM_TYPE_INVALID ||
type > TEE_OP_PARAM_TYPE_MEMREF_INOUT) return -EINVAL;
if (type == TEE_OP_PARAM_TYPE_NONE ||
type == TEE_OP_PARAM_TYPE_VALUE_INPUT ||
type == TEE_OP_PARAM_TYPE_MEMREF_INPUT) continue;
/* * It is assumed that buf_id remains unchanged for * both open_session and invoke_cmd call
*/ if (type > TEE_OP_PARAM_TYPE_MEMREF_INPUT) {
tee[i].u.memref.shm_offs = amd->params[i].mref.offset;
tee[i].u.memref.size = amd->params[i].mref.size;
pr_debug("%s: bufid[%d] = 0x%x, offset[%d] = 0x%x, size[%d] = 0x%x\n",
__func__,
i, amd->params[i].mref.buf_id,
i, amd->params[i].mref.offset,
i, amd->params[i].mref.size);
} else { /* field 'c' not supported by AMD TEE */
tee[i].u.value.a = amd->params[i].val.a;
tee[i].u.value.b = amd->params[i].val.b;
tee[i].u.value.c = 0;
pr_debug("%s: a[%d] = 0x%x, b[%d] = 0x%x\n",
__func__,
i, amd->params[i].val.a,
i, amd->params[i].val.b);
}
} return ret;
}
ret = psp_tee_process_cmd(TEE_CMD_ID_CLOSE_SESSION, (void *)&cmd, sizeof(cmd), &status); if (!ret && status != 0) {
pr_err("close session: status = 0x%x\n", status);
ret = -EBUSY;
}
ret = psp_tee_process_cmd(TEE_CMD_ID_INVOKE_CMD, (void *)&cmd, sizeof(cmd), &arg->ret); if (ret) {
arg->ret = TEEC_ERROR_COMMUNICATION;
} else {
ret = amd_params_to_tee_params(p, arg->num_params, &cmd.op); if (unlikely(ret)) {
pr_err("invoke command: failed to copy output\n");
arg->ret = TEEC_ERROR_GENERIC; return ret;
}
arg->ret_origin = cmd.return_origin;
pr_debug("invoke command: RO = 0x%x ret = 0x%x\n",
arg->ret_origin, arg->ret);
}
return ret;
}
int handle_map_shmem(u32 count, struct shmem_desc *start, u32 *buf_id)
{ struct tee_cmd_map_shared_mem *cmd;
phys_addr_t paddr; int ret, i;
u32 status;
if (!count || !start || !buf_id) return -EINVAL;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); if (!cmd) return -ENOMEM;
/* Size must be page aligned */ for (i = 0; i < count ; i++) { if (!start[i].kaddr || (start[i].size & (PAGE_SIZE - 1))) {
ret = -EINVAL; goto free_cmd;
}
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.