|
38 | 38 | VIRTGPU_BLOB_FLAG_USE_SHAREABLE | \ |
39 | 39 | VIRTGPU_BLOB_FLAG_USE_CROSS_DEVICE) |
40 | 40 |
|
41 | | -static int virtio_gpu_fence_event_create(struct drm_device *dev, |
42 | | - struct drm_file *file, |
43 | | - struct virtio_gpu_fence *fence, |
44 | | - uint32_t ring_idx) |
45 | | -{ |
46 | | - struct virtio_gpu_fpriv *vfpriv = file->driver_priv; |
47 | | - struct virtio_gpu_fence_event *e = NULL; |
48 | | - int ret; |
49 | | - |
50 | | - if (!(vfpriv->ring_idx_mask & BIT_ULL(ring_idx))) |
51 | | - return 0; |
52 | | - |
53 | | - e = kzalloc(sizeof(*e), GFP_KERNEL); |
54 | | - if (!e) |
55 | | - return -ENOMEM; |
56 | | - |
57 | | - e->event.type = VIRTGPU_EVENT_FENCE_SIGNALED; |
58 | | - e->event.length = sizeof(e->event); |
59 | | - |
60 | | - ret = drm_event_reserve_init(dev, file, &e->base, &e->event); |
61 | | - if (ret) |
62 | | - goto free; |
63 | | - |
64 | | - fence->e = e; |
65 | | - return 0; |
66 | | -free: |
67 | | - kfree(e); |
68 | | - return ret; |
69 | | -} |
70 | | - |
71 | 41 | /* Must be called with &virtio_gpu_fpriv.struct_mutex held. */ |
72 | 42 | static void virtio_gpu_create_context_locked(struct virtio_gpu_device *vgdev, |
73 | 43 | struct virtio_gpu_fpriv *vfpriv) |
@@ -108,158 +78,6 @@ static int virtio_gpu_map_ioctl(struct drm_device *dev, void *data, |
108 | 78 | &virtio_gpu_map->offset); |
109 | 79 | } |
110 | 80 |
|
111 | | -/* |
112 | | - * Usage of execbuffer: |
113 | | - * Relocations need to take into account the full VIRTIO_GPUDrawable size. |
114 | | - * However, the command as passed from user space must *not* contain the initial |
115 | | - * VIRTIO_GPUReleaseInfo struct (first XXX bytes) |
116 | | - */ |
117 | | -static int virtio_gpu_execbuffer_ioctl(struct drm_device *dev, void *data, |
118 | | - struct drm_file *file) |
119 | | -{ |
120 | | - struct drm_virtgpu_execbuffer *exbuf = data; |
121 | | - struct virtio_gpu_device *vgdev = dev->dev_private; |
122 | | - struct virtio_gpu_fpriv *vfpriv = file->driver_priv; |
123 | | - struct virtio_gpu_fence *out_fence; |
124 | | - int ret; |
125 | | - uint32_t *bo_handles = NULL; |
126 | | - void __user *user_bo_handles = NULL; |
127 | | - struct virtio_gpu_object_array *buflist = NULL; |
128 | | - struct sync_file *sync_file; |
129 | | - int out_fence_fd = -1; |
130 | | - void *buf; |
131 | | - uint64_t fence_ctx; |
132 | | - uint32_t ring_idx; |
133 | | - |
134 | | - fence_ctx = vgdev->fence_drv.context; |
135 | | - ring_idx = 0; |
136 | | - |
137 | | - if (vgdev->has_virgl_3d == false) |
138 | | - return -ENOSYS; |
139 | | - |
140 | | - if ((exbuf->flags & ~VIRTGPU_EXECBUF_FLAGS)) |
141 | | - return -EINVAL; |
142 | | - |
143 | | - if ((exbuf->flags & VIRTGPU_EXECBUF_RING_IDX)) { |
144 | | - if (exbuf->ring_idx >= vfpriv->num_rings) |
145 | | - return -EINVAL; |
146 | | - |
147 | | - if (!vfpriv->base_fence_ctx) |
148 | | - return -EINVAL; |
149 | | - |
150 | | - fence_ctx = vfpriv->base_fence_ctx; |
151 | | - ring_idx = exbuf->ring_idx; |
152 | | - } |
153 | | - |
154 | | - virtio_gpu_create_context(dev, file); |
155 | | - if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_IN) { |
156 | | - struct dma_fence *in_fence; |
157 | | - |
158 | | - in_fence = sync_file_get_fence(exbuf->fence_fd); |
159 | | - |
160 | | - if (!in_fence) |
161 | | - return -EINVAL; |
162 | | - |
163 | | - /* |
164 | | - * Wait if the fence is from a foreign context, or if the fence |
165 | | - * array contains any fence from a foreign context. |
166 | | - */ |
167 | | - ret = 0; |
168 | | - if (!dma_fence_match_context(in_fence, fence_ctx + ring_idx)) |
169 | | - ret = dma_fence_wait(in_fence, true); |
170 | | - |
171 | | - dma_fence_put(in_fence); |
172 | | - if (ret) |
173 | | - return ret; |
174 | | - } |
175 | | - |
176 | | - if (exbuf->flags & VIRTGPU_EXECBUF_FENCE_FD_OUT) { |
177 | | - out_fence_fd = get_unused_fd_flags(O_CLOEXEC); |
178 | | - if (out_fence_fd < 0) |
179 | | - return out_fence_fd; |
180 | | - } |
181 | | - |
182 | | - if (exbuf->num_bo_handles) { |
183 | | - bo_handles = kvmalloc_array(exbuf->num_bo_handles, |
184 | | - sizeof(uint32_t), GFP_KERNEL); |
185 | | - if (!bo_handles) { |
186 | | - ret = -ENOMEM; |
187 | | - goto out_unused_fd; |
188 | | - } |
189 | | - |
190 | | - user_bo_handles = u64_to_user_ptr(exbuf->bo_handles); |
191 | | - if (copy_from_user(bo_handles, user_bo_handles, |
192 | | - exbuf->num_bo_handles * sizeof(uint32_t))) { |
193 | | - ret = -EFAULT; |
194 | | - goto out_unused_fd; |
195 | | - } |
196 | | - |
197 | | - buflist = virtio_gpu_array_from_handles(file, bo_handles, |
198 | | - exbuf->num_bo_handles); |
199 | | - if (!buflist) { |
200 | | - ret = -ENOENT; |
201 | | - goto out_unused_fd; |
202 | | - } |
203 | | - kvfree(bo_handles); |
204 | | - bo_handles = NULL; |
205 | | - } |
206 | | - |
207 | | - buf = vmemdup_user(u64_to_user_ptr(exbuf->command), exbuf->size); |
208 | | - if (IS_ERR(buf)) { |
209 | | - ret = PTR_ERR(buf); |
210 | | - goto out_unused_fd; |
211 | | - } |
212 | | - |
213 | | - if (buflist) { |
214 | | - ret = virtio_gpu_array_lock_resv(buflist); |
215 | | - if (ret) |
216 | | - goto out_memdup; |
217 | | - } |
218 | | - |
219 | | - out_fence = virtio_gpu_fence_alloc(vgdev, fence_ctx, ring_idx); |
220 | | - if(!out_fence) { |
221 | | - ret = -ENOMEM; |
222 | | - goto out_unresv; |
223 | | - } |
224 | | - |
225 | | - ret = virtio_gpu_fence_event_create(dev, file, out_fence, ring_idx); |
226 | | - if (ret) |
227 | | - goto out_unresv; |
228 | | - |
229 | | - if (out_fence_fd >= 0) { |
230 | | - sync_file = sync_file_create(&out_fence->f); |
231 | | - if (!sync_file) { |
232 | | - dma_fence_put(&out_fence->f); |
233 | | - ret = -ENOMEM; |
234 | | - goto out_unresv; |
235 | | - } |
236 | | - |
237 | | - exbuf->fence_fd = out_fence_fd; |
238 | | - fd_install(out_fence_fd, sync_file->file); |
239 | | - } |
240 | | - |
241 | | - virtio_gpu_cmd_submit(vgdev, buf, exbuf->size, |
242 | | - vfpriv->ctx_id, buflist, out_fence); |
243 | | - dma_fence_put(&out_fence->f); |
244 | | - virtio_gpu_notify(vgdev); |
245 | | - return 0; |
246 | | - |
247 | | -out_unresv: |
248 | | - if (buflist) |
249 | | - virtio_gpu_array_unlock_resv(buflist); |
250 | | -out_memdup: |
251 | | - kvfree(buf); |
252 | | -out_unused_fd: |
253 | | - kvfree(bo_handles); |
254 | | - if (buflist) |
255 | | - virtio_gpu_array_put_free(buflist); |
256 | | - |
257 | | - if (out_fence_fd >= 0) |
258 | | - put_unused_fd(out_fence_fd); |
259 | | - |
260 | | - return ret; |
261 | | -} |
262 | | - |
263 | 81 | static int virtio_gpu_getparam_ioctl(struct drm_device *dev, void *data, |
264 | 82 | struct drm_file *file) |
265 | 83 | { |
|
0 commit comments