Patch "drm/amd/display: Fix two cursor duplication when using overlay" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    drm/amd/display: Fix two cursor duplication when using overlay

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     drm-amd-display-fix-two-cursor-duplication-when-usin.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 5ab595ecd014a4022bd09a57a0bafd5cb626a0bd
Author: Rodrigo Siqueira <Rodrigo.Siqueira@xxxxxxx>
Date:   Tue Apr 13 20:06:04 2021 -0400

    drm/amd/display: Fix two cursor duplication when using overlay
    
    [ Upstream commit 16e9b3e58bc3fce7391539e0eb3fd167cbf9951f ]
    
    Our driver supports overlay planes, and as expected, some userspace
    compositor takes advantage of these features. If the userspace is not
    enabling the cursor, they can use multiple planes as they please.
    Nevertheless, we start to have constraints when userspace tries to
    enable hardware cursor with various planes. Basically, we cannot draw
    the cursor at the same size and position on two separated pipes since it
    uses extra bandwidth and DML only run with one cursor.
    
    For those reasons, when we enable hardware cursor and multiple planes,
    our driver should accept variations like the ones described below:
    
      +-------------+   +--------------+
      | +---------+ |   |              |
      | |Primary  | |   | Primary      |
      | |         | |   | Overlay      |
      | +---------+ |   |              |
      |Overlay      |   |              |
      +-------------+   +--------------+
    
    In this scenario, we can have the desktop UI in the overlay and some
    other framebuffer attached to the primary plane (e.g., video). However,
    userspace needs to obey some rules and avoid scenarios like the ones
    described below (when enabling hw cursor):
    
                                          +--------+
                                          |Overlay |
     +-------------+    +-----+-------+ +-|        |--+
     | +--------+  | +--------+       | | +--------+  |
     | |Overlay |  | |Overlay |       | |             |
     | |        |  | |        |       | |             |
     | +--------+  | +--------+       | |             |
     | Primary     |    | Primary     | | Primary     |
     +-------------+    +-------------+ +-------------+
    
     +-------------+   +-------------+
     |     +--------+  |  Primary    |
     |     |Overlay |  |             |
     |     |        |  |             |
     |     +--------+  | +--------+  |
     | Primary     |   | |Overlay |  |
     +-------------+   +-|        |--+
                         +--------+
    
    If the userspace violates some of the above scenarios, our driver needs
    to reject the commit; otherwise, we can have unexpected behavior. Since
    we don't have a proper driver validation for the above case, we can see
    some problems like a duplicate cursor in applications that use multiple
    planes. This commit fixes the cursor issue and others by adding adequate
    verification for multiple planes.
    
    Change since V1 (Harry and Sean):
    - Remove cursor verification from the equation.
    
    Cc: Louis Li <Ching-shih.Li@xxxxxxx>
    Cc: Nicholas Kazlauskas <Nicholas.Kazlauskas@xxxxxxx>
    Cc: Harry Wentland <Harry.Wentland@xxxxxxx>
    Cc: Hersen Wu <hersenxs.wu@xxxxxxx>
    Cc: Sean Paul <seanpaul@xxxxxxxxxxxx>
    Signed-off-by: Rodrigo Siqueira <Rodrigo.Siqueira@xxxxxxx>
    Reviewed-by: Harry Wentland <harry.wentland@xxxxxxx>
    Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 8180894bbd1e..fbbb1bde6b06 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -8611,6 +8611,53 @@ static int add_affected_mst_dsc_crtcs(struct drm_atomic_state *state, struct drm
 }
 #endif
 
+static int validate_overlay(struct drm_atomic_state *state)
+{
+	int i;
+	struct drm_plane *plane;
+	struct drm_plane_state *old_plane_state, *new_plane_state;
+	struct drm_plane_state *primary_state, *overlay_state = NULL;
+
+	/* Check if primary plane is contained inside overlay */
+	for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
+		if (plane->type == DRM_PLANE_TYPE_OVERLAY) {
+			if (drm_atomic_plane_disabling(plane->state, new_plane_state))
+				return 0;
+
+			overlay_state = new_plane_state;
+			continue;
+		}
+	}
+
+	/* check if we're making changes to the overlay plane */
+	if (!overlay_state)
+		return 0;
+
+	/* check if overlay plane is enabled */
+	if (!overlay_state->crtc)
+		return 0;
+
+	/* find the primary plane for the CRTC that the overlay is enabled on */
+	primary_state = drm_atomic_get_plane_state(state, overlay_state->crtc->primary);
+	if (IS_ERR(primary_state))
+		return PTR_ERR(primary_state);
+
+	/* check if primary plane is enabled */
+	if (!primary_state->crtc)
+		return 0;
+
+	/* Perform the bounds check to ensure the overlay plane covers the primary */
+	if (primary_state->crtc_x < overlay_state->crtc_x ||
+	    primary_state->crtc_y < overlay_state->crtc_y ||
+	    primary_state->crtc_x + primary_state->crtc_w > overlay_state->crtc_x + overlay_state->crtc_w ||
+	    primary_state->crtc_y + primary_state->crtc_h > overlay_state->crtc_y + overlay_state->crtc_h) {
+		DRM_DEBUG_ATOMIC("Overlay plane is enabled with hardware cursor but does not fully cover primary plane\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /**
  * amdgpu_dm_atomic_check() - Atomic check implementation for AMDgpu DM.
  * @dev: The DRM device
@@ -8789,6 +8836,10 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
 			goto fail;
 	}
 
+	ret = validate_overlay(state);
+	if (ret)
+		goto fail;
+
 	/* Add new/modified planes */
 	for_each_oldnew_plane_in_state_reverse(state, plane, old_plane_state, new_plane_state, i) {
 		ret = dm_update_plane_state(dc, state, plane,



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux