Skip to content

Commit

Permalink
drm/amd/display: Verify Gamma & Degamma LUT sizes in amdgpu_dm_atomic…
Browse files Browse the repository at this point in the history
…_check

[ Upstream commit 03fc4cf ]

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: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Mark Yacoub <markyacoub@chromium.org>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
Mark Yacoub authored and gregkh committed Jul 19, 2021
1 parent db3c364 commit a5f8862
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 6 deletions.
4 changes: 4 additions & 0 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Expand Up @@ -8745,6 +8745,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
old_crtc_state->vrr_enabled == new_crtc_state->vrr_enabled)
continue;

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

if (!new_crtc_state->enable)
continue;

Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
Expand Up @@ -498,6 +498,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);
Expand Down
41 changes: 35 additions & 6 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_color.c
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit a5f8862

Please sign in to comment.