drm/edid: add function for checking drm_edid validity
authorJani Nikula <jani.nikula@intel.com>
Mon, 24 Oct 2022 12:33:36 +0000 (15:33 +0300)
committerJani Nikula <jani.nikula@intel.com>
Wed, 26 Oct 2022 06:53:17 +0000 (09:53 +0300)
We've lacked a function for immutable validity check on drm_edid. Add
one.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/f96188f64e9f7f3deff348d08296609353b12316.1666614699.git.jani.nikula@intel.com
drivers/gpu/drm/drm_edid.c
include/drm/drm_edid.h

index 616c1cdc750796149ba71d344e36e791113c01ec..c3cf942186b7acd38e12ac2772967d000cddc626 100644 (file)
@@ -2040,6 +2040,36 @@ bool drm_edid_is_valid(struct edid *edid)
 }
 EXPORT_SYMBOL(drm_edid_is_valid);
 
+/**
+ * drm_edid_valid - sanity check EDID data
+ * @drm_edid: EDID data
+ *
+ * Sanity check an EDID. Cross check block count against allocated size and
+ * checksum the blocks.
+ *
+ * Return: True if the EDID data is valid, false otherwise.
+ */
+bool drm_edid_valid(const struct drm_edid *drm_edid)
+{
+       int i;
+
+       if (!drm_edid)
+               return false;
+
+       if (edid_size_by_blocks(__drm_edid_block_count(drm_edid)) != drm_edid->size)
+               return false;
+
+       for (i = 0; i < drm_edid_block_count(drm_edid); i++) {
+               const void *block = drm_edid_block_data(drm_edid, i);
+
+               if (!edid_block_valid(block, i == 0))
+                       return false;
+       }
+
+       return true;
+}
+EXPORT_SYMBOL(drm_edid_valid);
+
 static struct edid *edid_filter_invalid_blocks(struct edid *edid,
                                               size_t *alloc_size)
 {
index 05380681a4fb52e2b3da2f616573c3a26e695fc7..a2e25e7e6ee593a5da2c50a9aae31aacf727dfae 100644 (file)
@@ -606,6 +606,7 @@ drm_display_mode_from_cea_vic(struct drm_device *dev,
 const struct drm_edid *drm_edid_alloc(const void *edid, size_t size);
 const struct drm_edid *drm_edid_dup(const struct drm_edid *drm_edid);
 void drm_edid_free(const struct drm_edid *drm_edid);
+bool drm_edid_valid(const struct drm_edid *drm_edid);
 const struct edid *drm_edid_raw(const struct drm_edid *drm_edid);
 const struct drm_edid *drm_edid_read(struct drm_connector *connector);
 const struct drm_edid *drm_edid_read_ddc(struct drm_connector *connector,