Commit cc9e67e3 authored by Christian König's avatar Christian König Committed by Alex Deucher

drm/radeon: fix VM IB handling

Calling radeon_vm_bo_find on the IB BO during CS
is illegal and can lead to an crash.
Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 036bf46a
...@@ -879,6 +879,8 @@ struct radeon_vm { ...@@ -879,6 +879,8 @@ struct radeon_vm {
/* array of page tables, one for each page directory entry */ /* array of page tables, one for each page directory entry */
struct radeon_vm_pt *page_tables; struct radeon_vm_pt *page_tables;
struct radeon_bo_va *ib_bo_va;
struct mutex mutex; struct mutex mutex;
/* last fence for cs using this vm */ /* last fence for cs using this vm */
struct radeon_fence *fence; struct radeon_fence *fence;
......
...@@ -472,13 +472,13 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p, ...@@ -472,13 +472,13 @@ static int radeon_bo_vm_update_pte(struct radeon_cs_parser *p,
if (r) if (r)
return r; return r;
bo_va = radeon_vm_bo_find(vm, rdev->ring_tmp_bo.bo); if (vm->ib_bo_va == NULL) {
if (bo_va == NULL) {
DRM_ERROR("Tmp BO not in VM!\n"); DRM_ERROR("Tmp BO not in VM!\n");
return -EINVAL; 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) if (r)
return r; return r;
......
...@@ -579,7 +579,7 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) ...@@ -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 */ /* new gpu have virtual address space support */
if (rdev->family >= CHIP_CAYMAN) { if (rdev->family >= CHIP_CAYMAN) {
struct radeon_fpriv *fpriv; struct radeon_fpriv *fpriv;
struct radeon_bo_va *bo_va; struct radeon_vm *vm;
int r; int r;
fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
...@@ -587,7 +587,8 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) ...@@ -587,7 +587,8 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
return -ENOMEM; return -ENOMEM;
} }
r = radeon_vm_init(rdev, &fpriv->vm); vm = &fpriv->vm;
r = radeon_vm_init(rdev, vm);
if (r) { if (r) {
kfree(fpriv); kfree(fpriv);
return r; return r;
...@@ -596,22 +597,23 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) ...@@ -596,22 +597,23 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
if (rdev->accel_working) { if (rdev->accel_working) {
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
if (r) { if (r) {
radeon_vm_fini(rdev, &fpriv->vm); radeon_vm_fini(rdev, vm);
kfree(fpriv); kfree(fpriv);
return r; return r;
} }
/* map the ib pool buffer read only into /* map the ib pool buffer read only into
* virtual address space */ * virtual address space */
bo_va = radeon_vm_bo_add(rdev, &fpriv->vm, vm->ib_bo_va = radeon_vm_bo_add(rdev, vm,
rdev->ring_tmp_bo.bo); rdev->ring_tmp_bo.bo);
r = radeon_vm_bo_set_addr(rdev, bo_va, RADEON_VA_IB_OFFSET, r = radeon_vm_bo_set_addr(rdev, vm->ib_bo_va,
RADEON_VA_IB_OFFSET,
RADEON_VM_PAGE_READABLE | RADEON_VM_PAGE_READABLE |
RADEON_VM_PAGE_SNOOPED); RADEON_VM_PAGE_SNOOPED);
radeon_bo_unreserve(rdev->ring_tmp_bo.bo); radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
if (r) { if (r) {
radeon_vm_fini(rdev, &fpriv->vm); radeon_vm_fini(rdev, vm);
kfree(fpriv); kfree(fpriv);
return r; return r;
} }
...@@ -640,21 +642,19 @@ void radeon_driver_postclose_kms(struct drm_device *dev, ...@@ -640,21 +642,19 @@ void radeon_driver_postclose_kms(struct drm_device *dev,
/* new gpu have virtual address space support */ /* new gpu have virtual address space support */
if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) { if (rdev->family >= CHIP_CAYMAN && file_priv->driver_priv) {
struct radeon_fpriv *fpriv = 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; int r;
if (rdev->accel_working) { if (rdev->accel_working) {
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
if (!r) { if (!r) {
bo_va = radeon_vm_bo_find(&fpriv->vm, if (vm->ib_bo_va)
rdev->ring_tmp_bo.bo); radeon_vm_bo_rmv(rdev, vm->ib_bo_va);
if (bo_va)
radeon_vm_bo_rmv(rdev, bo_va);
radeon_bo_unreserve(rdev->ring_tmp_bo.bo); radeon_bo_unreserve(rdev->ring_tmp_bo.bo);
} }
} }
radeon_vm_fini(rdev, &fpriv->vm); radeon_vm_fini(rdev, vm);
kfree(fpriv); kfree(fpriv);
file_priv->driver_priv = NULL; file_priv->driver_priv = NULL;
} }
......
...@@ -1007,6 +1007,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) ...@@ -1007,6 +1007,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm)
int r; int r;
vm->id = 0; vm->id = 0;
vm->ib_bo_va = NULL;
vm->fence = NULL; vm->fence = NULL;
vm->last_flush = NULL; vm->last_flush = NULL;
vm->last_id_use = NULL; vm->last_id_use = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment