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

Commit 4a5ab2fd authored by Veera Sundaram Sankaran's avatar Veera Sundaram Sankaran
Browse files

drm/msm/sde: avoid secure-camera/secure-ui concurrency with other displays



Add checks to fail secure-camera/secure-ui updates on
other displays. Fail updates on primary with
secure-camera/secure-ui layers when other display
session is in-progress. This would avoid all the
concurrency during secure updates.

Change-Id: I7cba4d41e3a0c719e18e27689e48d58c16336fa9
Signed-off-by: default avatarVeera Sundaram Sankaran <veeras@codeaurora.org>
parent 9327317f
Loading
Loading
Loading
Loading
+53 −8
Original line number Diff line number Diff line
@@ -1790,10 +1790,54 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc,
	_sde_crtc_program_lm_output_roi(crtc);
}

static int _sde_crtc_find_plane_fb_modes(struct drm_crtc_state *state,
		uint32_t *fb_ns,
		uint32_t *fb_sec,
		uint32_t *fb_sec_dir)
int sde_crtc_find_plane_fb_modes(struct drm_crtc *crtc,
		uint32_t *fb_ns, uint32_t *fb_sec, uint32_t *fb_sec_dir)
{
	struct drm_plane *plane;
	struct sde_plane_state *sde_pstate;
	uint32_t mode = 0;
	int rc;

	if (!crtc) {
		SDE_ERROR("invalid state\n");
		return -EINVAL;
	}

	*fb_ns = 0;
	*fb_sec = 0;
	*fb_sec_dir = 0;
	drm_atomic_crtc_for_each_plane(plane, crtc) {
		if (IS_ERR_OR_NULL(plane) || IS_ERR_OR_NULL(plane->state)) {
			rc = PTR_ERR(plane);
			SDE_ERROR("crtc%d failed to get plane%d state%d\n",
					DRMID(crtc), DRMID(plane), rc);
			return rc;
		}
		sde_pstate = to_sde_plane_state(plane->state);
		mode = sde_plane_get_property(sde_pstate,
				PLANE_PROP_FB_TRANSLATION_MODE);

		switch (mode) {
		case SDE_DRM_FB_NON_SEC:
			(*fb_ns)++;
			break;
		case SDE_DRM_FB_SEC:
			(*fb_sec)++;
			break;
		case SDE_DRM_FB_SEC_DIR_TRANS:
			(*fb_sec_dir)++;
			break;
		default:
			SDE_ERROR("Error: Plane[%d], fb_trans_mode:%d",
					DRMID(plane), mode);
			return -EINVAL;
		}
	}
	return 0;
}

int sde_crtc_state_find_plane_fb_modes(struct drm_crtc_state *state,
		uint32_t *fb_ns, uint32_t *fb_sec, uint32_t *fb_sec_dir)
{
	struct drm_plane *plane;
	const struct drm_plane_state *pstate;
@@ -1813,13 +1857,13 @@ static int _sde_crtc_find_plane_fb_modes(struct drm_crtc_state *state,
		if (IS_ERR_OR_NULL(pstate)) {
			rc = PTR_ERR(pstate);
			SDE_ERROR("crtc%d failed to get plane%d state%d\n",
					state->crtc->base.id,
					plane->base.id, rc);
					DRMID(state->crtc), DRMID(plane), rc);
			return rc;
		}
		sde_pstate = to_sde_plane_state(pstate);
		mode = sde_plane_get_property(sde_pstate,
				PLANE_PROP_FB_TRANSLATION_MODE);

		switch (mode) {
		case SDE_DRM_FB_NON_SEC:
			(*fb_ns)++;
@@ -1832,7 +1876,7 @@ static int _sde_crtc_find_plane_fb_modes(struct drm_crtc_state *state,
			break;
		default:
			SDE_ERROR("Error: Plane[%d], fb_trans_mode:%d",
					plane->base.id, mode);
					DRMID(plane), mode);
			return -EINVAL;
		}
	}
