Commit 03fc4cf4 authored by Mark Yacoub's avatar Mark Yacoub Committed by Alex Deucher
Browse files

drm/amd/display: Verify Gamma & Degamma LUT sizes in amdgpu_dm_atomic_check



For each CRTC state, check the size of Gamma and Degamma LUTs  so
unexpected and larger sizes wouldn't slip through.

TEST: IGT:kms_color::pipe-invalid-gamma-lut-sizes

v2: fix assignments in if clauses, Mark's email.

Reviewed-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarMark Yacoub <markyacoub@chromium.org>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 3a07101b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -10245,6 +10245,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
			dm_old_crtc_state->dsc_force_changed == false)
			continue;

		ret = amdgpu_dm_verify_lut_sizes(new_crtc_state);
		if (ret)
			goto fail;

		if (!new_crtc_state->enable)
			continue;

+1 −0
Original line number Diff line number Diff line
@@ -617,6 +617,7 @@ void amdgpu_dm_trigger_timing_sync(struct drm_device *dev);
#define MAX_COLOR_LEGACY_LUT_ENTRIES 256

void amdgpu_dm_init_color_mod(void);
int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state);
int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc);
int amdgpu_dm_update_plane_color_mgmt(struct dm_crtc_state *crtc,
				      struct dc_plane_state *dc_plane_state);
+35 −6
Original line number Diff line number Diff line
@@ -284,6 +284,37 @@ static int __set_input_tf(struct dc_transfer_func *func,
	return res ? 0 : -ENOMEM;
}

/**
 * Verifies that the Degamma and Gamma LUTs attached to the |crtc_state| are of
 * the expected size.
 * Returns 0 on success.
 */
int amdgpu_dm_verify_lut_sizes(const struct drm_crtc_state *crtc_state)
{
	const struct drm_color_lut *lut = NULL;
	uint32_t size = 0;

	lut = __extract_blob_lut(crtc_state->degamma_lut, &size);
	if (lut && size != MAX_COLOR_LUT_ENTRIES) {
		DRM_DEBUG_DRIVER(
			"Invalid Degamma LUT size. Should be %u but got %u.\n",
			MAX_COLOR_LUT_ENTRIES, size);
		return -EINVAL;
	}

	lut = __extract_blob_lut(crtc_state->gamma_lut, &size);
	if (lut && size != MAX_COLOR_LUT_ENTRIES &&
	    size != MAX_COLOR_LEGACY_LUT_ENTRIES) {
		DRM_DEBUG_DRIVER(
			"Invalid Gamma LUT size. Should be %u (or %u for legacy) but got %u.\n",
			MAX_COLOR_LUT_ENTRIES, MAX_COLOR_LEGACY_LUT_ENTRIES,
			size);
		return -EINVAL;
	}

	return 0;
}

/**
 * amdgpu_dm_update_crtc_color_mgmt: Maps DRM color management to DC stream.
 * @crtc: amdgpu_dm crtc state
@@ -317,14 +348,12 @@ int amdgpu_dm_update_crtc_color_mgmt(struct dm_crtc_state *crtc)
	bool is_legacy;
	int r;

	degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, &degamma_size);
	if (degamma_lut && degamma_size != MAX_COLOR_LUT_ENTRIES)
		return -EINVAL;
	r = amdgpu_dm_verify_lut_sizes(&crtc->base);
	if (r)
		return r;

	degamma_lut = __extract_blob_lut(crtc->base.degamma_lut, &degamma_size);
	regamma_lut = __extract_blob_lut(crtc->base.gamma_lut, &regamma_size);
	if (regamma_lut && regamma_size != MAX_COLOR_LUT_ENTRIES &&
	    regamma_size != MAX_COLOR_LEGACY_LUT_ENTRIES)
		return -EINVAL;

	has_degamma =
		degamma_lut && !__is_lut_linear(degamma_lut, degamma_size);