aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2015-04-09 10:44:15 -0400
committerJani Nikula <jani.nikula@intel.com>2015-04-10 07:29:27 -0400
commit9da7d69357389ea63893434fe3b17b9fbc2c2d2d (patch)
tree6ef4b8b6cc08a3b62915c3d95585fadd2db8a839
parent6e0aa8018f9c676b115b7ca6c20a056fc57c68a9 (diff)
drm/i915: Fix locking in DRRS flush/invalidate hooks
We must acquire the mutex before we can check drrs.dp, otherwise someone might sneak in with a modeset, clear the pointer after we've checked it and then the code will Oops. This issue has been introduced in commit a93fad0f7fb8a3ff12e8814b630648f6d187954c Author: Vandana Kannan <vandana.kannan@intel.com> Date: Sat Jan 10 02:25:59 2015 +0530 drm/i915: DRRS calls based on frontbuffer v2: Don't blow up on uninitialized mutex and work item by checking whether DRRS is support or not first. Also unconditionally initialize the mutex/work item to avoid future trouble. Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Ramalingam C <ramalingam.c@intel.com> Cc: Rodrigo Vivi <rodrigo.vivi@intel.com> Cc: Vandana Kannan <vandana.kannan@intel.com> Cc: stable@vger.kernel.org (4.0+ only) Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Tested-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index b70e635ccaf4..5e60473d08fe 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5157,7 +5157,6 @@ static void intel_edp_drrs_downclock_work(struct work_struct *work)
5157 downclock_mode->vrefresh); 5157 downclock_mode->vrefresh);
5158 5158
5159unlock: 5159unlock:
5160
5161 mutex_unlock(&dev_priv->drrs.mutex); 5160 mutex_unlock(&dev_priv->drrs.mutex);
5162} 5161}
5163 5162
@@ -5179,12 +5178,17 @@ void intel_edp_drrs_invalidate(struct drm_device *dev,
5179 struct drm_crtc *crtc; 5178 struct drm_crtc *crtc;
5180 enum pipe pipe; 5179 enum pipe pipe;
5181 5180
5182 if (!dev_priv->drrs.dp) 5181 if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
5183 return; 5182 return;
5184 5183
5185 cancel_delayed_work_sync(&dev_priv->drrs.work); 5184 cancel_delayed_work_sync(&dev_priv->drrs.work);
5186 5185
5187 mutex_lock(&dev_priv->drrs.mutex); 5186 mutex_lock(&dev_priv->drrs.mutex);
5187 if (!dev_priv->drrs.dp) {
5188 mutex_unlock(&dev_priv->drrs.mutex);
5189 return;
5190 }
5191
5188 crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc; 5192 crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc;
5189 pipe = to_intel_crtc(crtc)->pipe; 5193 pipe = to_intel_crtc(crtc)->pipe;
5190 5194
@@ -5218,12 +5222,17 @@ void intel_edp_drrs_flush(struct drm_device *dev,
5218 struct drm_crtc *crtc; 5222 struct drm_crtc *crtc;
5219 enum pipe pipe; 5223 enum pipe pipe;
5220 5224
5221 if (!dev_priv->drrs.dp) 5225 if (dev_priv->drrs.type == DRRS_NOT_SUPPORTED)
5222 return; 5226 return;
5223 5227
5224 cancel_delayed_work_sync(&dev_priv->drrs.work); 5228 cancel_delayed_work_sync(&dev_priv->drrs.work);
5225 5229
5226 mutex_lock(&dev_priv->drrs.mutex); 5230 mutex_lock(&dev_priv->drrs.mutex);
5231 if (!dev_priv->drrs.dp) {
5232 mutex_unlock(&dev_priv->drrs.mutex);
5233 return;
5234 }
5235
5227 crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc; 5236 crtc = dp_to_dig_port(dev_priv->drrs.dp)->base.base.crtc;
5228 pipe = to_intel_crtc(crtc)->pipe; 5237 pipe = to_intel_crtc(crtc)->pipe;
5229 dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits; 5238 dev_priv->drrs.busy_frontbuffer_bits &= ~frontbuffer_bits;
@@ -5294,6 +5303,9 @@ intel_dp_drrs_init(struct intel_connector *intel_connector,
5294 struct drm_i915_private *dev_priv = dev->dev_private; 5303 struct drm_i915_private *dev_priv = dev->dev_private;
5295 struct drm_display_mode *downclock_mode = NULL; 5304 struct drm_display_mode *downclock_mode = NULL;
5296 5305
5306 INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
5307 mutex_init(&dev_priv->drrs.mutex);
5308
5297 if (INTEL_INFO(dev)->gen <= 6) { 5309 if (INTEL_INFO(dev)->gen <= 6) {
5298 DRM_DEBUG_KMS("DRRS supported for Gen7 and above\n"); 5310 DRM_DEBUG_KMS("DRRS supported for Gen7 and above\n");
5299 return NULL; 5311 return NULL;
@@ -5312,10 +5324,6 @@ intel_dp_drrs_init(struct intel_connector *intel_connector,
5312 return NULL; 5324 return NULL;
5313 } 5325 }
5314 5326
5315 INIT_DELAYED_WORK(&dev_priv->drrs.work, intel_edp_drrs_downclock_work);
5316
5317 mutex_init(&dev_priv->drrs.mutex);
5318
5319 dev_priv->drrs.type = dev_priv->vbt.drrs_type; 5327 dev_priv->drrs.type = dev_priv->vbt.drrs_type;
5320 5328
5321 dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR; 5329 dev_priv->drrs.refresh_rate_type = DRRS_HIGH_RR;