diff mbox

drm/radeon: avoid segfault on device open when accel is not working.

Message ID 1399494924-6660-1-git-send-email-j.glisse@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jerome Glisse May 7, 2014, 8:35 p.m. UTC
From: Jérôme Glisse <jglisse@redhat.com>

When accel is not working on device with virtual address space radeon
segfault because the ib buffer is NULL and trying to map it inside the
virtual address space trigger segfault. This patch only map the ib
buffer if accel is working.

Cc: <stable@vger.kernel.org>
Signed-off-by: Jérôme Glisse <jglisse@redhat.com>
---
 drivers/gpu/drm/radeon/radeon_kms.c | 55 +++++++++++++++++++------------------
 1 file changed, 29 insertions(+), 26 deletions(-)

Comments

Alex Deucher May 7, 2014, 9:42 p.m. UTC | #1
On Wed, May 7, 2014 at 4:35 PM,  <j.glisse@gmail.com> wrote:
> From: Jérôme Glisse <jglisse@redhat.com>
>
> When accel is not working on device with virtual address space radeon
> segfault because the ib buffer is NULL and trying to map it inside the
> virtual address space trigger segfault. This patch only map the ib
> buffer if accel is working.
>
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Jérôme Glisse <jglisse@redhat.com>

Probably also fixes:
https://bugzilla.kernel.org/show_bug.cgi?id=73931

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/radeon/radeon_kms.c | 55 +++++++++++++++++++------------------
>  1 file changed, 29 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
> index 0cc47f1..eaaedba 100644
> --- a/drivers/gpu/drm/radeon/radeon_kms.c
> +++ b/drivers/gpu/drm/radeon/radeon_kms.c
> @@ -577,28 +577,29 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
>                         return r;
>                 }
>
> -               r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
> -               if (r) {
> -                       radeon_vm_fini(rdev, &fpriv->vm);
> -                       kfree(fpriv);
> -                       return r;
> -               }
> +               if (rdev->accel_working) {
> +                       r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
> +                       if (r) {
> +                               radeon_vm_fini(rdev, &fpriv->vm);
> +                               kfree(fpriv);
> +                               return r;
> +                       }
>
> -               /* map the ib pool buffer read only into
> -                * virtual address space */
> -               bo_va = radeon_vm_bo_add(rdev, &fpriv->vm,
> -                                        rdev->ring_tmp_bo.bo);
> -               r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
> -                                         RADEON_VM_PAGE_READABLE |
> -                                         RADEON_VM_PAGE_SNOOPED);
> +                       /* map the ib pool buffer read only into
> +                        * virtual address space */
> +                       bo_va = radeon_vm_bo_add(rdev, &fpriv->vm,
> +                                                rdev->ring_tmp_bo.bo);
> +                       r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
> +                                                 RADEON_VM_PAGE_READABLE |
> +                                                 RADEON_VM_PAGE_SNOOPED);
>
> -               radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
> -               if (r) {
> -                       radeon_vm_fini(rdev, &fpriv->vm);
> -                       kfree(fpriv);
> -                       return r;
> +                       radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
> +                       if (r) {
> +                               radeon_vm_fini(rdev, &fpriv->vm);
> +                               kfree(fpriv);
> +                               return r;
> +                       }
>                 }
> -
>                 file_priv->driver_priv = fpriv;
>         }
>
> @@ -626,13 +627,15 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
>                 struct radeon_bo_va *bo_va;
>                 int r;
>
> -               r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
> -               if (!r) {
> -                       bo_va = radeon_vm_bo_find(&fpriv->vm,
> -                                                 rdev->ring_tmp_bo.bo);
> -                       if (bo_va)
> -                               radeon_vm_bo_rmv(rdev, bo_va);
> -                       radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
> +               if (rdev->accel_working) {
> +                       r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
> +                       if (!r) {
> +                               bo_va = radeon_vm_bo_find(&fpriv->vm,
> +                                                         rdev->ring_tmp_bo.bo);
> +                               if (bo_va)
> +                                       radeon_vm_bo_rmv(rdev, bo_va);
> +                               radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
> +                       }
>                 }
>
>                 radeon_vm_fini(rdev, &fpriv->vm);
> --
> 1.9.0
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox

Patch

diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 0cc47f1..eaaedba 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -577,28 +577,29 @@  int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
 			return r;
 		}
 
-		r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
-		if (r) {
-			radeon_vm_fini(rdev, &fpriv->vm);
-			kfree(fpriv);
-			return r;
-		}
+		if (rdev->accel_working) {
+			r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
+			if (r) {
+				radeon_vm_fini(rdev, &fpriv->vm);
+				kfree(fpriv);
+				return r;
+			}
 
-		/* map the ib pool buffer read only into
-		 * virtual address space */
-		bo_va = radeon_vm_bo_add(rdev, &fpriv->vm,
-					 rdev->ring_tmp_bo.bo);
-		r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
-					  RADEON_VM_PAGE_READABLE |
-					  RADEON_VM_PAGE_SNOOPED);
+			/* map the ib pool buffer read only into
+			 * virtual address space */
+			bo_va = radeon_vm_bo_add(rdev, &fpriv->vm,
+						 rdev->ring_tmp_bo.bo);
+			r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET,
+						  RADEON_VM_PAGE_READABLE |
+						  RADEON_VM_PAGE_SNOOPED);
 
-		radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
-		if (r) {
-			radeon_vm_fini(rdev, &fpriv->vm);
-			kfree(fpriv);
-			return r;
+			radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
+			if (r) {
+				radeon_vm_fini(rdev, &fpriv->vm);
+				kfree(fpriv);
+				return r;
+			}
 		}
-
 		file_priv->driver_priv = fpriv;
 	}
 
@@ -626,13 +627,15 @@  void radeon_driver_postclose_kms(struct drm_device *dev,
 		struct radeon_bo_va *bo_va;
 		int r;
 
-		r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
-		if (!r) {
-			bo_va = radeon_vm_bo_find(&fpriv->vm,
-						  rdev->ring_tmp_bo.bo);
-			if (bo_va)
-				radeon_vm_bo_rmv(rdev, bo_va);
-			radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
+		if (rdev->accel_working) {
+			r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
+			if (!r) {
+				bo_va = radeon_vm_bo_find(&fpriv->vm,
+							  rdev->ring_tmp_bo.bo);
+				if (bo_va)
+					radeon_vm_bo_rmv(rdev, bo_va);
+				radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
+			}
 		}
 
 		radeon_vm_fini(rdev, &fpriv->vm);