lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 26 May 2020 14:23:10 -0400
From:   Lyude Paul <lyude@...hat.com>
To:     dri-devel@...ts.freedesktop.org
Cc:     Lee Shawn C <shawn.c.lee@...el.com>,
        Ville Syrjälä 
        <ville.syrjala@...ux.intel.com>,
        Manasi Navare <manasi.d.navare@...el.com>,
        Jani Nikula <jani.nikula@...ux.intel.com>,
        Cooper Chiou <cooper.chiou@...el.com>,
        Joonas Lahtinen <joonas.lahtinen@...ux.intel.com>,
        Rodrigo Vivi <rodrigo.vivi@...el.com>,
        David Airlie <airlied@...ux.ie>,
        Daniel Vetter <daniel@...ll.ch>,
        José Roberto de Souza <jose.souza@...el.com>,
        Lucas De Marchi <lucas.demarchi@...el.com>,
        Maarten Lankhorst <maarten.lankhorst@...ux.intel.com>,
        intel-gfx@...ts.freedesktop.org, linux-kernel@...r.kernel.org
Subject: [PATCH 2/2] drm/i915/mst: filter out the display mode exceed sink's capability

From: Lee Shawn C <shawn.c.lee@...el.com>

So far, max dot clock rate for MST mode rely on physcial
bandwidth limitation. It would caused compatibility issue
if source display resolution exceed MST hub output ability.

For example, source DUT had DP 1.2 output capability.
And MST docking just support HDMI 1.4 spec. When a HDMI 2.0
monitor connected. Source would retrieve EDID from external
and get max resolution 4k@...ps. DP 1.2 can support 4K@...ps
because it did not surpass DP physical bandwidth limitation.
Do modeset to 4k@...ps, source output display data but MST
docking can't output HDMI properly due to this resolution
already over HDMI 1.4 spec.

Refer to commit <fcf463807596> ("drm/dp_mst: Use full_pbn
instead of available_pbn for bandwidth checks").
Source driver should refer to full_pbn to evaluate sink
output capability. And filter out the resolution surpass
sink output limitation.

v2: Using mgr->base.lock to protect full_pbn.
v3: Add ctx lock.
v4:
* s/intel_dp_mst_mode_clock_exceed_pbn_bandwidth/
  intel_dp_mst_mode_clock_exceeds_pbn_bw/
* Use the new drm_connector_helper_funcs.mode_valid_ctx to properly pipe
  down the drm_modeset_acquire_ctx that the probe helpers are using, so
  we can safely grab &mgr->base.lock without deadlocking

Cc: Manasi Navare <manasi.d.navare@...el.com>
Cc: Jani Nikula <jani.nikula@...ux.intel.com>
Cc: Ville Syrjala <ville.syrjala@...ux.intel.com>
Cc: Cooper Chiou <cooper.chiou@...el.com>
Co-developed-by: Lyude Paul <lyude@...hat.com>
Signed-off-by: Lee Shawn C <shawn.c.lee@...el.com>
Tested-by: Lee Shawn C <shawn.c.lee@...el.com>
Signed-off-by: Lyude Paul <lyude@...hat.com>
---
 drivers/gpu/drm/i915/display/intel_dp_mst.c | 39 ++++++++++++++++++---
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index d18b406f2a7d2..cf052095ad785 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -610,15 +610,42 @@ static int intel_dp_mst_get_modes(struct drm_connector *connector)
 	return intel_dp_mst_get_ddc_modes(connector);
 }
 
+static int
+intel_dp_mst_mode_clock_exceeds_pbn_bw(struct drm_connector *connector,
+				       struct drm_modeset_acquire_ctx *ctx,
+				       int clock, int bpp)
+{
+	struct intel_connector *intel_connector = to_intel_connector(connector);
+	struct intel_dp *intel_dp = intel_connector->mst_port;
+	struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr;
+	struct drm_dp_mst_port *port = (to_intel_connector(connector))->port;
+	int ret = MODE_OK;
+
+	if (!mgr)
+		return ret;
+
+	ret = drm_modeset_lock(&mgr->base.lock, ctx);
+	if (ret == -EDEADLK)
+		return ret;
+
+	if (port->full_pbn &&
+	    drm_dp_calc_pbn_mode(clock, bpp, false) > port->full_pbn)
+		ret = MODE_CLOCK_HIGH;
+
+	return ret;
+}
+
 static enum drm_mode_status
-intel_dp_mst_mode_valid(struct drm_connector *connector,
-			struct drm_display_mode *mode)
+intel_dp_mst_mode_valid_ctx(struct drm_connector *connector,
+			    struct drm_display_mode *mode,
+			    struct drm_modeset_acquire_ctx *ctx)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
 	struct intel_connector *intel_connector = to_intel_connector(connector);
 	struct intel_dp *intel_dp = intel_connector->mst_port;
 	int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
 	int max_rate, mode_rate, max_lanes, max_link_clock;
+	int ret;
 
 	if (drm_connector_is_unregistered(connector))
 		return MODE_ERROR;
@@ -632,7 +659,11 @@ intel_dp_mst_mode_valid(struct drm_connector *connector,
 	max_rate = intel_dp_max_data_rate(max_link_clock, max_lanes);
 	mode_rate = intel_dp_link_required(mode->clock, 18);
 
-	/* TODO - validate mode against available PBN for link */
+	ret = intel_dp_mst_mode_clock_exceeds_pbn_bw(connector, ctx,
+						     mode->clock, 24);
+	if (ret != MODE_OK)
+		return ret;
+
 	if (mode->clock < 10000)
 		return MODE_CLOCK_LOW;
 
@@ -671,7 +702,7 @@ intel_dp_mst_detect(struct drm_connector *connector,
 
 static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = {
 	.get_modes = intel_dp_mst_get_modes,
-	.mode_valid = intel_dp_mst_mode_valid,
+	.mode_valid_ctx = intel_dp_mst_mode_valid_ctx,
 	.atomic_best_encoder = intel_mst_atomic_best_encoder,
 	.atomic_check = intel_dp_mst_atomic_check,
 	.detect_ctx = intel_dp_mst_detect,
-- 
2.26.2

Powered by blists - more mailing lists