Commit cf322b49 authored by Nicholas Kazlauskas's avatar Nicholas Kazlauskas Committed by Alex Deucher
Browse files

drm/amd/display: Avoid using unvalidated tiling_flags and tmz_surface in prepare_planes



[Why]
We're racing with userspace as the flags could potentially change
from when we acquired and validated them in commit_check.

[How]
We unfortunately can't drop this function in its entirety from
prepare_planes since we don't know the afb->address at commit_check
time yet.

So instead of querying new tiling_flags and tmz_surface use the ones
from the plane_state directly.

While we're at it, also update the force_disable_dcc option based
on the state from atomic check.

Signed-off-by: default avatarNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Reviewed-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 9a81cc60
Loading
Loading
Loading
Loading
+19 −17
Original line number Diff line number Diff line
@@ -5716,14 +5716,8 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
	struct list_head list;
	struct ttm_validate_buffer tv;
	struct ww_acquire_ctx ticket;
	uint64_t tiling_flags;
	uint32_t domain;
	int r;
	bool tmz_surface = false;
	bool force_disable_dcc = false;

	dm_plane_state_old = to_dm_plane_state(plane->state);
	dm_plane_state_new = to_dm_plane_state(new_state);

	if (!new_state->fb) {
		DRM_DEBUG_DRIVER("No FB bound\n");
@@ -5767,27 +5761,35 @@ static int dm_plane_helper_prepare_fb(struct drm_plane *plane,
		return r;
	}

	amdgpu_bo_get_tiling_flags(rbo, &tiling_flags);

	tmz_surface = amdgpu_bo_encrypted(rbo);

	ttm_eu_backoff_reservation(&ticket, &list);

	afb->address = amdgpu_bo_gpu_offset(rbo);

	amdgpu_bo_ref(rbo);

	/**
	 * We don't do surface updates on planes that have been newly created,
	 * but we also don't have the afb->address during atomic check.
	 *
	 * Fill in buffer attributes depending on the address here, but only on
	 * newly created planes since they're not being used by DC yet and this
	 * won't modify global state.
	 */
	dm_plane_state_old = to_dm_plane_state(plane->state);
	dm_plane_state_new = to_dm_plane_state(new_state);

	if (dm_plane_state_new->dc_state &&
	    dm_plane_state_old->dc_state != dm_plane_state_new->dc_state) {
		struct dc_plane_state *plane_state = dm_plane_state_new->dc_state;
		struct dc_plane_state *plane_state =
			dm_plane_state_new->dc_state;
		bool force_disable_dcc = !plane_state->dcc.enable;

		force_disable_dcc = adev->asic_type == CHIP_RAVEN && adev->in_suspend;
		fill_plane_buffer_attributes(
			adev, afb, plane_state->format, plane_state->rotation,
			tiling_flags, &plane_state->tiling_info,
			&plane_state->plane_size, &plane_state->dcc,
			&plane_state->address, tmz_surface,
			force_disable_dcc);
			dm_plane_state_new->tiling_flags,
			&plane_state->tiling_info, &plane_state->plane_size,
			&plane_state->dcc, &plane_state->address,
			dm_plane_state_new->tmz_surface, force_disable_dcc);
	}

	return 0;