Beispiel #1
0
static TEE_Result gprof_send_rpc(TEE_UUID *uuid, void *buf, size_t len,
				 uint32_t *id)
{
	struct mobj *mobj;
	TEE_Result res = TEE_ERROR_GENERIC;
	char *va;

	mobj = thread_rpc_alloc_payload(sizeof(*uuid) + len);
	if (!mobj)
		return TEE_ERROR_OUT_OF_MEMORY;

	va = mobj_get_va(mobj, 0);
	if (!va)
		goto exit;

	memcpy(va, uuid, sizeof(*uuid));
	memcpy(va + sizeof(*uuid), buf, len);

	struct thread_param params[3] = {
		[0] = THREAD_PARAM_VALUE(INOUT, *id, 0, 0),
		[1] = THREAD_PARAM_MEMREF(IN, mobj, 0, sizeof(*uuid)),
		[2] = THREAD_PARAM_MEMREF(IN, mobj, sizeof(*uuid), len),
	};

	res = thread_rpc_cmd(OPTEE_RPC_CMD_GPROF, 3, params);
	if (res != TEE_SUCCESS)
		goto exit;

	*id = (uint32_t)params[0].u.value.a;
exit:
	thread_rpc_free_payload(mobj);
	return res;
}
Beispiel #2
0
/*
 * Load a TA via RPC with UUID defined by input param @uuid. The virtual
 * address of the raw TA binary is received in out parameter @ta.
 */
