From: Michel Dänzer <mdaenzer@xxxxxxxxxx> 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 <mdaenzer@xxxxxxxxxx> --- 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