summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKumar, Mahesh <mahesh1.kumar@intel.com>2017-05-17 17:28:26 +0530
committerMatt Roper <matthew.d.roper@intel.com>2017-05-17 14:32:57 -0700
commit5ba6faafbe18451352747ae730392ddb316e4ed5 (patch)
tree1df6c492ba1eff60ab4009fd60f2f821b1ab57a9
parent336031ea1cdb056eb2f7bd21fce46dda52fc0412 (diff)
drm/i915/skl+: Fail the flip if ddb min requirement exceeds pipe allocation
DDB minimum requirement of crtc configuration (cumulative of all the enabled planes in crtc) may exceed the allocated DDB for crtc/pipe. This patch make changes to fail the flip/ioctl if minimum requirement for pipe exceeds the total ddb allocated to the pipe. Previously it succeeded but making alloc_size a negative value. Which will make subsequent calculations for plane ddb allocation bogus & may lead to screen corruption or system hang. Changes from V1: - Improve commit message as per Ander's comment - Remove extra parentheses (Ander) Signed-off-by: Mahesh Kumar <mahesh1.kumar@intel.com> Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20170517115831.13830-8-mahesh1.kumar@intel.com
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 37dd3e7108c9..bbc72069ab57 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -4057,6 +4057,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
int num_active;
unsigned plane_data_rate[I915_MAX_PLANES] = {};
unsigned plane_y_data_rate[I915_MAX_PLANES] = {};
+ uint16_t total_min_blocks = 0;
/* Clear the partitioning for disabled planes. */
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
@@ -4084,10 +4085,18 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
*/
for_each_plane_id_on_crtc(intel_crtc, plane_id) {
- alloc_size -= minimum[plane_id];
- alloc_size -= y_minimum[plane_id];
+ total_min_blocks += minimum[plane_id];
+ total_min_blocks += y_minimum[plane_id];
}
+ if (total_min_blocks > alloc_size) {
+ DRM_DEBUG_KMS("Requested display configuration exceeds system DDB limitations");
+ DRM_DEBUG_KMS("minimum required %d/%d\n", total_min_blocks,
+ alloc_size);
+ return -EINVAL;
+ }
+
+ alloc_size -= total_min_blocks;
ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - minimum[PLANE_CURSOR];
ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;