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: Christian König <christian.koenig@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
036bf46a39
commit
cc9e67e3d7
|
@ -879,6 +879,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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1007,6 +1007,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;
|
||||
|
|
Loading…
Reference in New Issue