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: Krishna Chaitanya Devarakonda <kdevarak@codeaurora.org>
This commit is contained in:
Krishna Chaitanya Devarakonda 2017-06-05 18:01:37 +05:30 committed by Gerrit - the friendly Code Review server
parent e5b8aadd07
commit c80985aa81
4 changed files with 69 additions and 4 deletions

View file

@ -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;
}

View file

@ -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);
@ -1291,7 +1303,7 @@ static int sde_hw_rotator_swts_map(struct sde_hw_rotator *rot)
data->mapped = true;
SDEROT_DBG("swts buffer mapped: %pad/%lx va:%p\n", &data->addr,
data->len, rot->swts_buffer);
data->len, rot->swts_buffer);
sde_smmu_ctrl(0);
return rc;
@ -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;
}

View file

@ -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)) {

View file

@ -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.
*/
@ -2393,9 +2418,19 @@ static int __overlay_secure_ctrl(struct msm_fb_data_type *mfd)
if (mdp5_data->secure_transition_state == SD_NON_SECURE_TO_SECURE) {
if (!mdss_get_sd_client_cnt()) {
MDSS_XLOG(0x11);
/*wait for ping pong done */
if (ctl->ops.wait_pingpong)
/* wait for ping pong done */
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