Exemplo n.º 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;
}
Exemplo n.º 2
0
void *tee_fs_rpc_cache_alloc(size_t size, struct mobj **mobj, uint64_t *cookie)
{
	struct thread_specific_data *tsd = thread_get_tsd();
	size_t sz = size;
	uint64_t c = 0;
	paddr_t p;
	void *va;

	if (!size)
		return NULL;

	/*
	 * Always allocate in page chunks as normal world allocates payload
	 * memory as complete pages.
	 */
	sz = ROUNDUP(size, SMALL_PAGE_SIZE);

	if (sz > tsd->rpc_fs_payload_size) {
		tee_fs_rpc_cache_clear(tsd);

		*mobj = thread_rpc_alloc_payload(sz,  &c);
		if (!*mobj)
			return NULL;

		if (mobj_get_pa(*mobj, 0, 0, &p))
			goto err;

		if (!ALIGNMENT_IS_OK(p, uint64_t))
			goto err;

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

		tsd->rpc_fs_payload = va;
		tsd->rpc_fs_payload_mobj = *mobj;
		tsd->rpc_fs_payload_cookie = c;
		tsd->rpc_fs_payload_size = sz;
	} else
		*mobj = tsd->rpc_fs_payload_mobj;

	*cookie = tsd->rpc_fs_payload_cookie;
	return tsd->rpc_fs_payload;
err:
	thread_rpc_free_payload(c, *mobj);
	return NULL;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
static TEE_Result alloc_benchmark_buffer(uint32_t type,
				TEE_Param p[TEE_NUM_PARAMS])
{
	TEE_Result res;

	if ((TEE_PARAM_TYPE_GET(type, 0) != TEE_PARAM_TYPE_VALUE_INOUT) ||
		(TEE_PARAM_TYPE_GET(type, 1) != TEE_PARAM_TYPE_VALUE_INPUT) ||
		(TEE_PARAM_TYPE_GET(type, 2) != TEE_PARAM_TYPE_NONE) ||
		(TEE_PARAM_TYPE_GET(type, 3) != TEE_PARAM_TYPE_NONE)) {
		return TEE_ERROR_BAD_PARAMETERS;
	}

	mutex_lock(&bench_reg_mu);

	/* Check if we have already registered buffer */
	if (bench_ts_global) {
		EMSG(TA_PRINT_PREFIX
			"timestamp buffer was already registered");
		mutex_unlock(&bench_reg_mu);
		return TEE_ERROR_BAD_STATE;
	}

	bench_ts_size = sizeof(struct tee_ts_global) +
		p[1].value.a * sizeof(struct tee_ts_cpu_buf);
	if (!bench_ts_size) {
		EMSG(TA_PRINT_PREFIX
			"invalid timestamp buffer size");
		mutex_unlock(&bench_reg_mu);
		return TEE_ERROR_BAD_STATE;
	}

	bench_mobj = thread_rpc_alloc_global_payload(bench_ts_size);
	if (!bench_mobj) {
		EMSG(TA_PRINT_PREFIX
			"can't create mobj for timestamp buffer");
		mutex_unlock(&bench_reg_mu);
		return TEE_ERROR_OUT_OF_MEMORY;
	}

	bench_ts_global = (struct tee_ts_global *)mobj_get_va(bench_mobj, 0);
	if (!bench_ts_global) {
		thread_rpc_free_global_payload(bench_mobj);
		bench_mobj = NULL;

		mutex_unlock(&bench_reg_mu);
		return TEE_ERROR_BAD_STATE;
	}

	memset((void *)bench_ts_global, 0, bench_ts_size);
	bench_ts_global->cores = p[1].value.a;

	DMSG(TA_PRINT_PREFIX
		"allocated timestamp buffer, addr = %p",
		(void *)bench_ts_global);

	mutex_unlock(&bench_reg_mu);

	/* Send back to the optee linux kernel module */
	res = rpc_reg_global_buf(OPTEE_MSG_RPC_CMD_BENCH_REG_NEW,
			virt_to_phys((void *)bench_ts_global),
			bench_ts_size);

	p[0].value.a = virt_to_phys((void *)bench_ts_global);
	p[0].value.b = bench_ts_size;

	return res;
}