summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_layer.c41
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_overlay.c38
-rw-r--r--drivers/video/fbdev/msm/mdss_mdp_util.c57
-rw-r--r--include/uapi/linux/msm_mdp_ext.h3
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
**********************************************************************/