Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7b001098 authored by Anmolpreet Kaur's avatar Anmolpreet Kaur Committed by Gerrit - the friendly Code Review server
Browse files

qseecom: Change in buffer sharing mechanism in qseecom



Copy the entire userspace request buffer to local kernel
buffer and use that to send to TZ. Update the response
received in the local buffer to the actual userspace buffer
after the request is complete.

Change-Id: I673d74a32966816c5248778fc967eb91da5b6df5
Signed-off-by: default avatarAnmolpreet Kaur <anmolpre@codeaurora.org>
parent 1c0ece44
Loading
Loading
Loading
Loading
+74 −23
Original line number Diff line number Diff line
@@ -460,6 +460,10 @@ static int __maybe_unused get_qseecom_keymaster_status(char *str)
}
__setup("androidboot.keymaster=", get_qseecom_keymaster_status);

static int __qseecom_alloc_coherent_buf(
			uint32_t size, u8 **vaddr, phys_addr_t *paddr);
static void __qseecom_free_coherent_buf(uint32_t size,
				u8 *vaddr, phys_addr_t paddr);

#define QSEECOM_SCM_EBUSY_WAIT_MS 30
#define QSEECOM_SCM_EBUSY_MAX_RETRY 67
@@ -3662,7 +3666,8 @@ static int __qseecom_process_reentrancy(struct qseecom_command_scm_resp *resp,
}