@@ -4515,7 +4559,8 @@ static int _sde_crtc_check_secure_state(struct drm_crtc *crtc,

	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_state_find_plane_fb_modes(state, &fb_ns,
					&fb_sec, &fb_sec_dir);
	if (rc)
		return rc;

+22 −0
Original line number Diff line number Diff line
@@ -746,6 +746,28 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc,
		struct drm_crtc_state *old_crtc_state,
		bool old_valid_fb);

/**
 * sde_crtc_find_plane_fb_modes - finds the modes of all planes attached
 *                                  to crtc
 * @crtc: Pointer to DRM crtc object
 * @fb_ns: number of non secure planes
 * @fb_sec: number of secure-playback planes
 * @fb_sec_dir: number of secure-ui/secure-camera planes
 */
int sde_crtc_find_plane_fb_modes(struct drm_crtc *crtc,
		uint32_t *fb_ns, uint32_t *fb_sec, uint32_t *fb_sec_dir);

/**
 * sde_crtc_state_find_plane_fb_modes - finds the modes of all planes attached
 *                                       to the crtc state
 * @crtc_state: Pointer to DRM crtc state object
 * @fb_ns: number of non secure planes
 * @fb_sec: number of secure-playback planes
 * @fb_sec_dir: number of secure-ui/secure-camera planes
 */
int sde_crtc_state_find_plane_fb_modes(struct drm_crtc_state *state,
		uint32_t *fb_ns, uint32_t *fb_sec, uint32_t *fb_sec_dir);

/**
 * sde_crtc_secure_ctrl - Initiates the transition between secure and
 *                          non-secure world
+34 −31
Original line number Diff line number Diff line
@@ -2099,6 +2099,7 @@ static int sde_kms_check_secure_transition(struct msm_kms *kms,
	struct drm_crtc_state *crtc_state;
	int active_crtc_cnt = 0, global_active_crtc_cnt = 0;
	bool sec_session = false, global_sec_session = false;
	uint32_t fb_ns = 0, fb_sec = 0, fb_sec_dir = 0;
	int i;

	if (!kms || !state) {
@@ -2115,56 +2116,58 @@ static int sde_kms_check_secure_transition(struct msm_kms *kms,
			continue;

		active_crtc_cnt++;
		if (sde_crtc_get_secure_level(crtc, crtc_state) ==
				SDE_DRM_SEC_ONLY)
		sde_crtc_state_find_plane_fb_modes(crtc_state, &fb_ns,
				&fb_sec, &fb_sec_dir);
		if (fb_sec_dir)
			sec_session = true;

		cur_crtc = crtc;
	}

	/* iterate global list for active and secure crtc */
	/* iterate global list for active and secure/non-secure crtc */
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		if (!crtc->state->active)
			continue;

		global_active_crtc_cnt++;
		if (sde_crtc_get_secure_level(crtc, crtc->state) ==
				SDE_DRM_SEC_ONLY)
		/* update only when crtc is not the same as current crtc */
		if (crtc != cur_crtc) {
			fb_ns = fb_sec = fb_sec_dir = 0;
			sde_crtc_find_plane_fb_modes(crtc, &fb_ns,
					&fb_sec, &fb_sec_dir);
			if (fb_sec_dir)
				global_sec_session = true;

			global_crtc = crtc;
		}
	}

	if (!global_sec_session && !sec_session)
		return 0;

	/*
	 * - 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
	 * - fail crtc commit, if secure-camera/secure-ui session is
	 *   in-progress in any other display
	 * - fail secure-camera/secure-ui crtc commit, if any other display
	 *   session is in-progress
	 */
	if (global_sec_session || sec_session) {
		if ((global_active_crtc_cnt >
					MAX_ALLOWED_CRTC_CNT_DURING_SECURE) ||
	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",
		    "crtc%d secure check failed global_active:%d active:%d\n",
				cur_crtc ? cur_crtc->base.id : -1,
				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
	 * in this commit should match with the global crtc
	 */
		} else if (global_crtc && (global_crtc != cur_crtc)) {
			SDE_ERROR(
			    "crtc%d-sec%d not allowed during crtc%d-sec%d\n",
				cur_crtc ? cur_crtc->base.id : -1, sec_session,
	} else if (global_crtc && cur_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;
}