[PATCH] drm/radeon: fix VM IB handling

Alex Deucher alexdeucher at gmail.com
Fri Jul 18 09:44:42 PDT 2014


On Fri, Jul 18, 2014 at 7:48 AM, Christian König
<deathsimple at vodafone.de> wrote:
> From: Christian König <christian.koenig at amd.com>
>
> Calling radeon_vm_bo_find on the IB BO during CS
> is illegal and can lead to an crash.
>
> Signed-off-by: Christian König <christian.koenig at amd.com>

Applied to my 3.16 tree.

Thanks!

Alex

> ---
>  drivers/gpu/drm/radeon/radeon.h     |  2 ++
>  drivers/gpu/drm/radeon/radeon_cs.c  |  6 +++---
>  drivers/gpu/drm/radeon/radeon_kms.c | 26 +++++++++++++-------------
>  drivers/gpu/drm/radeon/radeon_vm.c  |  1 +
>  4 files changed, 19 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index d07f9e3..83e8cee 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -880,6 +880,8 @@ struct radeon_vm {
>         /* array of page tables, one for each page directory entry */
>         struct radeon_vm_pt             *page_tables;
>
> +       struct radeon_bo_va             *ib_bo_va;
> +
>         struct mutex                    mutex;
>         /* last fence for cs using this vm */
>         struct radeon_fence             *fence;
> diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
> index 09fcf4d..ae763f6 100644
> --- a/drivers/gpu/drm/radeon/radeon_cs.c
> +++ b/drivers/gpu/drm/radeon/radeon_cs.c
> @@ -472,13 +472,13 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p,
>         if (r)
>                 return r;
>
> -       bo_va = radeon_vm_bo_find(vm, rdev->ring_tmp_bo.bo);
> -       if (bo_va == NULL) {
> +       if (vm->ib_bo_va == NULL) {
>                 DRM_ERROR("Tmp BO not in VM!\n");
>                 return -EINVAL;
>         }
>
> -       r = radeon_vm_bo_update(rdev, bo_va, &rdev->ring_tmp_bo.bo->tbo.mem);
> +       r = radeon_vm_bo_update(rdev, vm->ib_bo_va,
> +                               &rdev->ring_tmp_bo.bo->tbo.mem);
>         if (r)
>                 return r;
>
> diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
> index 35d9318..d25ae6a 100644
> --- a/drivers/gpu/drm/radeon/radeon_kms.c
> +++ b/drivers/gpu/drm/radeon/radeon_kms.c
> @@ -579,7 +579,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
>         /* new gpu have virtual address space support */
>         if (rdev->family >= CHIP_CAYMAN) {
>                 struct radeon_fpriv *fpriv;
> -               struct radeon_bo_va *bo_va;
> +               struct radeon_vm *vm;
>                 int r;
>
>                 fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
> @@ -587,7 +587,8 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
>                         return -ENOMEM;
>                 }
>
> -               r = radeon_vm_init(rdev, &fpriv->vm);
> +               vm = &fpriv->vm;
> +               r = radeon_vm_init(rdev, vm);
>                 if (r) {
>                         kfree(fpriv);
>                         return r;
> @@ -596,22 +597,23 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
>                 if (rdev->accel_working) {
>                         r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
>                         if (r) {
> -                               radeon_vm_fini(rdev, &fpriv->vm);
> +                               radeon_vm_fini(rdev, 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,
> +                       vm->ib_bo_va = radeon_vm_bo_add(rdev, vm,
> +                                                       rdev->ring_tmp_bo.bo);
> +                       r = radeon_vm_bo_set_addr(rdev, vm->ib_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);
> +                               radeon_vm_fini(rdev, vm);
>                                 kfree(fpriv);
>                                 return r;
>                         }
> @@ -640,21 +642,19 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
>         /* new gpu have virtual address space support */
>         if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) {
>                 struct radeon_fpriv *fpriv = file_priv->driver_priv;
> -               struct radeon_bo_va *bo_va;
> +               struct radeon_vm *vm = &fpriv->vm;
>                 int r;
>
>                 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);
> +                               if (vm->ib_bo_va)
> +                                       radeon_vm_bo_rmv(rdev, vm->ib_bo_va);
>                                 radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
>                         }
>                 }
>
> -               radeon_vm_fini(rdev, &fpriv->vm);
> +               radeon_vm_fini(rdev, vm);
>                 kfree(fpriv);
>                 file_priv->driver_priv = NULL;
>         }
> diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c
> index 251e175..f2060fc 100644
> --- a/drivers/gpu/drm/radeon/radeon_vm.c
> +++ b/drivers/gpu/drm/radeon/radeon_vm.c
> @@ -1006,6 +1006,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
>         int r;
>
>         vm->id = 0;
> +       vm->ib_bo_va = NULL;
>         vm->fence = NULL;
>         vm->last_flush = NULL;
>         vm->last_id_use = NULL;
> --
> 1.9.1
>


More information about the dri-devel mailing list