From d2a24edb532e6599755fc1bbd080cf57e0dd72c3 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Thu, 15 Mar 2018 17:22:41 +0200 Subject: [PATCH] drm: Verify gamma/degamma LUT size MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit While we want to potentially support multiple different gamma/degamma LUT sizes we can (and should) at least check that the blob length is a multiple of the LUT entry size. v2: s/expected_size_mod/expected_elem_size/ (Daniel) Add kernel doc (Daniel) v3: s/we/were/ typo in the docs Cc: Daniel Vetter Signed-off-by: Ville Syrjälä Reviewed-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180315152241.7113-1-ville.syrjala@linux.intel.com --- Documentation/gpu/drm-kms.rst | 3 +++ drivers/gpu/drm/drm_atomic.c | 39 +++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 56a3780e39b8..1dffd1ac4cd4 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -286,6 +286,9 @@ Atomic Mode Setting Function Reference .. kernel-doc:: drivers/gpu/drm/drm_atomic.c :export: +.. kernel-doc:: drivers/gpu/drm/drm_atomic.c + :internal: + CRTC Abstraction ================ diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 01060669dd49..7d25c42f22db 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -408,11 +408,36 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, } EXPORT_SYMBOL(drm_atomic_set_mode_prop_for_crtc); +/** + * drm_atomic_replace_property_blob_from_id - lookup the new blob and replace the old one with it + * @dev: DRM device + * @blob: a pointer to the member blob to be replaced + * @blob_id: ID of the new blob + * @expected_size: total expected size of the blob data (in bytes) + * @expected_elem_size: expected element size of the blob data (in bytes) + * @replaced: did the blob get replaced? + * + * Replace @blob with another blob with the ID @blob_id. If @blob_id is zero + * @blob becomes NULL. + * + * If @expected_size is positive the new blob length is expected to be equal + * to @expected_size bytes. If @expected_elem_size is positive the new blob + * length is expected to be a multiple of @expected_elem_size bytes. Otherwise + * an error is returned. + * + * @replaced will indicate to the caller whether the blob was replaced or not. + * If the old and new blobs were in fact the same blob @replaced will be false + * otherwise it will be true. + * + * RETURNS: + * Zero on success, error code on failure. + */ static int drm_atomic_replace_property_blob_from_id(struct drm_device *dev, struct drm_property_blob **blob, uint64_t blob_id, ssize_t expected_size, + ssize_t expected_elem_size, bool *replaced) { struct drm_property_blob *new_blob = NULL; @@ -422,7 +447,13 @@ drm_atomic_replace_property_blob_from_id(struct drm_device *dev, if (new_blob == NULL) return -EINVAL; - if (expected_size > 0 && expected_size != new_blob->length) { + if (expected_size > 0 && + new_blob->length != expected_size) { + drm_property_blob_put(new_blob); + return -EINVAL; + } + if (expected_elem_size > 0 && + new_blob->length % expected_elem_size != 0) { drm_property_blob_put(new_blob); return -EINVAL; } @@ -470,7 +501,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, ret = drm_atomic_replace_property_blob_from_id(dev, &state->degamma_lut, val, - -1, + -1, sizeof(struct drm_color_lut), &replaced); state->color_mgmt_changed |= replaced; return ret; @@ -478,7 +509,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, ret = drm_atomic_replace_property_blob_from_id(dev, &state->ctm, val, - sizeof(struct drm_color_ctm), + sizeof(struct drm_color_ctm), -1, &replaced); state->color_mgmt_changed |= replaced; return ret; @@ -486,7 +517,7 @@ int drm_atomic_crtc_set_property(struct drm_crtc *crtc, ret = drm_atomic_replace_property_blob_from_id(dev, &state->gamma_lut, val, - -1, + -1, sizeof(struct drm_color_lut), &replaced); state->color_mgmt_changed |= replaced; return ret; -- 2.30.2