[PATCH 2/3] drm: Perform basic sanity checks on probed modes

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Wed Dec 17 03:56:23 PST 2014


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

Make sure the timings of probed modes at least pass some very basic
sanity checks.

The checks include:
 - clock,hdisplay,vdisplay are non zero
 - sync pulse fits within the blanking period
 - htotal,vtotal are big enough

I have not checked all the drivers to see if the modes the generate
might violate these constraints. I'm hoping not, because that would mean
either abandoning the idea of doing this from the core code, or fixing
the drivers.

I'm not entirely sure about limiting the sync pulse to the blanking
period. Intel hardware doesn't support such things, but some other
hardware might. However at least HDMI doesn't allow having sync pulse
edges within the active period, so I'm thinking the check is probably
OK to have in the common code.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/drm_modes.c        | 32 ++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_probe_helper.c |  5 ++++-
 include/drm/drm_modes.h            |  1 +
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 61a4a9a..543f8c6 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -906,6 +906,38 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
 EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
 
 /**
+ * drm_mode_validate_basic - make sure the mode is somewhat sane
+ * @mode: mode to check
+ *
+ * Check that the mode timings are at least somewhat reasonable.
+ * Any hardware specific limits are left up for each driver to check.
+ *
+ * Returns:
+ * The mode status
+ */
+enum drm_mode_status
+drm_mode_validate_basic(const struct drm_display_mode *mode)
+{
+	if (mode->clock == 0)
+		return MODE_CLOCK_LOW;
+
+	if (mode->hdisplay == 0 ||
+	    mode->hsync_start < mode->hdisplay ||
+	    mode->hsync_end < mode->hsync_start ||
+	    mode->htotal < mode->hsync_end)
+		return MODE_H_ILLEGAL;
+
+	if (mode->vdisplay == 0 ||
+	    mode->vsync_start < mode->vdisplay ||
+	    mode->vsync_end < mode->vsync_start ||
+	    mode->vtotal < mode->vsync_end)
+		return MODE_V_ILLEGAL;
+
+	return MODE_OK;
+}
+EXPORT_SYMBOL(drm_mode_validate_basic);
+
+/**
  * drm_mode_validate_size - make sure modes adhere to size constraints
  * @mode: mode to check
  * @maxX: maximum width
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index c637bd9..0b86ab7 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -166,7 +166,10 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect
 		mode_flags |= DRM_MODE_FLAG_3D_MASK;
 
 	list_for_each_entry(mode, &connector->modes, head) {
-		mode->status = drm_mode_validate_size(mode, maxX, maxY);
+		mode->status = drm_mode_validate_basic(mode);
+
+		if (mode->status == MODE_OK)
+			mode->status = drm_mode_validate_size(mode, maxX, maxY);
 
 		if (mode->status == MODE_OK)
 			mode->status = drm_mode_validate_flag(mode, mode_flags);
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index 6c53114..a36a5bf 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -217,6 +217,7 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
 					const struct drm_display_mode *mode2);
 
 /* for use by the crtc helper probe functions */
+enum drm_mode_status drm_mode_validate_basic(const struct drm_display_mode *mode);
 enum drm_mode_status drm_mode_validate_size(const struct drm_display_mode *mode,
 					    int maxX, int maxY);
 void drm_mode_prune_invalid(struct drm_device *dev,
-- 
2.0.4



More information about the dri-devel mailing list