Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 OR MIT
0002 /**************************************************************************
0003  *
0004  * Copyright 2009 - 2015 VMware, Inc., Palo Alto, CA., USA
0005  *
0006  * Permission is hereby granted, free of charge, to any person obtaining a
0007  * copy of this software and associated documentation files (the
0008  * "Software"), to deal in the Software without restriction, including
0009  * without limitation the rights to use, copy, modify, merge, publish,
0010  * distribute, sub license, and/or sell copies of the Software, and to
0011  * permit persons to whom the Software is furnished to do so, subject to
0012  * the following conditions:
0013  *
0014  * The above copyright notice and this permission notice (including the
0015  * next paragraph) shall be included in all copies or substantial portions
0016  * of the Software.
0017  *
0018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0019  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0020  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
0021  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
0022  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
0023  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
0024  * USE OR OTHER DEALINGS IN THE SOFTWARE.
0025  *
0026  **************************************************************************/
0027 #include <linux/sync_file.h>
0028 
0029 #include "vmwgfx_drv.h"
0030 #include "vmwgfx_reg.h"
0031 #include <drm/ttm/ttm_bo_api.h>
0032 #include <drm/ttm/ttm_placement.h>
0033 #include "vmwgfx_so.h"
0034 #include "vmwgfx_binding.h"
0035 #include "vmwgfx_mksstat.h"
0036 
0037 #define VMW_RES_HT_ORDER 12
0038 
0039 /*
0040  * Helper macro to get dx_ctx_node if available otherwise print an error
0041  * message. This is for use in command verifier function where if dx_ctx_node
0042  * is not set then command is invalid.
0043  */
0044 #define VMW_GET_CTX_NODE(__sw_context)                                        \
0045 ({                                                                            \
0046     __sw_context->dx_ctx_node ? __sw_context->dx_ctx_node : ({            \
0047         VMW_DEBUG_USER("SM context is not set at %s\n", __func__);    \
0048         __sw_context->dx_ctx_node;                                    \
0049     });                                                                   \
0050 })
0051 
0052 #define VMW_DECLARE_CMD_VAR(__var, __type)                                    \
0053     struct {                                                              \
0054         SVGA3dCmdHeader header;                                       \
0055         __type body;                                                  \
0056     } __var
0057 
0058 /**
0059  * struct vmw_relocation - Buffer object relocation
0060  *
0061  * @head: List head for the command submission context's relocation list
0062  * @vbo: Non ref-counted pointer to buffer object
0063  * @mob_loc: Pointer to location for mob id to be modified
0064  * @location: Pointer to location for guest pointer to be modified
0065  */
0066 struct vmw_relocation {
0067     struct list_head head;
0068     struct vmw_buffer_object *vbo;
0069     union {
0070         SVGAMobId *mob_loc;
0071         SVGAGuestPtr *location;
0072     };
0073 };
0074 
0075 /**
0076  * enum vmw_resource_relocation_type - Relocation type for resources
0077  *
0078  * @vmw_res_rel_normal: Traditional relocation. The resource id in the
0079  * command stream is replaced with the actual id after validation.
0080  * @vmw_res_rel_nop: NOP relocation. The command is unconditionally replaced
0081  * with a NOP.
0082  * @vmw_res_rel_cond_nop: Conditional NOP relocation. If the resource id after
0083  * validation is -1, the command is replaced with a NOP. Otherwise no action.
0084  * @vmw_res_rel_max: Last value in the enum - used for error checking
0085 */
0086 enum vmw_resource_relocation_type {
0087     vmw_res_rel_normal,
0088     vmw_res_rel_nop,
0089     vmw_res_rel_cond_nop,
0090     vmw_res_rel_max
0091 };
0092 
0093 /**
0094  * struct vmw_resource_relocation - Relocation info for resources
0095  *
0096  * @head: List head for the software context's relocation list.
0097  * @res: Non-ref-counted pointer to the resource.
0098  * @offset: Offset of single byte entries into the command buffer where the id
0099  * that needs fixup is located.
0100  * @rel_type: Type of relocation.
0101  */
0102 struct vmw_resource_relocation {
0103     struct list_head head;
0104     const struct vmw_resource *res;
0105     u32 offset:29;
0106     enum vmw_resource_relocation_type rel_type:3;
0107 };
0108 
0109 /**
0110  * struct vmw_ctx_validation_info - Extra validation metadata for contexts
0111  *
0112  * @head: List head of context list
0113  * @ctx: The context resource
0114  * @cur: The context's persistent binding state
0115  * @staged: The binding state changes of this command buffer
0116  */
0117 struct vmw_ctx_validation_info {
0118     struct list_head head;
0119     struct vmw_resource *ctx;
0120     struct vmw_ctx_binding_state *cur;
0121     struct vmw_ctx_binding_state *staged;
0122 };
0123 
0124 /**
0125  * struct vmw_cmd_entry - Describe a command for the verifier
0126  *
0127  * @func: Call-back to handle the command.
0128  * @user_allow: Whether allowed from the execbuf ioctl.
0129  * @gb_disable: Whether disabled if guest-backed objects are available.
0130  * @gb_enable: Whether enabled iff guest-backed objects are available.
0131  * @cmd_name: Name of the command.
0132  */
0133 struct vmw_cmd_entry {
0134     int (*func) (struct vmw_private *, struct vmw_sw_context *,
0135              SVGA3dCmdHeader *);
0136     bool user_allow;
0137     bool gb_disable;
0138     bool gb_enable;
0139     const char *cmd_name;
0140 };
0141 
0142 #define VMW_CMD_DEF(_cmd, _func, _user_allow, _gb_disable, _gb_enable)  \
0143     [(_cmd) - SVGA_3D_CMD_BASE] = {(_func), (_user_allow),\
0144                        (_gb_disable), (_gb_enable), #_cmd}
0145 
0146 static int vmw_resource_context_res_add(struct vmw_private *dev_priv,
0147                     struct vmw_sw_context *sw_context,
0148                     struct vmw_resource *ctx);
0149 static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
0150                  struct vmw_sw_context *sw_context,
0151                  SVGAMobId *id,
0152                  struct vmw_buffer_object **vmw_bo_p);
0153 /**
0154  * vmw_ptr_diff - Compute the offset from a to b in bytes
0155  *
0156  * @a: A starting pointer.
0157  * @b: A pointer offset in the same address space.
0158  *
0159  * Returns: The offset in bytes between the two pointers.
0160  */
0161 static size_t vmw_ptr_diff(void *a, void *b)
0162 {
0163     return (unsigned long) b - (unsigned long) a;
0164 }
0165 
0166 /**
0167  * vmw_execbuf_bindings_commit - Commit modified binding state
0168  *
0169  * @sw_context: The command submission context
0170  * @backoff: Whether this is part of the error path and binding state changes
0171  * should be ignored
0172  */
0173 static void vmw_execbuf_bindings_commit(struct vmw_sw_context *sw_context,
0174                     bool backoff)
0175 {
0176     struct vmw_ctx_validation_info *entry;
0177 
0178     list_for_each_entry(entry, &sw_context->ctx_list, head) {
0179         if (!backoff)
0180             vmw_binding_state_commit(entry->cur, entry->staged);
0181 
0182         if (entry->staged != sw_context->staged_bindings)
0183             vmw_binding_state_free(entry->staged);
0184         else
0185             sw_context->staged_bindings_inuse = false;
0186     }
0187 
0188     /* List entries are freed with the validation context */
0189     INIT_LIST_HEAD(&sw_context->ctx_list);
0190 }
0191 
0192 /**
0193  * vmw_bind_dx_query_mob - Bind the DX query MOB if referenced
0194  *
0195  * @sw_context: The command submission context
0196  */
0197 static void vmw_bind_dx_query_mob(struct vmw_sw_context *sw_context)
0198 {
0199     if (sw_context->dx_query_mob)
0200         vmw_context_bind_dx_query(sw_context->dx_query_ctx,
0201                       sw_context->dx_query_mob);
0202 }
0203 
0204 /**
0205  * vmw_cmd_ctx_first_setup - Perform the setup needed when a context is added to
0206  * the validate list.
0207  *
0208  * @dev_priv: Pointer to the device private:
0209  * @sw_context: The command submission context
0210  * @res: Pointer to the resource
0211  * @node: The validation node holding the context resource metadata
0212  */
0213 static int vmw_cmd_ctx_first_setup(struct vmw_private *dev_priv,
0214                    struct vmw_sw_context *sw_context,
0215                    struct vmw_resource *res,
0216                    struct vmw_ctx_validation_info *node)
0217 {
0218     int ret;
0219 
0220     ret = vmw_resource_context_res_add(dev_priv, sw_context, res);
0221     if (unlikely(ret != 0))
0222         goto out_err;
0223 
0224     if (!sw_context->staged_bindings) {
0225         sw_context->staged_bindings = vmw_binding_state_alloc(dev_priv);
0226         if (IS_ERR(sw_context->staged_bindings)) {
0227             ret = PTR_ERR(sw_context->staged_bindings);
0228             sw_context->staged_bindings = NULL;
0229             goto out_err;
0230         }
0231     }
0232 
0233     if (sw_context->staged_bindings_inuse) {
0234         node->staged = vmw_binding_state_alloc(dev_priv);
0235         if (IS_ERR(node->staged)) {
0236             ret = PTR_ERR(node->staged);
0237             node->staged = NULL;
0238             goto out_err;
0239         }
0240     } else {
0241         node->staged = sw_context->staged_bindings;
0242         sw_context->staged_bindings_inuse = true;
0243     }
0244 
0245     node->ctx = res;
0246     node->cur = vmw_context_binding_state(res);
0247     list_add_tail(&node->head, &sw_context->ctx_list);
0248 
0249     return 0;
0250 
0251 out_err:
0252     return ret;
0253 }
0254 
0255 /**
0256  * vmw_execbuf_res_size - calculate extra size fore the resource validation node
0257  *
0258  * @dev_priv: Pointer to the device private struct.
0259  * @res_type: The resource type.
0260  *
0261  * Guest-backed contexts and DX contexts require extra size to store execbuf
0262  * private information in the validation node. Typically the binding manager
0263  * associated data structures.
0264  *
0265  * Returns: The extra size requirement based on resource type.
0266  */
0267 static unsigned int vmw_execbuf_res_size(struct vmw_private *dev_priv,
0268                      enum vmw_res_type res_type)
0269 {
0270     return (res_type == vmw_res_dx_context ||
0271         (res_type == vmw_res_context && dev_priv->has_mob)) ?
0272         sizeof(struct vmw_ctx_validation_info) : 0;
0273 }
0274 
0275 /**
0276  * vmw_execbuf_rcache_update - Update a resource-node cache entry
0277  *
0278  * @rcache: Pointer to the entry to update.
0279  * @res: Pointer to the resource.
0280  * @private: Pointer to the execbuf-private space in the resource validation
0281  * node.
0282  */
0283 static void vmw_execbuf_rcache_update(struct vmw_res_cache_entry *rcache,
0284                       struct vmw_resource *res,
0285                       void *private)
0286 {
0287     rcache->res = res;
0288     rcache->private = private;
0289     rcache->valid = 1;
0290     rcache->valid_handle = 0;
0291 }
0292 
0293 /**
0294  * vmw_execbuf_res_noref_val_add - Add a resource described by an unreferenced
0295  * rcu-protected pointer to the validation list.
0296  *
0297  * @sw_context: Pointer to the software context.
0298  * @res: Unreferenced rcu-protected pointer to the resource.
0299  * @dirty: Whether to change dirty status.
0300  *
0301  * Returns: 0 on success. Negative error code on failure. Typical error codes
0302  * are %-EINVAL on inconsistency and %-ESRCH if the resource was doomed.
0303  */
0304 static int vmw_execbuf_res_noref_val_add(struct vmw_sw_context *sw_context,
0305                      struct vmw_resource *res,
0306                      u32 dirty)
0307 {
0308     struct vmw_private *dev_priv = res->dev_priv;
0309     int ret;
0310     enum vmw_res_type res_type = vmw_res_type(res);
0311     struct vmw_res_cache_entry *rcache;
0312     struct vmw_ctx_validation_info *ctx_info;
0313     bool first_usage;
0314     unsigned int priv_size;
0315 
0316     rcache = &sw_context->res_cache[res_type];
0317     if (likely(rcache->valid && rcache->res == res)) {
0318         if (dirty)
0319             vmw_validation_res_set_dirty(sw_context->ctx,
0320                              rcache->private, dirty);
0321         vmw_user_resource_noref_release();
0322         return 0;
0323     }
0324 
0325     priv_size = vmw_execbuf_res_size(dev_priv, res_type);
0326     ret = vmw_validation_add_resource(sw_context->ctx, res, priv_size,
0327                       dirty, (void **)&ctx_info,
0328                       &first_usage);
0329     vmw_user_resource_noref_release();
0330     if (ret)
0331         return ret;
0332 
0333     if (priv_size && first_usage) {
0334         ret = vmw_cmd_ctx_first_setup(dev_priv, sw_context, res,
0335                           ctx_info);
0336         if (ret) {
0337             VMW_DEBUG_USER("Failed first usage context setup.\n");
0338             return ret;
0339         }
0340     }
0341 
0342     vmw_execbuf_rcache_update(rcache, res, ctx_info);
0343     return 0;
0344 }
0345 
0346 /**
0347  * vmw_execbuf_res_noctx_val_add - Add a non-context resource to the resource
0348  * validation list if it's not already on it
0349  *
0350  * @sw_context: Pointer to the software context.
0351  * @res: Pointer to the resource.
0352  * @dirty: Whether to change dirty status.
0353  *
0354  * Returns: Zero on success. Negative error code on failure.
0355  */
0356 static int vmw_execbuf_res_noctx_val_add(struct vmw_sw_context *sw_context,
0357                      struct vmw_resource *res,
0358                      u32 dirty)
0359 {
0360     struct vmw_res_cache_entry *rcache;
0361     enum vmw_res_type res_type = vmw_res_type(res);
0362     void *ptr;
0363     int ret;
0364 
0365     rcache = &sw_context->res_cache[res_type];
0366     if (likely(rcache->valid && rcache->res == res)) {
0367         if (dirty)
0368             vmw_validation_res_set_dirty(sw_context->ctx,
0369                              rcache->private, dirty);
0370         return 0;
0371     }
0372 
0373     ret = vmw_validation_add_resource(sw_context->ctx, res, 0, dirty,
0374                       &ptr, NULL);
0375     if (ret)
0376         return ret;
0377 
0378     vmw_execbuf_rcache_update(rcache, res, ptr);
0379 
0380     return 0;
0381 }
0382 
0383 /**
0384  * vmw_view_res_val_add - Add a view and the surface it's pointing to to the
0385  * validation list
0386  *
0387  * @sw_context: The software context holding the validation list.
0388  * @view: Pointer to the view resource.
0389  *
0390  * Returns 0 if success, negative error code otherwise.
0391  */
0392 static int vmw_view_res_val_add(struct vmw_sw_context *sw_context,
0393                 struct vmw_resource *view)
0394 {
0395     int ret;
0396 
0397     /*
0398      * First add the resource the view is pointing to, otherwise it may be
0399      * swapped out when the view is validated.
0400      */
0401     ret = vmw_execbuf_res_noctx_val_add(sw_context, vmw_view_srf(view),
0402                         vmw_view_dirtying(view));
0403     if (ret)
0404         return ret;
0405 
0406     return vmw_execbuf_res_noctx_val_add(sw_context, view,
0407                          VMW_RES_DIRTY_NONE);
0408 }
0409 
0410 /**
0411  * vmw_view_id_val_add - Look up a view and add it and the surface it's pointing
0412  * to to the validation list.
0413  *
0414  * @sw_context: The software context holding the validation list.
0415  * @view_type: The view type to look up.
0416  * @id: view id of the view.
0417  *
0418  * The view is represented by a view id and the DX context it's created on, or
0419  * scheduled for creation on. If there is no DX context set, the function will
0420  * return an -EINVAL error pointer.
0421  *
0422  * Returns: Unreferenced pointer to the resource on success, negative error
0423  * pointer on failure.
0424  */
0425 static struct vmw_resource *
0426 vmw_view_id_val_add(struct vmw_sw_context *sw_context,
0427             enum vmw_view_type view_type, u32 id)
0428 {
0429     struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
0430     struct vmw_resource *view;
0431     int ret;
0432 
0433     if (!ctx_node)
0434         return ERR_PTR(-EINVAL);
0435 
0436     view = vmw_view_lookup(sw_context->man, view_type, id);
0437     if (IS_ERR(view))
0438         return view;
0439 
0440     ret = vmw_view_res_val_add(sw_context, view);
0441     if (ret)
0442         return ERR_PTR(ret);
0443 
0444     return view;
0445 }
0446 
0447 /**
0448  * vmw_resource_context_res_add - Put resources previously bound to a context on
0449  * the validation list
0450  *
0451  * @dev_priv: Pointer to a device private structure
0452  * @sw_context: Pointer to a software context used for this command submission
0453  * @ctx: Pointer to the context resource
0454  *
0455  * This function puts all resources that were previously bound to @ctx on the
0456  * resource validation list. This is part of the context state reemission
0457  */
0458 static int vmw_resource_context_res_add(struct vmw_private *dev_priv,
0459                     struct vmw_sw_context *sw_context,
0460                     struct vmw_resource *ctx)
0461 {
0462     struct list_head *binding_list;
0463     struct vmw_ctx_bindinfo *entry;
0464     int ret = 0;
0465     struct vmw_resource *res;
0466     u32 i;
0467     u32 cotable_max = has_sm5_context(ctx->dev_priv) ?
0468         SVGA_COTABLE_MAX : SVGA_COTABLE_DX10_MAX;
0469 
0470     /* Add all cotables to the validation list. */
0471     if (has_sm4_context(dev_priv) &&
0472         vmw_res_type(ctx) == vmw_res_dx_context) {
0473         for (i = 0; i < cotable_max; ++i) {
0474             res = vmw_context_cotable(ctx, i);
0475             if (IS_ERR(res))
0476                 continue;
0477 
0478             ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
0479                                 VMW_RES_DIRTY_SET);
0480             if (unlikely(ret != 0))
0481                 return ret;
0482         }
0483     }
0484 
0485     /* Add all resources bound to the context to the validation list */
0486     mutex_lock(&dev_priv->binding_mutex);
0487     binding_list = vmw_context_binding_list(ctx);
0488 
0489     list_for_each_entry(entry, binding_list, ctx_list) {
0490         if (vmw_res_type(entry->res) == vmw_res_view)
0491             ret = vmw_view_res_val_add(sw_context, entry->res);
0492         else
0493             ret = vmw_execbuf_res_noctx_val_add
0494                 (sw_context, entry->res,
0495                  vmw_binding_dirtying(entry->bt));
0496         if (unlikely(ret != 0))
0497             break;
0498     }
0499 
0500     if (has_sm4_context(dev_priv) &&
0501         vmw_res_type(ctx) == vmw_res_dx_context) {
0502         struct vmw_buffer_object *dx_query_mob;
0503 
0504         dx_query_mob = vmw_context_get_dx_query_mob(ctx);
0505         if (dx_query_mob)
0506             ret = vmw_validation_add_bo(sw_context->ctx,
0507                             dx_query_mob, true, false);
0508     }
0509 
0510     mutex_unlock(&dev_priv->binding_mutex);
0511     return ret;
0512 }
0513 
0514 /**
0515  * vmw_resource_relocation_add - Add a relocation to the relocation list
0516  *
0517  * @sw_context: Pointer to the software context.
0518  * @res: The resource.
0519  * @offset: Offset into the command buffer currently being parsed where the id
0520  * that needs fixup is located. Granularity is one byte.
0521  * @rel_type: Relocation type.
0522  */
0523 static int vmw_resource_relocation_add(struct vmw_sw_context *sw_context,
0524                        const struct vmw_resource *res,
0525                        unsigned long offset,
0526                        enum vmw_resource_relocation_type
0527                        rel_type)
0528 {
0529     struct vmw_resource_relocation *rel;
0530 
0531     rel = vmw_validation_mem_alloc(sw_context->ctx, sizeof(*rel));
0532     if (unlikely(!rel)) {
0533         VMW_DEBUG_USER("Failed to allocate a resource relocation.\n");
0534         return -ENOMEM;
0535     }
0536 
0537     rel->res = res;
0538     rel->offset = offset;
0539     rel->rel_type = rel_type;
0540     list_add_tail(&rel->head, &sw_context->res_relocations);
0541 
0542     return 0;
0543 }
0544 
0545 /**
0546  * vmw_resource_relocations_free - Free all relocations on a list
0547  *
0548  * @list: Pointer to the head of the relocation list
0549  */
0550 static void vmw_resource_relocations_free(struct list_head *list)
0551 {
0552     /* Memory is validation context memory, so no need to free it */
0553     INIT_LIST_HEAD(list);
0554 }
0555 
0556 /**
0557  * vmw_resource_relocations_apply - Apply all relocations on a list
0558  *
0559  * @cb: Pointer to the start of the command buffer bein patch. This need not be
0560  * the same buffer as the one being parsed when the relocation list was built,
0561  * but the contents must be the same modulo the resource ids.
0562  * @list: Pointer to the head of the relocation list.
0563  */
0564 static void vmw_resource_relocations_apply(uint32_t *cb,
0565                        struct list_head *list)
0566 {
0567     struct vmw_resource_relocation *rel;
0568 
0569     /* Validate the struct vmw_resource_relocation member size */
0570     BUILD_BUG_ON(SVGA_CB_MAX_SIZE >= (1 << 29));
0571     BUILD_BUG_ON(vmw_res_rel_max >= (1 << 3));
0572 
0573     list_for_each_entry(rel, list, head) {
0574         u32 *addr = (u32 *)((unsigned long) cb + rel->offset);
0575         switch (rel->rel_type) {
0576         case vmw_res_rel_normal:
0577             *addr = rel->res->id;
0578             break;
0579         case vmw_res_rel_nop:
0580             *addr = SVGA_3D_CMD_NOP;
0581             break;
0582         default:
0583             if (rel->res->id == -1)
0584                 *addr = SVGA_3D_CMD_NOP;
0585             break;
0586         }
0587     }
0588 }
0589 
0590 static int vmw_cmd_invalid(struct vmw_private *dev_priv,
0591                struct vmw_sw_context *sw_context,
0592                SVGA3dCmdHeader *header)
0593 {
0594     return -EINVAL;
0595 }
0596 
0597 static int vmw_cmd_ok(struct vmw_private *dev_priv,
0598               struct vmw_sw_context *sw_context,
0599               SVGA3dCmdHeader *header)
0600 {
0601     return 0;
0602 }
0603 
0604 /**
0605  * vmw_resources_reserve - Reserve all resources on the sw_context's resource
0606  * list.
0607  *
0608  * @sw_context: Pointer to the software context.
0609  *
0610  * Note that since vmware's command submission currently is protected by the
0611  * cmdbuf mutex, no fancy deadlock avoidance is required for resources, since
0612  * only a single thread at once will attempt this.
0613  */
0614 static int vmw_resources_reserve(struct vmw_sw_context *sw_context)
0615 {
0616     int ret;
0617 
0618     ret = vmw_validation_res_reserve(sw_context->ctx, true);
0619     if (ret)
0620         return ret;
0621 
0622     if (sw_context->dx_query_mob) {
0623         struct vmw_buffer_object *expected_dx_query_mob;
0624 
0625         expected_dx_query_mob =
0626             vmw_context_get_dx_query_mob(sw_context->dx_query_ctx);
0627         if (expected_dx_query_mob &&
0628             expected_dx_query_mob != sw_context->dx_query_mob) {
0629             ret = -EINVAL;
0630         }
0631     }
0632 
0633     return ret;
0634 }
0635 
0636 /**
0637  * vmw_cmd_res_check - Check that a resource is present and if so, put it on the
0638  * resource validate list unless it's already there.
0639  *
0640  * @dev_priv: Pointer to a device private structure.
0641  * @sw_context: Pointer to the software context.
0642  * @res_type: Resource type.
0643  * @dirty: Whether to change dirty status.
0644  * @converter: User-space visisble type specific information.
0645  * @id_loc: Pointer to the location in the command buffer currently being parsed
0646  * from where the user-space resource id handle is located.
0647  * @p_res: Pointer to pointer to resource validalidation node. Populated on
0648  * exit.
0649  */
0650 static int
0651 vmw_cmd_res_check(struct vmw_private *dev_priv,
0652           struct vmw_sw_context *sw_context,
0653           enum vmw_res_type res_type,
0654           u32 dirty,
0655           const struct vmw_user_resource_conv *converter,
0656           uint32_t *id_loc,
0657           struct vmw_resource **p_res)
0658 {
0659     struct vmw_res_cache_entry *rcache = &sw_context->res_cache[res_type];
0660     struct vmw_resource *res;
0661     int ret;
0662 
0663     if (p_res)
0664         *p_res = NULL;
0665 
0666     if (*id_loc == SVGA3D_INVALID_ID) {
0667         if (res_type == vmw_res_context) {
0668             VMW_DEBUG_USER("Illegal context invalid id.\n");
0669             return -EINVAL;
0670         }
0671         return 0;
0672     }
0673 
0674     if (likely(rcache->valid_handle && *id_loc == rcache->handle)) {
0675         res = rcache->res;
0676         if (dirty)
0677             vmw_validation_res_set_dirty(sw_context->ctx,
0678                              rcache->private, dirty);
0679     } else {
0680         unsigned int size = vmw_execbuf_res_size(dev_priv, res_type);
0681 
0682         ret = vmw_validation_preload_res(sw_context->ctx, size);
0683         if (ret)
0684             return ret;
0685 
0686         res = vmw_user_resource_noref_lookup_handle
0687             (dev_priv, sw_context->fp->tfile, *id_loc, converter);
0688         if (IS_ERR(res)) {
0689             VMW_DEBUG_USER("Could not find/use resource 0x%08x.\n",
0690                        (unsigned int) *id_loc);
0691             return PTR_ERR(res);
0692         }
0693 
0694         ret = vmw_execbuf_res_noref_val_add(sw_context, res, dirty);
0695         if (unlikely(ret != 0))
0696             return ret;
0697 
0698         if (rcache->valid && rcache->res == res) {
0699             rcache->valid_handle = true;
0700             rcache->handle = *id_loc;
0701         }
0702     }
0703 
0704     ret = vmw_resource_relocation_add(sw_context, res,
0705                       vmw_ptr_diff(sw_context->buf_start,
0706                                id_loc),
0707                       vmw_res_rel_normal);
0708     if (p_res)
0709         *p_res = res;
0710 
0711     return 0;
0712 }
0713 
0714 /**
0715  * vmw_rebind_all_dx_query - Rebind DX query associated with the context
0716  *
0717  * @ctx_res: context the query belongs to
0718  *
0719  * This function assumes binding_mutex is held.
0720  */
0721 static int vmw_rebind_all_dx_query(struct vmw_resource *ctx_res)
0722 {
0723     struct vmw_private *dev_priv = ctx_res->dev_priv;
0724     struct vmw_buffer_object *dx_query_mob;
0725     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBindAllQuery);
0726 
0727     dx_query_mob = vmw_context_get_dx_query_mob(ctx_res);
0728 
0729     if (!dx_query_mob || dx_query_mob->dx_query_ctx)
0730         return 0;
0731 
0732     cmd = VMW_CMD_CTX_RESERVE(dev_priv, sizeof(*cmd), ctx_res->id);
0733     if (cmd == NULL)
0734         return -ENOMEM;
0735 
0736     cmd->header.id = SVGA_3D_CMD_DX_BIND_ALL_QUERY;
0737     cmd->header.size = sizeof(cmd->body);
0738     cmd->body.cid = ctx_res->id;
0739     cmd->body.mobid = dx_query_mob->base.resource->start;
0740     vmw_cmd_commit(dev_priv, sizeof(*cmd));
0741 
0742     vmw_context_bind_dx_query(ctx_res, dx_query_mob);
0743 
0744     return 0;
0745 }
0746 
0747 /**
0748  * vmw_rebind_contexts - Rebind all resources previously bound to referenced
0749  * contexts.
0750  *
0751  * @sw_context: Pointer to the software context.
0752  *
0753  * Rebind context binding points that have been scrubbed because of eviction.
0754  */
0755 static int vmw_rebind_contexts(struct vmw_sw_context *sw_context)
0756 {
0757     struct vmw_ctx_validation_info *val;
0758     int ret;
0759 
0760     list_for_each_entry(val, &sw_context->ctx_list, head) {
0761         ret = vmw_binding_rebind_all(val->cur);
0762         if (unlikely(ret != 0)) {
0763             if (ret != -ERESTARTSYS)
0764                 VMW_DEBUG_USER("Failed to rebind context.\n");
0765             return ret;
0766         }
0767 
0768         ret = vmw_rebind_all_dx_query(val->ctx);
0769         if (ret != 0) {
0770             VMW_DEBUG_USER("Failed to rebind queries.\n");
0771             return ret;
0772         }
0773     }
0774 
0775     return 0;
0776 }
0777 
0778 /**
0779  * vmw_view_bindings_add - Add an array of view bindings to a context binding
0780  * state tracker.
0781  *
0782  * @sw_context: The execbuf state used for this command.
0783  * @view_type: View type for the bindings.
0784  * @binding_type: Binding type for the bindings.
0785  * @shader_slot: The shader slot to user for the bindings.
0786  * @view_ids: Array of view ids to be bound.
0787  * @num_views: Number of view ids in @view_ids.
0788  * @first_slot: The binding slot to be used for the first view id in @view_ids.
0789  */
0790 static int vmw_view_bindings_add(struct vmw_sw_context *sw_context,
0791                  enum vmw_view_type view_type,
0792                  enum vmw_ctx_binding_type binding_type,
0793                  uint32 shader_slot,
0794                  uint32 view_ids[], u32 num_views,
0795                  u32 first_slot)
0796 {
0797     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
0798     u32 i;
0799 
0800     if (!ctx_node)
0801         return -EINVAL;
0802 
0803     for (i = 0; i < num_views; ++i) {
0804         struct vmw_ctx_bindinfo_view binding;
0805         struct vmw_resource *view = NULL;
0806 
0807         if (view_ids[i] != SVGA3D_INVALID_ID) {
0808             view = vmw_view_id_val_add(sw_context, view_type,
0809                            view_ids[i]);
0810             if (IS_ERR(view)) {
0811                 VMW_DEBUG_USER("View not found.\n");
0812                 return PTR_ERR(view);
0813             }
0814         }
0815         binding.bi.ctx = ctx_node->ctx;
0816         binding.bi.res = view;
0817         binding.bi.bt = binding_type;
0818         binding.shader_slot = shader_slot;
0819         binding.slot = first_slot + i;
0820         vmw_binding_add(ctx_node->staged, &binding.bi,
0821                 shader_slot, binding.slot);
0822     }
0823 
0824     return 0;
0825 }
0826 
0827 /**
0828  * vmw_cmd_cid_check - Check a command header for valid context information.
0829  *
0830  * @dev_priv: Pointer to a device private structure.
0831  * @sw_context: Pointer to the software context.
0832  * @header: A command header with an embedded user-space context handle.
0833  *
0834  * Convenience function: Call vmw_cmd_res_check with the user-space context
0835  * handle embedded in @header.
0836  */
0837 static int vmw_cmd_cid_check(struct vmw_private *dev_priv,
0838                  struct vmw_sw_context *sw_context,
0839                  SVGA3dCmdHeader *header)
0840 {
0841     VMW_DECLARE_CMD_VAR(*cmd, uint32_t) =
0842         container_of(header, typeof(*cmd), header);
0843 
0844     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
0845                  VMW_RES_DIRTY_SET, user_context_converter,
0846                  &cmd->body, NULL);
0847 }
0848 
0849 /**
0850  * vmw_execbuf_info_from_res - Get the private validation metadata for a
0851  * recently validated resource
0852  *
0853  * @sw_context: Pointer to the command submission context
0854  * @res: The resource
0855  *
0856  * The resource pointed to by @res needs to be present in the command submission
0857  * context's resource cache and hence the last resource of that type to be
0858  * processed by the validation code.
0859  *
0860  * Return: a pointer to the private metadata of the resource, or NULL if it
0861  * wasn't found
0862  */
0863 static struct vmw_ctx_validation_info *
0864 vmw_execbuf_info_from_res(struct vmw_sw_context *sw_context,
0865               struct vmw_resource *res)
0866 {
0867     struct vmw_res_cache_entry *rcache =
0868         &sw_context->res_cache[vmw_res_type(res)];
0869 
0870     if (rcache->valid && rcache->res == res)
0871         return rcache->private;
0872 
0873     WARN_ON_ONCE(true);
0874     return NULL;
0875 }
0876 
0877 static int vmw_cmd_set_render_target_check(struct vmw_private *dev_priv,
0878                        struct vmw_sw_context *sw_context,
0879                        SVGA3dCmdHeader *header)
0880 {
0881     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSetRenderTarget);
0882     struct vmw_resource *ctx;
0883     struct vmw_resource *res;
0884     int ret;
0885 
0886     cmd = container_of(header, typeof(*cmd), header);
0887 
0888     if (cmd->body.type >= SVGA3D_RT_MAX) {
0889         VMW_DEBUG_USER("Illegal render target type %u.\n",
0890                    (unsigned int) cmd->body.type);
0891         return -EINVAL;
0892     }
0893 
0894     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
0895                 VMW_RES_DIRTY_SET, user_context_converter,
0896                 &cmd->body.cid, &ctx);
0897     if (unlikely(ret != 0))
0898         return ret;
0899 
0900     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
0901                 VMW_RES_DIRTY_SET, user_surface_converter,
0902                 &cmd->body.target.sid, &res);
0903     if (unlikely(ret))
0904         return ret;
0905 
0906     if (dev_priv->has_mob) {
0907         struct vmw_ctx_bindinfo_view binding;
0908         struct vmw_ctx_validation_info *node;
0909 
0910         node = vmw_execbuf_info_from_res(sw_context, ctx);
0911         if (!node)
0912             return -EINVAL;
0913 
0914         binding.bi.ctx = ctx;
0915         binding.bi.res = res;
0916         binding.bi.bt = vmw_ctx_binding_rt;
0917         binding.slot = cmd->body.type;
0918         vmw_binding_add(node->staged, &binding.bi, 0, binding.slot);
0919     }
0920 
0921     return 0;
0922 }
0923 
0924 static int vmw_cmd_surface_copy_check(struct vmw_private *dev_priv,
0925                       struct vmw_sw_context *sw_context,
0926                       SVGA3dCmdHeader *header)
0927 {
0928     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSurfaceCopy);
0929     int ret;
0930 
0931     cmd = container_of(header, typeof(*cmd), header);
0932 
0933     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
0934                 VMW_RES_DIRTY_NONE, user_surface_converter,
0935                 &cmd->body.src.sid, NULL);
0936     if (ret)
0937         return ret;
0938 
0939     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
0940                  VMW_RES_DIRTY_SET, user_surface_converter,
0941                  &cmd->body.dest.sid, NULL);
0942 }
0943 
0944 static int vmw_cmd_buffer_copy_check(struct vmw_private *dev_priv,
0945                      struct vmw_sw_context *sw_context,
0946                      SVGA3dCmdHeader *header)
0947 {
0948     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBufferCopy);
0949     int ret;
0950 
0951     cmd = container_of(header, typeof(*cmd), header);
0952     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
0953                 VMW_RES_DIRTY_NONE, user_surface_converter,
0954                 &cmd->body.src, NULL);
0955     if (ret != 0)
0956         return ret;
0957 
0958     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
0959                  VMW_RES_DIRTY_SET, user_surface_converter,
0960                  &cmd->body.dest, NULL);
0961 }
0962 
0963 static int vmw_cmd_pred_copy_check(struct vmw_private *dev_priv,
0964                    struct vmw_sw_context *sw_context,
0965                    SVGA3dCmdHeader *header)
0966 {
0967     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXPredCopyRegion);
0968     int ret;
0969 
0970     cmd = container_of(header, typeof(*cmd), header);
0971     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
0972                 VMW_RES_DIRTY_NONE, user_surface_converter,
0973                 &cmd->body.srcSid, NULL);
0974     if (ret != 0)
0975         return ret;
0976 
0977     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
0978                  VMW_RES_DIRTY_SET, user_surface_converter,
0979                  &cmd->body.dstSid, NULL);
0980 }
0981 
0982 static int vmw_cmd_stretch_blt_check(struct vmw_private *dev_priv,
0983                      struct vmw_sw_context *sw_context,
0984                      SVGA3dCmdHeader *header)
0985 {
0986     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSurfaceStretchBlt);
0987     int ret;
0988 
0989     cmd = container_of(header, typeof(*cmd), header);
0990     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
0991                 VMW_RES_DIRTY_NONE, user_surface_converter,
0992                 &cmd->body.src.sid, NULL);
0993     if (unlikely(ret != 0))
0994         return ret;
0995 
0996     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
0997                  VMW_RES_DIRTY_SET, user_surface_converter,
0998                  &cmd->body.dest.sid, NULL);
0999 }
1000 
1001 static int vmw_cmd_blt_surf_screen_check(struct vmw_private *dev_priv,
1002                      struct vmw_sw_context *sw_context,
1003                      SVGA3dCmdHeader *header)
1004 {
1005     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBlitSurfaceToScreen) =
1006         container_of(header, typeof(*cmd), header);
1007 
1008     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1009                  VMW_RES_DIRTY_NONE, user_surface_converter,
1010                  &cmd->body.srcImage.sid, NULL);
1011 }
1012 
1013 static int vmw_cmd_present_check(struct vmw_private *dev_priv,
1014                  struct vmw_sw_context *sw_context,
1015                  SVGA3dCmdHeader *header)
1016 {
1017     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdPresent) =
1018         container_of(header, typeof(*cmd), header);
1019 
1020     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1021                  VMW_RES_DIRTY_NONE, user_surface_converter,
1022                  &cmd->body.sid, NULL);
1023 }
1024 
1025 /**
1026  * vmw_query_bo_switch_prepare - Prepare to switch pinned buffer for queries.
1027  *
1028  * @dev_priv: The device private structure.
1029  * @new_query_bo: The new buffer holding query results.
1030  * @sw_context: The software context used for this command submission.
1031  *
1032  * This function checks whether @new_query_bo is suitable for holding query
1033  * results, and if another buffer currently is pinned for query results. If so,
1034  * the function prepares the state of @sw_context for switching pinned buffers
1035  * after successful submission of the current command batch.
1036  */
1037 static int vmw_query_bo_switch_prepare(struct vmw_private *dev_priv,
1038                        struct vmw_buffer_object *new_query_bo,
1039                        struct vmw_sw_context *sw_context)
1040 {
1041     struct vmw_res_cache_entry *ctx_entry =
1042         &sw_context->res_cache[vmw_res_context];
1043     int ret;
1044 
1045     BUG_ON(!ctx_entry->valid);
1046     sw_context->last_query_ctx = ctx_entry->res;
1047 
1048     if (unlikely(new_query_bo != sw_context->cur_query_bo)) {
1049 
1050         if (unlikely(new_query_bo->base.resource->num_pages > 4)) {
1051             VMW_DEBUG_USER("Query buffer too large.\n");
1052             return -EINVAL;
1053         }
1054 
1055         if (unlikely(sw_context->cur_query_bo != NULL)) {
1056             sw_context->needs_post_query_barrier = true;
1057             ret = vmw_validation_add_bo(sw_context->ctx,
1058                             sw_context->cur_query_bo,
1059                             dev_priv->has_mob, false);
1060             if (unlikely(ret != 0))
1061                 return ret;
1062         }
1063         sw_context->cur_query_bo = new_query_bo;
1064 
1065         ret = vmw_validation_add_bo(sw_context->ctx,
1066                         dev_priv->dummy_query_bo,
1067                         dev_priv->has_mob, false);
1068         if (unlikely(ret != 0))
1069             return ret;
1070     }
1071 
1072     return 0;
1073 }
1074 
1075 /**
1076  * vmw_query_bo_switch_commit - Finalize switching pinned query buffer
1077  *
1078  * @dev_priv: The device private structure.
1079  * @sw_context: The software context used for this command submission batch.
1080  *
1081  * This function will check if we're switching query buffers, and will then,
1082  * issue a dummy occlusion query wait used as a query barrier. When the fence
1083  * object following that query wait has signaled, we are sure that all preceding
1084  * queries have finished, and the old query buffer can be unpinned. However,
1085  * since both the new query buffer and the old one are fenced with that fence,
1086  * we can do an asynchronus unpin now, and be sure that the old query buffer
1087  * won't be moved until the fence has signaled.
1088  *
1089  * As mentioned above, both the new - and old query buffers need to be fenced
1090  * using a sequence emitted *after* calling this function.
1091  */
1092 static void vmw_query_bo_switch_commit(struct vmw_private *dev_priv,
1093                      struct vmw_sw_context *sw_context)
1094 {
1095     /*
1096      * The validate list should still hold references to all
1097      * contexts here.
1098      */
1099     if (sw_context->needs_post_query_barrier) {
1100         struct vmw_res_cache_entry *ctx_entry =
1101             &sw_context->res_cache[vmw_res_context];
1102         struct vmw_resource *ctx;
1103         int ret;
1104 
1105         BUG_ON(!ctx_entry->valid);
1106         ctx = ctx_entry->res;
1107 
1108         ret = vmw_cmd_emit_dummy_query(dev_priv, ctx->id);
1109 
1110         if (unlikely(ret != 0))
1111             VMW_DEBUG_USER("Out of fifo space for dummy query.\n");
1112     }
1113 
1114     if (dev_priv->pinned_bo != sw_context->cur_query_bo) {
1115         if (dev_priv->pinned_bo) {
1116             vmw_bo_pin_reserved(dev_priv->pinned_bo, false);
1117             vmw_bo_unreference(&dev_priv->pinned_bo);
1118         }
1119 
1120         if (!sw_context->needs_post_query_barrier) {
1121             vmw_bo_pin_reserved(sw_context->cur_query_bo, true);
1122 
1123             /*
1124              * We pin also the dummy_query_bo buffer so that we
1125              * don't need to validate it when emitting dummy queries
1126              * in context destroy paths.
1127              */
1128             if (!dev_priv->dummy_query_bo_pinned) {
1129                 vmw_bo_pin_reserved(dev_priv->dummy_query_bo,
1130                             true);
1131                 dev_priv->dummy_query_bo_pinned = true;
1132             }
1133 
1134             BUG_ON(sw_context->last_query_ctx == NULL);
1135             dev_priv->query_cid = sw_context->last_query_ctx->id;
1136             dev_priv->query_cid_valid = true;
1137             dev_priv->pinned_bo =
1138                 vmw_bo_reference(sw_context->cur_query_bo);
1139         }
1140     }
1141 }
1142 
1143 /**
1144  * vmw_translate_mob_ptr - Prepare to translate a user-space buffer handle
1145  * to a MOB id.
1146  *
1147  * @dev_priv: Pointer to a device private structure.
1148  * @sw_context: The software context used for this command batch validation.
1149  * @id: Pointer to the user-space handle to be translated.
1150  * @vmw_bo_p: Points to a location that, on successful return will carry a
1151  * non-reference-counted pointer to the buffer object identified by the
1152  * user-space handle in @id.
1153  *
1154  * This function saves information needed to translate a user-space buffer
1155  * handle to a MOB id. The translation does not take place immediately, but
1156  * during a call to vmw_apply_relocations().
1157  *
1158  * This function builds a relocation list and a list of buffers to validate. The
1159  * former needs to be freed using either vmw_apply_relocations() or
1160  * vmw_free_relocations(). The latter needs to be freed using
1161  * vmw_clear_validations.
1162  */
1163 static int vmw_translate_mob_ptr(struct vmw_private *dev_priv,
1164                  struct vmw_sw_context *sw_context,
1165                  SVGAMobId *id,
1166                  struct vmw_buffer_object **vmw_bo_p)
1167 {
1168     struct vmw_buffer_object *vmw_bo;
1169     uint32_t handle = *id;
1170     struct vmw_relocation *reloc;
1171     int ret;
1172 
1173     vmw_validation_preload_bo(sw_context->ctx);
1174     vmw_bo = vmw_user_bo_noref_lookup(sw_context->filp, handle);
1175     if (IS_ERR_OR_NULL(vmw_bo)) {
1176         VMW_DEBUG_USER("Could not find or use MOB buffer.\n");
1177         return PTR_ERR(vmw_bo);
1178     }
1179     ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, true, false);
1180     ttm_bo_put(&vmw_bo->base);
1181     if (unlikely(ret != 0))
1182         return ret;
1183 
1184     reloc = vmw_validation_mem_alloc(sw_context->ctx, sizeof(*reloc));
1185     if (!reloc)
1186         return -ENOMEM;
1187 
1188     reloc->mob_loc = id;
1189     reloc->vbo = vmw_bo;
1190 
1191     *vmw_bo_p = vmw_bo;
1192     list_add_tail(&reloc->head, &sw_context->bo_relocations);
1193 
1194     return 0;
1195 }
1196 
1197 /**
1198  * vmw_translate_guest_ptr - Prepare to translate a user-space buffer handle
1199  * to a valid SVGAGuestPtr
1200  *
1201  * @dev_priv: Pointer to a device private structure.
1202  * @sw_context: The software context used for this command batch validation.
1203  * @ptr: Pointer to the user-space handle to be translated.
1204  * @vmw_bo_p: Points to a location that, on successful return will carry a
1205  * non-reference-counted pointer to the DMA buffer identified by the user-space
1206  * handle in @id.
1207  *
1208  * This function saves information needed to translate a user-space buffer
1209  * handle to a valid SVGAGuestPtr. The translation does not take place
1210  * immediately, but during a call to vmw_apply_relocations().
1211  *
1212  * This function builds a relocation list and a list of buffers to validate.
1213  * The former needs to be freed using either vmw_apply_relocations() or
1214  * vmw_free_relocations(). The latter needs to be freed using
1215  * vmw_clear_validations.
1216  */
1217 static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
1218                    struct vmw_sw_context *sw_context,
1219                    SVGAGuestPtr *ptr,
1220                    struct vmw_buffer_object **vmw_bo_p)
1221 {
1222     struct vmw_buffer_object *vmw_bo;
1223     uint32_t handle = ptr->gmrId;
1224     struct vmw_relocation *reloc;
1225     int ret;
1226 
1227     vmw_validation_preload_bo(sw_context->ctx);
1228     vmw_bo = vmw_user_bo_noref_lookup(sw_context->filp, handle);
1229     if (IS_ERR_OR_NULL(vmw_bo)) {
1230         VMW_DEBUG_USER("Could not find or use GMR region.\n");
1231         return PTR_ERR(vmw_bo);
1232     }
1233     ret = vmw_validation_add_bo(sw_context->ctx, vmw_bo, false, false);
1234     ttm_bo_put(&vmw_bo->base);
1235     if (unlikely(ret != 0))
1236         return ret;
1237 
1238     reloc = vmw_validation_mem_alloc(sw_context->ctx, sizeof(*reloc));
1239     if (!reloc)
1240         return -ENOMEM;
1241 
1242     reloc->location = ptr;
1243     reloc->vbo = vmw_bo;
1244     *vmw_bo_p = vmw_bo;
1245     list_add_tail(&reloc->head, &sw_context->bo_relocations);
1246 
1247     return 0;
1248 }
1249 
1250 /**
1251  * vmw_cmd_dx_define_query - validate SVGA_3D_CMD_DX_DEFINE_QUERY command.
1252  *
1253  * @dev_priv: Pointer to a device private struct.
1254  * @sw_context: The software context used for this command submission.
1255  * @header: Pointer to the command header in the command stream.
1256  *
1257  * This function adds the new query into the query COTABLE
1258  */
1259 static int vmw_cmd_dx_define_query(struct vmw_private *dev_priv,
1260                    struct vmw_sw_context *sw_context,
1261                    SVGA3dCmdHeader *header)
1262 {
1263     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXDefineQuery);
1264     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
1265     struct vmw_resource *cotable_res;
1266     int ret;
1267 
1268     if (!ctx_node)
1269         return -EINVAL;
1270 
1271     cmd = container_of(header, typeof(*cmd), header);
1272 
1273     if (cmd->body.type <  SVGA3D_QUERYTYPE_MIN ||
1274         cmd->body.type >= SVGA3D_QUERYTYPE_MAX)
1275         return -EINVAL;
1276 
1277     cotable_res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXQUERY);
1278     ret = vmw_cotable_notify(cotable_res, cmd->body.queryId);
1279 
1280     return ret;
1281 }
1282 
1283 /**
1284  * vmw_cmd_dx_bind_query - validate SVGA_3D_CMD_DX_BIND_QUERY command.
1285  *
1286  * @dev_priv: Pointer to a device private struct.
1287  * @sw_context: The software context used for this command submission.
1288  * @header: Pointer to the command header in the command stream.
1289  *
1290  * The query bind operation will eventually associate the query ID with its
1291  * backing MOB.  In this function, we take the user mode MOB ID and use
1292  * vmw_translate_mob_ptr() to translate it to its kernel mode equivalent.
1293  */
1294 static int vmw_cmd_dx_bind_query(struct vmw_private *dev_priv,
1295                  struct vmw_sw_context *sw_context,
1296                  SVGA3dCmdHeader *header)
1297 {
1298     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBindQuery);
1299     struct vmw_buffer_object *vmw_bo;
1300     int ret;
1301 
1302     cmd = container_of(header, typeof(*cmd), header);
1303 
1304     /*
1305      * Look up the buffer pointed to by q.mobid, put it on the relocation
1306      * list so its kernel mode MOB ID can be filled in later
1307      */
1308     ret = vmw_translate_mob_ptr(dev_priv, sw_context, &cmd->body.mobid,
1309                     &vmw_bo);
1310 
1311     if (ret != 0)
1312         return ret;
1313 
1314     sw_context->dx_query_mob = vmw_bo;
1315     sw_context->dx_query_ctx = sw_context->dx_ctx_node->ctx;
1316     return 0;
1317 }
1318 
1319 /**
1320  * vmw_cmd_begin_gb_query - validate SVGA_3D_CMD_BEGIN_GB_QUERY command.
1321  *
1322  * @dev_priv: Pointer to a device private struct.
1323  * @sw_context: The software context used for this command submission.
1324  * @header: Pointer to the command header in the command stream.
1325  */
1326 static int vmw_cmd_begin_gb_query(struct vmw_private *dev_priv,
1327                   struct vmw_sw_context *sw_context,
1328                   SVGA3dCmdHeader *header)
1329 {
1330     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBeginGBQuery) =
1331         container_of(header, typeof(*cmd), header);
1332 
1333     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
1334                  VMW_RES_DIRTY_SET, user_context_converter,
1335                  &cmd->body.cid, NULL);
1336 }
1337 
1338 /**
1339  * vmw_cmd_begin_query - validate SVGA_3D_CMD_BEGIN_QUERY command.
1340  *
1341  * @dev_priv: Pointer to a device private struct.
1342  * @sw_context: The software context used for this command submission.
1343  * @header: Pointer to the command header in the command stream.
1344  */
1345 static int vmw_cmd_begin_query(struct vmw_private *dev_priv,
1346                    struct vmw_sw_context *sw_context,
1347                    SVGA3dCmdHeader *header)
1348 {
1349     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBeginQuery) =
1350         container_of(header, typeof(*cmd), header);
1351 
1352     if (unlikely(dev_priv->has_mob)) {
1353         VMW_DECLARE_CMD_VAR(gb_cmd, SVGA3dCmdBeginGBQuery);
1354 
1355         BUG_ON(sizeof(gb_cmd) != sizeof(*cmd));
1356 
1357         gb_cmd.header.id = SVGA_3D_CMD_BEGIN_GB_QUERY;
1358         gb_cmd.header.size = cmd->header.size;
1359         gb_cmd.body.cid = cmd->body.cid;
1360         gb_cmd.body.type = cmd->body.type;
1361 
1362         memcpy(cmd, &gb_cmd, sizeof(*cmd));
1363         return vmw_cmd_begin_gb_query(dev_priv, sw_context, header);
1364     }
1365 
1366     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
1367                  VMW_RES_DIRTY_SET, user_context_converter,
1368                  &cmd->body.cid, NULL);
1369 }
1370 
1371 /**
1372  * vmw_cmd_end_gb_query - validate SVGA_3D_CMD_END_GB_QUERY command.
1373  *
1374  * @dev_priv: Pointer to a device private struct.
1375  * @sw_context: The software context used for this command submission.
1376  * @header: Pointer to the command header in the command stream.
1377  */
1378 static int vmw_cmd_end_gb_query(struct vmw_private *dev_priv,
1379                 struct vmw_sw_context *sw_context,
1380                 SVGA3dCmdHeader *header)
1381 {
1382     struct vmw_buffer_object *vmw_bo;
1383     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdEndGBQuery);
1384     int ret;
1385 
1386     cmd = container_of(header, typeof(*cmd), header);
1387     ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
1388     if (unlikely(ret != 0))
1389         return ret;
1390 
1391     ret = vmw_translate_mob_ptr(dev_priv, sw_context, &cmd->body.mobid,
1392                     &vmw_bo);
1393     if (unlikely(ret != 0))
1394         return ret;
1395 
1396     ret = vmw_query_bo_switch_prepare(dev_priv, vmw_bo, sw_context);
1397 
1398     return ret;
1399 }
1400 
1401 /**
1402  * vmw_cmd_end_query - validate SVGA_3D_CMD_END_QUERY command.
1403  *
1404  * @dev_priv: Pointer to a device private struct.
1405  * @sw_context: The software context used for this command submission.
1406  * @header: Pointer to the command header in the command stream.
1407  */
1408 static int vmw_cmd_end_query(struct vmw_private *dev_priv,
1409                  struct vmw_sw_context *sw_context,
1410                  SVGA3dCmdHeader *header)
1411 {
1412     struct vmw_buffer_object *vmw_bo;
1413     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdEndQuery);
1414     int ret;
1415 
1416     cmd = container_of(header, typeof(*cmd), header);
1417     if (dev_priv->has_mob) {
1418         VMW_DECLARE_CMD_VAR(gb_cmd, SVGA3dCmdEndGBQuery);
1419 
1420         BUG_ON(sizeof(gb_cmd) != sizeof(*cmd));
1421 
1422         gb_cmd.header.id = SVGA_3D_CMD_END_GB_QUERY;
1423         gb_cmd.header.size = cmd->header.size;
1424         gb_cmd.body.cid = cmd->body.cid;
1425         gb_cmd.body.type = cmd->body.type;
1426         gb_cmd.body.mobid = cmd->body.guestResult.gmrId;
1427         gb_cmd.body.offset = cmd->body.guestResult.offset;
1428 
1429         memcpy(cmd, &gb_cmd, sizeof(*cmd));
1430         return vmw_cmd_end_gb_query(dev_priv, sw_context, header);
1431     }
1432 
1433     ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
1434     if (unlikely(ret != 0))
1435         return ret;
1436 
1437     ret = vmw_translate_guest_ptr(dev_priv, sw_context,
1438                       &cmd->body.guestResult, &vmw_bo);
1439     if (unlikely(ret != 0))
1440         return ret;
1441 
1442     ret = vmw_query_bo_switch_prepare(dev_priv, vmw_bo, sw_context);
1443 
1444     return ret;
1445 }
1446 
1447 /**
1448  * vmw_cmd_wait_gb_query - validate SVGA_3D_CMD_WAIT_GB_QUERY command.
1449  *
1450  * @dev_priv: Pointer to a device private struct.
1451  * @sw_context: The software context used for this command submission.
1452  * @header: Pointer to the command header in the command stream.
1453  */
1454 static int vmw_cmd_wait_gb_query(struct vmw_private *dev_priv,
1455                  struct vmw_sw_context *sw_context,
1456                  SVGA3dCmdHeader *header)
1457 {
1458     struct vmw_buffer_object *vmw_bo;
1459     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdWaitForGBQuery);
1460     int ret;
1461 
1462     cmd = container_of(header, typeof(*cmd), header);
1463     ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
1464     if (unlikely(ret != 0))
1465         return ret;
1466 
1467     ret = vmw_translate_mob_ptr(dev_priv, sw_context, &cmd->body.mobid,
1468                     &vmw_bo);
1469     if (unlikely(ret != 0))
1470         return ret;
1471 
1472     return 0;
1473 }
1474 
1475 /**
1476  * vmw_cmd_wait_query - validate SVGA_3D_CMD_WAIT_QUERY command.
1477  *
1478  * @dev_priv: Pointer to a device private struct.
1479  * @sw_context: The software context used for this command submission.
1480  * @header: Pointer to the command header in the command stream.
1481  */
1482 static int vmw_cmd_wait_query(struct vmw_private *dev_priv,
1483                   struct vmw_sw_context *sw_context,
1484                   SVGA3dCmdHeader *header)
1485 {
1486     struct vmw_buffer_object *vmw_bo;
1487     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdWaitForQuery);
1488     int ret;
1489 
1490     cmd = container_of(header, typeof(*cmd), header);
1491     if (dev_priv->has_mob) {
1492         VMW_DECLARE_CMD_VAR(gb_cmd, SVGA3dCmdWaitForGBQuery);
1493 
1494         BUG_ON(sizeof(gb_cmd) != sizeof(*cmd));
1495 
1496         gb_cmd.header.id = SVGA_3D_CMD_WAIT_FOR_GB_QUERY;
1497         gb_cmd.header.size = cmd->header.size;
1498         gb_cmd.body.cid = cmd->body.cid;
1499         gb_cmd.body.type = cmd->body.type;
1500         gb_cmd.body.mobid = cmd->body.guestResult.gmrId;
1501         gb_cmd.body.offset = cmd->body.guestResult.offset;
1502 
1503         memcpy(cmd, &gb_cmd, sizeof(*cmd));
1504         return vmw_cmd_wait_gb_query(dev_priv, sw_context, header);
1505     }
1506 
1507     ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
1508     if (unlikely(ret != 0))
1509         return ret;
1510 
1511     ret = vmw_translate_guest_ptr(dev_priv, sw_context,
1512                       &cmd->body.guestResult, &vmw_bo);
1513     if (unlikely(ret != 0))
1514         return ret;
1515 
1516     return 0;
1517 }
1518 
1519 static int vmw_cmd_dma(struct vmw_private *dev_priv,
1520                struct vmw_sw_context *sw_context,
1521                SVGA3dCmdHeader *header)
1522 {
1523     struct vmw_buffer_object *vmw_bo = NULL;
1524     struct vmw_surface *srf = NULL;
1525     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSurfaceDMA);
1526     int ret;
1527     SVGA3dCmdSurfaceDMASuffix *suffix;
1528     uint32_t bo_size;
1529     bool dirty;
1530 
1531     cmd = container_of(header, typeof(*cmd), header);
1532     suffix = (SVGA3dCmdSurfaceDMASuffix *)((unsigned long) &cmd->body +
1533                            header->size - sizeof(*suffix));
1534 
1535     /* Make sure device and verifier stays in sync. */
1536     if (unlikely(suffix->suffixSize != sizeof(*suffix))) {
1537         VMW_DEBUG_USER("Invalid DMA suffix size.\n");
1538         return -EINVAL;
1539     }
1540 
1541     ret = vmw_translate_guest_ptr(dev_priv, sw_context,
1542                       &cmd->body.guest.ptr, &vmw_bo);
1543     if (unlikely(ret != 0))
1544         return ret;
1545 
1546     /* Make sure DMA doesn't cross BO boundaries. */
1547     bo_size = vmw_bo->base.base.size;
1548     if (unlikely(cmd->body.guest.ptr.offset > bo_size)) {
1549         VMW_DEBUG_USER("Invalid DMA offset.\n");
1550         return -EINVAL;
1551     }
1552 
1553     bo_size -= cmd->body.guest.ptr.offset;
1554     if (unlikely(suffix->maximumOffset > bo_size))
1555         suffix->maximumOffset = bo_size;
1556 
1557     dirty = (cmd->body.transfer == SVGA3D_WRITE_HOST_VRAM) ?
1558         VMW_RES_DIRTY_SET : 0;
1559     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1560                 dirty, user_surface_converter,
1561                 &cmd->body.host.sid, NULL);
1562     if (unlikely(ret != 0)) {
1563         if (unlikely(ret != -ERESTARTSYS))
1564             VMW_DEBUG_USER("could not find surface for DMA.\n");
1565         return ret;
1566     }
1567 
1568     srf = vmw_res_to_srf(sw_context->res_cache[vmw_res_surface].res);
1569 
1570     vmw_kms_cursor_snoop(srf, sw_context->fp->tfile, &vmw_bo->base, header);
1571 
1572     return 0;
1573 }
1574 
1575 static int vmw_cmd_draw(struct vmw_private *dev_priv,
1576             struct vmw_sw_context *sw_context,
1577             SVGA3dCmdHeader *header)
1578 {
1579     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDrawPrimitives);
1580     SVGA3dVertexDecl *decl = (SVGA3dVertexDecl *)(
1581         (unsigned long)header + sizeof(*cmd));
1582     SVGA3dPrimitiveRange *range;
1583     uint32_t i;
1584     uint32_t maxnum;
1585     int ret;
1586 
1587     ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
1588     if (unlikely(ret != 0))
1589         return ret;
1590 
1591     cmd = container_of(header, typeof(*cmd), header);
1592     maxnum = (header->size - sizeof(cmd->body)) / sizeof(*decl);
1593 
1594     if (unlikely(cmd->body.numVertexDecls > maxnum)) {
1595         VMW_DEBUG_USER("Illegal number of vertex declarations.\n");
1596         return -EINVAL;
1597     }
1598 
1599     for (i = 0; i < cmd->body.numVertexDecls; ++i, ++decl) {
1600         ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1601                     VMW_RES_DIRTY_NONE,
1602                     user_surface_converter,
1603                     &decl->array.surfaceId, NULL);
1604         if (unlikely(ret != 0))
1605             return ret;
1606     }
1607 
1608     maxnum = (header->size - sizeof(cmd->body) -
1609           cmd->body.numVertexDecls * sizeof(*decl)) / sizeof(*range);
1610     if (unlikely(cmd->body.numRanges > maxnum)) {
1611         VMW_DEBUG_USER("Illegal number of index ranges.\n");
1612         return -EINVAL;
1613     }
1614 
1615     range = (SVGA3dPrimitiveRange *) decl;
1616     for (i = 0; i < cmd->body.numRanges; ++i, ++range) {
1617         ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1618                     VMW_RES_DIRTY_NONE,
1619                     user_surface_converter,
1620                     &range->indexArray.surfaceId, NULL);
1621         if (unlikely(ret != 0))
1622             return ret;
1623     }
1624     return 0;
1625 }
1626 
1627 static int vmw_cmd_tex_state(struct vmw_private *dev_priv,
1628                  struct vmw_sw_context *sw_context,
1629                  SVGA3dCmdHeader *header)
1630 {
1631     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSetTextureState);
1632     SVGA3dTextureState *last_state = (SVGA3dTextureState *)
1633       ((unsigned long) header + header->size + sizeof(header));
1634     SVGA3dTextureState *cur_state = (SVGA3dTextureState *)
1635         ((unsigned long) header + sizeof(*cmd));
1636     struct vmw_resource *ctx;
1637     struct vmw_resource *res;
1638     int ret;
1639 
1640     cmd = container_of(header, typeof(*cmd), header);
1641 
1642     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
1643                 VMW_RES_DIRTY_SET, user_context_converter,
1644                 &cmd->body.cid, &ctx);
1645     if (unlikely(ret != 0))
1646         return ret;
1647 
1648     for (; cur_state < last_state; ++cur_state) {
1649         if (likely(cur_state->name != SVGA3D_TS_BIND_TEXTURE))
1650             continue;
1651 
1652         if (cur_state->stage >= SVGA3D_NUM_TEXTURE_UNITS) {
1653             VMW_DEBUG_USER("Illegal texture/sampler unit %u.\n",
1654                        (unsigned int) cur_state->stage);
1655             return -EINVAL;
1656         }
1657 
1658         ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1659                     VMW_RES_DIRTY_NONE,
1660                     user_surface_converter,
1661                     &cur_state->value, &res);
1662         if (unlikely(ret != 0))
1663             return ret;
1664 
1665         if (dev_priv->has_mob) {
1666             struct vmw_ctx_bindinfo_tex binding;
1667             struct vmw_ctx_validation_info *node;
1668 
1669             node = vmw_execbuf_info_from_res(sw_context, ctx);
1670             if (!node)
1671                 return -EINVAL;
1672 
1673             binding.bi.ctx = ctx;
1674             binding.bi.res = res;
1675             binding.bi.bt = vmw_ctx_binding_tex;
1676             binding.texture_stage = cur_state->stage;
1677             vmw_binding_add(node->staged, &binding.bi, 0,
1678                     binding.texture_stage);
1679         }
1680     }
1681 
1682     return 0;
1683 }
1684 
1685 static int vmw_cmd_check_define_gmrfb(struct vmw_private *dev_priv,
1686                       struct vmw_sw_context *sw_context,
1687                       void *buf)
1688 {
1689     struct vmw_buffer_object *vmw_bo;
1690 
1691     struct {
1692         uint32_t header;
1693         SVGAFifoCmdDefineGMRFB body;
1694     } *cmd = buf;
1695 
1696     return vmw_translate_guest_ptr(dev_priv, sw_context, &cmd->body.ptr,
1697                        &vmw_bo);
1698 }
1699 
1700 /**
1701  * vmw_cmd_res_switch_backup - Utility function to handle backup buffer
1702  * switching
1703  *
1704  * @dev_priv: Pointer to a device private struct.
1705  * @sw_context: The software context being used for this batch.
1706  * @res: Pointer to the resource.
1707  * @buf_id: Pointer to the user-space backup buffer handle in the command
1708  * stream.
1709  * @backup_offset: Offset of backup into MOB.
1710  *
1711  * This function prepares for registering a switch of backup buffers in the
1712  * resource metadata just prior to unreserving. It's basically a wrapper around
1713  * vmw_cmd_res_switch_backup with a different interface.
1714  */
1715 static int vmw_cmd_res_switch_backup(struct vmw_private *dev_priv,
1716                      struct vmw_sw_context *sw_context,
1717                      struct vmw_resource *res, uint32_t *buf_id,
1718                      unsigned long backup_offset)
1719 {
1720     struct vmw_buffer_object *vbo;
1721     void *info;
1722     int ret;
1723 
1724     info = vmw_execbuf_info_from_res(sw_context, res);
1725     if (!info)
1726         return -EINVAL;
1727 
1728     ret = vmw_translate_mob_ptr(dev_priv, sw_context, buf_id, &vbo);
1729     if (ret)
1730         return ret;
1731 
1732     vmw_validation_res_switch_backup(sw_context->ctx, info, vbo,
1733                      backup_offset);
1734     return 0;
1735 }
1736 
1737 /**
1738  * vmw_cmd_switch_backup - Utility function to handle backup buffer switching
1739  *
1740  * @dev_priv: Pointer to a device private struct.
1741  * @sw_context: The software context being used for this batch.
1742  * @res_type: The resource type.
1743  * @converter: Information about user-space binding for this resource type.
1744  * @res_id: Pointer to the user-space resource handle in the command stream.
1745  * @buf_id: Pointer to the user-space backup buffer handle in the command
1746  * stream.
1747  * @backup_offset: Offset of backup into MOB.
1748  *
1749  * This function prepares for registering a switch of backup buffers in the
1750  * resource metadata just prior to unreserving. It's basically a wrapper around
1751  * vmw_cmd_res_switch_backup with a different interface.
1752  */
1753 static int vmw_cmd_switch_backup(struct vmw_private *dev_priv,
1754                  struct vmw_sw_context *sw_context,
1755                  enum vmw_res_type res_type,
1756                  const struct vmw_user_resource_conv
1757                  *converter, uint32_t *res_id, uint32_t *buf_id,
1758                  unsigned long backup_offset)
1759 {
1760     struct vmw_resource *res;
1761     int ret;
1762 
1763     ret = vmw_cmd_res_check(dev_priv, sw_context, res_type,
1764                 VMW_RES_DIRTY_NONE, converter, res_id, &res);
1765     if (ret)
1766         return ret;
1767 
1768     return vmw_cmd_res_switch_backup(dev_priv, sw_context, res, buf_id,
1769                      backup_offset);
1770 }
1771 
1772 /**
1773  * vmw_cmd_bind_gb_surface - Validate SVGA_3D_CMD_BIND_GB_SURFACE command
1774  *
1775  * @dev_priv: Pointer to a device private struct.
1776  * @sw_context: The software context being used for this batch.
1777  * @header: Pointer to the command header in the command stream.
1778  */
1779 static int vmw_cmd_bind_gb_surface(struct vmw_private *dev_priv,
1780                    struct vmw_sw_context *sw_context,
1781                    SVGA3dCmdHeader *header)
1782 {
1783     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBindGBSurface) =
1784         container_of(header, typeof(*cmd), header);
1785 
1786     return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_surface,
1787                      user_surface_converter, &cmd->body.sid,
1788                      &cmd->body.mobid, 0);
1789 }
1790 
1791 /**
1792  * vmw_cmd_update_gb_image - Validate SVGA_3D_CMD_UPDATE_GB_IMAGE command
1793  *
1794  * @dev_priv: Pointer to a device private struct.
1795  * @sw_context: The software context being used for this batch.
1796  * @header: Pointer to the command header in the command stream.
1797  */
1798 static int vmw_cmd_update_gb_image(struct vmw_private *dev_priv,
1799                    struct vmw_sw_context *sw_context,
1800                    SVGA3dCmdHeader *header)
1801 {
1802     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdUpdateGBImage) =
1803         container_of(header, typeof(*cmd), header);
1804 
1805     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1806                  VMW_RES_DIRTY_NONE, user_surface_converter,
1807                  &cmd->body.image.sid, NULL);
1808 }
1809 
1810 /**
1811  * vmw_cmd_update_gb_surface - Validate SVGA_3D_CMD_UPDATE_GB_SURFACE command
1812  *
1813  * @dev_priv: Pointer to a device private struct.
1814  * @sw_context: The software context being used for this batch.
1815  * @header: Pointer to the command header in the command stream.
1816  */
1817 static int vmw_cmd_update_gb_surface(struct vmw_private *dev_priv,
1818                      struct vmw_sw_context *sw_context,
1819                      SVGA3dCmdHeader *header)
1820 {
1821     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdUpdateGBSurface) =
1822         container_of(header, typeof(*cmd), header);
1823 
1824     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1825                  VMW_RES_DIRTY_CLEAR, user_surface_converter,
1826                  &cmd->body.sid, NULL);
1827 }
1828 
1829 /**
1830  * vmw_cmd_readback_gb_image - Validate SVGA_3D_CMD_READBACK_GB_IMAGE command
1831  *
1832  * @dev_priv: Pointer to a device private struct.
1833  * @sw_context: The software context being used for this batch.
1834  * @header: Pointer to the command header in the command stream.
1835  */
1836 static int vmw_cmd_readback_gb_image(struct vmw_private *dev_priv,
1837                      struct vmw_sw_context *sw_context,
1838                      SVGA3dCmdHeader *header)
1839 {
1840     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdReadbackGBImage) =
1841         container_of(header, typeof(*cmd), header);
1842 
1843     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1844                  VMW_RES_DIRTY_NONE, user_surface_converter,
1845                  &cmd->body.image.sid, NULL);
1846 }
1847 
1848 /**
1849  * vmw_cmd_readback_gb_surface - Validate SVGA_3D_CMD_READBACK_GB_SURFACE
1850  * command
1851  *
1852  * @dev_priv: Pointer to a device private struct.
1853  * @sw_context: The software context being used for this batch.
1854  * @header: Pointer to the command header in the command stream.
1855  */
1856 static int vmw_cmd_readback_gb_surface(struct vmw_private *dev_priv,
1857                        struct vmw_sw_context *sw_context,
1858                        SVGA3dCmdHeader *header)
1859 {
1860     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdReadbackGBSurface) =
1861         container_of(header, typeof(*cmd), header);
1862 
1863     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1864                  VMW_RES_DIRTY_CLEAR, user_surface_converter,
1865                  &cmd->body.sid, NULL);
1866 }
1867 
1868 /**
1869  * vmw_cmd_invalidate_gb_image - Validate SVGA_3D_CMD_INVALIDATE_GB_IMAGE
1870  * command
1871  *
1872  * @dev_priv: Pointer to a device private struct.
1873  * @sw_context: The software context being used for this batch.
1874  * @header: Pointer to the command header in the command stream.
1875  */
1876 static int vmw_cmd_invalidate_gb_image(struct vmw_private *dev_priv,
1877                        struct vmw_sw_context *sw_context,
1878                        SVGA3dCmdHeader *header)
1879 {
1880     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdInvalidateGBImage) =
1881         container_of(header, typeof(*cmd), header);
1882 
1883     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1884                  VMW_RES_DIRTY_NONE, user_surface_converter,
1885                  &cmd->body.image.sid, NULL);
1886 }
1887 
1888 /**
1889  * vmw_cmd_invalidate_gb_surface - Validate SVGA_3D_CMD_INVALIDATE_GB_SURFACE
1890  * command
1891  *
1892  * @dev_priv: Pointer to a device private struct.
1893  * @sw_context: The software context being used for this batch.
1894  * @header: Pointer to the command header in the command stream.
1895  */
1896 static int vmw_cmd_invalidate_gb_surface(struct vmw_private *dev_priv,
1897                      struct vmw_sw_context *sw_context,
1898                      SVGA3dCmdHeader *header)
1899 {
1900     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdInvalidateGBSurface) =
1901         container_of(header, typeof(*cmd), header);
1902 
1903     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
1904                  VMW_RES_DIRTY_CLEAR, user_surface_converter,
1905                  &cmd->body.sid, NULL);
1906 }
1907 
1908 /**
1909  * vmw_cmd_shader_define - Validate SVGA_3D_CMD_SHADER_DEFINE command
1910  *
1911  * @dev_priv: Pointer to a device private struct.
1912  * @sw_context: The software context being used for this batch.
1913  * @header: Pointer to the command header in the command stream.
1914  */
1915 static int vmw_cmd_shader_define(struct vmw_private *dev_priv,
1916                  struct vmw_sw_context *sw_context,
1917                  SVGA3dCmdHeader *header)
1918 {
1919     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDefineShader);
1920     int ret;
1921     size_t size;
1922     struct vmw_resource *ctx;
1923 
1924     cmd = container_of(header, typeof(*cmd), header);
1925 
1926     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
1927                 VMW_RES_DIRTY_SET, user_context_converter,
1928                 &cmd->body.cid, &ctx);
1929     if (unlikely(ret != 0))
1930         return ret;
1931 
1932     if (unlikely(!dev_priv->has_mob))
1933         return 0;
1934 
1935     size = cmd->header.size - sizeof(cmd->body);
1936     ret = vmw_compat_shader_add(dev_priv, vmw_context_res_man(ctx),
1937                     cmd->body.shid, cmd + 1, cmd->body.type,
1938                     size, &sw_context->staged_cmd_res);
1939     if (unlikely(ret != 0))
1940         return ret;
1941 
1942     return vmw_resource_relocation_add(sw_context, NULL,
1943                        vmw_ptr_diff(sw_context->buf_start,
1944                             &cmd->header.id),
1945                        vmw_res_rel_nop);
1946 }
1947 
1948 /**
1949  * vmw_cmd_shader_destroy - Validate SVGA_3D_CMD_SHADER_DESTROY command
1950  *
1951  * @dev_priv: Pointer to a device private struct.
1952  * @sw_context: The software context being used for this batch.
1953  * @header: Pointer to the command header in the command stream.
1954  */
1955 static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv,
1956                   struct vmw_sw_context *sw_context,
1957                   SVGA3dCmdHeader *header)
1958 {
1959     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDestroyShader);
1960     int ret;
1961     struct vmw_resource *ctx;
1962 
1963     cmd = container_of(header, typeof(*cmd), header);
1964 
1965     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
1966                 VMW_RES_DIRTY_SET, user_context_converter,
1967                 &cmd->body.cid, &ctx);
1968     if (unlikely(ret != 0))
1969         return ret;
1970 
1971     if (unlikely(!dev_priv->has_mob))
1972         return 0;
1973 
1974     ret = vmw_shader_remove(vmw_context_res_man(ctx), cmd->body.shid,
1975                 cmd->body.type, &sw_context->staged_cmd_res);
1976     if (unlikely(ret != 0))
1977         return ret;
1978 
1979     return vmw_resource_relocation_add(sw_context, NULL,
1980                        vmw_ptr_diff(sw_context->buf_start,
1981                             &cmd->header.id),
1982                        vmw_res_rel_nop);
1983 }
1984 
1985 /**
1986  * vmw_cmd_set_shader - Validate SVGA_3D_CMD_SET_SHADER command
1987  *
1988  * @dev_priv: Pointer to a device private struct.
1989  * @sw_context: The software context being used for this batch.
1990  * @header: Pointer to the command header in the command stream.
1991  */
1992 static int vmw_cmd_set_shader(struct vmw_private *dev_priv,
1993                   struct vmw_sw_context *sw_context,
1994                   SVGA3dCmdHeader *header)
1995 {
1996     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSetShader);
1997     struct vmw_ctx_bindinfo_shader binding;
1998     struct vmw_resource *ctx, *res = NULL;
1999     struct vmw_ctx_validation_info *ctx_info;
2000     int ret;
2001 
2002     cmd = container_of(header, typeof(*cmd), header);
2003 
2004     if (cmd->body.type >= SVGA3D_SHADERTYPE_PREDX_MAX) {
2005         VMW_DEBUG_USER("Illegal shader type %u.\n",
2006                    (unsigned int) cmd->body.type);
2007         return -EINVAL;
2008     }
2009 
2010     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
2011                 VMW_RES_DIRTY_SET, user_context_converter,
2012                 &cmd->body.cid, &ctx);
2013     if (unlikely(ret != 0))
2014         return ret;
2015 
2016     if (!dev_priv->has_mob)
2017         return 0;
2018 
2019     if (cmd->body.shid != SVGA3D_INVALID_ID) {
2020         /*
2021          * This is the compat shader path - Per device guest-backed
2022          * shaders, but user-space thinks it's per context host-
2023          * backed shaders.
2024          */
2025         res = vmw_shader_lookup(vmw_context_res_man(ctx),
2026                     cmd->body.shid, cmd->body.type);
2027         if (!IS_ERR(res)) {
2028             ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
2029                                 VMW_RES_DIRTY_NONE);
2030             if (unlikely(ret != 0))
2031                 return ret;
2032 
2033             ret = vmw_resource_relocation_add
2034                 (sw_context, res,
2035                  vmw_ptr_diff(sw_context->buf_start,
2036                           &cmd->body.shid),
2037                  vmw_res_rel_normal);
2038             if (unlikely(ret != 0))
2039                 return ret;
2040         }
2041     }
2042 
2043     if (IS_ERR_OR_NULL(res)) {
2044         ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_shader,
2045                     VMW_RES_DIRTY_NONE,
2046                     user_shader_converter, &cmd->body.shid,
2047                     &res);
2048         if (unlikely(ret != 0))
2049             return ret;
2050     }
2051 
2052     ctx_info = vmw_execbuf_info_from_res(sw_context, ctx);
2053     if (!ctx_info)
2054         return -EINVAL;
2055 
2056     binding.bi.ctx = ctx;
2057     binding.bi.res = res;
2058     binding.bi.bt = vmw_ctx_binding_shader;
2059     binding.shader_slot = cmd->body.type - SVGA3D_SHADERTYPE_MIN;
2060     vmw_binding_add(ctx_info->staged, &binding.bi, binding.shader_slot, 0);
2061 
2062     return 0;
2063 }
2064 
2065 /**
2066  * vmw_cmd_set_shader_const - Validate SVGA_3D_CMD_SET_SHADER_CONST command
2067  *
2068  * @dev_priv: Pointer to a device private struct.
2069  * @sw_context: The software context being used for this batch.
2070  * @header: Pointer to the command header in the command stream.
2071  */
2072 static int vmw_cmd_set_shader_const(struct vmw_private *dev_priv,
2073                     struct vmw_sw_context *sw_context,
2074                     SVGA3dCmdHeader *header)
2075 {
2076     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdSetShaderConst);
2077     int ret;
2078 
2079     cmd = container_of(header, typeof(*cmd), header);
2080 
2081     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
2082                 VMW_RES_DIRTY_SET, user_context_converter,
2083                 &cmd->body.cid, NULL);
2084     if (unlikely(ret != 0))
2085         return ret;
2086 
2087     if (dev_priv->has_mob)
2088         header->id = SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE;
2089 
2090     return 0;
2091 }
2092 
2093 /**
2094  * vmw_cmd_bind_gb_shader - Validate SVGA_3D_CMD_BIND_GB_SHADER command
2095  *
2096  * @dev_priv: Pointer to a device private struct.
2097  * @sw_context: The software context being used for this batch.
2098  * @header: Pointer to the command header in the command stream.
2099  */
2100 static int vmw_cmd_bind_gb_shader(struct vmw_private *dev_priv,
2101                   struct vmw_sw_context *sw_context,
2102                   SVGA3dCmdHeader *header)
2103 {
2104     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdBindGBShader) =
2105         container_of(header, typeof(*cmd), header);
2106 
2107     return vmw_cmd_switch_backup(dev_priv, sw_context, vmw_res_shader,
2108                      user_shader_converter, &cmd->body.shid,
2109                      &cmd->body.mobid, cmd->body.offsetInBytes);
2110 }
2111 
2112 /**
2113  * vmw_cmd_dx_set_single_constant_buffer - Validate
2114  * SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER command.
2115  *
2116  * @dev_priv: Pointer to a device private struct.
2117  * @sw_context: The software context being used for this batch.
2118  * @header: Pointer to the command header in the command stream.
2119  */
2120 static int
2121 vmw_cmd_dx_set_single_constant_buffer(struct vmw_private *dev_priv,
2122                       struct vmw_sw_context *sw_context,
2123                       SVGA3dCmdHeader *header)
2124 {
2125     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetSingleConstantBuffer);
2126     SVGA3dShaderType max_shader_num = has_sm5_context(dev_priv) ?
2127         SVGA3D_NUM_SHADERTYPE : SVGA3D_NUM_SHADERTYPE_DX10;
2128 
2129     struct vmw_resource *res = NULL;
2130     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2131     struct vmw_ctx_bindinfo_cb binding;
2132     int ret;
2133 
2134     if (!ctx_node)
2135         return -EINVAL;
2136 
2137     cmd = container_of(header, typeof(*cmd), header);
2138     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
2139                 VMW_RES_DIRTY_NONE, user_surface_converter,
2140                 &cmd->body.sid, &res);
2141     if (unlikely(ret != 0))
2142         return ret;
2143 
2144     binding.bi.ctx = ctx_node->ctx;
2145     binding.bi.res = res;
2146     binding.bi.bt = vmw_ctx_binding_cb;
2147     binding.shader_slot = cmd->body.type - SVGA3D_SHADERTYPE_MIN;
2148     binding.offset = cmd->body.offsetInBytes;
2149     binding.size = cmd->body.sizeInBytes;
2150     binding.slot = cmd->body.slot;
2151 
2152     if (binding.shader_slot >= max_shader_num ||
2153         binding.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) {
2154         VMW_DEBUG_USER("Illegal const buffer shader %u slot %u.\n",
2155                    (unsigned int) cmd->body.type,
2156                    (unsigned int) binding.slot);
2157         return -EINVAL;
2158     }
2159 
2160     vmw_binding_add(ctx_node->staged, &binding.bi, binding.shader_slot,
2161             binding.slot);
2162 
2163     return 0;
2164 }
2165 
2166 /**
2167  * vmw_cmd_dx_set_constant_buffer_offset - Validate
2168  * SVGA_3D_CMD_DX_SET_VS/PS/GS/HS/DS/CS_CONSTANT_BUFFER_OFFSET command.
2169  *
2170  * @dev_priv: Pointer to a device private struct.
2171  * @sw_context: The software context being used for this batch.
2172  * @header: Pointer to the command header in the command stream.
2173  */
2174 static int
2175 vmw_cmd_dx_set_constant_buffer_offset(struct vmw_private *dev_priv,
2176                       struct vmw_sw_context *sw_context,
2177                       SVGA3dCmdHeader *header)
2178 {
2179     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetConstantBufferOffset);
2180 
2181     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2182     u32 shader_slot;
2183 
2184     if (!has_sm5_context(dev_priv))
2185         return -EINVAL;
2186 
2187     if (!ctx_node)
2188         return -EINVAL;
2189 
2190     cmd = container_of(header, typeof(*cmd), header);
2191     if (cmd->body.slot >= SVGA3D_DX_MAX_CONSTBUFFERS) {
2192         VMW_DEBUG_USER("Illegal const buffer slot %u.\n",
2193                    (unsigned int) cmd->body.slot);
2194         return -EINVAL;
2195     }
2196 
2197     shader_slot = cmd->header.id - SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET;
2198     vmw_binding_cb_offset_update(ctx_node->staged, shader_slot,
2199                      cmd->body.slot, cmd->body.offsetInBytes);
2200 
2201     return 0;
2202 }
2203 
2204 /**
2205  * vmw_cmd_dx_set_shader_res - Validate SVGA_3D_CMD_DX_SET_SHADER_RESOURCES
2206  * command
2207  *
2208  * @dev_priv: Pointer to a device private struct.
2209  * @sw_context: The software context being used for this batch.
2210  * @header: Pointer to the command header in the command stream.
2211  */
2212 static int vmw_cmd_dx_set_shader_res(struct vmw_private *dev_priv,
2213                      struct vmw_sw_context *sw_context,
2214                      SVGA3dCmdHeader *header)
2215 {
2216     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShaderResources) =
2217         container_of(header, typeof(*cmd), header);
2218     SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ?
2219         SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX;
2220 
2221     u32 num_sr_view = (cmd->header.size - sizeof(cmd->body)) /
2222         sizeof(SVGA3dShaderResourceViewId);
2223 
2224     if ((u64) cmd->body.startView + (u64) num_sr_view >
2225         (u64) SVGA3D_DX_MAX_SRVIEWS ||
2226         cmd->body.type >= max_allowed) {
2227         VMW_DEBUG_USER("Invalid shader binding.\n");
2228         return -EINVAL;
2229     }
2230 
2231     return vmw_view_bindings_add(sw_context, vmw_view_sr,
2232                      vmw_ctx_binding_sr,
2233                      cmd->body.type - SVGA3D_SHADERTYPE_MIN,
2234                      (void *) &cmd[1], num_sr_view,
2235                      cmd->body.startView);
2236 }
2237 
2238 /**
2239  * vmw_cmd_dx_set_shader - Validate SVGA_3D_CMD_DX_SET_SHADER command
2240  *
2241  * @dev_priv: Pointer to a device private struct.
2242  * @sw_context: The software context being used for this batch.
2243  * @header: Pointer to the command header in the command stream.
2244  */
2245 static int vmw_cmd_dx_set_shader(struct vmw_private *dev_priv,
2246                  struct vmw_sw_context *sw_context,
2247                  SVGA3dCmdHeader *header)
2248 {
2249     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetShader);
2250     SVGA3dShaderType max_allowed = has_sm5_context(dev_priv) ?
2251         SVGA3D_SHADERTYPE_MAX : SVGA3D_SHADERTYPE_DX10_MAX;
2252     struct vmw_resource *res = NULL;
2253     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2254     struct vmw_ctx_bindinfo_shader binding;
2255     int ret = 0;
2256 
2257     if (!ctx_node)
2258         return -EINVAL;
2259 
2260     cmd = container_of(header, typeof(*cmd), header);
2261 
2262     if (cmd->body.type >= max_allowed ||
2263         cmd->body.type < SVGA3D_SHADERTYPE_MIN) {
2264         VMW_DEBUG_USER("Illegal shader type %u.\n",
2265                    (unsigned int) cmd->body.type);
2266         return -EINVAL;
2267     }
2268 
2269     if (cmd->body.shaderId != SVGA3D_INVALID_ID) {
2270         res = vmw_shader_lookup(sw_context->man, cmd->body.shaderId, 0);
2271         if (IS_ERR(res)) {
2272             VMW_DEBUG_USER("Could not find shader for binding.\n");
2273             return PTR_ERR(res);
2274         }
2275 
2276         ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
2277                             VMW_RES_DIRTY_NONE);
2278         if (ret)
2279             return ret;
2280     }
2281 
2282     binding.bi.ctx = ctx_node->ctx;
2283     binding.bi.res = res;
2284     binding.bi.bt = vmw_ctx_binding_dx_shader;
2285     binding.shader_slot = cmd->body.type - SVGA3D_SHADERTYPE_MIN;
2286 
2287     vmw_binding_add(ctx_node->staged, &binding.bi, binding.shader_slot, 0);
2288 
2289     return 0;
2290 }
2291 
2292 /**
2293  * vmw_cmd_dx_set_vertex_buffers - Validates SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS
2294  * command
2295  *
2296  * @dev_priv: Pointer to a device private struct.
2297  * @sw_context: The software context being used for this batch.
2298  * @header: Pointer to the command header in the command stream.
2299  */
2300 static int vmw_cmd_dx_set_vertex_buffers(struct vmw_private *dev_priv,
2301                      struct vmw_sw_context *sw_context,
2302                      SVGA3dCmdHeader *header)
2303 {
2304     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2305     struct vmw_ctx_bindinfo_vb binding;
2306     struct vmw_resource *res;
2307     struct {
2308         SVGA3dCmdHeader header;
2309         SVGA3dCmdDXSetVertexBuffers body;
2310         SVGA3dVertexBuffer buf[];
2311     } *cmd;
2312     int i, ret, num;
2313 
2314     if (!ctx_node)
2315         return -EINVAL;
2316 
2317     cmd = container_of(header, typeof(*cmd), header);
2318     num = (cmd->header.size - sizeof(cmd->body)) /
2319         sizeof(SVGA3dVertexBuffer);
2320     if ((u64)num + (u64)cmd->body.startBuffer >
2321         (u64)SVGA3D_DX_MAX_VERTEXBUFFERS) {
2322         VMW_DEBUG_USER("Invalid number of vertex buffers.\n");
2323         return -EINVAL;
2324     }
2325 
2326     for (i = 0; i < num; i++) {
2327         ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
2328                     VMW_RES_DIRTY_NONE,
2329                     user_surface_converter,
2330                     &cmd->buf[i].sid, &res);
2331         if (unlikely(ret != 0))
2332             return ret;
2333 
2334         binding.bi.ctx = ctx_node->ctx;
2335         binding.bi.bt = vmw_ctx_binding_vb;
2336         binding.bi.res = res;
2337         binding.offset = cmd->buf[i].offset;
2338         binding.stride = cmd->buf[i].stride;
2339         binding.slot = i + cmd->body.startBuffer;
2340 
2341         vmw_binding_add(ctx_node->staged, &binding.bi, 0, binding.slot);
2342     }
2343 
2344     return 0;
2345 }
2346 
2347 /**
2348  * vmw_cmd_dx_set_index_buffer - Validate
2349  * SVGA_3D_CMD_DX_IA_SET_INDEX_BUFFER command.
2350  *
2351  * @dev_priv: Pointer to a device private struct.
2352  * @sw_context: The software context being used for this batch.
2353  * @header: Pointer to the command header in the command stream.
2354  */
2355 static int vmw_cmd_dx_set_index_buffer(struct vmw_private *dev_priv,
2356                        struct vmw_sw_context *sw_context,
2357                        SVGA3dCmdHeader *header)
2358 {
2359     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2360     struct vmw_ctx_bindinfo_ib binding;
2361     struct vmw_resource *res;
2362     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetIndexBuffer);
2363     int ret;
2364 
2365     if (!ctx_node)
2366         return -EINVAL;
2367 
2368     cmd = container_of(header, typeof(*cmd), header);
2369     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
2370                 VMW_RES_DIRTY_NONE, user_surface_converter,
2371                 &cmd->body.sid, &res);
2372     if (unlikely(ret != 0))
2373         return ret;
2374 
2375     binding.bi.ctx = ctx_node->ctx;
2376     binding.bi.res = res;
2377     binding.bi.bt = vmw_ctx_binding_ib;
2378     binding.offset = cmd->body.offset;
2379     binding.format = cmd->body.format;
2380 
2381     vmw_binding_add(ctx_node->staged, &binding.bi, 0, 0);
2382 
2383     return 0;
2384 }
2385 
2386 /**
2387  * vmw_cmd_dx_set_rendertargets - Validate SVGA_3D_CMD_DX_SET_RENDERTARGETS
2388  * command
2389  *
2390  * @dev_priv: Pointer to a device private struct.
2391  * @sw_context: The software context being used for this batch.
2392  * @header: Pointer to the command header in the command stream.
2393  */
2394 static int vmw_cmd_dx_set_rendertargets(struct vmw_private *dev_priv,
2395                     struct vmw_sw_context *sw_context,
2396                     SVGA3dCmdHeader *header)
2397 {
2398     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXSetRenderTargets) =
2399         container_of(header, typeof(*cmd), header);
2400     u32 num_rt_view = (cmd->header.size - sizeof(cmd->body)) /
2401         sizeof(SVGA3dRenderTargetViewId);
2402     int ret;
2403 
2404     if (num_rt_view > SVGA3D_DX_MAX_RENDER_TARGETS) {
2405         VMW_DEBUG_USER("Invalid DX Rendertarget binding.\n");
2406         return -EINVAL;
2407     }
2408 
2409     ret = vmw_view_bindings_add(sw_context, vmw_view_ds, vmw_ctx_binding_ds,
2410                     0, &cmd->body.depthStencilViewId, 1, 0);
2411     if (ret)
2412         return ret;
2413 
2414     return vmw_view_bindings_add(sw_context, vmw_view_rt,
2415                      vmw_ctx_binding_dx_rt, 0, (void *)&cmd[1],
2416                      num_rt_view, 0);
2417 }
2418 
2419 /**
2420  * vmw_cmd_dx_clear_rendertarget_view - Validate
2421  * SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW command
2422  *
2423  * @dev_priv: Pointer to a device private struct.
2424  * @sw_context: The software context being used for this batch.
2425  * @header: Pointer to the command header in the command stream.
2426  */
2427 static int vmw_cmd_dx_clear_rendertarget_view(struct vmw_private *dev_priv,
2428                           struct vmw_sw_context *sw_context,
2429                           SVGA3dCmdHeader *header)
2430 {
2431     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXClearRenderTargetView) =
2432         container_of(header, typeof(*cmd), header);
2433     struct vmw_resource *ret;
2434 
2435     ret = vmw_view_id_val_add(sw_context, vmw_view_rt,
2436                   cmd->body.renderTargetViewId);
2437 
2438     return PTR_ERR_OR_ZERO(ret);
2439 }
2440 
2441 /**
2442  * vmw_cmd_dx_clear_depthstencil_view - Validate
2443  * SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW command
2444  *
2445  * @dev_priv: Pointer to a device private struct.
2446  * @sw_context: The software context being used for this batch.
2447  * @header: Pointer to the command header in the command stream.
2448  */
2449 static int vmw_cmd_dx_clear_depthstencil_view(struct vmw_private *dev_priv,
2450                           struct vmw_sw_context *sw_context,
2451                           SVGA3dCmdHeader *header)
2452 {
2453     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXClearDepthStencilView) =
2454         container_of(header, typeof(*cmd), header);
2455     struct vmw_resource *ret;
2456 
2457     ret = vmw_view_id_val_add(sw_context, vmw_view_ds,
2458                   cmd->body.depthStencilViewId);
2459 
2460     return PTR_ERR_OR_ZERO(ret);
2461 }
2462 
2463 static int vmw_cmd_dx_view_define(struct vmw_private *dev_priv,
2464                   struct vmw_sw_context *sw_context,
2465                   SVGA3dCmdHeader *header)
2466 {
2467     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2468     struct vmw_resource *srf;
2469     struct vmw_resource *res;
2470     enum vmw_view_type view_type;
2471     int ret;
2472     /*
2473      * This is based on the fact that all affected define commands have the
2474      * same initial command body layout.
2475      */
2476     struct {
2477         SVGA3dCmdHeader header;
2478         uint32 defined_id;
2479         uint32 sid;
2480     } *cmd;
2481 
2482     if (!ctx_node)
2483         return -EINVAL;
2484 
2485     view_type = vmw_view_cmd_to_type(header->id);
2486     if (view_type == vmw_view_max)
2487         return -EINVAL;
2488 
2489     cmd = container_of(header, typeof(*cmd), header);
2490     if (unlikely(cmd->sid == SVGA3D_INVALID_ID)) {
2491         VMW_DEBUG_USER("Invalid surface id.\n");
2492         return -EINVAL;
2493     }
2494     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
2495                 VMW_RES_DIRTY_NONE, user_surface_converter,
2496                 &cmd->sid, &srf);
2497     if (unlikely(ret != 0))
2498         return ret;
2499 
2500     res = vmw_context_cotable(ctx_node->ctx, vmw_view_cotables[view_type]);
2501     ret = vmw_cotable_notify(res, cmd->defined_id);
2502     if (unlikely(ret != 0))
2503         return ret;
2504 
2505     return vmw_view_add(sw_context->man, ctx_node->ctx, srf, view_type,
2506                 cmd->defined_id, header,
2507                 header->size + sizeof(*header),
2508                 &sw_context->staged_cmd_res);
2509 }
2510 
2511 /**
2512  * vmw_cmd_dx_set_so_targets - Validate SVGA_3D_CMD_DX_SET_SOTARGETS command.
2513  *
2514  * @dev_priv: Pointer to a device private struct.
2515  * @sw_context: The software context being used for this batch.
2516  * @header: Pointer to the command header in the command stream.
2517  */
2518 static int vmw_cmd_dx_set_so_targets(struct vmw_private *dev_priv,
2519                      struct vmw_sw_context *sw_context,
2520                      SVGA3dCmdHeader *header)
2521 {
2522     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2523     struct vmw_ctx_bindinfo_so_target binding;
2524     struct vmw_resource *res;
2525     struct {
2526         SVGA3dCmdHeader header;
2527         SVGA3dCmdDXSetSOTargets body;
2528         SVGA3dSoTarget targets[];
2529     } *cmd;
2530     int i, ret, num;
2531 
2532     if (!ctx_node)
2533         return -EINVAL;
2534 
2535     cmd = container_of(header, typeof(*cmd), header);
2536     num = (cmd->header.size - sizeof(cmd->body)) / sizeof(SVGA3dSoTarget);
2537 
2538     if (num > SVGA3D_DX_MAX_SOTARGETS) {
2539         VMW_DEBUG_USER("Invalid DX SO binding.\n");
2540         return -EINVAL;
2541     }
2542 
2543     for (i = 0; i < num; i++) {
2544         ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
2545                     VMW_RES_DIRTY_SET,
2546                     user_surface_converter,
2547                     &cmd->targets[i].sid, &res);
2548         if (unlikely(ret != 0))
2549             return ret;
2550 
2551         binding.bi.ctx = ctx_node->ctx;
2552         binding.bi.res = res;
2553         binding.bi.bt = vmw_ctx_binding_so_target;
2554         binding.offset = cmd->targets[i].offset;
2555         binding.size = cmd->targets[i].sizeInBytes;
2556         binding.slot = i;
2557 
2558         vmw_binding_add(ctx_node->staged, &binding.bi, 0, binding.slot);
2559     }
2560 
2561     return 0;
2562 }
2563 
2564 static int vmw_cmd_dx_so_define(struct vmw_private *dev_priv,
2565                 struct vmw_sw_context *sw_context,
2566                 SVGA3dCmdHeader *header)
2567 {
2568     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2569     struct vmw_resource *res;
2570     /*
2571      * This is based on the fact that all affected define commands have
2572      * the same initial command body layout.
2573      */
2574     struct {
2575         SVGA3dCmdHeader header;
2576         uint32 defined_id;
2577     } *cmd;
2578     enum vmw_so_type so_type;
2579     int ret;
2580 
2581     if (!ctx_node)
2582         return -EINVAL;
2583 
2584     so_type = vmw_so_cmd_to_type(header->id);
2585     res = vmw_context_cotable(ctx_node->ctx, vmw_so_cotables[so_type]);
2586     if (IS_ERR(res))
2587         return PTR_ERR(res);
2588     cmd = container_of(header, typeof(*cmd), header);
2589     ret = vmw_cotable_notify(res, cmd->defined_id);
2590 
2591     return ret;
2592 }
2593 
2594 /**
2595  * vmw_cmd_dx_check_subresource - Validate SVGA_3D_CMD_DX_[X]_SUBRESOURCE
2596  * command
2597  *
2598  * @dev_priv: Pointer to a device private struct.
2599  * @sw_context: The software context being used for this batch.
2600  * @header: Pointer to the command header in the command stream.
2601  */
2602 static int vmw_cmd_dx_check_subresource(struct vmw_private *dev_priv,
2603                     struct vmw_sw_context *sw_context,
2604                     SVGA3dCmdHeader *header)
2605 {
2606     struct {
2607         SVGA3dCmdHeader header;
2608         union {
2609             SVGA3dCmdDXReadbackSubResource r_body;
2610             SVGA3dCmdDXInvalidateSubResource i_body;
2611             SVGA3dCmdDXUpdateSubResource u_body;
2612             SVGA3dSurfaceId sid;
2613         };
2614     } *cmd;
2615 
2616     BUILD_BUG_ON(offsetof(typeof(*cmd), r_body.sid) !=
2617              offsetof(typeof(*cmd), sid));
2618     BUILD_BUG_ON(offsetof(typeof(*cmd), i_body.sid) !=
2619              offsetof(typeof(*cmd), sid));
2620     BUILD_BUG_ON(offsetof(typeof(*cmd), u_body.sid) !=
2621              offsetof(typeof(*cmd), sid));
2622 
2623     cmd = container_of(header, typeof(*cmd), header);
2624     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
2625                  VMW_RES_DIRTY_NONE, user_surface_converter,
2626                  &cmd->sid, NULL);
2627 }
2628 
2629 static int vmw_cmd_dx_cid_check(struct vmw_private *dev_priv,
2630                 struct vmw_sw_context *sw_context,
2631                 SVGA3dCmdHeader *header)
2632 {
2633     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2634 
2635     if (!ctx_node)
2636         return -EINVAL;
2637 
2638     return 0;
2639 }
2640 
2641 /**
2642  * vmw_cmd_dx_view_remove - validate a view remove command and schedule the view
2643  * resource for removal.
2644  *
2645  * @dev_priv: Pointer to a device private struct.
2646  * @sw_context: The software context being used for this batch.
2647  * @header: Pointer to the command header in the command stream.
2648  *
2649  * Check that the view exists, and if it was not created using this command
2650  * batch, conditionally make this command a NOP.
2651  */
2652 static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv,
2653                   struct vmw_sw_context *sw_context,
2654                   SVGA3dCmdHeader *header)
2655 {
2656     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2657     struct {
2658         SVGA3dCmdHeader header;
2659         union vmw_view_destroy body;
2660     } *cmd = container_of(header, typeof(*cmd), header);
2661     enum vmw_view_type view_type = vmw_view_cmd_to_type(header->id);
2662     struct vmw_resource *view;
2663     int ret;
2664 
2665     if (!ctx_node)
2666         return -EINVAL;
2667 
2668     ret = vmw_view_remove(sw_context->man, cmd->body.view_id, view_type,
2669                   &sw_context->staged_cmd_res, &view);
2670     if (ret || !view)
2671         return ret;
2672 
2673     /*
2674      * If the view wasn't created during this command batch, it might
2675      * have been removed due to a context swapout, so add a
2676      * relocation to conditionally make this command a NOP to avoid
2677      * device errors.
2678      */
2679     return vmw_resource_relocation_add(sw_context, view,
2680                        vmw_ptr_diff(sw_context->buf_start,
2681                             &cmd->header.id),
2682                        vmw_res_rel_cond_nop);
2683 }
2684 
2685 /**
2686  * vmw_cmd_dx_define_shader - Validate SVGA_3D_CMD_DX_DEFINE_SHADER command
2687  *
2688  * @dev_priv: Pointer to a device private struct.
2689  * @sw_context: The software context being used for this batch.
2690  * @header: Pointer to the command header in the command stream.
2691  */
2692 static int vmw_cmd_dx_define_shader(struct vmw_private *dev_priv,
2693                     struct vmw_sw_context *sw_context,
2694                     SVGA3dCmdHeader *header)
2695 {
2696     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2697     struct vmw_resource *res;
2698     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXDefineShader) =
2699         container_of(header, typeof(*cmd), header);
2700     int ret;
2701 
2702     if (!ctx_node)
2703         return -EINVAL;
2704 
2705     res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_DXSHADER);
2706     ret = vmw_cotable_notify(res, cmd->body.shaderId);
2707     if (ret)
2708         return ret;
2709 
2710     return vmw_dx_shader_add(sw_context->man, ctx_node->ctx,
2711                  cmd->body.shaderId, cmd->body.type,
2712                  &sw_context->staged_cmd_res);
2713 }
2714 
2715 /**
2716  * vmw_cmd_dx_destroy_shader - Validate SVGA_3D_CMD_DX_DESTROY_SHADER command
2717  *
2718  * @dev_priv: Pointer to a device private struct.
2719  * @sw_context: The software context being used for this batch.
2720  * @header: Pointer to the command header in the command stream.
2721  */
2722 static int vmw_cmd_dx_destroy_shader(struct vmw_private *dev_priv,
2723                      struct vmw_sw_context *sw_context,
2724                      SVGA3dCmdHeader *header)
2725 {
2726     struct vmw_ctx_validation_info *ctx_node = VMW_GET_CTX_NODE(sw_context);
2727     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXDestroyShader) =
2728         container_of(header, typeof(*cmd), header);
2729     int ret;
2730 
2731     if (!ctx_node)
2732         return -EINVAL;
2733 
2734     ret = vmw_shader_remove(sw_context->man, cmd->body.shaderId, 0,
2735                 &sw_context->staged_cmd_res);
2736 
2737     return ret;
2738 }
2739 
2740 /**
2741  * vmw_cmd_dx_bind_shader - Validate SVGA_3D_CMD_DX_BIND_SHADER command
2742  *
2743  * @dev_priv: Pointer to a device private struct.
2744  * @sw_context: The software context being used for this batch.
2745  * @header: Pointer to the command header in the command stream.
2746  */
2747 static int vmw_cmd_dx_bind_shader(struct vmw_private *dev_priv,
2748                   struct vmw_sw_context *sw_context,
2749                   SVGA3dCmdHeader *header)
2750 {
2751     struct vmw_resource *ctx;
2752     struct vmw_resource *res;
2753     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXBindShader) =
2754         container_of(header, typeof(*cmd), header);
2755     int ret;
2756 
2757     if (cmd->body.cid != SVGA3D_INVALID_ID) {
2758         ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_context,
2759                     VMW_RES_DIRTY_SET,
2760                     user_context_converter, &cmd->body.cid,
2761                     &ctx);
2762         if (ret)
2763             return ret;
2764     } else {
2765         struct vmw_ctx_validation_info *ctx_node =
2766             VMW_GET_CTX_NODE(sw_context);
2767 
2768         if (!ctx_node)
2769             return -EINVAL;
2770 
2771         ctx = ctx_node->ctx;
2772     }
2773 
2774     res = vmw_shader_lookup(vmw_context_res_man(ctx), cmd->body.shid, 0);
2775     if (IS_ERR(res)) {
2776         VMW_DEBUG_USER("Could not find shader to bind.\n");
2777         return PTR_ERR(res);
2778     }
2779 
2780     ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
2781                         VMW_RES_DIRTY_NONE);
2782     if (ret) {
2783         VMW_DEBUG_USER("Error creating resource validation node.\n");
2784         return ret;
2785     }
2786 
2787     return vmw_cmd_res_switch_backup(dev_priv, sw_context, res,
2788                      &cmd->body.mobid,
2789                      cmd->body.offsetInBytes);
2790 }
2791 
2792 /**
2793  * vmw_cmd_dx_genmips - Validate SVGA_3D_CMD_DX_GENMIPS command
2794  *
2795  * @dev_priv: Pointer to a device private struct.
2796  * @sw_context: The software context being used for this batch.
2797  * @header: Pointer to the command header in the command stream.
2798  */
2799 static int vmw_cmd_dx_genmips(struct vmw_private *dev_priv,
2800                   struct vmw_sw_context *sw_context,
2801                   SVGA3dCmdHeader *header)
2802 {
2803     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXGenMips) =
2804         container_of(header, typeof(*cmd), header);
2805     struct vmw_resource *view;
2806     struct vmw_res_cache_entry *rcache;
2807 
2808     view = vmw_view_id_val_add(sw_context, vmw_view_sr,
2809                    cmd->body.shaderResourceViewId);
2810     if (IS_ERR(view))
2811         return PTR_ERR(view);
2812 
2813     /*
2814      * Normally the shader-resource view is not gpu-dirtying, but for
2815      * this particular command it is...
2816      * So mark the last looked-up surface, which is the surface
2817      * the view points to, gpu-dirty.
2818      */
2819     rcache = &sw_context->res_cache[vmw_res_surface];
2820     vmw_validation_res_set_dirty(sw_context->ctx, rcache->private,
2821                      VMW_RES_DIRTY_SET);
2822     return 0;
2823 }
2824 
2825 /**
2826  * vmw_cmd_dx_transfer_from_buffer - Validate
2827  * SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER command
2828  *
2829  * @dev_priv: Pointer to a device private struct.
2830  * @sw_context: The software context being used for this batch.
2831  * @header: Pointer to the command header in the command stream.
2832  */
2833 static int vmw_cmd_dx_transfer_from_buffer(struct vmw_private *dev_priv,
2834                        struct vmw_sw_context *sw_context,
2835                        SVGA3dCmdHeader *header)
2836 {
2837     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdDXTransferFromBuffer) =
2838         container_of(header, typeof(*cmd), header);
2839     int ret;
2840 
2841     ret = vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
2842                 VMW_RES_DIRTY_NONE, user_surface_converter,
2843                 &cmd->body.srcSid, NULL);
2844     if (ret != 0)
2845         return ret;
2846 
2847     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
2848                  VMW_RES_DIRTY_SET, user_surface_converter,
2849                  &cmd->body.destSid, NULL);
2850 }
2851 
2852 /**
2853  * vmw_cmd_intra_surface_copy - Validate SVGA_3D_CMD_INTRA_SURFACE_COPY command
2854  *
2855  * @dev_priv: Pointer to a device private struct.
2856  * @sw_context: The software context being used for this batch.
2857  * @header: Pointer to the command header in the command stream.
2858  */
2859 static int vmw_cmd_intra_surface_copy(struct vmw_private *dev_priv,
2860                        struct vmw_sw_context *sw_context,
2861                        SVGA3dCmdHeader *header)
2862 {
2863     VMW_DECLARE_CMD_VAR(*cmd, SVGA3dCmdIntraSurfaceCopy) =
2864         container_of(header, typeof(*cmd), header);
2865 
2866     if (!(dev_priv->capabilities2 & SVGA_CAP2_INTRA_SURFACE_COPY))
2867         return -EINVAL;
2868 
2869     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
2870                  VMW_RES_DIRTY_SET, user_surface_converter,
2871                  &cmd->body.surface.sid, NULL);
2872 }
2873 
2874 static int vmw_cmd_sm5(struct vmw_private *dev_priv,
2875                struct vmw_sw_context *sw_context,
2876                SVGA3dCmdHeader *header)
2877 {
2878     if (!has_sm5_context(dev_priv))
2879         return -EINVAL;
2880 
2881     return 0;
2882 }
2883 
2884 static int vmw_cmd_sm5_view_define(struct vmw_private *dev_priv,
2885                    struct vmw_sw_context *sw_context,
2886                    SVGA3dCmdHeader *header)
2887 {
2888     if (!has_sm5_context(dev_priv))
2889         return -EINVAL;
2890 
2891     return vmw_cmd_dx_view_define(dev_priv, sw_context, header);
2892 }
2893 
2894 static int vmw_cmd_sm5_view_remove(struct vmw_private *dev_priv,
2895                    struct vmw_sw_context *sw_context,
2896                    SVGA3dCmdHeader *header)
2897 {
2898     if (!has_sm5_context(dev_priv))
2899         return -EINVAL;
2900 
2901     return vmw_cmd_dx_view_remove(dev_priv, sw_context, header);
2902 }
2903 
2904 static int vmw_cmd_clear_uav_uint(struct vmw_private *dev_priv,
2905                   struct vmw_sw_context *sw_context,
2906                   SVGA3dCmdHeader *header)
2907 {
2908     struct {
2909         SVGA3dCmdHeader header;
2910         SVGA3dCmdDXClearUAViewUint body;
2911     } *cmd = container_of(header, typeof(*cmd), header);
2912     struct vmw_resource *ret;
2913 
2914     if (!has_sm5_context(dev_priv))
2915         return -EINVAL;
2916 
2917     ret = vmw_view_id_val_add(sw_context, vmw_view_ua,
2918                   cmd->body.uaViewId);
2919 
2920     return PTR_ERR_OR_ZERO(ret);
2921 }
2922 
2923 static int vmw_cmd_clear_uav_float(struct vmw_private *dev_priv,
2924                    struct vmw_sw_context *sw_context,
2925                    SVGA3dCmdHeader *header)
2926 {
2927     struct {
2928         SVGA3dCmdHeader header;
2929         SVGA3dCmdDXClearUAViewFloat body;
2930     } *cmd = container_of(header, typeof(*cmd), header);
2931     struct vmw_resource *ret;
2932 
2933     if (!has_sm5_context(dev_priv))
2934         return -EINVAL;
2935 
2936     ret = vmw_view_id_val_add(sw_context, vmw_view_ua,
2937                   cmd->body.uaViewId);
2938 
2939     return PTR_ERR_OR_ZERO(ret);
2940 }
2941 
2942 static int vmw_cmd_set_uav(struct vmw_private *dev_priv,
2943                struct vmw_sw_context *sw_context,
2944                SVGA3dCmdHeader *header)
2945 {
2946     struct {
2947         SVGA3dCmdHeader header;
2948         SVGA3dCmdDXSetUAViews body;
2949     } *cmd = container_of(header, typeof(*cmd), header);
2950     u32 num_uav = (cmd->header.size - sizeof(cmd->body)) /
2951         sizeof(SVGA3dUAViewId);
2952     int ret;
2953 
2954     if (!has_sm5_context(dev_priv))
2955         return -EINVAL;
2956 
2957     if (num_uav > vmw_max_num_uavs(dev_priv)) {
2958         VMW_DEBUG_USER("Invalid UAV binding.\n");
2959         return -EINVAL;
2960     }
2961 
2962     ret = vmw_view_bindings_add(sw_context, vmw_view_ua,
2963                     vmw_ctx_binding_uav, 0, (void *)&cmd[1],
2964                     num_uav, 0);
2965     if (ret)
2966         return ret;
2967 
2968     vmw_binding_add_uav_index(sw_context->dx_ctx_node->staged, 0,
2969                      cmd->body.uavSpliceIndex);
2970 
2971     return ret;
2972 }
2973 
2974 static int vmw_cmd_set_cs_uav(struct vmw_private *dev_priv,
2975                   struct vmw_sw_context *sw_context,
2976                   SVGA3dCmdHeader *header)
2977 {
2978     struct {
2979         SVGA3dCmdHeader header;
2980         SVGA3dCmdDXSetCSUAViews body;
2981     } *cmd = container_of(header, typeof(*cmd), header);
2982     u32 num_uav = (cmd->header.size - sizeof(cmd->body)) /
2983         sizeof(SVGA3dUAViewId);
2984     int ret;
2985 
2986     if (!has_sm5_context(dev_priv))
2987         return -EINVAL;
2988 
2989     if (num_uav > vmw_max_num_uavs(dev_priv)) {
2990         VMW_DEBUG_USER("Invalid UAV binding.\n");
2991         return -EINVAL;
2992     }
2993 
2994     ret = vmw_view_bindings_add(sw_context, vmw_view_ua,
2995                     vmw_ctx_binding_cs_uav, 0, (void *)&cmd[1],
2996                     num_uav, 0);
2997     if (ret)
2998         return ret;
2999 
3000     vmw_binding_add_uav_index(sw_context->dx_ctx_node->staged, 1,
3001                   cmd->body.startIndex);
3002 
3003     return ret;
3004 }
3005 
3006 static int vmw_cmd_dx_define_streamoutput(struct vmw_private *dev_priv,
3007                       struct vmw_sw_context *sw_context,
3008                       SVGA3dCmdHeader *header)
3009 {
3010     struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
3011     struct vmw_resource *res;
3012     struct {
3013         SVGA3dCmdHeader header;
3014         SVGA3dCmdDXDefineStreamOutputWithMob body;
3015     } *cmd = container_of(header, typeof(*cmd), header);
3016     int ret;
3017 
3018     if (!has_sm5_context(dev_priv))
3019         return -EINVAL;
3020 
3021     if (!ctx_node) {
3022         DRM_ERROR("DX Context not set.\n");
3023         return -EINVAL;
3024     }
3025 
3026     res = vmw_context_cotable(ctx_node->ctx, SVGA_COTABLE_STREAMOUTPUT);
3027     ret = vmw_cotable_notify(res, cmd->body.soid);
3028     if (ret)
3029         return ret;
3030 
3031     return vmw_dx_streamoutput_add(sw_context->man, ctx_node->ctx,
3032                        cmd->body.soid,
3033                        &sw_context->staged_cmd_res);
3034 }
3035 
3036 static int vmw_cmd_dx_destroy_streamoutput(struct vmw_private *dev_priv,
3037                        struct vmw_sw_context *sw_context,
3038                        SVGA3dCmdHeader *header)
3039 {
3040     struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
3041     struct vmw_resource *res;
3042     struct {
3043         SVGA3dCmdHeader header;
3044         SVGA3dCmdDXDestroyStreamOutput body;
3045     } *cmd = container_of(header, typeof(*cmd), header);
3046 
3047     if (!ctx_node) {
3048         DRM_ERROR("DX Context not set.\n");
3049         return -EINVAL;
3050     }
3051 
3052     /*
3053      * When device does not support SM5 then streamoutput with mob command is
3054      * not available to user-space. Simply return in this case.
3055      */
3056     if (!has_sm5_context(dev_priv))
3057         return 0;
3058 
3059     /*
3060      * With SM5 capable device if lookup fails then user-space probably used
3061      * old streamoutput define command. Return without an error.
3062      */
3063     res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx),
3064                      cmd->body.soid);
3065     if (IS_ERR(res))
3066         return 0;
3067 
3068     return vmw_dx_streamoutput_remove(sw_context->man, cmd->body.soid,
3069                       &sw_context->staged_cmd_res);
3070 }
3071 
3072 static int vmw_cmd_dx_bind_streamoutput(struct vmw_private *dev_priv,
3073                     struct vmw_sw_context *sw_context,
3074                     SVGA3dCmdHeader *header)
3075 {
3076     struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
3077     struct vmw_resource *res;
3078     struct {
3079         SVGA3dCmdHeader header;
3080         SVGA3dCmdDXBindStreamOutput body;
3081     } *cmd = container_of(header, typeof(*cmd), header);
3082     int ret;
3083 
3084     if (!has_sm5_context(dev_priv))
3085         return -EINVAL;
3086 
3087     if (!ctx_node) {
3088         DRM_ERROR("DX Context not set.\n");
3089         return -EINVAL;
3090     }
3091 
3092     res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx),
3093                      cmd->body.soid);
3094     if (IS_ERR(res)) {
3095         DRM_ERROR("Could not find streamoutput to bind.\n");
3096         return PTR_ERR(res);
3097     }
3098 
3099     vmw_dx_streamoutput_set_size(res, cmd->body.sizeInBytes);
3100 
3101     ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
3102                         VMW_RES_DIRTY_NONE);
3103     if (ret) {
3104         DRM_ERROR("Error creating resource validation node.\n");
3105         return ret;
3106     }
3107 
3108     return vmw_cmd_res_switch_backup(dev_priv, sw_context, res,
3109                      &cmd->body.mobid,
3110                      cmd->body.offsetInBytes);
3111 }
3112 
3113 static int vmw_cmd_dx_set_streamoutput(struct vmw_private *dev_priv,
3114                        struct vmw_sw_context *sw_context,
3115                        SVGA3dCmdHeader *header)
3116 {
3117     struct vmw_ctx_validation_info *ctx_node = sw_context->dx_ctx_node;
3118     struct vmw_resource *res;
3119     struct vmw_ctx_bindinfo_so binding;
3120     struct {
3121         SVGA3dCmdHeader header;
3122         SVGA3dCmdDXSetStreamOutput body;
3123     } *cmd = container_of(header, typeof(*cmd), header);
3124     int ret;
3125 
3126     if (!ctx_node) {
3127         DRM_ERROR("DX Context not set.\n");
3128         return -EINVAL;
3129     }
3130 
3131     if (cmd->body.soid == SVGA3D_INVALID_ID)
3132         return 0;
3133 
3134     /*
3135      * When device does not support SM5 then streamoutput with mob command is
3136      * not available to user-space. Simply return in this case.
3137      */
3138     if (!has_sm5_context(dev_priv))
3139         return 0;
3140 
3141     /*
3142      * With SM5 capable device if lookup fails then user-space probably used
3143      * old streamoutput define command. Return without an error.
3144      */
3145     res = vmw_dx_streamoutput_lookup(vmw_context_res_man(ctx_node->ctx),
3146                      cmd->body.soid);
3147     if (IS_ERR(res)) {
3148         return 0;
3149     }
3150 
3151     ret = vmw_execbuf_res_noctx_val_add(sw_context, res,
3152                         VMW_RES_DIRTY_NONE);
3153     if (ret) {
3154         DRM_ERROR("Error creating resource validation node.\n");
3155         return ret;
3156     }
3157 
3158     binding.bi.ctx = ctx_node->ctx;
3159     binding.bi.res = res;
3160     binding.bi.bt = vmw_ctx_binding_so;
3161     binding.slot = 0; /* Only one SO set to context at a time. */
3162 
3163     vmw_binding_add(sw_context->dx_ctx_node->staged, &binding.bi, 0,
3164             binding.slot);
3165 
3166     return ret;
3167 }
3168 
3169 static int vmw_cmd_indexed_instanced_indirect(struct vmw_private *dev_priv,
3170                           struct vmw_sw_context *sw_context,
3171                           SVGA3dCmdHeader *header)
3172 {
3173     struct vmw_draw_indexed_instanced_indirect_cmd {
3174         SVGA3dCmdHeader header;
3175         SVGA3dCmdDXDrawIndexedInstancedIndirect body;
3176     } *cmd = container_of(header, typeof(*cmd), header);
3177 
3178     if (!has_sm5_context(dev_priv))
3179         return -EINVAL;
3180 
3181     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
3182                  VMW_RES_DIRTY_NONE, user_surface_converter,
3183                  &cmd->body.argsBufferSid, NULL);
3184 }
3185 
3186 static int vmw_cmd_instanced_indirect(struct vmw_private *dev_priv,
3187                       struct vmw_sw_context *sw_context,
3188                       SVGA3dCmdHeader *header)
3189 {
3190     struct vmw_draw_instanced_indirect_cmd {
3191         SVGA3dCmdHeader header;
3192         SVGA3dCmdDXDrawInstancedIndirect body;
3193     } *cmd = container_of(header, typeof(*cmd), header);
3194 
3195     if (!has_sm5_context(dev_priv))
3196         return -EINVAL;
3197 
3198     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
3199                  VMW_RES_DIRTY_NONE, user_surface_converter,
3200                  &cmd->body.argsBufferSid, NULL);
3201 }
3202 
3203 static int vmw_cmd_dispatch_indirect(struct vmw_private *dev_priv,
3204                      struct vmw_sw_context *sw_context,
3205                      SVGA3dCmdHeader *header)
3206 {
3207     struct vmw_dispatch_indirect_cmd {
3208         SVGA3dCmdHeader header;
3209         SVGA3dCmdDXDispatchIndirect body;
3210     } *cmd = container_of(header, typeof(*cmd), header);
3211 
3212     if (!has_sm5_context(dev_priv))
3213         return -EINVAL;
3214 
3215     return vmw_cmd_res_check(dev_priv, sw_context, vmw_res_surface,
3216                  VMW_RES_DIRTY_NONE, user_surface_converter,
3217                  &cmd->body.argsBufferSid, NULL);
3218 }
3219 
3220 static int vmw_cmd_check_not_3d(struct vmw_private *dev_priv,
3221                 struct vmw_sw_context *sw_context,
3222                 void *buf, uint32_t *size)
3223 {
3224     uint32_t size_remaining = *size;
3225     uint32_t cmd_id;
3226 
3227     cmd_id = ((uint32_t *)buf)[0];
3228     switch (cmd_id) {
3229     case SVGA_CMD_UPDATE:
3230         *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdUpdate);
3231         break;
3232     case SVGA_CMD_DEFINE_GMRFB:
3233         *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdDefineGMRFB);
3234         break;
3235     case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:
3236         *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
3237         break;
3238     case SVGA_CMD_BLIT_SCREEN_TO_GMRFB:
3239         *size = sizeof(uint32_t) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
3240         break;
3241     default:
3242         VMW_DEBUG_USER("Unsupported SVGA command: %u.\n", cmd_id);
3243         return -EINVAL;
3244     }
3245 
3246     if (*size > size_remaining) {
3247         VMW_DEBUG_USER("Invalid SVGA command (size mismatch): %u.\n",
3248                    cmd_id);
3249         return -EINVAL;
3250     }
3251 
3252     if (unlikely(!sw_context->kernel)) {
3253         VMW_DEBUG_USER("Kernel only SVGA command: %u.\n", cmd_id);
3254         return -EPERM;
3255     }
3256 
3257     if (cmd_id == SVGA_CMD_DEFINE_GMRFB)
3258         return vmw_cmd_check_define_gmrfb(dev_priv, sw_context, buf);
3259 
3260     return 0;
3261 }
3262 
3263 static const struct vmw_cmd_entry vmw_cmd_entries[SVGA_3D_CMD_MAX] = {
3264     VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE, &vmw_cmd_invalid,
3265             false, false, false),
3266     VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DESTROY, &vmw_cmd_invalid,
3267             false, false, false),
3268     VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_COPY, &vmw_cmd_surface_copy_check,
3269             true, false, false),
3270     VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_STRETCHBLT, &vmw_cmd_stretch_blt_check,
3271             true, false, false),
3272     VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DMA, &vmw_cmd_dma,
3273             true, false, false),
3274     VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DEFINE, &vmw_cmd_invalid,
3275             false, false, false),
3276     VMW_CMD_DEF(SVGA_3D_CMD_CONTEXT_DESTROY, &vmw_cmd_invalid,
3277             false, false, false),
3278     VMW_CMD_DEF(SVGA_3D_CMD_SETTRANSFORM, &vmw_cmd_cid_check,
3279             true, false, false),
3280     VMW_CMD_DEF(SVGA_3D_CMD_SETZRANGE, &vmw_cmd_cid_check,
3281             true, false, false),
3282     VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERSTATE, &vmw_cmd_cid_check,
3283             true, false, false),
3284     VMW_CMD_DEF(SVGA_3D_CMD_SETRENDERTARGET,
3285             &vmw_cmd_set_render_target_check, true, false, false),
3286     VMW_CMD_DEF(SVGA_3D_CMD_SETTEXTURESTATE, &vmw_cmd_tex_state,
3287             true, false, false),
3288     VMW_CMD_DEF(SVGA_3D_CMD_SETMATERIAL, &vmw_cmd_cid_check,
3289             true, false, false),
3290     VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTDATA, &vmw_cmd_cid_check,
3291             true, false, false),
3292     VMW_CMD_DEF(SVGA_3D_CMD_SETLIGHTENABLED, &vmw_cmd_cid_check,
3293             true, false, false),
3294     VMW_CMD_DEF(SVGA_3D_CMD_SETVIEWPORT, &vmw_cmd_cid_check,
3295             true, false, false),
3296     VMW_CMD_DEF(SVGA_3D_CMD_SETCLIPPLANE, &vmw_cmd_cid_check,
3297             true, false, false),
3298     VMW_CMD_DEF(SVGA_3D_CMD_CLEAR, &vmw_cmd_cid_check,
3299             true, false, false),
3300     VMW_CMD_DEF(SVGA_3D_CMD_PRESENT, &vmw_cmd_present_check,
3301             false, false, false),
3302     VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DEFINE, &vmw_cmd_shader_define,
3303             true, false, false),
3304     VMW_CMD_DEF(SVGA_3D_CMD_SHADER_DESTROY, &vmw_cmd_shader_destroy,
3305             true, false, false),
3306     VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER, &vmw_cmd_set_shader,
3307             true, false, false),
3308     VMW_CMD_DEF(SVGA_3D_CMD_SET_SHADER_CONST, &vmw_cmd_set_shader_const,
3309             true, false, false),
3310     VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw,
3311             true, false, false),
3312     VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check,
3313             true, false, false),
3314     VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_begin_query,
3315             true, false, false),
3316     VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_end_query,
3317             true, false, false),
3318     VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_wait_query,
3319             true, false, false),
3320     VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok,
3321             true, false, false),
3322     VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN,
3323             &vmw_cmd_blt_surf_screen_check, false, false, false),
3324     VMW_CMD_DEF(SVGA_3D_CMD_SURFACE_DEFINE_V2, &vmw_cmd_invalid,
3325             false, false, false),
3326     VMW_CMD_DEF(SVGA_3D_CMD_GENERATE_MIPMAPS, &vmw_cmd_invalid,
3327             false, false, false),
3328     VMW_CMD_DEF(SVGA_3D_CMD_ACTIVATE_SURFACE, &vmw_cmd_invalid,
3329             false, false, false),
3330     VMW_CMD_DEF(SVGA_3D_CMD_DEACTIVATE_SURFACE, &vmw_cmd_invalid,
3331             false, false, false),
3332     VMW_CMD_DEF(SVGA_3D_CMD_SCREEN_DMA, &vmw_cmd_invalid,
3333             false, false, false),
3334     VMW_CMD_DEF(SVGA_3D_CMD_DEAD1, &vmw_cmd_invalid,
3335             false, false, false),
3336     VMW_CMD_DEF(SVGA_3D_CMD_DEAD2, &vmw_cmd_invalid,
3337             false, false, false),
3338     VMW_CMD_DEF(SVGA_3D_CMD_DEAD12, &vmw_cmd_invalid, false, false, false),
3339     VMW_CMD_DEF(SVGA_3D_CMD_DEAD13, &vmw_cmd_invalid, false, false, false),
3340     VMW_CMD_DEF(SVGA_3D_CMD_DEAD14, &vmw_cmd_invalid, false, false, false),
3341     VMW_CMD_DEF(SVGA_3D_CMD_DEAD15, &vmw_cmd_invalid, false, false, false),
3342     VMW_CMD_DEF(SVGA_3D_CMD_DEAD16, &vmw_cmd_invalid, false, false, false),
3343     VMW_CMD_DEF(SVGA_3D_CMD_DEAD17, &vmw_cmd_invalid, false, false, false),
3344     VMW_CMD_DEF(SVGA_3D_CMD_SET_OTABLE_BASE, &vmw_cmd_invalid,
3345             false, false, true),
3346     VMW_CMD_DEF(SVGA_3D_CMD_READBACK_OTABLE, &vmw_cmd_invalid,
3347             false, false, true),
3348     VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_MOB, &vmw_cmd_invalid,
3349             false, false, true),
3350     VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_MOB, &vmw_cmd_invalid,
3351             false, false, true),
3352     VMW_CMD_DEF(SVGA_3D_CMD_REDEFINE_GB_MOB64, &vmw_cmd_invalid,
3353             false, false, true),
3354     VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_MOB_MAPPING, &vmw_cmd_invalid,
3355             false, false, true),
3356     VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SURFACE, &vmw_cmd_invalid,
3357             false, false, true),
3358     VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SURFACE, &vmw_cmd_invalid,
3359             false, false, true),
3360     VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_SURFACE, &vmw_cmd_bind_gb_surface,
3361             true, false, true),
3362     VMW_CMD_DEF(SVGA_3D_CMD_COND_BIND_GB_SURFACE, &vmw_cmd_invalid,
3363             false, false, true),
3364     VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_IMAGE, &vmw_cmd_update_gb_image,
3365             true, false, true),
3366     VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_SURFACE,
3367             &vmw_cmd_update_gb_surface, true, false, true),
3368     VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_IMAGE,
3369             &vmw_cmd_readback_gb_image, true, false, true),
3370     VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_SURFACE,
3371             &vmw_cmd_readback_gb_surface, true, false, true),
3372     VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_IMAGE,
3373             &vmw_cmd_invalidate_gb_image, true, false, true),
3374     VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_SURFACE,
3375             &vmw_cmd_invalidate_gb_surface, true, false, true),
3376     VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_CONTEXT, &vmw_cmd_invalid,
3377             false, false, true),
3378     VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_CONTEXT, &vmw_cmd_invalid,
3379             false, false, true),
3380     VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_CONTEXT, &vmw_cmd_invalid,
3381             false, false, true),
3382     VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_CONTEXT, &vmw_cmd_invalid,
3383             false, false, true),
3384     VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_CONTEXT, &vmw_cmd_invalid,
3385             false, false, true),
3386     VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SHADER, &vmw_cmd_invalid,
3387             false, false, true),
3388     VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_SHADER, &vmw_cmd_bind_gb_shader,
3389             true, false, true),
3390     VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SHADER, &vmw_cmd_invalid,
3391             false, false, true),
3392     VMW_CMD_DEF(SVGA_3D_CMD_SET_OTABLE_BASE64, &vmw_cmd_invalid,
3393             false, false, false),
3394     VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_GB_QUERY, &vmw_cmd_begin_gb_query,
3395             true, false, true),
3396     VMW_CMD_DEF(SVGA_3D_CMD_END_GB_QUERY, &vmw_cmd_end_gb_query,
3397             true, false, true),
3398     VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_GB_QUERY, &vmw_cmd_wait_gb_query,
3399             true, false, true),
3400     VMW_CMD_DEF(SVGA_3D_CMD_NOP, &vmw_cmd_ok,
3401             true, false, true),
3402     VMW_CMD_DEF(SVGA_3D_CMD_NOP_ERROR, &vmw_cmd_ok,
3403             true, false, true),
3404     VMW_CMD_DEF(SVGA_3D_CMD_ENABLE_GART, &vmw_cmd_invalid,
3405             false, false, true),
3406     VMW_CMD_DEF(SVGA_3D_CMD_DISABLE_GART, &vmw_cmd_invalid,
3407             false, false, true),
3408     VMW_CMD_DEF(SVGA_3D_CMD_MAP_MOB_INTO_GART, &vmw_cmd_invalid,
3409             false, false, true),
3410     VMW_CMD_DEF(SVGA_3D_CMD_UNMAP_GART_RANGE, &vmw_cmd_invalid,
3411             false, false, true),
3412     VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SCREENTARGET, &vmw_cmd_invalid,
3413             false, false, true),
3414     VMW_CMD_DEF(SVGA_3D_CMD_DESTROY_GB_SCREENTARGET, &vmw_cmd_invalid,
3415             false, false, true),
3416     VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_SCREENTARGET, &vmw_cmd_invalid,
3417             false, false, true),
3418     VMW_CMD_DEF(SVGA_3D_CMD_UPDATE_GB_SCREENTARGET, &vmw_cmd_invalid,
3419             false, false, true),
3420     VMW_CMD_DEF(SVGA_3D_CMD_READBACK_GB_IMAGE_PARTIAL, &vmw_cmd_invalid,
3421             false, false, true),
3422     VMW_CMD_DEF(SVGA_3D_CMD_INVALIDATE_GB_IMAGE_PARTIAL, &vmw_cmd_invalid,
3423             false, false, true),
3424     VMW_CMD_DEF(SVGA_3D_CMD_SET_GB_SHADERCONSTS_INLINE, &vmw_cmd_cid_check,
3425             true, false, true),
3426     VMW_CMD_DEF(SVGA_3D_CMD_GB_SCREEN_DMA, &vmw_cmd_invalid,
3427             false, false, true),
3428     VMW_CMD_DEF(SVGA_3D_CMD_BIND_GB_SURFACE_WITH_PITCH, &vmw_cmd_invalid,
3429             false, false, true),
3430     VMW_CMD_DEF(SVGA_3D_CMD_GB_MOB_FENCE, &vmw_cmd_invalid,
3431             false, false, true),
3432     VMW_CMD_DEF(SVGA_3D_CMD_DEFINE_GB_SURFACE_V2, &vmw_cmd_invalid,
3433             false, false, true),
3434 
3435     /* SM commands */
3436     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_CONTEXT, &vmw_cmd_invalid,
3437             false, false, true),
3438     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_CONTEXT, &vmw_cmd_invalid,
3439             false, false, true),
3440     VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_CONTEXT, &vmw_cmd_invalid,
3441             false, false, true),
3442     VMW_CMD_DEF(SVGA_3D_CMD_DX_READBACK_CONTEXT, &vmw_cmd_invalid,
3443             false, false, true),
3444     VMW_CMD_DEF(SVGA_3D_CMD_DX_INVALIDATE_CONTEXT, &vmw_cmd_invalid,
3445             false, false, true),
3446     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SINGLE_CONSTANT_BUFFER,
3447             &vmw_cmd_dx_set_single_constant_buffer, true, false, true),
3448     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SHADER_RESOURCES,
3449             &vmw_cmd_dx_set_shader_res, true, false, true),
3450     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SHADER, &vmw_cmd_dx_set_shader,
3451             true, false, true),
3452     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SAMPLERS, &vmw_cmd_dx_cid_check,
3453             true, false, true),
3454     VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW, &vmw_cmd_dx_cid_check,
3455             true, false, true),
3456     VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INDEXED, &vmw_cmd_dx_cid_check,
3457             true, false, true),
3458     VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INSTANCED, &vmw_cmd_dx_cid_check,
3459             true, false, true),
3460     VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED,
3461             &vmw_cmd_dx_cid_check, true, false, true),
3462     VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_AUTO, &vmw_cmd_dx_cid_check,
3463             true, false, true),
3464     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_VERTEX_BUFFERS,
3465             &vmw_cmd_dx_set_vertex_buffers, true, false, true),
3466     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_INDEX_BUFFER,
3467             &vmw_cmd_dx_set_index_buffer, true, false, true),
3468     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_RENDERTARGETS,
3469             &vmw_cmd_dx_set_rendertargets, true, false, true),
3470     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_BLEND_STATE, &vmw_cmd_dx_cid_check,
3471             true, false, true),
3472     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_DEPTHSTENCIL_STATE,
3473             &vmw_cmd_dx_cid_check, true, false, true),
3474     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_RASTERIZER_STATE,
3475             &vmw_cmd_dx_cid_check, true, false, true),
3476     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_QUERY, &vmw_cmd_dx_define_query,
3477             true, false, true),
3478     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_QUERY, &vmw_cmd_dx_cid_check,
3479             true, false, true),
3480     VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_QUERY, &vmw_cmd_dx_bind_query,
3481             true, false, true),
3482     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_QUERY_OFFSET,
3483             &vmw_cmd_dx_cid_check, true, false, true),
3484     VMW_CMD_DEF(SVGA_3D_CMD_DX_BEGIN_QUERY, &vmw_cmd_dx_cid_check,
3485             true, false, true),
3486     VMW_CMD_DEF(SVGA_3D_CMD_DX_END_QUERY, &vmw_cmd_dx_cid_check,
3487             true, false, true),
3488     VMW_CMD_DEF(SVGA_3D_CMD_DX_READBACK_QUERY, &vmw_cmd_invalid,
3489             true, false, true),
3490     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PREDICATION, &vmw_cmd_dx_cid_check,
3491             true, false, true),
3492     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_VIEWPORTS, &vmw_cmd_dx_cid_check,
3493             true, false, true),
3494     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SCISSORRECTS, &vmw_cmd_dx_cid_check,
3495             true, false, true),
3496     VMW_CMD_DEF(SVGA_3D_CMD_DX_CLEAR_RENDERTARGET_VIEW,
3497             &vmw_cmd_dx_clear_rendertarget_view, true, false, true),
3498     VMW_CMD_DEF(SVGA_3D_CMD_DX_CLEAR_DEPTHSTENCIL_VIEW,
3499             &vmw_cmd_dx_clear_depthstencil_view, true, false, true),
3500     VMW_CMD_DEF(SVGA_3D_CMD_DX_PRED_COPY, &vmw_cmd_invalid,
3501             true, false, true),
3502     VMW_CMD_DEF(SVGA_3D_CMD_DX_GENMIPS, &vmw_cmd_dx_genmips,
3503             true, false, true),
3504     VMW_CMD_DEF(SVGA_3D_CMD_DX_UPDATE_SUBRESOURCE,
3505             &vmw_cmd_dx_check_subresource, true, false, true),
3506     VMW_CMD_DEF(SVGA_3D_CMD_DX_READBACK_SUBRESOURCE,
3507             &vmw_cmd_dx_check_subresource, true, false, true),
3508     VMW_CMD_DEF(SVGA_3D_CMD_DX_INVALIDATE_SUBRESOURCE,
3509             &vmw_cmd_dx_check_subresource, true, false, true),
3510     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_SHADERRESOURCE_VIEW,
3511             &vmw_cmd_dx_view_define, true, false, true),
3512     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_SHADERRESOURCE_VIEW,
3513             &vmw_cmd_dx_view_remove, true, false, true),
3514     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_RENDERTARGET_VIEW,
3515             &vmw_cmd_dx_view_define, true, false, true),
3516     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_RENDERTARGET_VIEW,
3517             &vmw_cmd_dx_view_remove, true, false, true),
3518     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW,
3519             &vmw_cmd_dx_view_define, true, false, true),
3520     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_VIEW,
3521             &vmw_cmd_dx_view_remove, true, false, true),
3522     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_ELEMENTLAYOUT,
3523             &vmw_cmd_dx_so_define, true, false, true),
3524     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_ELEMENTLAYOUT,
3525             &vmw_cmd_dx_cid_check, true, false, true),
3526     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_BLEND_STATE,
3527             &vmw_cmd_dx_so_define, true, false, true),
3528     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_BLEND_STATE,
3529             &vmw_cmd_dx_cid_check, true, false, true),
3530     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_STATE,
3531             &vmw_cmd_dx_so_define, true, false, true),
3532     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_DEPTHSTENCIL_STATE,
3533             &vmw_cmd_dx_cid_check, true, false, true),
3534     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_RASTERIZER_STATE,
3535             &vmw_cmd_dx_so_define, true, false, true),
3536     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_RASTERIZER_STATE,
3537             &vmw_cmd_dx_cid_check, true, false, true),
3538     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_SAMPLER_STATE,
3539             &vmw_cmd_dx_so_define, true, false, true),
3540     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_SAMPLER_STATE,
3541             &vmw_cmd_dx_cid_check, true, false, true),
3542     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_SHADER,
3543             &vmw_cmd_dx_define_shader, true, false, true),
3544     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_SHADER,
3545             &vmw_cmd_dx_destroy_shader, true, false, true),
3546     VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_SHADER,
3547             &vmw_cmd_dx_bind_shader, true, false, true),
3548     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT,
3549             &vmw_cmd_dx_so_define, true, false, true),
3550     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_STREAMOUTPUT,
3551             &vmw_cmd_dx_destroy_streamoutput, true, false, true),
3552     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_STREAMOUTPUT,
3553             &vmw_cmd_dx_set_streamoutput, true, false, true),
3554     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_SOTARGETS,
3555             &vmw_cmd_dx_set_so_targets, true, false, true),
3556     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_INPUT_LAYOUT,
3557             &vmw_cmd_dx_cid_check, true, false, true),
3558     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_TOPOLOGY,
3559             &vmw_cmd_dx_cid_check, true, false, true),
3560     VMW_CMD_DEF(SVGA_3D_CMD_DX_BUFFER_COPY,
3561             &vmw_cmd_buffer_copy_check, true, false, true),
3562     VMW_CMD_DEF(SVGA_3D_CMD_DX_PRED_COPY_REGION,
3563             &vmw_cmd_pred_copy_check, true, false, true),
3564     VMW_CMD_DEF(SVGA_3D_CMD_DX_TRANSFER_FROM_BUFFER,
3565             &vmw_cmd_dx_transfer_from_buffer,
3566             true, false, true),
3567     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_VS_CONSTANT_BUFFER_OFFSET,
3568             &vmw_cmd_dx_set_constant_buffer_offset,
3569             true, false, true),
3570     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_PS_CONSTANT_BUFFER_OFFSET,
3571             &vmw_cmd_dx_set_constant_buffer_offset,
3572             true, false, true),
3573     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_GS_CONSTANT_BUFFER_OFFSET,
3574             &vmw_cmd_dx_set_constant_buffer_offset,
3575             true, false, true),
3576     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_HS_CONSTANT_BUFFER_OFFSET,
3577             &vmw_cmd_dx_set_constant_buffer_offset,
3578             true, false, true),
3579     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_DS_CONSTANT_BUFFER_OFFSET,
3580             &vmw_cmd_dx_set_constant_buffer_offset,
3581             true, false, true),
3582     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_CS_CONSTANT_BUFFER_OFFSET,
3583             &vmw_cmd_dx_set_constant_buffer_offset,
3584             true, false, true),
3585     VMW_CMD_DEF(SVGA_3D_CMD_INTRA_SURFACE_COPY, &vmw_cmd_intra_surface_copy,
3586             true, false, true),
3587 
3588     /*
3589      * SM5 commands
3590      */
3591     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_UA_VIEW, &vmw_cmd_sm5_view_define,
3592             true, false, true),
3593     VMW_CMD_DEF(SVGA_3D_CMD_DX_DESTROY_UA_VIEW, &vmw_cmd_sm5_view_remove,
3594             true, false, true),
3595     VMW_CMD_DEF(SVGA_3D_CMD_DX_CLEAR_UA_VIEW_UINT, &vmw_cmd_clear_uav_uint,
3596             true, false, true),
3597     VMW_CMD_DEF(SVGA_3D_CMD_DX_CLEAR_UA_VIEW_FLOAT,
3598             &vmw_cmd_clear_uav_float, true, false, true),
3599     VMW_CMD_DEF(SVGA_3D_CMD_DX_COPY_STRUCTURE_COUNT, &vmw_cmd_invalid, true,
3600             false, true),
3601     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_UA_VIEWS, &vmw_cmd_set_uav, true, false,
3602             true),
3603     VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INDEXED_INSTANCED_INDIRECT,
3604             &vmw_cmd_indexed_instanced_indirect, true, false, true),
3605     VMW_CMD_DEF(SVGA_3D_CMD_DX_DRAW_INSTANCED_INDIRECT,
3606             &vmw_cmd_instanced_indirect, true, false, true),
3607     VMW_CMD_DEF(SVGA_3D_CMD_DX_DISPATCH, &vmw_cmd_sm5, true, false, true),
3608     VMW_CMD_DEF(SVGA_3D_CMD_DX_DISPATCH_INDIRECT,
3609             &vmw_cmd_dispatch_indirect, true, false, true),
3610     VMW_CMD_DEF(SVGA_3D_CMD_DX_SET_CS_UA_VIEWS, &vmw_cmd_set_cs_uav, true,
3611             false, true),
3612     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_DEPTHSTENCIL_VIEW_V2,
3613             &vmw_cmd_sm5_view_define, true, false, true),
3614     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_STREAMOUTPUT_WITH_MOB,
3615             &vmw_cmd_dx_define_streamoutput, true, false, true),
3616     VMW_CMD_DEF(SVGA_3D_CMD_DX_BIND_STREAMOUTPUT,
3617             &vmw_cmd_dx_bind_streamoutput, true, false, true),
3618     VMW_CMD_DEF(SVGA_3D_CMD_DX_DEFINE_RASTERIZER_STATE_V2,
3619             &vmw_cmd_dx_so_define, true, false, true),
3620 };
3621 
3622 bool vmw_cmd_describe(const void *buf, u32 *size, char const **cmd)
3623 {
3624     u32 cmd_id = ((u32 *) buf)[0];
3625 
3626     if (cmd_id >= SVGA_CMD_MAX) {
3627         SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf;
3628         const struct vmw_cmd_entry *entry;
3629 
3630         *size = header->size + sizeof(SVGA3dCmdHeader);
3631         cmd_id = header->id;
3632         if (cmd_id >= SVGA_3D_CMD_MAX)
3633             return false;
3634 
3635         cmd_id -= SVGA_3D_CMD_BASE;
3636         entry = &vmw_cmd_entries[cmd_id];
3637         *cmd = entry->cmd_name;
3638         return true;
3639     }
3640 
3641     switch (cmd_id) {
3642     case SVGA_CMD_UPDATE:
3643         *cmd = "SVGA_CMD_UPDATE";
3644         *size = sizeof(u32) + sizeof(SVGAFifoCmdUpdate);
3645         break;
3646     case SVGA_CMD_DEFINE_GMRFB:
3647         *cmd = "SVGA_CMD_DEFINE_GMRFB";
3648         *size = sizeof(u32) + sizeof(SVGAFifoCmdDefineGMRFB);
3649         break;
3650     case SVGA_CMD_BLIT_GMRFB_TO_SCREEN:
3651         *cmd = "SVGA_CMD_BLIT_GMRFB_TO_SCREEN";
3652         *size = sizeof(u32) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
3653         break;
3654     case SVGA_CMD_BLIT_SCREEN_TO_GMRFB:
3655         *cmd = "SVGA_CMD_BLIT_SCREEN_TO_GMRFB";
3656         *size = sizeof(u32) + sizeof(SVGAFifoCmdBlitGMRFBToScreen);
3657         break;
3658     default:
3659         *cmd = "UNKNOWN";
3660         *size = 0;
3661         return false;
3662     }
3663 
3664     return true;
3665 }
3666 
3667 static int vmw_cmd_check(struct vmw_private *dev_priv,
3668              struct vmw_sw_context *sw_context, void *buf,
3669              uint32_t *size)
3670 {
3671     uint32_t cmd_id;
3672     uint32_t size_remaining = *size;
3673     SVGA3dCmdHeader *header = (SVGA3dCmdHeader *) buf;
3674     int ret;
3675     const struct vmw_cmd_entry *entry;
3676     bool gb = dev_priv->capabilities & SVGA_CAP_GBOBJECTS;
3677 
3678     cmd_id = ((uint32_t *)buf)[0];
3679     /* Handle any none 3D commands */
3680     if (unlikely(cmd_id < SVGA_CMD_MAX))
3681         return vmw_cmd_check_not_3d(dev_priv, sw_context, buf, size);
3682 
3683 
3684     cmd_id = header->id;
3685     *size = header->size + sizeof(SVGA3dCmdHeader);
3686 
3687     cmd_id -= SVGA_3D_CMD_BASE;
3688     if (unlikely(*size > size_remaining))
3689         goto out_invalid;
3690 
3691     if (unlikely(cmd_id >= SVGA_3D_CMD_MAX - SVGA_3D_CMD_BASE))
3692         goto out_invalid;
3693 
3694     entry = &vmw_cmd_entries[cmd_id];
3695     if (unlikely(!entry->func))
3696         goto out_invalid;
3697 
3698     if (unlikely(!entry->user_allow && !sw_context->kernel))
3699         goto out_privileged;
3700 
3701     if (unlikely(entry->gb_disable && gb))
3702         goto out_old;
3703 
3704     if (unlikely(entry->gb_enable && !gb))
3705         goto out_new;
3706 
3707     ret = entry->func(dev_priv, sw_context, header);
3708     if (unlikely(ret != 0)) {
3709         VMW_DEBUG_USER("SVGA3D command: %d failed with error %d\n",
3710                    cmd_id + SVGA_3D_CMD_BASE, ret);
3711         return ret;
3712     }
3713 
3714     return 0;
3715 out_invalid:
3716     VMW_DEBUG_USER("Invalid SVGA3D command: %d\n",
3717                cmd_id + SVGA_3D_CMD_BASE);
3718     return -EINVAL;
3719 out_privileged:
3720     VMW_DEBUG_USER("Privileged SVGA3D command: %d\n",
3721                cmd_id + SVGA_3D_CMD_BASE);
3722     return -EPERM;
3723 out_old:
3724     VMW_DEBUG_USER("Deprecated (disallowed) SVGA3D command: %d\n",
3725                cmd_id + SVGA_3D_CMD_BASE);
3726     return -EINVAL;
3727 out_new:
3728     VMW_DEBUG_USER("SVGA3D command: %d not supported by virtual device.\n",
3729                cmd_id + SVGA_3D_CMD_BASE);
3730     return -EINVAL;
3731 }
3732 
3733 static int vmw_cmd_check_all(struct vmw_private *dev_priv,
3734                  struct vmw_sw_context *sw_context, void *buf,
3735                  uint32_t size)
3736 {
3737     int32_t cur_size = size;
3738     int ret;
3739 
3740     sw_context->buf_start = buf;
3741 
3742     while (cur_size > 0) {
3743         size = cur_size;
3744         ret = vmw_cmd_check(dev_priv, sw_context, buf, &size);
3745         if (unlikely(ret != 0))
3746             return ret;
3747         buf = (void *)((unsigned long) buf + size);
3748         cur_size -= size;
3749     }
3750 
3751     if (unlikely(cur_size != 0)) {
3752         VMW_DEBUG_USER("Command verifier out of sync.\n");
3753         return -EINVAL;
3754     }
3755 
3756     return 0;
3757 }
3758 
3759 static void vmw_free_relocations(struct vmw_sw_context *sw_context)
3760 {
3761     /* Memory is validation context memory, so no need to free it */
3762     INIT_LIST_HEAD(&sw_context->bo_relocations);
3763 }
3764 
3765 static void vmw_apply_relocations(struct vmw_sw_context *sw_context)
3766 {
3767     struct vmw_relocation *reloc;
3768     struct ttm_buffer_object *bo;
3769 
3770     list_for_each_entry(reloc, &sw_context->bo_relocations, head) {
3771         bo = &reloc->vbo->base;
3772         switch (bo->resource->mem_type) {
3773         case TTM_PL_VRAM:
3774             reloc->location->offset += bo->resource->start << PAGE_SHIFT;
3775             reloc->location->gmrId = SVGA_GMR_FRAMEBUFFER;
3776             break;
3777         case VMW_PL_GMR:
3778             reloc->location->gmrId = bo->resource->start;
3779             break;
3780         case VMW_PL_MOB:
3781             *reloc->mob_loc = bo->resource->start;
3782             break;
3783         default:
3784             BUG();
3785         }
3786     }
3787     vmw_free_relocations(sw_context);
3788 }
3789 
3790 static int vmw_resize_cmd_bounce(struct vmw_sw_context *sw_context,
3791                  uint32_t size)
3792 {
3793     if (likely(sw_context->cmd_bounce_size >= size))
3794         return 0;
3795 
3796     if (sw_context->cmd_bounce_size == 0)
3797         sw_context->cmd_bounce_size = VMWGFX_CMD_BOUNCE_INIT_SIZE;
3798 
3799     while (sw_context->cmd_bounce_size < size) {
3800         sw_context->cmd_bounce_size =
3801             PAGE_ALIGN(sw_context->cmd_bounce_size +
3802                    (sw_context->cmd_bounce_size >> 1));
3803     }
3804 
3805     vfree(sw_context->cmd_bounce);
3806     sw_context->cmd_bounce = vmalloc(sw_context->cmd_bounce_size);
3807 
3808     if (sw_context->cmd_bounce == NULL) {
3809         VMW_DEBUG_USER("Failed to allocate command bounce buffer.\n");
3810         sw_context->cmd_bounce_size = 0;
3811         return -ENOMEM;
3812     }
3813 
3814     return 0;
3815 }
3816 
3817 /*
3818  * vmw_execbuf_fence_commands - create and submit a command stream fence
3819  *
3820  * Creates a fence object and submits a command stream marker.
3821  * If this fails for some reason, We sync the fifo and return NULL.
3822  * It is then safe to fence buffers with a NULL pointer.
3823  *
3824  * If @p_handle is not NULL @file_priv must also not be NULL. Creates a
3825  * userspace handle if @p_handle is not NULL, otherwise not.
3826  */
3827 
3828 int vmw_execbuf_fence_commands(struct drm_file *file_priv,
3829                    struct vmw_private *dev_priv,
3830                    struct vmw_fence_obj **p_fence,
3831                    uint32_t *p_handle)
3832 {
3833     uint32_t sequence;
3834     int ret;
3835     bool synced = false;
3836 
3837     /* p_handle implies file_priv. */
3838     BUG_ON(p_handle != NULL && file_priv == NULL);
3839 
3840     ret = vmw_cmd_send_fence(dev_priv, &sequence);
3841     if (unlikely(ret != 0)) {
3842         VMW_DEBUG_USER("Fence submission error. Syncing.\n");
3843         synced = true;
3844     }
3845 
3846     if (p_handle != NULL)
3847         ret = vmw_user_fence_create(file_priv, dev_priv->fman,
3848                         sequence, p_fence, p_handle);
3849     else
3850         ret = vmw_fence_create(dev_priv->fman, sequence, p_fence);
3851 
3852     if (unlikely(ret != 0 && !synced)) {
3853         (void) vmw_fallback_wait(dev_priv, false, false, sequence,
3854                      false, VMW_FENCE_WAIT_TIMEOUT);
3855         *p_fence = NULL;
3856     }
3857 
3858     return ret;
3859 }
3860 
3861 /**
3862  * vmw_execbuf_copy_fence_user - copy fence object information to user-space.
3863  *
3864  * @dev_priv: Pointer to a vmw_private struct.
3865  * @vmw_fp: Pointer to the struct vmw_fpriv representing the calling file.
3866  * @ret: Return value from fence object creation.
3867  * @user_fence_rep: User space address of a struct drm_vmw_fence_rep to which
3868  * the information should be copied.
3869  * @fence: Pointer to the fenc object.
3870  * @fence_handle: User-space fence handle.
3871  * @out_fence_fd: exported file descriptor for the fence.  -1 if not used
3872  * @sync_file:  Only used to clean up in case of an error in this function.
3873  *
3874  * This function copies fence information to user-space. If copying fails, the
3875  * user-space struct drm_vmw_fence_rep::error member is hopefully left
3876  * untouched, and if it's preloaded with an -EFAULT by user-space, the error
3877  * will hopefully be detected.
3878  *
3879  * Also if copying fails, user-space will be unable to signal the fence object
3880  * so we wait for it immediately, and then unreference the user-space reference.
3881  */
3882 int
3883 vmw_execbuf_copy_fence_user(struct vmw_private *dev_priv,
3884                 struct vmw_fpriv *vmw_fp, int ret,
3885                 struct drm_vmw_fence_rep __user *user_fence_rep,
3886                 struct vmw_fence_obj *fence, uint32_t fence_handle,
3887                 int32_t out_fence_fd)
3888 {
3889     struct drm_vmw_fence_rep fence_rep;
3890 
3891     if (user_fence_rep == NULL)
3892         return 0;
3893 
3894     memset(&fence_rep, 0, sizeof(fence_rep));
3895 
3896     fence_rep.error = ret;
3897     fence_rep.fd = out_fence_fd;
3898     if (ret == 0) {
3899         BUG_ON(fence == NULL);
3900 
3901         fence_rep.handle = fence_handle;
3902         fence_rep.seqno = fence->base.seqno;
3903         vmw_update_seqno(dev_priv);
3904         fence_rep.passed_seqno = dev_priv->last_read_seqno;
3905     }
3906 
3907     /*
3908      * copy_to_user errors will be detected by user space not seeing
3909      * fence_rep::error filled in. Typically user-space would have pre-set
3910      * that member to -EFAULT.
3911      */
3912     ret = copy_to_user(user_fence_rep, &fence_rep,
3913                sizeof(fence_rep));
3914 
3915     /*
3916      * User-space lost the fence object. We need to sync and unreference the
3917      * handle.
3918      */
3919     if (unlikely(ret != 0) && (fence_rep.error == 0)) {
3920         ttm_ref_object_base_unref(vmw_fp->tfile, fence_handle);
3921         VMW_DEBUG_USER("Fence copy error. Syncing.\n");
3922         (void) vmw_fence_obj_wait(fence, false, false,
3923                       VMW_FENCE_WAIT_TIMEOUT);
3924     }
3925 
3926     return ret ? -EFAULT : 0;
3927 }
3928 
3929 /**
3930  * vmw_execbuf_submit_fifo - Patch a command batch and submit it using the fifo.
3931  *
3932  * @dev_priv: Pointer to a device private structure.
3933  * @kernel_commands: Pointer to the unpatched command batch.
3934  * @command_size: Size of the unpatched command batch.
3935  * @sw_context: Structure holding the relocation lists.
3936  *
3937  * Side effects: If this function returns 0, then the command batch pointed to
3938  * by @kernel_commands will have been modified.
3939  */
3940 static int vmw_execbuf_submit_fifo(struct vmw_private *dev_priv,
3941                    void *kernel_commands, u32 command_size,
3942                    struct vmw_sw_context *sw_context)
3943 {
3944     void *cmd;
3945 
3946     if (sw_context->dx_ctx_node)
3947         cmd = VMW_CMD_CTX_RESERVE(dev_priv, command_size,
3948                       sw_context->dx_ctx_node->ctx->id);
3949     else
3950         cmd = VMW_CMD_RESERVE(dev_priv, command_size);
3951 
3952     if (!cmd)
3953         return -ENOMEM;
3954 
3955     vmw_apply_relocations(sw_context);
3956     memcpy(cmd, kernel_commands, command_size);
3957     vmw_resource_relocations_apply(cmd, &sw_context->res_relocations);
3958     vmw_resource_relocations_free(&sw_context->res_relocations);
3959     vmw_cmd_commit(dev_priv, command_size);
3960 
3961     return 0;
3962 }
3963 
3964 /**
3965  * vmw_execbuf_submit_cmdbuf - Patch a command batch and submit it using the
3966  * command buffer manager.
3967  *
3968  * @dev_priv: Pointer to a device private structure.
3969  * @header: Opaque handle to the command buffer allocation.
3970  * @command_size: Size of the unpatched command batch.
3971  * @sw_context: Structure holding the relocation lists.
3972  *
3973  * Side effects: If this function returns 0, then the command buffer represented
3974  * by @header will have been modified.
3975  */
3976 static int vmw_execbuf_submit_cmdbuf(struct vmw_private *dev_priv,
3977                      struct vmw_cmdbuf_header *header,
3978                      u32 command_size,
3979                      struct vmw_sw_context *sw_context)
3980 {
3981     u32 id = ((sw_context->dx_ctx_node) ? sw_context->dx_ctx_node->ctx->id :
3982           SVGA3D_INVALID_ID);
3983     void *cmd = vmw_cmdbuf_reserve(dev_priv->cman, command_size, id, false,
3984                        header);
3985 
3986     vmw_apply_relocations(sw_context);
3987     vmw_resource_relocations_apply(cmd, &sw_context->res_relocations);
3988     vmw_resource_relocations_free(&sw_context->res_relocations);
3989     vmw_cmdbuf_commit(dev_priv->cman, command_size, header, false);
3990 
3991     return 0;
3992 }
3993 
3994 /**
3995  * vmw_execbuf_cmdbuf - Prepare, if possible, a user-space command batch for
3996  * submission using a command buffer.
3997  *
3998  * @dev_priv: Pointer to a device private structure.
3999  * @user_commands: User-space pointer to the commands to be submitted.
4000  * @command_size: Size of the unpatched command batch.
4001  * @header: Out parameter returning the opaque pointer to the command buffer.
4002  *
4003  * This function checks whether we can use the command buffer manager for
4004  * submission and if so, creates a command buffer of suitable size and copies
4005  * the user data into that buffer.
4006  *
4007  * On successful return, the function returns a pointer to the data in the
4008  * command buffer and *@header is set to non-NULL.
4009  *
4010  * @kernel_commands: If command buffers could not be used, the function will
4011  * return the value of @kernel_commands on function call. That value may be
4012  * NULL. In that case, the value of *@header will be set to NULL.
4013  *
4014  * If an error is encountered, the function will return a pointer error value.
4015  * If the function is interrupted by a signal while sleeping, it will return
4016  * -ERESTARTSYS casted to a pointer error value.
4017  */
4018 static void *vmw_execbuf_cmdbuf(struct vmw_private *dev_priv,
4019                 void __user *user_commands,
4020                 void *kernel_commands, u32 command_size,
4021                 struct vmw_cmdbuf_header **header)
4022 {
4023     size_t cmdbuf_size;
4024     int ret;
4025 
4026     *header = NULL;
4027     if (command_size > SVGA_CB_MAX_SIZE) {
4028         VMW_DEBUG_USER("Command buffer is too large.\n");
4029         return ERR_PTR(-EINVAL);
4030     }
4031 
4032     if (!dev_priv->cman || kernel_commands)
4033         return kernel_commands;
4034 
4035     /* If possible, add a little space for fencing. */
4036     cmdbuf_size = command_size + 512;
4037     cmdbuf_size = min_t(size_t, cmdbuf_size, SVGA_CB_MAX_SIZE);
4038     kernel_commands = vmw_cmdbuf_alloc(dev_priv->cman, cmdbuf_size, true,
4039                        header);
4040     if (IS_ERR(kernel_commands))
4041         return kernel_commands;
4042 
4043     ret = copy_from_user(kernel_commands, user_commands, command_size);
4044     if (ret) {
4045         VMW_DEBUG_USER("Failed copying commands.\n");
4046         vmw_cmdbuf_header_free(*header);
4047         *header = NULL;
4048         return ERR_PTR(-EFAULT);
4049     }
4050 
4051     return kernel_commands;
4052 }
4053 
4054 static int vmw_execbuf_tie_context(struct vmw_private *dev_priv,
4055                    struct vmw_sw_context *sw_context,
4056                    uint32_t handle)
4057 {
4058     struct vmw_resource *res;
4059     int ret;
4060     unsigned int size;
4061 
4062     if (handle == SVGA3D_INVALID_ID)
4063         return 0;
4064 
4065     size = vmw_execbuf_res_size(dev_priv, vmw_res_dx_context);
4066     ret = vmw_validation_preload_res(sw_context->ctx, size);
4067     if (ret)
4068         return ret;
4069 
4070     res = vmw_user_resource_noref_lookup_handle
4071         (dev_priv, sw_context->fp->tfile, handle,
4072          user_context_converter);
4073     if (IS_ERR(res)) {
4074         VMW_DEBUG_USER("Could not find or user DX context 0x%08x.\n",
4075                    (unsigned int) handle);
4076         return PTR_ERR(res);
4077     }
4078 
4079     ret = vmw_execbuf_res_noref_val_add(sw_context, res, VMW_RES_DIRTY_SET);
4080     if (unlikely(ret != 0))
4081         return ret;
4082 
4083     sw_context->dx_ctx_node = vmw_execbuf_info_from_res(sw_context, res);
4084     sw_context->man = vmw_context_res_man(res);
4085 
4086     return 0;
4087 }
4088 
4089 int vmw_execbuf_process(struct drm_file *file_priv,
4090             struct vmw_private *dev_priv,
4091             void __user *user_commands, void *kernel_commands,
4092             uint32_t command_size, uint64_t throttle_us,
4093             uint32_t dx_context_handle,
4094             struct drm_vmw_fence_rep __user *user_fence_rep,
4095             struct vmw_fence_obj **out_fence, uint32_t flags)
4096 {
4097     struct vmw_sw_context *sw_context = &dev_priv->ctx;
4098     struct vmw_fence_obj *fence = NULL;
4099     struct vmw_cmdbuf_header *header;
4100     uint32_t handle = 0;
4101     int ret;
4102     int32_t out_fence_fd = -1;
4103     struct sync_file *sync_file = NULL;
4104     DECLARE_VAL_CONTEXT(val_ctx, &sw_context->res_ht, 1);
4105 
4106     if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) {
4107         out_fence_fd = get_unused_fd_flags(O_CLOEXEC);
4108         if (out_fence_fd < 0) {
4109             VMW_DEBUG_USER("Failed to get a fence fd.\n");
4110             return out_fence_fd;
4111         }
4112     }
4113 
4114     if (throttle_us) {
4115         VMW_DEBUG_USER("Throttling is no longer supported.\n");
4116     }
4117 
4118     kernel_commands = vmw_execbuf_cmdbuf(dev_priv, user_commands,
4119                          kernel_commands, command_size,
4120                          &header);
4121     if (IS_ERR(kernel_commands)) {
4122         ret = PTR_ERR(kernel_commands);
4123         goto out_free_fence_fd;
4124     }
4125 
4126     ret = mutex_lock_interruptible(&dev_priv->cmdbuf_mutex);
4127     if (ret) {
4128         ret = -ERESTARTSYS;
4129         goto out_free_header;
4130     }
4131 
4132     sw_context->kernel = false;
4133     if (kernel_commands == NULL) {
4134         ret = vmw_resize_cmd_bounce(sw_context, command_size);
4135         if (unlikely(ret != 0))
4136             goto out_unlock;
4137 
4138         ret = copy_from_user(sw_context->cmd_bounce, user_commands,
4139                      command_size);
4140         if (unlikely(ret != 0)) {
4141             ret = -EFAULT;
4142             VMW_DEBUG_USER("Failed copying commands.\n");
4143             goto out_unlock;
4144         }
4145 
4146         kernel_commands = sw_context->cmd_bounce;
4147     } else if (!header) {
4148         sw_context->kernel = true;
4149     }
4150 
4151     sw_context->filp = file_priv;
4152     sw_context->fp = vmw_fpriv(file_priv);
4153     INIT_LIST_HEAD(&sw_context->ctx_list);
4154     sw_context->cur_query_bo = dev_priv->pinned_bo;
4155     sw_context->last_query_ctx = NULL;
4156     sw_context->needs_post_query_barrier = false;
4157     sw_context->dx_ctx_node = NULL;
4158     sw_context->dx_query_mob = NULL;
4159     sw_context->dx_query_ctx = NULL;
4160     memset(sw_context->res_cache, 0, sizeof(sw_context->res_cache));
4161     INIT_LIST_HEAD(&sw_context->res_relocations);
4162     INIT_LIST_HEAD(&sw_context->bo_relocations);
4163 
4164     if (sw_context->staged_bindings)
4165         vmw_binding_state_reset(sw_context->staged_bindings);
4166 
4167     if (!sw_context->res_ht_initialized) {
4168         ret = vmwgfx_ht_create(&sw_context->res_ht, VMW_RES_HT_ORDER);
4169         if (unlikely(ret != 0))
4170             goto out_unlock;
4171 
4172         sw_context->res_ht_initialized = true;
4173     }
4174 
4175     INIT_LIST_HEAD(&sw_context->staged_cmd_res);
4176     sw_context->ctx = &val_ctx;
4177     ret = vmw_execbuf_tie_context(dev_priv, sw_context, dx_context_handle);
4178     if (unlikely(ret != 0))
4179         goto out_err_nores;
4180 
4181     ret = vmw_cmd_check_all(dev_priv, sw_context, kernel_commands,
4182                 command_size);
4183     if (unlikely(ret != 0))
4184         goto out_err_nores;
4185 
4186     ret = vmw_resources_reserve(sw_context);
4187     if (unlikely(ret != 0))
4188         goto out_err_nores;
4189 
4190     ret = vmw_validation_bo_reserve(&val_ctx, true);
4191     if (unlikely(ret != 0))
4192         goto out_err_nores;
4193 
4194     ret = vmw_validation_bo_validate(&val_ctx, true);
4195     if (unlikely(ret != 0))
4196         goto out_err;
4197 
4198     ret = vmw_validation_res_validate(&val_ctx, true);
4199     if (unlikely(ret != 0))
4200         goto out_err;
4201 
4202     vmw_validation_drop_ht(&val_ctx);
4203 
4204     ret = mutex_lock_interruptible(&dev_priv->binding_mutex);
4205     if (unlikely(ret != 0)) {
4206         ret = -ERESTARTSYS;
4207         goto out_err;
4208     }
4209 
4210     if (dev_priv->has_mob) {
4211         ret = vmw_rebind_contexts(sw_context);
4212         if (unlikely(ret != 0))
4213             goto out_unlock_binding;
4214     }
4215 
4216     if (!header) {
4217         ret = vmw_execbuf_submit_fifo(dev_priv, kernel_commands,
4218                           command_size, sw_context);
4219     } else {
4220         ret = vmw_execbuf_submit_cmdbuf(dev_priv, header, command_size,
4221                         sw_context);
4222         header = NULL;
4223     }
4224     mutex_unlock(&dev_priv->binding_mutex);
4225     if (ret)
4226         goto out_err;
4227 
4228     vmw_query_bo_switch_commit(dev_priv, sw_context);
4229     ret = vmw_execbuf_fence_commands(file_priv, dev_priv, &fence,
4230                      (user_fence_rep) ? &handle : NULL);
4231     /*
4232      * This error is harmless, because if fence submission fails,
4233      * vmw_fifo_send_fence will sync. The error will be propagated to
4234      * user-space in @fence_rep
4235      */
4236     if (ret != 0)
4237         VMW_DEBUG_USER("Fence submission error. Syncing.\n");
4238 
4239     vmw_execbuf_bindings_commit(sw_context, false);
4240     vmw_bind_dx_query_mob(sw_context);
4241     vmw_validation_res_unreserve(&val_ctx, false);
4242 
4243     vmw_validation_bo_fence(sw_context->ctx, fence);
4244 
4245     if (unlikely(dev_priv->pinned_bo != NULL && !dev_priv->query_cid_valid))
4246         __vmw_execbuf_release_pinned_bo(dev_priv, fence);
4247 
4248     /*
4249      * If anything fails here, give up trying to export the fence and do a
4250      * sync since the user mode will not be able to sync the fence itself.
4251      * This ensures we are still functionally correct.
4252      */
4253     if (flags & DRM_VMW_EXECBUF_FLAG_EXPORT_FENCE_FD) {
4254 
4255         sync_file = sync_file_create(&fence->base);
4256         if (!sync_file) {
4257             VMW_DEBUG_USER("Sync file create failed for fence\n");
4258             put_unused_fd(out_fence_fd);
4259             out_fence_fd = -1;
4260 
4261             (void) vmw_fence_obj_wait(fence, false, false,
4262                           VMW_FENCE_WAIT_TIMEOUT);
4263         }
4264     }
4265 
4266     ret = vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret,
4267                     user_fence_rep, fence, handle, out_fence_fd);
4268 
4269     if (sync_file) {
4270         if (ret) {
4271             /* usercopy of fence failed, put the file object */
4272             fput(sync_file->file);
4273             put_unused_fd(out_fence_fd);
4274         } else {
4275             /* Link the fence with the FD created earlier */
4276             fd_install(out_fence_fd, sync_file->file);
4277         }
4278     }
4279 
4280     /* Don't unreference when handing fence out */
4281     if (unlikely(out_fence != NULL)) {
4282         *out_fence = fence;
4283         fence = NULL;
4284     } else if (likely(fence != NULL)) {
4285         vmw_fence_obj_unreference(&fence);
4286     }
4287 
4288     vmw_cmdbuf_res_commit(&sw_context->staged_cmd_res);
4289     mutex_unlock(&dev_priv->cmdbuf_mutex);
4290 
4291     /*
4292      * Unreference resources outside of the cmdbuf_mutex to avoid deadlocks
4293      * in resource destruction paths.
4294      */
4295     vmw_validation_unref_lists(&val_ctx);
4296 
4297     return ret;
4298 
4299 out_unlock_binding:
4300     mutex_unlock(&dev_priv->binding_mutex);
4301 out_err:
4302     vmw_validation_bo_backoff(&val_ctx);
4303 out_err_nores:
4304     vmw_execbuf_bindings_commit(sw_context, true);
4305     vmw_validation_res_unreserve(&val_ctx, true);
4306     vmw_resource_relocations_free(&sw_context->res_relocations);
4307     vmw_free_relocations(sw_context);
4308     if (unlikely(dev_priv->pinned_bo != NULL && !dev_priv->query_cid_valid))
4309         __vmw_execbuf_release_pinned_bo(dev_priv, NULL);
4310 out_unlock:
4311     vmw_cmdbuf_res_revert(&sw_context->staged_cmd_res);
4312     vmw_validation_drop_ht(&val_ctx);
4313     WARN_ON(!list_empty(&sw_context->ctx_list));
4314     mutex_unlock(&dev_priv->cmdbuf_mutex);
4315 
4316     /*
4317      * Unreference resources outside of the cmdbuf_mutex to avoid deadlocks
4318      * in resource destruction paths.
4319      */
4320     vmw_validation_unref_lists(&val_ctx);
4321 out_free_header:
4322     if (header)
4323         vmw_cmdbuf_header_free(header);
4324 out_free_fence_fd:
4325     if (out_fence_fd >= 0)
4326         put_unused_fd(out_fence_fd);
4327 
4328     return ret;
4329 }
4330 
4331 /**
4332  * vmw_execbuf_unpin_panic - Idle the fifo and unpin the query buffer.
4333  *
4334  * @dev_priv: The device private structure.
4335  *
4336  * This function is called to idle the fifo and unpin the query buffer if the
4337  * normal way to do this hits an error, which should typically be extremely
4338  * rare.
4339  */
4340 static void vmw_execbuf_unpin_panic(struct vmw_private *dev_priv)
4341 {
4342     VMW_DEBUG_USER("Can't unpin query buffer. Trying to recover.\n");
4343 
4344     (void) vmw_fallback_wait(dev_priv, false, true, 0, false, 10*HZ);
4345     vmw_bo_pin_reserved(dev_priv->pinned_bo, false);
4346     if (dev_priv->dummy_query_bo_pinned) {
4347         vmw_bo_pin_reserved(dev_priv->dummy_query_bo, false);
4348         dev_priv->dummy_query_bo_pinned = false;
4349     }
4350 }
4351 
4352 
4353 /**
4354  * __vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned query
4355  * bo.
4356  *
4357  * @dev_priv: The device private structure.
4358  * @fence: If non-NULL should point to a struct vmw_fence_obj issued _after_ a
4359  * query barrier that flushes all queries touching the current buffer pointed to
4360  * by @dev_priv->pinned_bo
4361  *
4362  * This function should be used to unpin the pinned query bo, or as a query
4363  * barrier when we need to make sure that all queries have finished before the
4364  * next fifo command. (For example on hardware context destructions where the
4365  * hardware may otherwise leak unfinished queries).
4366  *
4367  * This function does not return any failure codes, but make attempts to do safe
4368  * unpinning in case of errors.
4369  *
4370  * The function will synchronize on the previous query barrier, and will thus
4371  * not finish until that barrier has executed.
4372  *
4373  * the @dev_priv->cmdbuf_mutex needs to be held by the current thread before
4374  * calling this function.
4375  */
4376 void __vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv,
4377                      struct vmw_fence_obj *fence)
4378 {
4379     int ret = 0;
4380     struct vmw_fence_obj *lfence = NULL;
4381     DECLARE_VAL_CONTEXT(val_ctx, NULL, 0);
4382 
4383     if (dev_priv->pinned_bo == NULL)
4384         goto out_unlock;
4385 
4386     ret = vmw_validation_add_bo(&val_ctx, dev_priv->pinned_bo, false,
4387                     false);
4388     if (ret)
4389         goto out_no_reserve;
4390 
4391     ret = vmw_validation_add_bo(&val_ctx, dev_priv->dummy_query_bo, false,
4392                     false);
4393     if (ret)
4394         goto out_no_reserve;
4395 
4396     ret = vmw_validation_bo_reserve(&val_ctx, false);
4397     if (ret)
4398         goto out_no_reserve;
4399 
4400     if (dev_priv->query_cid_valid) {
4401         BUG_ON(fence != NULL);
4402         ret = vmw_cmd_emit_dummy_query(dev_priv, dev_priv->query_cid);
4403         if (ret)
4404             goto out_no_emit;
4405         dev_priv->query_cid_valid = false;
4406     }
4407 
4408     vmw_bo_pin_reserved(dev_priv->pinned_bo, false);
4409     if (dev_priv->dummy_query_bo_pinned) {
4410         vmw_bo_pin_reserved(dev_priv->dummy_query_bo, false);
4411         dev_priv->dummy_query_bo_pinned = false;
4412     }
4413     if (fence == NULL) {
4414         (void) vmw_execbuf_fence_commands(NULL, dev_priv, &lfence,
4415                           NULL);
4416         fence = lfence;
4417     }
4418     vmw_validation_bo_fence(&val_ctx, fence);
4419     if (lfence != NULL)
4420         vmw_fence_obj_unreference(&lfence);
4421 
4422     vmw_validation_unref_lists(&val_ctx);
4423     vmw_bo_unreference(&dev_priv->pinned_bo);
4424 
4425 out_unlock:
4426     return;
4427 out_no_emit:
4428     vmw_validation_bo_backoff(&val_ctx);
4429 out_no_reserve:
4430     vmw_validation_unref_lists(&val_ctx);
4431     vmw_execbuf_unpin_panic(dev_priv);
4432     vmw_bo_unreference(&dev_priv->pinned_bo);
4433 }
4434 
4435 /**
4436  * vmw_execbuf_release_pinned_bo - Flush queries and unpin the pinned query bo.
4437  *
4438  * @dev_priv: The device private structure.
4439  *
4440  * This function should be used to unpin the pinned query bo, or as a query
4441  * barrier when we need to make sure that all queries have finished before the
4442  * next fifo command. (For example on hardware context destructions where the
4443  * hardware may otherwise leak unfinished queries).
4444  *
4445  * This function does not return any failure codes, but make attempts to do safe
4446  * unpinning in case of errors.
4447  *
4448  * The function will synchronize on the previous query barrier, and will thus
4449  * not finish until that barrier has executed.
4450  */
4451 void vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv)
4452 {
4453     mutex_lock(&dev_priv->cmdbuf_mutex);
4454     if (dev_priv->query_cid_valid)
4455         __vmw_execbuf_release_pinned_bo(dev_priv, NULL);
4456     mutex_unlock(&dev_priv->cmdbuf_mutex);
4457 }
4458 
4459 int vmw_execbuf_ioctl(struct drm_device *dev, void *data,
4460               struct drm_file *file_priv)
4461 {
4462     struct vmw_private *dev_priv = vmw_priv(dev);
4463     struct drm_vmw_execbuf_arg *arg = data;
4464     int ret;
4465     struct dma_fence *in_fence = NULL;
4466 
4467     MKS_STAT_TIME_DECL(MKSSTAT_KERN_EXECBUF);
4468     MKS_STAT_TIME_PUSH(MKSSTAT_KERN_EXECBUF);
4469 
4470     /*
4471      * Extend the ioctl argument while maintaining backwards compatibility:
4472      * We take different code paths depending on the value of arg->version.
4473      *
4474      * Note: The ioctl argument is extended and zeropadded by core DRM.
4475      */
4476     if (unlikely(arg->version > DRM_VMW_EXECBUF_VERSION ||
4477              arg->version == 0)) {
4478         VMW_DEBUG_USER("Incorrect execbuf version.\n");
4479         ret = -EINVAL;
4480         goto mksstats_out;
4481     }
4482 
4483     switch (arg->version) {
4484     case 1:
4485         /* For v1 core DRM have extended + zeropadded the data */
4486         arg->context_handle = (uint32_t) -1;
4487         break;
4488     case 2:
4489     default:
4490         /* For v2 and later core DRM would have correctly copied it */
4491         break;
4492     }
4493 
4494     /* If imported a fence FD from elsewhere, then wait on it */
4495     if (arg->flags & DRM_VMW_EXECBUF_FLAG_IMPORT_FENCE_FD) {
4496         in_fence = sync_file_get_fence(arg->imported_fence_fd);
4497 
4498         if (!in_fence) {
4499             VMW_DEBUG_USER("Cannot get imported fence\n");
4500             ret = -EINVAL;
4501             goto mksstats_out;
4502         }
4503 
4504         ret = dma_fence_wait(in_fence, true);
4505         if (ret)
4506             goto out;
4507     }
4508 
4509     ret = vmw_execbuf_process(file_priv, dev_priv,
4510                   (void __user *)(unsigned long)arg->commands,
4511                   NULL, arg->command_size, arg->throttle_us,
4512                   arg->context_handle,
4513                   (void __user *)(unsigned long)arg->fence_rep,
4514                   NULL, arg->flags);
4515 
4516     if (unlikely(ret != 0))
4517         goto out;
4518 
4519     vmw_kms_cursor_post_execbuf(dev_priv);
4520 
4521 out:
4522     if (in_fence)
4523         dma_fence_put(in_fence);
4524 
4525 mksstats_out:
4526     MKS_STAT_TIME_POP(MKSSTAT_KERN_EXECBUF);
4527     return ret;
4528 }