mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
5662815950
commit
b5f5acbc87
|
@ -1278,8 +1278,7 @@ struct amdgpu_job {
|
|||
uint32_t oa_base, oa_size;
|
||||
|
||||
/* user fence handling */
|
||||
struct amdgpu_bo *uf_bo;
|
||||
uint32_t uf_offset;
|
||||
uint64_t uf_addr;
|
||||
uint64_t uf_sequence;
|
||||
|
||||
};
|
||||
|
|
|
@ -216,11 +216,8 @@ int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data)
|
|||
if (ret)
|
||||
goto free_all_kdata;
|
||||
|
||||
if (p->uf_entry.robj) {
|
||||
p->job->uf_bo = amdgpu_bo_ref(p->uf_entry.robj);
|
||||
p->job->uf_offset = uf_offset;
|
||||
}
|
||||
|
||||
if (p->uf_entry.robj)
|
||||
p->job->uf_addr = uf_offset;
|
||||
kfree(chunk_array);
|
||||
return 0;
|
||||
|
||||
|
@ -502,6 +499,9 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p,
|
|||
}
|
||||
}
|
||||
|
||||
if (p->uf_entry.robj)
|
||||
p->job->uf_addr += amdgpu_bo_gpu_offset(p->uf_entry.robj);
|
||||
|
||||
error_validate:
|
||||
if (r) {
|
||||
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,
|
|||
}
|
||||
|
||||
/* UVD & VCE fw doesn't support user fences */
|
||||
if (parser->job->uf_bo && (
|
||||
if (parser->job->uf_addr && (
|
||||
parser->job->ring->type == AMDGPU_RING_TYPE_UVD ||
|
||||
parser->job->ring->type == AMDGPU_RING_TYPE_VCE))
|
||||
return -EINVAL;
|
||||
|
|
|
@ -203,11 +203,8 @@ int amdgpu_ib_schedule(struct amdgpu_ring *ring, unsigned num_ibs,
|
|||
}
|
||||
|
||||
/* wrap the last IB with fence */
|
||||
if (job && job->uf_bo) {
|
||||
uint64_t addr = amdgpu_bo_gpu_offset(job->uf_bo);
|
||||
|
||||
addr += job->uf_offset;
|
||||
amdgpu_ring_emit_fence(ring, addr, job->uf_sequence,
|
||||
if (job && job->uf_addr) {
|
||||
amdgpu_ring_emit_fence(ring, job->uf_addr, job->uf_sequence,
|
||||
AMDGPU_FENCE_FLAG_64BIT);
|
||||
}
|
||||
|
||||
|
|
|
@ -91,7 +91,6 @@ static void amdgpu_job_free_resources(struct amdgpu_job *job)
|
|||
amdgpu_ib_free(job->adev, &job->ibs[i], f);
|
||||
fence_put(job->fence);
|
||||
|
||||
amdgpu_bo_unref(&job->uf_bo);
|
||||
amdgpu_sync_free(&job->sync);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue