diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c index 5a2a5ba29f9a..6d8df76b5a5d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | |||
@@ -66,11 +66,35 @@ static int amdgpu_cs_user_fence_chunk(struct amdgpu_cs_parser *p, | |||
66 | return 0; | 66 | return 0; |
67 | } | 67 | } |
68 | 68 | ||
69 | static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | 69 | static int amdgpu_cs_bo_handles_chunk(struct amdgpu_cs_parser *p, |
70 | struct drm_amdgpu_bo_list_in *data) | ||
71 | { | ||
72 | int r; | ||
73 | struct drm_amdgpu_bo_list_entry *info = NULL; | ||
74 | |||
75 | r = amdgpu_bo_create_list_entry_array(data, &info); | ||
76 | if (r) | ||
77 | return r; | ||
78 | |||
79 | r = amdgpu_bo_list_create(p->adev, p->filp, info, data->bo_number, | ||
80 | &p->bo_list); | ||
81 | if (r) | ||
82 | goto error_free; | ||
83 | |||
84 | kvfree(info); | ||
85 | return 0; | ||
86 | |||
87 | error_free: | ||
88 | if (info) | ||
89 | kvfree(info); | ||
90 | |||
91 | return r; | ||
92 | } | ||
93 | |||
94 | static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, union drm_amdgpu_cs *cs) | ||
70 | { | 95 | { |
71 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; | 96 | struct amdgpu_fpriv *fpriv = p->filp->driver_priv; |
72 | struct amdgpu_vm *vm = &fpriv->vm; | 97 | struct amdgpu_vm *vm = &fpriv->vm; |
73 | union drm_amdgpu_cs *cs = data; | ||
74 | uint64_t *chunk_array_user; | 98 | uint64_t *chunk_array_user; |
75 | uint64_t *chunk_array; | 99 | uint64_t *chunk_array; |
76 | unsigned size, num_ibs = 0; | 100 | unsigned size, num_ibs = 0; |
@@ -164,6 +188,19 @@ static int amdgpu_cs_parser_init(struct amdgpu_cs_parser *p, void *data) | |||
164 | 188 | ||
165 | break; | 189 | break; |
166 | 190 | ||
191 | case AMDGPU_CHUNK_ID_BO_HANDLES: | ||
192 | size = sizeof(struct drm_amdgpu_bo_list_in); | ||
193 | if (p->chunks[i].length_dw * sizeof(uint32_t) < size) { | ||
194 | ret = -EINVAL; | ||
195 | goto free_partial_kdata; | ||
196 | } | ||
197 | |||
198 | ret = amdgpu_cs_bo_handles_chunk(p, p->chunks[i].kdata); | ||
199 | if (ret) | ||
200 | goto free_partial_kdata; | ||
201 | |||
202 | break; | ||
203 | |||
167 | case AMDGPU_CHUNK_ID_DEPENDENCIES: | 204 | case AMDGPU_CHUNK_ID_DEPENDENCIES: |
168 | case AMDGPU_CHUNK_ID_SYNCOBJ_IN: | 205 | case AMDGPU_CHUNK_ID_SYNCOBJ_IN: |
169 | case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: | 206 | case AMDGPU_CHUNK_ID_SYNCOBJ_OUT: |
@@ -534,7 +571,12 @@ static int amdgpu_cs_parser_bos(struct amdgpu_cs_parser *p, | |||
534 | 571 | ||
535 | INIT_LIST_HEAD(&p->validated); | 572 | INIT_LIST_HEAD(&p->validated); |
536 | 573 | ||
537 | p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); | 574 | /* p->bo_list could already be assigned if AMDGPU_CHUNK_ID_BO_HANDLES is present */ |
575 | if (!p->bo_list) | ||
576 | p->bo_list = amdgpu_bo_list_get(fpriv, cs->in.bo_list_handle); | ||
577 | else | ||
578 | mutex_lock(&p->bo_list->lock); | ||
579 | |||
538 | if (p->bo_list) { | 580 | if (p->bo_list) { |
539 | amdgpu_bo_list_get_list(p->bo_list, &p->validated); | 581 | amdgpu_bo_list_get_list(p->bo_list, &p->validated); |
540 | if (p->bo_list->first_userptr != p->bo_list->num_entries) | 582 | if (p->bo_list->first_userptr != p->bo_list->num_entries) |