static TEE_Result rpc_load(const TEE_UUID *uuid, struct shdr **ta,
			   size_t *ta_size, struct mobj **mobj)
{
	TEE_Result res;
	struct thread_param params[2];

	if (!uuid || !ta || !mobj || !ta_size)
		return TEE_ERROR_BAD_PARAMETERS;

	memset(params, 0, sizeof(params));
	params[0].attr = THREAD_PARAM_ATTR_VALUE_IN;
	tee_uuid_to_octets((void *)&params[0].u.value, uuid);
	params[1].attr = THREAD_PARAM_ATTR_MEMREF_OUT;

	res = thread_rpc_cmd(OPTEE_RPC_CMD_LOAD_TA, 2, params);
	if (res != TEE_SUCCESS)
		return res;

	*mobj = thread_rpc_alloc_payload(params[1].u.memref.size);
	if (!*mobj)
		return TEE_ERROR_OUT_OF_MEMORY;

	if ((*mobj)->size < params[1].u.memref.size) {
		res = TEE_ERROR_SHORT_BUFFER;
		goto exit;
	}

	*ta = mobj_get_va(*mobj, 0);
	/* We don't expect NULL as thread_rpc_alloc_payload() was successful */
	assert(*ta);
	*ta_size = params[1].u.memref.size;

	params[0].attr = THREAD_PARAM_ATTR_VALUE_IN;
	tee_uuid_to_octets((void *)&params[0].u.value, uuid);
	params[1].attr = THREAD_PARAM_ATTR_MEMREF_OUT;
	params[1].u.memref.offs = 0;
	params[1].u.memref.mobj = *mobj;

	res = thread_rpc_cmd(OPTEE_RPC_CMD_LOAD_TA, 2, params);
exit:
	if (res != TEE_SUCCESS)
		thread_rpc_free_payload(*mobj);

	return res;
}
Beispiel #3
0
static TEE_Result socket_open(uint32_t instance_id, uint32_t param_types,
			      TEE_Param params[TEE_NUM_PARAMS])
{
	struct mobj *mobj;
	TEE_Result res;
	uint64_t cookie;
	void *va;
	struct optee_msg_param msg_params[4];
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_MEMREF_INPUT,
					  TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_VALUE_OUTPUT);

	if (exp_pt != param_types) {
		DMSG("got param_types 0x%x, expected 0x%x",
		     param_types, exp_pt);
		return TEE_ERROR_BAD_PARAMETERS;
	}

	memset(msg_params, 0, sizeof(msg_params));

	va = tee_fs_rpc_cache_alloc(params[1].memref.size, &mobj, &cookie);
	if (!va)
		return TEE_ERROR_OUT_OF_MEMORY;

	msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
	msg_params[0].u.value.a = OPTEE_MRC_SOCKET_OPEN;
	msg_params[0].u.value.b = instance_id;

	msg_params[1].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
	msg_params[1].u.value.a = params[0].value.b; /* server port number */
	msg_params[1].u.value.b = params[2].value.a; /* protocol */
	msg_params[1].u.value.c = params[0].value.a; /* ip version */

	/* server address */
	if (!msg_param_init_memparam(msg_params + 2, mobj, 0,
				     params[1].memref.size, cookie,
				     MSG_PARAM_MEM_DIR_IN))
		return TEE_ERROR_BAD_STATE;
	memcpy(va, params[1].memref.buffer, params[1].memref.size);

	/* socket handle */
	msg_params[3].attr = OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT;

	res = thread_rpc_cmd(OPTEE_MSG_RPC_CMD_SOCKET, 4, msg_params);

	if (res == TEE_SUCCESS)
		params[3].value.a = msg_params[3].u.value.a;

	return res;
}
Beispiel #4
0
static TEE_Result socket_ioctl(uint32_t instance_id, uint32_t param_types,
			       TEE_Param params[TEE_NUM_PARAMS])
{
	struct mobj *mobj;
	TEE_Result res;
	uint64_t cookie;
	void *va;
	struct optee_msg_param msg_params[3];
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_MEMREF_INOUT,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE);

	if (exp_pt != param_types) {
		DMSG("got param_types 0x%x, expected 0x%x",
		     param_types, exp_pt);
		return TEE_ERROR_BAD_PARAMETERS;
	}

	memset(msg_params, 0, sizeof(msg_params));

	va = tee_fs_rpc_cache_alloc(params[1].memref.size, &mobj, &cookie);
	if (!va)
		return TEE_ERROR_OUT_OF_MEMORY;

	msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
	msg_params[0].u.value.a = OPTEE_MRC_SOCKET_IOCTL;
	msg_params[0].u.value.b = instance_id;
	msg_params[0].u.value.c = params[0].value.a; /* handle */

	/* buffer */
	if (!msg_param_init_memparam(msg_params + 1, mobj, 0,
				     params[1].memref.size, cookie,
				     MSG_PARAM_MEM_DIR_INOUT))
		return TEE_ERROR_BAD_STATE;

	memcpy(va, params[1].memref.buffer, params[1].memref.size);

	msg_params[2].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
	msg_params[2].u.value.a = params[0].value.b; /* ioctl command */

	res = thread_rpc_cmd(OPTEE_MSG_RPC_CMD_SOCKET, 3, msg_params);
	if (msg_param_get_buf_size(msg_params + 1) <= params[1].memref.size)
		memcpy(params[1].memref.buffer, va,
		       msg_param_get_buf_size(msg_params + 1));

	params[1].memref.size = msg_param_get_buf_size(msg_params + 1);
	return res;
}
Beispiel #5
0
void tee_time_wait(uint32_t milliseconds_delay)
{
	struct tee_ta_session *sess = NULL;
	struct teesmc32_param params;

	tee_ta_get_current_session(&sess);
	if (sess)
		tee_ta_set_current_session(NULL);

	memset(&params, 0, sizeof(params));
	params.attr = TEESMC_ATTR_TYPE_VALUE_INPUT;
	params.u.value.a = milliseconds_delay;
	thread_rpc_cmd(TEE_RPC_WAIT, 1, &params);

	if (sess)
		tee_ta_set_current_session(sess);
}
Beispiel #6
0
/*
 * tee_time_get_ree_time(): this function implements the GP Internal API
 * function TEE_GetREETime()
 * Goal is to get the time of the Rich Execution Environment
 * This is why this time is provided through the supplicant
 */
TEE_Result tee_time_get_ree_time(TEE_Time *time)
{
	struct tee_ta_session *sess = NULL;
	TEE_Result res = TEE_ERROR_BAD_PARAMETERS;
	struct teesmc32_param params;
	paddr_t phpayload = 0;
	paddr_t cookie = 0;
	TEE_Time *payload;

	tee_ta_get_current_session(&sess);
	tee_ta_set_current_session(NULL);

	if (!time)
		goto exit;

	thread_optee_rpc_alloc_payload(sizeof(TEE_Time), &phpayload, &cookie);
	if (!phpayload)
		goto exit;

	if (!TEE_ALIGNMENT_IS_OK(phpayload, TEE_Time))
		goto exit;

	if (core_pa2va(phpayload, &payload))
		goto exit;

	memset(&params, 0, sizeof(params));
	params.attr = TEESMC_ATTR_TYPE_MEMREF_OUTPUT |
			 (TEESMC_ATTR_CACHE_I_WRITE_THR |
			  TEESMC_ATTR_CACHE_O_WRITE_THR) <<
				TEESMC_ATTR_CACHE_SHIFT;
	params.u.memref.buf_ptr = phpayload;
	params.u.memref.size = sizeof(TEE_Time);

	res = thread_rpc_cmd(TEE_RPC_GET_TIME, 1, &params);
	if (res != TEE_SUCCESS)
		goto exit;

	*time = *payload;

exit:
	thread_optee_rpc_free_payload(cookie);
	tee_ta_set_current_session(sess);
	return res;
}
Beispiel #7
0
static TEE_Result gprof_send_rpc(TEE_UUID *uuid, void *buf, size_t len,
				 uint32_t *id)
{
	struct optee_msg_param params[3];
	TEE_Result res = TEE_ERROR_GENERIC;
	uint64_t c = 0;
	paddr_t pa;
	char *va;

	thread_rpc_alloc_payload(sizeof(*uuid) + len, &pa, &c);
	if (!pa)
		return TEE_ERROR_OUT_OF_MEMORY;

	va = phys_to_virt(pa, MEM_AREA_NSEC_SHM);
	if (!va)
		goto exit;

	memcpy(va, uuid, sizeof(*uuid));
	memcpy(va + sizeof(*uuid), buf, len);

	memset(params, 0, sizeof(params));
	params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INOUT;
	params[0].u.value.a = *id;

	params[1].attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
	params[1].u.tmem.buf_ptr = pa;
	params[1].u.tmem.size = sizeof(*uuid);
	params[1].u.tmem.shm_ref = c;

	params[2].attr = OPTEE_MSG_ATTR_TYPE_TMEM_INPUT;
	params[2].u.tmem.buf_ptr = pa + sizeof(*uuid);
	params[2].u.tmem.size = len;
	params[2].u.tmem.shm_ref = c;

	res = thread_rpc_cmd(OPTEE_MSG_RPC_CMD_GPROF, 3, params);
	if (res != TEE_SUCCESS)
		goto exit;

	*id = (uint32_t)params[0].u.value.a;
exit:
	thread_rpc_free_payload(c);
	return res;
}
Beispiel #8
0
static TEE_Result socket_close(uint32_t instance_id, uint32_t param_types,
			       TEE_Param params[TEE_NUM_PARAMS])
{
	struct optee_msg_param msg_params[1];
	uint32_t exp_pt = TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_INPUT,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE,
					  TEE_PARAM_TYPE_NONE);

	if (exp_pt != param_types) {
		DMSG("got param_types 0x%x, expected 0x%x",
		     param_types, exp_pt);
		return TEE_ERROR_BAD_PARAMETERS;
	}

	memset(msg_params, 0, sizeof(msg_params));

	msg_params[0].attr = OPTEE_MSG_ATTR_TYPE_VALUE_INPUT;
	msg_params[0].u.value.a = OPTEE_MRC_SOCKET_CLOSE;
	msg_params[0].u.value.b = instance_id;
	msg_params[0].u.value.c = params[0].value.a;

	return thread_rpc_cmd(OPTEE_MSG_RPC_CMD_SOCKET, 1, msg_params);
}
Beispiel #9
0
static TEE_Result rpc_reg_global_buf(uint64_t type, paddr_t phta, size_t size)
{
	struct thread_param tpm = THREAD_PARAM_VALUE(IN, type, phta, size);

	return thread_rpc_cmd(OPTEE_RPC_CMD_BENCH_REG, 1, &tpm);
}