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

Commit 8e4e63ce authored by Zhen Kong's avatar Zhen Kong
Browse files

qseecom: processing invalid listener request



If the requested listener id is not valid, then its service entry
and whitelist table don't exist, so change to use legacy listener
response cmd without whitelist support in this case.

Change-Id: If23b659242b7e447d67abff14ed9cdd03d928cd0
Signed-off-by: default avatarZhen Kong <zkong@codeaurora.org>
parent 1595912d
Loading
Loading
Loading
Loading
+103 −67
Original line number Diff line number Diff line
@@ -1773,8 +1773,9 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
	int rc = 0;
	uint32_t lstnr;
	unsigned long flags;
	struct qseecom_client_listener_data_irsp send_data_rsp;
	struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit;
	struct qseecom_client_listener_data_irsp send_data_rsp = {0};
	struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit
									= {0};
	struct qseecom_registered_listener_list *ptr_svc = NULL;
	sigset_t new_sigset;
	sigset_t old_sigset;
@@ -1872,66 +1873,79 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
		}
err_resp:
		qseecom.send_resp_flag = 0;
		if (ptr_svc) {
			ptr_svc->send_resp_flag = 0;
			table = ptr_svc->sglistinfo_ptr;
		}
		if (qseecom.qsee_version < QSEE_VERSION_40) {
			send_data_rsp.listener_id  = lstnr;
			send_data_rsp.status = status;
			if (table) {
				send_data_rsp.sglistinfo_ptr =
					(uint32_t)virt_to_phys(table);
				send_data_rsp.sglistinfo_len =
					SGLISTINFO_TABLE_SIZE;
				dmac_flush_range((void *)table,
					(void *)table + SGLISTINFO_TABLE_SIZE);
			}
			cmd_buf = (void *)&send_data_rsp;
			cmd_len = sizeof(send_data_rsp);
		} else {
			send_data_rsp_64bit.listener_id  = lstnr;
			send_data_rsp_64bit.status = status;
			if (table) {
				send_data_rsp_64bit.sglistinfo_ptr =
					virt_to_phys(table);
				send_data_rsp_64bit.sglistinfo_len =
					SGLISTINFO_TABLE_SIZE;
				dmac_flush_range((void *)table,
					(void *)table + SGLISTINFO_TABLE_SIZE);
			}
			cmd_buf = (void *)&send_data_rsp_64bit;
			cmd_len = sizeof(send_data_rsp_64bit);
		}
		if (qseecom.whitelist_support == false)
		if (qseecom.whitelist_support == false || table == NULL)
			*(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND;
		else
			*(uint32_t *)cmd_buf =
				QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST;

		ret = qseecom_dmabuf_cache_operations(ptr_svc->dmabuf,
						QSEECOM_CACHE_CLEAN);
		if (ret)
			return ret;

		if ((lstnr == RPMB_SERVICE) || (lstnr == SSD_SERVICE)) {
			ret = __qseecom_enable_clk(CLK_QSEE);
			if (ret)
				return ret;
		}

		if (ptr_svc) {
			ret = qseecom_dmabuf_cache_operations(ptr_svc->dmabuf,
							QSEECOM_CACHE_CLEAN);
			if (ret)
				goto exit;

			ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
					cmd_buf, cmd_len, resp, sizeof(*resp));
			ptr_svc->listener_in_use = false;
			__qseecom_clean_listener_sglistinfo(ptr_svc);

		if ((lstnr == RPMB_SERVICE) || (lstnr == SSD_SERVICE))
			__qseecom_disable_clk(CLK_QSEE);

			if (ret) {
				pr_err("scm_call() failed with err: %d (app_id = %d)\n",
					ret, data->client.app_id);
			return ret;
				goto exit;
			}

			ret = qseecom_dmabuf_cache_operations(ptr_svc->dmabuf,
						QSEECOM_CACHE_INVALIDATE);
			if (ret)
			return ret;
				goto exit;
		} else {
			ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
					cmd_buf, cmd_len, resp, sizeof(*resp));
			if (ret) {
				pr_err("scm_call() failed with err: %d (app_id = %d)\n",
					ret, data->client.app_id);
				goto exit;
			}
		}

		pr_debug("resp status %d, res= %d, app_id = %d, lstr = %d\n",
			status, resp->result, data->client.app_id, lstnr);
