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

Commit c80985aa authored by Krishna Chaitanya Devarakonda's avatar Krishna Chaitanya Devarakonda Committed by Gerrit - the friendly Code Review server
Browse files

msm: mdss: unmap buffers before starting Secure Display session



IOMMU will be detached for Secure Display session. We need to make
sure to unmap all the buffers before detaching IOMMU. There are a
couple of cases where the buffer on pipe which is being used for
Secure Display, isn't unmapped before IOMMU detach. Add handling
for such cases in validate and kickoff. Also, add changes to wait
for secure session completion in rotator, before mapping buffers.

Change-Id: Ia47f519b8ba471848bbf2eef4ae1c010f1d0c1d2
Signed-off-by: default avatarKrishna Chaitanya Devarakonda <kdevarak@codeaurora.org>
parent e5b8aadd
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -621,9 +621,10 @@ static int sde_rotator_secure_session_ctrl(bool enable)
	if (mdata->wait_for_transition && mdata->secure_session_ctrl &&
		mdata->callback_request) {
		ret = mdata->wait_for_transition(mdata->sec_cam_en, enable);
		if (ret) {
		if (ret < 0) {
			SDEROT_ERR("failed Secure wait for transition %d\n",
				   ret);
			ret = -EPERM;
		} else {
			if (mdata->sec_cam_en ^ enable) {
				mdata->sec_cam_en = enable;
@@ -1090,6 +1091,8 @@ static int sde_rotator_assign_queue(struct sde_rot_mgr *mgr,
		if (IS_ERR_OR_NULL(hw)) {
			SDEROT_ERR("fail to allocate hw\n");
			ret = PTR_ERR(hw);
			if (!ret)
				ret = -EINVAL;
		} else {
			queue->hw = hw;
		}
+15 −1
Original line number Diff line number Diff line
@@ -1257,6 +1257,7 @@ err_put:
	data->srcp_dma_buf = NULL;
imap_err:
	ion_free(rot->iclient, handle);
	sde_smmu_ctrl(0);

	return rc;
}
@@ -1270,8 +1271,19 @@ static int sde_hw_rotator_swts_map(struct sde_hw_rotator *rot)
{
	int rc = 0;
	struct sde_mdp_img_data *data = &rot->swts_buf;
	struct sde_rot_data_type *mdata = sde_rot_get_mdata();

	sde_smmu_ctrl(1);
	if (mdata->wait_for_transition) {
		rc = mdata->wait_for_transition(0, 0);
		if (rc < 0) {
			SDEROT_ERR("failed Secure wait for transition %d\n",
					rc);
			rc = -EPERM;
			goto error;
		}
	}

	rc = sde_smmu_map_dma_buf(data->srcp_dma_buf, data->srcp_table,
			SDE_IOMMU_DOMAIN_ROT_UNSECURE, &data->addr,
			&data->len, DMA_BIDIRECTIONAL);
@@ -1301,6 +1313,8 @@ kmap_err:
err_unmap:
	dma_buf_unmap_attachment(data->srcp_attachment, data->srcp_table,
			DMA_FROM_DEVICE);
error:
	sde_smmu_ctrl(0);

	return rc;
}
+13 −0
Original line number Diff line number Diff line
@@ -1692,11 +1692,24 @@ static struct mdss_mdp_pipe *__find_and_move_cleanup_pipe(
	enum mdss_mdp_pipe_rect rect_num)
{
	struct mdss_mdp_pipe *pipe = NULL;
	struct mdss_mdp_data *buf, *tmpbuf;

	if (__find_pipe_in_list(&mdp5_data->pipes_destroy,
				pipe_ndx, &pipe, rect_num)) {
		pr_debug("reuse destroy pipe id:%d ndx:%d rect:%d\n",
				pipe->num, pipe_ndx, rect_num);
		/*
		 * Pipe is being moved from destroy list to used list.
		 * It is possible that the buffer which was attached to a pipe
		 * in destroy list hasn't been cleaned up yet. Mark the buffers
		 * as cleanup to make sure that they will be freed before the
		 * pipe is reused.
		 */
		list_for_each_entry_safe(buf, tmpbuf, &pipe->buf_queue,
						pipe_list) {
			buf->state = MDP_BUF_STATE_CLEANUP;
			list_del_init(&buf->pipe_list);
		}
		list_move(&pipe->list, &mdp5_data->pipes_used);
	} else if (__find_pipe_in_list(&mdp5_data->pipes_cleanup,
				pipe_ndx, &pipe, rect_num)) {
+37 −2
Original line number Diff line number Diff line
@@ -2317,6 +2317,31 @@ set_roi:
	mdss_mdp_set_roi(ctl, &l_roi, &r_roi);
}

/*
 * For the pipe which is being used for Secure Display,
 * cleanup the previously queued buffers.
 */
static void __overlay_cleanup_secure_pipe(struct msm_fb_data_type *mfd)
{
	struct mdss_overlay_private *mdp5_data = mfd_to_mdp5_data(mfd);
	struct mdss_mdp_pipe *pipe;
	struct mdss_mdp_data *buf, *tmpbuf;

	list_for_each_entry(pipe, &mdp5_data->pipes_used, list) {
		if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) {
			list_for_each_entry_safe(buf, tmpbuf, &pipe->buf_queue,
							pipe_list) {
				if (buf->state == MDP_BUF_STATE_ACTIVE) {
					__pipe_buf_mark_cleanup(mfd, buf);
					list_move(&buf->buf_list,
						&mdp5_data->bufs_freelist);
					mdss_mdp_overlay_buf_free(mfd, buf);
				}
			}
		}
	}
}

/*
 * Check if there is any change in secure state and store it.
 */
@@ -2394,8 +2419,18 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd)
		if (!mdss_get_sd_client_cnt()) {
			MDSS_XLOG(0x11);
			/* wait for ping pong done */
			if (ctl->ops.wait_pingpong)
			if (ctl->ops.wait_pingpong) {
				mdss_mdp_display_wait4pingpong(ctl, true);

				/*
				 * For command mode panels, there will not be
				 * a NULL commit preceding secure display. If
				 * a pipe is reused for secure display,
				 * cleanup buffers in the secure pipe before
				 * detaching IOMMU.
				 */
				__overlay_cleanup_secure_pipe(mfd);
			}
			/*
			 * unmap the previous commit buffers before
			 * transitioning to secure state