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

Commit bedc71e4 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "qseecom: support listener request from smcinvoke without reentrancy"

parents af4bdc7b 6586e888
Loading
Loading
Loading
Loading
+130 −24
Original line number Diff line number Diff line
@@ -278,6 +278,7 @@ struct qseecom_control {
	wait_queue_head_t app_block_wq;
	atomic_t qseecom_state;
	int is_apps_region_protected;
	bool smcinvoke_support;
};

struct qseecom_sec_buf_fd_info {
@@ -575,10 +576,12 @@ static int qseecom_scm_call2(uint32_t svc_id, uint32_t tz_cmd_id,
				desc.args[1] = req_64bit->sb_ptr;
				desc.args[2] = req_64bit->sb_len;
			}
			qseecom.smcinvoke_support = true;
			smc_id = TZ_OS_REGISTER_LISTENER_SMCINVOKE_ID;
			__qseecom_reentrancy_check_if_no_app_blocked(smc_id);
			ret = scm_call2(smc_id, &desc);
			if (ret) {
				qseecom.smcinvoke_support = false;
				smc_id = TZ_OS_REGISTER_LISTENER_ID;
				__qseecom_reentrancy_check_if_no_app_blocked(
					smc_id);
@@ -1003,10 +1006,14 @@ static int qseecom_scm_call2(uint32_t svc_id, uint32_t tz_cmd_id,
			struct qseecom_continue_blocked_request_ireq *req =
				(struct qseecom_continue_blocked_request_ireq *)
				req_buf;
			if (qseecom.smcinvoke_support)
				smc_id =
				TZ_OS_CONTINUE_BLOCKED_REQUEST_SMCINVOKE_ID;
			else
				smc_id = TZ_OS_CONTINUE_BLOCKED_REQUEST_ID;
			desc.arginfo =
				TZ_OS_CONTINUE_BLOCKED_REQUEST_ID_PARAM_ID;
			desc.args[0] = req->app_id;
			desc.args[0] = req->app_or_session_id;
			ret = scm_call2(smc_id, &desc);
			break;
		}
@@ -1836,7 +1843,7 @@ static int __qseecom_process_incomplete_cmd(struct qseecom_dev_handle *data,
	return ret;
}

int __qseecom_process_reentrancy_blocked_on_listener(
static int __qseecom_process_blocked_on_listener_legacy(
				struct qseecom_command_scm_resp *resp,
				struct qseecom_registered_app_list *ptr_app,
				struct qseecom_dev_handle *data)
@@ -1845,9 +1852,8 @@ int __qseecom_process_reentrancy_blocked_on_listener(
	int ret = 0;
	struct qseecom_continue_blocked_request_ireq ireq;
	struct qseecom_command_scm_resp continue_resp;
	sigset_t new_sigset, old_sigset;
	unsigned long flags;
	bool found_app = false;
	unsigned long flags;

	if (!resp || !data) {
		pr_err("invalid resp or data pointer\n");
@@ -1887,32 +1893,30 @@ int __qseecom_process_reentrancy_blocked_on_listener(
	pr_debug("lsntr %d in_use = %d\n",
			resp->data, list_ptr->listener_in_use);
	ptr_app->blocked_on_listener_id = resp->data;

	/* sleep until listener is available */
	do {
	qseecom.app_block_ref_cnt++;
	ptr_app->app_blocked = true;
		sigfillset(&new_sigset);
		sigprocmask(SIG_SETMASK, &new_sigset, &old_sigset);
	mutex_unlock(&app_access_lock);
		do {
			if (!wait_event_freezable(
	if (wait_event_freezable(
			list_ptr->listener_block_app_wq,
			!list_ptr->listener_in_use)) {
				break;
		pr_err("Interrupted: listener_id %d, app_id %d\n",
				resp->data, ptr_app->app_id);
		ret = -ERESTARTSYS;
		goto exit;
	}
		} while (1);
	mutex_lock(&app_access_lock);
		sigprocmask(SIG_SETMASK, &old_sigset, NULL);
	ptr_app->app_blocked = false;
	qseecom.app_block_ref_cnt--;
	} while (list_ptr->listener_in_use == true);

	ptr_app->blocked_on_listener_id = 0;
	/* notify the blocked app that listener is available */
	pr_warn("Lsntr %d is available, unblock app(%d) %s in TZ\n",
		resp->data, data->client.app_id,
		data->client.app_name);
	ireq.qsee_cmd_id = QSEOS_CONTINUE_BLOCKED_REQ_COMMAND;
	ireq.app_id = data->client.app_id;
	ireq.app_or_session_id = data->client.app_id;
	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
			&ireq, sizeof(ireq),
			&continue_resp, sizeof(continue_resp));
@@ -1931,6 +1935,73 @@ exit:
	return ret;
}

static int __qseecom_process_blocked_on_listener_smcinvoke(
			struct qseecom_command_scm_resp *resp)
{
	struct qseecom_registered_listener_list *list_ptr;
	int ret = 0;
	struct qseecom_continue_blocked_request_ireq ireq;
	struct qseecom_command_scm_resp continue_resp;
	unsigned int session_id;

	if (!resp) {
		pr_err("invalid resp pointer\n");
		ret = -EINVAL;
		goto exit;
	}
	session_id = resp->resp_type;
	list_ptr = __qseecom_find_svc(resp->data);
	if (!list_ptr) {
		pr_err("Invalid listener ID\n");
		ret = -ENODATA;
		goto exit;
	}
	pr_debug("lsntr %d in_use = %d\n",
			resp->data, list_ptr->listener_in_use);
	/* sleep until listener is available */
	qseecom.app_block_ref_cnt++;
	mutex_unlock(&app_access_lock);
	if (wait_event_freezable(
			list_ptr->listener_block_app_wq,
			!list_ptr->listener_in_use)) {
		pr_err("Interrupted: listener_id %d, session_id %d\n",
				resp->data, session_id);
		ret = -ERESTARTSYS;
		goto exit;
	}
	mutex_lock(&app_access_lock);
	qseecom.app_block_ref_cnt--;

	/* notify TZ that listener is available */
	pr_warn("Lsntr %d is available, unblock session(%d) in TZ\n",
			resp->data, session_id);
	ireq.qsee_cmd_id = QSEOS_CONTINUE_BLOCKED_REQ_COMMAND;
	ireq.app_or_session_id = session_id;
	ret = qseecom_scm_call(SCM_SVC_TZSCHEDULER, 1,
			&ireq, sizeof(ireq),
			&continue_resp, sizeof(continue_resp));
	if (ret) {
		pr_err("scm_call for continue blocked req for session %d failed, ret %d\n",
			session_id, ret);
		goto exit;
	}
	resp->result = QSEOS_RESULT_INCOMPLETE;
exit:
	return ret;
}

static int __qseecom_process_reentrancy_blocked_on_listener(
				struct qseecom_command_scm_resp *resp,
				struct qseecom_registered_app_list *ptr_app,
				struct qseecom_dev_handle *data)
{
	if (!qseecom.smcinvoke_support)
		return __qseecom_process_blocked_on_listener_legacy(
			resp, ptr_app, data);
	else
		return __qseecom_process_blocked_on_listener_smcinvoke(
			resp);
}
static int __qseecom_reentrancy_process_incomplete_cmd(
					struct qseecom_dev_handle *data,
					struct qseecom_command_scm_resp *resp)
@@ -4684,6 +4755,41 @@ int qseecom_set_bandwidth(struct qseecom_handle *handle, bool high)
}
EXPORT_SYMBOL(qseecom_set_bandwidth);

int qseecom_process_listener_from_smcinvoke(struct scm_desc *desc)
{
	struct qseecom_registered_app_list dummy_app_entry = { {0} };
	struct qseecom_dev_handle dummy_private_data = {0};
	struct qseecom_command_scm_resp resp;
	int ret = 0;

	if (!desc) {
		pr_err("desc is NULL\n");
		return -EINVAL;
	}

	resp.result = desc->ret[0];	/*req_cmd*/
	resp.resp_type = desc->ret[1]; /*incomplete:unused;blocked:session_id*/
	resp.data = desc->ret[2];	/*listener_id*/

	mutex_lock(&app_access_lock);
	if (qseecom.qsee_reentrancy_support)
		ret = __qseecom_process_reentrancy(&resp, &dummy_app_entry,
					&dummy_private_data);
	else
		ret = __qseecom_process_incomplete_cmd(&dummy_private_data,
					&resp);
	mutex_unlock(&app_access_lock);
	if (ret)
		pr_err("Failed on cmd %d for lsnr %d session %d, ret = %d\n",
			(int)desc->ret[0], (int)desc->ret[2],
			(int)desc->ret[1], ret);
	desc->ret[0] = resp.result;
	desc->ret[1] = resp.resp_type;
	desc->ret[2] = resp.data;
	return ret;
}
EXPORT_SYMBOL(qseecom_process_listener_from_smcinvoke);

static int qseecom_send_resp(void)
{
	qseecom.send_resp_flag = 1;
+2 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#define __QSEECOM_KERNEL_H_

#include <linux/types.h>
#include <soc/qcom/scm.h>

#define QSEECOM_ALIGN_SIZE	0x40
#define QSEECOM_ALIGN_MASK	(QSEECOM_ALIGN_SIZE - 1)
@@ -38,5 +39,6 @@ int qseecom_shutdown_app(struct qseecom_handle **handle);
int qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
			uint32_t sbuf_len, void *resp_buf, uint32_t rbuf_len);
int qseecom_set_bandwidth(struct qseecom_handle *handle, bool high);
int qseecom_process_listener_from_smcinvoke(struct scm_desc *desc);

#endif /* __QSEECOM_KERNEL_H_ */
+4 −1
Original line number Diff line number Diff line
@@ -336,7 +336,7 @@ __packed struct qseecom_client_send_fsm_key_req {

__packed struct qseecom_continue_blocked_request_ireq {
	uint32_t qsee_cmd_id;
	uint32_t app_id;
	uint32_t app_or_session_id; /*legacy: app_id; smcinvoke: session_id*/
};


@@ -681,6 +681,9 @@ __packed struct qseecom_continue_blocked_request_ireq {
#define TZ_OS_CONTINUE_BLOCKED_REQUEST_ID \
	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x04)

#define TZ_OS_CONTINUE_BLOCKED_REQUEST_SMCINVOKE_ID \
	TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x07)

#define TZ_OS_CONTINUE_BLOCKED_REQUEST_ID_PARAM_ID \
	TZ_SYSCALL_CREATE_PARAM_ID_1(TZ_SYSCALL_PARAM_TYPE_VAL)