vmwgfx: Use "Virtual" connectors and encoders rather than "LVDS".
[pandora-kernel.git] / drivers / gpu / drm / vmwgfx / vmwgfx_execbuf.c
1 /**************************************************************************
2  *
3  * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24  * USE OR OTHER DEALINGS IN THE SOFTWARE.
25  *
26  **************************************************************************/
27
28 #include "vmwgfx_drv.h"
29 #include "vmwgfx_reg.h"
30 #include "ttm/ttm_bo_api.h"
31 #include "ttm/ttm_placement.h"
32
33 static int vmw_cmd_invalid(struct vmw_private *dev_priv,
34                            struct vmw_sw_context *sw_context,
35                            SVGA3dCmdHeader *header)
36 {
37         return capable(CAP_SYS_ADMIN) ? : -EINVAL;
38 }
39
40 static int vmw_cmd_ok(struct vmw_private *dev_priv,
41                       struct vmw_sw_context *sw_context,
42                       SVGA3dCmdHeader *header)
43 {
44         return 0;
45 }
46
47 static void vmw_resource_to_validate_list(struct vmw_sw_context *sw_context,
48                                           struct vmw_resource **p_res)
49 {
50         struct vmw_resource *res = *p_res;
51
52         if (list_empty(&res->validate_head)) {
53                 list_add_tail(&res->validate_head, &sw_context->resource_list);
54                 *p_res = NULL;
55         } else
56                 vmw_resource_unreference(p_res);
57 }
58
59 /**
60  * vmw_bo_to_validate_list - add a bo to a validate list
61  *
62  * @sw_context: The software context used for this command submission batch.
63  * @bo: The buffer object to add.
64  * @fence_flags: Fence flags to be or'ed with any other fence flags for
65  * this buffer on this submission batch.
66  * @p_val_node: If non-NULL Will be updated with the validate node number
67  * on return.
68  *
69  * Returns -EINVAL if the limit of number of buffer objects per command
70  * submission is reached.
71  */
72 static int vmw_bo_to_validate_list(struct vmw_sw_context *sw_context,
73                                    struct ttm_buffer_object *bo,
74                                    uint32_t fence_flags,
75                                    uint32_t *p_val_node)
76 {
77         uint32_t val_node;
78         struct ttm_validate_buffer *val_buf;
79
80         val_node = vmw_dmabuf_validate_node(bo, sw_context->cur_val_buf);
81
82         if (unlikely(val_node >= VMWGFX_MAX_VALIDATIONS)) {
83                 DRM_ERROR("Max number of DMA buffers per submission"
84                           " exceeded.\n");
85                 return -EINVAL;
86         }
87
88         val_buf = &sw_context->val_bufs[val_node];
89         if (unlikely(val_node == sw_context->cur_val_buf)) {
90                 val_buf->new_sync_obj_arg = NULL;
91                 val_buf->bo = ttm_bo_reference(bo);
92                 list_add_tail(&val_buf->head, &sw_context->validate_nodes);
93                 ++sw_context->cur_val_buf;
94         }
95
96         val_buf->new_sync_obj_arg = (void *)
97                 ((unsigned long) val_buf->new_sync_obj_arg | fence_flags);
98         sw_context->fence_flags |= fence_flags;
99
100         if (p_val_node)
101                 *p_val_node = val_node;
102
103         return 0;
104 }
105
106 static int vmw_cmd_cid_check(struct vmw_private *dev_priv,
107                              struct vmw_sw_context *sw_context,
108                              SVGA3dCmdHeader *header)
109 {
110         struct vmw_resource *ctx;
111
112         struct vmw_cid_cmd {
113                 SVGA3dCmdHeader header;
114                 __le32 cid;
115         } *cmd;
116         int ret;
117
118         cmd = container_of(header, struct vmw_cid_cmd, header);
119         if (likely(sw_context->cid_valid && cmd->cid == sw_context->last_cid))
120                 return 0;
121
122         ret = vmw_context_check(dev_priv, sw_context->tfile, cmd->cid,
123                                 &ctx);
124         if (unlikely(ret != 0)) {
125                 DRM_ERROR("Could not find or use context %u\n",
126                           (unsigned) cmd->cid);
127                 return ret;
128         }
129
130         sw_context->last_cid = cmd->cid;
131         sw_context->cid_valid = true;
132         sw_context->cur_ctx = ctx;
133         vmw_resource_to_validate_list(sw_context, &ctx);
134
135         return 0;
136 }
137
138 static int vmw_cmd_sid_check(struct vmw_private *dev_priv,
139                              struct vmw_sw_context *sw_context,
140                              uint32_t *sid)
141 {
142         struct vmw_surface *srf;
143         int ret;
144         struct vmw_resource *res;
145
146         if (*sid == SVGA3D_INVALID_ID)
147                 return 0;
148
149         if (likely((sw_context->sid_valid  &&
150                       *sid == sw_context->last_sid))) {
151                 *sid = sw_context->sid_translation;
152                 return 0;
153         }
154
155         ret = vmw_user_surface_lookup_handle(dev_priv,
156                                              sw_context->tfile,
157                                              *sid, &srf);
158         if (unlikely(ret != 0)) {
159                 DRM_ERROR("Could ot find or use surface 0x%08x "
160                           "address 0x%08lx\n",
161                           (unsigned int) *sid,
162                           (unsigned long) sid);
163                 return ret;
164         }
165
166         ret = vmw_surface_validate(dev_priv, srf);
167         if (unlikely(ret != 0)) {
168                 if (ret != -ERESTARTSYS)
169                         DRM_ERROR("Could not validate surface.\n");
170                 vmw_surface_unreference(&srf);
171                 return ret;
172         }
173
174         sw_context->last_sid = *sid;
175         sw_context->sid_valid = true;
176         sw_context->sid_translation = srf->res.id;
177         *sid = sw_context->sid_translation;
178
179         res = &srf->res;
180         vmw_resource_to_validate_list(sw_context, &res);
181
182         return 0;
183 }
184
185
186 static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv,
187                                            struct vmw_sw_context *sw_context,
188                                            SVGA3dCmdHeader *header)
189 {
190         struct vmw_sid_cmd {
191                 SVGA3dCmdHeader header;
192                 SVGA3dCmdSetRenderTarget body;
193         } *cmd;
194         int ret;
195
196         ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
197         if (unlikely(ret != 0))
198                 return ret;
199
200         cmd = container_of(header, struct vmw_sid_cmd, header);
201         ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.target.sid);
202         return ret;
203 }
204
205 static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv,
206                                       struct vmw_sw_context *sw_context,
207                                       SVGA3dCmdHeader *header)
208 {
209         struct vmw_sid_cmd {
210                 SVGA3dCmdHeader header;
211                 SVGA3dCmdSurfaceCopy body;
212         } *cmd;
213         int ret;
214
215         cmd = container_of(header, struct vmw_sid_cmd, header);
216         ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid);
217         if (unlikely(ret != 0))
218                 return ret;
219         return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid);
220 }
221
222 static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv,
223                                      struct vmw_sw_context *sw_context,
224                                      SVGA3dCmdHeader *header)
225 {
226         struct vmw_sid_cmd {
227                 SVGA3dCmdHeader header;
228                 SVGA3dCmdSurfaceStretchBlt body;
229         } *cmd;
230         int ret;
231
232         cmd = container_of(header, struct vmw_sid_cmd, header);
233         ret = vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.src.sid);
234         if (unlikely(ret != 0))
235                 return ret;
236         return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.dest.sid);
237 }
238
239 static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv,
240                                          struct vmw_sw_context *sw_context,
241                                          SVGA3dCmdHeader *header)
242 {
243         struct vmw_sid_cmd {
244                 SVGA3dCmdHeader header;
245                 SVGA3dCmdBlitSurfaceToScreen body;
246         } *cmd;
247
248         cmd = container_of(header, struct vmw_sid_cmd, header);
249
250         if (unlikely(!sw_context->kernel)) {
251                 DRM_ERROR("Kernel only SVGA3d command: %u.\n", cmd->header.id);
252                 return -EPERM;
253         }
254
255         return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.srcImage.sid);
256 }
257
258 static int vmw_cmd_present_check(struct vmw_private *dev_priv,
259                                  struct vmw_sw_context *sw_context,
260                                  SVGA3dCmdHeader *header)
261 {
262         struct vmw_sid_cmd {
263                 SVGA3dCmdHeader header;
264                 SVGA3dCmdPresent body;
265         } *cmd;
266
267
268         cmd = container_of(header, struct vmw_sid_cmd, header);
269
270         if (unlikely(!sw_context->kernel)) {
271                 DRM_ERROR("Kernel only SVGA3d command: %u.\n", cmd->header.id);
272                 return -EPERM;
273         }
274
275         return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.sid);
276 }
277
278 /**
279  * vmw_query_bo_switch_prepare - Prepare to switch pinned buffer for queries.
280  *
281  * @dev_priv: The device private structure.
282  * @cid: The hardware context for the next query.
283  * @new_query_bo: The new buffer holding query results.
284  * @sw_context: The software context used for this command submission.
285  *
286  * This function checks whether @new_query_bo is suitable for holding
287  * query results, and if another buffer currently is pinned for query
288  * results. If so, the function prepares the state of @sw_context for
289  * switching pinned buffers after successful submission of the current
290  * command batch. It also checks whether we're using a new query context.
291  * In that case, it makes sure we emit a query barrier for the old
292  * context before the current query buffer is fenced.
293  */
294 static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv,
295                                        uint32_t cid,
296                                        struct ttm_buffer_object *new_query_bo,
297                                        struct vmw_sw_context *sw_context)
298 {
299         int ret;
300         bool add_cid = false;
301         uint32_t cid_to_add;
302
303         if (unlikely(new_query_bo != sw_context->cur_query_bo)) {
304
305                 if (unlikely(new_query_bo->num_pages > 4)) {
306                         DRM_ERROR("Query buffer too large.\n");
307                         return -EINVAL;
308                 }
309
310                 if (unlikely(sw_context->cur_query_bo != NULL)) {
311                         BUG_ON(!sw_context->query_cid_valid);
312                         add_cid = true;
313                         cid_to_add = sw_context->cur_query_cid;
314                         ret = vmw_bo_to_validate_list(sw_context,
315                                                       sw_context->cur_query_bo,
316                                                       DRM_VMW_FENCE_FLAG_EXEC,
317                                                       NULL);
318                         if (unlikely(ret != 0))
319                                 return ret;
320                 }
321                 sw_context->cur_query_bo = new_query_bo;
322
323                 ret = vmw_bo_to_validate_list(sw_context,
324                                               dev_priv->dummy_query_bo,
325                                               DRM_VMW_FENCE_FLAG_EXEC,
326                                               NULL);
327                 if (unlikely(ret != 0))
328                         return ret;
329
330         }
331
332         if (unlikely(cid != sw_context->cur_query_cid &&
333                      sw_context->query_cid_valid)) {
334                 add_cid = true;
335                 cid_to_add = sw_context->cur_query_cid;
336         }
337
338         sw_context->cur_query_cid = cid;
339         sw_context->query_cid_valid = true;
340
341         if (add_cid) {
342                 struct vmw_resource *ctx = sw_context->cur_ctx;
343
344                 if (list_empty(&ctx->query_head))
345                         list_add_tail(&ctx->query_head,
346                                       &sw_context->query_list);
347                 ret = vmw_bo_to_validate_list(sw_context,
348                                               dev_priv->dummy_query_bo,
349                                               DRM_VMW_FENCE_FLAG_EXEC,
350                                               NULL);
351                 if (unlikely(ret != 0))
352                         return ret;
353         }
354         return 0;
355 }
356
357
358 /**
359  * vmw_query_bo_switch_commit - Finalize switching pinned query buffer
360  *
361  * @dev_priv: The device private structure.
362  * @sw_context: The software context used for this command submission batch.
363  *
364  * This function will check if we're switching query buffers, and will then,
365  * if no other query waits are issued this command submission batch,
366  * issue a dummy occlusion query wait used as a query barrier. When the fence
367  * object following that query wait has signaled, we are sure that all
368  * preseding queries have finished, and the old query buffer can be unpinned.
369  * However, since both the new query buffer and the old one are fenced with
370  * that fence, we can do an asynchronus unpin now, and be sure that the
371  * old query buffer won't be moved until the fence has signaled.
372  *
373  * As mentioned above, both the new - and old query buffers need to be fenced
374  * using a sequence emitted *after* calling this function.
375  */
376 static void vmw_query_bo_switch_commit(struct vmw_private *dev_priv,
377                                      struct vmw_sw_context *sw_context)
378 {
379
380         struct vmw_resource *ctx, *next_ctx;
381         int ret;
382
383         /*
384          * The validate list should still hold references to all
385          * contexts here.
386          */
387
388         list_for_each_entry_safe(ctx, next_ctx, &sw_context->query_list,
389                                  query_head) {
390                 list_del_init(&ctx->query_head);
391
392                 BUG_ON(list_empty(&ctx->validate_head));
393
394                 ret = vmw_fifo_emit_dummy_query(dev_priv, ctx->id);
395
396                 if (unlikely(ret != 0))
397                         DRM_ERROR("Out of fifo space for dummy query.\n");
398         }
399
400         if (dev_priv->pinned_bo != sw_context->cur_query_bo) {
401                 if (dev_priv->pinned_bo) {
402                         vmw_bo_pin(dev_priv->pinned_bo, false);
403                         ttm_bo_unref(&dev_priv->pinned_bo);
404                 }
405
406                 vmw_bo_pin(sw_context->cur_query_bo, true);
407
408                 /*
409                  * We pin also the dummy_query_bo buffer so that we
410                  * don't need to validate it when emitting
411                  * dummy queries in context destroy paths.
412                  */
413
414                 vmw_bo_pin(dev_priv->dummy_query_bo, true);
415                 dev_priv->dummy_query_bo_pinned = true;
416
417                 dev_priv->query_cid = sw_context->cur_query_cid;
418                 dev_priv->pinned_bo =
419                         ttm_bo_reference(sw_context->cur_query_bo);
420         }
421 }
422
423 /**
424  * vmw_query_switch_backoff - clear query barrier list
425  * @sw_context: The sw context used for this submission batch.
426  *
427  * This function is used as part of an error path, where a previously
428  * set up list of query barriers needs to be cleared.
429  *
430  */
431 static void vmw_query_switch_backoff(struct vmw_sw_context *sw_context)
432 {
433         struct list_head *list, *next;
434
435         list_for_each_safe(list, next, &sw_context->query_list) {
436                 list_del_init(list);
437         }
438 }
439
440 static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
441                                    struct vmw_sw_context *sw_context,
442                                    SVGAGuestPtr *ptr,
443                                    struct vmw_dma_buffer **vmw_bo_p)
444 {
445         struct vmw_dma_buffer *vmw_bo = NULL;
446         struct ttm_buffer_object *bo;
447         uint32_t handle = ptr->gmrId;
448         struct vmw_relocation *reloc;
449         int ret;
450
451         ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo);
452         if (unlikely(ret != 0)) {
453                 DRM_ERROR("Could not find or use GMR region.\n");
454                 return -EINVAL;
455         }
456         bo = &vmw_bo->base;
457
458         if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) {
459                 DRM_ERROR("Max number relocations per submission"
460                           " exceeded\n");
461                 ret = -EINVAL;
462                 goto out_no_reloc;
463         }
464
465         reloc = &sw_context->relocs[sw_context->cur_reloc++];
466         reloc->location = ptr;
467
468         ret = vmw_bo_to_validate_list(sw_context, bo, DRM_VMW_FENCE_FLAG_EXEC,
469                                       &reloc->index);
470         if (unlikely(ret != 0))
471                 goto out_no_reloc;
472
473         *vmw_bo_p = vmw_bo;
474         return 0;
475
476 out_no_reloc:
477         vmw_dmabuf_unreference(&vmw_bo);
478         vmw_bo_p = NULL;
479         return ret;
480 }
481
482 static int vmw_cmd_end_query(struct vmw_private *dev_priv,
483                              struct vmw_sw_context *sw_context,
484                              SVGA3dCmdHeader *header)
485 {
486         struct vmw_dma_buffer *vmw_bo;
487         struct vmw_query_cmd {
488                 SVGA3dCmdHeader header;
489                 SVGA3dCmdEndQuery q;
490         } *cmd;
491         int ret;
492
493         cmd = container_of(header, struct vmw_query_cmd, header);
494         ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
495         if (unlikely(ret != 0))
496                 return ret;
497
498         ret = vmw_translate_guest_ptr(dev_priv, sw_context,
499                                       &cmd->q.guestResult,
500                                       &vmw_bo);
501         if (unlikely(ret != 0))
502                 return ret;
503
504         ret = vmw_query_bo_switch_prepare(dev_priv, cmd->q.cid,
505                                           &vmw_bo->base, sw_context);
506
507         vmw_dmabuf_unreference(&vmw_bo);
508         return ret;
509 }
510
511 static int vmw_cmd_wait_query(struct vmw_private *dev_priv,
512                               struct vmw_sw_context *sw_context,
513                               SVGA3dCmdHeader *header)
514 {
515         struct vmw_dma_buffer *vmw_bo;
516         struct vmw_query_cmd {
517                 SVGA3dCmdHeader header;
518                 SVGA3dCmdWaitForQuery q;
519         } *cmd;
520         int ret;
521         struct vmw_resource *ctx;
522
523         cmd = container_of(header, struct vmw_query_cmd, header);
524         ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
525         if (unlikely(ret != 0))
526                 return ret;
527
528         ret = vmw_translate_guest_ptr(dev_priv, sw_context,
529                                       &cmd->q.guestResult,
530                                       &vmw_bo);
531         if (unlikely(ret != 0))
532                 return ret;
533
534         vmw_dmabuf_unreference(&vmw_bo);
535
536         /*
537          * This wait will act as a barrier for previous waits for this
538          * context.
539          */
540
541         ctx = sw_context->cur_ctx;
542         if (!list_empty(&ctx->query_head))
543                 list_del_init(&ctx->query_head);
544
545         return 0;
546 }
547
548 static int vmw_cmd_dma(struct vmw_private *dev_priv,
549                        struct vmw_sw_context *sw_context,
550                        SVGA3dCmdHeader *header)
551 {
552         struct vmw_dma_buffer *vmw_bo = NULL;
553         struct ttm_buffer_object *bo;
554         struct vmw_surface *srf = NULL;
555         struct vmw_dma_cmd {
556                 SVGA3dCmdHeader header;
557                 SVGA3dCmdSurfaceDMA dma;
558         } *cmd;
559         int ret;
560         struct vmw_resource *res;
561
562         cmd = container_of(header, struct vmw_dma_cmd, header);
563         ret = vmw_translate_guest_ptr(dev_priv, sw_context,
564                                       &cmd->dma.guest.ptr,
565                                       &vmw_bo);
566         if (unlikely(ret != 0))
567                 return ret;
568
569         bo = &vmw_bo->base;
570         ret = vmw_user_surface_lookup_handle(dev_priv, sw_context->tfile,
571                                              cmd->dma.host.sid, &srf);
572         if (ret) {
573                 DRM_ERROR("could not find surface\n");
574                 goto out_no_reloc;
575         }
576
577         ret = vmw_surface_validate(dev_priv, srf);
578         if (unlikely(ret != 0)) {
579                 if (ret != -ERESTARTSYS)
580                         DRM_ERROR("Culd not validate surface.\n");
581                 goto out_no_validate;
582         }
583
584         /*
585          * Patch command stream with device SID.
586          */
587         cmd->dma.host.sid = srf->res.id;
588         vmw_kms_cursor_snoop(srf, sw_context->tfile, bo, header);
589
590         vmw_dmabuf_unreference(&vmw_bo);
591
592         res = &srf->res;
593         vmw_resource_to_validate_list(sw_context, &res);
594
595         return 0;
596
597 out_no_validate:
598         vmw_surface_unreference(&srf);
599 out_no_reloc:
600         vmw_dmabuf_unreference(&vmw_bo);
601         return ret;
602 }
603
604 static int vmw_cmd_draw(struct vmw_private *dev_priv,
605                         struct vmw_sw_context *sw_context,
606                         SVGA3dCmdHeader *header)
607 {
608         struct vmw_draw_cmd {
609                 SVGA3dCmdHeader header;
610                 SVGA3dCmdDrawPrimitives body;
611         } *cmd;
612         SVGA3dVertexDecl *decl = (SVGA3dVertexDecl *)(
613                 (unsigned long)header + sizeof(*cmd));
614         SVGA3dPrimitiveRange *range;
615         uint32_t i;
616         uint32_t maxnum;
617         int ret;
618
619         ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
620         if (unlikely(ret != 0))
621                 return ret;
622
623         cmd = container_of(header, struct vmw_draw_cmd, header);
624         maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl);
625
626         if (unlikely(cmd->body.numVertexDecls > maxnum)) {
627                 DRM_ERROR("Illegal number of vertex declarations.\n");
628                 return -EINVAL;
629         }
630
631         for (i = 0; i < cmd->body.numVertexDecls; ++i, ++decl) {
632                 ret = vmw_cmd_sid_check(dev_priv, sw_context,
633                                         &decl->array.surfaceId);
634                 if (unlikely(ret != 0))
635                         return ret;
636         }
637
638         maxnum = (header->size - sizeof(cmd->body) -
639                   cmd->body.numVertexDecls * sizeof(*decl)) / sizeof(*range);
640         if (unlikely(cmd->body.numRanges > maxnum)) {
641                 DRM_ERROR("Illegal number of index ranges.\n");
642                 return -EINVAL;
643         }
644
645         range = (SVGA3dPrimitiveRange *) decl;
646         for (i = 0; i < cmd->body.numRanges; ++i, ++range) {
647                 ret = vmw_cmd_sid_check(dev_priv, sw_context,
648                                         &range->indexArray.surfaceId);
649                 if (unlikely(ret != 0))
650                         return ret;
651         }
652         return 0;
653 }
654
655
656 static int vmw_cmd_tex_state(struct vmw_private *dev_priv,
657                              struct vmw_sw_context *sw_context,
658                              SVGA3dCmdHeader *header)
659 {
660         struct vmw_tex_state_cmd {
661                 SVGA3dCmdHeader header;
662                 SVGA3dCmdSetTextureState state;
663         };
664
665         SVGA3dTextureState *last_state = (SVGA3dTextureState *)
666           ((unsigned long) header + header->size + sizeof(header));
667         SVGA3dTextureState *cur_state = (SVGA3dTextureState *)
668                 ((unsigned long) header + sizeof(struct vmw_tex_state_cmd));
669         int ret;
670
671         ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
672         if (unlikely(ret != 0))
673                 return ret;
674
675         for (; cur_state < last_state; ++cur_state) {
676                 if (likely(cur_state->name != SVGA3D_TS_BIND_TEXTURE))
677                         continue;
678
679                 ret = vmw_cmd_sid_check(dev_priv, sw_context,
680                                         &cur_state->value);
681                 if (unlikely(ret != 0))
682                         return ret;
683         }
684
685         return 0;
686 }
687
688 static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv,
689                                       struct vmw_sw_context *sw_context,
690                                       void *buf)
691 {
692         struct vmw_dma_buffer *vmw_bo;
693         int ret;
694
695         struct {
696                 uint32_t header;
697                 SVGAFifoCmdDefineGMRFB body;
698         } *cmd = buf;
699
700         ret = vmw_translate_guest_ptr(dev_priv, sw_context,
701                                       &cmd->body.ptr,
702                                       &vmw_bo);
703         if (unlikely(ret != 0))
704                 return ret;
705
706         vmw_dmabuf_unreference(&vmw_bo);
707
708         return ret;
709 }
710
711 static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv,
712                                 struct vmw_sw_context *sw_context,
713                                 void *buf, uint32_t *size)
714 {
715         uint32_t size_remaining = *size;
716         uint32_t cmd_id;
717
718         cmd_id = le32_to_cpu(((uint32_t *)buf)[0]);
719         switch (cmd_id) {
720         case SVGA_CMD_UPDATE:
721                 *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdUpdate);
722                 break;
723         case SVGA_CMD_DEFINE_GMRFB:
724                 *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdDefineGMRFB);
725                 break;
726         case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:
727                 *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
728                 break;
729         case SVGA_CMD_BLIT_SCREEN_TO_GMRFB:
730                 *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
731                 break;
732         default:
733                 DRM_ERROR("Unsupported SVGA command: %u.\n", cmd_id);
734                 return -EINVAL;
735         }
736
737         if (*size > size_remaining) {
738                 DRM_ERROR("Invalid SVGA command (size mismatch):"
739                           " %u.\n", cmd_id);
740                 return -EINVAL;
741         }
742
743         if (unlikely(!sw_context->kernel)) {
744                 DRM_ERROR("Kernel only SVGA command: %u.\n", cmd_id);
745                 return -EPERM;
746         }
747
748         if (cmd_id == SVGA_CMD_DEFINE_GMRFB)
749                 return vmw_cmd_check_define_gmrfb(dev_priv, sw_context, buf);
750
751         return 0;
752 }
753
754 typedef int (*vmw_cmd_func) (struct vmw_private *,
755                              struct vmw_sw_context *,
756                              SVGA3dCmdHeader *);
757
758 #define VMW_CMD_DEF(cmd, func) \
759         [cmd - SVGA_3D_CMD_BASE] = func
760
761 static vmw_cmd_func vmw_cmd_funcs[SVGA_3D_CMD_MAX] = {
762         VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid),
763         VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid),
764         VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_COPY, &vmw_cmd_surface_copy_check),
765         VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_STRETCHBLT, &vmw_cmd_stretch_blt_check),
766         VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DMA, &vmw_cmd_dma),
767         VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DEFINE, &vmw_cmd_invalid),
768         VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DESTROY, &vmw_cmd_invalid),
769         VMW_CMD_DEF(SVGA_3D_CMD_SETTRANSFORM, &vmw_cmd_cid_check),
770         VMW_CMD_DEF(SVGA_3D_CMD_SETZRANGE, &vmw_cmd_cid_check),
771         VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERSTATE, &vmw_cmd_cid_check),
772         VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERTARGET,
773                     &vmw_cmd_set_render_target_check),
774         VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_tex_state),
775         VMW_CMD_DEF(SVGA_3D_CMD_SETMATERIAL, &vmw_cmd_cid_check),
776         VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTDATA, &vmw_cmd_cid_check),
777         VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTENABLED, &vmw_cmd_cid_check),
778         VMW_CMD_DEF(SVGA_3D_CMD_SETVIEWPORT, &vmw_cmd_cid_check),
779         VMW_CMD_DEF(SVGA_3D_CMD_SETCLIPPLANE, &vmw_cmd_cid_check),
780         VMW_CMD_DEF(SVGA_3D_CMD_CLEAR, &vmw_cmd_cid_check),
781         VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check),
782         VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_cid_check),
783         VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_cid_check),
784         VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_cid_check),
785         VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_cid_check),
786         VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw),
787         VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check),
788         VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check),
789         VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_end_query),
790         VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_wait_query),
791         VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok),
792         VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN,
793                     &vmw_cmd_blt_surf_screen_check)
794 };
795
796 static int vmw_cmd_check(struct vmw_private *dev_priv,
797                          struct vmw_sw_context *sw_context,
798                          void *buf, uint32_t *size)
799 {
800         uint32_t cmd_id;
801         uint32_t size_remaining = *size;
802         SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf;
803         int ret;
804
805         cmd_id = le32_to_cpu(((uint32_t *)buf)[0]);
806         /* Handle any none 3D commands */
807         if (unlikely(cmd_id < SVGA_CMD_MAX))
808                 return vmw_cmd_check_not_3d(dev_priv, sw_context, buf, size);
809
810
811         cmd_id = le32_to_cpu(header->id);
812         *size = le32_to_cpu(header->size) + sizeof(SVGA3dCmdHeader);
813
814         cmd_id -= SVGA_3D_CMD_BASE;
815         if (unlikely(*size > size_remaining))
816                 goto out_err;
817
818         if (unlikely(cmd_id >= SVGA_3D_CMD_MAX - SVGA_3D_CMD_BASE))
819                 goto out_err;
820
821         ret = vmw_cmd_funcs[cmd_id](dev_priv, sw_context, header);
822         if (unlikely(ret != 0))
823                 goto out_err;
824
825         return 0;
826 out_err:
827         DRM_ERROR("Illegal / Invalid SVGA3D command: %d\n",
828                   cmd_id + SVGA_3D_CMD_BASE);
829         return -EINVAL;
830 }
831
832 static int vmw_cmd_check_all(struct vmw_private *dev_priv,
833                              struct vmw_sw_context *sw_context,
834                              void *buf,
835                              uint32_t size)
836 {
837         int32_t cur_size = size;
838         int ret;
839
840         while (cur_size > 0) {
841                 size = cur_size;
842                 ret = vmw_cmd_check(dev_priv, sw_context, buf, &size);
843                 if (unlikely(ret != 0))
844                         return ret;
845                 buf = (void *)((unsigned long) buf + size);
846                 cur_size -= size;
847         }
848
849         if (unlikely(cur_size != 0)) {
850                 DRM_ERROR("Command verifier out of sync.\n");
851                 return -EINVAL;
852         }
853
854         return 0;
855 }
856
857 static void vmw_free_relocations(struct vmw_sw_context *sw_context)
858 {
859         sw_context->cur_reloc = 0;
860 }
861
862 static void vmw_apply_relocations(struct vmw_sw_context *sw_context)
863 {
864         uint32_t i;
865         struct vmw_relocation *reloc;
866         struct ttm_validate_buffer *validate;
867         struct ttm_buffer_object *bo;
868
869         for (i = 0; i < sw_context->cur_reloc; ++i) {
870                 reloc = &sw_context->relocs[i];
871                 validate = &sw_context->val_bufs[reloc->index];
872                 bo = validate->bo;
873                 if (bo->mem.mem_type == TTM_PL_VRAM) {
874                         reloc->location->offset += bo->offset;
875                         reloc->location->gmrId = SVGA_GMR_FRAMEBUFFER;
876                 } else
877                         reloc->location->gmrId = bo->mem.start;
878         }
879         vmw_free_relocations(sw_context);
880 }
881
882 static void vmw_clear_validations(struct vmw_sw_context *sw_context)
883 {
884         struct ttm_validate_buffer *entry, *next;
885         struct vmw_resource *res, *res_next;
886
887         /*
888          * Drop references to DMA buffers held during command submission.
889          */
890         list_for_each_entry_safe(entry, next, &sw_context->validate_nodes,
891                                  head) {
892                 list_del(&entry->head);
893                 vmw_dmabuf_validate_clear(entry->bo);
894                 ttm_bo_unref(&entry->bo);
895                 sw_context->cur_val_buf--;
896         }
897         BUG_ON(sw_context->cur_val_buf != 0);
898
899         /*
900          * Drop references to resources held during command submission.
901          */
902         vmw_resource_unreserve(&sw_context->resource_list);
903         list_for_each_entry_safe(res, res_next, &sw_context->resource_list,
904                                  validate_head) {
905                 list_del_init(&res->validate_head);
906                 vmw_resource_unreference(&res);
907         }
908 }
909
910 static int vmw_validate_single_buffer(struct vmw_private *dev_priv,
911                                       struct ttm_buffer_object *bo)
912 {
913         int ret;
914
915
916         /*
917          * Don't validate pinned buffers.
918          */
919
920         if (bo == dev_priv->pinned_bo ||
921             (bo == dev_priv->dummy_query_bo &&
922              dev_priv->dummy_query_bo_pinned))
923                 return 0;
924
925         /**
926          * Put BO in VRAM if there is space, otherwise as a GMR.
927          * If there is no space in VRAM and GMR ids are all used up,
928          * start evicting GMRs to make room. If the DMA buffer can't be
929          * used as a GMR, this will return -ENOMEM.
930          */
931
932         ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, true, false, false);
933         if (likely(ret == 0 || ret == -ERESTARTSYS))
934                 return ret;
935
936         /**
937          * If that failed, try VRAM again, this time evicting
938          * previous contents.
939          */
940
941         DRM_INFO("Falling through to VRAM.\n");
942         ret = ttm_bo_validate(bo, &vmw_vram_placement, true, false, false);
943         return ret;
944 }
945
946
947 static int vmw_validate_buffers(struct vmw_private *dev_priv,
948                                 struct vmw_sw_context *sw_context)
949 {
950         struct ttm_validate_buffer *entry;
951         int ret;
952
953         list_for_each_entry(entry, &sw_context->validate_nodes, head) {
954                 ret = vmw_validate_single_buffer(dev_priv, entry->bo);
955                 if (unlikely(ret != 0))
956                         return ret;
957         }
958         return 0;
959 }
960
961 static int vmw_resize_cmd_bounce(struct vmw_sw_context *sw_context,
962                                  uint32_t size)
963 {
964         if (likely(sw_context->cmd_bounce_size >= size))
965                 return 0;
966
967         if (sw_context->cmd_bounce_size == 0)
968                 sw_context->cmd_bounce_size = VMWGFX_CMD_BOUNCE_INIT_SIZE;
969
970         while (sw_context->cmd_bounce_size < size) {
971                 sw_context->cmd_bounce_size =
972                         PAGE_ALIGN(sw_context->cmd_bounce_size +
973                                    (sw_context->cmd_bounce_size >> 1));
974         }
975
976         if (sw_context->cmd_bounce != NULL)
977                 vfree(sw_context->cmd_bounce);
978
979         sw_context->cmd_bounce = vmalloc(sw_context->cmd_bounce_size);
980
981         if (sw_context->cmd_bounce == NULL) {
982                 DRM_ERROR("Failed to allocate command bounce buffer.\n");
983                 sw_context->cmd_bounce_size = 0;
984                 return -ENOMEM;
985         }
986
987         return 0;
988 }
989
990 /**
991  * vmw_execbuf_fence_commands - create and submit a command stream fence
992  *
993  * Creates a fence object and submits a command stream marker.
994  * If this fails for some reason, We sync the fifo and return NULL.
995  * It is then safe to fence buffers with a NULL pointer.
996  *
997  * If @p_handle is not NULL @file_priv must also not be NULL. Creates
998  * a userspace handle if @p_handle is not NULL, otherwise not.
999  */
1000
1001 int vmw_execbuf_fence_commands(struct drm_file *file_priv,
1002                                struct vmw_private *dev_priv,
1003                                struct vmw_fence_obj **p_fence,
1004                                uint32_t *p_handle)
1005 {
1006         uint32_t sequence;
1007         int ret;
1008         bool synced = false;
1009
1010         /* p_handle implies file_priv. */
1011         BUG_ON(p_handle != NULL && file_priv == NULL);
1012
1013         ret = vmw_fifo_send_fence(dev_priv, &sequence);
1014         if (unlikely(ret != 0)) {
1015                 DRM_ERROR("Fence submission error. Syncing.\n");
1016                 synced = true;
1017         }
1018
1019         if (p_handle != NULL)
1020                 ret = vmw_user_fence_create(file_priv, dev_priv->fman,
1021                                             sequence,
1022                                             DRM_VMW_FENCE_FLAG_EXEC,
1023                                             p_fence, p_handle);
1024         else
1025                 ret = vmw_fence_create(dev_priv->fman, sequence,
1026                                        DRM_VMW_FENCE_FLAG_EXEC,
1027                                        p_fence);
1028
1029         if (unlikely(ret != 0 && !synced)) {
1030                 (void) vmw_fallback_wait(dev_priv, false, false,
1031                                          sequence, false,
1032                                          VMW_FENCE_WAIT_TIMEOUT);
1033                 *p_fence = NULL;
1034         }
1035
1036         return 0;
1037 }
1038
1039 /**
1040  * vmw_execbuf_copy_fence_user - copy fence object information to
1041  * user-space.
1042  *
1043  * @dev_priv: Pointer to a vmw_private struct.
1044  * @vmw_fp: Pointer to the struct vmw_fpriv representing the calling file.
1045  * @ret: Return value from fence object creation.
1046  * @user_fence_rep: User space address of a struct drm_vmw_fence_rep to
1047  * which the information should be copied.
1048  * @fence: Pointer to the fenc object.
1049  * @fence_handle: User-space fence handle.
1050  *
1051  * This function copies fence information to user-space. If copying fails,
1052  * The user-space struct drm_vmw_fence_rep::error member is hopefully
1053  * left untouched, and if it's preloaded with an -EFAULT by user-space,
1054  * the error will hopefully be detected.
1055  * Also if copying fails, user-space will be unable to signal the fence
1056  * object so we wait for it immediately, and then unreference the
1057  * user-space reference.
1058  */
1059 void
1060 vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
1061                             struct vmw_fpriv *vmw_fp,
1062                             int ret,
1063                             struct drm_vmw_fence_rep __user *user_fence_rep,
1064                             struct vmw_fence_obj *fence,
1065                             uint32_t fence_handle)
1066 {
1067         struct drm_vmw_fence_rep fence_rep;
1068
1069         if (user_fence_rep == NULL)
1070                 return;
1071
1072         memset(&fence_rep, 0, sizeof(fence_rep));
1073
1074         fence_rep.error = ret;
1075         if (ret == 0) {
1076                 BUG_ON(fence == NULL);
1077
1078                 fence_rep.handle = fence_handle;
1079                 fence_rep.seqno = fence->seqno;
1080                 vmw_update_seqno(dev_priv, &dev_priv->fifo);
1081                 fence_rep.passed_seqno = dev_priv->last_read_seqno;
1082         }
1083
1084         /*
1085          * copy_to_user errors will be detected by user space not
1086          * seeing fence_rep::error filled in. Typically
1087          * user-space would have pre-set that member to -EFAULT.
1088          */
1089         ret = copy_to_user(user_fence_rep, &fence_rep,
1090                            sizeof(fence_rep));
1091
1092         /*
1093          * User-space lost the fence object. We need to sync
1094          * and unreference the handle.
1095          */
1096         if (unlikely(ret != 0) && (fence_rep.error == 0)) {
1097                 ttm_ref_object_base_unref(vmw_fp->tfile,
1098                                           fence_handle, TTM_REF_USAGE);
1099                 DRM_ERROR("Fence copy error. Syncing.\n");
1100                 (void) vmw_fence_obj_wait(fence, fence->signal_mask,
1101                                           false, false,
1102                                           VMW_FENCE_WAIT_TIMEOUT);
1103         }
1104 }
1105
1106 int vmw_execbuf_process(struct drm_file *file_priv,
1107                         struct vmw_private *dev_priv,
1108                         void __user *user_commands,
1109                         void *kernel_commands,
1110                         uint32_t command_size,
1111                         uint64_t throttle_us,
1112                         struct drm_vmw_fence_rep __user *user_fence_rep)
1113 {
1114         struct vmw_sw_context *sw_context = &dev_priv->ctx;
1115         struct vmw_fence_obj *fence;
1116         uint32_t handle;
1117         void *cmd;
1118         int ret;
1119
1120         ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
1121         if (unlikely(ret != 0))
1122                 return -ERESTARTSYS;
1123
1124         if (kernel_commands == NULL) {
1125                 sw_context->kernel = false;
1126
1127                 ret = vmw_resize_cmd_bounce(sw_context, command_size);
1128                 if (unlikely(ret != 0))
1129                         goto out_unlock;
1130
1131
1132                 ret = copy_from_user(sw_context->cmd_bounce,
1133                                      user_commands, command_size);
1134
1135                 if (unlikely(ret != 0)) {
1136                         ret = -EFAULT;
1137                         DRM_ERROR("Failed copying commands.\n");
1138                         goto out_unlock;
1139                 }
1140                 kernel_commands = sw_context->cmd_bounce;
1141         } else
1142                 sw_context->kernel = true;
1143
1144         sw_context->tfile = vmw_fpriv(file_priv)->tfile;
1145         sw_context->cid_valid = false;
1146         sw_context->sid_valid = false;
1147         sw_context->cur_reloc = 0;
1148         sw_context->cur_val_buf = 0;
1149         sw_context->fence_flags = 0;
1150         INIT_LIST_HEAD(&sw_context->query_list);
1151         INIT_LIST_HEAD(&sw_context->resource_list);
1152         sw_context->cur_query_bo = dev_priv->pinned_bo;
1153         sw_context->cur_query_cid = dev_priv->query_cid;
1154         sw_context->query_cid_valid = (dev_priv->pinned_bo != NULL);
1155
1156         INIT_LIST_HEAD(&sw_context->validate_nodes);
1157
1158         ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands,
1159                                 command_size);
1160         if (unlikely(ret != 0))
1161                 goto out_err;
1162
1163         ret = ttm_eu_reserve_buffers(&sw_context->validate_nodes);
1164         if (unlikely(ret != 0))
1165                 goto out_err;
1166
1167         ret = vmw_validate_buffers(dev_priv, sw_context);
1168         if (unlikely(ret != 0))
1169                 goto out_err;
1170
1171         vmw_apply_relocations(sw_context);
1172
1173         if (throttle_us) {
1174                 ret = vmw_wait_lag(dev_priv, &dev_priv->fifo.marker_queue,
1175                                    throttle_us);
1176
1177                 if (unlikely(ret != 0))
1178                         goto out_throttle;
1179         }
1180
1181         cmd = vmw_fifo_reserve(dev_priv, command_size);
1182         if (unlikely(cmd == NULL)) {
1183                 DRM_ERROR("Failed reserving fifo space for commands.\n");
1184                 ret = -ENOMEM;
1185                 goto out_throttle;
1186         }
1187
1188         memcpy(cmd, kernel_commands, command_size);
1189         vmw_fifo_commit(dev_priv, command_size);
1190
1191         vmw_query_bo_switch_commit(dev_priv, sw_context);
1192         ret = vmw_execbuf_fence_commands(file_priv, dev_priv,
1193                                          &fence,
1194                                          (user_fence_rep) ? &handle : NULL);
1195         /*
1196          * This error is harmless, because if fence submission fails,
1197          * vmw_fifo_send_fence will sync. The error will be propagated to
1198          * user-space in @fence_rep
1199          */
1200
1201         if (ret != 0)
1202                 DRM_ERROR("Fence submission error. Syncing.\n");
1203
1204         ttm_eu_fence_buffer_objects(&sw_context->validate_nodes,
1205                                     (void *) fence);
1206
1207         vmw_clear_validations(sw_context);
1208         vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
1209                                     user_fence_rep, fence, handle);
1210
1211         if (likely(fence != NULL))
1212                 vmw_fence_obj_unreference(&fence);
1213
1214         mutex_unlock(&dev_priv->cmdbuf_mutex);
1215         return 0;
1216
1217 out_err:
1218         vmw_free_relocations(sw_context);
1219 out_throttle:
1220         vmw_query_switch_backoff(sw_context);
1221         ttm_eu_backoff_reservation(&sw_context->validate_nodes);
1222         vmw_clear_validations(sw_context);
1223 out_unlock:
1224         mutex_unlock(&dev_priv->cmdbuf_mutex);
1225         return ret;
1226 }
1227
1228 /**
1229  * vmw_execbuf_unpin_panic - Idle the fifo and unpin the query buffer.
1230  *
1231  * @dev_priv: The device private structure.
1232  *
1233  * This function is called to idle the fifo and unpin the query buffer
1234  * if the normal way to do this hits an error, which should typically be
1235  * extremely rare.
1236  */
1237 static void vmw_execbuf_unpin_panic(struct vmw_private *dev_priv)
1238 {
1239         DRM_ERROR("Can't unpin query buffer. Trying to recover.\n");
1240
1241         (void) vmw_fallback_wait(dev_priv, false, true, 0, false, 10*HZ);
1242         vmw_bo_pin(dev_priv->pinned_bo, false);
1243         vmw_bo_pin(dev_priv->dummy_query_bo, false);
1244         dev_priv->dummy_query_bo_pinned = false;
1245 }
1246
1247
1248 /**
1249  * vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned
1250  * query bo.
1251  *
1252  * @dev_priv: The device private structure.
1253  * @only_on_cid_match: Only flush and unpin if the current active query cid
1254  * matches @cid.
1255  * @cid: Optional context id to match.
1256  *
1257  * This function should be used to unpin the pinned query bo, or
1258  * as a query barrier when we need to make sure that all queries have
1259  * finished before the next fifo command. (For example on hardware
1260  * context destructions where the hardware may otherwise leak unfinished
1261  * queries).
1262  *
1263  * This function does not return any failure codes, but make attempts
1264  * to do safe unpinning in case of errors.
1265  *
1266  * The function will synchronize on the previous query barrier, and will
1267  * thus not finish until that barrier has executed.
1268  */
1269 void vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv,
1270                                    bool only_on_cid_match, uint32_t cid)
1271 {
1272         int ret = 0;
1273         struct list_head validate_list;
1274         struct ttm_validate_buffer pinned_val, query_val;
1275         struct vmw_fence_obj *fence;
1276
1277         mutex_lock(&dev_priv->cmdbuf_mutex);
1278
1279         if (dev_priv->pinned_bo == NULL)
1280                 goto out_unlock;
1281
1282         if (only_on_cid_match && cid != dev_priv->query_cid)
1283                 goto out_unlock;
1284
1285         INIT_LIST_HEAD(&validate_list);
1286
1287         pinned_val.new_sync_obj_arg = (void *)(unsigned long)
1288                 DRM_VMW_FENCE_FLAG_EXEC;
1289         pinned_val.bo = ttm_bo_reference(dev_priv->pinned_bo);
1290         list_add_tail(&pinned_val.head, &validate_list);
1291
1292         query_val.new_sync_obj_arg = pinned_val.new_sync_obj_arg;
1293         query_val.bo = ttm_bo_reference(dev_priv->dummy_query_bo);
1294         list_add_tail(&query_val.head, &validate_list);
1295
1296         do {
1297                 ret = ttm_eu_reserve_buffers(&validate_list);
1298         } while (ret == -ERESTARTSYS);
1299
1300         if (unlikely(ret != 0)) {
1301                 vmw_execbuf_unpin_panic(dev_priv);
1302                 goto out_no_reserve;
1303         }
1304
1305         ret = vmw_fifo_emit_dummy_query(dev_priv, dev_priv->query_cid);
1306         if (unlikely(ret != 0)) {
1307                 vmw_execbuf_unpin_panic(dev_priv);
1308                 goto out_no_emit;
1309         }
1310
1311         vmw_bo_pin(dev_priv->pinned_bo, false);
1312         vmw_bo_pin(dev_priv->dummy_query_bo, false);
1313         dev_priv->dummy_query_bo_pinned = false;
1314
1315         (void) vmw_execbuf_fence_commands(NULL, dev_priv, &fence, NULL);
1316         ttm_eu_fence_buffer_objects(&validate_list, (void *) fence);
1317
1318         ttm_bo_unref(&query_val.bo);
1319         ttm_bo_unref(&pinned_val.bo);
1320         ttm_bo_unref(&dev_priv->pinned_bo);
1321
1322 out_unlock:
1323         mutex_unlock(&dev_priv->cmdbuf_mutex);
1324         return;
1325
1326 out_no_emit:
1327         ttm_eu_backoff_reservation(&validate_list);
1328 out_no_reserve:
1329         ttm_bo_unref(&query_val.bo);
1330         ttm_bo_unref(&pinned_val.bo);
1331         ttm_bo_unref(&dev_priv->pinned_bo);
1332         mutex_unlock(&dev_priv->cmdbuf_mutex);
1333 }
1334
1335
1336 int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
1337                       struct drm_file *file_priv)
1338 {
1339         struct vmw_private *dev_priv = vmw_priv(dev);
1340         struct drm_vmw_execbuf_arg *arg = (struct drm_vmw_execbuf_arg *)data;
1341         struct vmw_master *vmaster = vmw_master(file_priv->master);
1342         int ret;
1343
1344         /*
1345          * This will allow us to extend the ioctl argument while
1346          * maintaining backwards compatibility:
1347          * We take different code paths depending on the value of
1348          * arg->version.
1349          */
1350
1351         if (unlikely(arg->version != DRM_VMW_EXECBUF_VERSION)) {
1352                 DRM_ERROR("Incorrect execbuf version.\n");
1353                 DRM_ERROR("You're running outdated experimental "
1354                           "vmwgfx user-space drivers.");
1355                 return -EINVAL;
1356         }
1357
1358         ret = ttm_read_lock(&vmaster->lock, true);
1359         if (unlikely(ret != 0))
1360                 return ret;
1361
1362         ret = vmw_execbuf_process(file_priv, dev_priv,
1363                                   (void __user *)(unsigned long)arg->commands,
1364                                   NULL, arg->command_size, arg->throttle_us,
1365                                   (void __user *)(unsigned long)arg->fence_rep);
1366
1367         if (unlikely(ret != 0))
1368                 goto out_unlock;
1369
1370         vmw_kms_cursor_post_execbuf(dev_priv);
1371
1372 out_unlock:
1373         ttm_read_unlock(&vmaster->lock);
1374         return ret;
1375 }