[PATCH 1/3] drm/amdgpu: Refuse to create a KMS FB for non-P2P exported dma-bufs

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

 



From: Michel Dänzer <mdaenzer@xxxxxxxxxx>

Pinning the BO storage to VRAM for scanout would make it inaccessible
to non-P2P dma-buf importers.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10635
Signed-off-by: Michel Dänzer <mdaenzer@xxxxxxxxxx>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 38 ++++++++++++++++++---
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index b8fbe97efe1d3..514a5b2159815 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1255,13 +1255,41 @@ amdgpu_display_user_framebuffer_create(struct drm_device *dev,
 		return ERR_PTR(-ENOENT);
 	}
 
-	/* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */
 	bo = gem_to_amdgpu_bo(obj);
 	domains = amdgpu_display_supported_domains(drm_to_adev(dev), bo->flags);
-	if (obj->import_attach && !(domains & AMDGPU_GEM_DOMAIN_GTT)) {
-		drm_dbg_kms(dev, "Cannot create framebuffer from imported dma_buf\n");
-		drm_gem_object_put(obj);
-		return ERR_PTR(-EINVAL);
+	if (!(domains & AMDGPU_GEM_DOMAIN_GTT)) {
+		bool can_pin = true;
+
+		mutex_lock(&file_priv->prime.lock);
+
+		/* Handle is imported dma-buf, so cannot be migrated to VRAM for scanout */
+		if (obj->import_attach) {
+			drm_dbg_kms(dev, "Cannot create framebuffer from imported dma_buf\n");
+			can_pin = false;
+		} else if (obj->dma_buf) {
+			struct dma_buf *dmabuf = obj->dma_buf;
+			struct dma_buf_attachment *attachment;
+
+			dma_resv_lock(dmabuf->resv, NULL);
+
+			list_for_each_entry(attachment, &dmabuf->attachments, node) {
+				if (IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY) && attachment->peer2peer)
+					continue;
+
+				drm_dbg_kms(dev, "Cannot create framebuffer from non-P2P exported dma_buf\n");
+				can_pin = false;
+				break;
+			}
+
+			dma_resv_unlock(dmabuf->resv);
+		}
+
+		mutex_unlock(&file_priv->prime.lock);
+
+		if (!can_pin) {
+			drm_gem_object_put(obj);
+			return ERR_PTR(-EINVAL);
+		}
 	}
 
 	amdgpu_fb = kzalloc(sizeof(*amdgpu_fb), GFP_KERNEL);
-- 
2.43.0




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux