Loading drivers/gpu/drm/msm/sde/sde_crtc.c +38 −30 Original line number Diff line number Diff line Loading @@ -4329,13 +4329,14 @@ static int _sde_crtc_excl_dim_layer_check(struct drm_crtc_state *state, } static int _sde_crtc_check_secure_state(struct drm_crtc *crtc, struct drm_crtc_state *state) struct drm_crtc_state *state, struct plane_state pstates[], int cnt) { struct drm_encoder *encoder; struct sde_crtc_state *cstate; uint32_t secure; uint32_t fb_ns = 0, fb_sec = 0, fb_sec_dir = 0; int encoder_cnt = 0; int encoder_cnt = 0, i; int rc; if (!crtc || !state) { Loading @@ -4345,31 +4346,40 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc, cstate = to_sde_crtc_state(state); secure = sde_crtc_get_property(cstate, CRTC_PROP_SECURITY_LEVEL); secure = sde_crtc_get_property(cstate, CRTC_PROP_SECURITY_LEVEL); rc = _sde_crtc_find_plane_fb_modes(state, &fb_ns, &fb_sec, &fb_sec_dir); rc = _sde_crtc_find_plane_fb_modes(state, &fb_ns, &fb_sec, &fb_sec_dir); if (rc) return rc; /** * validate planes * fb_sec_dir is for secure camera preview and secure display use case, * fb_sec is for secure video playback, * fb_ns is for normal non secure use cases. if (secure == SDE_DRM_SEC_ONLY) { /* * validate planes - only fb_sec_dir is allowed during sec_crtc * - fb_sec_dir is for secure camera preview and * secure display use case * - fb_sec is for secure video playback * - fb_ns is for normal non secure use cases */ if ((secure == SDE_DRM_SEC_ONLY) && (fb_ns || fb_sec || (fb_sec && fb_sec_dir))) { if (fb_ns || fb_sec) { SDE_ERROR( "crtc%d: invalid planes fb_modes Sec:%d, NS:%d, Sec_Dir:%d\n", "crtc%d: invalid fb_modes Sec:%d, NS:%d, Sec_Dir:%d\n", crtc->base.id, fb_sec, fb_ns, fb_sec_dir); return -EINVAL; } /** /* only one blending stage is allowed in sec_crtc */ for (i = 1; i < cnt; i++) { if (pstates[i].stage != pstates[i-1].stage) { SDE_ERROR( "crtc%d: invalid blend stages %d:%d, %d:%d\n", crtc->base.id, i, pstates[i].stage, i-1, pstates[i-1].stage); return -EINVAL; } } } /* * secure_crtc is not allowed in a shared toppolgy * across different encoders. */ Loading @@ -4378,17 +4388,15 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc, if (encoder->crtc == crtc) encoder_cnt++; if (encoder_cnt > MAX_ALLOWED_ENCODER_CNT_PER_SECURE_CRTC) { SDE_ERROR( "crtc%d, invalid virtual encoder crtc%d\n", crtc->base.id, encoder_cnt); if (encoder_cnt > MAX_ALLOWED_ENCODER_CNT_PER_SECURE_CRTC) { SDE_ERROR("crtc%d, invalid virtual encoder crtc%d\n", crtc->base.id, encoder_cnt); return -EINVAL; } } SDE_DEBUG("crtc:%d Secure validation successful\n", crtc->base.id); return 0; } Loading Loading @@ -4445,10 +4453,6 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc, _sde_crtc_setup_is_ppsplit(state); _sde_crtc_setup_lm_bounds(crtc, state); rc = _sde_crtc_check_secure_state(crtc, state); if (rc) return rc; /* get plane state for all drm planes associated with crtc state */ drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { if (IS_ERR_OR_NULL(pstate)) { Loading Loading @@ -4522,6 +4526,10 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc, /* assign mixer stages based on sorted zpos property */ sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL); rc = _sde_crtc_check_secure_state(crtc, state, pstates, cnt); if (rc) goto end; rc = _sde_crtc_excl_dim_layer_check(state, pstates, cnt); if (rc) goto end; Loading drivers/gpu/drm/msm/sde/sde_kms.c +44 −36 Original line number Diff line number Diff line Loading @@ -1910,10 +1910,10 @@ static int sde_kms_check_secure_transition(struct msm_kms *kms, struct sde_kms *sde_kms; struct drm_device *dev; struct drm_crtc *crtc; struct drm_crtc *sec_crtc = NULL, *temp_crtc = NULL; struct drm_crtc *cur_crtc = NULL, *global_crtc = NULL; struct drm_crtc_state *crtc_state; int secure_crtc_cnt = 0, active_crtc_cnt = 0; int secure_global_crtc_cnt = 0, active_mode_crtc_cnt = 0; int active_crtc_cnt = 0, global_active_crtc_cnt = 0; bool sec_session = false, global_sec_session = false; int i; if (!kms || !state) { Loading @@ -1921,56 +1921,64 @@ static int sde_kms_check_secure_transition(struct msm_kms *kms, SDE_ERROR("invalid arguments\n"); } /* iterate state object for active and secure crtc */ sde_kms = to_sde_kms(kms); dev = sde_kms->dev; /* iterate state object for active secure/non-secure crtc */ for_each_crtc_in_state(state, crtc, crtc_state, i) { if (!crtc_state->active) continue; active_crtc_cnt++; if (sde_crtc_get_secure_level(crtc, crtc_state) == SDE_DRM_SEC_ONLY) { sec_crtc = crtc; secure_crtc_cnt++; } } /* bail out from further validation if no secure ctrc */ if (!secure_crtc_cnt) return 0; SDE_DRM_SEC_ONLY) sec_session = true; if ((secure_crtc_cnt > MAX_ALLOWED_SECURE_CLIENT_CNT) || (secure_crtc_cnt && (active_crtc_cnt > MAX_ALLOWED_CRTC_CNT_DURING_SECURE))) { SDE_ERROR("Secure check failed active:%d, secure:%d\n", active_crtc_cnt, secure_crtc_cnt); return -EPERM; cur_crtc = crtc; } sde_kms = to_sde_kms(kms); dev = sde_kms->dev; /* iterate global list for active and secure crtc */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (!crtc->state->active) continue; active_mode_crtc_cnt++; global_active_crtc_cnt++; if (sde_crtc_get_secure_level(crtc, crtc->state) == SDE_DRM_SEC_ONLY) { secure_global_crtc_cnt++; temp_crtc = crtc; } SDE_DRM_SEC_ONLY) global_sec_session = true; global_crtc = crtc; } /** * if more than one crtc is active fail * check if the previous and current commit secure * are same /* * - fail secure crtc commit, if any other crtc session is already * in progress * - fail non-secure crtc commit, if any secure crtc session is already * in progress */ if (secure_crtc_cnt && ((active_mode_crtc_cnt > 1) || (secure_global_crtc_cnt && (temp_crtc != sec_crtc)))) SDE_ERROR("Secure check failed active:%d crtc_id:%d\n", active_mode_crtc_cnt, temp_crtc->base.id); if (global_sec_session || sec_session) { if ((global_active_crtc_cnt > MAX_ALLOWED_CRTC_CNT_DURING_SECURE) || (active_crtc_cnt > MAX_ALLOWED_CRTC_CNT_DURING_SECURE)) { SDE_ERROR( "Secure check failed global_active:%d active:%d\n", global_active_crtc_cnt, active_crtc_cnt); return -EPERM; /* * As only one crtc is allowed during secure session, the crtc * in this commit should match with the global crtc, if it * exists */ } else if (global_crtc && (global_crtc != cur_crtc)) { SDE_ERROR( "crtc%d-sec%d not allowed during crtc%d-sec%d\n", cur_crtc->base.id, sec_session, global_crtc->base.id, global_sec_session); return -EPERM; } } return 0; } Loading Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +38 −30 Original line number Diff line number Diff line Loading @@ -4329,13 +4329,14 @@ static int _sde_crtc_excl_dim_layer_check(struct drm_crtc_state *state, } static int _sde_crtc_check_secure_state(struct drm_crtc *crtc, struct drm_crtc_state *state) struct drm_crtc_state *state, struct plane_state pstates[], int cnt) { struct drm_encoder *encoder; struct sde_crtc_state *cstate; uint32_t secure; uint32_t fb_ns = 0, fb_sec = 0, fb_sec_dir = 0; int encoder_cnt = 0; int encoder_cnt = 0, i; int rc; if (!crtc || !state) { Loading @@ -4345,31 +4346,40 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc, cstate = to_sde_crtc_state(state); secure = sde_crtc_get_property(cstate, CRTC_PROP_SECURITY_LEVEL); secure = sde_crtc_get_property(cstate, CRTC_PROP_SECURITY_LEVEL); rc = _sde_crtc_find_plane_fb_modes(state, &fb_ns, &fb_sec, &fb_sec_dir); rc = _sde_crtc_find_plane_fb_modes(state, &fb_ns, &fb_sec, &fb_sec_dir); if (rc) return rc; /** * validate planes * fb_sec_dir is for secure camera preview and secure display use case, * fb_sec is for secure video playback, * fb_ns is for normal non secure use cases. if (secure == SDE_DRM_SEC_ONLY) { /* * validate planes - only fb_sec_dir is allowed during sec_crtc * - fb_sec_dir is for secure camera preview and * secure display use case * - fb_sec is for secure video playback * - fb_ns is for normal non secure use cases */ if ((secure == SDE_DRM_SEC_ONLY) && (fb_ns || fb_sec || (fb_sec && fb_sec_dir))) { if (fb_ns || fb_sec) { SDE_ERROR( "crtc%d: invalid planes fb_modes Sec:%d, NS:%d, Sec_Dir:%d\n", "crtc%d: invalid fb_modes Sec:%d, NS:%d, Sec_Dir:%d\n", crtc->base.id, fb_sec, fb_ns, fb_sec_dir); return -EINVAL; } /** /* only one blending stage is allowed in sec_crtc */ for (i = 1; i < cnt; i++) { if (pstates[i].stage != pstates[i-1].stage) { SDE_ERROR( "crtc%d: invalid blend stages %d:%d, %d:%d\n", crtc->base.id, i, pstates[i].stage, i-1, pstates[i-1].stage); return -EINVAL; } } } /* * secure_crtc is not allowed in a shared toppolgy * across different encoders. */ Loading @@ -4378,17 +4388,15 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc, if (encoder->crtc == crtc) encoder_cnt++; if (encoder_cnt > MAX_ALLOWED_ENCODER_CNT_PER_SECURE_CRTC) { SDE_ERROR( "crtc%d, invalid virtual encoder crtc%d\n", crtc->base.id, encoder_cnt); if (encoder_cnt > MAX_ALLOWED_ENCODER_CNT_PER_SECURE_CRTC) { SDE_ERROR("crtc%d, invalid virtual encoder crtc%d\n", crtc->base.id, encoder_cnt); return -EINVAL; } } SDE_DEBUG("crtc:%d Secure validation successful\n", crtc->base.id); return 0; } Loading Loading @@ -4445,10 +4453,6 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc, _sde_crtc_setup_is_ppsplit(state); _sde_crtc_setup_lm_bounds(crtc, state); rc = _sde_crtc_check_secure_state(crtc, state); if (rc) return rc; /* get plane state for all drm planes associated with crtc state */ drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) { if (IS_ERR_OR_NULL(pstate)) { Loading Loading @@ -4522,6 +4526,10 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc, /* assign mixer stages based on sorted zpos property */ sort(pstates, cnt, sizeof(pstates[0]), pstate_cmp, NULL); rc = _sde_crtc_check_secure_state(crtc, state, pstates, cnt); if (rc) goto end; rc = _sde_crtc_excl_dim_layer_check(state, pstates, cnt); if (rc) goto end; Loading
drivers/gpu/drm/msm/sde/sde_kms.c +44 −36 Original line number Diff line number Diff line Loading @@ -1910,10 +1910,10 @@ static int sde_kms_check_secure_transition(struct msm_kms *kms, struct sde_kms *sde_kms; struct drm_device *dev; struct drm_crtc *crtc; struct drm_crtc *sec_crtc = NULL, *temp_crtc = NULL; struct drm_crtc *cur_crtc = NULL, *global_crtc = NULL; struct drm_crtc_state *crtc_state; int secure_crtc_cnt = 0, active_crtc_cnt = 0; int secure_global_crtc_cnt = 0, active_mode_crtc_cnt = 0; int active_crtc_cnt = 0, global_active_crtc_cnt = 0; bool sec_session = false, global_sec_session = false; int i; if (!kms || !state) { Loading @@ -1921,56 +1921,64 @@ static int sde_kms_check_secure_transition(struct msm_kms *kms, SDE_ERROR("invalid arguments\n"); } /* iterate state object for active and secure crtc */ sde_kms = to_sde_kms(kms); dev = sde_kms->dev; /* iterate state object for active secure/non-secure crtc */ for_each_crtc_in_state(state, crtc, crtc_state, i) { if (!crtc_state->active) continue; active_crtc_cnt++; if (sde_crtc_get_secure_level(crtc, crtc_state) == SDE_DRM_SEC_ONLY) { sec_crtc = crtc; secure_crtc_cnt++; } } /* bail out from further validation if no secure ctrc */ if (!secure_crtc_cnt) return 0; SDE_DRM_SEC_ONLY) sec_session = true; if ((secure_crtc_cnt > MAX_ALLOWED_SECURE_CLIENT_CNT) || (secure_crtc_cnt && (active_crtc_cnt > MAX_ALLOWED_CRTC_CNT_DURING_SECURE))) { SDE_ERROR("Secure check failed active:%d, secure:%d\n", active_crtc_cnt, secure_crtc_cnt); return -EPERM; cur_crtc = crtc; } sde_kms = to_sde_kms(kms); dev = sde_kms->dev; /* iterate global list for active and secure crtc */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (!crtc->state->active) continue; active_mode_crtc_cnt++; global_active_crtc_cnt++; if (sde_crtc_get_secure_level(crtc, crtc->state) == SDE_DRM_SEC_ONLY) { secure_global_crtc_cnt++; temp_crtc = crtc; } SDE_DRM_SEC_ONLY) global_sec_session = true; global_crtc = crtc; } /** * if more than one crtc is active fail * check if the previous and current commit secure * are same /* * - fail secure crtc commit, if any other crtc session is already * in progress * - fail non-secure crtc commit, if any secure crtc session is already * in progress */ if (secure_crtc_cnt && ((active_mode_crtc_cnt > 1) || (secure_global_crtc_cnt && (temp_crtc != sec_crtc)))) SDE_ERROR("Secure check failed active:%d crtc_id:%d\n", active_mode_crtc_cnt, temp_crtc->base.id); if (global_sec_session || sec_session) { if ((global_active_crtc_cnt > MAX_ALLOWED_CRTC_CNT_DURING_SECURE) || (active_crtc_cnt > MAX_ALLOWED_CRTC_CNT_DURING_SECURE)) { SDE_ERROR( "Secure check failed global_active:%d active:%d\n", global_active_crtc_cnt, active_crtc_cnt); return -EPERM; /* * As only one crtc is allowed during secure session, the crtc * in this commit should match with the global crtc, if it * exists */ } else if (global_crtc && (global_crtc != cur_crtc)) { SDE_ERROR( "crtc%d-sec%d not allowed during crtc%d-sec%d\n", cur_crtc->base.id, sec_session, global_crtc->base.id, global_sec_session); return -EPERM; } } return 0; } Loading