From: Michel Dänzer <mdaen...@redhat.com>

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

Also keep file_priv->prime.lock locked until after bumping bo->num_fbs
in amdgpu_display_user_framebuffer_create, so that the checks there and
in amdgpu_dma_buf_attach are always consistent with each other.

Signed-off-by: Michel Dänzer <mdaen...@redhat.com>
---
 drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 20 ++++++++++++--------
 drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 11 +++++++++++
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index 89bda2a2baf58..2afe5558ba895 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -1251,6 +1251,7 @@ amdgpu_display_user_framebuffer_create(struct drm_device 
*dev,
 {
        struct amdgpu_framebuffer *amdgpu_fb;
        struct drm_gem_object *obj;
+       bool prime_locked = false;
        struct amdgpu_bo *bo;
        uint32_t domains;
        int ret;
@@ -1270,6 +1271,7 @@ amdgpu_display_user_framebuffer_create(struct drm_device 
*dev,
                bool can_pin = true;
 
                mutex_lock(&file_priv->prime.lock);
+               prime_locked = true;
 
                /* Handle is imported dma-buf, so cannot be migrated to VRAM 
for scanout */
                if (obj->import_attach) {
@@ -1293,29 +1295,31 @@ amdgpu_display_user_framebuffer_create(struct 
drm_device *dev,
                        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 = ERR_PTR(-EINVAL);
+                       goto out;
                }
        }
 
        amdgpu_fb = kzalloc(sizeof(*amdgpu_fb), GFP_KERNEL);
        if (amdgpu_fb == NULL) {
-               drm_gem_object_put(obj);
-               return ERR_PTR(-ENOMEM);
+               amdgpu_fb = ERR_PTR(-ENOMEM);
+               goto out;
        }
 
        ret = amdgpu_display_gem_fb_verify_and_init(dev, amdgpu_fb, file_priv,
                                                    mode_cmd, obj);
        if (ret) {
                kfree(amdgpu_fb);
-               drm_gem_object_put(obj);
-               return ERR_PTR(ret);
+               amdgpu_fb = ERR_PTR(ret);
+               goto out;
        }
 
        atomic_inc(&bo->num_fbs);
+
+out:
+       if (prime_locked)
+               mutex_unlock(&file_priv->prime.lock);
        drm_gem_object_put(obj);
        return &amdgpu_fb->base;
 }
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
index decbbe3d4f06e..275d34898284d 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -63,6 +63,17 @@ static int amdgpu_dma_buf_attach(struct dma_buf *dmabuf,
        if (pci_p2pdma_distance(adev->pdev, attach->dev, false) < 0)
                attach->peer2peer = false;
 
+       if ((!IS_ENABLED(CONFIG_DMABUF_MOVE_NOTIFY) || !attach->peer2peer) &&
+           atomic_read(&bo->num_fbs) > 0) {
+               uint32_t domains = amdgpu_display_supported_domains(adev, 
bo->flags);
+
+               if (!(domains & AMDGPU_GEM_DOMAIN_GTT)) {
+                       drm_dbg_prime(adev_to_drm(adev),
+                                     "Cannot attach to BO with KMS FBs without 
P2P\n");
+                       return -EINVAL;
+               }
+       }
+
        r = pm_runtime_get_sync(adev_to_drm(adev)->dev);
        trace_amdgpu_runpm_reference_dumps(1, __func__);
        if (r < 0)
-- 
2.43.0

Reply via email to