diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_layer.c | 41 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_overlay.c | 38 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_util.c | 57 | ||||
| -rw-r--r-- | include/uapi/linux/msm_mdp_ext.h | 3 |
4 files changed, 118 insertions, 21 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_layer.c b/drivers/video/fbdev/msm/mdss_mdp_layer.c index 1a7681e4f904..434d10e996df 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_layer.c +++ b/drivers/video/fbdev/msm/mdss_mdp_layer.c @@ -444,6 +444,8 @@ static int __configure_pipe_params(struct msm_fb_data_type *mfd, pipe->flags |= MDP_FLIP_UD; if (layer->flags & MDP_LAYER_SECURE_SESSION) pipe->flags |= MDP_SECURE_OVERLAY_SESSION; + if (layer->flags & MDP_LAYER_SECURE_DISPLAY_SESSION) + pipe->flags |= MDP_SECURE_DISPLAY_OVERLAY_SESSION; if (layer->flags & MDP_LAYER_SOLID_FILL) pipe->flags |= MDP_SOLID_FILL; if (layer->flags & MDP_LAYER_DEINTERLACE) @@ -812,7 +814,8 @@ static struct mdss_mdp_data *__map_layer_buffer(struct msm_fb_data_type *mfd, goto end; } - flags = (pipe->flags & MDP_SECURE_OVERLAY_SESSION); + flags = (pipe->flags & (MDP_SECURE_OVERLAY_SESSION | + MDP_SECURE_DISPLAY_OVERLAY_SESSION)); /* current implementation only supports one plane mapping */ if (buffer->planes[0].fd < 0) { @@ -977,6 +980,40 @@ end: } /* + * __validate_secure_display() - validate secure display + * + * This function travers through used pipe list and checks if any pipe + * is with secure display enabled flag. It fails if client tries to stage + * unsecure content with secure display session. + * + */ +static int __validate_secure_display(struct mdss_overlay_private *mdp5_data) +{ + struct mdss_mdp_pipe *pipe, *tmp; + uint32_t sd_pipes = 0, nonsd_pipes = 0; + + mutex_lock(&mdp5_data->list_lock); + list_for_each_entry_safe(pipe, tmp, &mdp5_data->pipes_used, list) { + if (pipe->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) + sd_pipes++; + else + nonsd_pipes++; + } + mutex_unlock(&mdp5_data->list_lock); + + pr_debug("pipe count:: secure display:%d non-secure:%d\n", + sd_pipes, nonsd_pipes); + + if (sd_pipes && nonsd_pipes) { + pr_err("pipe count:: secure display:%d non-secure:%d\n", + sd_pipes, nonsd_pipes); + return -EINVAL; + } else { + return 0; + } +} + +/* * __handle_free_list() - updates free pipe list * * This function travers through used pipe list and checks if any pipe @@ -1207,6 +1244,8 @@ static int __validate_layers(struct msm_fb_data_type *mfd, __handle_free_list(mdp5_data, layer_list, layer_count); + ret = __validate_secure_display(mdp5_data); + validate_exit: pr_debug("err=%d total_layer:%d left:%d right:%d release_ndx=0x%x processed=%d\n", ret, layer_count, left_lm_layers, right_lm_layers, diff --git a/drivers/video/fbdev/msm/mdss_mdp_overlay.c b/drivers/video/fbdev/msm/mdss_mdp_overlay.c index 0c6c84050dbc..7456485a8dd7 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_overlay.c +++ b/drivers/video/fbdev/msm/mdss_mdp_overlay.c @@ -1853,17 +1853,17 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, pipe->num, pipe->flags); } } + /* - * If there is no secure display session and sd_enabled, disable the - * secure display session + * start secure display session if there is secure display session and + * sd_enabled is not true. */ - if (!sd_in_pipe && mdp5_data->sd_enabled) { - /* disable the secure display on last client */ - if (mdss_get_sd_client_cnt() == 1) - ret = mdss_mdp_secure_display_ctrl(0); + if (!mdp5_data->sd_enabled && sd_in_pipe) { + if (!mdss_get_sd_client_cnt()) + ret = mdss_mdp_secure_display_ctrl(1); if (!ret) { - mdss_update_sd_client(mdp5_data->mdata, false); - mdp5_data->sd_enabled = 0; + mdp5_data->sd_enabled = 1; + mdss_update_sd_client(mdp5_data->mdata, true); } } @@ -1935,14 +1935,17 @@ int mdss_mdp_overlay_kickoff(struct msm_fb_data_type *mfd, ATRACE_END("display_wait4comp"); mutex_lock(&mdp5_data->ov_lock); - if (ret == 0) { - if (!mdp5_data->sd_enabled && sd_in_pipe) { - if (!mdss_get_sd_client_cnt()) - ret = mdss_mdp_secure_display_ctrl(1); - if (!ret) { - mdp5_data->sd_enabled = 1; - mdss_update_sd_client(mdp5_data->mdata, true); - } + /* + * If there is no secure display session and sd_enabled, disable the + * secure display session + */ + if (mdp5_data->sd_enabled && !sd_in_pipe && !ret) { + /* disable the secure display on last client */ + if (mdss_get_sd_client_cnt() == 1) + ret = mdss_mdp_secure_display_ctrl(0); + if (!ret) { + mdss_update_sd_client(mdp5_data->mdata, false); + mdp5_data->sd_enabled = 0; } } @@ -2136,7 +2139,8 @@ static int mdss_mdp_overlay_queue(struct msm_fb_data_type *mfd, if (pipe->flags & MDP_SOLID_FILL) pr_warn("Unexpected buffer queue to a solid fill pipe\n"); - flags = (pipe->flags & MDP_SECURE_OVERLAY_SESSION); + flags = (pipe->flags & (MDP_SECURE_OVERLAY_SESSION | + MDP_SECURE_DISPLAY_OVERLAY_SESSION)); mutex_lock(&mdp5_data->list_lock); src_data = mdss_mdp_overlay_buf_alloc(mfd, pipe); diff --git a/drivers/video/fbdev/msm/mdss_mdp_util.c b/drivers/video/fbdev/msm/mdss_mdp_util.c index 46499c592211..53c6756efc8d 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_util.c +++ b/drivers/video/fbdev/msm/mdss_mdp_util.c @@ -30,6 +30,8 @@ #include "mdss_smmu.h" #include "mdss_panel.h" +#define PHY_ADDR_4G (1ULL<<32) + enum { MDP_INTR_VSYNC_INTF_0, MDP_INTR_VSYNC_INTF_1, @@ -965,7 +967,12 @@ static int mdss_mdp_put_img(struct mdss_mdp_img_data *data, bool rotator, data->srcp_dma_buf = NULL; } } - + } else if (data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION) { + /* + * skip memory unmapping - secure display uses physical + * address which does not require buffer unmapping + */ + pr_debug("skip memory unmapping for secure display content\n"); } else { return -ENOMEM; } @@ -1007,7 +1014,8 @@ static int mdss_mdp_get_img(struct msmfb_data *img, pr_err("invalid FB_MAJOR\n"); ret = -1; } - } else if (iclient) { + } else if (iclient && + !(data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)) { data->srcp_dma_buf = dma_buf_get(img->memory_id); if (IS_ERR(data->srcp_dma_buf)) { pr_err("error on ion_import_fd\n"); @@ -1039,6 +1047,48 @@ static int mdss_mdp_get_img(struct msmfb_data *img, /* return early, mapping will be done later */ return 0; + } else if (iclient && + (data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)) { + struct ion_handle *ihandle = NULL; + struct sg_table *sg_ptr = NULL; + + do { + ihandle = ion_import_dma_buf(iclient, img->memory_id); + if (IS_ERR_OR_NULL(ihandle)) { + ret = -EINVAL; + pr_err("ion import buffer failed\n"); + break; + } + + sg_ptr = ion_sg_table(iclient, ihandle); + if (sg_ptr == NULL) { + pr_err("ion sg table get failed\n"); + ret = -EINVAL; + break; + } + + if (sg_ptr->nents != 1) { + pr_err("ion buffer mapping failed\n"); + ret = -EINVAL; + break; + } + + if (((uint64_t)sg_dma_address(sg_ptr->sgl) >= + PHY_ADDR_4G - sg_ptr->sgl->length)) { + pr_err("ion buffer mapped size is invalid\n"); + ret = -EINVAL; + break; + } + + data->addr = sg_dma_address(sg_ptr->sgl); + data->len = sg_ptr->sgl->length; + data->mapped = true; + ret = 0; + } while (0); + + if (!IS_ERR_OR_NULL(ihandle)) + ion_free(iclient, ihandle); + return ret; } if (!*start) { @@ -1076,7 +1126,8 @@ static int mdss_mdp_map_buffer(struct mdss_mdp_img_data *data, bool rotator, return 0; if (!IS_ERR_OR_NULL(data->srcp_dma_buf)) { - if (mdss_res->mdss_util->iommu_attached()) { + if (mdss_res->mdss_util->iommu_attached() && + !(data->flags & MDP_SECURE_DISPLAY_OVERLAY_SESSION)) { domain = mdss_smmu_get_domain_type(data->flags, rotator); ret = mdss_smmu_map_dma_buf(data->srcp_dma_buf, diff --git a/include/uapi/linux/msm_mdp_ext.h b/include/uapi/linux/msm_mdp_ext.h index afb462069224..845133bfd8f8 100644 --- a/include/uapi/linux/msm_mdp_ext.h +++ b/include/uapi/linux/msm_mdp_ext.h @@ -62,6 +62,9 @@ LAYER FLAG CONFIGURATION /* layer contains postprocessing configuration data */ #define MDP_LAYER_PP 0x200 +/* Flag indicates that layer is associated with secure display session */ +#define MDP_LAYER_SECURE_DISPLAY_SESSION 0x400 + /********************************************************************** VALIDATE/COMMIT FLAG CONFIGURATION **********************************************************************/ |
