aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian König <christian.koenig@amd.com>2016-06-29 07:26:41 -0400
committerAlex Deucher <alexander.deucher@amd.com>2016-07-07 15:06:09 -0400
commitb5f5acbc87052e1bd8ada6915e1dedd856da767d (patch)
tree0892fd1a08ab03f5ff5fc074685c8294ba34166f
parent566281595037a6f5932adbf8e04d3a63e7687fd7 (diff)
drm/amdgpu: fix user fence handling once more
Same problem as with the VM page tables. The user fence address must be determined before the job is scheduled, not when the IB is executed. This fixes a security problem where user fences could be used to overwrite any part of VRAM. Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Chunming Zhou <david1.zhou@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h3
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c7
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_job.c1
4 files changed, 9 insertions, 14 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index cd7d15941a83..4fc879e594aa 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1278,8 +1278,7 @@ struct amdgpu_job {
1278 uint32_t oa_base, oa_size; 1278 uint32_t oa_base, oa_size;
1279 1279
1280 /* user fence handling */ 1280 /* user fence handling */
1281 struct amdgpu_bo *uf_bo; 1281 uint64_t uf_addr;
1282 uint32_t uf_offset;
1283 uint64_t uf_sequence; 1282 uint64_t uf_sequence;
1284 1283
1285}; 1284};
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index 95b248159947..475c95f670f8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -216,11 +216,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
216 if (ret) 216 if (ret)
217 goto free_all_kdata; 217 goto free_all_kdata;
218 218
219 if (p->uf_entry.robj) { 219 if (p->uf_entry.robj)
220 p->job->uf_bo = amdgpu_bo_ref(p->uf_entry.robj); 220 p->job->uf_addr = uf_offset;
221 p->job->uf_offset = uf_offset;
222 }
223
224 kfree(chunk_array); 221 kfree(chunk_array);
225 return 0; 222 return 0;
226 223
@@ -502,6 +499,9 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
502 } 499 }
503 } 500 }
504 501
502 if (p->uf_entry.robj)
503 p->job->uf_addr += amdgpu_bo_gpu_offset(p->uf_entry.robj);
504
505error_validate: 505error_validate:
506 if (r) { 506 if (r) {
507 amdgpu_vm_move_pt_bos_in_lru(p->adev, &fpriv->vm); 507 amdgpu_vm_move_pt_bos_in_lru(p->adev, &fpriv->vm);
@@ -767,7 +767,7 @@ static int amdgpu_cs_ib_fill(struct amdgpu_device *adev,
767 } 767 }
768 768
769 /* UVD & VCE fw doesn't support user fences */ 769 /* UVD & VCE fw doesn't support user fences */
770 if (parser->job->uf_bo && ( 770 if (parser->job->uf_addr && (
771 parser->job->ring->type == AMDGPU_RING_TYPE_UVD || 771 parser->job->ring->type == AMDGPU_RING_TYPE_UVD ||
772 parser->job->ring->type == AMDGPU_RING_TYPE_VCE)) 772 parser->job->ring->type == AMDGPU_RING_TYPE_VCE))
773 return -EINVAL; 773 return -EINVAL;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
index 34e35423b78e..0bf6c1b330be 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
@@ -203,11 +203,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
203 } 203 }
204 204
205 /* wrap the last IB with fence */ 205 /* wrap the last IB with fence */
206 if (job && job->uf_bo) { 206 if (job && job->uf_addr) {
207 uint64_t addr = amdgpu_bo_gpu_offset(job->uf_bo); 207 amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence,
208
209 addr += job->uf_offset;
210 amdgpu_ring_emit_fence(ring, addr, job->uf_sequence,
211 AMDGPU_FENCE_FLAG_64BIT); 208 AMDGPU_FENCE_FLAG_64BIT);
212 } 209 }
213 210
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
index b50a8450fcae..87b75d726ae8 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c
@@ -91,7 +91,6 @@ static void amdgpu_job_free_resources(struct amdgpu_job *job)
91 amdgpu_ib_free(job->adev, &job->ibs[i], f); 91 amdgpu_ib_free(job->adev, &job->ibs[i], f);
92 fence_put(job->fence); 92 fence_put(job->fence);
93 93
94 amdgpu_bo_unref(&job->uf_bo);
95 amdgpu_sync_free(&job->sync); 94 amdgpu_sync_free(&job->sync);
96} 95}
97 96