@@ -1941,6 +1955,10 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
				resp->result, data->client.app_id, lstnr);
			ret = -EINVAL;
		}
exit:
		if ((lstnr == RPMB_SERVICE) || (lstnr == SSD_SERVICE))
			__qseecom_disable_clk(CLK_QSEE);

	}
	if (rc)
		return rc;
@@ -2075,8 +2093,9 @@ static int __qseecom_reentrancy_process_incomplete_cmd(
	int rc = 0;
	uint32_t lstnr;
	unsigned long flags;
	struct qseecom_client_listener_data_irsp send_data_rsp;
	struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit;
	struct qseecom_client_listener_data_irsp send_data_rsp = {0};
	struct qseecom_client_listener_data_64bit_irsp send_data_rsp_64bit
									= {0};
	struct qseecom_registered_listener_list *ptr_svc = NULL;
	sigset_t new_sigset;
	sigset_t old_sigset;
@@ -2167,30 +2186,36 @@ static int __qseecom_reentrancy_process_incomplete_cmd(
			status  = QSEOS_RESULT_SUCCESS;
		}
err_resp:
		if (ptr_svc)
			table = ptr_svc->sglistinfo_ptr;
		if (qseecom.qsee_version < QSEE_VERSION_40) {
			send_data_rsp.listener_id  = lstnr;
			send_data_rsp.status = status;
			if (table) {
				send_data_rsp.sglistinfo_ptr =
					(uint32_t)virt_to_phys(table);
			send_data_rsp.sglistinfo_len = SGLISTINFO_TABLE_SIZE;
				send_data_rsp.sglistinfo_len =
						SGLISTINFO_TABLE_SIZE;
				dmac_flush_range((void *)table,
					(void *)table + SGLISTINFO_TABLE_SIZE);
			}
			cmd_buf = (void *)&send_data_rsp;
			cmd_len = sizeof(send_data_rsp);
		} else {
			send_data_rsp_64bit.listener_id  = lstnr;
			send_data_rsp_64bit.status = status;
			if (table) {
				send_data_rsp_64bit.sglistinfo_ptr =
					virt_to_phys(table);
				send_data_rsp_64bit.sglistinfo_len =
					SGLISTINFO_TABLE_SIZE;
				dmac_flush_range((void *)table,
					(void *)table + SGLISTINFO_TABLE_SIZE);
			}
			cmd_buf = (void *)&send_data_rsp_64bit;
			cmd_len = sizeof(send_data_rsp_64bit);
		}
		if (qseecom.whitelist_support == false)
		if (qseecom.whitelist_support == false || table == NULL)
			*(uint32_t *)cmd_buf = QSEOS_LISTENER_DATA_RSP_COMMAND;
		else
			*(uint32_t *)cmd_buf =
@@ -2202,6 +2227,7 @@ static int __qseecom_reentrancy_process_incomplete_cmd(
				return ret;
		}

		if (ptr_svc) {
			ret = qseecom_dmabuf_cache_operations(ptr_svc->dmabuf,
						QSEECOM_CACHE_CLEAN);
			if (ret)
@@ -2222,6 +2248,15 @@ static int __qseecom_reentrancy_process_incomplete_cmd(
						QSEECOM_CACHE_INVALIDATE);
			if (ret)
				goto exit;
		} else {
			ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
					cmd_buf, cmd_len, resp, sizeof(*resp));
			if (ret) {
				pr_err("scm_call() failed with err: %d (app_id = %d)\n",
					ret, data->client.app_id);
				goto exit;
			}
		}

		switch (resp->result) {
		case QSEOS_RESULT_BLOCKED_ON_LISTENER:
@@ -2746,6 +2781,7 @@ static int qseecom_unload_app(struct qseecom_dev_handle *data,
		}
	}

unload_exit:
	if (found_app) {
		spin_lock_irqsave(&qseecom.registered_app_list_lock, flags1);
		if (app_crash) {
@@ -2768,7 +2804,7 @@ static int qseecom_unload_app(struct qseecom_dev_handle *data,
		spin_unlock_irqrestore(&qseecom.registered_app_list_lock,
								flags1);
	}
unload_exit:

	if (data->client.dmabuf)
		qseecom_vaddr_unmap(data->client.sb_virt, data->client.sgt,
			data->client.attach, data->client.dmabuf);