static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
				struct qseecom_send_cmd_req *req)
			struct qseecom_send_cmd_req *req,
			bool is_phys_adr)
{
	int ret = 0;
	u32 reqd_len_sb_in = 0;
@@ -3703,11 +3708,20 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,

	if (qseecom.qsee_version < QSEE_VERSION_40) {
		send_data_req.app_id = data->client.app_id;
		send_data_req.req_ptr = (uint32_t)(__qseecom_uvirt_to_kphys(
					data, (uintptr_t)req->cmd_req_buf));
		send_data_req.req_len = req->cmd_req_len;
		send_data_req.rsp_ptr = (uint32_t)(__qseecom_uvirt_to_kphys(

		if (!is_phys_adr) {
			send_data_req.req_ptr =
				(uint32_t)(__qseecom_uvirt_to_kphys
				(data, (uintptr_t)req->cmd_req_buf));
			send_data_req.rsp_ptr =
				(uint32_t)(__qseecom_uvirt_to_kphys(
				data, (uintptr_t)req->resp_buf));
		} else {
			send_data_req.req_ptr = (uint32_t)req->cmd_req_buf;
			send_data_req.rsp_ptr = (uint32_t)req->resp_buf;
		}

		send_data_req.req_len = req->cmd_req_len;
		send_data_req.rsp_len = req->resp_len;
		send_data_req.sglistinfo_ptr =
				(uint32_t)data->sglistinfo_shm.paddr;
@@ -3717,11 +3731,21 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
		cmd_len = sizeof(struct qseecom_client_send_data_ireq);
	} else {
		send_data_req_64bit.app_id = data->client.app_id;
		send_data_req_64bit.req_ptr = __qseecom_uvirt_to_kphys(data,

		if (!is_phys_adr) {
			send_data_req_64bit.req_ptr =
				 __qseecom_uvirt_to_kphys(data,
				(uintptr_t)req->cmd_req_buf);
		send_data_req_64bit.req_len = req->cmd_req_len;
		send_data_req_64bit.rsp_ptr = __qseecom_uvirt_to_kphys(data,
			send_data_req_64bit.rsp_ptr =
				__qseecom_uvirt_to_kphys(data,
				(uintptr_t)req->resp_buf);
		} else {
			send_data_req_64bit.req_ptr =
				(uintptr_t)req->cmd_req_buf;
			send_data_req_64bit.rsp_ptr =
				(uintptr_t)req->resp_buf;
		}
		send_data_req_64bit.req_len = req->cmd_req_len;
		send_data_req_64bit.rsp_len = req->resp_len;
		/* check if 32bit app's phys_addr region is under 4GB.*/
		if ((data->client.app_arch == ELFCLASS32) &&
@@ -3818,7 +3842,7 @@ static int qseecom_send_cmd(struct qseecom_dev_handle *data, void __user *argp)
	if (__validate_send_cmd_inputs(data, &req))
		return -EINVAL;

	ret = __qseecom_send_cmd(data, &req);
	ret = __qseecom_send_cmd(data, &req, false);

	return ret;
}
@@ -4336,6 +4360,9 @@ static int __qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
	int i;
	struct qseecom_send_modfd_cmd_req req;
	struct qseecom_send_cmd_req send_cmd_req;
	void *origin_req_buf_kvirt, *origin_rsp_buf_kvirt;
	phys_addr_t pa;
	u8 *va = NULL;

	ret = copy_from_user(&req, argp, sizeof(req));
	if (ret) {
@@ -4359,33 +4386,57 @@ static int __qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
			return -EINVAL;
		}
	}
	req.cmd_req_buf = (void *)__qseecom_uvirt_to_kvirt(data,

	/*Back up original address */
	origin_req_buf_kvirt = (void *)__qseecom_uvirt_to_kvirt(data,
				(uintptr_t)req.cmd_req_buf);
	req.resp_buf = (void *)__qseecom_uvirt_to_kvirt(data,
	origin_rsp_buf_kvirt = (void *)__qseecom_uvirt_to_kvirt(data,
				(uintptr_t)req.resp_buf);

	/* Allocate kernel buffer for request and response*/
	ret = __qseecom_alloc_coherent_buf(req.cmd_req_len + req.resp_len,
					&va, &pa);
	req.cmd_req_buf = va;
	send_cmd_req.cmd_req_buf = (void *)pa;

	req.resp_buf = va + req.cmd_req_len;
	send_cmd_req.resp_buf = (void *)pa + req.cmd_req_len;

	/* Copy the data to kernel request and response buffers*/
	memcpy(req.cmd_req_buf, origin_req_buf_kvirt, req.cmd_req_len);
	memcpy(req.resp_buf, origin_rsp_buf_kvirt, req.resp_len);

	if (!is_64bit_addr) {
		ret = __qseecom_update_cmd_buf(&req, false, data);
		if (ret)
			return ret;
		ret = __qseecom_send_cmd(data, &send_cmd_req);
			goto out;
		ret = __qseecom_send_cmd(data, &send_cmd_req, true);
		if (ret)
			return ret;
			goto out;
		ret = __qseecom_update_cmd_buf(&req, true, data);
		if (ret)
			return ret;
			goto out;
	} else {
		ret = __qseecom_update_cmd_buf_64(&req, false, data);
		if (ret)
			return ret;
		ret = __qseecom_send_cmd(data, &send_cmd_req);
			goto out;
		ret = __qseecom_send_cmd(data, &send_cmd_req, true);
		if (ret)
			return ret;
			goto out;
		ret = __qseecom_update_cmd_buf_64(&req, true, data);
		if (ret)
			return ret;
			goto out;
	}

	/*Copy the response back to the userspace buffer*/
	memcpy(origin_rsp_buf_kvirt, req.resp_buf, req.resp_len);
	memcpy(origin_req_buf_kvirt, req.cmd_req_buf, req.cmd_req_len);

out:
	if (req.cmd_req_buf)
		__qseecom_free_coherent_buf(req.cmd_req_len + req.resp_len,
			req.cmd_req_buf, (phys_addr_t)send_cmd_req.cmd_req_buf);

	return ret;
}

@@ -5251,7 +5302,7 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
	if (!strcmp(data->client.app_name, "securemm"))
		data->use_legacy_cmd = true;

	ret = __qseecom_send_cmd(data, &req);
	ret = __qseecom_send_cmd(data, &req, false);

	data->use_legacy_cmd = false;
	if (qseecom.support_bus_scaling)